diff --git a/README b/README new file mode 100644 index 0000000000..54877d3f2d --- /dev/null +++ b/README @@ -0,0 +1,71 @@ + +Where to start +~~~~~~~~~~~~~~ +A good place to start is the "doc" directory, where you +will find "user" guides for the MOM. + +How to run the MOM tests +~~~~~~~~~~~~~~~~~~~~~~~~~ +MOM tests provided in exp directory divide in two types, +both using the GFDL shared infrastructure (FMS) : + +1. Solo models : Run stand alone MOM Ocean model. +2. Coupled models: Run MOM coupled with GFDL ice model + (besides null versions of atmosphere and land models). + +To run Solo models: + a. cd to exp and run mom4p1_solo_compile.csh first. + b. Modify the 'name' variable in the script + mom4p1_solo_run.csh to be the name of the test you + want to run. A list of available tests is included in the script. + c. Get the required input data for the test from GFDL ftp site. + You can get the info by running the script mom4p1_solo_run.csh + and following the instructions. + d. Run mom4p1_solo_run.csh + e. The results go into subdir name/workdir + +To run Coupled models: + Do the same steps above to mom4p1_coupled_compile.csh and mom4p1_coupled_run.csh + +To run EBM models: + Do the same steps above to mom4p1_ebm_compile.csh and mom4p1_ebm_run.csh + + + +Warning: The Solo and Coupled run scripts have been tested only on 10 and 24, ia64 + processors respectively. +Warning: Some of these tests require a large disk space to save the input data. + Choose a partition with enough space (1-2 G) to untar the code and data bundels. +Warning: If you want to use the same root directory for all three experiments we suggest to + compile in the order of increasing complexity: solo -> coupled -> ebm . + You may have to remove some of the existing .o and .mod files + if you want to compile ebm experiment after the coupled experiment. + E.g., you probably have to: cd ../exec; rm mpp*.o mpp*.mod fms_io*.o fms_io*.mod + +Note: IBM platform users might want to add the following line to the top of the run scripts + setenv LDR_CNTRL MAXDATA=0xD0000000@DSA + + +Note: The compile scripts provide the basic capability to use static memory allocation + which might be faster on some platforms. In that case you need to adjust the values + of domain bounds properly according to the number of processors and layout. + + +Summary of directory contents +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bin/ + -- mkmf script for creating Makefiles + -- template files for the mkmf script + -- assorted other scripts + +exp/ + -- all MOM experiments (test cases) + +src/ + -- source code for all models + +src/postprocessing/ + -- source code for postprocessing programs + +src/preprocessing/ + -- source code for preprocessing programs diff --git a/bin/.prepare_pubrel.csh.swp b/bin/.prepare_pubrel.csh.swp new file mode 100644 index 0000000000..d655e66061 Binary files /dev/null and b/bin/.prepare_pubrel.csh.swp differ diff --git a/bin/diag_table_chk b/bin/diag_table_chk index f988da66e3..55423a43cb 100755 --- a/bin/diag_table_chk +++ b/bin/diag_table_chk @@ -1,8 +1,8 @@ #! /usr/bin/perl -# $Author: fms $ -# $Revision: 17.0 $ -# $Date: 2009/08/10 20:51:27 $ +# $Author: Niki.Zadeh $ +# $Revision: 1.1.2.1 $ +# $Date: 2013/12/18 17:47:53 $ # Perl script to parse the diag_table. Count the number of files to # be used, and the max number of fields per file used. diff --git a/bin/environs.ibm.xlf b/bin/environs.ibm.xlf new file mode 100644 index 0000000000..57deddb846 --- /dev/null +++ b/bin/environs.ibm.xlf @@ -0,0 +1,3 @@ +export OMP_NUM_THREADS=1 +export BG_APPTHREADDEPTH=1 + diff --git a/bin/environs.ncrc2.gnu b/bin/environs.ncrc2.gnu new file mode 100644 index 0000000000..64609814a0 --- /dev/null +++ b/bin/environs.ncrc2.gnu @@ -0,0 +1,15 @@ + source $MODULESHOME/init/csh + module use -a /ncrc/home2/fms/local/modulefiles + module unload PrgEnv-pgi PrgEnv-pathscale PrgEnv-intel PrgEnv-gnu PrgEnv-cray + module unload netcdf fre fre-commands + module load PrgEnv-gnu + module load hdf5/1.8.8 + module load netcdf/4.2.0 + module list + setenv MPICH_MAX_SHORT_MSG_SIZE 8000 + setenv KMP_STACKSIZE 512m + setenv NC_BLKSZ 1M + + setenv mpirunCommand "aprun -n" + setenv PATH ${PATH}:. + diff --git a/bin/environs.ncrc2.intel b/bin/environs.ncrc2.intel index f71429b8a3..fda798ef01 100644 --- a/bin/environs.ncrc2.intel +++ b/bin/environs.ncrc2.intel @@ -4,7 +4,7 @@ # source $MODULESHOME/init/csh module rm PrgEnv-pgi PrgEnv-pathscale netcdf - module load PrgEnv-intel/4.0.30 + module load PrgEnv-intel module swap intel intel/12.0.5.220 module load hdf5/1.8.7 module load netcdf/4.1.3 diff --git a/bin/environs.workstation.gfort b/bin/environs.workstation.gfort new file mode 100644 index 0000000000..124be6ea84 --- /dev/null +++ b/bin/environs.workstation.gfort @@ -0,0 +1,2 @@ + setenv mpirunCommand "mpirun -np" + diff --git a/bin/environs.workstation.intel b/bin/environs.workstation.intel new file mode 100644 index 0000000000..cd80b1f614 --- /dev/null +++ b/bin/environs.workstation.intel @@ -0,0 +1,17 @@ + source $MODULESHOME/init/csh + module use -a /home/fms/local/modulefiles + module purge + module load ifort.11.0.074 + module load icc.11.0.074 + module load idb.10.1.35 + module load hdf5-1.8.3 + module load netcdf-4.0.1 + setenv OMP_NUM_THREADS 1 +# + setenv NC_BLKSZ 64K + setenv FMS_ARCHIVE /archive/fms + setenv PATH ${PATH}:. + setenv netcdf3_inc_dir "/usr/local/netcdf-3.6.2/include" + setenv netcdf3_lib_dir "/usr/local/netcdf-3.6.2/lib" + setenv mpirunCommand "mpirun -np" + diff --git a/bin/list_files_with_tag b/bin/list_files_with_tag index 40a0432f1f..08a8cfca4f 100755 --- a/bin/list_files_with_tag +++ b/bin/list_files_with_tag @@ -4,7 +4,7 @@ # Returns list of files under CVS control, relative to current # directory, which can be updated or checked out with the tag tagname. #Modified to also list files not currently checked out (arl, 4/2002) -#Version: $Id: list_files_with_tag,v 10.0 2003/10/27 22:46:40 fms Exp $ +#Version: $Id: list_files_with_tag,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ #test that a tagname was given as an argument if( "$#ARGV" ne "0" ) { diff --git a/bin/list_paths b/bin/list_paths index 2b2efa81d0..1cb890bf5f 100755 --- a/bin/list_paths +++ b/bin/list_paths @@ -1,5 +1,5 @@ #!/bin/csh -ef -# $Id: list_paths,v 10.1 2010/05/19 18:42:43 fms Exp $ +# $Id: list_paths,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ #----------------------------------------------------------------------- # list_paths: CVS administrative script # @@ -93,6 +93,6 @@ echo "
" $1 ""}' >> $outdoc echo '
-# Makefile created by mkmf $Id: mkmf.html,v 10.0 2003/10/27 22:46:40 fms Exp $ +# Makefile created by mkmf $Id: mkmf.html,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ .DEFAULT: @@ -348,7 +348,7 @@mkmf - a tool for making makefiles
The new Makefile looks like this:-# Makefile created by mkmf $Id: mkmf.html,v 10.0 2003/10/27 22:46:40 fms Exp $ +# Makefile created by mkmf $Id: mkmf.html,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ .DEFAULT: diff --git a/bin/mkmf.template.gfdl_ws_64.gnu b/bin/mkmf.template.gfdl_ws_64.gnu index d3a15ad28b..9f7a06e43c 100644 --- a/bin/mkmf.template.gfdl_ws_64.gnu +++ b/bin/mkmf.template.gfdl_ws_64.gnu @@ -1,4 +1,4 @@ -# $Id: gnu.mk,v 1.1.2.1.2.1 2012/03/07 15:08:54 sdu Exp $ +# $Id: mkmf.template.gfdl_ws_64.gnu,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ # template for the Intel fortran compiler # typical use with mkmf # mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include diff --git a/bin/mkmf.template.gfdl_ws_64.gnu.debug b/bin/mkmf.template.gfdl_ws_64.gnu.debug new file mode 100644 index 0000000000..1744c6cb20 --- /dev/null +++ b/bin/mkmf.template.gfdl_ws_64.gnu.debug @@ -0,0 +1,184 @@ +# $Id: mkmf.template.gfdl_ws_64.gnu.debug,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ +# template for the Intel fortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +############ +# commands # +############ +FC = gfortran +CC = gcc +LD = gfortran $(MAIN_PROGRAM) +######### +# flags # +######### +DEBUG = on +REPRO = +VERBOSE = +OPENMP = + +MAKEFLAGS += --jobs=$(shell grep '^processor' /proc/cpuinfo | wc -l) + +FPPFLAGS := + +FFLAGS := -fcray-pointer -fdefault-real-8 -Waliasing -ffree-line-length-none -fno-range-check +FFLAGS += -I/net2/nnz/opt/netcdf-4.1.1/include +#FFLAGS += -I/home/fms/local/opt/netcdf/4.1.1-gnu-4/include +#The above fails with USE netcdf, ONLY: NF_FILL_REAL => NF90_FILL_REAL +# 1 +# Fatal Error: Parse error when checking module version for file 'netcdf.mod' opened at (1) +# +#FFLAGS += $(shell nc-config --fflags) +# +FFLAGS += -I/net2/nnz/opt/mpich2-1.3_ifort11_x64/include +#FFLAGS += -I/usr/local/x64/mpich2-1.2.1p1/include # I do not trust this package, mpirun does not work +#$(shell pkg-config --cflags-only-I mpich2-c) +FFLAGS_OPT = -O2 +FFLAGS_REPRO = +FFLAGS_DEBUG = -O0 -g -W -fbounds-check +FFLAGS_OPENMP = -fopenmp +FFLAGS_VERBOSE = + +CFLAGS := -D__IFC +CFLAGS += $(shell nc-config --cflags) +CFLAGS += -I/net2/nnz/opt/netcdf-4.1.1/include -I/net2/nnz/opt/mpich2-1.3_ifort11_x64/include +#CFLAGS += $(shell pkg-config --cflags-only-I mpich2-c) +CFLAGS_OPT = -O2 +CFLAGS_OPENMP = -fopenmp +CFLAGS_DEBUG = -O0 -g + +# Optional Testing compile flags. Mutually exclusive from DEBUG, REPRO, and OPT +# *_TEST will match the production if no new option(s) is(are) to be tested. +FFLAGS_TEST = -O2 +CFLAGS_TEST = -O2 + +LDFLAGS := +LDFLAGS_OPENMP := -fopenmp +LDFLAGS_VERBOSE := + +ifneq ($(REPRO),) +CFLAGS += $(CFLAGS_REPRO) +FFLAGS += $(FFLAGS_REPRO) +endif +ifneq ($(DEBUG),) +CFLAGS += $(CFLAGS_DEBUG) +FFLAGS += $(FFLAGS_DEBUG) +else ifneq ($(TEST),) +CFLAGS += $(CFLAGS_TEST) +FFLAGS += $(FFLAGS_TEST) +else +CFLAGS += $(CFLAGS_OPT) +FFLAGS += $(FFLAGS_OPT) +endif + +ifneq ($(OPENMP),) +CFLAGS += $(CFLAGS_OPENMP) +FFLAGS += $(FFLAGS_OPENMP) +LDFLAGS += $(LDFLAGS_OPENMP) +endif + +ifneq ($(VERBOSE),) +CFLAGS += $(CFLAGS_VERBOSE) +FFLAGS += $(FFLAGS_VERBOSE) +LDFLAGS += $(LDFLAGS_VERBOSE) +endif + +ifeq ($(NETCDF),3) + # add the use_LARGEFILE cppdef + ifneq ($(findstring -Duse_netCDF,$(CPPDEFS)),) + CPPDEFS += -Duse_LARGEFILE + endif +endif + +LIBS := $(shell nc-config --flibs) -L/net2/nnz/opt/mpich2-1.3_ifort11_x64/lib -lmpich -lmpl -lpthread +#$(shell pkg-config --libs mpich2-f90) #does not work +LDFLAGS += $(LIBS) + +#--------------------------------------------------------------------------- +# you should never need to change any lines below. + +# see the MIPSPro F90 manual for more details on some of the file extensions +# discussed here. +# this makefile template recognizes fortran sourcefiles with extensions +# .f, .f90, .F, .F90. Given a sourcefile. , where is one of +# the above, this provides a number of default actions: + +# make .opt create an optimization report +# make .o create an object file +# make .s create an assembly listing +# make .x create an executable file, assuming standalone +# source +# make .i create a preprocessed file (for .F) +# make .i90 create a preprocessed file (for .F90) + +# The macro TMPFILES is provided to slate files like the above for removal. + +RM = rm -f +SHELL = /bin/csh -f +TMPFILES = .*.m *.B *.L *.i *.i90 *.l *.s *.mod *.opt + +.SUFFIXES: .F .F90 .H .L .T .f .f90 .h .i .i90 .l .o .s .opt .x + +.f.L: + $(FC) $(FFLAGS) -c -listing $*.f +.f.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f +.f.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f +.f.T: + $(FC) $(FFLAGS) -c -cif $*.f +.f.o: + $(FC) $(FFLAGS) -c $*.f +.f.s: + $(FC) $(FFLAGS) -S $*.f +.f.x: + $(FC) $(FFLAGS) -o $*.x $*.f *.o $(LDFLAGS) +.f90.L: + $(FC) $(FFLAGS) -c -listing $*.f90 +.f90.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f90 +.f90.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f90 +.f90.T: + $(FC) $(FFLAGS) -c -cif $*.f90 +.f90.o: + $(FC) $(FFLAGS) -c $*.f90 +.f90.s: + $(FC) $(FFLAGS) -c -S $*.f90 +.f90.x: + $(FC) $(FFLAGS) -o $*.x $*.f90 *.o $(LDFLAGS) +.F.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F +.F.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F +.F.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F +.F.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F +.F.f: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F > $*.f +.F.i: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F +.F.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F +.F.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F +.F.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F *.o $(LDFLAGS) +.F90.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F90 +.F90.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F90 +.F90.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F90 +.F90.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F90 +.F90.f90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F90 > $*.f90 +.F90.i90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F90 +.F90.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F90 +.F90.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F90 +.F90.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F90 *.o $(LDFLAGS) diff --git a/bin/mkmf.template.ibm.xlf b/bin/mkmf.template.ibm.xlf new file mode 100644 index 0000000000..97cd20d1fc --- /dev/null +++ b/bin/mkmf.template.ibm.xlf @@ -0,0 +1,15 @@ +# Template for IBM xlf and xlc compilers +#typical use with netCDF: +# mkmf -t template.ibm -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +FC = mpxlf90_r +LD = mpxlf90_r +CC = mpcc_r + CPPFLAGS = + NETCDF = /usr/local + FFLAGS = $(CPPFLAGS) -I$(NETCDF)/include -O2 -qalias_size=1207959552 -qmaxmem=256000 -g -d -qsuffix=cpp=F90 -qintsize=4 -qrealsize=8 -qdpc -qextname=flush -qextname=mld_id -qsmp=omp:noauto -qnohot -qsimd=noauto -qnoipa + GFLAGS = $(CPPFLAGS) -I$(NETCDF)/include -O2 -qalias_size=1207959552 -qmaxmem=256000 -g -d -qsuffix=cpp=F90 -qintsize=4 -qrealsize=8 -qdpc -qextname=flush -qextname=mld_id -qsmp=omp:noauto -qnohot -qsimd=noauto + PFLAGS = $(CPPFLAGS) -I$(NETCDF)/include -O0 -qalias_size=1207959552 -qmaxmem=256000 -g -d -qsuffix=cpp=F90 -qintsize=4 -qrealsize=8 -qdpc -qextname=flush -qextname=mld_id -qsmp=omp:noauto -qnohot -qsimd=noauto + QFLAGS = $(CPPFLAGS) -I$(NETCDF)/include -O2 -qalias_size=1207959552 -qmaxmem=256000 -g -d -qsuffix=cpp=F90 -qintsize=4 -qrealsize=8 -qdpc -qextname=flush -qextname=mld_id -qsmp=omp:noauto -qnohot -qsimd=noauto -qfixed + CFLAGS = -I$(NETCDF)/include + LDFLAGS = -L$(NETCDF)/lib -lnetcdf -lmass -qsmp + diff --git a/bin/mkmf.template.ncrc2.gnu b/bin/mkmf.template.ncrc2.gnu new file mode 100644 index 0000000000..035b81ebc2 --- /dev/null +++ b/bin/mkmf.template.ncrc2.gnu @@ -0,0 +1,177 @@ +# $Id: mkmf.template.ncrc2.gnu,v 1.1.2.1 2013/12/18 17:47:55 Niki.Zadeh Exp $ +# template for the Intel fortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +############ +# commands # +############ +FC = ftn +CC = cc +LD = ftn $(MAIN_PROGRAM) +######### +# flags # +######### +DEBUG = +REPRO = +VERBOSE = +OPENMP = + +MAKEFLAGS += --jobs=2 + +FPPFLAGS := + +FFLAGS := -fcray-pointer -fdefault-real-8 -fdefault-double-8 -Waliasing -ffree-line-length-none -fno-range-check +FFLAGS_OPT = -O2 -fno-expensive-optimizations +FFLAGS_REPRO = +FFLAGS_DEBUG = -O0 -g -W -fbounds-check +FFLAGS_OPENMP = -fopenmp +FFLAGS_VERBOSE = + +CFLAGS := -D__IFC +CFLAGS_OPT = -O2 +CFLAGS_OPENMP = -fopenmp +CFLAGS_DEBUG = -O0 -g + +# Optional Testing compile flags. Mutually exclusive from DEBUG, REPRO, and OPT +# *_TEST will match the production if no new option(s) is(are) to be tested. +FFLAGS_TEST = -O2 +CFLAGS_TEST = -O2 + +LDFLAGS := +LDFLAGS_OPENMP := -fopenmp +LDFLAGS_VERBOSE := + +ifneq ($(REPRO),) +CFLAGS += $(CFLAGS_REPRO) +FFLAGS += $(FFLAGS_REPRO) +endif +ifneq ($(DEBUG),) +CFLAGS += $(CFLAGS_DEBUG) +FFLAGS += $(FFLAGS_DEBUG) +else ifneq ($(TEST),) +CFLAGS += $(CFLAGS_TEST) +FFLAGS += $(FFLAGS_TEST) +else +CFLAGS += $(CFLAGS_OPT) +FFLAGS += $(FFLAGS_OPT) +endif + +ifneq ($(OPENMP),) +CFLAGS += $(CFLAGS_OPENMP) +FFLAGS += $(FFLAGS_OPENMP) +LDFLAGS += $(LDFLAGS_OPENMP) +endif + +ifneq ($(VERBOSE),) +CFLAGS += $(CFLAGS_VERBOSE) +FFLAGS += $(FFLAGS_VERBOSE) +LDFLAGS += $(LDFLAGS_VERBOSE) +endif + +ifeq ($(NETCDF),3) + # add the use_LARGEFILE cppdef + ifneq ($(findstring -Duse_netCDF,$(CPPDEFS)),) + CPPDEFS += -Duse_LARGEFILE + endif +endif + +LIBS := + +ifneq ($(findstring netcdf,$(LOADEDMODULES)),) + LIBS += -lnetcdff -lnetcdf -lhdf5_hl -lhdf5 -lz +else + LIBS += -lnetcdf +endif + +LIBS += +LDFLAGS += $(LIBS) + +#--------------------------------------------------------------------------- +# you should never need to change any lines below. + +# see the MIPSPro F90 manual for more details on some of the file extensions +# discussed here. +# this makefile template recognizes fortran sourcefiles with extensions +# .f, .f90, .F, .F90. Given a sourcefile . , where is one of +# the above, this provides a number of default actions: + +# make .opt create an optimization report +# make .o create an object file +# make .s create an assembly listing +# make .x create an executable file, assuming standalone +# source +# make .i create a preprocessed file (for .F) +# make .i90 create a preprocessed file (for .F90) + +# The macro TMPFILES is provided to slate files like the above for removal. + +RM = rm -f +SHELL = /bin/csh -f +TMPFILES = .*.m *.B *.L *.i *.i90 *.l *.s *.mod *.opt + +.SUFFIXES: .F .F90 .H .L .T .f .f90 .h .i .i90 .l .o .s .opt .x + +.f.L: + $(FC) $(FFLAGS) -c -listing $*.f +.f.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f +.f.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f +.f.T: + $(FC) $(FFLAGS) -c -cif $*.f +.f.o: + $(FC) $(FFLAGS) -c $*.f +.f.s: + $(FC) $(FFLAGS) -S $*.f +.f.x: + $(FC) $(FFLAGS) -o $*.x $*.f *.o $(LDFLAGS) +.f90.L: + $(FC) $(FFLAGS) -c -listing $*.f90 +.f90.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f90 +.f90.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f90 +.f90.T: + $(FC) $(FFLAGS) -c -cif $*.f90 +.f90.o: + $(FC) $(FFLAGS) -c $*.f90 +.f90.s: + $(FC) $(FFLAGS) -c -S $*.f90 +.f90.x: + $(FC) $(FFLAGS) -o $*.x $*.f90 *.o $(LDFLAGS) +.F.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F +.F.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F +.F.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F +.F.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F +.F.f: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F > $*.f +.F.i: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F +.F.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F +.F.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F +.F.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F *.o $(LDFLAGS) +.F90.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F90 +.F90.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F90 +.F90.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F90 +.F90.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F90 +.F90.f90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F90 > $*.f90 +.F90.i90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F90 +.F90.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F90 +.F90.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F90 +.F90.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F90 *.o $(LDFLAGS) diff --git a/bin/mkmf.template.ncrc2.intel b/bin/mkmf.template.ncrc2.intel index 3cc0a6c174..bac56740b0 100644 --- a/bin/mkmf.template.ncrc2.intel +++ b/bin/mkmf.template.ncrc2.intel @@ -11,7 +11,7 @@ LD = ftn # flags # ######### DEBUG = -REPRO = +REPRO = on VERBOSE = OPENMP = @@ -32,10 +32,10 @@ INCLUDE = -I$(NETCDF_ROOT)/include FPPFLAGS := -fpp -Wp,-w $(INCLUDE) -FFLAGS := -fno-alias -automatic -safe-cray-ptr -ftz -assume byterecl -i4 -r8 -nowarn +FFLAGS := -fno-alias -automatic -safe-cray-ptr -ftz -assume byterecl -i4 -r8 -nowarn FFLAGS_OPT = -O3 -debug minimal -fp-model precise -override-limits FFLAGS_DEBUG = -g -O0 -check -check noarg_temp_created -check nopointer -warn -warn noerrors -fpe0 -traceback -ftrapuv -FFLAGS_REPRO = -O2 -debug minimal -fp-model precise -override-limits +FFLAGS_REPRO = -O2 -debug minimal -fp-model precise -override-limits -g -traceback FFLAGS_OPENMP = -openmp FFLAGS_VERBOSE = -v -V -what diff --git a/bin/mkmf.template.workstation.gfort b/bin/mkmf.template.workstation.gfort new file mode 100644 index 0000000000..a8118c6c61 --- /dev/null +++ b/bin/mkmf.template.workstation.gfort @@ -0,0 +1,18 @@ +# template for the Gnu Fortran (gfortran) compiler version (GCC) 4.4.0 20090514 when using libMPI +# this template was tested with FRE on the workstation nnz on 10/06/2010 +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +# +#We need to locate the netcdf.mod that was compiled with gfort and pass it BEFORE any other location that might have a netcdf.mod +NETCDF_MOD_FILE_LOCATION = /home/nnz/local/include/gfort +MPICH_LOCATION = /net2/nnz/opt/mpich2-1.3_gfort44 +#MPICH_LOCATION = /usr/local/mpich +# +FFLAGS_BASE = -fcray-pointer -g -fdefault-real-8 -O2 -Waliasing -ffree-line-length-none -fno-range-check +FFLAGS = $(FFLAGS_BASE) +CPPFLAGS = -I/usr/include -I$(MPICH_LOCATION)/include -I$(NETCDF_MOD_FILE_LOCATION) -I/usr/local/netcdf4/include +FC = gfortran44 +LD = gfortran44 $(MAIN_PROGRAM) +LDFLAGS = -L/usr/local/netcdf4/lib -lnetcdf -L/usr/local/hdf5/lib -lhdf5_hl -lhdf5 -lz -L$(MPICH_LOCATION)/lib -lmpich -lpthread -lmpl +CFLAGS = -D__IFC + diff --git a/bin/mkmf.template.workstation.intel b/bin/mkmf.template.workstation.intel new file mode 100644 index 0000000000..47bc3de92b --- /dev/null +++ b/bin/mkmf.template.workstation.intel @@ -0,0 +1,182 @@ +# template for the Intel fortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +############ +# commands # +############ +FC = ifort +CC = icc +LD = ifort +######### +# flags # +######### +DEBUG = +REPRO = on +VERBOSE = +OPENMP = + +############################################## +# Need to use at least GNU Make version 3.81 # +############################################## +need := 3.81 +ok := $(filter $(need),$(firstword $(sort $(MAKE_VERSION) $(need)))) +ifneq ($(need),$(ok)) +$(error Need at least make version $(need). Load module gmake/3.81) +endif + +MAKEFLAGS += --jobs=2 + +NETCDF_ROOT = /home/nnz/local/build/netcdf-4.1.1_ifort11_HDF +MPICH_ROOT = /home/nnz/local/build/mpich2-1.3_ifort11 +#MPICH_ROOT = /usr/local/mpich +HDF5_ROOT = /home/nnz/local/build/hdf5-1.8.5-patch1_zlib-1.2.5_ifort11/lib +ZLIB_ROOT = /home/nnz/local/build/zlib-1.2.5 +INCLUDE = -I$(NETCDF_ROOT)/include -I$(MPICH_ROOT)/include + + +FPPFLAGS := -fpp -Wp,-w $(INCLUDE) + +FFLAGS := -fno-alias -automatic -safe-cray-ptr -ftz -assume byterecl -i4 -r8 -nowarn +FFLAGS_OPT = -O3 -debug minimal -fp-model precise -override-limits +FFLAGS_DEBUG = -g -O0 -check -check noarg_temp_created -check nopointer -warn -warn noerrors -fpe0 -traceback -ftrapuv +FFLAGS_REPRO = -O2 -debug minimal -no-vec -fp-model precise -override-limits +FFLAGS_OPENMP = -openmp +FFLAGS_VERBOSE = -v -V -what + + +CFLAGS := -D__IFC $(INCLUDE) +CFLAGS_OPT = -O2 -debug minimal -no-vec +CFLAGS_OPENMP = -openmp +CFLAGS_DEBUG = -O0 -g -ftrapuv -traceback + +LDFLAGS := +LDFLAGS_VERBOSE := -Wl,-V,--verbose,-cref,-M + +ifneq ($(REPRO),) +CFLAGS += $(CFLAGS_REPRO) +FFLAGS += $(FFLAGS_REPRO) +endif +ifneq ($(DEBUG),) +CFLAGS += $(CFLAGS_DEBUG) +FFLAGS += $(FFLAGS_DEBUG) +#else +#CFLAGS += $(CFLAGS_OPT) +#FFLAGS += $(FFLAGS_OPT) +endif + +ifneq ($(OPENMP),) +CFLAGS += $(CFLAGS_OPENMP) +FFLAGS += $(FFLAGS_OPENMP) +endif + +ifneq ($(VERBOSE),) +CFLAGS += $(CFLAGS_VERBOSE) +FFLAGS += $(FFLAGS_VERBOSE) +LDFLAGS += $(LDFLAGS_VERBOSE) +endif + +ifeq ($(NETCDF),3) + # add the use_LARGEFILE cppdef + ifneq ($(findstring -Duse_netCDF,$(CPPDEFS)),) + CPPDEFS += -Duse_LARGEFILE + endif +endif + +ifneq ($(findstring netcdf-4.0.1,$(LOADEDMODULES)),) + LIBS := -L$(NETCDF_ROOT)/lib -lnetcdf -L$(HDF5_ROOT)/lib -lhdf5_hl -lhdf5 -lcurl -L$(ZLIB_ROOT)/lib -lz +else + LIBS := -L$(NETCDF_ROOT)/lib -lnetcdf +endif + +LIBS += -L$(MPICH_ROOT)/lib -lmpich -lpthread -lmpl +LDFLAGS += $(LIBS) + +#--------------------------------------------------------------------------- +# you should never need to change any lines below. + +# see the MIPSPro F90 manual for more details on some of the file extensions +# discussed here. +# this makefile template recognizes fortran sourcefiles with extensions +# .f, .f90, .F, .F90. Given a sourcefile . , where is one of +# the above, this provides a number of default actions: + +# make .opt create an optimization report +# make .o create an object file +# make .s create an assembly listing +# make .x create an executable file, assuming standalone +# source +# make .i create a preprocessed file (for .F) +# make .i90 create a preprocessed file (for .F90) + +# The macro TMPFILES is provided to slate files like the above for removal. + +RM = rm -f +SHELL = /bin/csh -f +TMPFILES = .*.m *.B *.L *.i *.i90 *.l *.s *.mod *.opt + +.SUFFIXES: .F .F90 .H .L .T .f .f90 .h .i .i90 .l .o .s .opt .x + +.f.L: + $(FC) $(FFLAGS) -c -listing $*.f +.f.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f +.f.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f +.f.T: + $(FC) $(FFLAGS) -c -cif $*.f +.f.o: + $(FC) $(FFLAGS) -c $*.f +.f.s: + $(FC) $(FFLAGS) -S $*.f +.f.x: + $(FC) $(FFLAGS) -o $*.x $*.f *.o $(LDFLAGS) +.f90.L: + $(FC) $(FFLAGS) -c -listing $*.f90 +.f90.opt: + $(FC) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.f90 +.f90.l: + $(FC) $(FFLAGS) -c $(LIST) $*.f90 +.f90.T: + $(FC) $(FFLAGS) -c -cif $*.f90 +.f90.o: + $(FC) $(FFLAGS) -c $*.f90 +.f90.s: + $(FC) $(FFLAGS) -c -S $*.f90 +.f90.x: + $(FC) $(FFLAGS) -o $*.x $*.f90 *.o $(LDFLAGS) +.F.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F +.F.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F +.F.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F +.F.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F +.F.f: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F > $*.f +.F.i: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F +.F.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F +.F.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F +.F.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F *.o $(LDFLAGS) +.F90.L: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -listing $*.F90 +.F90.opt: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -opt_report_level max -opt_report_phase all -opt_report_file $*.opt $*.F90 +.F90.l: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $(LIST) $*.F90 +.F90.T: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -cif $*.F90 +.F90.f90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -EP $*.F90 > $*.f90 +.F90.i90: + $(FC) $(CPPDEFS) $(FPPFLAGS) -P $*.F90 +.F90.o: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c $*.F90 +.F90.s: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -c -S $*.F90 +.F90.x: + $(FC) $(CPPDEFS) $(FPPFLAGS) $(FFLAGS) -o $*.x $*.F90 *.o $(LDFLAGS) diff --git a/bin/mppnccombine.gfdl_ws_64.intel b/bin/mppnccombine.gfdl_ws_64.intel new file mode 100755 index 0000000000..c6388f05c0 Binary files /dev/null and b/bin/mppnccombine.gfdl_ws_64.intel differ diff --git a/bin/prepare_pubrel.csh b/bin/prepare_pubrel.csh new file mode 100755 index 0000000000..73fadabfce --- /dev/null +++ b/bin/prepare_pubrel.csh @@ -0,0 +1,119 @@ +#!/bin/csh +# +#These are the notes on how to make the MOM4p1 public release. +#The notes are intended only for the GFDL people responsible for making the MOM4p1 public release. +# +set FMS_RELEASE=tikal +set MOM_RELEASE=tikal +set PUB_RELEASE=mom5_pubrel_December2013 +mkdir src +cd src + +#check outs +cvs co -r $MOM_RELEASE mom5 +cvs co -r $FMS_RELEASE shared ocean_shared +cvs co -r $FMS_RELEASE ice_sis ice_param +cvs co -r $FMS_RELEASE land_lad land_null land_param land_lad2 +cvs co -r $FMS_RELEASE atmos_param_am3 +cvs co -r $FMS_RELEASE atmos_bgrid atmos_coupled atmos_ebm atmos_fv_dynamics +cvs co -r $FMS_RELEASE atmos_null atmos_shared atmos_spectral +cvs co -r $FMS_RELEASE coupler + +cvs co -r $FMS_RELEASE postprocessing preprocessing tools + +#cut and nullify some stuff +\rm -rf atmos_param/qe_moist_convection atmos_param/two_stream_gray_rad atmos_param/shallow_physics +\rm -rf atmos_param/lin_cloud_microphys/* atmos_param/clubb/* +cvs co -r nullify_rab_nnz atmos_param/lin_cloud_microphys/lin_cloud_microphys.F90 atmos_param/clubb/CLUBB_driver_SCM.F90 atmos_param/clubb/MG_microp_3D.F90 + +#The following file is not needed +\rm -rf mom5/drivers/coupler_types.* + +\rm -rf tools/xmlDoc tools/fremetar tools/fbrowser + + +cvs up -r mom5_pubrel_dec2013_nnz mom5/doc +mv mom5/doc ../ + +#No pdf,ps,html +find . -name '*.pdf' -exec rm -f {} \; +find . -name '*.ps' -exec rm -f {} \; +find . -name '*.html' -exec rm -f {} \; + +#bin/ and exp/ + +cvs co -r mom5_pubrel_dec2013_nnz mom5/utils/ +mv mom5/utils/bin ../ +mv mom5/utils/exp ../ +\rm -rf mom5/utils + +#Date tag (sticky) the whole thing +#cvs tag $(PUB_RELEASE)_nnz * + +exit +#The following cleanups is done after tagging. +#No www.gfdl.noaa.gov +foreach file ( `grep -l -r noaa.gov .` ) +foreach? sed '/.*www.*.noaa.gov.*/d' -i $file +foreach? end + +#No work emails +foreach file ( `grep -l -r @noaa.gov .`) +foreach? sed 's/@noaa.gov/@no.gov/g' -i $file +foreach? end + +foreach file ( `grep -l -r @gfdl.noaa.gov .`) +foreach? sed 's/@gfdl.noaa.gov/@no.gov/g' -i $file +foreach? end + +foreach file ( `grep -l -r EMAIL .`) +sed 's/EMAIL=.*.gov/EMAIL="GFDL.Climate.Model.Info@noaa.gov/g' -i $file +end + +foreach file ( `grep -l -r @no.gov .` ) +foreach? sed 's/@.*no.gov//g' -i $file +foreach? end + +exit + +#update the htmls for some major files +#The following is too big to be included +cvs co -r xmlDoc_clean_sdu tools/xmlDoc + + +setenv XMLDOC_ROOT ${PWD}/tools/xmlDoc + +foreach file ( coupler shared/diag_manager shared/mpp shared/time_manager shared/data_override preprocessing shared/field_manager mom5 ) +${PWD}/tools/xmlDoc/bin/xmlDoc --dir $file +end + +#GNUize all F90 and c files +#Some files are checked in without write permission +#chmod -R +w . +#/home/nnz/bin/GNULicense.pl -f --dir=. --recursive +#This will touch ALL code, so you have to test, test, test! +# cvs ci or not ci , I wouldn't do it GNU!! + +# +#tar up +# +cd ../ + + +tar cvf $PUB_RELEASE.tar $PUB_RELEASE/src +tar rvf $PUB_RELEASE.tar $PUB_RELEASE/bin +tar rvf $PUB_RELEASE.tar $PUB_RELEASE/exp +gzip $PUB_RELEASE.tar + +#Documentation +#cvs co -r $MOM_RELEASE mom5/doc +#cd mom5/doc +##Work on the doc/README check it in and move it up +##Work on the doc/quickstart_guide.xml and MOM_practice.xml +##Generate the html and pdf from xml +#/home/nnz/bin/mkdocbk quickstart_guide.xml +#/home/nnz/bin/mkdocbk MOM_practice.xml +#Run Seth's tool to produce .html files for time_manager.html field_manager.html diag_manager.html mpp.html mpp_io.html coupler_main.html +#and move them in doc/ +#cvs ci README quickstart_guide.xml quickstart_guide.html MOM_practice.xml MOM_practice.html time_manager.html field_manager.html diag_manager.html mpp.html mpp_io.html coupler_main.html +#mv README ../ diff --git a/exp/FMS_compile.csh b/exp/FMS_compile.csh deleted file mode 100644 index 5465fd0dee..0000000000 --- a/exp/FMS_compile.csh +++ /dev/null @@ -1,108 +0,0 @@ -# Build the shared FMS component library -# The list of source files that should be compiled for this component. - -set pathnames_shared = $code_dir/path_names_shared # path to file containing list of source paths - -cat > $pathnames_shared < 1 @@ -73,94 +70,769 @@ source $root/bin/environs.$platform # environment variables and loadable module cc -O -o $mppnccombine -I/usr/local/include -L/usr/local/lib $code_dir/postprocessing/mppnccombine/mppnccombine.c -lnetcdf endif -set mkmf_lib = "$mkmf -f -m Makefile -a $code_dir -t $mkmfTemplate" -set lib_include_dirs = "$root/include $code_dir/shared/include $code_dir/shared/mpp/include" -source ./FMS_compile.csh +# Build the shared FMS component library +# The list of source files that should be compiled for this component. + +set pathnames_shared = $code_dir/path_names_shared # path to file containing list of source paths + +cat > $pathnames_shared < $pathnames_atmos_param < $pathnames_atmos_fv < $pathnames_land_lad < $pathnames_land_lad2 < $pathnames_atmos_bg < 1 +#NOTE: On some platforms you may need to specify the location for netcdf.h and libnetcdf.a +# by modifying the following -I and -L + if ( ! -f $mppnccombine ) then + cc -O -o $mppnccombine -I/usr/local/include -L/usr/local/lib $code_dir/postprocessing/mppnccombine/mppnccombine.c -lnetcdf + endif + + + +# The list of source files that should be compiled for this experiment. +cat > $pathnames < 1) Then - Time_step = Time_next - Time - call diag_send_complete(Time_step) - endif - - call physics_driver_up_endts(1, 1) !Note that these arguments are not used yet. call fv_array_sync() diff --git a/src/atmos_fv_dynamics/driver/solo/atmosphere.F90 b/src/atmos_fv_dynamics/driver/solo/atmosphere.F90 index d87fa88ca2..663337562c 100644 --- a/src/atmos_fv_dynamics/driver/solo/atmosphere.F90 +++ b/src/atmos_fv_dynamics/driver/solo/atmosphere.F90 @@ -79,7 +79,7 @@ module atmosphere_mod !----------------------------------------------------------------------- character(len=128) :: version = '$Id: atmosphere.F90,v 19.0 2012/01/06 20:00:14 fms Exp $' -character(len=128) :: tag = '$Name: siena_201207 $' +character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- !---- private data ---- diff --git a/src/atmos_fv_dynamics/model/fv_arrays.F90 b/src/atmos_fv_dynamics/model/fv_arrays.F90 index d6d4fbdad2..9ce1246636 100644 --- a/src/atmos_fv_dynamics/model/fv_arrays.F90 +++ b/src/atmos_fv_dynamics/model/fv_arrays.F90 @@ -150,7 +150,7 @@ module fv_arrays_mod !MPI communicator for ypelist integer :: commID !PSET - type(mpp_pset_type),save, public :: pset + type(mpp_pset_type), public :: pset public :: fv_arrays_init, fv_arrays_exit, fv_stack_push, & fv_print_chksum, fv_print_chksums, fv_thread_bcast, & diff --git a/src/atmos_fv_dynamics/model/fv_pack.F90 b/src/atmos_fv_dynamics/model/fv_pack.F90 index 2c902c9f06..0a82bb0fdd 100644 --- a/src/atmos_fv_dynamics/model/fv_pack.F90 +++ b/src/atmos_fv_dynamics/model/fv_pack.F90 @@ -169,7 +169,7 @@ module fv_pack character(len=24) :: restart_format = 'native' ! native or netcdf character(len=128) :: version = '$Id: fv_pack.F90 1.1.2.15.2.2' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' #ifndef USE_LIMA diff --git a/src/atmos_fv_dynamics/tools/fv_diagnostics.F90 b/src/atmos_fv_dynamics/tools/fv_diagnostics.F90 index f1ad35eb27..c8e8b9eca3 100644 --- a/src/atmos_fv_dynamics/tools/fv_diagnostics.F90 +++ b/src/atmos_fv_dynamics/tools/fv_diagnostics.F90 @@ -53,7 +53,7 @@ module fv_diagnostics !----------------------------------------------------------------------- character(len=128) :: version = '$Id: fv_diagnostics.F90,v 17.0 2009/07/21 02:53:23 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' contains diff --git a/src/atmos_null/atmos_model.F90 b/src/atmos_null/atmos_model.F90 index d1730a21a7..94076a8bb4 100644 --- a/src/atmos_null/atmos_model.F90 +++ b/src/atmos_null/atmos_model.F90 @@ -185,8 +185,8 @@ module atmos_model_mod !----------------------------------------------------------------------- -character(len=128) :: version = '$Id: atmos_model.F90,v 18.0.2.1.4.1.2.2.4.1 2012/05/31 15:56:39 Niki.Zadeh Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_model.F90,v 20.0 2013/12/13 23:08:53 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !---- atmos_model_nml integer :: layout(2) @@ -395,7 +395,7 @@ subroutine atmos_model_init (Atmos, Time_init, Time, Time_step) allocate ( glat(nlon, nlat)) allocate ( Atmos%lon_bnd(ie-is+2,je-js+2) ) allocate ( Atmos%lat_bnd(ie-is+2,je-js+2) ) -allocate ( area(ie-is+2,je-js+2) ) +allocate ( area(ie-is+1,je-js+1) ) allocate(tile_ids(mpp_get_current_ntile(Atmos%domain))) tile_ids = mpp_get_tile_id(Atmos%domain) diff --git a/src/atmos_null/atmos_tracer_driver.F90 b/src/atmos_null/atmos_tracer_driver.F90 index a0d228fb20..e5099a0b78 100644 --- a/src/atmos_null/atmos_tracer_driver.F90 +++ b/src/atmos_null/atmos_tracer_driver.F90 @@ -112,7 +112,7 @@ module atmos_tracer_driver_mod !---- version number ----- character(len=128) :: version = '$Id: atmos_tracer_driver.F90,v 15.0 2007/08/14 03:52:31 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains diff --git a/src/atmos_param/betts_miller/betts_miller.F90 b/src/atmos_param/betts_miller/betts_miller.F90 index 0380728d74..110c1cc8fd 100644 --- a/src/atmos_param/betts_miller/betts_miller.F90 +++ b/src/atmos_param/betts_miller/betts_miller.F90 @@ -26,7 +26,7 @@ module betts_miller_mod ! ---- version number ---- character(len=128) :: version = '$Id: betts_miller.F90,v 19.0 2012/01/06 20:01:31 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- ! ---- local/private data ---- diff --git a/src/atmos_param/betts_miller/bm_massflux.F90 b/src/atmos_param/betts_miller/bm_massflux.F90 index 2b6993a20d..fa2bfe7146 100644 --- a/src/atmos_param/betts_miller/bm_massflux.F90 +++ b/src/atmos_param/betts_miller/bm_massflux.F90 @@ -20,7 +20,7 @@ module bm_massflux_mod ! ---- version number ---- character(len=128) :: version = '$Id: bm_massflux.F90,v 19.0 2012/01/06 20:01:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- ! ---- local/private data ---- diff --git a/src/atmos_param/betts_miller/bm_omp.F90 b/src/atmos_param/betts_miller/bm_omp.F90 index fb0ac7ed3a..525a26c54c 100644 --- a/src/atmos_param/betts_miller/bm_omp.F90 +++ b/src/atmos_param/betts_miller/bm_omp.F90 @@ -22,7 +22,7 @@ module bm_omp_mod ! ---- version number ---- character(len=128) :: version = '$Id: bm_omp.F90,v 19.0 2012/01/06 20:01:35 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- ! ---- local/private data ---- diff --git a/src/atmos_param/cg_drag/cg_drag.F90 b/src/atmos_param/cg_drag/cg_drag.F90 index 6e81f96b63..4ed5ccd94a 100644 --- a/src/atmos_param/cg_drag/cg_drag.F90 +++ b/src/atmos_param/cg_drag/cg_drag.F90 @@ -38,8 +38,8 @@ module cg_drag_mod !----------- ****** VERSION NUMBER ******* --------------------------- -character(len=128) :: version = '$Id: cg_drag.F90,v 19.0 2012/01/06 20:01:37 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: cg_drag.F90,v 20.0 2013/12/13 23:09:00 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' @@ -368,8 +368,8 @@ subroutine cg_drag_init (lonb, latb, pref, Time, axes) end do do j=1,jdf - lat(:,j)= 0.5*( latb(:,j+1)+latb(:,j) ) do i=1,idf + lat(i,j)= 0.5*( latb(i,j+1)+latb(i,j) ) source_level(i,j) = (kmax + 1) - ((kmax + 1 - & klevel_of_source)*cos(lat(i,j)) + 0.5) source_amp(i,j) = Bt_0 + & diff --git a/src/atmos_param/cg_drag/null/cg_drag.F90 b/src/atmos_param/cg_drag/null/cg_drag.F90 deleted file mode 100644 index 9977a16d84..0000000000 --- a/src/atmos_param/cg_drag/null/cg_drag.F90 +++ /dev/null @@ -1,204 +0,0 @@ - module cg_drag_mod - -use fms_mod, only: fms_init, mpp_pe, mpp_root_pe, & - file_exist, check_nml_error, & - error_mesg, FATAL, WARNING, NOTE, & - close_file, open_namelist_file, & - stdlog, write_version_number, & - open_restart_file -use time_manager_mod, only: time_manager_init, time_type -use diag_manager_mod, only: diag_manager_init, & - register_diag_field, send_data -use constants_mod, only: constants_init, PI, RDGAS, GRAV, CP_AIR -use column_diagnostics_mod, only: column_diagnostics_init, & - initialize_diagnostic_columns, & - column_diagnostics_header, & - close_column_diagnostics_units - -!------------------------------------------------------------------- - -implicit none -private - -!--------------------------------------------------------------------- -! cg_drag_mod computes the convective gravity wave forcing on -! the zonal flow. the parameterization is described in Alexander and -! Dunkerton [JAS, 15 December 1999]. -!-------------------------------------------------------------------- - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - -character(len=128) :: version = '$Id: cg_drag.F90,v 18.0 2010/03/02 23:28:42 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public cg_drag_init, cg_drag_calc, cg_drag_end, cg_drag_restart, & - cg_drag_time_vary, cg_drag_endts - - -logical :: module_is_initialized=.false. - -!------------------------------------------------------------------- -!------------------------------------------------------------------- - - - - contains - -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! -! PUBLIC SUBROUTINES -! -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -!#################################################################### - -subroutine cg_drag_init (lonb, latb, pref, Time, axes) - -!------------------------------------------------------------------- -! cg_drag_init is the constructor for cg_drag_mod. -!------------------------------------------------------------------- - -!------------------------------------------------------------------- -real, dimension(:,:), intent(in) :: lonb, latb -real, dimension(:), intent(in) :: pref -integer, dimension(4), intent(in) :: axes -type(time_type), intent(in) :: Time -!------------------------------------------------------------------- - -!------------------------------------------------------------------- -! intent(in) variables: -! -! lonb array of model longitudes on cell boundaries [radians] -! latb array of model latitudes at cell boundaries [radians] -! pref array of reference pressures at full levels (plus -! surface value at nlev+1), based on 1013.25hPa pstar -! [ Pa ] -! Time current time (time_type) -! axes data axes for diagnostics -! -!------------------------------------------------------------------ - - -!--------------------------------------------------------------------- -! write version number and namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - - -!--------------------------------------------------------------------- -! mark the module as initialized. -!--------------------------------------------------------------------- - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('cg_drag_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cg_drag_init - - - -!#################################################################### - -subroutine cg_drag_calc (is, js, lat, pfull, zfull, temp, uuu, vvv, & - Time, delt, gwfcng_u, gwfcng_v) - -!-------------------------------------------------------------------- -! cg_drag_calc defines the arrays needed to calculate the convective -! gravity wave forcing, calls gwfc to calculate the forcing, returns -! the desired output fields, and saves the values for later retrieval -! if they are not calculated on every timestep. -! -!--------------------------------------------------------------------- - -!--------------------------------------------------------------------- -integer, intent(in) :: is, js -real, dimension(:,:), intent(in) :: lat -real, dimension(:,:,:), intent(in) :: pfull, zfull, temp, uuu, vvv -type(time_type), intent(in) :: Time -real , intent(in) :: delt -real, dimension(:,:,:), intent(out) :: gwfcng_u, gwfcng_v - -!------------------------------------------------------------------- -! intent(in) variables: -! -! is,js starting subdomain i,j indices of data in -! the physics_window being integrated -! lat array of model latitudes at cell boundaries [radians] -! pfull pressure at model full levels [ Pa ] -! zfull height at model full levels [ m ] -! temp temperature at model levels [ deg K ] -! uuu zonal wind [ m/s ] -! Time current time, needed for diagnostics [ time_type ] -! delt physics time step [ s ] -! -! intent(out) variables: -! -! gwfcng time tendency for u eqn due to gravity-wave forcing -! [ m/s^2 ] -! -!------------------------------------------------------------------- - - call error_mesg('cg_drag_calc', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cg_drag_calc - - - -!################################################################### - -subroutine cg_drag_end - -!-------------------------------------------------------------------- -! cg_drag_end is the destructor for cg_drag_mod. -!-------------------------------------------------------------------- - - -!--------------------------------------------------------------------- -! mark the module as uninitialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('cg_drag_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cg_drag_end - - -!#################################################################### -!dummy interface -subroutine cg_drag_restart(timestamp) - character(len=*), intent(in), optional :: timestamp - -end subroutine cg_drag_restart - - -!#################################################################### -!dummy interface -subroutine cg_drag_time_vary (delt) -real , intent(in) :: delt - -end subroutine cg_drag_time_vary - -!#################################################################### -!dummy interface -subroutine cg_drag_endts - -end subroutine cg_drag_endts - -end module cg_drag_mod - - diff --git a/src/atmos_param/cloud_generator/betaDistribution.F90 b/src/atmos_param/cloud_generator/betaDistribution.F90 index 8c5a80fe33..c1cbefc472 100644 --- a/src/atmos_param/cloud_generator/betaDistribution.F90 +++ b/src/atmos_param/cloud_generator/betaDistribution.F90 @@ -18,7 +18,7 @@ module beta_dist_mod ! The arrays bounds are from 0 to nSteps + 1, just in case we draw exactly 0 or 1. ! character(len=128) :: version = '$Id: betaDistribution.F90,v 16.0 2008/07/30 22:06:18 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_param/cloud_generator/cloud_generator.F90 b/src/atmos_param/cloud_generator/cloud_generator.F90 index 295d071bc8..424ff9798c 100644 --- a/src/atmos_param/cloud_generator/cloud_generator.F90 +++ b/src/atmos_param/cloud_generator/cloud_generator.F90 @@ -39,7 +39,7 @@ module cloud_generator_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: cloud_generator.F90,v 19.0 2012/01/06 20:02:09 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- diff --git a/src/atmos_param/cloud_generator/null/betaDistribution.F90 b/src/atmos_param/cloud_generator/null/betaDistribution.F90 deleted file mode 100644 index 0ce7fe1583..0000000000 --- a/src/atmos_param/cloud_generator/null/betaDistribution.F90 +++ /dev/null @@ -1,213 +0,0 @@ -module beta_dist_mod - use fms_mod,only: error_mesg, FATAL, WARNING - - implicit none - private - - ! Provide values of the beta distribtion as a function of the CDF (the incomplete beta - ! function). Returns a value as a function of two beta distribution parameters p, q - ! (here they must be integers) and the value x of the CDF between 0 and 1. - - ! In this version we build tables using the NAG library function nag_beta_deviate, then - ! look up values from a table. The table can be built at run time or read from - ! a file (this version uses netcdf format). - - ! betaDeviateTable is a 3D table with dimensions - ! x, p, q. The range of P and Q are specified when the tables are built. - ! The arrays bounds are from 0 to nSteps + 1, just in case we draw exactly 0 or 1. - ! - character(len=128) :: version = '$Id: betaDistribution.F90,v 13.0 2006/03/28 21:07:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - logical :: module_is_initialized = .false. - - - interface beta_deviate - module procedure betaDeviate_s, betaDeviate_1D, betaDeviate_2D, & - betaDeviate_3D, betaDeviate_4D - end interface ! betaDeviate - - interface incomplete_beta - module procedure incompleteBeta_s, incompleteBeta_1D, incompleteBeta_2D, & - incompleteBeta_3D, incompleteBeta_4D - end interface ! incompleteBeta - - public :: beta_dist_init, beta_deviate, incomplete_beta, beta_dist_end -contains - ! --------------------------------------------------------- - subroutine test_beta - - integer :: i - real :: x, inc_x, inv_inc_x, inv_x, inc_inv_x - - end subroutine test_beta - ! --------------------------------------------------------- - subroutine beta_dist_init - ! Initialize the tables containing the incomplete beta function - ! and its inverse (beta deviate). - ! If the table parameters are supplied we use the NAG libraries to - ! compute a new table and write it to a file; if just - ! the file name is supplied we read the table from the file. - ! - - call error_mesg('beta_dist_mod', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine beta_dist_init -!--------------------------------------------------------------------- - subroutine beta_dist_end - - !--------------------------------------------------------------------- - ! be sure module has been initialized. - !--------------------------------------------------------------------- - call error_mesg('beta_dist_mod', & - 'This module is not supported as part of the public release', WARNING) - - end subroutine beta_dist_end -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! -! SEMI-PRIVATE PROCEDURES -! Not accessed directly but through generic interface -! -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! --------------------------------------------------------- -! Functions to look up the beta deviate (inverse incomplete beta distribution) -! from a table -! Overloaded, to allow for input arguments from 0 to 4 dimensions -! It might be more efficient to loop over dimensions higher than 1 to -! avoid using reshape. -! --------------------------------------------------------- - function betaDeviate_s(x, p, q) result (betaDeviate) - real, intent( in) :: x - integer, intent( in) :: p, q - real :: betaDeviate - - call error_mesg('betaDeviate', & - 'This module is not supported as part of the public release', FATAL) - - betaDeviate = 0.0 - end function betaDeviate_s -! --------------------------------------------------------- - function betaDeviate_1D(x, p, q) result (betaDeviate) - real, dimension(:), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x)) :: betaDeviate - - call error_mesg('betaDeviate', & - 'This module is not supported as part of the public release', FATAL) - - betaDeviate(:) = 0.0 - - end function betaDeviate_1D -! --------------------------------------------------------- - function betaDeviate_2D(x, p, q) result (betaDeviate) - real, dimension(:, :), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x, 1), & - size(x, 2)) :: betaDeviate - - call error_mesg('betaDeviate', & - 'This module is not supported as part of the public release', FATAL) - - betaDeviate(:, :) = 0.0 - - end function betaDeviate_2D -! --------------------------------------------------------- - function betaDeviate_3D(x, p, q) result (betaDeviate) - real, dimension(:, :, :), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x, 1), & - size(x, 2), & - size(x, 3)) :: betaDeviate - - call error_mesg('betaDeviate', & - 'This module is not supported as part of the public release', FATAL) - - betaDeviate(:, :, :) = 0.0 - - end function betaDeviate_3D -! --------------------------------------------------------- - function betaDeviate_4D(x, p, q) result (betaDeviate) - real, dimension(:, :, :, :), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x, 1), size(x, 2), & - size(x, 3), size(x, 4)) :: betaDeviate - - call error_mesg('betaDeviate', & - 'This module is not supported as part of the public release', FATAL) - - betaDeviate(:, :, :, :) = 0.0 - - end function betaDeviate_4D -! --------------------------------------------------------- -! --------------------------------------------------------- -! Functions to look up the incomplete beta function from a table. -! Overloaded, to allow for input arguments from 0 to 4 dimensions -! It might be more efficient to loop over dimensions higher than 1 to -! avoid using reshape. -! --------------------------------------------------------- - function incompleteBeta_s(x, p, q) result (incompleteBeta) - real, intent( in) :: x - integer, intent( in) :: p, q - real :: incompleteBeta - - call error_mesg('incompleteBeta', & - 'This module is not supported as part of the public release', FATAL) - - incompleteBeta = 0.0 - - end function incompleteBeta_s -! --------------------------------------------------------- - function incompleteBeta_1D(x, p, q) result (incompleteBeta) - real, dimension(:), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x)) :: incompleteBeta - - call error_mesg('incompleteBeta', & - 'This module is not supported as part of the public release', FATAL) - - incompleteBeta(:) = 0.0 - - end function incompleteBeta_1D -! --------------------------------------------------------- - function incompleteBeta_2D(x, p, q) result (incompleteBeta) - real, dimension(:, :), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x, 1), & - size(x, 2)) :: incompleteBeta - - call error_mesg('incompleteBeta', & - 'This module is not supported as part of the public release', FATAL) - - incompleteBeta(:, :) = 0.0 - - end function incompleteBeta_2D -! --------------------------------------------------------- - function incompleteBeta_3D(x, p, q) result (incompleteBeta) - real, dimension(:, :, :), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x, 1), & - size(x, 2), & - size(x, 3)) :: incompleteBeta - - call error_mesg('incompleteBeta', & - 'This module is not supported as part of the public release', FATAL) - - incompleteBeta(:, :, :) = 0.0 - end function incompleteBeta_3D -! --------------------------------------------------------- - function incompleteBeta_4D(x, p, q) result (incompleteBeta) - real, dimension(:, :, :, :), intent( in) :: x - integer, intent( in) :: p, q - real, dimension(size(x, 1), size(x, 2), & - size(x, 3), size(x, 4)) :: incompleteBeta - - call error_mesg('incompleteBeta', & - 'This module is not supported as part of the public release', FATAL) - - incompleteBeta(:, :, :, :) = 0.0 - - end function incompleteBeta_4D -! --------------------------------------------------------- -end module beta_dist_mod - diff --git a/src/atmos_param/cloud_generator/null/cloud_generator.F90 b/src/atmos_param/cloud_generator/null/cloud_generator.F90 deleted file mode 100644 index a14f78d3b3..0000000000 --- a/src/atmos_param/cloud_generator/null/cloud_generator.F90 +++ /dev/null @@ -1,117 +0,0 @@ -module cloud_generator_mod - -USE fms_mod, ONLY: error_mesg, FATAL, NOTE, write_version_number - -use random_numbers_mod, only: randomNumberStream -!-------------------------------------------------------------------- - implicit none - private - -!--------------------------------------------------------------------- -!----------- version number for this module -------------------------- - -character(len=128) :: version = '$Id: cloud_generator.F90,v 19.0 2012/01/06 20:02:11 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - -!--------------------------------------------------------------------- - public :: cloud_generator_init, & - cloud_generator_end, & - generate_stochastic_clouds, & - do_cloud_generator, & - compute_overlap_weighting - -!--------------------------------------------------------------------- -!---- private data ------- - -logical :: module_is_initialized = .false. ! module is initialized ? - -!---------------------------------------------------------------------- - - contains - -!###################################################################### -subroutine cloud_generator_init - - -!--------------------------------------------------------------------- -! cloud_generator_init is the constructor for -! cloud_generator_mod. - -!---------------------------------------------------------------------- - - if (.not. module_is_initialized) then - call write_version_number ('Null module: '//version, tagname) - module_is_initialized = .true. - end if - - call error_mesg('subroutine cloud_generator_init in cloud_generator_mod', & - 'This module is not supported as part of the public release', NOTE) - -end subroutine cloud_generator_init -!---------------------------------------------------------------------- -subroutine generate_stochastic_clouds(streams, ql, qi, qa, qn, qni, & - overlap, pFull, pHalf, & - temperature, qv,& - cld_thickness, & - ql_stoch, qi_stoch, qa_stoch, & - qn_stoch, qni_stoch) -!-------------------------------------------------------------------- -! intent(in) variables: -! - type(randomNumberStream), & - dimension(:, :), intent(inout) :: streams - ! Dimension nx, ny, nz - real, dimension(:, :, :), intent( in) :: ql, qi, qa, qn, qni - integer, optional, & - intent( in) :: overlap - real, dimension(:, :, :), optional, & - intent( in) :: pFull, temperature, qv - ! Dimension nx, ny, nz+1 - real, dimension(:, :, :), optional, & - intent( in) :: pHalf - ! Dimension nx, ny, nz, nCol = nBands - integer, dimension(:, :, :, :), intent(out) :: cld_thickness - real, dimension(:, :, :, :), intent(out) :: ql_stoch, qi_stoch, & - qa_stoch, qn_stoch, & - qni_stoch - ! --------------------------------------------------------- - - call error_mesg('subroutine generate_stochastic_clouds in cloud_generator_mod', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine generate_stochastic_clouds -!---------------------------------------------------------------------- - -function compute_overlap_weighting(qaPlus, qaMinus, pPlus, pMinus) result(weighting) - real, dimension(:, :), intent( in) :: qaPlus, qaMinus, pPlus, pMinus - real, dimension(size(pPlus,1),size(pPlus,2)) :: weighting - - call error_mesg("function compute_overlap_weighting in cloud_generator_mod", & - 'This module is not supported as part of the public release', FATAL) - - weighting = 0. ! This line of code exists only to prevent compiler warnings - -end function compute_overlap_weighting - -! --------------------------------------------------------- - - subroutine cloud_generator_end - - call error_mesg ('subroutine cloud_generator_end in cloud_generator_mod', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine cloud_generator_end -!-------------------------------------------------------------------- - - !-------------------------------------------------------------------- - ! - ! Function to report if the cloud generator is being used. - ! - function do_cloud_generator() - logical :: do_cloud_generator - - do_cloud_generator = .false. - end function do_cloud_generator - !-------------------------------------------------------------------- - -end module cloud_generator_mod diff --git a/src/atmos_param/cloud_obs/cloud_obs.F90 b/src/atmos_param/cloud_obs/cloud_obs.F90 index f0cea31dbe..8b3c8ea98c 100644 --- a/src/atmos_param/cloud_obs/cloud_obs.F90 +++ b/src/atmos_param/cloud_obs/cloud_obs.F90 @@ -29,7 +29,7 @@ module cloud_obs_mod ! ---------- private data ------------ character(len=128) :: version = '$Id: cloud_obs.F90,v 19.0 2012/01/06 20:02:13 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' real, allocatable, dimension(:,:,:) :: clda,cldb real, allocatable, dimension(:) :: londat,latdat diff --git a/src/atmos_param/cloud_obs/null/cloud_obs.F90 b/src/atmos_param/cloud_obs/null/cloud_obs.F90 deleted file mode 100644 index 45f7982d73..0000000000 --- a/src/atmos_param/cloud_obs/null/cloud_obs.F90 +++ /dev/null @@ -1,113 +0,0 @@ - - module cloud_obs_mod - -!----------------------------------------------------------------------- -! -! sets up observed (climatological) clouds -! -!----------------------------------------------------------------------- - -use horiz_interp_mod, only: horiz_interp -use fms_mod, only: file_exist, error_mesg, FATAL, & - open_namelist_file, close_file, & - check_nml_error, mpp_pe, mpp_root_pe, & - write_version_number, stdlog -use time_manager_mod, only: time_type, get_date -use time_interp_mod, only: time_interp - -implicit none -private - -!---------- public interfaces ---------- - -public cloud_obs, cloud_obs_init, cloud_obs_end - -!----------------------------------------------------------------------- -! ---------- private data ------------ - - character(len=128) :: version = '$Id: cloud_obs.F90,v 15.0 2007/08/14 03:52:46 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - logical :: module_is_initialized = .false. - -!----------------------------------------------------------------------- - -contains - -!####################################################################### - -subroutine cloud_obs ( is, js, Time, cldamt ) - -!----------------------------------------------------------------------- -! routine that reads monthly records of climatological -! isccp cloud amount and then linearly interpolates between them -!----------------------------------------------------------------------- -! input -! ----- -! is, js starting i,j indices (dimension(2)) -! Time current time (time_type) -! -! output -! ------ -! cldamt cloud amount data on horizontal grid, -! dimensioned ix x jx x 3, for high,med, & low clouds. -!----------------------------------------------------------------------- - integer, intent(in) :: is, js -type(time_type), intent(in) :: Time - real, intent(out), dimension(:,:,:) :: cldamt -!----------------------------------------------------------------------- - - call error_mesg('cloud_obs', & - 'This module is not supported as part of the public release', FATAL) - - -!----------------------------------------------------------------------- - - end subroutine cloud_obs - -!####################################################################### - - subroutine cloud_obs_init (lonb,latb) - -!----------------------------------------------------------------------- -! lonb = longitude in radians of the grid box edges -! latb = longitude in radians of the grid box edges -!----------------------------------------------------------------------- - real, intent(in), dimension(:,:) :: lonb,latb -!----------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! write version number and namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - - -!--------------------------------------------------------------------- -! mark the module as initialized. -!--------------------------------------------------------------------- - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('cloud_obs_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine cloud_obs_init - -!####################################################################### - - subroutine cloud_obs_end - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('cloud_obs_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine cloud_obs_end - -!####################################################################### - -end module cloud_obs_mod - diff --git a/src/atmos_param/cloud_rad/cloud_rad.F90 b/src/atmos_param/cloud_rad/cloud_rad.F90 index 2b4c0d9c50..c919dcf23a 100644 --- a/src/atmos_param/cloud_rad/cloud_rad.F90 +++ b/src/atmos_param/cloud_rad/cloud_rad.F90 @@ -227,7 +227,7 @@ module cloud_rad_mod use constants_mod, only: RDGAS, GRAV, TFREEZE, DENS_H2O, & constants_init, pi use gamma_mg_mod, ONLY : gamma_mg, gamma_mg_init, gamma_mg_end -use mg_const_mod, ONLY : mg_const_init, rhow, qcvar, di_mg, ci_mg +use mg_const_mod, ONLY : mg_const_init, rhow, di_mg, ci_mg use diag_manager_mod, only: diag_manager_init, & register_diag_field, send_data use time_manager_mod, only: time_type, time_manager_init @@ -254,8 +254,8 @@ module cloud_rad_mod !--------------------------------------------------------------------- !------------ version number for this module ------------------------- -character(len=128) :: version = '$Id: cloud_rad.F90,v 19.0 2012/01/06 20:02:15 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: cloud_rad.F90,v 20.0 2013/12/13 23:09:10 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !---------------------------------------------------------------------- @@ -461,6 +461,8 @@ module cloud_rad_mod ! that both strat_cloud and cloud_rad have the exact same values ! for these parameters. +real :: qcvar + !---------------------------------------------------------------------- ! diagnostics variables. !---------------------------------------------------------------------- @@ -560,7 +562,8 @@ module cloud_rad_mod ! ! subroutine cloud_rad_init (axes, Time, qmin_in, N_land_in, N_ocean_in, & - prog_droplet_in, prog_ice_num_in, overlap_out) + prog_droplet_in, prog_ice_num_in, qcvar_in, & + overlap_out) !-------------------------------------------------------------------- ! cloud_rad_init is the constructor for cloud_rad_mod. @@ -628,6 +631,7 @@ subroutine cloud_rad_init (axes, Time, qmin_in, N_land_in, N_ocean_in, & N_ocean_in LOGICAL, INTENT (IN), OPTIONAL :: prog_droplet_in LOGICAL, INTENT (IN), OPTIONAL :: prog_ice_num_in +REAL , INTENT (IN), OPTIONAL :: qcvar_in INTEGER, INTENT (OUT), OPTIONAL :: overlap_out ! Internal variables @@ -719,6 +723,9 @@ subroutine cloud_rad_init (axes, Time, qmin_in, N_land_in, N_ocean_in, & if (present(prog_ice_num_in)) then do_ice_num = prog_ice_num_in end if + if (present(qcvar_in)) then + qcvar = qcvar_in + end if call mg_const_init call gamma_mg_init diff --git a/src/atmos_param/cloud_zonal/cloud_zonal.F90 b/src/atmos_param/cloud_zonal/cloud_zonal.F90 index fea762e46c..53750b2f91 100644 --- a/src/atmos_param/cloud_zonal/cloud_zonal.F90 +++ b/src/atmos_param/cloud_zonal/cloud_zonal.F90 @@ -26,7 +26,7 @@ module cloud_zonal_mod real :: rad2deg character(len=128) :: version = '$Id: cloud_zonal.F90,v 13.0 2006/03/28 21:07:56 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/cloud_zonal/null/cloud_zonal.F90 b/src/atmos_param/cloud_zonal/null/cloud_zonal.F90 deleted file mode 100644 index 9c4c866aec..0000000000 --- a/src/atmos_param/cloud_zonal/null/cloud_zonal.F90 +++ /dev/null @@ -1,153 +0,0 @@ - -module cloud_zonal_mod - -!======================================================================= -! -! determines zonal cloud amounts and model levels. -! -!======================================================================= - -use time_manager_mod, only: time_type -use time_interp_mod, only: fraction_of_year -use fms_mod, only: error_mesg, FATAL, open_namelist_file, & - close_file, mpp_pe, mpp_root_pe, & - write_version_number - -implicit none -private - -public cloud_zonal, cloud_zonal_init, cloud_zonal_end, getcld - -!------------------- private data used by this module ------------------ - - character(len=128) :: version = '$Id: cloud_zonal.F90,v 10.0 2003/10/24 22:00:25 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized=.false. - -!----------------------------------------------------------------------- - -contains - -!####################################################################### - -subroutine cloud_zonal_init (season) - -!----------------------------------------------------------------------- -! -! initialization routine for retrieval of -! zonal cloud amounts and level indices. -! -! input argument -! -------------- -! -! season scalar integer between 1-5 -! where 1-4 uses fixed data (1=winter, 2=spring, etc.) -! season=5 is seasonal varying clouds -! - - integer, intent(in) :: season - - - -!--------------------------------------------------------------------- -! write version number and namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - - -!--------------------------------------------------------------------- -! mark the module as initialized. -!--------------------------------------------------------------------- - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('cloud_zonal_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cloud_zonal_init - -!####################################################################### - -subroutine getcld (time, lat, phalf, ktopsw, kbtmsw, cldamt) - -!----------------------------------------------------------------------- -! -! routine for retrieval of zonal cloud amounts and level indices. -! -! input arguments -! -------------- -! -! time time of year (time_type) -! lat latitudes in radians, dimensioned by ncol -! phalf pressure at model layer interfaces, -! dimensioned mxcol x nlev, although only -! the first ncol points of the first dimension -! are processed -! -! output arguments -! ---------------- -! -! (all output arguments are dimensioned ncol x 3; the second -! dimension represents high, middle, and low clouds) -! -! ktopsw model layer interface indices for cloud tops -! kbtmsw model layer interface indices for cloud bottoms -! cldamt fractional cloud amounts -! - -type(time_type), intent(in) :: time -real, intent(in) :: lat(:,:), phalf(:,:,:) -integer, intent(out) :: ktopsw(:,:,:),kbtmsw(:,:,:) -real , intent(out), optional :: cldamt(:,:,:) - -!----------------------------------------------------------------------- - - call error_mesg('getcld', & - 'This module is not supported as part of the public release', FATAL) - -!----------------------------------------------------------------------- - -end subroutine getcld - -!####################################################################### - - -subroutine cloud_zonal (time, lat, phalf, & - nclds, ktopsw, kbtmsw, ktoplw, kbtmlw, & - cldamt, cuvrf, cirrf, cirab, emcld) - -!----------------------------------------------------------------------- -type(time_type), intent(in) :: time - real, intent(in) :: lat(:,:), phalf(:,:,:) -integer, intent(out), dimension(:,:) :: nclds -integer, intent(out), dimension(:,:,:) :: ktopsw,kbtmsw,ktoplw,kbtmlw - real, intent(out), dimension(:,:,:) :: cldamt,cuvrf,cirrf,cirab,emcld -!----------------------------------------------------------------------- - - call error_mesg('cloud_zonal', & - 'This module is not supported as part of the public release', FATAL) - -!----------------------------------------------------------------------- - -end subroutine cloud_zonal - -!####################################################################### - - -subroutine cloud_zonal_end - - module_is_initialized=.false. - -!----------------------------------------------------------------------- - - call error_mesg('cloud_zonal_end', & - 'This module is not supported as part of the public release', FATAL) - - -end subroutine cloud_zonal_end - -!####################################################################### - -end module cloud_zonal_mod - diff --git a/src/atmos_param/clouds/clouds.F90 b/src/atmos_param/clouds/clouds.F90 index 29395895de..cb9ead138e 100644 --- a/src/atmos_param/clouds/clouds.F90 +++ b/src/atmos_param/clouds/clouds.F90 @@ -33,7 +33,7 @@ module clouds_mod !----------------------------------------------------------------------- !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: clouds.F90,v 19.0 2012/01/06 20:02:48 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- !----------------------------------------------------------------------- ! note: the fels-schwarzkopf radiation code permits bi-spectral diff --git a/src/atmos_param/clouds/null/clouds.F90 b/src/atmos_param/clouds/null/clouds.F90 deleted file mode 100644 index 3915f0e064..0000000000 --- a/src/atmos_param/clouds/null/clouds.F90 +++ /dev/null @@ -1,117 +0,0 @@ - - module clouds_mod - -!======================================================================= -! -! determines cloud properties necessary for -! fels-schwartzkopf radiation -! -!======================================================================= - -use cloud_rad_mod, only: cloud_rad_init, cloud_summary -use cloud_zonal_mod, only: cloud_zonal -use cloud_obs_mod, only: cloud_obs, cloud_obs_init -use time_manager_mod, only: time_type -use fms_mod, only: error_mesg, FATAL, file_exist, & - check_nml_error, open_namelist_file, & - mpp_pe, mpp_root_pe, close_file, & - write_version_number, stdlog -use rh_clouds_mod, only: do_rh_clouds, rh_clouds, rh_clouds_avg -use strat_cloud_mod, only: do_strat_cloud, strat_cloud_avg -use diag_cloud_mod, only: do_diag_cloud, diag_cloud_driver, & - diag_cloud_avg -use diag_manager_mod, only: register_diag_field, send_data -use isccp_clouds_mod, only: isccp_clouds_init - -implicit none -private - -!------------------- public interfaces --------------------------------- - -public clouds, clouds_init, clouds_end - -!----------------------------------------------------------------------- -!--------------------- version number ---------------------------------- - character(len=128) :: version = '$Id: clouds.F90,v 15.0 2007/08/14 03:52:54 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' -!----------------------------------------------------------------------- - - logical :: module_is_initialized=.false. - -!----------------------------------------------------------------------- - -contains - -!####################################################################### - -subroutine clouds (is, js, clear_sky, Time, Time_diag, lat, & - land, tsfc, pfull, phalf, t, q, cosz, & - nclds, ktopsw, kbtmsw, ktoplw, kbtmlw, & - cldamt, cuvrf, cirrf, cirab, emcld, mask, kbot) - -!----------------------------------------------------------------------- - integer, intent(in) :: is, js - logical, intent(in) :: clear_sky -type(time_type), intent(in) :: Time, Time_diag - - real, intent(in), dimension(:,:) :: lat - real, intent(in), dimension(:,:) :: land,tsfc - real, intent(in), dimension(:,:,:) :: pfull,phalf,t,q - real, intent(in), dimension(:,:) :: cosz -integer, intent(out), dimension(:,:) :: nclds -integer, intent(out), dimension(:,:,:) :: ktopsw,kbtmsw,ktoplw,kbtmlw - real, intent(out), dimension(:,:,:) :: cldamt,cuvrf,cirrf,cirab,emcld - real, intent(in), dimension(:,:,:),optional :: mask -integer, intent(in), dimension(:,:), optional :: kbot -!----------------------------------------------------------------------- - - call error_mesg('clouds', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine clouds - -!####################################################################### - - subroutine clouds_init ( lonb, latb, axes, Time ) - -!----------------------------------------------------------------------- - real, intent(in), dimension(:,:) :: lonb, latb - integer, intent(in), dimension(4) :: axes -type(time_type), intent(in) :: Time - -!----------------------------------------------------------------------- -! write version number and namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - - -!--------------------------------------------------------------------- -! mark the module as initialized. -!--------------------------------------------------------------------- - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('clouds_init', & - 'This module is not supported as part of the public release', FATAL) - - - end subroutine clouds_init - -!####################################################################### - - subroutine clouds_end - -!----------------------------------------------------------------------- - module_is_initialized=.false. -!----------------------------------------------------------------------- - - call error_mesg('clouds_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine clouds_end - -!####################################################################### - -end module clouds_mod - diff --git a/src/atmos_param/clubb/CLUBB_driver_SCM.F90 b/src/atmos_param/clubb/CLUBB_driver_SCM.F90 new file mode 100644 index 0000000000..0f987f7407 --- /dev/null +++ b/src/atmos_param/clubb/CLUBB_driver_SCM.F90 @@ -0,0 +1,129 @@ +module clubb_driver_mod + +! --- Imported from FMS modules --- + +use constants_mod, only: RAD_TO_DEG +use mpp_mod, only: mpp_pe, mpp_root_pe, stdlog, mpp_chksum, & + mpp_clock_id, mpp_clock_begin, mpp_clock_end, & + CLOCK_MODULE_DRIVER +use diag_manager_mod, only: register_diag_field, send_data +use time_manager_mod, only: time_type, get_time, set_time, get_date, & + operator(+), operator(-) +use fms_mod, only: write_version_number, open_file, & + open_namelist_file, check_nml_error, & + file_exist, error_mesg, close_file, & + read_data, write_data, & + mpp_error, FATAL, NOTE +use field_manager_mod, only: MODEL_ATMOS +use tracer_manager_mod, only: get_number_tracers, get_tracer_index, & + get_tracer_names +use rad_utilities_mod, only: aerosol_type +use aer_ccn_act_mod, only: aer_ccn_act_init, aer_ccn_act_end +use aer_ccn_act_k_mod, only: aer_ccn_act_k +use ice_nucl_mod, only: ice_nucl_wpdf_init, ice_nucl_wpdf_end +implicit none +public :: clubb_setup, & + clubb_init, & + clubb, & + clubb_end + +!--------------------- version number ---------------------------------- +character(len=128) :: version = '$Id: CLUBB_driver_SCM.F90,v 1.1.6.2.2.2.2.1 2013/12/17 19:46:01 Niki.Zadeh Exp $' +character(len=128) :: tagname = '$Name: nullify_rab_nnz $' + +contains + +! NULL routines return error if called but not compiled for clubb + subroutine clubb(is, ie, js, je, lon, lat, & + Time_next, & + dtmain, & + phalf, pfull, zhalf, zfull, omega_avg, & + t, q, r, u, v, & + u_star, b_star, q_star, & + tdt, qdt, rdt, udt, vdt, & + dcond_ls_liquid, dcond_ls_ice, & + Ndrop_act_clubb, Icedrop_act_clubb, & + ndust, rbar_dust, & + diff_t_clubb, & + qcvar_clubb, & + tdt_shf, qdt_lhf , & + Aerosol, mask, & + mc_full, & + conv_frac_clubb, & + convective_humidity_ratio_clubb) + + integer, intent(in) :: is, ie, js, je + real, intent(in), dimension(:,:) :: lon, lat + type(time_type), intent(in) :: Time_next + real, intent(in) :: dtmain + real, intent(in), dimension(:,:,:) :: phalf, pfull, zhalf, zfull, omega_avg + real, intent(in), dimension(:,:,:) :: t, q, u, v + real, intent(inout), dimension(:,:,:,:) :: r + real, intent(in), dimension(:,:) :: u_star, b_star, q_star + real, intent(inout), dimension(:,:,:) :: tdt, qdt, udt, vdt + real, intent(inout), dimension(:,:,:,:) :: rdt + real, intent(out), dimension(:,:,:) :: dcond_ls_liquid + real, intent(out), dimension(:,:,:) :: dcond_ls_ice + real, intent(out), dimension(:,:,:) :: Ndrop_act_clubb + real, intent(out), dimension(:,:,:) :: Icedrop_act_clubb + real, intent(out), dimension(:,:,:) :: ndust, rbar_dust + real, intent(out), dimension(:,:,:) :: diff_t_clubb + real, intent(out), optional, dimension(:,:,:) :: qcvar_clubb + type(aerosol_type), intent(in), optional :: Aerosol + real, intent(in), optional, dimension(:,:,:) :: mask + real, intent(in), optional, dimension(:,:,:) :: mc_full + real, intent(in), optional, dimension(:,:,:) :: conv_frac_clubb + real, intent(in), optional, dimension(:,:,:) :: convective_humidity_ratio_clubb + real, intent(in), optional, dimension(:,:) :: tdt_shf, qdt_lhf + + call error_mesg ('clubb_driver_mod', 'Not compiled with -DCLUBB', FATAL) + + end subroutine clubb + + !===================================================================== + !===================================================================== + + subroutine clubb_init(id, jd, kd, lon, lat, axes, Time, phalf ) + + integer, intent(in) :: id, jd, kd + real, dimension(:,:), intent(in) :: lon, lat + integer, dimension(4), intent(in) :: axes + type(time_type), intent(in) :: Time + real, dimension(:,:,:), intent(in) :: phalf + + call error_mesg ('clubb_driver_mod', 'Not compiled with -DCLUBB', FATAL) + + end subroutine clubb_init + !===================================================================== + + !===================================================================== + subroutine clubb_setup(id, jd, phalf) + + !--------------------------------------------------------------------- + ! id, jd input + ! subdomain dimensions + ! + ! phalf input + ! pressure at half levels in pascals + ! [real, dimension(nlon,nlat,nlev+1)] + ! + !--------------------------------------------------------------------- + + ! ----- Calling arguments ----- + + integer, intent(in) :: id, jd + real, dimension(:,:,:), intent(in) :: phalf + + call error_mesg ('clubb_driver_mod', 'Not compiled with -DCLUBB', FATAL) + + end subroutine clubb_setup + !===================================================================== + + !===================================================================== + subroutine clubb_end + + call error_mesg ('clubb_driver_mod', 'Not compiled with -DCLUBB', FATAL) + + end subroutine clubb_end + !===================================================================== +end module clubb_driver_mod diff --git a/src/atmos_param/clubb/MG_microp_3D.F90 b/src/atmos_param/clubb/MG_microp_3D.F90 new file mode 100644 index 0000000000..5a5a9fc6f4 --- /dev/null +++ b/src/atmos_param/clubb/MG_microp_3D.F90 @@ -0,0 +1,76 @@ +module MG_microp_3D_mod + + ! --- external modules --- + + use fms_mod, only : file_exist, open_namelist_file, close_file, & + error_mesg, FATAL, check_nml_error + use time_manager_mod, only : time_type, get_time, set_date + + implicit none + + + ! --- available public interfaces --- + public MG_microp_3D_init, MG_microp_3D, MG_microp_3D_end + +contains + +! NULL routines return error if called but not compiled for clubb +subroutine MG_microp_3D_init(axes,Time,idim,jdim,kdim) + + ! --- calling arguments --- + integer, intent (in) :: axes(4) ! x,y,z,z_half axes types + integer, intent (in) :: idim,jdim,kdim ! dimensions + type(time_type), intent(in) :: Time ! time + call error_mesg('MG_microp_3D_init','Not compiled with -DCLUBB',FATAL) +end subroutine MG_microp_3D_init +!############################################################################## + + +!############################################################################## +subroutine MG_microp_3D( Time, is, ie, js, je, lon, lat, dtcloud, & + pfull3d, phalf3d, zhalf3d, LAND, & + T3d, qv3d, ql3d, qi3d, qa3d, qn3d, qni3d, ahuco3d, & + dcond_ls_liquid, dcond_ls_ice, & + Ndrop_act_CLUBB, Icedrop_act_CLUBB, & + ndust, rbar_dust, & + ST3d, SQ3d, SL3d, SI3d, SA3d, SN3d, SNi3d, & + rain3d, snow3d, surfrain, surfsnow, & + do_clubb, qcvar_clubb, MASK3d, & + lsc_snow, lsc_rain, lsc_snow_size, lsc_rain_size ) + + ! --- calling arguments --- + type(time_type), intent (in) :: Time + integer, intent (in) :: is,ie,js,je + real, intent (in), dimension(:,:) :: lon,lat + real, intent (in) :: dtcloud + real, intent (in), dimension(:,:,:) :: pfull3d,phalf3d + real, intent (in), dimension(:,:,:) :: zhalf3d + real, intent (in), dimension(:,:) :: LAND + real, intent (in), dimension(:,:,:) :: T3d,qv3d,ql3d,qi3d,qa3d,qn3d,qni3d + real, intent (in), dimension(:,:,:) :: ahuco3d + real, intent (in), dimension(:,:,:) :: dcond_ls_liquid,dcond_ls_ice + real, intent (in), dimension(:,:,:) :: Ndrop_act_CLUBB,Icedrop_act_CLUBB + real, intent (in), dimension(:,:,:) :: ndust, rbar_dust + real, intent (out), dimension(:,:,:) :: ST3d,SQ3d,SL3d,SI3d,SA3d,SN3d,SNi3d + real, intent (out), dimension(:,:,:) :: rain3d,snow3d + real, intent (out), dimension(:,:) :: surfrain,surfsnow + + integer, intent (in), optional :: do_clubb + real, intent (in), optional, dimension(:,:,:) :: qcvar_clubb + real, intent (in), optional, dimension(:,:,:) :: MASK3d + real, intent (out), optional, dimension(:,:,:) :: lsc_snow, & + lsc_rain, & + lsc_snow_size, & + lsc_rain_size + call error_mesg('MG_microp_3D','Not compiled with -DCLUBB',FATAL) +end subroutine MG_microp_3D +!############################################################################## + + +!############################################################################## +subroutine MG_microp_3D_end() + call error_mesg('MG_microp_3D_end','Not compiled with -DCLUBB',FATAL) +end subroutine MG_microp_3D_end +!############################################################################## + +end module MG_microp_3D_mod diff --git a/src/atmos_param/cosp/MISR_simulator/MISR_simulator.F b/src/atmos_param/cosp/MISR_simulator/MISR_simulator.F new file mode 100644 index 0000000000..8235386765 --- /dev/null +++ b/src/atmos_param/cosp/MISR_simulator/MISR_simulator.F @@ -0,0 +1,541 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL + +!--------------------------------------------------------------------- +!------------ FMS version number and tagname for this file ----------- + +! $Id: MISR_simulator.F,v 20.0 2013/12/13 23:15:55 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif +! +! Copyright (c) 2009, Roger Marchand, version 1.2 +! All rights reserved. +! +! Redistribution and use in source and binary forms, with or without modification, are permitted +! provided that the following conditions are met: +! +! * Redistributions of source code must retain the above copyright notice, this list of +! conditions and the following disclaimer. +! * Redistributions in binary form must reproduce the above copyright notice, this list +! of conditions and the following disclaimer in the documentation and/or other materials +! provided with the distribution. +! * Neither the name of the University of Washington nor the names of its contributors may be used +! to endorse or promote products derived from this software without specific prior written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +! BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +! SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +! + +#ifdef COSP_GFDL + SUBROUTINE MISR_simulator( + & npoints, + & nlev, + & ncol, + & sunlit, + & zfull, + & at, + & dtau_s, + & dtau_c, + & frac_out, + & missing_value, + & fq_MISR_TAU_v_CTH, + & dist_model_layertops, + & MISR_mean_ztop, + & MISR_cldarea, + & dtau_col + & ) +#else + SUBROUTINE MISR_simulator( + & npoints, + & nlev, + & ncol, + & sunlit, + & zfull, + & at, + & dtau_s, + & dtau_c, + & frac_out, + & missing_value, + & fq_MISR_TAU_v_CTH, + & dist_model_layertops, + & MISR_mean_ztop, + & MISR_cldarea + & ) +#endif + + + implicit none + integer n_MISR_CTH + parameter(n_MISR_CTH=16) + +! ----- +! Input +! ----- + + INTEGER npoints ! if ncol ==1, the number of model points in the horizontal grid + ! else the number of GCM grid points + + INTEGER nlev ! number of model vertical levels + + INTEGER ncol ! number of model sub columns + ! (must already be generated in via scops and passed to this + ! routine via the variable frac_out ) + + INTEGER sunlit(npoints) ! 1 for day points, 0 for night time + + REAL zfull(npoints,nlev) ! height (in meters) of full model levels (i.e. midpoints) + ! zfull(npoints,1) is top level of model + ! zfull(npoints,nlev) is bottom level of model (closest point to surface) + + REAL at(npoints,nlev) ! temperature in each model level (K) + + REAL dtau_s(npoints,nlev) ! visible wavelength cloud optical depth ... for "stratiform" condensate + ! NOTE: this the cloud optical depth of only the + ! the model cell (i,j) + + REAL dtau_c(npoints,nlev) ! visible wavelength cloud optical depth ... for "convective" condensate + ! NOTE: this the cloud optical depth of only the + ! the model cell (i,j) + + REAL frac_out(npoints,ncol,nlev) ! NOTE: only need if columns>1 ... subgrid scheme in use. + + REAL missing_value +#ifdef COSP_GFDL + REAL,optional :: dtau_col(npoints,ncol,nlev) + ! tau values obtained from model + ! stochastic columns + + +#endif + +! ------ +! Outputs +! ------ + + REAL fq_MISR_TAU_v_CTH(npoints,7,n_MISR_CTH) + REAL dist_model_layertops(npoints,n_MISR_CTH) + REAL MISR_cldarea(npoints) ! fractional area coverged by clouds + REAL MISR_mean_ztop(npoints) ! mean cloud top hieght(m) MISR would observe + ! NOTE: == 0 if area ==0 + + +! ------ +! Working variables +! ------ + + REAL tau(npoints,ncol) ! total column optical depth ... + + INTEGER j,ilev,ilev2,ibox,k + INTEGER itau + + LOGICAL box_cloudy(npoints,ncol) + + real isccp_taumin + real boxarea + real tauchk + REAL box_MISR_ztop(npoints,ncol) ! cloud top hieght(m) MISR would observe + + integer thres_crossed_MISR + integer loop,iMISR_ztop + + real dtau, cloud_dtau, MISR_penetration_height,ztest + + real MISR_CTH_boundaries(n_MISR_CTH+1) + + DATA MISR_CTH_boundaries / -99, 0, 0.5, 1, 1.5, 2, 2.5, 3, + c 4, 5, 7, 9, 11, 13, 15, 17, 99 / + + DATA isccp_taumin / 0.3 / + + tauchk = -1.*log(0.9999999) + + ! + ! For each GCM cell or horizontal model grid point ... + ! + do j=1,npoints + + ! + ! estimate distribution of Model layer tops + ! + dist_model_layertops(j,:)=0 + + do ilev=1,nlev + + ! define location of "layer top" + if(ilev.eq.1 .or. ilev.eq.nlev) then + ztest=zfull(j,ilev) + else + ztest=0.5*(zfull(j,ilev)+zfull(j,ilev-1)) + endif + + ! find MISR layer that contains this level + ! note, the first MISR level is "no height" level + iMISR_ztop=2 + do loop=2,n_MISR_CTH + + if ( ztest .gt. + & 1000*MISR_CTH_boundaries(loop+1) ) then + + iMISR_ztop=loop+1 + endif + enddo + + dist_model_layertops(j,iMISR_ztop)= + & dist_model_layertops(j,iMISR_ztop)+1 + enddo + + + ! + ! compute total cloud optical depth for each column + ! + do ibox=1,ncol + + ! Initialize tau to zero in each subcolum + tau(j,ibox)=0. + box_cloudy(j,ibox)=.false. + box_MISR_ztop(j,ibox)=0 + + ! initialize threshold detection for each sub column + thres_crossed_MISR=0; + + do ilev=1,nlev + +#ifdef COSP_GFDL + if (present(dtau_col)) then + dtau = dtau_col(j,ibox,ilev) + else +#endif + dtau=0 + + if (frac_out(j,ibox,ilev).eq.1) then + dtau = dtau_s(j,ilev) + endif + + if (frac_out(j,ibox,ilev).eq.2) then + dtau = dtau_c(j,ilev) + end if + +#ifdef COSP_GFDL + endif +#endif + tau(j,ibox)=tau(j,ibox)+ dtau + + + ! NOW for MISR .. + ! if there a cloud ... start the counter ... store this height + if(thres_crossed_MISR .eq. 0 .and. dtau .gt. 0.) then + + ! first encountered a "cloud" + thres_crossed_MISR=1 + cloud_dtau=0 + endif + + if( thres_crossed_MISR .lt. 99 .and. + & thres_crossed_MISR .gt. 0 ) then + + if( dtau .eq. 0.) then + + ! we have come to the end of the current cloud + ! layer without yet selecting a CTH boundary. + ! ... restart cloud tau counter + cloud_dtau=0 + else + ! add current optical depth to count for + ! the current cloud layer + cloud_dtau=cloud_dtau+dtau + endif + + ! if the cloud is continuous but optically thin (< 1) + ! from above the current layer cloud top to the current level + ! then MISR will like see a top below the top of the current + ! layer + if( dtau.gt.0 .and. (cloud_dtau-dtau) .lt. 1) then + + if(dtau .lt. 1 .or. ilev.eq.1 .or. ilev.eq.nlev) then + + ! MISR will likely penetrate to some point + ! within this layer ... the middle + MISR_penetration_height=zfull(j,ilev) + + else + ! take the OD = 1.0 level into this layer + MISR_penetration_height= + & 0.5*(zfull(j,ilev)+zfull(j,ilev-1)) - + & 0.5*(zfull(j,ilev-1)-zfull(j,ilev+1)) + & /dtau + endif + + box_MISR_ztop(j,ibox)=MISR_penetration_height + + endif + + ! check for a distinctive water layer + if(dtau .gt. 1 .and. at(j,ilev).gt.273 ) then + + ! must be a water cloud ... + ! take this as CTH level + thres_crossed_MISR=99 + endif + + ! if the total column optical depth is "large" than + ! MISR can't seen anything else ... set current point as CTH level + if(tau(j,ibox) .gt. 5) then + + thres_crossed_MISR=99 + endif + + endif ! MISR CTH booundary not set + + enddo !ilev - loop over vertical levesl + + ! written by roj 5/2006 + ! check to see if there was a cloud for which we didn't + ! set a MISR cloud top boundary + if( thres_crossed_MISR .eq. 1) then + + ! if the cloud has a total optical depth of greater + ! than ~ 0.5 MISR will still likely pick up this cloud + ! with a height near the true cloud top + ! otherwise there should be no CTH + if( tau(j,ibox) .gt. 0.5) then + + ! keep MISR detected CTH + + elseif(tau(j,ibox) .gt. 0.2) then + + ! MISR may detect but wont likley have a good height + box_MISR_ztop(j,ibox)=-1 + + else + ! MISR not likely to even detect. + ! so set as not cloudy + box_MISR_ztop(j,ibox)=0 + + endif + + endif + + enddo ! loop of subcolumns + enddo ! loop of gridpoints + + + ! + ! Modify MISR CTH for satellite spatial / pattern matcher effects + ! + ! Code in this region added by roj 5/2006 to account + ! for spatial effect of the MISR pattern matcher. + ! Basically, if a column is found between two neighbors + ! at the same CTH, and that column has no hieght or + ! a lower CTH, THEN misr will tend to but place the + ! odd column at the same height as it neighbors. + ! + ! This setup assumes the columns represent a about a 1 to 4 km scale + ! it will need to be modified significantly, otherwise + if(ncol.eq.1) then + + ! adjust based on neightboring points ... i.e. only 2D grid was input + do j=2,npoints-1 + + if(box_MISR_ztop(j-1,1).gt.0 .and. + & box_MISR_ztop(j+1,1).gt.0 ) then + + if( abs( box_MISR_ztop(j-1,1) - + & box_MISR_ztop(j+1,1) ) .lt. 500 + & .and. + & box_MISR_ztop(j,1) .lt. + & box_MISR_ztop(j+1,1) ) then + + box_MISR_ztop(j,1) = + & box_MISR_ztop(j+1,1) + endif + + endif + enddo + else + + ! adjust based on neighboring subcolumns .... +#ifdef COSP_GFDL +!RSH ADDS j loop and uses j as index rather than just j=1: + do j=1,npoints +#endif + do ibox=2,ncol-1 + +#ifndef COSP_GFDL + if(box_MISR_ztop(1,ibox-1).gt.0 .and. + & box_MISR_ztop(1,ibox+1).gt.0 ) then + + if( abs( box_MISR_ztop(1,ibox-1) - + & box_MISR_ztop(1,ibox+1) ) .lt. 500 + & .and. + & box_MISR_ztop(1,ibox) .lt. + & box_MISR_ztop(1,ibox+1) ) then + + box_MISR_ztop(1,ibox) = + & box_MISR_ztop(1,ibox+1) +#else + + if(box_MISR_ztop(j,ibox-1).gt.0 .and. + & box_MISR_ztop(j,ibox+1).gt.0 ) then + + if( abs( box_MISR_ztop(j,ibox-1) - + & box_MISR_ztop(j,ibox+1) ) .lt. 500 + & .and. + & box_MISR_ztop(j,ibox) .lt. + & box_MISR_ztop(j,ibox+1) ) then + + box_MISR_ztop(j,ibox) = + & box_MISR_ztop(j,ibox+1) +#endif + endif + + endif + enddo +#ifdef COSP_GFDL + enddo +#endif + + endif + + ! + ! DETERMINE CLOUD TYPE FREQUENCIES + ! + ! Now that ztop and tau have been determined, + ! determine amount of each cloud type + boxarea=1./real(ncol) + do j=1,npoints + + ! reset frequencies -- modified loop structure, roj 5/2006 + do ilev=1,7 ! "tau loop" + do ilev2=1,n_MISR_CTH + fq_MISR_TAU_v_CTH(j,ilev,ilev2)=0. + enddo + enddo + + MISR_cldarea(j)=0. + MISR_mean_ztop(j)=0. + + do ibox=1,ncol + + if (tau(j,ibox) .gt. (tauchk)) then + box_cloudy(j,ibox)=.true. + endif + + itau = 0 + + if (box_cloudy(j,ibox)) then + + !determine optical depth category + if (tau(j,ibox) .lt. isccp_taumin) then + itau=1 + else if (tau(j,ibox) .ge. isccp_taumin + & .and. tau(j,ibox) .lt. 1.3) then + itau=2 + else if (tau(j,ibox) .ge. 1.3 + & .and. tau(j,ibox) .lt. 3.6) then + itau=3 + else if (tau(j,ibox) .ge. 3.6 + & .and. tau(j,ibox) .lt. 9.4) then + itau=4 + else if (tau(j,ibox) .ge. 9.4 + & .and. tau(j,ibox) .lt. 23.) then + itau=5 + else if (tau(j,ibox) .ge. 23. + & .and. tau(j,ibox) .lt. 60.) then + itau=6 + else if (tau(j,ibox) .ge. 60.) then + itau=7 + endif + + endif + + ! update MISR histograms and summary metrics - roj 5/2005 + if (sunlit(j).eq.1) then + + !if cloudy added by roj 5/2005 + if( box_MISR_ztop(j,ibox).eq.0) then + + ! no cloud detected + iMISR_ztop=0 + + elseif( box_MISR_ztop(j,ibox).eq.-1) then + + ! cloud can be detected but too thin to get CTH + iMISR_ztop=1 + + fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop)= + & fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop) + boxarea + + else + + ! + ! determine index for MISR bin set + ! + + iMISR_ztop=2 + + do loop=2,n_MISR_CTH + + if ( box_MISR_ztop(j,ibox) .gt. + & 1000*MISR_CTH_boundaries(loop+1) ) then + + iMISR_ztop=loop+1 + + endif + enddo + + if(box_cloudy(j,ibox)) then + + ! there is an isccp clouds so itau(j) is defined + fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop)= + & fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop) + boxarea + + else + ! MISR CTH resolution is trying to fill in a + ! broken cloud scene where there is no condensate. + ! The MISR CTH-1D-OD product will only put in a cloud + ! if the MISR cloud mask indicates cloud. + ! therefore we will not include this column in the histogram + ! in reality aerosoal and 3D effects or bright surfaces + ! could fool the MISR cloud mask + + ! the alternative is to count as very thin cloud ?? +! fq_MISR_TAU_v_CTH(1,iMISR_ztop)= +! & fq_MISR_TAU_v_CTH(1,iMISR_ztop) + boxarea + endif + + + MISR_mean_ztop(j)=MISR_mean_ztop(j)+ + & box_MISR_ztop(j,ibox)*boxarea + + MISR_cldarea(j)=MISR_cldarea(j) + boxarea + + endif + else + ! Set to issing data. A. Bodas - 14/05/2010 + do loop=1,n_MISR_CTH + do k=1,7 + fq_MISR_TAU_v_CTH(j,k,loop) = missing_value + enddo + dist_model_layertops(j,loop) = missing_value + enddo + MISR_cldarea(j) = missing_value + MISR_mean_ztop(npoints) = missing_value + + endif ! is sunlight ? + + enddo ! ibox - loop over subcolumns + + if( MISR_cldarea(j) .gt. 0.) then + MISR_mean_ztop(j)= MISR_mean_ztop(j) / MISR_cldarea(j) ! roj 5/2006 + endif + + enddo ! loop over grid points + + return + end diff --git a/src/atmos_param/cosp/MISR_simulator/MISR_simulator.f b/src/atmos_param/cosp/MISR_simulator/MISR_simulator.f deleted file mode 100644 index 3ec7f8c740..0000000000 --- a/src/atmos_param/cosp/MISR_simulator/MISR_simulator.f +++ /dev/null @@ -1,481 +0,0 @@ - -!--------------------------------------------------------------------- -!------------ FMS version number and tagname for this file ----------- - -! $Id: MISR_simulator.f,v 19.0 2012/01/06 20:04:12 fms Exp $ -! $Name: siena_201207 $ - -! -! Copyright (c) 2009, Roger Marchand, version 1.2 -! All rights reserved. -! -! Redistribution and use in source and binary forms, with or without modification, are permitted -! provided that the following conditions are met: -! -! * Redistributions of source code must retain the above copyright notice, this list of -! conditions and the following disclaimer. -! * Redistributions in binary form must reproduce the above copyright notice, this list -! of conditions and the following disclaimer in the documentation and/or other materials -! provided with the distribution. -! * Neither the name of the University of Washington nor the names of its contributors may be used -! to endorse or promote products derived from this software without specific prior written permission. -! -! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -! BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -! SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -! - - SUBROUTINE MISR_simulator( - & npoints, - & nlev, - & ncol, - & sunlit, - & zfull, - & at, - & dtau_s, - & dtau_c, - & frac_out, - & fq_MISR_TAU_v_CTH, - & dist_model_layertops, - & MISR_mean_ztop, - & MISR_cldarea, - & dtau_col, - & passing_in_column_data - & ) - - - implicit none - integer n_MISR_CTH - parameter(n_MISR_CTH=16) - -! ----- -! Input -! ----- - - INTEGER npoints ! if ncol ==1, the number of model points in the horizontal grid - ! else the number of GCM grid points - - INTEGER nlev ! number of model vertical levels - - INTEGER ncol ! number of model sub columns - ! (must already be generated in via scops and passed to this - ! routine via the variable frac_out ) - - INTEGER sunlit(npoints) ! 1 for day points, 0 for night time - - REAL zfull(npoints,nlev) ! height (in meters) of full model levels (i.e. midpoints) - ! zfull(npoints,1) is top level of model - ! zfull(npoints,nlev) is bottom level of model (closest point to surface) - - REAL at(npoints,nlev) ! temperature in each model level (K) - - REAL dtau_s(npoints,nlev) ! visible wavelength cloud optical depth ... for "stratiform" condensate - ! NOTE: this the cloud optical depth of only the - ! the model cell (i,j) - - REAL dtau_c(npoints,nlev) ! visible wavelength cloud optical depth ... for "convective" condensate - ! NOTE: this the cloud optical depth of only the - ! the model cell (i,j) - - REAL frac_out(npoints,ncol,nlev) ! NOTE: only need if columns>1 ... subgrid scheme in use. - - REAL dtau_col(npoints,ncol,nlev) - ! tau values obtained from model - ! stochastic columns - - LOGICAL passing_in_column_data - ! tau and emissivity from model columns - ! is passed in ? - -! ------ -! Outputs -! ------ - - REAL fq_MISR_TAU_v_CTH(npoints,7,n_MISR_CTH) - REAL dist_model_layertops(npoints,n_MISR_CTH) - REAL MISR_cldarea(npoints) ! fractional area coverged by clouds - REAL MISR_mean_ztop(npoints) ! mean cloud top hieght(m) MISR would observe - ! NOTE: == 0 if area ==0 - - -! ------ -! Working variables -! ------ - - REAL tau(npoints,ncol) ! total column optical depth ... - - INTEGER j,ilev,ilev2,ibox - INTEGER itau - - LOGICAL box_cloudy(npoints,ncol) - - real isccp_taumin - real boxarea - real tauchk - REAL box_MISR_ztop(npoints,ncol) ! cloud top hieght(m) MISR would observe - - integer thres_crossed_MISR - integer loop,iMISR_ztop - - real dtau, cloud_dtau, MISR_penetration_height,ztest - - real MISR_CTH_boundaries(n_MISR_CTH+1) - - DATA MISR_CTH_boundaries / -99, 0, 0.5, 1, 1.5, 2, 2.5, 3, - c 4, 5, 7, 9, 11, 13, 15, 17, 99 / - - DATA isccp_taumin / 0.3 / - - tauchk = -1.*log(0.9999999) - - ! - ! For each GCM cell or horizontal model grid point ... - ! - do j=1,npoints - - ! - ! estimate distribution of Model layer tops - ! - dist_model_layertops(j,:)=0 - - do ilev=1,nlev - - ! define location of "layer top" - if(ilev.eq.1 .or. ilev.eq.nlev) then - ztest=zfull(j,ilev) - else - ztest=0.5*(zfull(j,ilev)+zfull(j,ilev-1)) - endif - - ! find MISR layer that contains this level - ! note, the first MISR level is "no height" level - iMISR_ztop=2 - do loop=2,n_MISR_CTH - - if ( ztest .gt. - & 1000*MISR_CTH_boundaries(loop+1) ) then - - iMISR_ztop=loop+1 - endif - enddo - - dist_model_layertops(j,iMISR_ztop)= - & dist_model_layertops(j,iMISR_ztop)+1 - enddo - - - ! - ! compute total cloud optical depth for each column - ! - do ibox=1,ncol - - ! Initialize tau to zero in each subcolum - tau(j,ibox)=0. - box_cloudy(j,ibox)=.false. - box_MISR_ztop(j,ibox)=0 - - ! initialize threshold detection for each sub column - thres_crossed_MISR=0; - - do ilev=1,nlev - - if (passing_in_column_data) then - dtau = dtau_col(j,ibox,ilev) - else - dtau=0 - - if (frac_out(j,ibox,ilev).eq.1) then - dtau = dtau_s(j,ilev) - endif - - if (frac_out(j,ibox,ilev).eq.2) then - dtau = dtau_c(j,ilev) - end if - endif - - tau(j,ibox)=tau(j,ibox)+ dtau - - - ! NOW for MISR .. - ! if there a cloud ... start the counter ... store this height - if(thres_crossed_MISR .eq. 0 .and. dtau .gt. 0.) then - - ! first encountered a "cloud" - thres_crossed_MISR=1 - cloud_dtau=0 - endif - - if( thres_crossed_MISR .lt. 99 .and. - & thres_crossed_MISR .gt. 0 ) then - - if( dtau .eq. 0.) then - - ! we have come to the end of the current cloud - ! layer without yet selecting a CTH boundary. - ! ... restart cloud tau counter - cloud_dtau=0 - else - ! add current optical depth to count for - ! the current cloud layer - cloud_dtau=cloud_dtau+dtau - endif - - ! if the cloud is continuous but optically thin (< 1) - ! from above the current layer cloud top to the current level - ! then MISR will like see a top below the top of the current - ! layer - if( dtau.gt.0 .and. (cloud_dtau-dtau) .lt. 1) then - - if(dtau .lt. 1 .or. ilev.eq.1 .or. ilev.eq.nlev) then - - ! MISR will likely penetrate to some point - ! within this layer ... the middle - MISR_penetration_height=zfull(j,ilev) - - else - ! take the OD = 1.0 level into this layer - MISR_penetration_height= - & 0.5*(zfull(j,ilev)+zfull(j,ilev-1)) - - & 0.5*(zfull(j,ilev-1)-zfull(j,ilev+1)) - & /dtau - endif - - box_MISR_ztop(j,ibox)=MISR_penetration_height - - endif - - ! check for a distinctive water layer - if(dtau .gt. 1 .and. at(j,ilev).gt.273 ) then - - ! must be a water cloud ... - ! take this as CTH level - thres_crossed_MISR=99 - endif - - ! if the total column optical depth is "large" than - ! MISR can't seen anything else ... set current point as CTH level - if(tau(j,ibox) .gt. 5) then - - thres_crossed_MISR=99 - endif - - endif ! MISR CTH booundary not set - - enddo !ilev - loop over vertical levesl - - ! written by roj 5/2006 - ! check to see if there was a cloud for which we didn't - ! set a MISR cloud top boundary - if( thres_crossed_MISR .eq. 1) then - - ! if the cloud has a total optical depth of greater - ! than ~ 0.5 MISR will still likely pick up this cloud - ! with a height near the true cloud top - ! otherwise there should be no CTH - if( tau(j,ibox) .gt. 0.5) then - - ! keep MISR detected CTH - - elseif(tau(j,ibox) .gt. 0.2) then - - ! MISR may detect but wont likley have a good height - box_MISR_ztop(j,ibox)=-1 - - else - ! MISR not likely to even detect. - ! so set as not cloudy - box_MISR_ztop(j,ibox)=0 - - endif - - endif - - enddo ! loop of subcolumns - enddo ! loop of gridpoints - - - ! - ! Modify MISR CTH for satellite spatial / pattern matcher effects - ! - ! Code in this region added by roj 5/2006 to account - ! for spatial effect of the MISR pattern matcher. - ! Basically, if a column is found between two neighbors - ! at the same CTH, and that column has no hieght or - ! a lower CTH, THEN misr will tend to but place the - ! odd column at the same height as it neighbors. - ! - ! This setup assumes the columns represent a about a 1 to 4 km scale - ! it will need to be modified significantly, otherwise - if(ncol.eq.1) then - - ! adjust based on neightboring points ... i.e. only 2D grid was input - do j=2,npoints-1 - - if(box_MISR_ztop(j-1,1).gt.0 .and. - & box_MISR_ztop(j+1,1).gt.0 ) then - - if( abs( box_MISR_ztop(j-1,1) - - & box_MISR_ztop(j+1,1) ) .lt. 500 - & .and. - & box_MISR_ztop(j,1) .lt. - & box_MISR_ztop(j+1,1) ) then - - box_MISR_ztop(j,1) = - & box_MISR_ztop(j+1,1) - endif - - endif - enddo - else - - ! adjust based on neighboring subcolumns .... - do ibox=2,ncol-1 - - if(box_MISR_ztop(1,ibox-1).gt.0 .and. - & box_MISR_ztop(1,ibox+1).gt.0 ) then - - if( abs( box_MISR_ztop(1,ibox-1) - - & box_MISR_ztop(1,ibox+1) ) .lt. 500 - & .and. - & box_MISR_ztop(1,ibox) .lt. - & box_MISR_ztop(1,ibox+1) ) then - - box_MISR_ztop(1,ibox) = - & box_MISR_ztop(1,ibox+1) - endif - - endif - enddo - - endif - - ! - ! DETERMINE CLOUD TYPE FREQUENCIES - ! - ! Now that ztop and tau have been determined, - ! determine amount of each cloud type - boxarea=1./real(ncol) - do j=1,npoints - - ! reset frequencies -- modified loop structure, roj 5/2006 - do ilev=1,7 ! "tau loop" - do ilev2=1,n_MISR_CTH - fq_MISR_TAU_v_CTH(j,ilev,ilev2)=0. - enddo - enddo - - MISR_cldarea(j)=0. - MISR_mean_ztop(j)=0. - - do ibox=1,ncol - - if (tau(j,ibox) .gt. (tauchk)) then - box_cloudy(j,ibox)=.true. - endif - - itau = 0 - - if (box_cloudy(j,ibox)) then - - !determine optical depth category - if (tau(j,ibox) .lt. isccp_taumin) then - itau=1 - else if (tau(j,ibox) .ge. isccp_taumin - & .and. tau(j,ibox) .lt. 1.3) then - itau=2 - else if (tau(j,ibox) .ge. 1.3 - & .and. tau(j,ibox) .lt. 3.6) then - itau=3 - else if (tau(j,ibox) .ge. 3.6 - & .and. tau(j,ibox) .lt. 9.4) then - itau=4 - else if (tau(j,ibox) .ge. 9.4 - & .and. tau(j,ibox) .lt. 23.) then - itau=5 - else if (tau(j,ibox) .ge. 23. - & .and. tau(j,ibox) .lt. 60.) then - itau=6 - else if (tau(j,ibox) .ge. 60.) then - itau=7 - endif - - endif - - ! update MISR histograms and summary metrics - roj 5/2005 - if (sunlit(j).eq.1) then - - !if cloudy added by roj 5/2005 - if( box_MISR_ztop(j,ibox).eq.0) then - - ! no cloud detected - iMISR_ztop=0 - - elseif( box_MISR_ztop(j,ibox).eq.-1) then - - ! cloud can be detected but too thin to get CTH - iMISR_ztop=1 - - fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop)= - & fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop) + boxarea - - else - - ! - ! determine index for MISR bin set - ! - - iMISR_ztop=2 - - do loop=2,n_MISR_CTH - - if ( box_MISR_ztop(j,ibox) .gt. - & 1000*MISR_CTH_boundaries(loop+1) ) then - - iMISR_ztop=loop+1 - - endif - enddo - - if(box_cloudy(j,ibox)) then - - ! there is an isccp clouds so itau(j) is defined - fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop)= - & fq_MISR_TAU_v_CTH(j,itau,iMISR_ztop) + boxarea - - else - ! MISR CTH resolution is trying to fill in a - ! broken cloud scene where there is no condensate. - ! The MISR CTH-1D-OD product will only put in a cloud - ! if the MISR cloud mask indicates cloud. - ! therefore we will not include this column in the histogram - ! in reality aerosoal and 3D effects or bright surfaces - ! could fool the MISR cloud mask - - ! the alternative is to count as very thin cloud ?? -! fq_MISR_TAU_v_CTH(1,iMISR_ztop)= -! & fq_MISR_TAU_v_CTH(1,iMISR_ztop) + boxarea - endif - - - MISR_mean_ztop(j)=MISR_mean_ztop(j)+ - & box_MISR_ztop(j,ibox)*boxarea - - MISR_cldarea(j)=MISR_cldarea(j) + boxarea - - endif - - endif ! is sunlight ? - - enddo ! ibox - loop over subcolumns - - if( MISR_cldarea(j) .gt. 0.) then - MISR_mean_ztop(j)= MISR_mean_ztop(j) / MISR_cldarea(j) ! roj 5/2006 - endif - - enddo ! loop over grid points - - return - end diff --git a/src/atmos_param/cosp/MODIS_simulator/modis_simulator.f90 b/src/atmos_param/cosp/MODIS_simulator/modis_simulator.F90 similarity index 86% rename from src/atmos_param/cosp/MODIS_simulator/modis_simulator.f90 rename to src/atmos_param/cosp/MODIS_simulator/modis_simulator.F90 index acf94b0c60..e8c74739eb 100644 --- a/src/atmos_param/cosp/MODIS_simulator/modis_simulator.f90 +++ b/src/atmos_param/cosp/MODIS_simulator/modis_simulator.F90 @@ -1,10 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: modis_simulator.f90,v 19.0 2012/01/06 20:04:13 fms Exp $ -! $Name: siena_201207 $ +! $Id: modis_simulator.F90,v 20.0 2013/12/13 23:15:56 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 +#endif ! (c) 2009-2010, Regents of the Unversity of Colorado ! Author: Robert Pincus, Cooperative Institute for Research in the Environmental Sciences @@ -38,7 +42,7 @@ ! June 2009 - Steve Platnick and Robert Pincus - Simple radiative transfer for size retrievals ! August 2009 - Robert Pincus - Consistency and bug fixes suggested by Rick Hemler (GFDL) ! November 2009 - Robert Pincus - Bux fixes and speed-ups after experience with Rick Hemler using AM2 (GFDL) -! January 2010 - Robert Pincus - Added high, middle, low cloud fractions +! January 2010 - Robert Pincus - Added high, middle, low cloud fractions ! ! @@ -57,8 +61,10 @@ ! bottom of this module. Users probably want to replace this with something more graceful. ! module mod_modis_sim - use MOD_COSP_TYPES, only : R_UNDEF + USE MOD_COSP_TYPES, only: R_UNDEF +#ifdef COSP_GFDL use fms_mod, only : error_mesg, FATAL +#endif implicit none ! ------------------------------ ! Algorithmic parameters @@ -106,9 +112,8 @@ module mod_modis_sim real, dimension(numTauHistogramBins + 1), parameter :: & tauHistogramBoundaries = (/ min_OpticalThickness, 1.3, 3.6, 9.4, 23., 60., huge(dummy_real) /) real, dimension(numPressureHistogramBins + 1), parameter :: & ! Units Pa - pressureHistogramBoundaries = (/ 0., 18000., 31000., 44000., 56000., 68000., 80000., huge(dummy_real) /) + pressureHistogramBoundaries = (/ 0., 18000., 31000., 44000., 56000., 68000., 80000., huge(dummy_real) /) real, parameter :: highCloudPressureLimit = 440. * 100., lowCloudPressureLimit = 680. * 100. - ! ! For output - nominal bin centers and bin boundaries. On output pressure bins are highest to lowest. ! @@ -189,7 +194,7 @@ subroutine modis_L2_simulator_twoTaus( & logical, dimension(size(retrievedTau)) :: cloudMask real, dimension(size(waterSize, 1), size(waterSize, 2)) :: tauLiquidFraction, tauTotal real :: integratedLiquidFraction - integer :: i, j, nSubcols, nLevels + integer :: i, nSubcols, nLevels ! --------------------------------------------------- nSubcols = size(liquid_opticalThickness, 1) @@ -202,24 +207,18 @@ subroutine modis_L2_simulator_twoTaus( & size(isccpTau), size(isccpCloudTopPressure), & size(retrievedPhase), size(retrievedCloudTopPressure), & size(retrievedTau), size(retrievedSize) /) /= nSubcols )) & -! call complain_and_die("Differing number of subcolumns in one or more arrays") - call error_mesg ('modis_L2_simulator_two_taus', & - 'Differing number of subcolumns in one or more arrays', FATAL) + call complain_and_die("Differing number of subcolumns in one or more arrays") if(any((/ size(ice_opticalThickness, 2), size(waterSize, 2), size(iceSize, 2), & size(temp), size(pressureLayers), size(pressureLevels)-1 /) /= nLevels )) & -! call complain_and_die("Differing number of levels in one or more arrays") - call error_mesg ('modis_L2_simulator_two_taus', & - 'Differing number of levels in one or more arrays', FATAL) + call complain_and_die("Differing number of levels in one or more arrays") if(any( (/ any(temp <= 0.), any(pressureLayers <= 0.), & any(liquid_opticalThickness < 0.), & any(ice_opticalThickness < 0.), & any(waterSize < 0.), any(iceSize < 0.) /) )) & -! call complain_and_die("Input values out of bounds") - call error_mesg ('modis_L2_simulator_two_taus', & - 'Input values out of bounds', FATAL) + call complain_and_die("Input values out of bounds") ! --------------------------------------------------- ! @@ -307,22 +306,21 @@ subroutine modis_L2_simulator_twoTaus( & end if else retrievedSize(i) = 1.0e-06*retrieve_re(retrievedPhase(i), retrievedTau(i), & - obs_Refl_nir = compute_nir_reflectance(liquid_opticalThickness(i, :), waterSize(i, :)*1.0e6, & - ice_opticalThickness(i, :), iceSize(i, :)*1.0e6)) + obs_Refl_nir = compute_nir_reflectance(liquid_opticalThickness(i, :), waterSize(i, :)*1.0e6, & + ice_opticalThickness(i, :), iceSize(i, :)*1.0e6)) end if else ! ! Values when we don't think there's a cloud. ! - retrievedCloudTopPressure(i) = R_UNDEF + retrievedCloudTopPressure(i) = R_UNDEF retrievedPhase(i) = phaseIsNone - retrievedSize(i) = R_UNDEF - retrievedTau(i) = R_UNDEF + retrievedSize(i) = R_UNDEF + retrievedTau(i) = R_UNDEF end if - end do - where((retrievedSize(:) < 0.) .and. & - (retrievedSize(:) /= R_UNDEF)) retrievedSize(:) = 1.0e-06*re_fill - + end do + where((retrievedSize(:) < 0.).and.(retrievedSize(:) /= R_UNDEF)) retrievedSize(:) = 1.0e-06*re_fill + ! We use the ISCCP-derived CTP for low clouds, since the ISCCP simulator ICARUS ! mimics what MODIS does to first order. ! Of course, ISCCP cloud top pressures are in mb. @@ -429,7 +427,7 @@ subroutine modis_L3_simulator(phase, cloud_top_pressure, optical_thickness, part ! --------------------------- ! Local variables ! - real, parameter :: LWP_conversion = 2./3. * 1000. ! modulo units. + real, parameter :: LWP_conversion = 2./3. * 1000. ! MKS units integer :: i, j integer :: nPoints, nSubcols logical, dimension(size(phase, 1), size(phase, 2)) :: & @@ -443,21 +441,17 @@ subroutine modis_L3_simulator(phase, cloud_top_pressure, optical_thickness, part ! ! Array conformance checks ! - if(any( (/ size(cloud_top_pressure, 1), size(optical_thickness, 1), size(particle_size, 1), & - size(Cloud_Fraction_Total_Mean), size(Cloud_Fraction_Water_Mean), size(Cloud_Fraction_Ice_Mean), & - size(Cloud_Fraction_High_Mean), size(Cloud_Fraction_Mid_Mean), size(Cloud_Fraction_Low_Mean), & - size(Optical_Thickness_Total_Mean), size(Optical_Thickness_Water_Mean), size(Optical_Thickness_Ice_Mean), & - size(Optical_Thickness_Total_MeanLog10), size(Optical_Thickness_Water_MeanLog10), size(Optical_Thickness_Ice_MeanLog10), & - size(Cloud_Particle_Size_Water_Mean), size(Cloud_Particle_Size_Ice_Mean), & - size(Cloud_Top_Pressure_Total_Mean), & - size(Liquid_Water_Path_Mean), size(Ice_Water_Path_Mean) /) /= nPoints)) & -! call complain_and_die("Some L3 arrays have wrong number of grid points") - call error_mesg ('modis_L3_simulator', & - 'Some L3 arrays have wrong number of grid points', FATAL) + if(any( (/ size(cloud_top_pressure, 1), size(optical_thickness, 1), size(particle_size, 1), & + size(Cloud_Fraction_Total_Mean), size(Cloud_Fraction_Water_Mean), size(Cloud_Fraction_Ice_Mean), & + size(Cloud_Fraction_High_Mean), size(Cloud_Fraction_Mid_Mean), size(Cloud_Fraction_Low_Mean), & + size(Optical_Thickness_Total_Mean), size(Optical_Thickness_Water_Mean), size(Optical_Thickness_Ice_Mean), & + size(Optical_Thickness_Total_MeanLog10), size(Optical_Thickness_Water_MeanLog10), & + size(Optical_Thickness_Ice_MeanLog10), size(Cloud_Particle_Size_Water_Mean), & + size(Cloud_Particle_Size_Ice_Mean), size(Cloud_Top_Pressure_Total_Mean), & + size(Liquid_Water_Path_Mean), size(Ice_Water_Path_Mean) /) /= nPoints)) & + call complain_and_die("Some L3 arrays have wrong number of grid points") if(any( (/ size(cloud_top_pressure, 2), size(optical_thickness, 2), size(particle_size, 2) /) /= nSubcols)) & -! call complain_and_die("Some L3 arrays have wrong number of subcolumns") - call error_mesg ('modis_L3_simulator', & - 'Some L3 arrays have wrong number of subcolumns', FATAL) + call complain_and_die("Some L3 arrays have wrong number of subcolumns") ! @@ -473,11 +467,11 @@ subroutine modis_L3_simulator(phase, cloud_top_pressure, optical_thickness, part Cloud_Fraction_Total_Mean(:) = real(count(cloudMask, dim = 2)) Cloud_Fraction_Water_Mean(:) = real(count(waterCloudMask, dim = 2)) Cloud_Fraction_Ice_Mean(:) = real(count(iceCloudMask, dim = 2)) - - Cloud_Fraction_High_Mean(:) = real(count(cloudMask .and. cloud_top_pressure <= highCloudPressureLimit, dim = 2)) - Cloud_Fraction_Low_Mean(:) = real(count(cloudMask .and. cloud_top_pressure > lowCloudPressureLimit, dim = 2)) + + Cloud_Fraction_High_Mean(:) = real(count(cloudMask .and. cloud_top_pressure <= highCloudPressureLimit, dim = 2)) + Cloud_Fraction_Low_Mean(:) = real(count(cloudMask .and. cloud_top_pressure > lowCloudPressureLimit, dim = 2)) Cloud_Fraction_Mid_Mean(:) = Cloud_Fraction_Total_Mean(:) - Cloud_Fraction_High_Mean(:) - Cloud_Fraction_Low_Mean(:) - + ! ! Don't want to divide by 0, even though the sums will be 0 where the pixel counts are 0. ! @@ -485,38 +479,14 @@ subroutine modis_L3_simulator(phase, cloud_top_pressure, optical_thickness, part where (Cloud_Fraction_Water_Mean == 0) Cloud_Fraction_Water_Mean = -1. where (Cloud_Fraction_Ice_Mean == 0) Cloud_Fraction_Ice_Mean = -1. -!wfc Moving the following sums to a do loop below. -! Optical_Thickness_Total_Mean = sum(optical_thickness, mask = cloudMask, dim = 2) / Cloud_Fraction_Total_Mean(:) -! Optical_Thickness_Water_Mean = sum(optical_thickness, mask = waterCloudMask, dim = 2) / Cloud_Fraction_Water_Mean(:) -! Optical_Thickness_Ice_Mean = sum(optical_thickness, mask = iceCloudMask, dim = 2) / Cloud_Fraction_Ice_Mean(:) - -!wfc The following sum of a log10 fails under debug conditions. The Intel compiler does the log10 operation before the mask gets applied. -!wfc Therefore you are taking the log of a negative number. -! Optical_Thickness_Total_MeanLog10 = sum(log10(optical_thickness), mask = cloudMask, dim = 2) / Cloud_Fraction_Total_Mean(:) -! Optical_Thickness_Water_MeanLog10 = sum(log10(optical_thickness), mask = waterCloudMask, dim = 2) / Cloud_Fraction_Water_Mean(:) -! Optical_Thickness_Ice_MeanLog10 = sum(log10(optical_thickness), mask = iceCloudMask, dim = 2) / Cloud_Fraction_Ice_Mean(:) - -! Cloud_Particle_Size_Water_Mean = sum(particle_size, mask = waterCloudMask, dim = 2) / Cloud_Fraction_Water_Mean(:) -! Cloud_Particle_Size_Ice_Mean = sum(particle_size, mask = iceCloudMask, dim = 2) / Cloud_Fraction_Ice_Mean(:) - -!! Cloud_Top_Pressure_Total_Mean = sum(cloud_top_pressure, mask = cloudMask, dim = 2) & -!! / max(1, count(phase(:, :) /= phaseIsNone, dim = 2)) -! Cloud_Top_Pressure_Total_Mean = sum(cloud_top_pressure, mask = cloudMask, dim = 2) / max(1, count(cloudMask, dim = 2)) - -! Liquid_Water_Path_Mean = LWP_conversion & -! * sum(particle_size * optical_thickness, mask = waterCloudMask, dim = 2) & -! / Cloud_Fraction_Water_Mean(:) -! Ice_Water_Path_Mean = LWP_conversion * ice_density & -! * sum(particle_size * optical_thickness, mask = iceCloudMask, dim = 2) & -! / Cloud_Fraction_Ice_Mean(:) - +#ifdef COSP_GFDL Optical_Thickness_Total_Mean = 0.0 Optical_Thickness_Water_Mean = 0.0 Optical_Thickness_Ice_Mean = 0.0 Optical_Thickness_Total_MeanLog10 = 0.0 Optical_Thickness_Water_MeanLog10 = 0.0 Optical_Thickness_Ice_MeanLog10 = 0.0 - Cloud_Particle_Size_Water_Mean = 0.0 + Cloud_Particle_Size_Water_Mean = 0.0 Cloud_Particle_Size_Ice_Mean = 0.0 Cloud_Top_Pressure_Total_Mean = 0.0 Liquid_Water_Path_Mean = 0.0 @@ -537,56 +507,60 @@ subroutine modis_L3_simulator(phase, cloud_top_pressure, optical_thickness, part LWP_conversion * particle_size(i,j) * optical_thickness(i,j) endif if (iceCloudMask(i,j)) then - Optical_Thickness_Ice_Mean(i) = Optical_Thickness_Ice_Mean(i) + optical_thickness(i,j) + Optical_Thickness_Ice_Mean(i) = Optical_Thickness_Ice_Mean (i) + optical_thickness(i,j) Optical_Thickness_Ice_MeanLog10(i) = Optical_Thickness_Ice_MeanLog10(i) + log10(optical_thickness(i,j)) Cloud_Particle_Size_Ice_Mean(i) = Cloud_Particle_Size_Ice_Mean(i) + particle_size(i,j) Ice_Water_Path_Mean(i) = Ice_Water_Path_Mean(i) + & LWP_conversion * ice_density * particle_size(i,j) * optical_thickness(i,j) - endif + endif enddo enddo - Optical_Thickness_Total_Mean(:) = Optical_Thickness_Total_Mean(:) / Cloud_Fraction_Total_Mean(:) + Optical_Thickness_Total_Mean(:) = Optical_Thickness_Total_Mean(:) / Cloud_Fraction_Total_Mean(:) Optical_Thickness_Water_Mean(:) = Optical_Thickness_Water_Mean(:) / Cloud_Fraction_Water_Mean(:) Optical_Thickness_Ice_Mean(:) = Optical_Thickness_Ice_Mean(:) / Cloud_Fraction_Ice_Mean(:) - + Optical_Thickness_Total_MeanLog10(:) = Optical_Thickness_Total_MeanLog10(:) / Cloud_Fraction_Total_Mean(:) Optical_Thickness_Water_MeanLog10(:) = Optical_Thickness_Water_MeanLog10(:) / Cloud_Fraction_Water_Mean(:) Optical_Thickness_Ice_MeanLog10(:) = Optical_Thickness_Ice_MeanLog10(:) / Cloud_Fraction_Ice_Mean(:) - + Cloud_Particle_Size_Water_Mean(:) = Cloud_Particle_Size_Water_Mean(:) / Cloud_Fraction_Water_Mean(:) Cloud_Particle_Size_Ice_Mean(:) = Cloud_Particle_Size_Ice_Mean(:) / Cloud_Fraction_Ice_Mean(:) - + Cloud_Top_Pressure_Total_Mean(:) = Cloud_Top_Pressure_Total_Mean(:) / max(1, count(cloudMask, dim = 2)) - + Liquid_Water_Path_Mean(:) = Liquid_Water_Path_Mean(:) / Cloud_Fraction_Water_Mean(:) Ice_Water_Path_Mean(:) = Ice_Water_Path_Mean(:) / Cloud_Fraction_Ice_Mean(:) + +#else + Optical_Thickness_Total_Mean = sum(optical_thickness, mask = cloudMask, dim = 2) / Cloud_Fraction_Total_Mean(:) + Optical_Thickness_Water_Mean = sum(optical_thickness, mask = waterCloudMask, dim = 2) / Cloud_Fraction_Water_Mean(:) + Optical_Thickness_Ice_Mean = sum(optical_thickness, mask = iceCloudMask, dim = 2) / Cloud_Fraction_Ice_Mean(:) + + Optical_Thickness_Total_MeanLog10 = sum(log10(optical_thickness), mask = cloudMask, dim = 2) / Cloud_Fraction_Total_Mean(:) + Optical_Thickness_Water_MeanLog10 = sum(log10(optical_thickness), mask = waterCloudMask, dim = 2) / Cloud_Fraction_Water_Mean(:) + Optical_Thickness_Ice_MeanLog10 = sum(log10(optical_thickness), mask = iceCloudMask, dim = 2) / Cloud_Fraction_Ice_Mean(:) + + Cloud_Particle_Size_Water_Mean = sum(particle_size, mask = waterCloudMask, dim = 2) / Cloud_Fraction_Water_Mean(:) + Cloud_Particle_Size_Ice_Mean = sum(particle_size, mask = iceCloudMask, dim = 2) / Cloud_Fraction_Ice_Mean(:) + Cloud_Top_Pressure_Total_Mean = sum(cloud_top_pressure, mask = cloudMask, dim = 2) / max(1, count(cloudMask, dim = 2)) + + Liquid_Water_Path_Mean = LWP_conversion & + * sum(particle_size * optical_thickness, mask = waterCloudMask, dim = 2) & + / Cloud_Fraction_Water_Mean(:) + Ice_Water_Path_Mean = LWP_conversion * ice_density & + * sum(particle_size * optical_thickness, mask = iceCloudMask, dim = 2) & + / Cloud_Fraction_Ice_Mean(:) +#endif ! ! Normalize pixel counts to fraction ! The first three cloud fractions have been set to -1 in cloud-free areas, so set those places to 0. ! -! where(Cloud_Fraction_Total_Mean(:) > 0) -! Cloud_Fraction_Total_Mean(:) = Cloud_Fraction_Total_Mean(:)/nSubcols -! elsewhere -! Cloud_Fraction_Total_Mean(:) = 0. -! end where - -! where(Cloud_Fraction_Water_Mean(:) > 0) -! Cloud_Fraction_Water_Mean(:) = Cloud_Fraction_Water_Mean(:)/nSubcols -! elsewhere -! Cloud_Fraction_Water_Mean(:) = 0. -! end where - -! where(Cloud_Fraction_Ice_Mean(:) > 0) -! Cloud_Fraction_Ice_Mean(:) = Cloud_Fraction_Ice_Mean(:)/nSubcols -! elsewhere -! Cloud_Fraction_Ice_Mean(:) = 0. -! end where Cloud_Fraction_Total_Mean(:) = max(0., Cloud_Fraction_Total_Mean(:)/nSubcols) Cloud_Fraction_Water_Mean(:) = max(0., Cloud_Fraction_Water_Mean(:)/nSubcols) Cloud_Fraction_Ice_Mean(:) = max(0., Cloud_Fraction_Ice_Mean(:) /nSubcols) - + Cloud_Fraction_High_Mean(:) = Cloud_Fraction_High_Mean(:) /nSubcols Cloud_Fraction_Mid_Mean(:) = Cloud_Fraction_Mid_Mean(:) /nSubcols Cloud_Fraction_Low_Mean(:) = Cloud_Fraction_Low_Mean(:) /nSubcols @@ -642,12 +616,9 @@ function cloud_top_pressure(tauIncrement, pressure, tauLimit) ! Result for trapezoidal rule when you take less than a full step ! tauIncrement is a layer-integrated value ! -! totalProduct = totalProduct + & -! deltaX * ((pressure(i) - pressure(i-1)) * deltaX**2/(2. * tauIncrement(i)) + & -! pressure(i-1) * deltaX) totalProduct = totalProduct & + pressure(i-1) * deltaX & - + (pressure(i) - pressure(i-1)) * deltaX**2/(2. * tauIncrement(i)) + + (pressure(i) - pressure(i-1)) * deltaX**2/(2. * tauIncrement(i)) else totalTau = totalTau + tauIncrement(i) totalProduct = totalProduct + tauIncrement(i) * (pressure(i) + pressure(i-1)) / 2. @@ -689,7 +660,9 @@ pure function compute_nir_reflectance(water_tau, water_size, ice_tau, ice_size) real, dimension(size(water_tau)) :: water_g, water_w0, ice_g, ice_w0, & tau, g, w0 +#ifdef COSP_GFDL integer :: cnt_tau +#endif !---------------------------------------- water_g(:) = get_g_nir( phaseIsLiquid, water_size) water_w0(:) = get_ssa_nir(phaseIsLiquid, water_size) @@ -707,8 +680,12 @@ pure function compute_nir_reflectance(water_tau, water_size, ice_tau, ice_size) (g(:) * tau(:)) end where +#ifdef COSP_GFDL cnt_tau = count(tau(:) > 0.0) compute_nir_reflectance = compute_toa_reflectace(tau, g, w0, cnt_tau) +#else + compute_nir_reflectance = compute_toa_reflectace(tau, g, w0) +#endif end function compute_nir_reflectance !------------------------------------------------------------------------------------------------ ! Retreivals @@ -717,15 +694,15 @@ elemental function retrieve_re (phase, tau, obs_Refl_nir) integer, intent(in) :: phase real, intent(in) :: tau, obs_Refl_nir real :: retrieve_re - ! - ! Finds the re that produces the minimum mis-match between predicted and observed reflectance in - ! MODIS band 7 (near IR) - ! Uses - ! fits for asymmetry parameter g(re) and single scattering albedo w0(re) based on MODIS tables - ! two-stream for layer reflectance and transmittance as a function of optical thickness tau, g, and w0 - ! adding-doubling for total reflectance - ! - ! + ! + ! Finds the re that produces the minimum mis-match between predicted and observed reflectance in + ! MODIS band 7 (near IR) + ! Uses + ! fits for asymmetry parameter g(re) and single scattering albedo w0(re) based on MODIS tables + ! two-stream for layer reflectance and transmittance as a function of optical thickness tau, g, and w0 + ! adding-doubling for total reflectance + ! + ! ! ! Local variables ! @@ -736,7 +713,7 @@ elemental function retrieve_re (phase, tau, obs_Refl_nir) real, dimension(num_trial_res) :: trial_re, g, w0, predicted_Refl_nir ! -------------------------- - if(any(phase == (/ phaseIsLiquid, phaseIsUndetermined, phaseIsIce /))) then + if(any(phase == (/ phaseIsLiquid, phaseIsUndetermined, phaseIsIce /))) then if (phase == phaseIsLiquid .OR. phase == phaseIsUndetermined) then re_min = re_water_min re_max = re_water_max @@ -784,7 +761,6 @@ pure function interpolate_to_min(x, y, yobs) ! y must be monotonic in x ! real, dimension(size(x)) :: diff - real :: weight integer :: nPoints, minDiffLoc, lowerBound, upperBound ! --------------------------------- nPoints = size(y) @@ -855,31 +831,31 @@ elemental function get_g_nir (phase, re) end function get_g_nir ! -------------------------------------------- - elemental function get_ssa_nir (phase, re) - integer, intent(in) :: phase - real, intent(in) :: re - real :: get_ssa_nir - ! - ! Polynomial fit for single scattering albedo in MODIS band 7 (near IR) as a function - ! of size for ice and water - ! Fits from Steve Platnick - ! - - real, dimension(4), parameter :: ice_coefficients = (/ 0.9994, -4.5199e-3, 3.9370e-5, -1.5235e-7 /) - real, dimension(3), parameter :: water_coefficients = (/ 1.0008, -2.5626e-3, 1.6024e-5 /) - - ! approx. fits from MODIS Collection 5 LUT scattering calculations - if(phase == phaseIsLiquid) then - get_ssa_nir = fit_to_quadratic(re, water_coefficients) + elemental function get_ssa_nir (phase, re) + integer, intent(in) :: phase + real, intent(in) :: re + real :: get_ssa_nir + ! + ! Polynomial fit for single scattering albedo in MODIS band 7 (near IR) as a function + ! of size for ice and water + ! Fits from Steve Platnick + ! + + real, dimension(4), parameter :: ice_coefficients = (/ 0.9994, -4.5199e-3, 3.9370e-5, -1.5235e-7 /) + real, dimension(3), parameter :: water_coefficients = (/ 1.0008, -2.5626e-3, 1.6024e-5 /) + + ! approx. fits from MODIS Collection 5 LUT scattering calculations + if(phase == phaseIsLiquid) then + get_ssa_nir = fit_to_quadratic(re, water_coefficients) if(re < re_water_min) get_ssa_nir = fit_to_quadratic(re_water_min, water_coefficients) if(re > re_water_max) get_ssa_nir = fit_to_quadratic(re_water_max, water_coefficients) - else - get_ssa_nir = fit_to_cubic(re, ice_coefficients) + else + get_ssa_nir = fit_to_cubic(re, ice_coefficients) if(re < re_ice_min) get_ssa_nir = fit_to_cubic(re_ice_min, ice_coefficients) if(re > re_ice_max) get_ssa_nir = fit_to_cubic(re_ice_max, ice_coefficients) - end if + end if - end function get_ssa_nir + end function get_ssa_nir ! -------------------------------------------- pure function fit_to_cubic(x, coefficients) real, intent(in) :: x @@ -901,14 +877,25 @@ end function fit_to_quadratic ! -------------------------------------------- ! Radiative transfer ! -------------------------------------------- +#ifdef COSP_GFDL pure function compute_toa_reflectace(tau, g, w0, cnt_tau) +#else + pure function compute_toa_reflectace(tau, g, w0) +#endif real, dimension(:), intent(in) :: tau, g, w0 +#ifdef COSP_GFDL integer, intent(in) :: cnt_tau +#endif real :: compute_toa_reflectace logical, dimension(size(tau)) :: cloudMask - integer, dimension(cnt_tau) :: cloudIndicies +#ifdef COSP_GFDL + integer, dimension(cnt_tau) :: cloudIndicies real, dimension(cnt_tau) :: Refl, Trans +#else + integer, dimension(count(tau(:) > 0)) :: cloudIndicies + real, dimension(count(tau(:) > 0)) :: Refl, Trans +#endif real :: Refl_tot, Trans_tot integer :: i ! --------------------------------------- @@ -921,10 +908,10 @@ pure function compute_toa_reflectace(tau, g, w0, cnt_tau) call two_stream(tau(cloudIndicies(i)), g(cloudIndicies(i)), w0(cloudIndicies(i)), Refl(i), Trans(i)) end do - call adding_doubling(Refl(:), Trans(:), Refl_tot, Trans_tot) - - compute_toa_reflectace = Refl_tot - + call adding_doubling(Refl(:), Trans(:), Refl_tot, Trans_tot) + + compute_toa_reflectace = Refl_tot + end function compute_toa_reflectace ! -------------------------------------------- pure subroutine two_stream(tauint, gint, w0int, ref, tra) @@ -1020,7 +1007,7 @@ elemental function two_stream_reflectance(tauint, gint, w0int) integer, parameter :: beam = 2 real, parameter :: xmu = 0.866, minConservativeW0 = 0.9999999 real :: tau, w0, g, f, gamma1, gamma2, gamma3, gamma4, & - rh, a1, a2, rk, r1, r2, r3, r4, r5, t1, t2, t3, t4, t5, beta, e1, e2, ef1, ef2, den, th + rh, a1, a2, rk, r1, r2, r3, r4, r5, t1, t2, t3, t4, t5, beta, e1, e2, ef1, ef2, den ! ------------------------ @@ -1044,7 +1031,7 @@ elemental function two_stream_reflectance(tauint, gint, w0int) two_stream_reflectance = gamma1*tau/(1 + gamma1*tau) endif - else ! + else ! ! Non-conservative scattering a1 = gamma1 * gamma4 + gamma2 * gamma3 @@ -1081,17 +1068,17 @@ elemental function two_stream_reflectance(tauint, gint, w0int) end if end function two_stream_reflectance ! -------------------------------------------- - pure subroutine adding_doubling (Refl, Tran, Refl_tot, Tran_tot) + pure subroutine adding_doubling (Refl, Tran, Refl_tot, Tran_tot) real, dimension(:), intent(in) :: Refl, Tran real, intent(out) :: Refl_tot, Tran_tot - ! - ! Use adding/doubling formulas to compute total reflectance and transmittance from layer values - ! - - integer :: i + ! + ! Use adding/doubling formulas to compute total reflectance and transmittance from layer values + ! + + integer :: i real, dimension(size(Refl)) :: Refl_cumulative, Tran_cumulative - Refl_cumulative(1) = Refl(1); Tran_cumulative(1) = Tran(1) + Refl_cumulative(1) = Refl(1); Tran_cumulative(1) = Tran(1) do i=2, size(Refl) ! place (add) previous combined layer(s) reflectance on top of layer i, w/black surface (or ignoring surface): @@ -1102,17 +1089,19 @@ pure subroutine adding_doubling (Refl, Tran, Refl_tot, Tran_tot) Refl_tot = Refl_cumulative(size(Refl)) Tran_tot = Tran_cumulative(size(Refl)) - end subroutine adding_doubling + end subroutine adding_doubling ! -------------------------------------------------- subroutine complain_and_die(message) character(len = *), intent(in) :: message -! write(6, *) "Failure in MODIS simulator" -! write(6, *) trim(message) -! flush(6) -! stop - call error_mesg ('modis_simulator', trim(message), FATAL) - +#ifdef COSP_GFDL + call error_mesg ('mod_modis_sim', trim(message), FATAL) +#else + write(6, *) "Failure in MODIS simulator" + write(6, *) trim(message) + flush(6) + stop +#endif end subroutine complain_and_die !------------------------------------------------------------------------------------------------ end module mod_modis_sim diff --git a/src/atmos_param/cosp/actsim/lidar_simulator.f90 b/src/atmos_param/cosp/actsim/lidar_simulator.F90 similarity index 97% rename from src/atmos_param/cosp/actsim/lidar_simulator.f90 rename to src/atmos_param/cosp/actsim/lidar_simulator.F90 index 5f2bc992f0..4859106d6d 100644 --- a/src/atmos_param/cosp/actsim/lidar_simulator.f90 +++ b/src/atmos_param/cosp/actsim/lidar_simulator.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- + +! $Id: lidar_simulator.F90,v 20.0 2013/12/13 23:15:57 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 -! $Id: lidar_simulator.f90,v 19.0 2012/01/06 20:04:15 fms Exp $ -! $Name: siena_201207 $ +#endif ! Copyright (c) 2009, Centre National de la Recherche Scientifique ! All rights reserved. @@ -79,11 +84,9 @@ SUBROUTINE lidar_simulator(npoints,nlev,npart,nrefl & ! - Bug fix in computation of pmol and pnorm of upper layer ! ! April 2008, J-L. Dufresne -! - Bug fix in computation of pmol and pnorm, thanks to Masaki Satoh: a -! factor 2 was missing. This affects the ATB values but not the -! cloud fraction. +! - Bug fix in computation of pmol and pnorm, thanks to Masaki Satoh: a factor 2 +! was missing. This affects the ATB values but not the cloud fraction. ! - !--------------------------------------------------------------------------------- ! ! Inputs: @@ -382,7 +385,9 @@ SUBROUTINE lidar_simulator(npoints,nlev,npart,nrefl & DO k= nlev-1, 1, -1 tautot_lay(:) = tautot(:,k)-tautot(:,k+1) ! optical thickness of layer k WHERE (tautot_lay(:).GT.0.) - pnorm(:,k) = betatot(:,k) * EXP(-2.0*tautot(:,k+1)) / (2.*tautot_lay(:)) & + pnorm(:,k) = betatot(:,k) * EXP(-2.0*tautot(:,k+1)) / (2.*tautot_lay(:)) & +!correc pnorm(:,k) = betatot(:,k) * EXP(-2.0*tautot(:,k+1)) & ! correc Satoh +!correc & / (2.0*tautot_lay(:)) & ! correc Satoh & * (1.-EXP(-2.0*tautot_lay(:))) ELSEWHERE ! This must never happend, but just in case, to avoid div. by 0 diff --git a/src/atmos_param/cosp/actsim/lmd_ipsl_stats.f90 b/src/atmos_param/cosp/actsim/lmd_ipsl_stats.F90 similarity index 73% rename from src/atmos_param/cosp/actsim/lmd_ipsl_stats.f90 rename to src/atmos_param/cosp/actsim/lmd_ipsl_stats.F90 index 7f00e1e566..a19aec7c2f 100644 --- a/src/atmos_param/cosp/actsim/lmd_ipsl_stats.f90 +++ b/src/atmos_param/cosp/actsim/lmd_ipsl_stats.F90 @@ -1,32 +1,35 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: lmd_ipsl_stats.f90,v 19.0 2012/01/06 20:04:17 fms Exp $ -! $Name: siena_201207 $ - +! $Id: lmd_ipsl_stats.F90,v 20.0 2013/12/13 23:15:58 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! Copyright (c) 2009, Centre National de la Recherche Scientifique ! All rights reserved. -! -! Redistribution and use in source and binary forms, with or without modification, are permitted +! +! Redistribution and use in source and binary forms, with or without modification, are permitted ! provided that the following conditions are met: -! -! * Redistributions of source code must retain the above copyright notice, this list +! +! * Redistributions of source code must retain the above copyright notice, this list ! of conditions and the following disclaimer. ! * Redistributions in binary form must reproduce the above copyright notice, this list -! of conditions and the following disclaimer in the documentation and/or other materials +! of conditions and the following disclaimer in the documentation and/or other materials ! provided with the distribution. ! * Neither the name of the LMD/IPSL/CNRS/UPMC nor the names of its -! contributors may be used to endorse or promote products derived from this software without +! contributors may be used to endorse or promote products derived from this software without ! specific prior written permission. -! -! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ! OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @@ -35,19 +38,26 @@ !------------------------------------------------------------------------------------ MODULE MOD_LMD_IPSL_STATS USE MOD_LLNL_STATS - use mod_cosp_constants + +#ifdef COSP_GFDL + use mod_cosp_constants, only : SR_BINS, LIDAR_UNDEF +#endif + IMPLICIT NONE -!RSH made module variables so can be accessed from cosp_driver_init for -! use in defining netcdf axes. +#ifdef COSP_GFDL +!RSH the following are made module variables so they can be used by both +! cosp_cfad_sr and define_srbval, which is called from cosp_driver_init +! to define netcdf axes. ! c threshold for cloud detection : - real S_clr - parameter (S_clr = 1.2) - real S_cld + real S_clr + parameter (S_clr = 1.2) + real S_cld ! parameter (S_cld = 3.0) ! Previous thresold for cloud detection - parameter (S_cld = 5.0) ! New (dec 2008) thresold for cloud detection - real S_att - parameter (S_att = 0.01) + parameter (S_cld = 5.0) ! New (dec 2008) thresold for cloud detection + real S_att + parameter (S_att = 0.01) +#endif CONTAINS SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & @@ -57,15 +67,15 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & ! ! ----------------------------------------------------------------------------------- ! Lidar outputs : -! +! ! Diagnose cloud fraction (3D cloud fraction + low/middle/high/total cloud fraction ! from the lidar signals (ATB and molecular ATB) computed from model outputs ! + ! Compute CFADs of lidar scattering ratio SR and of depolarization index -! +! ! Authors: Sandrine Bony and Helene Chepfer (LMD/IPSL, CNRS, UPMC, France). ! -! December 2008, S. Bony, H. Chepfer and J-L. Dufresne : +! December 2008, S. Bony, H. Chepfer and J-L. Dufresne : ! - change of the cloud detection threshold S_cld from 3 to 5, for better ! with both day and night observations. The optical thinest clouds are missed. ! - remove of the detection of the first fully attenuated layer encountered from above. @@ -75,6 +85,8 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & ! - Warning message regarding PARASOL being valid only over ocean deleted. ! February 2010, A. Bodas-Salcedo: ! - Undef passed into cosp_cfad_sr +! June 2010, T. Yokohata, T. Nishimura and K. Ogochi +! Optimisation of COSP_CFAD_SR ! ! Version 1.0 (June 2007) ! Version 1.1 (May 2008) @@ -92,20 +104,30 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & integer nrefl ! nb of solar zenith angles for parasol reflectances real undef ! undefined value - real pnorm(npoints,ncol,llm) ! lidar ATB + real pnorm(npoints,ncol,llm) ! lidar ATB real pmol(npoints,llm) ! molecular ATB - real land(npoints) ! Landmask [0 - Ocean, 1 - Land] + real land(npoints) ! Landmask [0 - Ocean, 1 - Land] real pplay(npoints,llm) ! pressure on model levels (Pa) logical ok_lidar_cfad ! true if lidar CFAD diagnostics need to be computed real refl(npoints,ncol,nrefl) ! subgrid parasol reflectance ! parasol ! c outputs : - real lidarcld(npoints,llm) ! 3D "lidar" cloud fraction + real lidarcld(npoints,llm) ! 3D "lidar" cloud fraction real cldlayer(npoints,ncat) ! "lidar" cloud fraction (low, mid, high, total) - real cfad2(npoints,max_bin,llm) ! CFADs of SR - real srbval(max_bin) ! SR bins in CFADs + real cfad2(npoints,max_bin,llm) ! CFADs of SR + real srbval(max_bin) ! SR bins in CFADs real parasolrefl(npoints,nrefl)! grid-averaged parasol reflectance +#ifndef COSP_GFDL +! c threshold for cloud detection : + real S_clr + parameter (S_clr = 1.2) + real S_cld +! parameter (S_cld = 3.0) ! Previous thresold for cloud detection + parameter (S_cld = 5.0) ! New (dec 2008) thresold for cloud detection + real S_att + parameter (S_att = 0.01) +#endif ! c local variables : integer ic,k @@ -125,7 +147,7 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & ! c 1- Lidar scattering ratio : ! c ------------------------------------------------------- ! -! where ((pnorm.lt.xmax) .and. (pmol.lt.xmax) .and. (pmol.gt. 0.0 )) +! where ((pnorm.lt.xmax) .and. (pmol.lt.xmax) .and. (pmol.gt. 0.0 )) ! x3d = pnorm/pmol ! elsewhere ! x3d = undef @@ -133,7 +155,7 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & ! A.B-S: pmol reduced to 2D (npoints,llm) (Dec 08) do ic = 1, ncol pnorm_c = pnorm(:,ic,:) - where ((pnorm_c.lt.xmax) .and. (pmol.lt.xmax) .and. (pmol.gt. 0.0 )) + where ((pnorm_c.lt.xmax) .and. (pmol.lt.xmax) .and. (pmol.gt. 0.0 )) x3d_c = pnorm_c/pmol elsewhere x3d_c = undef @@ -151,13 +173,13 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & cldlayer) ! c ------------------------------------------------------- -! c 3- CFADs +! c 3- CFADs ! c ------------------------------------------------------- if (ok_lidar_cfad) then ! ! c CFADs of subgrid-scale lidar scattering ratios : ! c ------------------------------------------------------- - CALL COSP_CFAD_SR(npoints,ncol,llm,max_bin, undef, & + CALL COSP_CFAD_SR(npoints,ncol,llm,max_bin,undef, & x3d, & S_att,S_clr,xmax,cfad2,srbval) @@ -181,13 +203,13 @@ SUBROUTINE diag_lidar(npoints,ncol,llm,max_bin,nrefl & ! if land=1 -> parasolrefl=undef ! if land=0 -> parasolrefl=parasolrefl parasolrefl(:,k) = parasolrefl(:,k) * MAX(1.0-land(:),0.0) & - + (1.0 - MAX(1.0-land(:),0.0))*undef + + (1.0 - MAX(1.0-land(:),0.0))*undef enddo RETURN END SUBROUTINE diag_lidar - - + + !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% !-------------------- FUNCTION COSP_CFAD_SR ------------------------ ! Author: Sandrine Bony (LMD/IPSL, CNRS, Paris) @@ -229,43 +251,58 @@ SUBROUTINE COSP_CFAD_SR(Npoints,Ncolumns,Nlevels,Nbins,undef, & ! c ------------------------------------------------------- if ( Nbins .lt. 6) return +#ifdef COSP_GFDL call define_srbval (srbval) - - +#else + srbval(1) = S_att + srbval(2) = S_clr + srbval(3) = 3.0 + srbval(4) = 5.0 + srbval(5) = 7.0 + srbval(6) = 10.0 + do i = 7, MIN(10,Nbins) + srbval(i) = srbval(i-1) + 5.0 + enddo + DO i = 11, MIN(13,Nbins) + srbval(i) = srbval(i-1) + 10.0 + enddo + srbval(MIN(14,Nbins)) = 80.0 + srbval(Nbins) = xmax +#endif cfad(:,:,:) = 0.0 srbval_ext(1:Nbins) = srbval srbval_ext(0) = -1.0 - ! c ------------------------------------------------------- ! c c- Compute CFAD ! c ------------------------------------------------------- do j = 1, Nlevels - do ib = 1, Nbins - do i = 1, Npoints + do ib = 1, Nbins do k = 1, Ncolumns - if (x(i,k,j) /= undef) then - if ((x(i,k,j).gt.srbval_ext(ib-1)).and.(x(i,k,j).le.srbval_ext(ib))) & - cfad(i,ib,j) = cfad(i,ib,j) + 1.0 - else - cfad(i,:,j) = undef - endif + do i = 1, Npoints + if (x(i,k,j) /= undef) then + if ((x(i,k,j).gt.srbval_ext(ib-1)).and.(x(i,k,j).le.srbval_ext(ib))) & + cfad(i,ib,j) = cfad(i,ib,j) + 1.0 + else + cfad(i,ib,j) = undef + endif + enddo enddo - enddo - enddo !k - enddo !j - + enddo + enddo + where (cfad .ne. undef) cfad = cfad / float(Ncolumns) ! c ------------------------------------------------------- RETURN END SUBROUTINE COSP_CFAD_SR +#ifdef COSP_GFDL -subroutine define_srbval (srbval) - + subroutine define_srbval (srbval) + real, dimension(:), intent(out) :: srbval integer :: i, Nbins @@ -289,11 +326,12 @@ subroutine define_srbval (srbval) end subroutine define_srbval +#endif - + !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% !-------------------- SUBROUTINE COSP_CLDFRAC ------------------- -! c Purpose: Cloud fraction diagnosed from lidar measurements +! c Purpose: Cloud fraction diagnosed from lidar measurements !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & x,pplay,S_att,S_cld,undef,lidarcld, & @@ -316,10 +354,17 @@ SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & real cldlay(Npoints,Ncolumns,Ncat) real nsublay(Npoints,Ncolumns,Ncat), nsublayer(Npoints,Ncat) real nsub(Npoints,Nlevels) - +#ifdef SYS_SX + real cldlay1(Npoints,Ncolumns) + real cldlay2(Npoints,Ncolumns) + real cldlay3(Npoints,Ncolumns) + real nsublay1(Npoints,Ncolumns) + real nsublay2(Npoints,Ncolumns) + real nsublay3(Npoints,Ncolumns) +#endif ! --------------------------------------------------------------- -! 1- initialization +! 1- initialization ! --------------------------------------------------------------- if ( Ncat .ne. 4 ) then @@ -346,7 +391,7 @@ SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & endwhere ! number of usefull sub-columns: - where ( (x(:,:,k).gt.S_att) .and. (x(:,:,k).ne. undef) ) + where ( (x(:,:,k).gt.S_att) .and. (x(:,:,k).ne. undef) ) srok(:,:,k)=1.0 elsewhere srok(:,:,k)=0.0 @@ -358,7 +403,50 @@ SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & ! 3- grid-box 3D cloud fraction and layered cloud fractions (ISCCP pressure ! categories) : ! --------------------------------------------------------------- + lidarcld = 0.0 + nsub = 0.0 +#ifdef SYS_SX +!! XXX: Use cldlay[1-3] and nsublay[1-3] to avoid bank-conflicts. + cldlay1 = 0.0 + cldlay2 = 0.0 + cldlay3 = 0.0 + cldlay(:,:,4) = 0.0 !! XXX: Ncat == 4 + nsublay1 = 0.0 + nsublay2 = 0.0 + nsublay3 = 0.0 + nsublay(:,:,4) = 0.0 + do k = Nlevels, 1, -1 + do ic = 1, Ncolumns + do ip = 1, Npoints + p1 = pplay(ip,k) + + if ( p1.gt.0. .and. p1.lt.(440.*100.)) then ! high clouds + cldlay3(ip,ic) = MAX(cldlay3(ip,ic), cldy(ip,ic,k)) + nsublay3(ip,ic) = MAX(nsublay3(ip,ic), srok(ip,ic,k)) + else if(p1.ge.(440.*100.) .and. p1.lt.(680.*100.)) then ! mid clouds + cldlay2(ip,ic) = MAX(cldlay2(ip,ic), cldy(ip,ic,k)) + nsublay2(ip,ic) = MAX(nsublay2(ip,ic), srok(ip,ic,k)) + else + cldlay1(ip,ic) = MAX(cldlay1(ip,ic), cldy(ip,ic,k)) + nsublay1(ip,ic) = MAX(nsublay1(ip,ic), srok(ip,ic,k)) + endif + cldlay(ip,ic,4) = MAX(cldlay(ip,ic,4), cldy(ip,ic,k)) + lidarcld(ip,k)=lidarcld(ip,k) + cldy(ip,ic,k) + nsublay(ip,ic,4) = MAX(nsublay(ip,ic,4),srok(ip,ic,k)) + nsub(ip,k)=nsub(ip,k) + srok(ip,ic,k) + enddo + enddo + enddo + cldlay(:,:,1) = cldlay1 + cldlay(:,:,2) = cldlay2 + cldlay(:,:,3) = cldlay3 + nsublay(:,:,1) = nsublay1 + nsublay(:,:,2) = nsublay2 + nsublay(:,:,3) = nsublay3 +#else + cldlay = 0.0 + nsublay = 0.0 do k = Nlevels, 1, -1 do ic = 1, Ncolumns do ip = 1, Npoints @@ -382,6 +470,7 @@ SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & enddo enddo enddo +#endif ! -- grid-box 3D cloud fraction @@ -399,8 +488,8 @@ SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & do iz = 1, Ncat do ic = 1, Ncolumns - cldlayer(:,iz)=cldlayer(:,iz) + cldlay(:,ic,iz) - nsublayer(:,iz)=nsublayer(:,iz) + nsublay(:,ic,iz) + cldlayer(:,iz)=cldlayer(:,iz) + cldlay(:,ic,iz) + nsublayer(:,iz)=nsublayer(:,iz) + nsublay(:,ic,iz) enddo enddo @@ -413,5 +502,5 @@ SUBROUTINE COSP_CLDFRAC(Npoints,Ncolumns,Nlevels,Ncat, & RETURN END SUBROUTINE COSP_CLDFRAC ! --------------------------------------------------------------- - + END MODULE MOD_LMD_IPSL_STATS diff --git a/src/atmos_param/cosp/cosp.F90 b/src/atmos_param/cosp/cosp.F90 index 485d125efc..66e7b040e0 100644 --- a/src/atmos_param/cosp/cosp.F90 +++ b/src/atmos_param/cosp/cosp.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: cosp.F90,v 19.0 2012/01/06 20:02:49 fms Exp $ -! $Name: siena_201207 $ +! $Id: cosp.F90,v 20.0 2013/12/13 23:10:35 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -29,7 +34,10 @@ ! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ! OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef COSP_GFDL #include "cosp_defs.h" +#endif MODULE MOD_COSP USE MOD_COSP_TYPES USE MOD_COSP_SIMULATOR @@ -43,13 +51,19 @@ MODULE MOD_COSP !--------------------- SUBROUTINE COSP --------------------------- !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef RTTOV -SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar, sghydro,cloud_type) +#ifdef COSP_GFDL +SUBROUTINE COSP(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar,sghydro,cloud_type) #else -SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro, cloud_type) +SUBROUTINE COSP(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) +#endif COSP_GFDL +#else +#ifdef COSP_GFDL +SUBROUTINE COSP(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro, cloud_type) +#else +SUBROUTINE COSP(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) +#endif COSP_GFDL #endif - ! Arguments - integer, intent(in) :: me integer,intent(in) :: overlap ! overlap type in SCOPS: 1=max, 2=rand, 3=max/rand integer,intent(in) :: Ncolumns type(cosp_config),intent(in) :: cfg ! Configuration options @@ -60,15 +74,17 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr type(cosp_sglidar),intent(inout) :: sglidar ! Output from lidar simulator type(cosp_isccp),intent(inout) :: isccp ! Output from ISCCP simulator type(cosp_misr),intent(inout) :: misr ! Output from MISR simulator - type(cosp_MODIS),intent(inout) :: modis ! Output from MODIS simulator + type(cosp_modis),intent(inout) :: modis ! Output from MODIS simulator #ifdef RTTOV type(cosp_rttov),intent(inout) :: rttov ! Output from RTTOV #endif type(cosp_radarstats),intent(inout) :: stradar ! Summary statistics from radar simulator type(cosp_lidarstats),intent(inout) :: stlidar ! Summary statistics from lidar simulator +#ifdef COSP_GFDL type(cosp_sghydro), intent(inout) :: sghydro ! Subgrid info for hydrometeors en each iteration real, dimension(gbx%Npoints, Ncolumns, gbx%Nlevels), & - intent(in), optional :: cloud_type + intent(in), optional :: cloud_type +#endif ! Local variables integer :: Npoints ! Number of gridpoints @@ -76,10 +92,9 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr integer :: Nhydro ! Number of hydrometeors integer :: Niter ! Number of calls to cosp_simulator integer :: i_first,i_last ! First and last gridbox to be processed in each iteration - integer :: i,j,k,Ni + integer :: i,Ni integer,dimension(2) :: ix,iy logical :: reff_zero - real :: minv,maxv real :: maxp,minp integer,dimension(:),allocatable :: & ! Dimensions nPoints seed ! It is recommended that the seed is set to a different value for each model @@ -89,12 +104,14 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr ! Types used in one iteration type(cosp_gridbox) :: gbx_it type(cosp_subgrid) :: sgx_it +#ifdef COSP_GFDL type(cosp_sghydro) :: sghydro_it +#endif type(cosp_vgrid) :: vgrid_it type(cosp_sgradar) :: sgradar_it type(cosp_sglidar) :: sglidar_it type(cosp_isccp) :: isccp_it - type(cosp_MODIS) :: modis_it + type(cosp_modis) :: modis_it type(cosp_misr) :: misr_it #ifdef RTTOV type(cosp_rttov) :: rttov_it @@ -138,7 +155,6 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr call cosp_check_input('mr_hydro',gbx%mr_hydro,min_val=0.0) ! Effective radius [m]. (Npoints,Nlevels,Nhydro) call cosp_check_input('Reff',gbx%Reff,min_val=0.0) - reff_zero=.true. if (any(gbx%Reff > 1.e-8)) then reff_zero=.false. @@ -157,7 +173,8 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr ! Aerosols concentration and distribution parameters call cosp_check_input('conc_aero',gbx%conc_aero,min_val=0.0) - ! Check sg tau, emiss, mrs and sizes if they are being input from +#ifdef COSP_GFDL + ! Check sg tau, emiss, mrs and sizes if they are being input from ! model if (sgx%cols_input_from_model) then call cosp_check_input('sgx%Reff1',sghydro%Reff(:,:,:,1),min_val=0.0) @@ -166,11 +183,34 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr call cosp_check_input('sgx%Reff6',sghydro%Reff(:,:,:,6),min_val=0.0) call cosp_check_input('sgx% mr1',sghydro%mr_hydro(:,:,:,1),min_val=0.0) call cosp_check_input('sgx% mr2',sghydro%mr_hydro(:,:,:,2),min_val=0.0) - call cosp_check_input('sgx% mr5',sghydro%mr_hydro(:,:,:,5),min_val=0.0) + call cosp_check_input('sgx% mr5',sghydro%mr_hydro(:,:,:,5),min_val=0.0) call cosp_check_input('sgx% mr6',sghydro%mr_hydro(:,:,:,6),min_val=0.0) - call cosp_check_input('sgx% tau',sgx%dtau_col,min_val=0.0) + call cosp_check_input('sgx% tau',sgx%dtau_col,min_val=0.0) call cosp_check_input('sgx% em',sgx%dem_col,min_val=0.0) endif +#else + ! Checks for CRM mode + if (Ncolumns == 1) then + if (gbx%use_precipitation_fluxes) then + print *, '---------- COSP ERROR ------------' + print *, '' + print *, 'Use of precipitation fluxes not supported in CRM mode (Ncolumns=1)' + print *, '' + print *, '----------------------------------' + stop + endif + if ((maxval(gbx%dtau_c) > 0.0).or.(maxval(gbx%dem_c) > 0.0)) then + print *, '---------- COSP ERROR ------------' + print *, '' + print *, ' dtau_c > 0.0 or dem_c > 0.0. In CRM mode (Ncolumns=1), ' + print *, ' the optical depth (emmisivity) of all clouds must be ' + print *, ' passed through dtau_s (dem_s)' + print *, '' + print *, '----------------------------------' + stop + endif + endif +#endif ! We base the seed in the decimal part of the surface pressure. allocate(seed(Npoints)) @@ -180,13 +220,25 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr minp = minval(gbx%psfc) maxp = maxval(gbx%psfc) if (Npoints .gt. 1) seed=int((gbx%psfc-minp)/(maxp-minp)*100000) + 1 + ! Below it's how it was done in the original implementation of the ISCCP simulator. + ! The one above is better for offline data, when you may have packed data + ! that subsamples the decimal fraction of the surface pressure. +! if (Npoints .gt. 1) seed=(gbx%psfc-int(gbx%psfc))*1000000 if (gbx%Npoints_it >= gbx%Npoints) then ! One iteration gbx%Npoints #ifdef RTTOV - call cosp_iter(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar,sghydro,cloud_type) +#ifdef COSP_GFDL + call cosp_iter(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar,sghydro,cloud_type) +#else + call cosp_iter(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) +#endif +#else +#ifdef COSP_GFDL + call cosp_iter(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro,cloud_type) #else - call cosp_iter(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro,cloud_type) + call cosp_iter(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) +#endif #endif else ! Several iterations to save memory Niter = gbx%Npoints/gbx%Npoints_it ! Integer division @@ -210,11 +262,17 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr gbx_it) call construct_cosp_vgrid(gbx_it,vgrid%Nlvgrid,vgrid%use_vgrid,vgrid%csat_vgrid,vgrid_it) call construct_cosp_subgrid(Ni, Ncolumns, Nlevels, sgx_it) +#ifdef COSP_GFDL call construct_cosp_sghydro(Ni, Ncolumns, Nlevels, N_hydro, sghydro_it) +#endif call construct_cosp_sgradar(cfg,Ni,Ncolumns,Nlevels,N_HYDRO,sgradar_it) call construct_cosp_sglidar(cfg,Ni,Ncolumns,Nlevels,N_HYDRO,PARASOL_NREFL,sglidar_it) call construct_cosp_isccp(cfg,Ni,Ncolumns,Nlevels,isccp_it) +#ifdef COSP_GFDL call construct_cosp_modis(cfg, Ni, Ncolumns, modis_it) +#else + call construct_cosp_modis(cfg, Ni, modis_it) +#endif call construct_cosp_misr(cfg,Ni,misr_it) #ifdef RTTOV call construct_cosp_rttov(Ni,gbx%nchan,rttov_it) @@ -224,7 +282,9 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr elseif (i == Niter) then ! last iteration call free_cosp_gridbox(gbx_it,.true.) call free_cosp_subgrid(sgx_it) +#ifdef COSP_GFDL call free_cosp_sghydro(sghydro_it) +#endif call free_cosp_vgrid(vgrid_it) call free_cosp_sgradar(sgradar_it) call free_cosp_sglidar(sglidar_it) @@ -237,8 +297,8 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr call free_cosp_radarstats(stradar_it) call free_cosp_lidarstats(stlidar_it) ! Allocate types for iterations - call construct_cosp_gridbox(gbx%time,gbx%time_bnds,gbx%radar_freq,gbx%surface_radar,gbx%use_mie_tables, & - gbx%use_gas_abs,gbx%do_ray,gbx%melt_lay,gbx%k2,Ni,Nlevels, & + call construct_cosp_gridbox(gbx%time,gbx%time_bnds,gbx%radar_freq,gbx%surface_radar,gbx%use_mie_tables, & + gbx%use_gas_abs,gbx%do_ray,gbx%melt_lay,gbx%k2,Ni,Nlevels, & Ncolumns,N_HYDRO,gbx%Nprmts_max_hydro, & gbx%Naero,gbx%Nprmts_max_aero,Ni,gbx%lidar_ice_type,gbx%isccp_top_height, & gbx%isccp_top_height_direction,gbx%isccp_overlap,gbx%isccp_emsfc_lw, & @@ -252,15 +312,21 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr gbx_it%dist_type_aero = gbx_it%dist_type_aero call construct_cosp_vgrid(gbx_it,vgrid%Nlvgrid,vgrid%use_vgrid,vgrid%csat_vgrid,vgrid_it) call construct_cosp_subgrid(Ni, Ncolumns, Nlevels, sgx_it) +#ifdef COSP_GFDL call construct_cosp_sghydro(Ni, Ncolumns, Nlevels, N_hydro, sghydro_it) +#endif call construct_cosp_sgradar(cfg,Ni,Ncolumns,Nlevels,N_HYDRO,sgradar_it) call construct_cosp_sglidar(cfg,Ni,Ncolumns,Nlevels,N_HYDRO,PARASOL_NREFL,sglidar_it) call construct_cosp_isccp(cfg,Ni,Ncolumns,Nlevels,isccp_it) +#ifdef COSP_GFDL call construct_cosp_modis(cfg,Ni, Ncolumns, modis_it) +#else + call construct_cosp_modis(cfg,Ni, modis_it) +#endif call construct_cosp_misr(cfg,Ni,misr_it) #ifdef RTTOV - call construct_cosp_rttov(Ni,gbx%nchan,rttov_it) -#endif + call construct_cosp_rttov(Ni,gbx%nchan,rttov_it) +#endif call construct_cosp_radarstats(cfg,Ni,Ncolumns,vgrid%Nlvgrid,N_HYDRO,stradar_it) call construct_cosp_lidarstats(cfg,Ni,Ncolumns,vgrid%Nlvgrid,N_HYDRO,PARASOL_NREFL,stlidar_it) endif @@ -276,19 +342,28 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr if (cfg%Lmodis_sim) call cosp_modis_cpsection(ix,iy,modis,modis_it) if (cfg%Lmisr_sim) call cosp_misr_cpsection(ix,iy,misr,misr_it) #ifdef RTTOV - if (cfg%Lrttov_sim) call cosp_rttov_cpsection(ix,iy,rttov,rttov_it) + if (cfg%Lrttov_sim) call cosp_rttov_cpsection(ix,iy,rttov,rttov_it) #endif if (cfg%Lradar_sim) call cosp_radarstats_cpsection(ix,iy,stradar,stradar_it) if (cfg%Llidar_sim) call cosp_lidarstats_cpsection(ix,iy,stlidar,stlidar_it) - print *,'---------ix: ',ix +! print *,'---------ix: ',ix #ifdef RTTOV - call cosp_iter(me,overlap,seed(ix(1):ix(2)),cfg,vgrid_it,gbx_it,sgx_it,sgradar_it, & +#ifdef COSP_GFDL + call cosp_iter(overlap,seed(ix(1):ix(2)),cfg,vgrid_it,gbx_it,sgx_it,sgradar_it, & sglidar_it,isccp_it,misr_it,modis_it,rttov_it,stradar_it,stlidar_it, sghydro_it, cloud_type) #else - call cosp_iter(me, overlap,seed(ix(1):ix(2)),cfg,vgrid_it,gbx_it,sgx_it,sgradar_it, & + call cosp_iter(overlap,seed(ix(1):ix(2)),cfg,vgrid_it,gbx_it,sgx_it,sgradar_it, & + sglidar_it,isccp_it,misr_it,modis_it,rttov_it,stradar_it,stlidar_it) +#endif +#else +#ifdef COSP_GFDL + call cosp_iter( overlap,seed(ix(1):ix(2)),cfg,vgrid_it,gbx_it,sgx_it,sgradar_it, & sglidar_it,isccp_it,misr_it,modis_it,stradar_it,stlidar_it, sghydro_it,cloud_type) +#else + call cosp_iter(overlap,seed(ix(1):ix(2)),cfg,vgrid_it,gbx_it,sgx_it,sgradar_it, & + sglidar_it,isccp_it,misr_it,modis_it,stradar_it,stlidar_it) +#endif #endif - ! --- Copy results to output structures --- ix=(/1,Ni/) iy=(/i_first,i_last/) @@ -299,15 +374,17 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr if (cfg%Lmodis_sim) call cosp_modis_cpsection(ix,iy,modis_it,modis) if (cfg%Lmisr_sim) call cosp_misr_cpsection(ix,iy,misr_it,misr) #ifdef RTTOV - if (cfg%Lrttov_sim) call cosp_rttov_cpsection(ix,iy,rttov_it,rttov) -#endif + if (cfg%Lrttov_sim) call cosp_rttov_cpsection(ix,iy,rttov_it,rttov) +#endif if (cfg%Lradar_sim) call cosp_radarstats_cpsection(ix,iy,stradar_it,stradar) if (cfg%Llidar_sim) call cosp_lidarstats_cpsection(ix,iy,stlidar_it,stlidar) enddo ! Deallocate types call free_cosp_gridbox(gbx_it,.true.) call free_cosp_subgrid(sgx_it) +#ifdef COSP_GFDL call free_cosp_sghydro(sghydro_it) +#endif call free_cosp_vgrid(vgrid_it) call free_cosp_sgradar(sgradar_it) call free_cosp_sglidar(sglidar_it) @@ -315,7 +392,7 @@ SUBROUTINE COSP(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr call free_cosp_modis(modis_it) call free_cosp_misr(misr_it) #ifdef RTTOV - call free_cosp_rttov(rttov_it) + call free_cosp_rttov(rttov_it) #endif call free_cosp_radarstats(stradar_it) call free_cosp_lidarstats(stlidar_it) @@ -329,13 +406,19 @@ END SUBROUTINE COSP !--------------------- SUBROUTINE COSP_ITER ---------------------- !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef RTTOV -SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar, sghydro, cloud_type) +#ifdef COSP_GFDL +SUBROUTINE COSP_ITER(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar, sghydro, cloud_type) #else -SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro,cloud_type) +SUBROUTINE COSP_ITER(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) +#endif +#else +#ifdef COSP_GFDL +SUBROUTINE COSP_ITER(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro,cloud_type) +#else +SUBROUTINE COSP_ITER(overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) +#endif #endif - ! Arguments - integer, intent(in) :: me integer,intent(in) :: overlap ! overlap type in SCOPS: 1=max, 2=rand, 3=max/rand integer,dimension(:),intent(in) :: seed type(cosp_config),intent(in) :: cfg ! Configuration options @@ -352,17 +435,20 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis #endif type(cosp_radarstats),intent(inout) :: stradar ! Summary statistics from radar simulator type(cosp_lidarstats),intent(inout) :: stlidar ! Summary statistics from lidar simulator +#ifdef COSP_GFDL type(cosp_sghydro), intent(inout) :: sghydro ! Subgrid info for hydrometeors en each iteration real, dimension(gbx%Npoints, gbx%Ncolumns, gbx%Nlevels), & intent(in), optional :: cloud_type +#endif + ! Local variables integer :: Npoints ! Number of gridpoints integer :: Ncolumns ! Number of subcolumns integer :: Nlevels ! Number of levels integer :: Nhydro ! Number of hydrometeors - integer :: Niter ! Number of calls to cosp_simulator integer :: i,j,k + integer :: I_HYDRO real,dimension(:,:),pointer :: column_frac_out ! Array with one column of frac_out integer :: scops_debug=0 ! set to non-zero value to print out inputs for debugging in SCOPS real,dimension(:, :),allocatable :: cca_scops,ls_p_rate,cv_p_rate, & @@ -370,7 +456,10 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis ! Levels are from TOA to SURFACE. (nPoints, nLev) real,dimension(:,:),allocatable :: frac_ls,prec_ls,frac_cv,prec_cv ! Cloud/Precipitation fraction in each model level ! Levels are from SURFACE to TOA -! type(cosp_sghydro) :: sghydro ! Subgrid info for hydrometeors en each iteration + real,dimension(:,:),allocatable :: rho ! (Npoints, Nlevels). Atmospheric density +#ifndef COSP_GFDL + type(cosp_sghydro) :: sghydro ! Subgrid info for hydrometeors en each iteration +#endif !++++++++++ Dimensions ++++++++++++ @@ -378,7 +467,7 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis Ncolumns = gbx%Ncolumns Nlevels = gbx%Nlevels Nhydro = gbx%Nhydro - + !++++++++++ Climate/NWP mode ++++++++++ if (Ncolumns > 1) then !++++++++++ Subgrid sampling ++++++++++ @@ -391,18 +480,27 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis prec_ls=0.0 frac_cv=0.0 prec_cv=0.0 - +#ifdef COSP_GFDL IF (sgx%cols_input_from_model) then sgx%frac_out = cloud_type ELSE ! Cloud fractions for SCOPS from TOA to SFC tca_scops = gbx%tca(:,Nlevels:1:-1) cca_scops = gbx%cca(:,Nlevels:1:-1) - + ! Call to SCOPS ! strat and conv arrays are passed with levels from TOA to SURFACE. call scops(Npoints,Nlevels,Ncolumns,seed,tca_scops,cca_scops,overlap,sgx%frac_out,scops_debug) ENDIF +#else + ! Cloud fractions for SCOPS from TOA to SFC + tca_scops = gbx%tca(:,Nlevels:1:-1) + cca_scops = gbx%cca(:,Nlevels:1:-1) + + ! Call to SCOPS + ! strat and conv arrays are passed with levels from TOA to SURFACE. + call scops(Npoints,Nlevels,Ncolumns,seed,tca_scops,cca_scops,overlap,sgx%frac_out,scops_debug) +#endif ! temporarily use prec_ls/cv to transfer information about precipitation flux into prec_scops if(gbx%use_precipitation_fluxes) then @@ -422,8 +520,8 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis do j=1,Npoints,1 do k=1,Nlevels,1 do i=1,Ncolumns,1 - if (sgx%frac_out (j,i,Nlevels+1-k) .eq. I_LSC) frac_ls(j,k)=frac_ls(j,k)+1. - if (sgx%frac_out (j,i,Nlevels+1-k) .eq. I_CVC) frac_cv(j,k)=frac_cv(j,k)+1. + if (sgx%frac_out (j,i,Nlevels+1-k) == I_LSC) frac_ls(j,k)=frac_ls(j,k)+1. + if (sgx%frac_out (j,i,Nlevels+1-k) == I_CVC) frac_cv(j,k)=frac_cv(j,k)+1. if (sgx%prec_frac(j,i,Nlevels+1-k) .eq. 1) prec_ls(j,k)=prec_ls(j,k)+1. if (sgx%prec_frac(j,i,Nlevels+1-k) .eq. 2) prec_cv(j,k)=prec_cv(j,k)+1. if (sgx%prec_frac(j,i,Nlevels+1-k) .eq. 3) then @@ -452,14 +550,39 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis ! Deallocate arrays that will no longer be used deallocate(tca_scops,cca_scops,ls_p_rate,cv_p_rate) - + ! Populate the subgrid arrays -! call construct_cosp_sghydro(Npoints,Ncolumns,Nlevels,Nhydro,sghydro) +#ifndef COSP_GFDL + call construct_cosp_sghydro(Npoints,Ncolumns,Nlevels,Nhydro,sghydro) +#endif do k=1,Ncolumns +#ifdef COSP_GFDL IF (sgx%cols_input_from_model) then -! the sghydro%mr_hydro cloud components were previously defined in -! cosp_driver and have been passed in +! the sghydro%mr_hydro cloud components were previously defined in +! cosp_driver and have been passed in ELSE + !--------- Mixing ratios for clouds and Reff for Clouds and precip ------- + column_frac_out => sgx%frac_out(:,k,:) + where (column_frac_out == I_LSC) !+++++++++++ LS clouds ++++++++ + sghydro%mr_hydro(:,k,:,I_LSCLIQ) = gbx%mr_hydro(:,:,I_LSCLIQ) + sghydro%mr_hydro(:,k,:,I_LSCICE) = gbx%mr_hydro(:,:,I_LSCICE) + + sghydro%Reff(:,k,:,I_LSCLIQ) = gbx%Reff(:,:,I_LSCLIQ) + sghydro%Reff(:,k,:,I_LSCICE) = gbx%Reff(:,:,I_LSCICE) + sghydro%Reff(:,k,:,I_LSRAIN) = gbx%Reff(:,:,I_LSRAIN) + sghydro%Reff(:,k,:,I_LSSNOW) = gbx%Reff(:,:,I_LSSNOW) + sghydro%Reff(:,k,:,I_LSGRPL) = gbx%Reff(:,:,I_LSGRPL) + elsewhere (column_frac_out == I_CVC) !+++++++++++ CONV clouds ++++++++ + sghydro%mr_hydro(:,k,:,I_CVCLIQ) = gbx%mr_hydro(:,:,I_CVCLIQ) + sghydro%mr_hydro(:,k,:,I_CVCICE) = gbx%mr_hydro(:,:,I_CVCICE) + + sghydro%Reff(:,k,:,I_CVCLIQ) = gbx%Reff(:,:,I_CVCLIQ) + sghydro%Reff(:,k,:,I_CVCICE) = gbx%Reff(:,:,I_CVCICE) + sghydro%Reff(:,k,:,I_CVRAIN) = gbx%Reff(:,:,I_CVRAIN) + sghydro%Reff(:,k,:,I_CVSNOW) = gbx%Reff(:,:,I_CVSNOW) + end where +ENDIF +#else !--------- Mixing ratios for clouds and Reff for Clouds and precip ------- column_frac_out => sgx%frac_out(:,k,:) where (column_frac_out == I_LSC) !+++++++++++ LS clouds ++++++++ @@ -480,7 +603,7 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis sghydro%Reff(:,k,:,I_CVRAIN) = gbx%Reff(:,:,I_CVRAIN) sghydro%Reff(:,k,:,I_CVSNOW) = gbx%Reff(:,:,I_CVSNOW) end where -ENDIF +#endif !--------- Precip ------- if (.not. gbx%use_precipitation_fluxes) then where (column_frac_out == I_LSC) !+++++++++++ LS Precipitation ++++++++ @@ -496,9 +619,21 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis ! convert the mixing ratio and precipitation flux from gridbox mean to the fraction-based values do k=1,Nlevels do j=1,Npoints +#ifdef COSP_GFDL !RSH: When columns are input, are already in-cloud values. IF (sgx%cols_input_from_model) then ELSE + !--------- Clouds ------- + if (frac_ls(j,k) .ne. 0.) then + sghydro%mr_hydro(j,:,k,I_LSCLIQ) = sghydro%mr_hydro(j,:, k,I_LSCLIQ)/frac_ls(j,k) + sghydro%mr_hydro(j,:,k,I_LSCICE) = sghydro%mr_hydro(j,:, k,I_LSCICE)/frac_ls(j,k) + endif + if (frac_cv(j,k) .ne. 0.) then + sghydro%mr_hydro(j,:,k,I_CVCLIQ) = sghydro%mr_hydro(j,:,k,I_CVCLIQ)/frac_cv(j,k) + sghydro%mr_hydro(j,:,k,I_CVCICE) = sghydro%mr_hydro(j,:,k,I_CVCICE)/frac_cv(j,k) + endif +ENDIF +#else !--------- Clouds ------- if (frac_ls(j,k) .ne. 0.) then sghydro%mr_hydro(j,:,k,I_LSCLIQ) = sghydro%mr_hydro(j,:,k,I_LSCLIQ)/frac_ls(j,k) @@ -508,7 +643,7 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis sghydro%mr_hydro(j,:,k,I_CVCLIQ) = sghydro%mr_hydro(j,:,k,I_CVCLIQ)/frac_cv(j,k) sghydro%mr_hydro(j,:,k,I_CVCICE) = sghydro%mr_hydro(j,:,k,I_CVCICE)/frac_cv(j,k) endif -ENDIF +#endif !--------- Precip ------- if (gbx%use_precipitation_fluxes) then if (prec_ls(j,k) .ne. 0.) then @@ -536,16 +671,45 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis deallocate(frac_ls,prec_ls,frac_cv,prec_cv) if (gbx%use_precipitation_fluxes) then - ! convert precipitation flux into mixing ratio - - call pf_to_mr(me,Npoints,Nlevels,Ncolumns,gbx%rain_ls,gbx%snow_ls,gbx%grpl_ls, & - gbx%rain_cv,gbx%snow_cv,sgx%prec_frac,gbx%p,gbx%T, & - sghydro%mr_hydro(:,:,:,I_LSRAIN),sghydro%mr_hydro(:,:,:,I_LSSNOW),sghydro%mr_hydro(:,:,:,I_LSGRPL), & - sghydro%mr_hydro(:,:,:,I_CVRAIN),sghydro%mr_hydro(:,:,:,I_CVSNOW)) + ! Density + allocate(rho(Npoints,Nlevels)) + I_HYDRO = I_LSRAIN + call cosp_precip_mxratio(Npoints,Nlevels,Ncolumns,gbx%p,gbx%T,sgx%prec_frac,1., & + n_ax(I_HYDRO),n_bx(I_HYDRO),alpha_x(I_HYDRO),c_x(I_HYDRO),d_x(I_HYDRO), & + g_x(I_HYDRO),a_x(I_HYDRO),b_x(I_HYDRO), & + gamma_1(I_HYDRO),gamma_2(I_HYDRO),gamma_3(I_HYDRO),gamma_4(I_HYDRO), & + gbx%rain_ls,sghydro%mr_hydro(:,:,:,I_HYDRO),sghydro%Reff(:,:,:,I_HYDRO)) + I_HYDRO = I_LSSNOW + call cosp_precip_mxratio(Npoints,Nlevels,Ncolumns,gbx%p,gbx%T,sgx%prec_frac,1., & + n_ax(I_HYDRO),n_bx(I_HYDRO),alpha_x(I_HYDRO),c_x(I_HYDRO),d_x(I_HYDRO), & + g_x(I_HYDRO),a_x(I_HYDRO),b_x(I_HYDRO), & + gamma_1(I_HYDRO),gamma_2(I_HYDRO),gamma_3(I_HYDRO),gamma_4(I_HYDRO), & + gbx%snow_ls,sghydro%mr_hydro(:,:,:,I_HYDRO),sghydro%Reff(:,:,:,I_HYDRO)) + I_HYDRO = I_CVRAIN + call cosp_precip_mxratio(Npoints,Nlevels,Ncolumns,gbx%p,gbx%T,sgx%prec_frac,2., & + n_ax(I_HYDRO),n_bx(I_HYDRO),alpha_x(I_HYDRO),c_x(I_HYDRO),d_x(I_HYDRO), & + g_x(I_HYDRO),a_x(I_HYDRO),b_x(I_HYDRO), & + gamma_1(I_HYDRO),gamma_2(I_HYDRO),gamma_3(I_HYDRO),gamma_4(I_HYDRO), & + gbx%rain_cv,sghydro%mr_hydro(:,:,:,I_HYDRO),sghydro%Reff(:,:,:,I_HYDRO)) + I_HYDRO = I_CVSNOW + call cosp_precip_mxratio(Npoints,Nlevels,Ncolumns,gbx%p,gbx%T,sgx%prec_frac,2., & + n_ax(I_HYDRO),n_bx(I_HYDRO),alpha_x(I_HYDRO),c_x(I_HYDRO),d_x(I_HYDRO), & + g_x(I_HYDRO),a_x(I_HYDRO),b_x(I_HYDRO), & + gamma_1(I_HYDRO),gamma_2(I_HYDRO),gamma_3(I_HYDRO),gamma_4(I_HYDRO), & + gbx%snow_cv,sghydro%mr_hydro(:,:,:,I_HYDRO),sghydro%Reff(:,:,:,I_HYDRO)) + I_HYDRO = I_LSGRPL + call cosp_precip_mxratio(Npoints,Nlevels,Ncolumns,gbx%p,gbx%T,sgx%prec_frac,1., & + n_ax(I_HYDRO),n_bx(I_HYDRO),alpha_x(I_HYDRO),c_x(I_HYDRO),d_x(I_HYDRO), & + g_x(I_HYDRO),a_x(I_HYDRO),b_x(I_HYDRO), & + gamma_1(I_HYDRO),gamma_2(I_HYDRO),gamma_3(I_HYDRO),gamma_4(I_HYDRO), & + gbx%grpl_ls,sghydro%mr_hydro(:,:,:,I_HYDRO),sghydro%Reff(:,:,:,I_HYDRO)) + if(allocated(rho)) deallocate(rho) endif !++++++++++ CRM mode ++++++++++ else -! call construct_cosp_sghydro(Npoints,Ncolumns,Nlevels,Nhydro,sghydro) +#ifndef COSP_GFDL + call construct_cosp_sghydro(Npoints,Ncolumns,Nlevels,Nhydro,sghydro) +#endif sghydro%mr_hydro(:,1,:,:) = gbx%mr_hydro sghydro%Reff(:,1,:,:) = gbx%Reff !--------- Clouds ------- @@ -553,16 +717,18 @@ SUBROUTINE COSP_ITER(me,overlap,seed,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,mis sgx%frac_out(:,1,:) = 1 ! Subgrid cloud array. Dimensions (Npoints,Ncolumns,Nlevels) endwhere endif ! Ncolumns > 1 - + !++++++++++ Simulator ++++++++++ #ifdef RTTOV - call cosp_simulator(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) + call cosp_simulator(gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) #else - call cosp_simulator(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) + call cosp_simulator(gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) #endif - ! Deallocate subgrid arrays +#ifndef COSP_GFDL + call free_cosp_sghydro(sghydro) +#endif END SUBROUTINE COSP_ITER END MODULE MOD_COSP diff --git a/src/atmos_param/cosp/cosp_constants.f90 b/src/atmos_param/cosp/cosp_constants.F90 similarity index 53% rename from src/atmos_param/cosp/cosp_constants.f90 rename to src/atmos_param/cosp/cosp_constants.F90 index b07c160e5c..e4c7f185e5 100644 --- a/src/atmos_param/cosp/cosp_constants.f90 +++ b/src/atmos_param/cosp/cosp_constants.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: cosp_constants.f90,v 19.0 2012/01/06 20:03:21 fms Exp $ -! $Name: siena_201207 $ +! $Id: cosp_constants.F90,v 20.0 2013/12/13 23:15:36 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -40,6 +45,8 @@ MODULE MOD_COSP_CONSTANTS IMPLICIT NONE + character(len=32) :: COSP_VERSION='COSP v1.3.1' + ! Indices to address arrays of LS and CONV hydrometeors integer,parameter :: I_LSCLIQ = 1 integer,parameter :: I_LSCICE = 2 @@ -54,7 +61,7 @@ MODULE MOD_COSP_CONSTANTS ! Missing value real,parameter :: R_UNDEF = -1.0E30 ! Number of possible output variables - integer,parameter :: N_OUT_LIST = 45 + integer,parameter :: N_OUT_LIST = 44 ! Value for forward model result from a level that is under the ground real,parameter :: R_GROUND = -1.0E20 @@ -114,32 +121,65 @@ MODULE MOD_COSP_CONSTANTS HCLASS_CP(N_HYDRO),HCLASS_DMIN(N_HYDRO),HCLASS_DMAX(N_HYDRO) real :: HCLASS_APM(N_HYDRO),HCLASS_BPM(N_HYDRO),HCLASS_RHO(N_HYDRO), & HCLASS_P1(N_HYDRO),HCLASS_P2(N_HYDRO),HCLASS_P3(N_HYDRO) - data HCLASS_TYPE/5,1,2,2,5,1,2,2,2/ - data HCLASS_COL/1,2,3,4,5,6,7,8,9/ - data HCLASS_PHASE/0,1,0,1,0,1,0,1,1/ - data HCLASS_CP/0,0,0,0,0,0,0,0,0/ ! This is not used in the version of Quickbeam included in COSP - data HCLASS_DMIN/-1,-1,-1,-1,-1,-1,-1,-1,-1/ - data HCLASS_DMAX/-1,-1,-1,-1,-1,-1,-1,-1,-1/ - data HCLASS_APM/524,110.8,524, -1,524,110.8,524, -1, -1/ - data HCLASS_BPM/ 3, 2.91, 3, -1, 3, 2.91, 3, -1, -1/ - data HCLASS_RHO/ -1, -1, -1,100, -1, -1, -1,100,400/ - data HCLASS_P1/ -1,-1,8000000.,3000000., -1,-1,8000000.,3000000.,4000000./ - data HCLASS_P2/ 6,40, -1, -1, 6,40, -1, -1, -1/ - data HCLASS_P3/0.3, 2, -1, -1,0.3, 2, -1, -1, -1/ - -! LSL LSI LSR LSS CVL CVI CVR CVS LSG -! data HCLASS_TYPE/ 1, 1, 1, -1, 1, 1, 1, 1, -1/ -! data HCLASS_COL/ 1, 2, 3, 4, 5, 6, 7, 8, 9/ -! data HCLASS_PHASE/ 0, 1, 0, 1, 0, 1, 0, 1, 1/ -! data HCLASS_CP/ 0, 0, 0, 0, 0, 0, 0, 0, 0/ ! This is not used in the version of Quickbeam included in COSP -! data HCLASS_DMIN/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ -! data HCLASS_DMAX/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ -! data HCLASS_APM/ -1, 0.587, -1, 0.0444, -1, 0.587, -1, 0.0444, 261.8/ -! data HCLASS_BPM/ -1, 2.45, -1, 2.1, -1, 2.45, -1, 2.1, 3/ -! data HCLASS_RHO/ 1000, -1, 1000, -1, 1000, -1, 1000, -1, -1/ -! data HCLASS_P1/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ -! data HCLASS_P2/ 10, 40, 1000, 120, 10, 40, 1000, 120, 1000/ -! data HCLASS_P3/ 3, 1, 1, 1, 3, 1, 1, 1, 3.5/ + real,dimension(N_HYDRO) :: N_ax,N_bx,alpha_x,c_x,d_x,g_x,a_x,b_x,gamma_1,gamma_2,gamma_3,gamma_4 + + ! HCLASS_CP is not used in the version of Quickbeam included in COSP +! LSL LSI LSR LSS CVL CVI CVR CVS LSG + data HCLASS_TYPE/ 5, 1, 2, 2, 5, 1, 2, 2, 2/ + data HCLASS_COL/ 1, 2, 3, 4, 5, 6, 7, 8, 9/ + data HCLASS_PHASE/ 0, 1, 0, 1, 0, 1, 0, 1, 1/ + data HCLASS_CP/ 0, 0, 0, 0, 0, 0, 0, 0, 0/ + data HCLASS_DMIN/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ + data HCLASS_DMAX/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ + data HCLASS_APM/ 524, 110.8, 524, -1, 524, 110.8, 524, -1, -1/ + data HCLASS_BPM/ 3, 2.91, 3, -1, 3, 2.91, 3, -1, -1/ + data HCLASS_RHO/ -1, -1, -1, 100, -1, -1, -1, 100, 400/ + data HCLASS_P1/ -1, -1, 8.e6, 3.e6, -1, -1, 8.e6, 3.e6, 4.e6/ + data HCLASS_P2/ 6, 40, -1, -1, 6, 40, -1, -1, -1/ + data HCLASS_P3/ 0.3, 2, -1, -1, 0.3, 2, -1, -1, -1/ + + ! Microphysical settings for the precipitation flux to mixing ratio conversion +! LSL LSI LSR LSS CVL CVI CVR CVS LSG + data N_ax/ -1., -1., 8.e6, 3.e6, -1., -1., 8.e6, 3.e6, 4.e6/ + data N_bx/ -1., -1., 0.0, 0.0, -1., -1., 0.0, 0.0, 0.0/ + data alpha_x/ -1., -1., 0.0, 0.0, -1., -1., 0.0, 0.0, 0.0/ + data c_x/ -1., -1., 842.0, 4.84, -1., -1., 842.0, 4.84, 94.5/ + data d_x/ -1., -1., 0.8, 0.25, -1., -1., 0.8, 0.25, 0.5/ + data g_x/ -1., -1., 0.5, 0.5, -1., -1., 0.5, 0.5, 0.5/ + data a_x/ -1., -1., 524.0, 52.36, -1., -1., 524.0, 52.36, 209.44/ + data b_x/ -1., -1., 3.0, 3.0, -1., -1., 3.0, 3.0, 3.0/ + data gamma_1/ -1., -1., 17.83725, 8.284701, -1., -1., 17.83725, 8.284701, 11.63230/ + data gamma_2/ -1., -1., 6.0, 6.0, -1., -1., 6.0, 6.0, 6.0/ + data gamma_3/ -1., -1., 2.0, 2.0, -1., -1., 2.0, 2.0, 2.0/ + data gamma_4/ -1., -1., 6.0, 6.0, -1., -1., 6.0, 6.0, 6.0/ +! ! LSL LSI LSR LSS CVL CVI CVR CVS LSG +! data HCLASS_TYPE/ 1, 1, 1, -1, 1, 1, 1, 1, -1/ +! data HCLASS_COL/ 1, 2, 3, 4, 5, 6, 7, 8, 9/ +! data HCLASS_PHASE/ 0, 1, 0, 1, 0, 1, 0, 1, 1/ +! data HCLASS_CP/ 0, 0, 0, 0, 0, 0, 0, 0, 0/ +! data HCLASS_DMIN/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ +! data HCLASS_DMAX/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ +! data HCLASS_APM/ -1, 0.0444, -1, 0.0444, -1, 0.0444, -1, 0.0444, 261.8/ +! data HCLASS_BPM/ -1, 2.1, -1, 2.1, -1, 2.1, -1, 2.1, 3/ +! data HCLASS_RHO/ 1000, -1, 1000, -1, 1000, -1, 1000, -1, -1/ +! data HCLASS_P1/ -1, -1, -1, -1, -1, -1, -1, -1, -1/ +! data HCLASS_P2/ 10, 40, 1000, 120, 10, 40, 1000, 120, 1000/ +! data HCLASS_P3/ 3, 1, 1, 1, 3, 1, 1, 1, 3.5/ +! +! ! Microphysical settings for the precipitation flux to mixing ratio conversion +! ! LSL LSI LSR LSS CVL CVI CVR CVS LSG +! data N_ax/ -1., -1., 26.2, -1., -1., -1., 26.2, 4.e6, -1./ +! data N_bx/ -1., -1., 1.57, -1., -1., -1., 1.57, 0.0, -1./ +! data alpha_x/ -1., -1., 0.0, -1., -1., -1., 0.0, 0.0, -1./ +! data c_x/ -1., -1., 386.8, -1., -1., -1., 386.8, 14.3, -1./ +! data d_x/ -1., -1., 0.67, -1., -1., -1., 0.67, 0.416, -1./ +! data g_x/ -1., -1., 0.4, -1., -1., -1., 0.4, 0.4, -1./ +! data a_x/ -1., -1., 523.6, -1., -1., -1., 523.6, 0.0444, -1./ +! data b_x/ -1., -1., 3.0, -1., -1., -1., 3.0, 2.1, -1./ +! data gamma_1/ -1., -1., 14.78119, -1., -1., -1., 14.78119, 3.382827, -1./ +! data gamma_2/ -1., -1., 6.0, -1., -1., -1., 6.0, 2.197659, -1./ +! data gamma_3/ -1., -1., 2.0, -1., -1., -1., 2.0, 2.0, -1./ +! data gamma_4/ -1., -1., 6.0, -1., -1., -1., 6.0, 6.0, -1./ END MODULE MOD_COSP_CONSTANTS diff --git a/src/atmos_param/cosp/cosp_defs.h b/src/atmos_param/cosp/cosp_defs.H similarity index 91% rename from src/atmos_param/cosp/cosp_defs.h rename to src/atmos_param/cosp/cosp_defs.H index 5e39b64f45..5589aa9175 100644 --- a/src/atmos_param/cosp/cosp_defs.h +++ b/src/atmos_param/cosp/cosp_defs.H @@ -1,9 +1,14 @@ +#define COSP_GFDL +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: cosp_defs.h,v 19.0 2012/01/06 20:03:22 fms Exp $ -! $Name: siena_201207 $ + +! $Id: cosp_defs.H,v 20.0 2013/12/13 23:15:38 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -31,3 +36,4 @@ !#define USE_CMOR1 use_cmor1 !#define RTTOV rttov +!#define SYS_SX sys_sx diff --git a/src/atmos_param/cosp/cosp_diagnostics.F90 b/src/atmos_param/cosp/cosp_diagnostics.F90 new file mode 100644 index 0000000000..a6d82ee8e4 --- /dev/null +++ b/src/atmos_param/cosp/cosp_diagnostics.F90 @@ -0,0 +1,2359 @@ +#include "cosp_defs.H" + +! (c) British Crown Copyright 2008, the Met Office. +! All rights reserved. +! +! Redistribution and use in source and binary forms, with or without modification, are permitted +! provided that the following conditions are met: +! +! * Redistributions of source code must retain the above copyright notice, this list +! of conditions and the following disclaimer. +! * Redistributions in binary form must reproduce the above copyright notice, this list +! of conditions and the following disclaimer in the documentation and/or other materials +! provided with the distribution. +! * Neither the name of the Met Office nor the names of its contributors may be used +! to endorse or promote products derived from this software without specific prior written +! permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +! OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +module cosp_diagnostics_mod + +use mpp_mod, only: input_nml_file +use fms_mod, only: open_namelist_file, open_file, & + close_file, error_mesg, FATAL, & + file_exist, mpp_pe, mpp_root_pe, & + check_nml_error, write_version_number,& + stdlog +use time_manager_mod, only: set_date, time_type, operator (+), & + operator(-), operator(<), & + operator(>), operator(<=), & + operator(>=), get_date, print_date, & + get_calendar_type, NOLEAP, & + assignment(=), set_time +use diag_grid_mod, only: get_local_indexes2 +use diag_manager_mod, only: register_diag_field, send_data, & + diag_axis_init, register_static_field +USE MOD_COSP_TYPES, only: cosp_config, cosp_gridbox, & + cosp_subgrid, cosp_sgradar, & + cosp_sglidar, cosp_isccp, & +#ifdef RTTOV + cosp_rttov, & +#endif + cosp_vgrid, cosp_radarstats, & + cosp_lidarstats, & + cosp_sghydro, cosp_misr, & + construct_cosp_vgrid, & + free_cosp_vgrid +USE MOD_COSP_IO, only: map_point_to_ll + +use MOD_COSP_CONSTANTS, only: DBZE_BINS,SR_BINS, PARASOL_NREFL, & + PARASOL_SZA, CFAD_ZE_MIN, & + CFAD_ZE_WIDTH, & + LIDAR_UNDEF, ISCCP_PC_BNDS, ISCCP_TAU,& + I_LSCLIQ, I_LSCICE, I_CVCLIQ, & + I_CVCICE, I_LSGRPL, & + I_LSRAIN, I_LSSNOW, I_CVRAIN, & + I_CVSNOW, & + N_HYDRO, ISCCP_TAU_BNDS,& + RTTOV_MAX_CHANNELS, MISR_N_CTH, & + MISR_CTH_BNDS +use MOD_LMD_IPSL_STATS, only: define_srbval +use MOD_COSP_Modis_Simulator, only: COSP_MODIS +use mod_modis_sim, only: numTauHistogramBins, & + numPressureHistogramBins, & + tauHistogramBoundaries, & + nominalTauHistogramBoundaries, & + nominalTauHistogramCenters, & + nominalPressureHistogramBoundaries +use mod_cosp_utils, only: flip_vert_index + +IMPLICIT NONE + +public cosp_diagnostics_init, output_cosp_fields, cosp_diagnostics_end, & + cosp_diagnostics_time_vary, cosp_diagnostics_endts + +!--------------------------------------------------------------------- +!----------- version number for this module -------------------------- + +character(len=128) :: version = '$Id $' +character(len=128) :: tagname = '$Name $' + +!--------------------------------------------------------------------- +!namelist variables + +logical :: output_p_and_z_by_index = .false. +logical :: generate_orbital_output = .false. +character (len = 128) :: orbital_filename = ' ' +integer, dimension(6) :: sat_begin_time = (/0,0,0,0,0,0/) +integer :: sat_period = 0 ! [seconds] +integer :: num_sat_periods = 0 +integer :: max_sdgs_per_sat_period = 3500 + +namelist/cosp_diagnostics_nml/ output_p_and_z_by_index, & + generate_orbital_output, orbital_filename, & + sat_begin_time, sat_period, num_sat_periods, & + max_sdgs_per_sat_period + +! Local variables + +character(len=16) :: mod_name = 'cosp' + +integer, dimension(14) :: cosp_axes + +integer :: id_lat, id_lon, id_p, id_ph, id_z, id_zh, id_T, id_sh, & + id_u_wind, id_v_wind, id_mr_ozone, & + id_tot_h2o, & + id_rh, id_tca, id_cca, id_lsliq, id_lsice, id_ccliq, & + id_ccice, id_fl_lsrain, id_fl_lssnow, id_fl_lsgrpl, & + id_fl_ccrain, id_fl_ccsnow, & + id_reff_lsclliq, id_reff_lsclice, & + id_reff_lsprliq, id_reff_lsprice, & + id_reff_ccclliq, id_reff_ccclice, & + id_reff_ccprliq, id_reff_ccprice, & + id_reff_lsclliq_cmip, id_reff_ccclliq_cmip, & + id_lsca_cmip, id_cca_cmip, & + id_dtau_s, id_dtau_c, id_dem_s, id_dem_c, id_skt, id_land, & + id_sfcht, id_sunlit +integer :: id_cltcalipso_sat, id_cllcalipso_sat, id_clmcalipso_sat, & + id_clhcalipso_sat +integer :: id_cltcalipso, id_cllcalipso, id_clmcalipso, id_clhcalipso, & + id_cltlidarradar, id_tclisccp, id_ctpisccp, id_tauisccp, & + id_tbisccp, id_tbclrisccp, & + id_betamol532, & + id_albisccp, id_clcalipso, id_clcalipso2, & + id_clcalipso_sat, id_clcalipso2_sat, & + id_clcalipso_mdl, id_clcalipso2_mdl, & + id_boxtauisccp, id_boxptopisccp, id_parasolrefl, & + id_parasolrefl_sat, & + id_sampling_sat, id_location_sat, id_lat_sat, id_lon_sat +integer :: id_tclmodis, id_lclmodis, id_iclmodis, id_ttaumodis, & + id_ltaumodis, id_itaumodis, id_tlogtaumodis, & + id_llogtaumodis, id_ilogtaumodis, id_lremodis, & + id_badlremodis, id_badiremodis, & + id_locldmodis, id_mdcldmodis, id_hicldmodis, & + id_iremodis, id_ctpmodis, id_lwpmodis, id_iwpmodis +integer, allocatable, dimension(:) :: id_dbze94, id_cloudsatcfad, & + id_cloudsatcfad_sat, & + id_atb532, id_calipsosrcfad, & + id_calipsosrcfad_sat, & + id_cloud_type, id_boxtauisccp_n, & + id_boxptopisccp_n, & + id_taumodis_n, id_ptopmodis_n, & + id_badsizemodis_n, & + id_sizemodis_n, id_phasemodis_n +integer, allocatable, dimension(:) :: id_cloudsatcfad_mdl, & + id_calipsosrcfad_mdl +integer , dimension(7) :: id_clisccp +integer , dimension(7,7) :: id_clisccp_n +integer , dimension(MISR_N_CTH) :: id_misr +integer , dimension(7,MISR_N_CTH) :: id_misr_n +integer , dimension(numTauHistogramBins, numPressureHistogramBins) :: & + id_tauctpmodis_n +integer , dimension(numPressureHistogramBins) :: id_tauctpmodis + +real :: missing_value = -1.0E30 + +real, dimension(:,:,:), allocatable :: location +logical, dimension(:,:,:), allocatable :: lflag_array +logical, dimension(:,:,:,:), allocatable :: lflag_array_temp, & + lflag_array_parasol +real, dimension(:,:,:), allocatable :: flag_array +type(time_type), dimension(:), allocatable :: Time_start, Time_end +integer :: imax, jmax, nlr, nlevels, ncolumns +integer :: nsat_time_prev +integer :: nsat_time +logical :: use_vgrid, csat_vgrid + +!---------------- End of declaration of variables -------------- + +include 'netcdf.inc' + +contains + +!###################################################################### + +subroutine cosp_diagnostics_init & + (imax_in, jmax_in, Time, axes, nlevels_in, ncolumns_in, cfg, & + use_vgrid_in, csat_vgrid_in, nlr_in) + +type(time_type), intent(in) :: Time +integer, dimension(4), intent(in) :: axes +integer, intent(in) :: imax_in, jmax_in +integer, intent(in) :: nlevels_in, ncolumns_in +logical, intent(in) :: use_vgrid_in +type(cosp_config), intent(in) :: cfg ! Configuration options +logical, intent(in) :: csat_vgrid_in +integer, intent (in) :: nlr_in + + integer :: io, unit, ierr, logunit + +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=cosp_diagnostics_nml, iostat=io) + ierr = check_nml_error(io,"cosp_diagnostics_nml") +#else +!--------------------------------------------------------------------- +! read namelist. +!--------------------------------------------------------------------- + if ( file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1; do while (ierr /= 0) + read (unit, nml=cosp_diagnostics_nml, iostat=io, end=10) + ierr = check_nml_error(io,'cosp_diagnostics_nml') + enddo +10 call close_file (unit) + endif +#endif + +!--------------------------------------------------------------------- +! write namelist to logfile. +!--------------------------------------------------------------------- + call write_version_number (version, tagname) + logunit = stdlog() + if (mpp_pe() == mpp_root_pe() ) & + write (logunit, nml=cosp_diagnostics_nml) + +!---------------------------------------------------------------------- +! save i and j dimensions. +!---------------------------------------------------------------------- + imax = imax_in + jmax = jmax_in + nlr = nlr_in + nlevels = nlevels_in + ncolumns = ncolumns_in + use_vgrid = use_vgrid_in + csat_vgrid = csat_vgrid_in + + if (generate_orbital_output) then + if (sat_begin_time(1) == 0 .or. sat_begin_time(2) == 0 .or. & + sat_begin_time(3) ==0) then + call error_mesg ('cosp_diagnostics_init', & + 'requesting orbital output but not supplying & + &valid start time', FATAL) + endif + if (sat_period == 0) then + call error_mesg ('cosp_diagnostics_init', & + 'satellite sampling period [seconds] must be non-zero', FATAL) + endif + if (num_sat_periods == 0) then + call error_mesg ('cosp_diagnostics_init', & + 'must define number of satellite periods to be processed', FATAL) + endif + if (trim(orbital_filename) == '') then + call error_mesg ('cosp_diagnostics_init', & + 'filename for orbital specification not provided', FATAL) + endif + endif + + call diag_field_init (Time, axes, cfg) + + if (generate_orbital_output) then + allocate (location (imax,jmax, 1:num_sat_periods)) + allocate (lflag_array (imax,jmax, 0:num_sat_periods)) + allocate (lflag_array_temp (imax,jmax, nlr, 0:num_sat_periods)) + allocate (lflag_array_parasol & + (imax,jmax, PARASOL_NREFL, 0:num_sat_periods)) + allocate (flag_array(imax,jmax,12)) + allocate (Time_start(num_sat_periods)) + allocate (Time_end (num_sat_periods)) + call read_cloudsat_orbit + nsat_time_prev = 1 + endif + +end subroutine cosp_diagnostics_init + +!##################################################################### + +subroutine diag_field_init (Time, axes, cfg) + +type(time_type), intent(in) :: Time +integer, dimension(4), intent(in) :: axes +type(cosp_config), intent(in) :: cfg ! Configuration options + + real :: column_ax(Ncolumns) + real :: level_ax(Nlevels ) + real :: isccp_ax(7) + real :: modis_ax(numTauHistogramBins) + real :: dbze_ax(DBZE_BINS) + real :: lidar_ax(SR_BINS) + real :: sratio_bounds(2, SR_BINS) + real :: srbval(SR_BINS) + real :: csat_ax(NLR) + real :: month_ax(12) + real :: hr_ax(num_sat_periods) + integer :: parasol_ax(PARASOL_NREFL) + integer, dimension(3) :: halfindx = (/1,2,4/) + integer, dimension(3) :: columnindx = (/1,2,5/) + integer, dimension(3) :: levelindx = (/1,2,11/) + integer, dimension(3) :: parasolindx = (/1,2,6/) + integer, dimension(3) :: dbzeindx = (/1,2,7/) + integer, dimension(3) :: lidarindx = (/1,2,8/) + integer, dimension(3) :: tauindx = (/1,2,9/) + integer, dimension(3) :: modistauindx = (/1,2,12/) + integer, dimension(3) :: csatindx = (/1,2,10/) + integer, dimension(3) :: samplingindx = (/1,2,13/) + integer, dimension(3) :: samplingindx2 = (/1,2,14/) + integer :: i, n, m + integer :: id_columnindx, id_parasolindx, id_dbzeindx, id_lidarindx + integer :: id_levelindx + integer :: id_tauindx + integer :: id_modistauindx + integer :: id_csatindx + integer :: id_monindx + integer :: id_3hrindx + character(len=2) :: chvers, chvers4 + character(len=8) :: chvers2, chvers3, chvers5, chvers6 + type(cosp_gridbox) :: gbx_t ! Gridbox information. Input for COSP + type(cosp_vgrid) :: vgrid_t ! Information on vertical grid of stats + + +!-------------------------------------------------------------------- +! define the varisous axes needed for this data. +!-------------------------------------------------------------------- + cosp_axes(1:4) = axes(1:4) + +!-------------------------------------------------------------------- +! a level counter: +!-------------------------------------------------------------------- + do i=1,Nlevels + level_ax(i) = float(i) + end do + id_levelindx = diag_axis_init ('levelindx', level_ax, & + 'levels', 'n', 'level number', & + set_name = mod_name) + cosp_axes(11) = id_levelindx + +!-------------------------------------------------------------------- +! a stochastic column counter: +!-------------------------------------------------------------------- + do i=1,Ncolumns + column_ax(i) = float(i) + end do + id_columnindx = diag_axis_init ('columnindx', column_ax, & + 'subcol', 'n', 'subcolumn number', & + set_name = mod_name) + cosp_axes(5) = id_columnindx + +!-------------------------------------------------------------------- +! a PARASOL index counter: +!-------------------------------------------------------------------- + id_parasolindx = diag_axis_init ('parasolindx', PARASOL_SZA, & + 'parasolindx', 'n', 'parasol reflectivity index', & + set_name = mod_name) + cosp_axes(6) = id_parasolindx + +!-------------------------------------------------------------------- +! a radar bin counter: +!-------------------------------------------------------------------- + do i=1,DBZE_BINS + dbze_ax(i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i-0.5) + end do + id_dbzeindx = diag_axis_init ('dbzeindx', dbze_ax, & + 'dbzeindx', 'n', 'dbze', & + set_name = mod_name) + cosp_axes(7) = id_dbzeindx + +!-------------------------------------------------------------------- +! a lidar bin counter: +!-------------------------------------------------------------------- + + call define_srbval (srbval) + + sratio_bounds(1,:) = srbval(:) + sratio_bounds(2,1:SR_BINS-1) = srbval(2:SR_BINS) + sratio_bounds(2,SR_BINS) = srbval(SR_BINS) +10.0 + lidar_ax(1:SR_BINS) = (sratio_bounds(1,1:SR_BINS) + & + sratio_bounds(2,1:SR_BINS))/2.0 + id_lidarindx = diag_axis_init ('lidarindx', lidar_ax, & + 'lidarindx', 'n', 'lidar scattering', & + set_name = mod_name) + cosp_axes(8) = id_lidarindx + +!-------------------------------------------------------------------- +! an isccp tau bin counter: +!-------------------------------------------------------------------- + isccp_ax = isccp_tau + id_tauindx = diag_axis_init ('tauindx', isccp_ax, & + 'tauindx', 'n', 'isccp tau category', & + set_name = mod_name) + cosp_axes(9) = id_tauindx + +!-------------------------------------------------------------------- +! a modis tau bin counter: +!-------------------------------------------------------------------- + modis_ax = nominalTauHistogramCenters + id_modistauindx = diag_axis_init ('modistauindx', modis_ax, & + 'modistauindx', 'n', 'modis tau category', & + set_name = mod_name) + cosp_axes(12) = id_modistauindx + +!-------------------------------------------------------------------- +! a specified vertical index needed when use_vgrid = .true. +!-------------------------------------------------------------------- + gbx_t%Npoints = 256 + gbx_t%Ncolumns = ncolumns + gbx_t%Nlevels = Nlevels + allocate(gbx_t%zlev(256 , nlevels)) + allocate(gbx_t%zlev_half(256 , nlevels)) + gbx_t%zlev = 0.0 + gbx_t%zlev_half = 0.0 + call construct_cosp_vgrid(gbx_t,Nlr,use_vgrid,csat_vgrid,vgrid_t) + csat_ax = vgrid_t%z + id_csatindx = diag_axis_init ('csatindx', csat_ax, & + 'csatindx', 'z', 'csat vert index', & + set_name = mod_name) + cosp_axes(10) = id_csatindx + deallocate (gbx_t%zlev, gbx_t%zlev_half) + call free_cosp_vgrid (vgrid_t) + do i=1,12 + month_ax(i) = i + end do + id_monindx = diag_axis_init ('samplingindx', month_ax, & + 'samplingindx', 'n', 'month index', & + set_name = mod_name) + cosp_axes(13) = id_monindx + + do i=1,num_sat_periods + hr_ax(i) = i + end do + id_3hrindx = diag_axis_init ('samplingindx2', hr_ax, & + 'samplingindx2', 'n', '3hr index', & + set_name = mod_name) + cosp_axes(14) = id_3hrindx + +!-------------------------------------------------------------------- +! register input fields with diag_manager. +!-------------------------------------------------------------------- + id_lat = register_diag_field & + (mod_name, 'lat', axes(1:2), Time, 'Latitude', 'degrees N') + + id_lon = register_diag_field & + (mod_name, 'lon', axes(1:2), Time, 'Longitude', 'degrees E') + + id_u_wind = register_diag_field & + (mod_name, 'u_wind', axes(1:2), Time, 'sfc u wind', 'm / s') + + id_v_wind = register_diag_field & + (mod_name, 'v_wind', axes(1:2), Time, 'sfc v wind', 'm / s') + + if (output_p_and_z_by_index) then + id_p = register_diag_field & + (mod_name, 'p', cosp_axes(levelindx), Time, & + 'P at full levels', 'Pa ') + id_ph = register_diag_field & + (mod_name, 'ph', cosp_axes(levelindx), Time, & + 'p at half levels', 'Pa') + id_z = register_diag_field & + (mod_name, 'z', cosp_axes(levelindx), Time, 'height ', 'meters') + id_zh = register_diag_field & + (mod_name, 'zh', cosp_axes(levelindx), Time, & + 'height at half levs', 'meters') + else + id_p = register_diag_field & + (mod_name, 'p', axes(1:3), Time, 'P at full levels', 'Pa ') + id_ph = register_diag_field & + (mod_name, 'ph', axes(halfindx), Time, 'p at half levels', 'Pa') + id_z = register_diag_field & + (mod_name, 'z', axes(1:3), Time, 'height ', 'meters ') + id_zh = register_diag_field & + (mod_name, 'zh', axes(halfindx), Time, 'height at half levs', & + 'meters') + endif + + id_mr_ozone = register_diag_field & + (mod_name, 'ozone', axes(1:3), Time, 'Ozone mass mixing ratio', & + 'kg (o3) / kg (air)') + + id_T = register_diag_field & + (mod_name, 'T', axes(1:3), Time, 'Temp at full levels', 'deg K ') + + id_sh = register_diag_field & + (mod_name, 'sh', axes(1:3), Time, & + 'vapor specific humidity at full levels', 'kg(h2o) / kg(air) ') + + id_rh = register_diag_field & + (mod_name, 'relhum', axes(1:3), Time, & + 'relative humidity at full levels', 'fraction ') + + id_tot_h2o = register_diag_field & + (mod_name, 'tot_h2o', axes(1:3), Time, & + 'total water substance', & + 'kg(h2o) / kg(air) ' ) + + id_lsca_cmip = register_diag_field & + (mod_name, 'lsca_cmip', axes(1:3), Time, & + 'ls liq cld fraction', 'fraction ', & + mask_variant = .true., & + missing_value = missing_value) + + id_cca_cmip = register_diag_field & + (mod_name, 'cca_cmip', axes(1:3), Time, & + 'convective liq cld fraction', 'fraction ', & + mask_variant = .true., & + missing_value = missing_value) + + id_tca = register_diag_field & + (mod_name, 'tca', axes(1:3), Time, & + 'total cld fraction', 'fraction ') + + id_cca = register_diag_field & + (mod_name, 'cca', axes(1:3), Time, & + 'convective cld fraction', 'fraction ') + + id_lsliq = register_diag_field & + (mod_name, 'lsliq', axes(1:3), Time, & + 'large scale cld liq', 'kg / kg ') + + id_lsice = register_diag_field & + (mod_name, 'lsice', axes(1:3), Time, & + 'large scale cld ice', 'kg / kg ') + + id_ccliq = register_diag_field & + (mod_name, 'ccliq', axes(1:3), Time, & + 'convective cld liq', 'kg / kg ') + + id_ccice = register_diag_field & + (mod_name, 'ccice', axes(1:3), Time, & + 'convective cld ice', 'kg / kg ') + + id_fl_lsrain = register_diag_field & + (mod_name, 'fl_lsrain', axes(1:3), Time, & + 'large scale rain flx', 'kg / (m**2 s)') + + id_fl_lssnow = register_diag_field & + (mod_name, 'fl_lssnow', axes(1:3), Time, & + 'large scale snow flx', 'kg / (m**2 s)') + + id_fl_lsgrpl = register_diag_field & + (mod_name, 'fl_lsgrpl', axes(1:3), Time, & + 'large scale graupel flx', 'kg / (m**2 s)') + + id_fl_ccrain = register_diag_field & + (mod_name, 'fl_ccrain', axes(1:3), Time, & + 'cnvctv scale rain flx', 'kg / (m**2 s)') + + id_fl_ccsnow = register_diag_field & + (mod_name, 'fl_ccsnow', axes(1:3), Time, & + 'cnvctv scale snow flx', 'kg / (m**2 s)') + + id_reff_lsclliq_cmip = register_diag_field & + (mod_name, 'reff_lsclliq_cmip', axes(1:3), Time, & + 'ls liq cld drop size*cfrac ', 'm', mask_variant = .true., & + missing_value = missing_value) + + id_reff_ccclliq_cmip = register_diag_field & + (mod_name, 'reff_ccclliq_cmip', axes(1:3), Time, & + 'cv liq cld drop size*cfrac ', 'm', mask_variant = .true., & + missing_value = missing_value) + + id_reff_lsclliq = register_diag_field & + (mod_name, 'reff_lsclliq', axes(1:3), Time, & + 'ls liq cld drop size ', 'm', mask_variant = .true., & + missing_value = missing_value) + + id_reff_lsclice = register_diag_field & + (mod_name, 'reff_lsclice', axes(1:3), Time, & + 'ls ice cld drop size ', 'm', mask_variant = .true., & + missing_value = missing_value) + + id_reff_lsprliq = register_diag_field & + (mod_name, 'reff_lsprliq', axes(1:3), Time, & + 'ls liq prcp drop size ', 'm') + + id_reff_lsprice = register_diag_field & + (mod_name, 'reff_lsprice', axes(1:3), Time, & + 'ls ice prcp drop size ', 'm') + + id_reff_ccclliq = register_diag_field & + (mod_name, 'reff_ccclliq', axes(1:3), Time, & + 'cv liq cld drop size ', 'm', mask_variant = .true., & + missing_value = missing_value) + + id_reff_ccclice = register_diag_field & + (mod_name, 'reff_ccclice', axes(1:3), Time, & + 'cv ice cld drop size ', 'm', mask_variant = .true., & + missing_value = missing_value) + + id_reff_ccprliq = register_diag_field & + (mod_name, 'reff_ccprliq', axes(1:3), Time, & + 'cv liq prcp drop size ', 'm') + + id_reff_ccprice = register_diag_field & + (mod_name, 'reff_ccprice', axes(1:3), Time, & + 'cv ice prcp drop size ', 'm') + + id_dtau_s = register_diag_field & + (mod_name, 'dtau_s', axes(1:3), Time, & + 'ls cloud optical depth ', 'dimensionless') + + id_dtau_c = register_diag_field & + (mod_name, 'dtau_c', axes(1:3), Time, & + 'cv cloud optical depth ', 'dimensionless') + + id_dem_s = register_diag_field & + (mod_name, 'dem_s', axes(1:3), Time, & + 'ls cloud emissivity ', 'dimensionless') + + id_dem_c = register_diag_field & + (mod_name, 'dem_c', axes(1:3), Time, & + 'cv cloud emissivity ', 'dimensionless') + + id_skt = register_diag_field & + (mod_name, 'skt', axes(1:2), Time, 'skin temp', 'deg K') + + id_sunlit = register_diag_field & + (mod_name, 'sunlit', axes(1:2), Time, 'sun is shining?', 'none') + + id_land = register_diag_field & + (mod_name, 'land', axes(1:2), Time, 'land frac', 'fraction') + + id_sfcht = register_diag_field & + (mod_name, 'sfc_ht', axes(1:2), Time, 'height of surface', & + 'meters') + +!--------------------------------------------------------------------- +! COSP output fields: +!--------------------------------------------------------------------- + allocate (id_dbze94(Ncolumns)) + if (use_vgrid) then + allocate (id_cloudsatcfad(DBZE_BINS)) + allocate (id_calipsosrcfad(SR_BINS )) + allocate (id_cloudsatcfad_sat(DBZE_BINS)) + allocate (id_calipsosrcfad_sat(SR_BINS )) + else + allocate (id_cloudsatcfad_mdl(DBZE_BINS)) + allocate (id_calipsosrcfad_mdl(SR_BINS )) + endif + allocate (id_cloud_type (Ncolumns )) + do n=1, size(id_cloud_type,1) + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 levels', FATAL) + endif + id_cloud_type(n) = register_diag_field & + (mod_name, 'cloud_type_' // trim(chvers), axes(1:3), Time, & + 'Cloud type present in column ' // trim(chvers), 'none') + end do + + if (cfg%Llidar_sim) then + id_cltcalipso = register_diag_field & + (mod_name, 'cltcalipso', axes(1:2), Time, & + 'Lidar Total Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_cllcalipso = register_diag_field & + (mod_name, 'cllcalipso', axes(1:2), Time, & + 'Lidar Low-level Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_clmcalipso = register_diag_field & + (mod_name, 'clmcalipso', axes(1:2), Time, & + 'Lidar Mid-level Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_clhcalipso = register_diag_field & + (mod_name, 'clhcalipso', axes(1:2), Time, & + 'Lidar High-level Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + if (generate_orbital_output) then + + id_cltcalipso_sat = register_diag_field & + (mod_name, 'cltcalipso_sat', axes(1:2), Time, & + 'Lidar Total Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_cllcalipso_sat = register_diag_field & + (mod_name, 'cllcalipso_sat', axes(1:2), Time, & + 'Lidar Low-level Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_clmcalipso_sat = register_diag_field & + (mod_name, 'clmcalipso_sat', axes(1:2), Time, & + 'Lidar Mid-level Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_clhcalipso_sat = register_diag_field & + (mod_name, 'clhcalipso_sat', axes(1:2), Time, & + 'Lidar High-level Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_clcalipso_sat = register_diag_field & + (mod_name, 'clcalipso_sat', cosp_axes(csatindx), Time, & + 'Lidar Cloud Fraction (532 nm)', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_sampling_sat = register_static_field & + (mod_name, 'sampling_sat', cosp_axes(samplingindx), & + 'Times sampled by Cloudsat', 'number', & + missing_value=missing_value) + + id_location_sat = register_static_field & + (mod_name, 'location_sat', cosp_axes(samplingindx2), & + 'Satellite location index', 'counter', & + missing_value=missing_value) + + id_lon_sat = register_diag_field & + (mod_name, 'lon_sat', axes(1:2), Time, & + 'Satellite longitude', 'degrees E', & + mask_variant = .true., missing_value=missing_value) + + id_lat_sat = register_diag_field & + (mod_name, 'lat_sat', axes(1:2), Time, & + 'Satellite latitude', 'degrees N', & + mask_variant = .true., missing_value=missing_value) + + id_parasolrefl_sat = register_diag_field & + (mod_name, 'parasol_refl_sat', cosp_axes(parasolindx), Time, & + 'PARASOL-like mono-directional reflectance', 'fraction', & + mask_variant = .true., missing_value=missing_value) + + endif + + id_clcalipso = register_diag_field & + (mod_name, 'clcalipso', cosp_axes(csatindx), Time, & + 'Lidar Cloud Fraction (532 nm)', 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_clcalipso_mdl = register_diag_field & + (mod_name, 'clcalipso_mdl', axes(1:3), Time, & + 'Lidar Cloud Fraction (532 nm)', 'percent', & + mask_variant = .true., missing_value=missing_value) + id_parasolrefl = register_diag_field & + (mod_name, 'parasol_refl', cosp_axes(parasolindx), Time, & + 'PARASOL-like mono-directional reflectance', 'fraction', & + mask_variant = .true., missing_value=missing_value) + id_betamol532 = register_diag_field & + (mod_name, 'betamol532', axes(1:3 ), Time, & + 'Lidar Molecular Backscatter (532 nm)', & + '(m sr)**(-1)', & + mask_variant = .true., missing_value=missing_value) + allocate (id_atb532(Ncolumns)) + do n=1, size(id_atb532,1) + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 columns', FATAL) + endif + id_atb532(n) = register_diag_field & + (mod_name, 'atb532_' // trim(chvers), axes(1:3 ), Time, & + 'Lidar Attenuated Total Backscatter (532 nm) column# ' // & + & trim(chvers), '(m sr)**(-1)', & + mask_variant = .true., missing_value=missing_value) + end do + + do n=1, SR_BINS + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 levels', FATAL) + endif + if (n == 1) then + write (chvers2, '(f8.2)') -100.0 + else + write (chvers2, '(f8.2)') srbval(n-1) + endif + write (chvers3, '(f8.2)') srbval(n) + if (use_vgrid) then + id_calipsosrcfad(n) = register_diag_field & + (mod_name, 'calipsosrcfad_' // trim(chvers), & + cosp_axes(csatindx ), Time, & + 'Fractional area with Lidar 532 nm Scattering Ratio & + &between' // trim(chvers2) // ' and' // trim(chvers3) // & + ' -- bin' // trim(chvers), 'fraction', & + mask_variant = .true., missing_value=missing_value) + if (generate_orbital_output) then + id_calipsosrcfad_sat(n) = register_diag_field & + (mod_name, 'calipsosrcfad_sat_' // trim(chvers), & + cosp_axes(csatindx ), Time, & + 'Fractional area with Lidar 532 nm Scattering Ratio & + &between' // trim(chvers2) // ' and' // trim(chvers3) // & + ' -- bin' // trim(chvers), 'fraction', & + mask_variant = .true., missing_value=missing_value) + endif + else + id_calipsosrcfad_mdl(n) = register_diag_field & + (mod_name, 'calipsosrcfad_mdl_' // trim(chvers), axes(1:3), & + Time, 'Fractional area with Lidar 532 nm Scattering Ratio & + &between' // trim(chvers2) // ' and' // trim(chvers3) // & + ' -- bin' // trim(chvers), 'fraction', & + mask_variant = .true., missing_value=missing_value) + endif + end do + endif !(Llidar_sim) + + if (cfg%Lradar_sim) then + do n=1, size(id_dbze94,1) + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 levels', FATAL) + endif + id_dbze94(n) = register_diag_field & + (mod_name, 'dbze94_' // trim(chvers), axes(1:3), Time, & + 'Radar Effective Reflectivity Factor in dBZe (94 GHz) column# ' & + // trim(chvers), 'dBZe') + end do + + do n=1, DBZE_BINS + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 levels', FATAL) + endif + write (chvers2, '(i6)') INT(cfad_ze_min + float(n-1)*cfad_ze_width) + write (chvers3, '(i6)') INT(cfad_ze_min + float(n)*cfad_ze_width) + if (use_vgrid) then + id_cloudsatcfad(n) = register_diag_field & + (mod_name, 'cloudsatcfad_' // trim(chvers), & + cosp_axes(csatindx), Time, & + 'Fractional area with radar reflectivity (94 GHz) between ' & + // trim(chvers2) // ' and' // trim(chvers3) // & + ' dbZe -- bin # ' // trim(chvers), 'fraction', & + mask_variant = .true., missing_value=missing_value) + if (generate_orbital_output) then + id_cloudsatcfad_sat(n) = register_diag_field & + (mod_name, 'cloudsatcfad_sat_' // trim(chvers), & + cosp_axes(csatindx), Time, & + 'Fractional area with radar reflectivity (94 GHz) between ' & + // trim(chvers2) // ' and' // trim(chvers3) // & + ' dbZe -- bin # ' // trim(chvers), 'fraction', & + mask_variant = .true., missing_value=missing_value) + endif + else + id_cloudsatcfad_mdl(n) = register_diag_field & + (mod_name, 'cloudsatcfad_mdl_' // trim(chvers), axes(1:3), & + Time, 'Fractional area with radar reflectivity & + &(94 GHz) between ' // trim(chvers2) // ' and' // & + & trim(chvers3) // ' dbZe -- bin # ' // trim(chvers), & + 'fraction', & + mask_variant = .true., missing_value=missing_value) + endif + end do + endif ! (Lradar_sim) + + + if (cfg%Lradar_sim .and. cfg%Llidar_sim) then + id_cltlidarradar = register_diag_field & + (mod_name, 'cltlidarradar', axes(1:2), Time, & + 'Lidar and Radar Total Cloud Fraction', 'percent', & + mask_variant = .true., missing_value=missing_value) + id_clcalipso2 = register_diag_field & + (mod_name, 'clcalipso2', cosp_axes(csatindx), Time, & +'Cloud frequency of occurrence as seen by CALIPSO but not CloudSat', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + if (generate_orbital_output) then + id_clcalipso2_sat = register_diag_field & + (mod_name, 'clcalipso2_sat', cosp_axes(csatindx), Time, & +'Cloud frequency of occurrence as seen by CALIPSO but not CloudSat', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + endif + + id_clcalipso2_mdl = register_diag_field & + (mod_name, 'clcalipso2_mdl', axes(1:3), Time, & +'Cloud frequency of occurrence as seen by CALIPSO but not CloudSat', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + endif !(cfg%Lradar_sim .and. cfg%Llidar_sim) + + if (cfg%Lisccp_sim) then + id_tclisccp = register_diag_field & + (mod_name, 'tclisccp', axes(1:2), Time, & + 'Total Cloud Fraction as Calculated by the ISCCP Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_ctpisccp = register_diag_field & + (mod_name, 'ctpisccp', axes(1:2), Time, & + 'Mean Cloud Top Pressure *CPCT as Calculated by the ISCCP Simulator', & + 'Pa', mask_variant = .true., missing_value=missing_value) + + id_tbisccp = register_diag_field & + (mod_name, 'tbisccp', axes(1:2), Time, & + 'Mean All-sky 10.5 micron brightness temp -- ISCCP Simulator', & + 'deg K', mask_variant = .true., missing_value=missing_value) + + id_tbclrisccp = register_diag_field & + (mod_name, 'tbclrisccp', axes(1:2), Time, & + 'Mean Clr-sky 10.5 micron brightness temp -- ISCCP Simulator', & + 'deg K', mask_variant = .true., missing_value=missing_value) + + id_tauisccp = register_diag_field & + (mod_name, 'tauisccp', axes(1:2), Time, & + 'Mean Optical Depth *CPCT as Calculated by the ISCCP Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_albisccp = register_diag_field & + (mod_name, 'albisccp', axes(1:2), Time, & + 'Mean Cloud Albedo *CPCT as Calculated by the ISCCP Simulator', & + 'fraction', & + mask_variant = .true., missing_value=missing_value) + id_boxtauisccp = register_diag_field & + (mod_name, 'boxtauisccp', cosp_axes(columnindx), Time, & + 'Optical Depth from the ISCCP Simulator', 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_boxptopisccp = register_diag_field & + (mod_name, 'boxptopisccp', cosp_axes(columnindx), Time, & + 'Cloud Top Pressure from the ISCCP Simulator', 'Pa') + allocate (id_boxtauisccp_n(Ncolumns)) + allocate (id_boxptopisccp_n(Ncolumns)) + do n=1,Ncolumns + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 levels', FATAL) + endif + + id_boxtauisccp_n(n) = register_diag_field & + (mod_name, 'boxtauisccp_' // trim(chvers), axes(1:2), Time, & + 'Optical Depth in stochastic Column' // trim(chvers) // & + ' from the ISCCP Simulator', 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_boxptopisccp_n(n) = register_diag_field & + (mod_name, 'boxptopisccp_' // trim(chvers), axes(1:2), Time, & + 'Cloud Top Pressure in stochastic column' // trim(chvers) & + //' from the ISCCP Simulator', 'Pa', & + mask_variant = .true., missing_value=missing_value) + end do + do n=1,7 + write (chvers, '(i1)') n + write (chvers2, '(i6)') INT(isccp_pc_bnds(1,n)*1.0e-02) + write (chvers3, '(i6)') INT(isccp_pc_bnds(2,n)*1.0e-02) + id_clisccp(n) = register_diag_field & + (mod_name, 'clisccp_'// trim(chvers), cosp_axes(tauindx), & + Time, 'ISCP Cld Frac for clouds between ' // trim(chvers2) & + // ' and' // trim(chvers3) // ' hPa', 'percent', & + mask_variant = .true., missing_value=missing_value) + end do + + do m=1,7 + write (chvers4, '(i1)') m + write (chvers5, '(f4.1)') isccp_tau_bnds(1,m) + write (chvers6, '(f8.1)') isccp_tau_bnds(2,m) + do n=1,7 + write (chvers, '(i1)') n + write (chvers2, '(i5)') INT(isccp_pc_bnds(1,n)*1.0e-02) + write (chvers3, '(i5)') INT(isccp_pc_bnds(2,n)*1.0e-02) + id_clisccp_n(m,n) = register_diag_field & + (mod_name, 'clisccp_'// trim(chvers4)//'_' // trim(chvers), & + axes(1:2), Time, 'ISCCP CldFrac - tau between ' // & + trim(chvers5) // ' and ' // trim(chvers6) // & + ' , pr between ' // trim(chvers2) // ' and' // & + trim(chvers3) // ' hPa', 'percent', & + mask_variant = .true., missing_value=missing_value) + end do + end do + endif !(Lisccp_sim) + + if (cfg%Lmisr_sim) then + do n=1,MISR_N_CTH + if (n <=9) then + write (chvers, '(i1)') n + else + write (chvers, '(i2)') n + endif + write (chvers2, '(f6.1)') 1.0e-03*MISR_CTH_BNDS(1,n) + write (chvers3, '(f6.1)') 1.0E-03*MISR_CTH_BNDS(2,n) + id_misr(n) = register_diag_field & + (mod_name, 'misr_'// trim(chvers), cosp_axes(tauindx), & + Time, 'MISR Cld Frac for clouds with top between ' // trim(chvers2) & + // ' and' // trim(chvers3) // ' km', 'percent', & + mask_variant = .true., missing_value=missing_value) + end do + + do m=1,7 + write (chvers4, '(i1)') m + write (chvers5, '(f4.1)') isccp_tau_bnds(1,m) + write (chvers6, '(f8.1)') isccp_tau_bnds(2,m) + do n=1,MISR_N_CTH + if (n <=9) then + write (chvers, '(i1)') n + else + write (chvers, '(i2)') n + endif + write (chvers2, '(f6.1)') 1.0e-03*MISR_CTH_BNDS(1,n) + write (chvers3, '(f6.1)') 1.0e-03*MISR_CTH_BNDS(2,n) + id_misr_n(m,n) = register_diag_field & + (mod_name, 'misr_'// trim(chvers4)//'_' // trim(chvers), & + axes(1:2), Time, 'MISR CldFrac - tau between ' // & + trim(chvers5) // ' and ' // trim(chvers6) // & + ' , top between ' // trim(chvers2) // ' and' // & + trim(chvers3) // ' km', 'percent', & + mask_variant = .true., missing_value=missing_value) + end do + end do + endif !(Lmisr_sim) + + if (cfg%Lmodis_sim) then + + id_tclmodis = register_diag_field & + (mod_name, 'tclmodis', axes(1:2), Time, & + 'Total Cloud Fraction as Calculated by the MODIS Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_locldmodis = register_diag_field & + (mod_name, 'locldmodis', axes(1:2), Time, & + 'Low Cloud Fraction as Calculated by the MODIS Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_mdcldmodis = register_diag_field & + (mod_name, 'mdcldmodis', axes(1:2), Time, & + 'Middle Cloud Fraction as Calculated by the MODIS Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_hicldmodis = register_diag_field & + (mod_name, 'hicldmodis', axes(1:2), Time, & + 'High Cloud Fraction as Calculated by the MODIS Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_lclmodis = register_diag_field & + (mod_name, 'lclmodis', axes(1:2), Time, & + 'Total Liquid Cloud Fraction as Calculated by the MODIS Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_iclmodis = register_diag_field & + (mod_name, 'iclmodis', axes(1:2), Time, & + 'Total Ice Cloud Fraction as Calculated by the MODIS Simulator', & + 'percent', & + mask_variant = .true., missing_value=missing_value) + + id_ttaumodis = register_diag_field & + (mod_name, 'ttaumodis', axes(1:2), Time, & + 'Total Optical Thickness*CPCT as Calculated by the MODIS Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_ltaumodis = register_diag_field & + (mod_name, 'ltaumodis', axes(1:2), Time, & + 'Total Liquid Optical Thickness*CPCT as Calculated by the MODIS Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_itaumodis = register_diag_field & + (mod_name, 'itaumodis', axes(1:2), Time, & + 'Total Ice Optical Thickness*CPCT as Calculated by the MODIS Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_tlogtaumodis = register_diag_field & + (mod_name, 'tlogtaumodis', axes(1:2), Time, & + 'Total Log Mean Optical Thickness*CPCT as Calculated by the MODIS Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_llogtaumodis = register_diag_field & + (mod_name, 'llogtaumodis', axes(1:2), Time, & + 'Total Log Mean Liquid Optical Thickness*CPCT as Calculated by the MODIS Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_ilogtaumodis = register_diag_field & + (mod_name, 'ilogtaumodis', axes(1:2), Time, & + 'Total Log Mean Ice Optical Thickness*CPCT as Calculated by the MODIS Simulator', & + 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_lremodis = register_diag_field & + (mod_name, 'lremodis', axes(1:2), Time, & + ' Liquid Water particle Size*CPCT as Calculated by the MODIS Simulator', & + 'm', & + mask_variant = .true., missing_value=missing_value) + + id_badlremodis = register_diag_field & + (mod_name, 'badlsizemodis', axes(1:2), Time, & + ' Flag for liquid size retrieval failure in the MODIS Simulator', & + '1', & + mask_variant = .true., missing_value=missing_value) + + id_badiremodis = register_diag_field & + (mod_name, 'badisizemodis', axes(1:2), Time, & + ' Flag for ice size retrieval failure in the MODIS Simulator', & + '1', & + mask_variant = .true., missing_value=missing_value) + + id_iremodis = register_diag_field & + (mod_name, 'iremodis', axes(1:2), Time, & + ' Ice Water particle Size*CPCT as Calculated by the MODIS Simulator', & + 'm', & + mask_variant = .true., missing_value=missing_value) + + id_ctpmodis = register_diag_field & + (mod_name, 'ctpmodis', axes(1:2), Time, & + ' Mean Cloud Top Pressure*CPCT as Calculated by the MODIS Simulator', & + 'Pa', & + mask_variant = .true., missing_value=missing_value) + + id_lwpmodis = register_diag_field & + (mod_name, 'lwpmodis', axes(1:2), Time, & + ' Mean Liquid Water Path*CPCT as Calculated by the MODIS Simulator', & + 'kg / ( m**2)', & + mask_variant = .true., missing_value=missing_value) + + id_iwpmodis = register_diag_field & + (mod_name, 'iwpmodis', axes(1:2), Time, & + ' Mean Ice Water Path*CPCT as Calculated by the MODIS Simulator', & + 'kg / ( m**2)', & + mask_variant = .true., missing_value=missing_value) + + allocate (id_taumodis_n(Ncolumns)) + allocate (id_ptopmodis_n(Ncolumns)) + allocate (id_sizemodis_n(Ncolumns)) + allocate (id_badsizemodis_n(Ncolumns)) + allocate (id_phasemodis_n(Ncolumns)) + do n=1,Ncolumns + if (n <= 9) then + write (chvers, '(i1)') n + else if (n <=99) then + write (chvers, '(i2)') n + else + call error_mesg ('cosp_driver', & + 'can not process over 99 levels', FATAL) + endif + + id_taumodis_n(n) = register_diag_field & + (mod_name, 'taumodis_' // trim(chvers), axes(1:2), Time, & + 'Optical Depth in stochastic Column' // trim(chvers) // & + ' from the MODIS Simulator', 'dimensionless', & + mask_variant = .true., missing_value=missing_value) + + id_ptopmodis_n(n) = register_diag_field & + (mod_name, 'ptopmodis_' // trim(chvers), axes(1:2), Time, & + 'Cloud Top Pressure in stochastic column' // trim(chvers) & + //' from the MODIS Simulator', 'hPa', & + mask_variant = .true., missing_value=missing_value) + + id_sizemodis_n(n) = register_diag_field & + (mod_name, 'sizemodis_' // trim(chvers), axes(1:2), Time, & + 'Particle Size in stochastic Column' // trim(chvers) // & + ' from the MODIS Simulator', 'meters', & + mask_variant = .true., missing_value=missing_value) + + id_badsizemodis_n(n) = register_diag_field & + (mod_name, 'badsizemodis_' // trim(chvers), axes(1:2), Time, & + 'Particle Size failures in stochastic Column' // trim(chvers) // & + ' from the MODIS Simulator', 'meters', & + mask_variant = .true., missing_value=missing_value) + + id_phasemodis_n(n) = register_diag_field & + (mod_name, 'phasemodis_' // trim(chvers), axes(1:2), Time, & + 'Phase in stochastic Column' // trim(chvers) // & + ' from the MODIS Simulator', 'unitless', & + mask_variant = .true., missing_value=missing_value) + + end do + do n=numPressureHistogramBins,1,-1 + if (n <=9) then + write (chvers, '(i1)') n + else + write (chvers, '(i2)') n + endif + write (chvers2, '(f8.1)') nominalPressureHistogramBoundaries(1,n) + write (chvers3, '(f8.1)') nominalPressureHistogramBoundaries(2,n) + id_tauctpmodis(n) = register_diag_field & + (mod_name, 'tauctpmodis_'// trim(chvers), cosp_axes(modistauindx), & + Time, 'MODIS Cld Frac for clouds with top between ' // trim(chvers2) & + // ' and' // trim(chvers3) // ' Pa', 'percent', & + mask_variant = .true., missing_value=missing_value) + end do + + do m=1,numTauHistogramBins + write (chvers4, '(i1)') m + 1 + write (chvers5, '(f6.1)') nominalTauHistogramBoundaries(1,m) + write (chvers6, '(f6.1)') nominalTauHistogramBoundaries(2,m) + do n=numPressureHistogramBins,1,-1 + if (n <=9) then + write (chvers, '(i1)') n + else + write (chvers, '(i2)') n + endif + write (chvers2, '(f8.1)') nominalPressureHistogramBoundaries(1,n) + write (chvers3, '(f8.1)') nominalPressureHistogramBoundaries(2,n) + id_tauctpmodis_n(m,n) = register_diag_field & + (mod_name, 'tauctpmodis_'// trim(chvers4)//'_' // trim(chvers), & + axes(1:2), Time, 'MODIS CldFrac - tau between ' // & + trim(chvers5) // ' and ' // trim(chvers6) // & + ' , top between ' // trim(chvers2) // ' and' // & + trim(chvers3) // ' Pa', 'percent', & + mask_variant = .true., missing_value=missing_value) + end do + end do + endif !(Lmodis_sim) + + + + + end subroutine diag_field_init + +!#################################################################### + +subroutine cosp_diagnostics_time_vary (Time_diag) + +type(time_type), intent(in) :: Time_diag + + integer :: n + + if (generate_orbital_output) then +!---------------------------------------------------------------------- +! determine the time index of the current time in the satellite +! orbit data. +!---------------------------------------------------------------------- + do n= nsat_time_prev, num_sat_periods + if (Time_diag >= Time_start(n) .and. & + Time_diag < Time_end(n)) then + nsat_time = n + nsat_time_prev = nsat_time + exit + else +! set nsat_time to 0 if current time not within sampling region + nsat_time = 0 + endif + end do + endif + + + +end subroutine cosp_diagnostics_time_vary + + + +!#################################################################### + +subroutine cosp_diagnostics_endts + + return + +end subroutine cosp_diagnostics_endts + +!#################################################################### + +subroutine output_cosp_fields & + (nlon,nlat,npoints, geomode, stlidar, stradar, isccp, modis, & + misr, sgradar, sglidar, sg, Time_diag, is, js, cloud_type, & + gbx, cfg, phalf_plus, zhalf_plus) + +!--------------------------------------------------------------------- +! subroutine output_cosp_fields outputs fields relevant to the +! cosp ismulator, both input and output. +!--------------------------------------------------------------------- + +integer, intent(in) :: nlon,nlat,npoints +integer, intent(in) :: geomode +integer, intent(in) :: is, js +type(cosp_config), intent(in) :: cfg +real, dimension(npoints, ncolumns, nlevels), intent(in) :: cloud_type +type(cosp_lidarstats), intent(in) :: stlidar +type(cosp_radarstats), intent(in) :: stradar +type(cosp_isccp ), intent(in) :: isccp +type(cosp_modis ), intent(in) :: modis +type(cosp_misr ), intent(in) :: misr +type(cosp_sgradar ), intent(in) :: sgradar +type(cosp_sglidar ), intent(in) :: sglidar +type(cosp_subgrid ), intent(in) :: sg +type(time_type) , intent(in) :: Time_diag +type(cosp_gridbox) , intent(in) :: gbx +real, dimension(nlon,nlat, nlevels+1), intent(in) :: phalf_plus, zhalf_plus + +! local variables: + + logical :: used + integer :: n, m + real, dimension(Nlon,Nlat) :: y2, y2save, alpha, y2sunlit + real, dimension(Nlon,Nlat) :: y2lsave, y2isave + real, dimension(Nlon,Nlat,Nlevels) :: y3 + real, dimension(Nlon,Nlat,Nlevels) :: y31,y32, y33,y34, y35, y36,y37 + real, dimension(Nlon,Nlat,Nlevels) :: y3a + real, dimension(Nlon,Nlat,Nlr ) :: z3 + real, dimension(Nlon,Nlat,Nlr ) :: z3a + real, dimension(Nlon,Nlat,Ncolumns) :: y4 + real, dimension(Nlon,Nlat,PARASOL_NREFL) :: y5 + real, dimension(Nlon,Nlat,Ncolumns,Nlevels) :: y6,y6a + real, dimension(Nlon,Nlat,Ncolumns,Nlr ) :: z6,z6a + real, dimension(Nlon,Nlat,DBZE_BINS,Nlevels) :: y7,y7a + real, dimension(Nlon,Nlat,DBZE_BINS,Nlr ) :: z7,z7a + real, dimension(Nlon,Nlat,SR_BINS,Nlevels) :: y8, y8a + real, dimension(Nlon,Nlat,SR_BINS,Nlr ) :: z8, z8a + real, dimension(Nlon,Nlat,7,7 ) :: y9 + real, dimension(Nlon,Nlat,numTauHistogramBins, & + numPressureHistogramBins ) :: y13 + real, dimension(Nlon,Nlat,numTauHistogramBins+1, & + numPressureHistogramBins ) :: y12 + real, dimension(Nlon,Nlat,7,MISR_N_CTH ) :: y10 + logical, dimension (Nlon,Nlat,Nlevels) :: mask_y3a + logical, dimension (Nlon,Nlat) :: lmsk + integer :: ie, je + + ie = is + nlon -1 + je = js + nlat -1 +!---------------------------------------------------------------------- +! output the input fields to COSP. fields must be converted from +! 2d arrays (i,j) +!---------------------------------------------------------------------- + +! 2D fields: + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%latitude, y2 = y2) + used = send_data (id_lat , y2, Time_diag, is, js ) + if (generate_orbital_output) then + used = send_data (id_lat_sat , y2, Time_diag, is, js, mask = & + lflag_array(is:ie,js:je,nsat_time)) +endif + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%longitude, y2 = y2) + used = send_data (id_lon , y2, Time_diag, is, js ) + if (generate_orbital_output) then + used = send_data (id_lon_sat , y2, Time_diag, is, js, mask = & + lflag_array(is:ie,js:je,nsat_time)) +endif + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%sunlit, y2 = y2sunlit) + used = send_data (id_sunlit , y2sunlit, Time_diag, is, js ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%skt, y2 = y2) + used = send_data (id_skt , y2, Time_diag, is, js ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%land, y2 = y2) + used = send_data (id_land , y2, Time_diag, is, js ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%u_wind, y2 = y2) + used = send_data (id_u_wind , y2, Time_diag, is, js ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%v_wind, y2 = y2) + used = send_data (id_v_wind , y2, Time_diag, is, js ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=gbx%sfc_height, y2 = y2) + used = send_data (id_sfcht , y2, Time_diag, is, js ) + +! 3D fields: + + used = send_data (id_ph , phalf_plus, Time_diag, is, js, 1 ) + used = send_data (id_zh , zhalf_plus, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%p, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_p , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%zlev, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_z , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%mr_ozone, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_mr_ozone , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%T, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_T , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%sh, y3 = y3) + call flip_vert_index (y3, nlevels,y37 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%q, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_rh , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%tca, y3 = y3) + call flip_vert_index (y3, nlevels,y35 ) + used = send_data (id_tca , y35, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%cca, y3 = y3) + call flip_vert_index (y3, nlevels,y36 ) + used = send_data (id_cca , y36, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%mr_hydro(:,:,I_lscliq), y3 = y3) + call flip_vert_index (y3, nlevels,y31 ) + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%mr_hydro(:,:,i_lscice), y3 = y3) + call flip_vert_index (y3, nlevels,y32 ) + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%mr_hydro(:,:,i_cvcliq), y3 = y3) + call flip_vert_index (y3, nlevels,y33 ) + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%mr_hydro(:,:,I_cvcice), y3 = y3) + call flip_vert_index (y3, nlevels,y34 ) + + used = send_data (id_lsca_cmip , y35-y36, Time_diag, is, js, 1, & + mask = y31 > 0) + used = send_data (id_cca_cmip , y36, Time_diag, is, js, 1, & + mask = y33 > 0) + + used = send_data (id_lsliq , (y35-y36)*y31/((1.0+y36*(y33+y34))*& + (1+y31)), Time_diag, is, js, 1 ) + + used = send_data (id_lsice , (y35-y36)*y32/((1.0+y36* & + (y33+y34))*(1+y32)), Time_diag, is, js, 1 ) + + used = send_data (id_ccliq , y36*y33/((1.0+y36*(y33+y34))* & + (1+y33)), Time_diag, is, js, 1 ) + + used = send_data (id_ccice , y36*y34/((1.0+y36*(y33+y34))* & + (1+y34)), Time_diag, is, js, 1 ) + + used = send_data (id_sh , y37/(1.+y36*(y33+y34)), & + Time_diag, is, js, 1 ) + used = send_data (id_tot_h2o , (y37 + (y35-y36)*y31/(1.+y31)+ & + (y35-y36)*y32/(1.+y32)+y36*(y33/(1.+y33)+y34/(1.+y34)))/ & + ((1.0+y36*(y33+y34) )), Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%rain_ls, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_fl_lsrain , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%snow_ls, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_fl_lssnow , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%grpl_ls, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_fl_lsgrpl , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%rain_cv, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_fl_ccrain , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%snow_cv, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_fl_ccsnow , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_lscliq),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_lsclliq , 0.5*y3a, Time_diag, is, js, 1, & + mask = y31 > 0.0 ) + used = send_data (id_reff_lsclliq_cmip , 0.5*y3a*(y35-y36) , Time_diag, is, js, 1, & + mask = y31 > 0.0 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_lscice),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_lsclice , 0.5*y3a, Time_diag, is, js, 1 , & + mask = y32 > 0.0) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_lsrain),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_lsprliq , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_lssnow),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_lsprice , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_cvcliq),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_ccclliq , 0.5*y3a, Time_diag, is, js, 1 , & + mask = y33 > 0.0) + used = send_data (id_reff_ccclliq_cmip , 0.5*y3a*y36 , Time_diag, is, js, 1 , & + mask = y33 > 0.0) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_cvcice),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_ccclice , 0.5*y3a, Time_diag, is, js, 1 , & + mask = y34 > 0.0) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_cvrain),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_ccprliq , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%reff(:,:,i_cvsnow),& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_reff_ccprice , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%dtau_s, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_dtau_s , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%dtau_c, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_dtau_c , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%dem_s, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_dem_s , y3a, Time_diag, is, js, 1 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x2=gbx%dem_c, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_dem_c , y3a, Time_diag, is, js, 1 ) + +!--------------------------------------------------------------------- +! process COSP output variables +!--------------------------------------------------------------------- + + if (cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,4),& + y2 = y2) + used = send_data (id_cltcalipso, y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + if (generate_orbital_output) then + used = send_data (id_cltcalipso_sat, y2, Time_diag, is, js , & + mask = y2 /= missing_value .and. & + lflag_array(is:ie,js:je,nsat_time)) + endif + + call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,1),& + y2 = y2) + used = send_data (id_cllcalipso, y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + if (generate_orbital_output) then + used = send_data (id_cllcalipso_sat, y2, Time_diag, is, js , & + mask = y2 /= missing_value .and. & + lflag_array(is:ie,js:je,nsat_time)) + endif + + call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,2),& + y2 = y2) + used = send_data (id_clmcalipso, y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + if (generate_orbital_output) then + used = send_data (id_clmcalipso_sat, y2, Time_diag, is, js , & + mask = y2 /= missing_value .and. & + lflag_array(is:ie,js:je,nsat_time)) + endif + + call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,3),& + y2 = y2) + used = send_data (id_clhcalipso, y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + if (generate_orbital_output) then + used = send_data (id_clhcalipso_sat, y2, Time_diag, is, js , & + mask = y2 /= missing_value .and. & + lflag_array(is:ie,js:je,nsat_time)) + endif + endif + + if(cfg%Lradar_sim .and.cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=stradar%radar_lidar_tcc,y2 = y2) + used = send_data (id_cltlidarradar, y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + endif + + if (cfg%Lisccp_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%totalcldarea,& + y2 = y2save) + used = send_data (id_tclisccp, y2save, Time_diag, is, js , & + mask = y2save /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meanptop,& + y2 = y2) + where (y2save== 0.0 .and. y2sunlit == 1.0) + alpha = 0.0 + elsewhere + alpha = y2*y2save + endwhere + + used = send_data (id_ctpisccp , alpha , Time_diag, is, js , & + mask = y2sunlit == 1.0 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meantb,& + y2 = y2) + + used = send_data (id_tbisccp , y2, Time_diag, is, js , & + mask = y2sunlit == 1.0 ) +!--- + + call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meantbclr,& + y2 = y2) + used = send_data (id_tbclrisccp , y2, Time_diag, is, js , & + mask = y2sunlit == 1.0 ) + +!---- + call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meantaucld,& + y2 = y2) + where (y2save== 0.0 .and. y2sunlit == 1.0) + alpha = 0.0 + elsewhere + alpha = y2*y2save + endwhere + + used = send_data (id_tauisccp , alpha , Time_diag, is, js , & + mask = y2sunlit == 1.0 ) + + call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meanalbedocld,& + y2 = y2) + where (y2save== 0.0 .and. y2sunlit == 1.0) + alpha = 0.0 + elsewhere + alpha = y2*y2save + endwhere + + used = send_data (id_albisccp , alpha, Time_diag, is, js , & + mask = y2sunlit == 1.0 ) + endif + + if (cfg%Lmodis_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Fraction_Total_Mean, & + y2 = y2save) + used = send_data (id_tclmodis , y2save, Time_diag, is, js , & + mask = y2save /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Fraction_High_Mean, & + y2 = y2) + used = send_data (id_hicldmodis , y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Fraction_Mid_Mean, & + y2 = y2) + used = send_data (id_mdcldmodis , y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Fraction_Low_Mean, & + y2 = y2) + used = send_data (id_locldmodis , y2, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Fraction_Water_Mean, & + y2 = y2lsave) + used = send_data (id_lclmodis , y2lsave, Time_diag, is, js , & + mask = y2lsave /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Fraction_Ice_Mean, & + y2 = y2isave) + used = send_data (id_iclmodis , y2isave, Time_diag, is, js , & + mask = y2isave /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Optical_Thickness_Total_Mean, & + y2 = y2) + + where (y2save == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2save + endwhere + + used = send_data (id_ttaumodis , alpha, Time_diag, is, js , & + mask = y2sunlit == 1.0 ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Optical_Thickness_Water_Mean, & + y2 = y2) + where (y2lsave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2lsave + endwhere + + used = send_data (id_ltaumodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Optical_Thickness_Ice_Mean, & + y2 = y2) + where (y2isave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2save + alpha = y2*y2isave + endwhere + + used = send_data (id_itaumodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Optical_Thickness_Total_LogMean, & + y2 = y2) + where (y2save == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2save + endwhere + + used = send_data (id_tlogtaumodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Optical_Thickness_Water_LogMean, & + y2 = y2) + where (y2lsave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2lsave + endwhere + + used = send_data (id_llogtaumodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Optical_Thickness_Ice_LogMean, & + y2 = y2) + where (y2isave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2isave + endwhere + + used = send_data (id_ilogtaumodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Particle_Size_Water_Mean, & + y2 = y2) + where (y2lsave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2lsave + endwhere + + used = send_data (id_lremodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + lmsk(:,:) = (y2(:,:) < 0.0) .and. (y2(:,:) > -1.0) + used = send_data (id_badlremodis , y2, Time_diag, is, js , & + mask = lmsk ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Particle_Size_Ice_Mean, & + y2 = y2) + where (y2isave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2isave + endwhere + + used = send_data (id_iremodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + lmsk(:,:) = (y2(:,:) < 0.0) .and. (y2(:,:) > -1.0) + used = send_data (id_badiremodis , y2, Time_diag, is, js , & + mask = lmsk ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Cloud_Top_Pressure_Total_Mean, & + y2 = y2) + where (y2save == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2save + endwhere + + used = send_data (id_ctpmodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Liquid_Water_Path_Mean, & + y2 = y2) + where (y2lsave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2lsave + endwhere + + used = send_data (id_lwpmodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + call map_point_to_ll (Nlon, Nlat, geomode, & + x1=modis%Ice_Water_Path_Mean, & + y2 = y2) + where (y2isave == 0.0 .and. y2sunlit == 1.0) + alpha = 0. + elsewhere + alpha = y2*y2isave + endwhere + + used = send_data (id_iwpmodis , alpha, Time_diag, is, js , & + mask = y2 /= missing_value ) + + + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=modis%Column_Optical_Thickness, y3 = y4) + do n=1,ncolumns + used = send_data (id_taumodis_n(n), y4(:,:,n), Time_diag, & + is, js, mask = y4(:,:,n) /= missing_value ) + end do + + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=modis%Column_Cloud_Top_Pressure, y3 = y4) + do n=1,ncolumns + used = send_data (id_ptopmodis_n(n), 0.01*y4(:,:,n), Time_diag, & + is, js, mask = y4(:,:,n) /= missing_value ) + end do + + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=modis%Column_Particle_Size, y3 = y4) + do n=1,ncolumns + used = send_data (id_sizemodis_n(n), y4(:,:,n), Time_diag, & + is, js, mask = y4(:,:,n) > 0.0 ) + + lmsk(:,:) = (y4(:,:,n) < 0.0) .and. (y4(:,:,n) > -1.0) + used = send_data (id_badsizemodis_n(n), y4(:,:,n), Time_diag, & + is, js, mask = lmsk ) + end do + + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=modis%retrievedPhase , y3 = y4) + do n=1,ncolumns + used = send_data (id_phasemodis_n(n), y4(:,:,n), Time_diag, & + is, js, mask = y4(:,:,n) /= missing_value ) + end do + + endif + + if (use_vgrid) then + if (cfg%Llidar_sim) then + + call map_point_to_ll (Nlon, Nlat, geomode, x2=stlidar%lidarcld,& + y3 = z3) + used = send_data (id_clcalipso, z3 , Time_diag, is, js, 1, & + mask = z3 (:,:,:) /= missing_value ) + if (generate_orbital_output) then + used = send_data (id_clcalipso_sat, z3 , Time_diag, is, js, 1, & + mask = (z3 (:,:,:) /= missing_value) .and.& + lflag_array_temp(is:ie,js:je,:,nsat_time)) + endif + endif + if(cfg%Lradar_sim .and. cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=stradar%lidar_only_freq_cloud, y3 = z3) + used = send_data (id_clcalipso2, z3 , Time_diag, is, js, 1 , & + mask = z3 (:,:,:) /= missing_value ) + if (generate_orbital_output) then + used = send_data (id_clcalipso2_sat, z3 , Time_diag, is, js, 1, & + mask = (z3 (:,:,:) /= missing_value) .and.& + lflag_array_temp(is:ie,js:je,:,nsat_time)) + endif + endif + else + if (cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, x2=stlidar%lidarcld,& + y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_clcalipso_mdl, y3a, Time_diag, is, js, 1, & + mask = y3a(:,:,:) /= missing_value ) + endif + if(cfg%Lradar_sim .and. cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=stradar%lidar_only_freq_cloud, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_clcalipso2_mdl, y3a, Time_diag, is, js, 1 , & + mask = y3a(:,:,:) /= missing_value ) + endif + endif + +!3d arrays (i,j,columns): + if (cfg%Lisccp_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=isccp%boxtau, y3 = y4) + used = send_data (id_boxtauisccp, y4, Time_diag, is, js, & + mask = y4 /= missing_value ) + do n=1,ncolumns + used = send_data (id_boxtauisccp_n(n), y4(:,:,n), Time_diag, & + is, js, mask = y4(:,:,n) /= missing_value ) + end do + + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=isccp%boxptop, y3 = y4) + used = send_data (id_boxptopisccp, y4, Time_diag, is, js ) + do n=1,ncolumns + used = send_data (id_boxptopisccp_n(n), y4(:,:,n), Time_diag, & + is, js, mask = y4(:,:,n) /= missing_value ) + end do + endif + +!3d arrays (i,j,parasol_nrefl): + if (cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=stlidar%parasolrefl, y3 = y5) + used = send_data (id_parasolrefl, y5, Time_diag, is, js, 1 , & + mask = y5 /= missing_value ) + if (generate_orbital_output) then + used = send_data (id_parasolrefl_sat, y5, Time_diag, is, js, 1 , & + mask = y5 /= missing_value .and. & + lflag_array_parasol(is:ie,js:je,:,nsat_time)) + endif + call map_point_to_ll (Nlon, Nlat, geomode, & + x2=sglidar%beta_mol, y3 = y3) + call flip_vert_index (y3, nlevels,y3a ) + used = send_data (id_betamol532, y3a, Time_diag, is, js, 1 , & + mask = y3 /= missing_value ) + endif + +!4d array (i,j,columns, levels): + call map_point_to_ll (Nlon, Nlat, geomode, x3=sg%frac_out, y4 = y6) + call flip_vert_index (y6, nlevels,y6a ) + do n=1, size(id_cloud_type,1) + used = send_data (id_cloud_type(n), y6a(:,:,n,:), & + Time_diag, is, js,1 ) + end do + +!4d array (i,j,columns, levels): + if(cfg%Lradar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=sgradar%Ze_tot, y4 = y6) + call flip_vert_index (y6, nlevels,y6a ) + do n=1, size(id_dbze94,1) + used = send_data (id_dbze94(n), y6a(:,:,n,:), Time_diag, is, js,1 ) + end do + +!4d array (i,j, dbze_bins, levels): + if (use_vgrid) then + call map_point_to_ll (Nlon, Nlat, geomode, x3=stradar%cfad_ze, & + y4 = z7) + do n=1, size(id_cloudsatcfad,1) + used = send_data (id_cloudsatcfad(n), z7(:,:,n,:), Time_diag, & + is, js, 1, mask = z7(:,:,n,:) /= missing_value ) + if (generate_orbital_output) then + used = send_data (id_cloudsatcfad_sat(n), z7(:,:,n,:), Time_diag,& + is, js, 1, mask = (z7(:,:,n,:) /= missing_value) .and. & + lflag_array_temp(is:ie,js:je,:,nsat_time)) + endif + end do + else + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=stradar%cfad_ze, y4 = y7) + call flip_vert_index (y7, nlevels,y7a ) + do n=1, size(id_cloudsatcfad_mdl,1) + used = send_data (id_cloudsatcfad_mdl(n), y7a(:,:,n,:), & + Time_diag, is, js,1 , & + mask = y7a(:,:,n,:) /= missing_value ) + end do + endif +endif + +!4d array (i,j,columns, levels ): + if (cfg%Llidar_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=sglidar%beta_tot, y4 = y6) + call flip_vert_index (y6, nlevels,y6a ) + do n=1, size(id_atb532,1) + used = send_data (id_atb532(n), y6a(:,:,n,:), Time_diag, is, & + js, 1, mask = y6a(:,:,n,:) /= missing_value ) + end do + +!4d array (i,j, sr_bins,levels): + if (use_vgrid) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=stlidar%cfad_sr, y4 = z8) + do n=1, size(id_calipsosrcfad,1) + used = send_data (id_calipsosrcfad(n), z8(:,:,n,:), & + Time_diag, is, js,1 , & + mask = z8 (:,:,n,:) /= missing_value ) + if (generate_orbital_output) then + used = send_data (id_calipsosrcfad_sat(n), z8(:,:,n,:), & + Time_diag, is, js,1 , & + mask = (z8 (:,:,n,:) /= missing_value) .and. & + lflag_array_temp(is:ie,js:je,:,nsat_time)) + endif + end do + else + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=stlidar%cfad_sr, y4 = y8) + call flip_vert_index (y8, nlevels,y8a ) + do n=1, size(id_calipsosrcfad_mdl,1) + used = send_data (id_calipsosrcfad_mdl(n), y8a (:,:,n,:), & + Time_diag, is, js,1 , & + mask = y8a(:,:,n,:) /= missing_value ) + end do + endif + endif + +!4d array (i,j, isccp_tau,isccp_press): + if (cfg%Lisccp_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=isccp%fq_isccp, y4 = y9) + do n=1, 7 + used = send_data (id_clisccp(n), y9(:,:,:,n), Time_diag, is, & + js, 1, mask = y9(:,:,:,n) /= missing_value ) + end do + + do m=1,7 + do n=1, 7 + used = send_data (id_clisccp_n(m,n), y9(:,:,m,n), Time_diag, & + is, js, mask = y9(:,:,m,n) /= missing_value ) + end do + end do + endif + + +!4d array (i,j, modis_tau,modis_press): + if (cfg%Lmodis_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=modis%Optical_Thickness_vs_Cloud_Top_Pressure, y4 = y12) + y13(:,:,1:numTauHistogramBins,:) = y12(:,:,2:numTauHistogramBins+1,:) + do n=1, numPressureHistogramBins + used = send_data (id_tauctpmodis(n), y13(:,:,:,n), Time_diag, is, & + js, 1, mask = y13(:,:,:,n) /= missing_value ) + end do + + do m=1,numTauHistogramBins + do n=1, numPressureHistogramBins + used = send_data (id_tauctpmodis_n(m,n), y13(:,:,m,n), Time_diag, & + is, js, mask = y13(:,:,m,n) /= missing_value ) + end do + end do + endif + +!4d array (i,j, isccp_tau,MISR_N_CTH ): + if (cfg%Lmisr_sim) then + call map_point_to_ll (Nlon, Nlat, geomode, & + x3=misr%fq_misr, y4 = y10) + do n=1, MISR_N_CTH + used = send_data (id_misr(n), y10(:,:,:,n), Time_diag, is, & + js, 1, mask = y10(:,:,:,n) /= missing_value ) + end do + + do m=1,7 + do n=1, MISR_N_CTH + used = send_data (id_misr_n(m,n), y10(:,:,m,n), Time_diag, & + is, js, mask = y10(:,:,m,n) /= missing_value ) + end do + end do + endif + +!------------------------------------------------------------------- + + +end subroutine output_cosp_fields + + + +!##################################################################### + +subroutine cosp_diagnostics_end + +!------------------------------------------------------------------- +! deallocate the module arrays. +!------------------------------------------------------------------- + deallocate (id_dbze94) + deallocate (id_cloud_type) + if (allocated(id_atb532)) deallocate (id_atb532) + if (use_vgrid) then + deallocate (id_cloudsatcfad) + deallocate (id_calipsosrcfad) + deallocate (id_cloudsatcfad_sat) + deallocate (id_calipsosrcfad_sat) + else + deallocate (id_cloudsatcfad_mdl) + deallocate (id_calipsosrcfad_mdl) + endif + + if (generate_orbital_output) then + deallocate (location, lflag_array, flag_array, lflag_array_temp, & + lflag_array_parasol, Time_start, Time_end) + endif + +end subroutine cosp_diagnostics_end + +!####################################################################### + +subroutine read_cloudsat_orbit + + +!------------------------------------------------------------------------ +! subroutine read_cloudsat_orbit reads a netcdf file containing the +! orbital position of the satellites as a function of time. +!------------------------------------------------------------------------ + + real*4, dimension(:), allocatable :: lat_in, lon_in + integer*2, dimension(:), allocatable :: year_in + byte, dimension(:), allocatable :: mon_in + byte, dimension(:), allocatable :: day_in, hour_in + byte, dimension(:), allocatable :: min_in + real*4, dimension(:), allocatable :: sec_in + integer, dimension(:), allocatable :: int_year_in + integer, dimension(:), allocatable :: int_mon_in + integer, dimension(:), allocatable :: int_day_in, int_hour_in + integer, dimension(:), allocatable :: int_min_in + real*8, dimension(:,:), allocatable :: lat_out, lon_out + + character (len = *), parameter :: LAT_NAME = "lat" + character (len = *), parameter :: LON_NAME = "lon" + character (len = *), parameter :: YEAR_NAME = "year" + character (len = *), parameter :: MON_NAME = "month" + character (len = *), parameter :: DAY_NAME = "day" + character (len = *), parameter :: HOUR_NAME = "hour" + character (len = *), parameter :: MIN_NAME = "minute" + character (len = *), parameter :: SEC_NAME = "second" + + integer :: lat_varid, lon_varid, year_varid, day_varid, & + mon_varid, hour_varid, min_varid, sec_varid + integer :: ncid + integer :: nlocs + integer (kind=4) :: rcode, recdim + type(time_type) :: Time + integer :: k, mm, ptctr, n, ll, j, i + integer :: yeara, montha, daya, houra, minutea, seconda + integer :: yearb, monthb, dayb, hourb, minuteb, secondb + integer :: is, ie, js, je + real :: UNSET = -500. + integer :: calendar, nstart + logical :: used + integer :: ndims, nvars, ngatts + integer :: ndsize + character*31 :: dummy + +!------------------------------------------------------------------------ +! open the netcdf file. +!------------------------------------------------------------------------ + ncid = ncopn (orbital_filename, 0, rcode) + +!------------------------------------------------------------------------ +! determine number of dimensions (ndims); current file has +! only 1 ("location") +!------------------------------------------------------------------------ + call ncinq (ncid, ndims, nvars, ngatts, recdim, rcode) + +!------------------------------------------------------------------------ +! determine value of the location dimension (nlocs) to use to dimension +! arrays allocated below. +!------------------------------------------------------------------------ + do n=1,ndims + call ncdinq(ncid, n, dummy, ndsize, rcode) + if (trim(dummy) == 'location') then + nlocs = ndsize + endif + end do + +!------------------------------------------------------------------------ +! allocate arrays to hold the data read from the file. +!------------------------------------------------------------------------ + allocate (lat_in(nlocs), lon_in(nlocs), year_in(nlocs), & + mon_in(nlocs), day_in(nlocs), hour_in(nlocs), & + min_in(nlocs), sec_in(nlocs), int_year_in(nlocs), & + int_mon_in(nlocs), int_day_in(nlocs), int_hour_in(nlocs), & + int_min_in(nlocs) ) + allocate (lat_out(num_sat_periods, max_sdgs_per_sat_period), & + lon_out(num_sat_periods, max_sdgs_per_sat_period) ) + +!------------------------------------------------------------------------ +! obtain the var_ids for the needed variables. +!------------------------------------------------------------------------ + + lat_varid = ncvid(ncid, LAT_NAME , rcode) + lon_varid = ncvid(ncid, LON_NAME , rcode) + year_varid = ncvid(ncid, YEAR_NAME , rcode) + mon_varid = ncvid(ncid, MON_NAME , rcode) + day_varid = ncvid(ncid, DAY_NAME , rcode) + hour_varid = ncvid(ncid, HOUR_NAME , rcode) + min_varid = ncvid(ncid, MIN_NAME , rcode) + sec_varid = ncvid(ncid, SEC_NAME , rcode) + +!------------------------------------------------------------------------ +! read the netcdf data. +!------------------------------------------------------------------------ + call ncvgt (ncid, lat_varid, 1, nlocs, lat_in, rcode) + call ncvgt (ncid, lon_varid, 1, nlocs, lon_in, rcode) + call ncvgt (ncid, year_varid, 1, nlocs, year_in, rcode) + call ncvgt (ncid, mon_varid, 1, nlocs, mon_in, rcode) + call ncvgt (ncid, day_varid, 1, nlocs, day_in, rcode) + call ncvgt (ncid, hour_varid, 1, nlocs, hour_in, rcode) + call ncvgt (ncid, min_varid, 1, nlocs, min_in, rcode) + call ncvgt (ncid, sec_varid, 1, nlocs, sec_in, rcode) + + call ncclos (ncid, rcode) + +!------------------------------------------------------------------------ +! convert non-integer fields to integers. +!------------------------------------------------------------------------ + int_year_in = year_in + int_mon_in = mon_in + int_day_in = day_in + int_hour_in = hour_in + int_min_in = min_in + +!------------------------------------------------------------------------ +! convert longitude to lie between 0 --> 360, rather than -180 --> 180. +!------------------------------------------------------------------------ + do mm=1, size(lon_in) + if (lon_in(mm) < 0.) then + lon_in(mm) = lon_in(mm) + 360. + endif + end do + +!------------------------------------------------------------------------ +! define the start and end of each time period for which the satellite +! orbital curtain data is desired. it is centered on sat_begin_time from +! the cosp_input namelist. +!------------------------------------------------------------------------ + Time_start(1) = set_date (sat_begin_time(1), sat_begin_time(2), & + sat_begin_time(3), sat_begin_time(4), & + sat_begin_time(5), sat_begin_time(6)) - & + set_time(sat_period/2,0) + Time_end(1) = Time_start(1) + set_time(sat_period, 0) + + do mm = 2,num_sat_periods + Time_start(mm) = Time_start(mm-1) + set_time(sat_period, 0) + Time_end (mm) = Time_end (mm-1) + set_time(sat_period, 0) + end do + +!------------------------------------------------------------------------ +! initialize output variables. +!------------------------------------------------------------------------ + lat_out = UNSET + lon_out = UNSET + flag_array = 0. + lflag_array = .false. + location = 0. + +!------------------------------------------------------------------------ +! define the latitudes/longitudes coordinates over which the satellite +! passes during each of the requested model sampling periods. +!------------------------------------------------------------------------ + calendar = get_calendar_type() + + nstart = 1 + do k=1,num_sat_periods + ptctr = 0 + do n=nstart, nlocs + if (calendar == NOLEAP) then +!------------------------------------------------------------------------ +! ignore 2/29 when using the noleap calendar +!------------------------------------------------------------------------ + if (int_mon_in(n) == 2 .and. int_day_in(n) == 29) cycle + endif + +!------------------------------------------------------------------------- +! determine if satellite observation time n is in any of the requested +! sampling periods. if it is before the first sampling period, cycle. +! if it is within sampling period k, increment the counter of obser- +! vation times ptctr and enter the satellite location in the output +! arrays as the ptctr occurrence for sampling period k. if the sampling +! period has ended, exit the loop. +!------------------------------------------------------------------------- + Time = set_date(int_year_in(n), int_mon_in(n), int_day_in(n), & + int_hour_in(n), int_min_in(n), INT(sec_in(n))) + if (Time < Time_start(k)) then + cycle + else if (Time >= Time_start(k) .and. Time < Time_end(k)) then + ptctr = ptctr + 1 + if (ptctr >= max_sdgs_per_sat_period) then + call error_mesg ('cosp_driver:read_cloudsat_orbit', & + ' Need to increase &cosp_input variable & + &max_sdgs_per_sat_period', FATAL) + endif + lat_out(k, ptctr) = lat_in(n) + lon_out(k,ptctr) = lon_in(n) + else if (Time >= Time_end(k)) then + +!------------------------------------------------------------------------- +! reset starting index into observations for next sampling period. +!------------------------------------------------------------------------- + nstart = n - 1 + exit + endif + end do ! n + +!------------------------------------------------------------------------- +! reset counter for next sampling period. +!------------------------------------------------------------------------- + ptctr = 0 + end do ! k + +!------------------------------------------------------------------------- +! call get_local_indexes2 to map the latitudes/longitudes seen by the +! satellite during sampling period k to the closest model grid point +! (is,js). set a logical to indicate that grid point (is,js) is seen +! during time period k. +!------------------------------------------------------------------------- + do k=1,num_sat_periods + do ll = 1,max_sdgs_per_sat_period + if (lat_out(k,ll) == UNSET .and. lon_out(k,ll) == UNSET) exit + call get_local_indexes2(lat_out(k,ll),lon_out(k,ll), is,js) + if (is /= 0 .and. js /= 0 .and. is <= imax .and. js <= jmax) then + lflag_array(is,js,k) = .true. + location(is,js,k) = ll + endif + end do + +!------------------------------------------------------------------------- +! collect sampling frequency diagnostic, if desired. +!------------------------------------------------------------------------- + if (id_sampling_sat > 0) then + call get_date(Time_end(k), yearb, monthb, dayb, hourb, & + minuteb, secondb) + do j=1,jmax + do i=1,imax + if (lflag_array(i,j,k)) then + flag_array(i,j,monthb) = flag_array(i,j,monthb) + 1. + endif + end do + end do + endif + end do + +!------------------------------------------------------------------------- +! define additional flag arrays for other diagnostics. +!------------------------------------------------------------------------- + do k=1,PARASOL_NREFL + lflag_array_parasol(:,:,k,:) = lflag_array(:,:,:) + end do + do k=1,nlr + lflag_array_temp(:,:,k,:) = lflag_array(:,:,:) + end do + +!------------------------------------------------------------------------- +! output the satellite sampling frequency at each point for each +! month of the year for which data is requested. +!------------------------------------------------------------------------- + used = send_data (id_sampling_sat, flag_array, & + is_in=1, js_in=1, ks_in=1) + +!------------------------------------------------------------------------- +! output the satellite location index for each sampling period +! for which data is requested. +!------------------------------------------------------------------------- + used = send_data (id_location_sat, location, & + is_in=1, js_in=1, ks_in=1, mask = location > 0.) + +!----------------------------------------------------------------------- +! deallocate local variables. +!----------------------------------------------------------------------- + deallocate (lat_in, lon_in, year_in, mon_in,& + day_in, hour_in, min_in, sec_in,& + int_year_in, int_mon_in, int_day_in, & + int_hour_in, int_min_in, lat_out, lon_out ) + +end subroutine read_cloudsat_orbit + +!##################################################################### + + + +end module cosp_diagnostics_mod + diff --git a/src/atmos_param/cosp/cosp_driver.F90 b/src/atmos_param/cosp/cosp_driver.F90 index 432c5cc677..d67654cd56 100644 --- a/src/atmos_param/cosp/cosp_driver.F90 +++ b/src/atmos_param/cosp/cosp_driver.F90 @@ -1,264 +1,234 @@ +#include "cosp_defs.H" + +module cosp_driver_mod ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. ! -! Redistribution and use in source and binary forms, with or without mod ification, are permitted +! Redistribution and use in source and binary forms, with or without modification, are permitted ! provided that the following conditions are met: ! ! * Redistributions of source code must retain the above copyright notice, this list ! of conditions and the following disclaimer. ! * Redistributions in binary form must reproduce the above copyright notice, this list ! of conditions and the following disclaimer in the documentation and/or other materials -! provided with the distributio +! provided with the distribution. ! * Neither the name of the Met Office nor the names of its contributors may be used ! to endorse or promote products derived from this software without specific prior written ! permission. -! +! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR ! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THECOPYRIGHT OWNER OR +! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER ! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ! OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -! -! History: -! Feb 2008 - A. Bodas-Salcedo - Initial version -! -#include "cosp_defs.h" -!PROGRAM COSPTEST -module cosp_driver_mod -use mpp_mod, only: input_nml_file -use fms_mod, only: open_namelist_file, open_file, & - close_file, error_mesg, FATAL, & - file_exist, mpp_pe, mpp_root_pe, & - check_nml_error, write_version_number, & - stdlog -use sat_vapor_pres_mod, only: compute_qs -use time_manager_mod, only: set_date, time_type, operator (+), & - operator(-), & - operator(<), operator(>), operator(<=), & - operator(>=), get_date, print_date, & - get_calendar_type, NOLEAP, & - assignment(=), set_time -use diag_grid_mod, only: get_local_indexes2 -use diag_manager_mod, only: register_diag_field, send_data, & - diag_axis_init, register_static_field -USE MOD_COSP_TYPES, only: cosp_config, cosp_gridbox, cosp_subgrid,& - cosp_sgradar, cosp_sglidar, cosp_isccp, & +use mpp_mod, only: input_nml_file +use fms_mod, only: open_namelist_file, open_file, & + close_file, error_mesg, FATAL, & + file_exist, mpp_pe, mpp_root_pe, & + check_nml_error, write_version_number, & + stdlog +use sat_vapor_pres_mod, only: compute_qs +use time_manager_mod, only: set_date, time_type, operator (+), & + operator(-), operator(<), & + operator(>), operator(<=), & + operator(>=), get_date, print_date, & + get_calendar_type, NOLEAP, & + assignment(=), set_time +USE MOD_COSP_TYPES, only: cosp_config, cosp_gridbox, & + cosp_subgrid, cosp_sgradar, & + cosp_sglidar, cosp_isccp, & #ifdef RTTOV - cosp_rttov, & + cosp_rttov, & #endif - cosp_vgrid, cosp_radarstats, & - cosp_lidarstats, & - cosp_sghydro, cosp_misr, & - construct_cosp_gridbox, & - construct_cosp_misr, & - construct_cosp_vgrid, & - construct_cosp_subgrid, & - construct_cosp_sghydro, & - construct_cosp_sgradar, & - construct_cosp_radarstats, & - construct_cosp_sglidar, & - construct_cosp_lidarstats, & - construct_cosp_isccp, & + cosp_vgrid, cosp_radarstats, & + cosp_lidarstats, & + cosp_sghydro, cosp_misr, & + construct_cosp_gridbox, & + construct_cosp_misr, & + construct_cosp_vgrid, & + construct_cosp_subgrid, & + construct_cosp_sghydro, & + construct_cosp_sgradar, & + construct_cosp_radarstats, & + construct_cosp_sglidar, & + construct_cosp_lidarstats, & + construct_cosp_isccp, & #ifdef RTTOV - construct_cosp_rttov, & - free_cosp_rttov, & + construct_cosp_rttov, & + free_cosp_rttov, & #endif - free_cosp_gridbox, & - free_cosp_misr, & - free_cosp_vgrid, & - free_cosp_subgrid, & - free_cosp_sghydro, & - free_cosp_sgradar, & - free_cosp_radarstats, & - free_cosp_sglidar, & - free_cosp_lidarstats, & - free_cosp_isccp -USE MOD_COSP, only: cosp -USE MOD_COSP_IO, only: read_cosp_output_nl, & -! references to these routines are currently commented out when -! COSP is run within GCM -! nc_read_input_file,& -! nc_write_cosp_1d, nc_write_cosp_2d, & - map_ll_to_point, map_point_to_ll + free_cosp_gridbox, & + free_cosp_misr, & + free_cosp_vgrid, & + free_cosp_subgrid, & + free_cosp_sghydro, & + free_cosp_sgradar, & + free_cosp_radarstats, & + free_cosp_sglidar, & + free_cosp_lidarstats, & + free_cosp_isccp +USE MOD_COSP, only: cosp +USE MOD_COSP_IO, only: read_cosp_output_nl, & + map_ll_to_point, map_point_to_ll -use MOD_COSP_CONSTANTS, only: DBZE_BINS,SR_BINS, PARASOL_NREFL, & - PARASOL_SZA, CFAD_ZE_MIN, CFAD_ZE_WIDTH, & - LIDAR_UNDEF, ISCCP_PC_BNDS, ISCCP_TAU, & - I_LSCLIQ, I_LSCICE, I_CVCLIQ, I_CVCICE, & - I_LSGRPL, & - I_LSRAIN, I_LSSNOW, I_CVRAIN, I_CVSNOW, & - N_HYDRO, ISCCP_TAU_BNDS,& - RTTOV_MAX_CHANNELS, MISR_N_CTH, & - MISR_CTH_BNDS -use MOD_LMD_IPSL_STATS, only: define_srbval -use radar_simulator_types, only: radar_simulator_types_init +use MOD_COSP_CONSTANTS, only: PARASOL_NREFL, I_LSCLIQ, I_LSCICE, & + I_CVCLIQ, I_CVCICE, I_LSGRPL, & + I_LSRAIN, I_LSSNOW, I_CVRAIN, I_CVSNOW,& + N_HYDRO, RTTOV_MAX_CHANNELS use MOD_COSP_Modis_Simulator, only: COSP_MODIS, FREE_COSP_MODIS, & CONSTRUCT_COSP_MODIS -use mod_modis_sim, only: numTauHistogramBins, & - numPressureHistogramBins, & - tauHistogramBoundaries, & - nominalTauHistogramBoundaries, & - nominalTauHistogramCenters, & - nominalPressureHistogramBoundaries - +use cosp_diagnostics_mod, only: cosp_diagnostics_init, & + cosp_diagnostics_time_vary, & + output_cosp_fields, & + cosp_diagnostics_endts, & + cosp_diagnostics_end +use mod_cosp_utils, only: flip_vert_index + IMPLICIT NONE +public cosp_driver, cosp_driver_init, cosp_driver_end, cosp_driver_endts, & + cosp_driver_time_vary + !--------------------------------------------------------------------- !----------- version number for this module -------------------------- -character(len=128) :: version = '$Id: cosp_driver.F90,v 19.0 2012/01/06 20:03:24 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - - - - ! Local variables - character(len=64) :: cosp_input_nl='cosp_input_nl.txt' - character(len=64) :: cosp_output_nl='cosp_output_nl.txt' - character(len=512) :: finput ! Input file name - character(len=512) :: cmor_nl - character(len=8) :: wmode ! Writing mode 'replace' or 'append' - integer :: overlap ! overlap type: 1=max, 2=rand, 3=max/rand - integer :: isccp_topheight,isccp_topheight_direction - integer :: Ncolumns ! Number of subcolumns in SCOPS -! integer :: Npoints ! Number of gridpoints - integer :: Nlevels ! Number of levels - integer :: Nlr ! Number of levels in statistical outputs - integer :: Npoints_it ! Max number of gridpoints to be processed in one iteration - integer,parameter :: ntsteps=5 - type(cosp_config) :: cfg ! Configuration options - integer :: t0,t1,count_rate,count_max -! integer :: Nlon,Nlat,geomode - integer :: geomode - real :: radar_freq,k2,ZenAng,co2,ch4,n2o,co,emsfc_lw - integer,dimension(RTTOV_MAX_CHANNELS) :: Channels - real,dimension(RTTOV_MAX_CHANNELS) :: Surfem - integer :: surface_radar,use_mie_tables,use_gas_abs,do_ray,melt_lay - integer :: Nprmts_max_hydro,Naero,Nprmts_max_aero,lidar_ice_type - integer :: platform,satellite,Instrument,Nchannels - logical :: use_vgrid,csat_vgrid,use_precipitation_fluxes,use_reff - logical :: use_input_file = .true. - logical :: produce_cmor_output_fields = .true. - logical :: output_p_and_z_by_index = .false. - logical :: generate_orbital_output = .false. - character (len = 128) :: orbital_filename = ' ' - integer, dimension(6) :: sat_begin_time = (/0,0,0,0,0,0/) - integer :: sat_period = 0 ! [seconds] - integer :: num_sat_periods = 0 - integer :: max_sdgs_per_sat_period = 3500 - real :: emsfc_lw_nml=0.94 - logical :: use_rh_wrt_liq = .true. - namelist/COSP_INPUT/cmor_nl,overlap,isccp_topheight, & - isccp_topheight_direction, & - use_vgrid,nlr,csat_vgrid, & - npoints_it,finput, & - radar_freq,surface_radar,use_mie_tables, & - use_input_file, produce_cmor_output_fields, & - output_p_and_z_by_index, & - generate_orbital_output, orbital_filename, & - sat_begin_time, sat_period, num_sat_periods, & - max_sdgs_per_sat_period, & - emsfc_lw_nml, use_rh_wrt_liq, & - use_gas_abs,do_ray,melt_lay,k2,Nprmts_max_hydro, & - Naero,Nprmts_max_aero,lidar_ice_type, & - use_precipitation_fluxes,use_reff, & - platform,satellite,Instrument,Nchannels, & - Channels,Surfem,ZenAng,co2,ch4,n2o,co - double precision :: time(ntsteps)=(/1.D0,2.D0,3.D0,4.D0,5.D0/) +character(len=128) :: version = '$Id: cosp_driver.F90,v 20.0 2013/12/13 23:15:41 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' - !---------------- End of declaration of variables -------------- +!--------------------------------------------------------------------- +!namelist variables + +character(len=512) :: finput ! Input file name, not used in FMS +character(len=512) :: cmor_nl = ' ' ! not used in FMS +integer :: overlap = 3 ! overlap type: 1=max, 2=rand, 3=max/rand +integer :: isccp_topheight = 1 + ! 1 = adjust top height using both a computed + ! infrared brightness temperature and the visible + ! optical depth to adjust cloud top pressure. Note + ! that this calculation is most appropriate to + ! compare to ISCCP data during sunlit hours. + ! 2 = do not adjust top height, that is cloud top + ! pressure is the actual cloud top pressure + ! in the model + ! 3 = adjust top height using only the computed + ! infrared brightness temperature. Note that this + ! calculation is most appropriate to compare to + ! ISCCP IR only algortihm (i.e. you can compare to + ! nighttime ISCCP data with this option) + +integer :: isccp_topheight_direction = 2 + ! direction for finding atmosphere pressure level + ! with interpolated temperature equal to the + ! radiance determined cloud-top temperature + ! 1 = find the *lowest* altitude (highest pressure) + ! level with interpolated temperature equal to the + ! radiance determined cloud-top temperature + ! 2 = find the *highest* altitude (lowest pressure) + ! level with interpolated temperature equal to the + ! radiance determined cloud-top temperature + ! ONLY APPLICABLE IF top_height EQUALS 1 or 3 + +integer :: Nlr = 40 ! Number of levels in statistical outputs +integer :: Npoints_it = 20000 + ! Max number of gridpoints to be processed in + ! one iteration +real :: radar_freq = 94. ! CloudSat radar frequency (GHz) +real :: k2= -1. ! |K|^2, -1=use frequency dependent default +integer :: surface_radar = 0 ! surface=1, spaceborne=0 +integer :: use_mie_tables = 0 ! use a precomputed lookup table? yes=1,no=0 +integer :: use_gas_abs = 1 ! include gaseous absorption? yes=1,no=0 +integer :: do_ray = 0 ! calculate/output Rayleigh refl=1, not=0 +integer :: melt_lay = 0 ! melting layer model off=0, on=1 +integer :: Nprmts_max_hydro = 12 + ! Max number of parameters for hydrometeor + ! size distributions +integer :: Naero = 1 ! Number of aerosol species (Not used) +integer :: Nprmts_max_aero = 1 ! Max number of parameters for aerosol + ! size distributions (Not used) +integer :: lidar_ice_type = 0 ! Ice particle shape in lidar calculations + ! (0=ice-spheres ; 1=ice-non-spherical) +logical :: use_vgrid = .true. ! Use fixed vertical grid for outputs? + ! (if .true. then you need to define number + ! of levels with Nlr) +logical :: csat_vgrid =.true. ! CloudSat vertical? + ! (if .true. then the CloudSat standard grid + ! is used for the outputs. +logical :: use_precipitation_fluxes =.true. + ! True if precipitation fluxes are input + ! to the algorithm +logical :: use_reff =.true. ! True if you want effective radius to be + ! used by radar simulator (always used + ! by lidar) +logical :: use_input_file = .false. +logical :: produce_cmor_output_fields = .false. +real :: emsfc_lw_nml=0.94 +logical :: use_rh_wrt_liq = .true. +!------------------------------------------------------------------------- +!-------------- RTTOV inputs +!------------------------------------------------------------------------- +integer :: platform = 1 ! satellite platform +integer :: satellite = 15 ! satellite +integer :: Instrument = 0 ! instrument +integer :: Nchannels = 8 ! Number of channels to be computed +real :: ZenAng = 50. ! Satellite Zenith Angle +real :: co2 = 5.241e-04 ! mixing ratio of trace gas +real :: ch4 = 9.139e-07 ! mixing ratio of trace gas +real :: n2o = 4.665e-07 ! mixing ratio of trace gas +real :: co = 2.098e-07 ! mixing ratio of trace gas +integer,dimension(RTTOV_MAX_CHANNELS) :: Channels = 0 + ! Channel numbers (please be sure that + ! you supply Nchannels) +real,dimension(RTTOV_MAX_CHANNELS) :: Surfem = 0.0 + ! Surface emissivity (please be sure that + ! you supply Nchannels) + +namelist/COSP_INPUT/cmor_nl,overlap,isccp_topheight, & + isccp_topheight_direction, & + use_vgrid,nlr,csat_vgrid, & + npoints_it,finput, & + radar_freq,surface_radar,use_mie_tables, & + use_input_file, produce_cmor_output_fields, & + emsfc_lw_nml, use_rh_wrt_liq, & + use_gas_abs,do_ray,melt_lay,k2,Nprmts_max_hydro, & + Naero,Nprmts_max_aero,lidar_ice_type, & + use_precipitation_fluxes,use_reff, & + platform,satellite,Instrument,Nchannels, & + Channels,Surfem,ZenAng,co2,ch4,n2o,co + +! Local variables + +character(len=64) :: cosp_output_nl='cosp_output_nl.txt' +integer :: Ncolumns ! Number of subcolumns in SCOPS +integer :: Nlevels ! Number of levels +type(cosp_config) :: cfg ! Configuration options +integer :: geomode +real :: emsfc_lw +double precision :: time=1.D0 +double precision :: time_bnds(2)= (0.5D0, 1.5D0) + +!---------------- End of declaration of variables -------------- -public cosp_driver, cosp_driver_init, cosp_driver_end - -character(len=16) :: mod_name = 'cosp' - -integer, dimension(14) :: cosp_axes - -integer :: id_lat, id_lon, id_p, id_ph, id_z, id_zh, id_T, id_sh, & - id_u_wind, id_v_wind, id_mr_ozone, & - id_tot_h2o, & - id_rh, id_tca, id_cca, id_lsliq, id_lsice, id_ccliq, & - id_ccice, id_fl_lsrain, id_fl_lssnow, id_fl_lsgrpl, & - id_fl_ccrain, id_fl_ccsnow, & - id_reff_lsclliq, id_reff_lsclice, & - id_reff_lsprliq, id_reff_lsprice, & - id_reff_ccclliq, id_reff_ccclice, & - id_reff_ccprliq, id_reff_ccprice, & - id_reff_lsclliq_cmip, id_reff_ccclliq_cmip, & - id_lsca_cmip, id_cca_cmip, & - id_dtau_s, id_dtau_c, id_dem_s, id_dem_c, id_skt, id_land, & - id_sfcht, id_sunlit -integer :: id_cltcalipso_sat, id_cllcalipso_sat, id_clmcalipso_sat, & - id_clhcalipso_sat -integer :: id_cltcalipso, id_cllcalipso, id_clmcalipso, id_clhcalipso, & - id_cltlidarradar, id_tclisccp, id_ctpisccp, id_tauisccp, & - id_tbisccp, id_tbclrisccp, & - id_betamol532, & - id_albisccp, id_clcalipso, id_clcalipso2, & - id_clcalipso_sat, id_clcalipso2_sat, & - id_clcalipso_mdl, id_clcalipso2_mdl, & - id_boxtauisccp, id_boxptopisccp, id_parasolrefl, & - id_parasolrefl_sat, & - id_sampling_sat, id_location_sat, id_lat_sat, id_lon_sat -integer :: id_tclmodis, id_lclmodis, id_iclmodis, id_ttaumodis, & - id_ltaumodis, id_itaumodis, id_tlogtaumodis, & - id_llogtaumodis, id_ilogtaumodis, id_lremodis, & - id_badlremodis, id_badiremodis, & - id_locldmodis, id_mdcldmodis, id_hicldmodis, & - id_iremodis, id_ctpmodis, id_lwpmodis, id_iwpmodis -integer, allocatable, dimension(:) :: id_dbze94, id_cloudsatcfad, & - id_cloudsatcfad_sat, & - id_atb532, id_calipsosrcfad, & - id_calipsosrcfad_sat, & - id_cloud_type, id_boxtauisccp_n, & - id_boxptopisccp_n, & - id_taumodis_n, id_ptopmodis_n, & - id_badsizemodis_n, & - id_sizemodis_n, id_phasemodis_n -integer, allocatable, dimension(:) :: id_cloudsatcfad_mdl, & - id_calipsosrcfad_mdl -integer , dimension(7) :: id_clisccp -integer , dimension(7,7) :: id_clisccp_n -integer , dimension(MISR_N_CTH) :: id_misr -integer , dimension(7,MISR_N_CTH) :: id_misr_n -integer , dimension(numTauHistogramBins, numPressureHistogramBins) :: & - id_tauctpmodis_n -integer , dimension(numPressureHistogramBins) :: id_tauctpmodis - -real :: missing_value = -1.0E30 -real :: missing_value2 = -.000999 -double precision :: time_bnds(2,ntsteps) - -real, dimension(:,:,:), allocatable :: location -logical, dimension(:,:,:), allocatable :: lflag_array -logical, dimension(:,:,:,:), allocatable :: lflag_array_temp, & - lflag_array_parasol -real, dimension(:,:,:), allocatable :: flag_array -type(time_type), dimension(:), allocatable :: Time_start, Time_end -integer :: imax, jmax -integer :: nsat_time_prev - -include 'netcdf.inc' contains !###################################################################### -subroutine cosp_driver_init (lonb, latb, Time_diag, axes,kd_in, ncol_in) +subroutine cosp_driver_init (lonb, latb, Time_diag, axes, kd_in, ncol_in) - real, dimension(:,:), intent(in) :: lonb, latb - type(time_type), intent(in) :: Time_diag - integer, dimension(4), intent(in) :: axes - integer, intent(in) :: kd_in, ncol_in +real, dimension(:,:), intent(in) :: lonb, latb +type(time_type), intent(in) :: Time_diag +integer, dimension(4), intent(in) :: axes +integer, intent(in) :: kd_in, ncol_in integer :: io, unit, ierr, logunit + integer :: imax, jmax #ifdef INTERNAL_FILE_NML read (input_nml_file, nml=cosp_input, iostat=io) @@ -273,7 +243,7 @@ subroutine cosp_driver_init (lonb, latb, Time_diag, axes,kd_in, ncol_in) read (unit, nml=cosp_input, iostat=io, end=10) ierr = check_nml_error(io,'cosp_input') enddo -10 call close_file (unit) +10 call close_file (unit) endif #endif @@ -285,35 +255,21 @@ subroutine cosp_driver_init (lonb, latb, Time_diag, axes,kd_in, ncol_in) if (mpp_pe() == mpp_root_pe() ) & write (logunit, nml=cosp_input) + if (use_mie_tables /= 0) then + call error_mesg ('cosp_driver', & + 'use_mie_tables must be set to 0 currently', FATAL) + endif + nlevels = kd_in ncolumns = ncol_in - imax = size(lonb,1)- 1 - jmax = size(lonb,2)- 1 - - if (generate_orbital_output) then - if (sat_begin_time(1) == 0 .or. sat_begin_time(2) == 0 .or. & - sat_begin_time(3) ==0) then - call error_mesg ('cosp_driver_init', & - 'requesting orbital output but not supplying & - &valid start time', FATAL) - endif - if (sat_period == 0) then - call error_mesg ('cosp_driver_init', & - 'satellite sampling period [seconds] must be non-zero', FATAL) - endif - if (num_sat_periods == 0) then - call error_mesg ('cosp_driver_init', & - 'must define number of satellite periods to be processed', FATAL) - endif - if (trim(orbital_filename) == '') then - call error_mesg ('cosp_driver_init', & - 'filename for orbital specification not provided', FATAL) - endif - endif - + imax = size(lonb,1) - 1 + jmax = size(lonb,2) - 1 + call read_cosp_output_nl(cosp_output_nl,cfg) - call diag_field_init (Time_diag, axes) + call cosp_diagnostics_init & + (imax, jmax, Time_diag, axes, nlevels, ncolumns, cfg, & + use_vgrid, csat_vgrid, nlr) !--------------------------------------------------------------------- ! COSP takes a single, spacially independent value for surface @@ -326,976 +282,28 @@ subroutine cosp_driver_init (lonb, latb, Time_diag, axes,kd_in, ncol_in) !-------------------------------------------------------------------- geomode = 2 - call radar_simulator_types_init - - if (generate_orbital_output) then - allocate (location (imax,jmax, 1:num_sat_periods)) - allocate (lflag_array (imax,jmax, 0:num_sat_periods)) - allocate (lflag_array_temp (imax,jmax, nlr, 0:num_sat_periods)) - allocate (lflag_array_parasol & - (imax,jmax, PARASOL_NREFL, 0:num_sat_periods)) - allocate (flag_array(imax,jmax,12)) - allocate (Time_start(num_sat_periods)) - allocate (Time_end (num_sat_periods)) - call read_cloudsat_orbit - nsat_time_prev = 1 - endif end subroutine cosp_driver_init +!###################################################################### -!##################################################################### - - subroutine diag_field_init (Time, axes) - - type(time_type), intent(in) :: Time - integer, dimension(4), intent(in) :: axes - - real :: column_ax(Ncolumns) - real :: level_ax(Nlevels ) - real :: isccp_ax(7) - real :: modis_ax(numTauHistogramBins) - real :: dbze_ax(DBZE_BINS) - real :: lidar_ax(SR_BINS) - real :: sratio_bounds(2, SR_BINS) - real :: srbval(SR_BINS) - real :: csat_ax(NLR) - real :: month_ax(12) - real :: hr_ax(num_sat_periods) - integer :: parasol_ax(PARASOL_NREFL) - integer, dimension(3) :: halfindx = (/1,2,4/) - integer, dimension(3) :: columnindx = (/1,2,5/) - integer, dimension(3) :: levelindx = (/1,2,11/) - integer, dimension(3) :: parasolindx = (/1,2,6/) - integer, dimension(3) :: dbzeindx = (/1,2,7/) - integer, dimension(3) :: lidarindx = (/1,2,8/) - integer, dimension(3) :: tauindx = (/1,2,9/) - integer, dimension(3) :: modistauindx = (/1,2,12/) - integer, dimension(3) :: csatindx = (/1,2,10/) - integer, dimension(3) :: samplingindx = (/1,2,13/) - integer, dimension(3) :: samplingindx2 = (/1,2,14/) - integer :: i, n, m - integer :: id_columnindx, id_parasolindx, id_dbzeindx, id_lidarindx - integer :: id_levelindx - integer :: id_tauindx - integer :: id_modistauindx - integer :: id_csatindx - integer :: id_monindx - integer :: id_3hrindx - character(len=2) :: chvers, chvers4 - character(len=8) :: chvers2, chvers3, chvers5, chvers6 - type(cosp_gridbox) :: gbx_t ! Gridbox information. Input for COSP - type(cosp_vgrid) :: vgrid_t ! Information on vertical grid of stats - - -!-------------------------------------------------------------------- -! define the varisous axes needed for this data. -!-------------------------------------------------------------------- - cosp_axes(1:4) = axes(1:4) - -!-------------------------------------------------------------------- -! a level counter: -!-------------------------------------------------------------------- - do i=1,Nlevels - level_ax(i) = float(i) - end do - id_levelindx = diag_axis_init ('levelindx', level_ax, & - 'levels', 'n', 'level number', & - set_name = mod_name) - cosp_axes(11) = id_levelindx - -!-------------------------------------------------------------------- -! a stochastic column counter: -!-------------------------------------------------------------------- - do i=1,Ncolumns - column_ax(i) = float(i) - end do - id_columnindx = diag_axis_init ('columnindx', column_ax, & - 'subcol', 'n', 'subcolumn number', & - set_name = mod_name) - cosp_axes(5) = id_columnindx - -!-------------------------------------------------------------------- -! a PARASOL index counter: -!-------------------------------------------------------------------- - id_parasolindx = diag_axis_init ('parasolindx', PARASOL_SZA, & - 'parasolindx', 'n', 'parasol reflectivity index', & - set_name = mod_name) - cosp_axes(6) = id_parasolindx - -!-------------------------------------------------------------------- -! a radar bin counter: -!-------------------------------------------------------------------- - do i=1,DBZE_BINS - dbze_ax(i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i-0.5) - end do - id_dbzeindx = diag_axis_init ('dbzeindx', dbze_ax, & - 'dbzeindx', 'n', 'dbze', & - set_name = mod_name) - cosp_axes(7) = id_dbzeindx - -!-------------------------------------------------------------------- -! a lidar bin counter: -!-------------------------------------------------------------------- - - call define_srbval (srbval) - - sratio_bounds(1,:) = srbval(:) - sratio_bounds(2,1:SR_BINS-1) = srbval(2:SR_BINS) - sratio_bounds(2,SR_BINS) = srbval(SR_BINS) +10.0 - lidar_ax(1:SR_BINS) = (sratio_bounds(1,1:SR_BINS) + sratio_bounds(2,1:SR_BINS))/2.0 - id_lidarindx = diag_axis_init ('lidarindx', lidar_ax, & - 'lidarindx', 'n', 'lidar scattering', & - set_name = mod_name) - cosp_axes(8) = id_lidarindx - -!-------------------------------------------------------------------- -! an isccp tau bin counter: -!-------------------------------------------------------------------- - isccp_ax = isccp_tau - id_tauindx = diag_axis_init ('tauindx', isccp_ax, & - 'tauindx', 'n', 'isccp tau category', & - set_name = mod_name) - cosp_axes(9) = id_tauindx - -!-------------------------------------------------------------------- -! a modis tau bin counter: -!-------------------------------------------------------------------- - modis_ax = nominalTauHistogramCenters - id_modistauindx = diag_axis_init ('modistauindx', modis_ax, & - 'modistauindx', 'n', 'modis tau category', & - set_name = mod_name) - cosp_axes(12) = id_modistauindx - -!-------------------------------------------------------------------- -! a specified vertical index needed when use_vgrid = .true. -!-------------------------------------------------------------------- - gbx_t%Npoints = 256 - gbx_t%Ncolumns = ncolumns - gbx_t%Nlevels = Nlevels - allocate(gbx_t%zlev(256 , nlevels)) - allocate(gbx_t%zlev_half(256 , nlevels)) - gbx_t%zlev = 0.0 - gbx_t%zlev_half = 0.0 - call construct_cosp_vgrid(gbx_t,Nlr,use_vgrid,csat_vgrid,vgrid_t) - csat_ax = vgrid_t%z - id_csatindx = diag_axis_init ('csatindx', csat_ax, & - 'csatindx', 'z', 'csat vert index', & - set_name = mod_name) - cosp_axes(10) = id_csatindx - deallocate (gbx_t%zlev, gbx_t%zlev_half) - deallocate (vgrid_t%z, vgrid_t%zl, vgrid_t%zu, & - vgrid_t%mz, vgrid_t%mzl, vgrid_t%mzu) - do i=1,12 - month_ax(i) = i - end do - id_monindx = diag_axis_init ('samplingindx', month_ax, & - 'samplingindx', 'n', 'month index', & - set_name = mod_name) - cosp_axes(13) = id_monindx - - do i=1,num_sat_periods - hr_ax(i) = i - end do - id_3hrindx = diag_axis_init ('samplingindx2', hr_ax, & - 'samplingindx2', 'n', '3hr index', & - set_name = mod_name) - cosp_axes(14) = id_3hrindx - -!-------------------------------------------------------------------- -! register input fields with diag_manager. -!-------------------------------------------------------------------- - id_lat = register_diag_field & - (mod_name, 'lat', axes(1:2), Time, 'Latitude', 'degrees N') - - id_lon = register_diag_field & - (mod_name, 'lon', axes(1:2), Time, 'Longitude', 'degrees E') - - id_u_wind = register_diag_field & - (mod_name, 'u_wind', axes(1:2), Time, 'sfc u wind', 'm / s') - - id_v_wind = register_diag_field & - (mod_name, 'v_wind', axes(1:2), Time, 'sfc v wind', 'm / s') - - if (output_p_and_z_by_index) then - id_p = register_diag_field & - (mod_name, 'p', cosp_axes(levelindx), Time, & - 'P at full levels', 'Pa ') - id_ph = register_diag_field & - (mod_name, 'ph', cosp_axes(levelindx), Time, & - 'p at half levels', 'Pa') - id_z = register_diag_field & - (mod_name, 'z', cosp_axes(levelindx), Time, 'height ', 'meters') - id_zh = register_diag_field & - (mod_name, 'zh', cosp_axes(levelindx), Time, & - 'height at half levs', 'meters') - else - id_p = register_diag_field & - (mod_name, 'p', axes(1:3), Time, 'P at full levels', 'Pa ') - id_ph = register_diag_field & - (mod_name, 'ph', axes(halfindx), Time, 'p at half levels', 'Pa') - id_z = register_diag_field & - (mod_name, 'z', axes(1:3), Time, 'height ', 'meters ') - id_zh = register_diag_field & - (mod_name, 'zh', axes(halfindx), Time, 'height at half levs', & - 'meters') - endif - - id_mr_ozone = register_diag_field & - (mod_name, 'ozone', axes(1:3), Time, 'Ozone mass mixing ratio', & - 'kg (o3) / kg (air)') - - id_T = register_diag_field & - (mod_name, 'T', axes(1:3), Time, 'Temp at full levels', 'deg K ') - - id_sh = register_diag_field & - (mod_name, 'sh', axes(1:3), Time, & - 'vapor specific humidity at full levels', 'kg(h2o) / kg(air) ') - - id_rh = register_diag_field & - (mod_name, 'relhum', axes(1:3), Time, & - 'relative humidity at full levels', 'fraction ') - - id_tot_h2o = register_diag_field & - (mod_name, 'tot_h2o', axes(1:3), Time, & - 'total water substance', & - 'kg(h2o) / kg(air) ' ) - - id_lsca_cmip = register_diag_field & - (mod_name, 'lsca_cmip', axes(1:3), Time, & - 'ls liq cld fraction', 'fraction ', & - mask_variant = .true., & - missing_value = missing_value) - - id_cca_cmip = register_diag_field & - (mod_name, 'cca_cmip', axes(1:3), Time, & - 'convective liq cld fraction', 'fraction ', & - mask_variant = .true., & - missing_value = missing_value) - - id_tca = register_diag_field & - (mod_name, 'tca', axes(1:3), Time, & - 'total cld fraction', 'fraction ') - - id_cca = register_diag_field & - (mod_name, 'cca', axes(1:3), Time, & - 'convective cld fraction', 'fraction ') - - id_lsliq = register_diag_field & - (mod_name, 'lsliq', axes(1:3), Time, & - 'large scale cld liq', 'kg / kg ') - - id_lsice = register_diag_field & - (mod_name, 'lsice', axes(1:3), Time, & - 'large scale cld ice', 'kg / kg ') - - id_ccliq = register_diag_field & - (mod_name, 'ccliq', axes(1:3), Time, & - 'convective cld liq', 'kg / kg ') - - id_ccice = register_diag_field & - (mod_name, 'ccice', axes(1:3), Time, & - 'convective cld ice', 'kg / kg ') - - id_fl_lsrain = register_diag_field & - (mod_name, 'fl_lsrain', axes(1:3), Time, & - 'large scale rain flx', 'kg / (m**2 s)') - - id_fl_lssnow = register_diag_field & - (mod_name, 'fl_lssnow', axes(1:3), Time, & - 'large scale snow flx', 'kg / (m**2 s)') - - id_fl_lsgrpl = register_diag_field & - (mod_name, 'fl_lsgrpl', axes(1:3), Time, & - 'large scale graupel flx', 'kg / (m**2 s)') - - id_fl_ccrain = register_diag_field & - (mod_name, 'fl_ccrain', axes(1:3), Time, & - 'cnvctv scale rain flx', 'kg / (m**2 s)') - - id_fl_ccsnow = register_diag_field & - (mod_name, 'fl_ccsnow', axes(1:3), Time, & - 'cnvctv scale snow flx', 'kg / (m**2 s)') - - id_reff_lsclliq_cmip = register_diag_field & - (mod_name, 'reff_lsclliq_cmip', axes(1:3), Time, & - 'ls liq cld drop size*cfrac ', 'm', mask_variant = .true., & - missing_value = missing_value) - - id_reff_ccclliq_cmip = register_diag_field & - (mod_name, 'reff_ccclliq_cmip', axes(1:3), Time, & - 'cv liq cld drop size*cfrac ', 'm', mask_variant = .true., & - missing_value = missing_value) - - id_reff_lsclliq = register_diag_field & - (mod_name, 'reff_lsclliq', axes(1:3), Time, & - 'ls liq cld drop size ', 'm', mask_variant = .true., & - missing_value = missing_value) - - id_reff_lsclice = register_diag_field & - (mod_name, 'reff_lsclice', axes(1:3), Time, & - 'ls ice cld drop size ', 'm', mask_variant = .true., & - missing_value = missing_value) - - id_reff_lsprliq = register_diag_field & - (mod_name, 'reff_lsprliq', axes(1:3), Time, & - 'ls liq prcp drop size ', 'm') - - id_reff_lsprice = register_diag_field & - (mod_name, 'reff_lsprice', axes(1:3), Time, & - 'ls ice prcp drop size ', 'm') - - id_reff_ccclliq = register_diag_field & - (mod_name, 'reff_ccclliq', axes(1:3), Time, & - 'cv liq cld drop size ', 'm', mask_variant = .true., & - missing_value = missing_value) - - id_reff_ccclice = register_diag_field & - (mod_name, 'reff_ccclice', axes(1:3), Time, & - 'cv ice cld drop size ', 'm', mask_variant = .true., & - missing_value = missing_value) - - id_reff_ccprliq = register_diag_field & - (mod_name, 'reff_ccprliq', axes(1:3), Time, & - 'cv liq prcp drop size ', 'm') - - id_reff_ccprice = register_diag_field & - (mod_name, 'reff_ccprice', axes(1:3), Time, & - 'cv ice prcp drop size ', 'm') - - id_dtau_s = register_diag_field & - (mod_name, 'dtau_s', axes(1:3), Time, & - 'ls cloud optical depth ', 'dimensionless') - - id_dtau_c = register_diag_field & - (mod_name, 'dtau_c', axes(1:3), Time, & - 'cv cloud optical depth ', 'dimensionless') - - id_dem_s = register_diag_field & - (mod_name, 'dem_s', axes(1:3), Time, & - 'ls cloud emissivity ', 'dimensionless') - - id_dem_c = register_diag_field & - (mod_name, 'dem_c', axes(1:3), Time, & - 'cv cloud emissivity ', 'dimensionless') - - id_skt = register_diag_field & - (mod_name, 'skt', axes(1:2), Time, 'skin temp', 'deg K') - - id_sunlit = register_diag_field & - (mod_name, 'sunlit', axes(1:2), Time, 'sun is shining?', 'none') - - id_land = register_diag_field & - (mod_name, 'land', axes(1:2), Time, 'land frac', 'fraction') - - id_sfcht = register_diag_field & - (mod_name, 'sfc_ht', axes(1:2), Time, 'height of surface', & - 'meters') - -!--------------------------------------------------------------------- -! COSP output fields: -!--------------------------------------------------------------------- - allocate (id_dbze94(Ncolumns)) - if (use_vgrid) then - allocate (id_cloudsatcfad(DBZE_BINS)) - allocate (id_calipsosrcfad(SR_BINS )) - allocate (id_cloudsatcfad_sat(DBZE_BINS)) - allocate (id_calipsosrcfad_sat(SR_BINS )) - else - allocate (id_cloudsatcfad_mdl(DBZE_BINS)) - allocate (id_calipsosrcfad_mdl(SR_BINS )) - endif - allocate (id_cloud_type (Ncolumns )) - do n=1, size(id_cloud_type,1) - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 levels', FATAL) - endif - id_cloud_type(n) = register_diag_field & - (mod_name, 'cloud_type_' // trim(chvers), axes(1:3), Time, & - 'Cloud type present in column ' // trim(chvers), 'none') - end do - - if (cfg%Llidar_sim) then - id_cltcalipso = register_diag_field & - (mod_name, 'cltcalipso', axes(1:2), Time, & - 'Lidar Total Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_cllcalipso = register_diag_field & - (mod_name, 'cllcalipso', axes(1:2), Time, & - 'Lidar Low-level Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_clmcalipso = register_diag_field & - (mod_name, 'clmcalipso', axes(1:2), Time, & - 'Lidar Mid-level Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_clhcalipso = register_diag_field & - (mod_name, 'clhcalipso', axes(1:2), Time, & - 'Lidar High-level Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - -if (generate_orbital_output) then - - id_cltcalipso_sat = register_diag_field & - (mod_name, 'cltcalipso_sat', axes(1:2), Time, & - 'Lidar Total Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_cllcalipso_sat = register_diag_field & - (mod_name, 'cllcalipso_sat', axes(1:2), Time, & - 'Lidar Low-level Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_clmcalipso_sat = register_diag_field & - (mod_name, 'clmcalipso_sat', axes(1:2), Time, & - 'Lidar Mid-level Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_clhcalipso_sat = register_diag_field & - (mod_name, 'clhcalipso_sat', axes(1:2), Time, & - 'Lidar High-level Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_clcalipso_sat = register_diag_field & - (mod_name, 'clcalipso_sat', cosp_axes(csatindx), Time, & - 'Lidar Cloud Fraction (532 nm)', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_sampling_sat = register_static_field & - (mod_name, 'sampling_sat', cosp_axes(samplingindx), & - 'Times sampled by Cloudsat', 'number', & - missing_value=missing_value) - - id_location_sat = register_static_field & - (mod_name, 'location_sat', cosp_axes(samplingindx2), & - 'Satellite location index', 'counter', & - missing_value=missing_value) - - id_lon_sat = register_diag_field & - (mod_name, 'lon_sat', axes(1:2), Time, & - 'Satellite longitude', 'degrees E', & - mask_variant = .true., missing_value=missing_value) - - id_lat_sat = register_diag_field & - (mod_name, 'lat_sat', axes(1:2), Time, & - 'Satellite latitude', 'degrees N', & - mask_variant = .true., missing_value=missing_value) - - id_parasolrefl_sat = register_diag_field & - (mod_name, 'parasol_refl_sat', cosp_axes(parasolindx), Time, & - 'PARASOL-like mono-directional reflectance', 'fraction', & - mask_variant = .true., missing_value=missing_value) - -endif - - id_clcalipso = register_diag_field & - (mod_name, 'clcalipso', cosp_axes(csatindx), Time, & - 'Lidar Cloud Fraction (532 nm)', 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_clcalipso_mdl = register_diag_field & - (mod_name, 'clcalipso_mdl', axes(1:3), Time, & - 'Lidar Cloud Fraction (532 nm)', 'percent', & - mask_variant = .true., missing_value=missing_value) - id_parasolrefl = register_diag_field & - (mod_name, 'parasol_refl', cosp_axes(parasolindx), Time, & - 'PARASOL-like mono-directional reflectance', 'fraction', & - mask_variant = .true., missing_value=missing_value) - id_betamol532 = register_diag_field & - (mod_name, 'betamol532', axes(1:3 ), Time, & - 'Lidar Molecular Backscatter (532 nm)', & - '(m sr)**(-1)', & - mask_variant = .true., missing_value=missing_value) - allocate (id_atb532(Ncolumns)) - do n=1, size(id_atb532,1) - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 columns', FATAL) - endif - id_atb532(n) = register_diag_field & - (mod_name, 'atb532_' // trim(chvers), axes(1:3 ), Time, & - 'Lidar Attenuated Total Backscatter (532 nm) column# ' // & - & trim(chvers), '(m sr)**(-1)', & - mask_variant = .true., missing_value=missing_value) - end do - - do n=1, SR_BINS - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 levels', FATAL) - endif - if (n == 1) then - write (chvers2, '(f8.2)') -100.0 - else - write (chvers2, '(f8.2)') srbval(n-1) - endif - write (chvers3, '(f8.2)') srbval(n) - if (use_vgrid) then - id_calipsosrcfad(n) = register_diag_field & - (mod_name, 'calipsosrcfad_' // trim(chvers), & - cosp_axes(csatindx ), Time, & - 'Fractional area with Lidar 532 nm Scattering Ratio & - &between' // trim(chvers2) // ' and' // trim(chvers3) // & - ' -- bin' // trim(chvers), 'fraction', & - mask_variant = .true., missing_value=missing_value) - if (generate_orbital_output) then - id_calipsosrcfad_sat(n) = register_diag_field & - (mod_name, 'calipsosrcfad_sat_' // trim(chvers), & - cosp_axes(csatindx ), Time, & - 'Fractional area with Lidar 532 nm Scattering Ratio & - &between' // trim(chvers2) // ' and' // trim(chvers3) // & - ' -- bin' // trim(chvers), 'fraction', & - mask_variant = .true., missing_value=missing_value) - endif - else - id_calipsosrcfad_mdl(n) = register_diag_field & - (mod_name, 'calipsosrcfad_mdl_' // trim(chvers), axes(1:3), & - Time, 'Fractional area with Lidar 532 nm Scattering Ratio & - &between' // trim(chvers2) // ' and' // trim(chvers3) // & - ' -- bin' // trim(chvers), 'fraction', & - mask_variant = .true., missing_value=missing_value) - endif - end do - endif !(Llidar_sim) - - if (cfg%Lradar_sim) then - do n=1, size(id_dbze94,1) - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 levels', FATAL) - endif - id_dbze94(n) = register_diag_field & - (mod_name, 'dbze94_' // trim(chvers), axes(1:3), Time, & - 'Radar Effective Reflectivity Factor in dBZe (94 GHz) column# ' & - // trim(chvers), 'dBZe') - end do - - do n=1, DBZE_BINS - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 levels', FATAL) - endif - write (chvers2, '(i6)') INT(cfad_ze_min + float(n-1)*cfad_ze_width) - write (chvers3, '(i6)') INT(cfad_ze_min + float(n)*cfad_ze_width) - if (use_vgrid) then - id_cloudsatcfad(n) = register_diag_field & - (mod_name, 'cloudsatcfad_' // trim(chvers), & - cosp_axes(csatindx), Time, & - 'Fractional area with radar reflectivity (94 GHz) between ' & - // trim(chvers2) // ' and' // trim(chvers3) // & - ' dbZe -- bin # ' // trim(chvers), 'fraction', & - mask_variant = .true., missing_value=missing_value) - if (generate_orbital_output) then - id_cloudsatcfad_sat(n) = register_diag_field & - (mod_name, 'cloudsatcfad_sat_' // trim(chvers), & - cosp_axes(csatindx), Time, & - 'Fractional area with radar reflectivity (94 GHz) between ' & - // trim(chvers2) // ' and' // trim(chvers3) // & - ' dbZe -- bin # ' // trim(chvers), 'fraction', & - mask_variant = .true., missing_value=missing_value) - endif - else - id_cloudsatcfad_mdl(n) = register_diag_field & - (mod_name, 'cloudsatcfad_mdl_' // trim(chvers), axes(1:3), & - Time, 'Fractional area with radar reflectivity & - &(94 GHz) between ' // trim(chvers2) // ' and' // & - & trim(chvers3) // ' dbZe -- bin # ' // trim(chvers), & - 'fraction', & - mask_variant = .true., missing_value=missing_value) - endif - end do - endif ! (Lradar_sim) - - - if (cfg%Lradar_sim .and. cfg%Llidar_sim) then - id_cltlidarradar = register_diag_field & - (mod_name, 'cltlidarradar', axes(1:2), Time, & - 'Lidar and Radar Total Cloud Fraction', 'percent', & - mask_variant = .true., missing_value=missing_value) - id_clcalipso2 = register_diag_field & - (mod_name, 'clcalipso2', cosp_axes(csatindx), Time, & -'Cloud frequency of occurrence as seen by CALIPSO but not CloudSat', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - if (generate_orbital_output) then - id_clcalipso2_sat = register_diag_field & - (mod_name, 'clcalipso2_sat', cosp_axes(csatindx), Time, & -'Cloud frequency of occurrence as seen by CALIPSO but not CloudSat', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - endif - - id_clcalipso2_mdl = register_diag_field & - (mod_name, 'clcalipso2_mdl', axes(1:3), Time, & -'Cloud frequency of occurrence as seen by CALIPSO but not CloudSat', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - endif !(cfg%Lradar_sim .and. cfg%Llidar_sim) - - if (cfg%Lisccp_sim) then - id_tclisccp = register_diag_field & - (mod_name, 'tclisccp', axes(1:2), Time, & - 'Total Cloud Fraction as Calculated by the ISCCP Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_ctpisccp = register_diag_field & - (mod_name, 'ctpisccp', axes(1:2), Time, & - 'Mean Cloud Top Pressure *CPCT as Calculated by the ISCCP Simulator', & - 'Pa', mask_variant = .true., missing_value=missing_value) - - id_tbisccp = register_diag_field & - (mod_name, 'tbisccp', axes(1:2), Time, & - 'Mean All-sky 10.5 micron brightness temp -- ISCCP Simulator', & - 'deg K', mask_variant = .true., missing_value=missing_value) - - id_tbclrisccp = register_diag_field & - (mod_name, 'tbclrisccp', axes(1:2), Time, & - 'Mean Clr-sky 10.5 micron brightness temp -- ISCCP Simulator', & - 'deg K', mask_variant = .true., missing_value=missing_value) - - id_tauisccp = register_diag_field & - (mod_name, 'tauisccp', axes(1:2), Time, & - 'Mean Optical Depth *CPCT as Calculated by the ISCCP Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_albisccp = register_diag_field & - (mod_name, 'albisccp', axes(1:2), Time, & - 'Mean Cloud Albedo *CPCT as Calculated by the ISCCP Simulator', & - 'fraction', & - mask_variant = .true., missing_value=missing_value) - id_boxtauisccp = register_diag_field & - (mod_name, 'boxtauisccp', cosp_axes(columnindx), Time, & - 'Optical Depth from the ISCCP Simulator', 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_boxptopisccp = register_diag_field & - (mod_name, 'boxptopisccp', cosp_axes(columnindx), Time, & - 'Cloud Top Pressure from the ISCCP Simulator', 'Pa') - - allocate (id_boxtauisccp_n(Ncolumns)) - allocate (id_boxptopisccp_n(Ncolumns)) - do n=1,Ncolumns - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 levels', FATAL) - endif - - id_boxtauisccp_n(n) = register_diag_field & - (mod_name, 'boxtauisccp_' // trim(chvers), axes(1:2), Time, & - 'Optical Depth in stochastic Column' // trim(chvers) // & - ' from the ISCCP Simulator', 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_boxptopisccp_n(n) = register_diag_field & - (mod_name, 'boxptopisccp_' // trim(chvers), axes(1:2), Time, & - 'Cloud Top Pressure in stochastic column' // trim(chvers) & - //' from the ISCCP Simulator', 'Pa', & - mask_variant = .true., missing_value=missing_value) - end do - do n=1,7 - write (chvers, '(i1)') n - write (chvers2, '(i6)') INT(isccp_pc_bnds(1,n)*1.0e-02) - write (chvers3, '(i6)') INT(isccp_pc_bnds(2,n)*1.0e-02) - id_clisccp(n) = register_diag_field & - (mod_name, 'clisccp_'// trim(chvers), cosp_axes(tauindx), & - Time, 'ISCP Cld Frac for clouds between ' // trim(chvers2) & - // ' and' // trim(chvers3) // ' hPa', 'percent', & - mask_variant = .true., missing_value=missing_value) - end do - - do m=1,7 - write (chvers4, '(i1)') m - write (chvers5, '(f4.1)') isccp_tau_bnds(1,m) - write (chvers6, '(f8.1)') isccp_tau_bnds(2,m) - do n=1,7 - write (chvers, '(i1)') n - write (chvers2, '(i5)') INT(isccp_pc_bnds(1,n)*1.0e-02) - write (chvers3, '(i5)') INT(isccp_pc_bnds(2,n)*1.0e-02) - id_clisccp_n(m,n) = register_diag_field & - (mod_name, 'clisccp_'// trim(chvers4)//'_' // trim(chvers), & - axes(1:2), Time, 'ISCCP CldFrac - tau between ' // & - trim(chvers5) // ' and ' // trim(chvers6) // & - ' , pr between ' // trim(chvers2) // ' and' // & - trim(chvers3) // ' hPa', 'percent', & - mask_variant = .true., missing_value=missing_value) - end do - end do - endif !(Lisccp_sim) - - if (cfg%Lmisr_sim) then - do n=1,MISR_N_CTH - if (n <=9) then - write (chvers, '(i1)') n - else - write (chvers, '(i2)') n - endif - write (chvers2, '(f6.1)') 1.0e-03*MISR_CTH_BNDS(1,n) - write (chvers3, '(f6.1)') 1.0E-03*MISR_CTH_BNDS(2,n) - id_misr(n) = register_diag_field & - (mod_name, 'misr_'// trim(chvers), cosp_axes(tauindx), & - Time, 'MISR Cld Frac for clouds with top between ' // trim(chvers2) & - // ' and' // trim(chvers3) // ' km', 'percent', & - mask_variant = .true., missing_value=missing_value) - end do +subroutine cosp_driver_time_vary (Time_diag) - do m=1,7 - write (chvers4, '(i1)') m - write (chvers5, '(f4.1)') isccp_tau_bnds(1,m) - write (chvers6, '(f8.1)') isccp_tau_bnds(2,m) - do n=1,MISR_N_CTH - if (n <=9) then - write (chvers, '(i1)') n - else - write (chvers, '(i2)') n - endif - write (chvers2, '(f6.1)') 1.0e-03*MISR_CTH_BNDS(1,n) - write (chvers3, '(f6.1)') 1.0e-03*MISR_CTH_BNDS(2,n) - id_misr_n(m,n) = register_diag_field & - (mod_name, 'misr_'// trim(chvers4)//'_' // trim(chvers), & - axes(1:2), Time, 'MISR CldFrac - tau between ' // & - trim(chvers5) // ' and ' // trim(chvers6) // & - ' , top between ' // trim(chvers2) // ' and' // & - trim(chvers3) // ' km', 'percent', & - mask_variant = .true., missing_value=missing_value) - end do - end do - endif !(Lmisr_sim) - - if (cfg%Lmodis_sim) then - - id_tclmodis = register_diag_field & - (mod_name, 'tclmodis', axes(1:2), Time, & - 'Total Cloud Fraction as Calculated by the MODIS Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_locldmodis = register_diag_field & - (mod_name, 'locldmodis', axes(1:2), Time, & - 'Low Cloud Fraction as Calculated by the MODIS Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_mdcldmodis = register_diag_field & - (mod_name, 'mdcldmodis', axes(1:2), Time, & - 'Middle Cloud Fraction as Calculated by the MODIS Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_hicldmodis = register_diag_field & - (mod_name, 'hicldmodis', axes(1:2), Time, & - 'High Cloud Fraction as Calculated by the MODIS Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_lclmodis = register_diag_field & - (mod_name, 'lclmodis', axes(1:2), Time, & - 'Total Liquid Cloud Fraction as Calculated by the MODIS Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_iclmodis = register_diag_field & - (mod_name, 'iclmodis', axes(1:2), Time, & - 'Total Ice Cloud Fraction as Calculated by the MODIS Simulator', & - 'percent', & - mask_variant = .true., missing_value=missing_value) - - id_ttaumodis = register_diag_field & - (mod_name, 'ttaumodis', axes(1:2), Time, & - 'Total Optical Thickness*CPCT as Calculated by the MODIS Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_ltaumodis = register_diag_field & - (mod_name, 'ltaumodis', axes(1:2), Time, & - 'Total Liquid Optical Thickness*CPCT as Calculated by the MODIS Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_itaumodis = register_diag_field & - (mod_name, 'itaumodis', axes(1:2), Time, & - 'Total Ice Optical Thickness*CPCT as Calculated by the MODIS Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_tlogtaumodis = register_diag_field & - (mod_name, 'tlogtaumodis', axes(1:2), Time, & - 'Total Log Mean Optical Thickness*CPCT as Calculated by the MODIS Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_llogtaumodis = register_diag_field & - (mod_name, 'llogtaumodis', axes(1:2), Time, & - 'Total Log Mean Liquid Optical Thickness*CPCT as Calculated by the MODIS Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_ilogtaumodis = register_diag_field & - (mod_name, 'ilogtaumodis', axes(1:2), Time, & - 'Total Log Mean Ice Optical Thickness*CPCT as Calculated by the MODIS Simulator', & - 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_lremodis = register_diag_field & - (mod_name, 'lremodis', axes(1:2), Time, & - ' Liquid Water particle Size*CPCT as Calculated by the MODIS Simulator', & - 'm', & - mask_variant = .true., missing_value=missing_value) - - id_badlremodis = register_diag_field & - (mod_name, 'badlsizemodis', axes(1:2), Time, & - ' Flag for liquid size retrieval failure in the MODIS Simulator', & - '1', & - mask_variant = .true., missing_value=missing_value) - - id_badiremodis = register_diag_field & - (mod_name, 'badisizemodis', axes(1:2), Time, & - ' Flag for ice size retrieval failure in the MODIS Simulator', & - '1', & - mask_variant = .true., missing_value=missing_value) - - id_iremodis = register_diag_field & - (mod_name, 'iremodis', axes(1:2), Time, & - ' Ice Water particle Size*CPCT as Calculated by the MODIS Simulator', & - 'm', & - mask_variant = .true., missing_value=missing_value) - - id_ctpmodis = register_diag_field & - (mod_name, 'ctpmodis', axes(1:2), Time, & - ' Mean Cloud Top Pressure*CPCT as Calculated by the MODIS Simulator', & - 'Pa', & - mask_variant = .true., missing_value=missing_value) - - id_lwpmodis = register_diag_field & - (mod_name, 'lwpmodis', axes(1:2), Time, & - ' Mean Liquid Water Path*CPCT as Calculated by the MODIS Simulator', & - 'kg / ( m**2)', & - mask_variant = .true., missing_value=missing_value) - - id_iwpmodis = register_diag_field & - (mod_name, 'iwpmodis', axes(1:2), Time, & - ' Mean Ice Water Path*CPCT as Calculated by the MODIS Simulator', & - 'kg / ( m**2)', & - mask_variant = .true., missing_value=missing_value) - - allocate (id_taumodis_n(Ncolumns)) - allocate (id_ptopmodis_n(Ncolumns)) - allocate (id_sizemodis_n(Ncolumns)) - allocate (id_badsizemodis_n(Ncolumns)) - allocate (id_phasemodis_n(Ncolumns)) - do n=1,Ncolumns - if (n <= 9) then - write (chvers, '(i1)') n - else if (n <=99) then - write (chvers, '(i2)') n - else - call error_mesg ('cosp_driver', & - 'can not process over 99 levels', FATAL) - endif +type(time_type), intent(in) :: Time_diag - id_taumodis_n(n) = register_diag_field & - (mod_name, 'taumodis_' // trim(chvers), axes(1:2), Time, & - 'Optical Depth in stochastic Column' // trim(chvers) // & - ' from the MODIS Simulator', 'dimensionless', & - mask_variant = .true., missing_value=missing_value) - - id_ptopmodis_n(n) = register_diag_field & - (mod_name, 'ptopmodis_' // trim(chvers), axes(1:2), Time, & - 'Cloud Top Pressure in stochastic column' // trim(chvers) & - //' from the MODIS Simulator', 'hPa', & - mask_variant = .true., missing_value=missing_value) - - id_sizemodis_n(n) = register_diag_field & - (mod_name, 'sizemodis_' // trim(chvers), axes(1:2), Time, & - 'Particle Size in stochastic Column' // trim(chvers) // & - ' from the MODIS Simulator', 'meters', & - mask_variant = .true., missing_value=missing_value) - - id_badsizemodis_n(n) = register_diag_field & - (mod_name, 'badsizemodis_' // trim(chvers), axes(1:2), Time, & - 'Particle Size failures in stochastic Column' // trim(chvers) // & - ' from the MODIS Simulator', 'meters', & - mask_variant = .true., missing_value=missing_value) - - id_phasemodis_n(n) = register_diag_field & - (mod_name, 'phasemodis_' // trim(chvers), axes(1:2), Time, & - 'Phase in stochastic Column' // trim(chvers) // & - ' from the MODIS Simulator', 'unitless', & - mask_variant = .true., missing_value=missing_value) + call cosp_diagnostics_time_vary (Time_diag) - end do - do n=numPressureHistogramBins,1,-1 - if (n <=9) then - write (chvers, '(i1)') n - else - write (chvers, '(i2)') n - endif - write (chvers2, '(f8.1)') nominalPressureHistogramBoundaries(1,n) - write (chvers3, '(f8.1)') nominalPressureHistogramBoundaries(2,n) - id_tauctpmodis(n) = register_diag_field & - (mod_name, 'tauctpmodis_'// trim(chvers), cosp_axes(modistauindx), & - Time, 'MODIS Cld Frac for clouds with top between ' // trim(chvers2) & - // ' and' // trim(chvers3) // ' Pa', 'percent', & - mask_variant = .true., missing_value=missing_value) - end do +end subroutine cosp_driver_time_vary - do m=1,numTauHistogramBins - write (chvers4, '(i1)') m + 1 - write (chvers5, '(f6.1)') nominalTauHistogramBoundaries(1,m) - write (chvers6, '(f6.1)') nominalTauHistogramBoundaries(2,m) - do n=numPressureHistogramBins,1,-1 - if (n <=9) then - write (chvers, '(i1)') n - else - write (chvers, '(i2)') n - endif - write (chvers2, '(f8.1)') nominalPressureHistogramBoundaries(1,n) - write (chvers3, '(f8.1)') nominalPressureHistogramBoundaries(2,n) - id_tauctpmodis_n(m,n) = register_diag_field & - (mod_name, 'tauctpmodis_'// trim(chvers4)//'_' // trim(chvers), & - axes(1:2), Time, 'MODIS CldFrac - tau between ' // & - trim(chvers5) // ' and ' // trim(chvers6) // & - ' , top between ' // trim(chvers2) // ' and' // & - trim(chvers3) // ' Pa', 'percent', & - mask_variant = .true., missing_value=missing_value) - end do - end do - endif !(Lmodis_sim) +!###################################################################### +subroutine cosp_driver_endts + call cosp_diagnostics_endts - end subroutine diag_field_init +end subroutine cosp_driver_endts !#################################################################### @@ -1335,14 +343,11 @@ subroutine cosp_driver & !local variables: - integer, intent(in) :: is, js - real, dimension(size(T_in,1)*size(T_in,2), size(T_in,3), & + integer, intent(in) :: is, js + real, dimension(size(T_in,1)*size(T_in,2), size(T_in,3), & ncolumns) :: y3, y3a, y4, y5, y6, y7, y8 - integer :: nxdir, nydir, npts - integer :: i, j, n, l - integer :: k - integer :: me - logical :: used + integer :: i, j, n, l + integer :: k type(cosp_gridbox) :: gbx ! Gridbox information. Input for COSP type(cosp_subgrid) :: sgx ! Subgrid outputs @@ -1354,29 +359,27 @@ subroutine cosp_driver & type(cosp_misr) :: misr ! Output from MISR simulator #ifdef RTTOV type(cosp_rttov) :: rttov ! Output from RTTOV -#endif +#endif type(cosp_vgrid) :: vgrid ! Information on vertical grid of stats type(cosp_radarstats) :: stradar ! Summary statistics from radar simulator type(cosp_lidarstats) :: stlidar ! Summary statistics from lidar simulator - real,dimension(:),allocatable :: lon,lat - real,dimension(:),allocatable :: daytime - real,dimension(:,:),allocatable :: & - p, ph, zlev, zlev_half, T, sh, rh, tca, cca, & - mr_lsliq, mr_lsice, mr_ccliq, mr_ccice, fl_lsrain, & - fl_lssnow, fl_lsgrpl, fl_ccrain, fl_ccsnow, dtau_s, dtau_c, & - dem_s,dem_c, mr_ozone - real,dimension(:,:,:),allocatable :: cloud_type - real,dimension(:,:,:),allocatable :: Reff - real,dimension(:,:,:),allocatable :: p_half_in, z_half_in - real,dimension(:),allocatable :: skt,landmask,sfc_height,u_wind,v_wind + real, dimension ( size(T_in,1)*size(T_in,2), size(T_in,3)) :: & + fl_lsrain, & + fl_lssnow, fl_lsgrpl, fl_ccrain, fl_ccsnow + real, dimension ( size(T_in,1)*size(T_in,2), & + Ncolumns, size(T_in,3)) :: & + cloud_type + real, dimension ( size(T_in,1),size(T_in,2), size(T_in,3)) :: & + p_half_in, z_half_in integer :: nlon,nlat,npoints + !---------------- End of declaration of variables -------------- + nlon = size(T_in,1) nlat = size(T_in,2) - npoints = nlon*nlat - - allocate (p_half_in (size(T_in,1),size(T_in,2), size(T_in,3)) ) - allocate (z_half_in (size(T_in,1),size(T_in,2), size(T_in,3)) ) + npoints = nlon*nlat + + p_half_in(:,:,1:size(T_in,3)) = phalf_plus(:,:,2:size(T_in,3)+1) z_half_in(:,:,1:size(T_in,3)) = zhalf_plus(:,:,2:size(T_in,3)+1) if (present (tau_stoch_in) .and. & @@ -1391,51 +394,19 @@ subroutine cosp_driver & sgx%cols_input_from_model = .false. endif -!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! Allocate arrays which are passed to the simulator code. -!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - allocate(lon(Npoints),lat(Npoints), & - p(Npoints,Nlevels),ph(Npoints,Nlevels), & - zlev(Npoints,Nlevels), zlev_half(Npoints,Nlevels), & - T(Npoints,Nlevels), sh(Npoints,Nlevels), & - rh(Npoints,Nlevels), tca(Npoints,Nlevels), & - cca(Npoints,Nlevels), mr_lsliq(Npoints,Nlevels), & - mr_lsice(Npoints,Nlevels), mr_ccliq(Npoints,Nlevels),& - mr_ccice(Npoints,Nlevels), fl_lsrain(Npoints,Nlevels),& - fl_lssnow(Npoints,Nlevels), fl_lsgrpl(Npoints,Nlevels),& - fl_ccrain(Npoints,Nlevels),& - fl_ccsnow(Npoints,Nlevels), & - Reff(Npoints,Nlevels,N_hydro), dtau_s(Npoints,Nlevels), & - dtau_c(Npoints,Nlevels), dem_s(Npoints,Nlevels), & - dem_c(Npoints,Nlevels), skt(Npoints), & - landmask(Npoints), sfc_height(Npoints), & - mr_ozone(Npoints,Nlevels), u_wind(Npoints), & - v_wind(Npoints), daytime(Npoints)) - allocate ( cloud_type(Npoints, Ncolumns, Nlevels)) + + call construct_cosp_gridbox & + (time, time_bnds, radar_freq, surface_radar, use_mie_tables, & + use_gas_abs, do_ray, melt_lay, k2, Npoints, Nlevels, & + Ncolumns, N_HYDRO, Nprmts_max_hydro, Naero, Nprmts_max_aero, & + Npoints_it, lidar_ice_type, isccp_topheight, & + isccp_topheight_direction,overlap, emsfc_lw, & + use_precipitation_fluxes, use_reff, & + Platform, Satellite, Instrument, Nchannels, ZenAng, & + channels(1:Nchannels), surfem(1:Nchannels), co2, ch4, n2o, co,& + gbx) - ! Example that processes ntsteps. It always uses the same input data - wmode = 'replace' ! Only for first iteration - do i=1,1 - time_bnds(:,i) = (/time(i)-0.5,time(i)+0.5/) ! This is just for exam ple purposes -! if (use_input_file) then - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Read input geophysical variables from NetCDF file - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! input : surface to top -! call nc_read_input_file(finput,Npoints,Nlevels,N_hydro,lon,lat,p,ph,zlev,zlev_half,T,sh,rh,tca,cca, & -! mr_lsliq,mr_lsice,mr_ccliq,mr_ccice,fl_lsrain,fl_lssnow,fl_lsgrpl,fl_ccrain,fl_ccsnow,Reff, & -! dtau_s,dtau_c,dem_s,dem_c,skt,landmask, & -! sfc_height,mr_ozone,u_wind,v_wind, & -! emsfc_lw,geomode,Nlon,Nlat) - ! geomode = 2 for (lon,lat) mode. - ! geomode = 3 for (lat,lon) mode. - ! In those modes it returns Nlon and Nlat with the correct values - -! else -!--------------------------------------------------------------------- -! this code used when attached to AM3 -!--------------------------------------------------------------------- - call produce_cosp_input_fields ( Npoints, Nlevels, N_hydro, & + call produce_cosp_input_fields ( Npoints, Nlevels, N_hydro, & lon_in, lat_in, daytime_in, p_half_in, p_full_in, z_half_in, & z_full_in, u_wind_in, v_wind_in, mr_ozone_in, T_in, & sh_in, tca_in, & @@ -1446,94 +417,21 @@ subroutine cosp_driver & reff_lsprice_in, reff_ccclliq_in, reff_ccclice_in, & reff_ccprliq_in, reff_ccprice_in, tau_stoch_in, & lwem_stoch_in, stoch_cloud_type_in, skt_in, land_in, & - lon,lat, daytime, p, ph, zlev, zlev_half, u_wind, v_wind, & - mr_ozone, T, sh, rh,& - tca, & - cca, mr_lsliq, mr_lsice, mr_ccliq, mr_ccice, fl_lsrain,& - fl_lssnow, fl_lsgrpl, fl_ccrain, fl_ccsnow, Reff, dtau_s,& - dtau_c,& - dem_s, dem_c, cloud_type, skt, landmask, & - sfc_height) - - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Allocate memory for gridbox type - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! print *, 'Allocating memory for gridbox type...' - if (use_mie_tables /= 0) then - call error_mesg ('cosp_driver', & - 'use_mie_tables must be set to 0 currently', FATAL) - endif - call construct_cosp_gridbox(time(i), time_bnds(:,i), radar_freq,surface_radar,use_mie_tables,use_gas_abs,do_ray,melt_lay,k2, & - Npoints,Nlevels,Ncolumns,N_HYDRO,Nprmts_max_hydro,Naero,Nprmts_max_aero, Npoints_it, & - lidar_ice_type, & - isccp_topheight,isccp_topheight_direction,overlap, & - emsfc_lw, use_precipitation_fluxes,use_reff, & - Platform,Satellite,Instrument,Nchannels,ZenAng, & - channels(1:Nchannels),surfem(1:Nchannels),co2,ch4,n2o,co, & - gbx) + cloud_type, gbx) - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Here code to populate input structure - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! print *, 'Populating input structure...' - gbx%longitude = lon - gbx%latitude = lat - gbx%p = p - gbx%ph = ph - gbx%zlev = zlev - gbx%zlev_half = zlev_half - gbx%T = T - gbx%q = rh - gbx%sh = sh - gbx%cca = cca - gbx%tca = tca - gbx%psfc = ph(:,1) - gbx%skt = skt - gbx%land = landmask - gbx%sfc_height = sfc_height - gbx%mr_ozone = mr_ozone - gbx%u_wind = u_wind - gbx%v_wind = v_wind - gbx%sunlit(:) = daytime(:) +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +! Define new vertical grid +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + call construct_cosp_vgrid(gbx,Nlr,use_vgrid,csat_vgrid,vgrid) - gbx%mr_hydro(:,:,I_LSCLIQ) = mr_lsliq - gbx%mr_hydro(:,:,I_LSCICE) = mr_lsice - gbx%mr_hydro(:,:,I_CVCLIQ) = mr_ccliq - gbx%mr_hydro(:,:,I_CVCICE) = mr_ccice - - +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +! Allocate memory for other types +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + call construct_cosp_subgrid(Npoints, Ncolumns, Nlevels, sgx) + call construct_cosp_sghydro(Npoints,Ncolumns,Nlevels,N_hydro,sghydro) - gbx%rain_ls = fl_lsrain - gbx%snow_ls = fl_lssnow - gbx%grpl_ls = fl_lsgrpl - gbx%rain_cv = fl_ccrain - gbx%snow_cv = fl_ccsnow - me = mpp_pe() - - gbx%Reff = Reff - - ! ISCCP simulator - gbx%dtau_s = dtau_s - gbx%dtau_c = dtau_c - gbx%dem_s = dem_s - gbx%dem_c = dem_c - - - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Define new vertical grid - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! print *, 'Defining new vertical grid...' - call construct_cosp_vgrid(gbx,Nlr,use_vgrid,csat_vgrid,vgrid) - - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Allocate memory for other types - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! print *, 'Allocating memory for other types...' - call construct_cosp_subgrid(Npoints, Ncolumns, Nlevels, sgx) - call construct_cosp_sghydro(Npoints,Ncolumns,Nlevels,N_hydro,sghydro) - - if (sgx%cols_input_from_model) then + if (sgx%cols_input_from_model) then !--------------------------------------------------------------------- ! convert the stochastic column inputs from lon-lat to npoints, then ! save the column values, reversing the vertical indices, into the @@ -1559,16 +457,16 @@ subroutine cosp_driver & if (y3a(n,k,l) == 1.0) then sghydro%mr_hydro(n,l,nlevels-k+1,I_LSCLIQ) = y3(n,k,l) sghydro%mr_hydro(n,l,nlevels+1-k,I_LSCICE) = y4(n,k,l) - if ( sghydro%mr_hydro(n,l,nlevels-k+1,I_LSCLIQ) > 0.0) then - sghydro%Reff(n,l,nlevels-k+1,I_LSCLIQ) = y5(n,k,l) - else - sghydro%Reff(n,l,nlevels+1-k,I_LSCLIQ) = 0.0 - endif - if (sghydro%mr_hydro(n,l,nlevels+1-k,I_LSCICE) > 0.0) then - sghydro%Reff(n,l,nlevels+1-k,I_LSCICE) = y6(n,k,l) - else - sghydro%Reff(n,l,nlevels+1-k,I_LSCICE) = 0.0 - endif + if ( sghydro%mr_hydro(n,l,nlevels-k+1,I_LSCLIQ) > 0.0) then + sghydro%Reff(n,l,nlevels-k+1,I_LSCLIQ) = y5(n,k,l) + else + sghydro%Reff(n,l,nlevels+1-k,I_LSCLIQ) = 0.0 + endif + if (sghydro%mr_hydro(n,l,nlevels+1-k,I_LSCICE) > 0.0) then + sghydro%Reff(n,l,nlevels+1-k,I_LSCICE) = y6(n,k,l) + else + sghydro%Reff(n,l,nlevels+1-k,I_LSCICE) = 0.0 + endif else sghydro%mr_hydro(n,l,nlevels+1-k,I_LSCLIQ) = 0.0 sghydro%mr_hydro(n,l,nlevels+1-k,I_LSCICE) = 0.0 @@ -1578,16 +476,16 @@ subroutine cosp_driver & if (y3a(n,k,l) == 2.0) then sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCLIQ) = y3(n,k,l) sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCICE) = y4(n,k,l) - if (sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCLIQ) > 0.0) then - sghydro%Reff(n,l,nlevels+1-k,I_CVCLIQ) = y5(n,k,l) - else - sghydro%Reff(n,l,nlevels+1-k,I_CVCLIQ) = 0.0 - endif - if (sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCICE) > 0.0) then - sghydro%Reff(n,l,nlevels+1-k,I_CVCICE) = y6(n,k,l) - else - sghydro%Reff(n,l,nlevels+1-k,I_CVCICE) = 0.0 - endif + if (sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCLIQ) > 0.0) then + sghydro%Reff(n,l,nlevels+1-k,I_CVCLIQ) = y5(n,k,l) + else + sghydro%Reff(n,l,nlevels+1-k,I_CVCLIQ) = 0.0 + endif + if (sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCICE) > 0.0) then + sghydro%Reff(n,l,nlevels+1-k,I_CVCICE) = y6(n,k,l) + else + sghydro%Reff(n,l,nlevels+1-k,I_CVCICE) = 0.0 + endif else sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCLIQ) = 0.0 sghydro%mr_hydro(n,l,nlevels+1-k,I_CVCICE) = 0.0 @@ -1600,979 +498,140 @@ subroutine cosp_driver & end do end do endif - - - call construct_cosp_sgradar(cfg,Npoints,Ncolumns,Nlevels,N_HYDRO,sgradar) - call construct_cosp_radarstats(cfg,Npoints,Ncolumns,vgrid%Nlvgrid,N_HYDRO,stradar) - call construct_cosp_sglidar(cfg,Npoints,Ncolumns,Nlevels,N_HYDRO,PARASOL_NREFL,sglidar) - call construct_cosp_lidarstats(cfg,Npoints,Ncolumns,vgrid%Nlvgrid,N_HYDRO,PARASOL_NREFL,stlidar) - call construct_cosp_isccp(cfg,Npoints,Ncolumns,Nlevels,isccp) - call construct_cosp_modis(cfg,Npoints,Ncolumns,modis) -! call construct_cosp_modis(cfg,Npoints,modis) - call construct_cosp_misr(cfg,Npoints,misr) + call construct_cosp_sgradar & + (cfg,Npoints,Ncolumns,Nlevels,N_HYDRO,sgradar) + call construct_cosp_radarstats & + (cfg,Npoints,Ncolumns,vgrid%Nlvgrid,N_HYDRO,stradar) + call construct_cosp_sglidar & + (cfg,Npoints,Ncolumns,Nlevels,N_HYDRO,PARASOL_NREFL,sglidar) + call construct_cosp_lidarstats & + (cfg,Npoints,Ncolumns,vgrid%Nlvgrid,N_HYDRO,PARASOL_NREFL,stlidar) + call construct_cosp_isccp & + (cfg,Npoints,Ncolumns,Nlevels,isccp) + call construct_cosp_modis & + (cfg,Npoints,Ncolumns,modis) + call construct_cosp_misr & + (cfg,Npoints,misr) #ifdef RTTOV - call construct_cosp_rttov(Npoints,Nchannels,rttov) + call construct_cosp_rttov & + (Npoints,Nchannels,rttov) #endif - - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Call simulator - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! print *, 'Calling simulator...' - me = mpp_pe() - if (Ncolumns == 1) then - if (gbx%use_precipitation_fluxes) then - call error_mesg ('cosp_driver:cosp_driver', & - 'Use of precipitation fluxes not supported in& - & CRM mode (Ncolumns=1)', FATAL) - endif - if ((maxval(gbx%dtau_c) > 0.0).or.(maxval(gbx%dem_c) > 0.0)) then - call error_mesg ('cosp_driver:cosp_driver', & - ' dtau_c > 0.0 or dem_c > 0.0. In CRM mode (Ncolumns=1) & +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +! Call simulator +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + if (Ncolumns == 1) then + if (gbx%use_precipitation_fluxes) then + call error_mesg ('cosp_driver:cosp_driver', & + 'Use of precipitation fluxes not supported in& + & CRM mode (Ncolumns=1)', FATAL) + endif + if ((maxval(gbx%dtau_c) > 0.0).or.(maxval(gbx%dem_c) > 0.0)) then + call error_mesg ('cosp_driver:cosp_driver', & + ' dtau_c > 0.0 or dem_c > 0.0. In CRM mode (Ncolumns=1) & &the optical depth (emmisivity) of all clouds must be & &passed through dtau_s (dem_s)', FATAL) - endif + endif endif + +!------------------------------------------------------------------------- +! save the grid-box mean of these fields for diagnostic output. The gbx% +! arrays will be changed to sub-column values in subroutine cosp. +!------------------------------------------------------------------------ + fl_lsrain = gbx%rain_ls + fl_lssnow = gbx%snow_ls + fl_lsgrpl = gbx%grpl_ls + fl_ccrain = gbx%rain_cv + fl_ccsnow = gbx%snow_cv #ifdef RTTOV - call cosp(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar, sghydro, cloud_type) + call cosp(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar, & + isccp,misr,modis,rttov,stradar,stlidar, sghydro, cloud_type) #else - call cosp(me,overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,modis,stradar,stlidar, sghydro, cloud_type) + call cosp(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar, & + isccp,misr,modis,stradar,stlidar, sghydro, cloud_type) #endif - -!output results - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Write outputs to CMOR-compliant NetCDF - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - if (i /= 1) wmode = 'append' - gbx%time = time(i) -! if (cfg%Lwrite_output) then -! print *, 'Writing outputs...' -! if (produce_cmor_output_fields) then -! if (geomode == 1) then -!#ifdef RTTOV -! call nc_write_cosp_1d(cmor_nl,wmode,cfg,vgrid,gbx,sgx,sgradar,sglidar, & -! isccp,misr,modis, rttov,stradar,stlidar) -!#else -! call nc_write_cosp_1d(cmor_nl,wmode,cfg,vgrid,gbx,sgx,sgradar,sglidar, & -! isccp,misr,modis, stradar,stlidar) -!#endif -! else if (geomode > 1) then -!#ifdef RTTOV -! call nc_write_cosp_2d(cmor_nl,wmode,cfg,vgrid,gbx,sgx,sgradar,sglidar, & -! isccp,misr,modis, rttov, stradar,stlidar,geomode,Nlon,Nlat) -!#else -! call nc_write_cosp_2d(cmor_nl,wmode,cfg,vgrid,gbx,sgx,sgradar,sglidar, & -! isccp,misr,modis, stradar,stlidar,geomode,Nlon,Nlat) -!#endif -! endif -! else -!--------------------------------------------------------------------- -! this is the routine which accesses diag_manager when run in AM3. -!--------------------------------------------------------------------- -! print *, 'calling output_cosp_fields' - used = send_data (id_ph , phalf_plus, Time_diag, is, js, 1 ) - used = send_data (id_zh , zhalf_plus, Time_diag, is, js, 1 ) - call output_cosp_fields (nlon,nlat,npoints, & - stlidar, stradar, isccp, modis, misr, sgradar, & - sglidar, sgx, Time_diag, is, js, lat, lon,& - p, ph, zlev, zlev_half, u_wind, v_wind, & - mr_ozone, T, sh, rh, & - tca, cca, mr_lsliq, mr_lsice, & - mr_ccliq, mr_ccice, fl_lsrain, & - fl_lssnow, fl_lsgrpl, fl_ccrain, & - fl_ccsnow, & - Reff, dtau_s, dtau_c, dem_s, dem_c, & - gbx%sunlit, & - skt,landmask, cloud_type, sfc_height) -! endif - - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Deallocate memory in derived types - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -! print *, 'Deallocating memory...' - call free_cosp_gridbox(gbx) - call free_cosp_subgrid(sgx) - call free_cosp_sghydro(sghydro) - call free_cosp_sgradar(sgradar) - call free_cosp_radarstats(stradar) - call free_cosp_sglidar(sglidar) - call free_cosp_lidarstats(stlidar) - call free_cosp_isccp(isccp) - call free_cosp_misr(misr) - call free_cosp_modis(modis) -#ifdef RTTOV - call free_cosp_rttov(rttov) -#endif - call free_cosp_vgrid(vgrid) - enddo - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ! Deallocate memory in local arrays - !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - deallocate(lon,lat,daytime, p,ph,zlev,zlev_half,T,sh,rh,tca,cca, & - mr_lsliq,mr_lsice,mr_ccliq,mr_ccice, & - fl_lsrain,fl_lssnow,fl_lsgrpl,fl_ccrain,fl_ccsnow,Reff,dtau_s, & - dtau_c,dem_s,dem_c, cloud_type, skt,landmask,sfc_height,mr_ozone,u_wind,v_wind) - - ! Time in s. Only for testing purposes -! call system_clock(t1,count_rate,count_max) -! print *,(t1-t0)*1.0/count_rate +!------------------------------------------------------------------------- +! define the effective size of precipitation particles in the gridbox. +! each subcolumn with precip type will have the same size. +!------------------------------------------------------------------------- + gbx%Reff(:,:,I_LSRAIN) = 0. + gbx%Reff(:,:,I_LSSNOW) = 0. + gbx%Reff(:,:,I_LSGRPL) = 0. + gbx%Reff(:,:,I_CVRAIN) = 0. + gbx%Reff(:,:,I_CVSNOW) = 0. + do l=1,Ncolumns + gbx%Reff(:,:,I_LSRAIN) = & + Max(sghydro%reff(:,l,:,I_LSRAIN), gbx%Reff(:,:,I_LSRAIN)) + gbx%Reff(:,:,I_LSSNOW) = & + Max(sghydro%reff(:,l,:,I_LSSNOW), gbx%Reff(:,:,I_LSSNOW)) + gbx%Reff(:,:,I_LSGRPL) = & + Max(sghydro%reff(:,l,:,I_LSGRPL), gbx%Reff(:,:,I_LSGRPL)) + gbx%Reff(:,:,I_CVRAIN) = & + Max(sghydro%reff(:,l,:,I_CVRAIN), gbx%Reff(:,:,I_CVRAIN)) + gbx%Reff(:,:,I_CVSNOW) = & + Max(sghydro%reff(:,l,:,I_CVSNOW), gbx%Reff(:,:,I_CVSNOW)) + end do +!------------------------------------------------------------------------- +! return these fields to grid-box mean values for diagnostic +! output purposes. +!------------------------------------------------------------------------- + gbx%rain_ls = fl_lsrain + gbx%snow_ls = fl_lssnow + gbx%grpl_ls = fl_lsgrpl + gbx%rain_cv = fl_ccrain + gbx%snow_cv = fl_ccsnow -end subroutine cosp_driver +!------------------------------------------------------------------------- +! call output_cosp_fields to produce netcdf output of desired COSP fields. +!------------------------------------------------------------------------- + call output_cosp_fields (nlon, nlat, npoints, geomode, stlidar, & + stradar, isccp, modis, misr, sgradar, & + sglidar, sgx, Time_diag, is, js, & + cloud_type, gbx, cfg, phalf_plus, zhalf_plus) +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +! Deallocate memory in derived types +!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + call free_cosp_gridbox(gbx) + call free_cosp_subgrid(sgx) + call free_cosp_sghydro(sghydro) + call free_cosp_sgradar(sgradar) + call free_cosp_radarstats(stradar) + call free_cosp_sglidar(sglidar) + call free_cosp_lidarstats(stlidar) + call free_cosp_isccp(isccp) + call free_cosp_misr(misr) + call free_cosp_modis(modis) +#ifdef RTTOV + call free_cosp_rttov(rttov) +#endif + call free_cosp_vgrid(vgrid) + +end subroutine cosp_driver !##################################################################### subroutine cosp_driver_end -!------------------------------------------------------------------- -! deallocate the module arrays. -!------------------------------------------------------------------- - deallocate (id_dbze94) - deallocate (id_cloud_type) - if (allocated(id_atb532)) deallocate (id_atb532) - if (use_vgrid) then - deallocate (id_cloudsatcfad) - deallocate (id_calipsosrcfad) - deallocate (id_cloudsatcfad_sat) - deallocate (id_calipsosrcfad_sat) - else - deallocate (id_cloudsatcfad_mdl) - deallocate (id_calipsosrcfad_mdl) - endif - if (generate_orbital_output) then - deallocate (location, lflag_array, flag_array, lflag_array_temp, & - lflag_array_parasol, Time_start, Time_end) - endif - -end subroutine cosp_driver_end - -!##################################################################### - -subroutine output_cosp_fields & - (nlon,nlat,npoints,stlidar, stradar, isccp, modis, misr, sgradar, sglidar, sg, & - Time_diag, is, & - js, lat, lon, p, ph, z, zh, u_wind, v_wind, mr_ozone, T, & - sh, rh, tca, cca, lsliq, & - lsice, ccliq, ccice, fl_lsrain, fl_lssnow, fl_lsgrpl, & - fl_ccrain, & - fl_ccsnow, reff, dtau_s, dtau_c, dem_s, dem_c, sunlit,skt,landmask,& - cloud_type, sfc_height) - -!--------------------------------------------------------------------- -! subroutine output_cosp_fields outputs fields relevant to the -! cosp ismulator, both input and output. -!--------------------------------------------------------------------- - -integer, intent(in) :: nlon,nlat,npoints -integer, intent(in) :: is, js -real, dimension(npoints), intent(in) :: lat, lon, sunlit, skt, & - landmask, sfc_height,& - u_wind, v_wind -real, dimension(npoints, nlevels), intent(in) :: p, z, mr_ozone -real, dimension(npoints, nlevels), intent(in) :: & - ph, zh, T, sh, rh, tca, cca, lsliq, lsice, & - ccliq, ccice, fl_lsrain, fl_lssnow, fl_lsgrpl, & - fl_ccrain, fl_ccsnow, dtau_s, dtau_c, dem_s, & - dem_c -real, dimension(npoints, nlevels,n_hydro), intent(in) :: reff -real, dimension(npoints, ncolumns, nlevels), intent(in) :: cloud_type -type(cosp_lidarstats), intent(in) :: stlidar -type(cosp_radarstats), intent(in) :: stradar -type(cosp_isccp ), intent(in) :: isccp -type(cosp_modis ), intent(in) :: modis -type(cosp_misr ), intent(in) :: misr -type(cosp_sgradar ), intent(in) :: sgradar -type(cosp_sglidar ), intent(in) :: sglidar -type(cosp_subgrid ), intent(in) :: sg -type(time_type) , intent(in) :: Time_diag - -! local variables: - - logical :: used - integer :: n, m - real, dimension(Nlon,Nlat) :: y2, y2save, alpha, y2sunlit - real, dimension(Nlon,Nlat) :: y2lsave, y2isave - real, dimension(Nlon,Nlat,Nlevels) :: y3 - real, dimension(Nlon,Nlat,Nlevels) :: y31,y32, y33,y34, y35, y36,y37 - real, dimension(Nlon,Nlat,Nlevels) :: y3a - real, dimension(Nlon,Nlat,Nlr ) :: z3 - real, dimension(Nlon,Nlat,Nlr ) :: z3a - real, dimension(Nlon,Nlat,Ncolumns) :: y4 - real, dimension(Nlon,Nlat,PARASOL_NREFL) :: y5 - real, dimension(Nlon,Nlat,Ncolumns,Nlevels) :: y6,y6a - real, dimension(Nlon,Nlat,Ncolumns,Nlr ) :: z6,z6a - real, dimension(Nlon,Nlat,DBZE_BINS,Nlevels) :: y7,y7a - real, dimension(Nlon,Nlat,DBZE_BINS,Nlr ) :: z7,z7a - real, dimension(Nlon,Nlat,SR_BINS,Nlevels) :: y8, y8a - real, dimension(Nlon,Nlat,SR_BINS,Nlr ) :: z8, z8a - real, dimension(Nlon,Nlat,7,7 ) :: y9 - real, dimension(Nlon,Nlat,numTauHistogramBins, & - numPressureHistogramBins ) :: y12 - real, dimension(Nlon,Nlat,7,MISR_N_CTH ) :: y10 - logical, dimension (Nlon,Nlat,Nlevels) :: mask_y3a - logical, dimension (Nlon,Nlat) :: lmsk - integer :: nsat_time - - if (generate_orbital_output) then -!---------------------------------------------------------------------- -! determine the time index of the current time in the satellite -! orbit data. -!---------------------------------------------------------------------- - do n= nsat_time_prev, num_sat_periods - if (Time_diag >= Time_start(n) .and. & - Time_diag <= Time_end(n)) then - nsat_time = n - nsat_time_prev = nsat_time - exit - else -! set nsat_time to 0 if current time not within sampling region - nsat_time = 0 - endif - end do - endif - -!---------------------------------------------------------------------- -! output the input fields to COSP. fields must be converted from -! 2d arrays (i,j) -!---------------------------------------------------------------------- - -! 2D fields: - call map_point_to_ll (Nlon, Nlat, geomode, x1=lat, y2 = y2) - used = send_data (id_lat , y2, Time_diag, is, js ) - used = send_data (id_lat_sat , y2, Time_diag, is, js, mask = & - lflag_array(:,:,nsat_time)) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=lon, y2 = y2) - used = send_data (id_lon , y2, Time_diag, is, js ) - used = send_data (id_lon_sat , y2, Time_diag, is, js, mask = & - lflag_array(:,:,nsat_time)) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=sunlit, y2 = y2sunlit) - used = send_data (id_sunlit , y2sunlit, Time_diag, is, js ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=skt, y2 = y2) - used = send_data (id_skt , y2, Time_diag, is, js ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=landmask, y2 = y2) - used = send_data (id_land , y2, Time_diag, is, js ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=u_wind, y2 = y2) - used = send_data (id_u_wind , y2, Time_diag, is, js ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=v_wind, y2 = y2) - used = send_data (id_v_wind , y2, Time_diag, is, js ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=sfc_height, y2 = y2) - used = send_data (id_sfcht , y2, Time_diag, is, js ) - -! 3D fields: - call map_point_to_ll (Nlon, Nlat, geomode, x2=p, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_p , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=z, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_z , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=mr_ozone, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_mr_ozone , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=T, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_T , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=sh, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y37 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=rh, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_rh , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=tca, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y35 ) - used = send_data (id_tca , y35, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=cca, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y36 ) - used = send_data (id_cca , y36, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=lsliq, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y31 ) - call map_point_to_ll (Nlon, Nlat, geomode, x2=lsice, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y32 ) - call map_point_to_ll (Nlon, Nlat, geomode, x2=ccliq, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y33 ) - call map_point_to_ll (Nlon, Nlat, geomode, x2=ccice, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y34 ) - - used = send_data (id_lsca_cmip , y35-y36, Time_diag, is, js, 1, & - mask = y31 > 0) - used = send_data (id_cca_cmip , y36, Time_diag, is, js, 1, & - mask = y33 > 0) - - used = send_data (id_lsliq , (y35-y36)*y31/((1.0+y36*(y33+y34))*& - (1+y31)), Time_diag, is, js, 1 ) - - used = send_data (id_lsice , (y35-y36)*y32/((1.0+y36* & - (y33+y34))*(1+y32)), Time_diag, is, js, 1 ) - - used = send_data (id_ccliq , y36*y33/((1.0+y36*(y33+y34))* & - (1+y33)), Time_diag, is, js, 1 ) - - used = send_data (id_ccice , y36*y34/((1.0+y36*(y33+y34))* & - (1+y34)), Time_diag, is, js, 1 ) - - used = send_data (id_sh , y37/(1.+y36*(y33+y34)), & - Time_diag, is, js, 1 ) - used = send_data (id_tot_h2o , (y37 + (y35-y36)*y31/(1.+y31)+ & - (y35-y36)*y32/(1.+y32)+y36*(y33/(1.+y33)+y34/(1.+y34)))/ & - ((1.0+y36*(y33+y34) )), Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=fl_lsrain, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_fl_lsrain , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=fl_lssnow, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_fl_lssnow , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=fl_lsgrpl, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_fl_lsgrpl , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=fl_ccrain, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_fl_ccrain , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=fl_ccsnow, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_fl_ccsnow , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_lscliq),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_lsclliq , 0.5*y3a, Time_diag, is, js, 1, & - mask = y31 > 0.0 ) - used = send_data (id_reff_lsclliq_cmip , 0.5*y3a*(y35-y36) , Time_diag, is, js, 1, & - mask = y31 > 0.0 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_lscice),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_lsclice , 0.5*y3a, Time_diag, is, js, 1 , & - mask = y32 > 0.0) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_lsrain),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_lsprliq , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_lssnow),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_lsprice , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_cvcliq),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_ccclliq , 0.5*y3a, Time_diag, is, js, 1 , & - mask = y33 > 0.0) - used = send_data (id_reff_ccclliq_cmip , 0.5*y3a*y36 , Time_diag, is, js, 1 , & - mask = y33 > 0.0) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_cvcice),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_ccclice , 0.5*y3a, Time_diag, is, js, 1 , & - mask = y34 > 0.0) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_cvrain),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_ccprliq , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=reff(:,:,i_cvsnow),& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_reff_ccprice , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=dtau_s, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_dtau_s , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=dtau_c, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_dtau_c , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=dem_s, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_dem_s , y3a, Time_diag, is, js, 1 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x2=dem_c, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_dem_c , y3a, Time_diag, is, js, 1 ) - -!--------------------------------------------------------------------- -! process COSP output variables -!--------------------------------------------------------------------- - - if (cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,4),& - y2 = y2) - used = send_data (id_cltcalipso, y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - if (generate_orbital_output) then - used = send_data (id_cltcalipso_sat, y2, Time_diag, is, js , & - mask = y2 /= missing_value .and. & - lflag_array(:,:,nsat_time)) - endif - - call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,1),& - y2 = y2) - used = send_data (id_cllcalipso, y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - if (generate_orbital_output) then - used = send_data (id_cllcalipso_sat, y2, Time_diag, is, js , & - mask = y2 /= missing_value .and. & - lflag_array(:,:,nsat_time)) - endif - - call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,2),& - y2 = y2) - used = send_data (id_clmcalipso, y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - if (generate_orbital_output) then - used = send_data (id_clmcalipso_sat, y2, Time_diag, is, js , & - mask = y2 /= missing_value .and. & - lflag_array(:,:,nsat_time)) - endif - - call map_point_to_ll (Nlon, Nlat, geomode, x1=stlidar%cldlayer(:,3),& - y2 = y2) - used = send_data (id_clhcalipso, y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - if (generate_orbital_output) then - used = send_data (id_clhcalipso_sat, y2, Time_diag, is, js , & - mask = y2 /= missing_value .and. & - lflag_array(:,:,nsat_time)) - endif - endif - - if(cfg%Lradar_sim .and.cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=stradar%radar_lidar_tcc,y2 = y2) - used = send_data (id_cltlidarradar, y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - endif - - if (cfg%Lisccp_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%totalcldarea,& - y2 = y2save) - used = send_data (id_tclisccp, y2save, Time_diag, is, js , & - mask = y2save /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meanptop,& - y2 = y2) - where (y2save== 0.0 .and. y2sunlit == 1.0) - alpha = 0.0 - elsewhere - alpha = y2*y2save - endwhere - - used = send_data (id_ctpisccp , alpha , Time_diag, is, js , & - mask = y2sunlit == 1.0 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meantb,& - y2 = y2) - - used = send_data (id_tbisccp , y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meantbclr,& - y2 = y2) - - used = send_data (id_tbclrisccp , y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meantaucld,& - y2 = y2) - where (y2save== 0.0 .and. y2sunlit == 1.0) - alpha = 0.0 - elsewhere - alpha = y2*y2save - endwhere - - used = send_data (id_tauisccp , alpha , Time_diag, is, js , & - mask = y2sunlit == 1.0 ) - - call map_point_to_ll (Nlon, Nlat, geomode, x1=isccp%meanalbedocld,& - y2 = y2) - where (y2save== 0.0 .and. y2sunlit == 1.0) - alpha = 0.0 - elsewhere - alpha = y2*y2save - endwhere - - used = send_data (id_albisccp , alpha, Time_diag, is, js , & - mask = y2sunlit == 1.0 ) - endif - - if (cfg%Lmodis_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Fraction_Total_Mean, & - y2 = y2save) - used = send_data (id_tclmodis , y2save, Time_diag, is, js , & - mask = y2save /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Fraction_High_Mean, & - y2 = y2) - used = send_data (id_hicldmodis , y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Fraction_Mid_Mean, & - y2 = y2) - used = send_data (id_mdcldmodis , y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Fraction_Low_Mean, & - y2 = y2) - used = send_data (id_locldmodis , y2, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Fraction_Water_Mean, & - y2 = y2lsave) - used = send_data (id_lclmodis , y2lsave, Time_diag, is, js , & - mask = y2lsave /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Fraction_Ice_Mean, & - y2 = y2isave) - used = send_data (id_iclmodis , y2isave, Time_diag, is, js , & - mask = y2isave /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Optical_Thickness_Total_Mean, & - y2 = y2) - - where (y2save == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2save - endwhere - - used = send_data (id_ttaumodis , alpha, Time_diag, is, js , & - mask = y2sunlit == 1.0 ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Optical_Thickness_Water_Mean, & - y2 = y2) - where (y2lsave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2lsave - endwhere - - used = send_data (id_ltaumodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Optical_Thickness_Ice_Mean, & - y2 = y2) - where (y2isave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2save - alpha = y2*y2isave - endwhere - - used = send_data (id_itaumodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Optical_Thickness_Total_LogMean, & - y2 = y2) - where (y2save == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2save - endwhere - - used = send_data (id_tlogtaumodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Optical_Thickness_Water_LogMean, & - y2 = y2) - where (y2lsave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2lsave - endwhere - - used = send_data (id_llogtaumodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Optical_Thickness_Ice_LogMean, & - y2 = y2) - where (y2isave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2isave - endwhere - - used = send_data (id_ilogtaumodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Particle_Size_Water_Mean, & - y2 = y2) - where (y2lsave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2lsave - endwhere - - used = send_data (id_lremodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - lmsk(:,:) = (y2(:,:) < 0.0) .and. (y2(:,:) > -1.0) - used = send_data (id_badlremodis , y2, Time_diag, is, js , & - mask = lmsk ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Particle_Size_Ice_Mean, & - y2 = y2) - where (y2isave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2isave - endwhere - - used = send_data (id_iremodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - lmsk(:,:) = (y2(:,:) < 0.0) .and. (y2(:,:) > -1.0) - used = send_data (id_badiremodis , y2, Time_diag, is, js , & - mask = lmsk ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Cloud_Top_Pressure_Total_Mean, & - y2 = y2) - where (y2save == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2save - endwhere - - used = send_data (id_ctpmodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Liquid_Water_Path_Mean, & - y2 = y2) - where (y2lsave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2lsave - endwhere - - used = send_data (id_lwpmodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - call map_point_to_ll (Nlon, Nlat, geomode, & - x1=modis%Ice_Water_Path_Mean, & - y2 = y2) - where (y2isave == 0.0 .and. y2sunlit == 1.0) - alpha = 0. - elsewhere - alpha = y2*y2isave - endwhere - - used = send_data (id_iwpmodis , alpha, Time_diag, is, js , & - mask = y2 /= missing_value ) - - - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=modis%Column_Optical_Thickness, y3 = y4) - do n=1,ncolumns - used = send_data (id_taumodis_n(n), y4(:,:,n), Time_diag, & - is, js, mask = y4(:,:,n) /= missing_value ) - end do - - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=modis%Column_Cloud_Top_Pressure, y3 = y4) - do n=1,ncolumns - used = send_data (id_ptopmodis_n(n), 0.01*y4(:,:,n), Time_diag, & - is, js, mask = y4(:,:,n) /= missing_value ) - end do - - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=modis%Column_Particle_Size, y3 = y4) - do n=1,ncolumns - used = send_data (id_sizemodis_n(n), y4(:,:,n), Time_diag, & - is, js, mask = y4(:,:,n) > 0.0 ) - - lmsk(:,:) = (y4(:,:,n) < 0.0) .and. (y4(:,:,n) > -1.0) - used = send_data (id_badsizemodis_n(n), y4(:,:,n), Time_diag, & - is, js, mask = lmsk ) - end do - - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=modis%retrievedPhase , y3 = y4) - do n=1,ncolumns - used = send_data (id_phasemodis_n(n), y4(:,:,n), Time_diag, & - is, js, mask = y4(:,:,n) /= missing_value ) - end do - - endif - - if (use_vgrid) then - if (cfg%Llidar_sim) then - - call map_point_to_ll (Nlon, Nlat, geomode, x2=stlidar%lidarcld,& - y3 = z3) - used = send_data (id_clcalipso, z3 , Time_diag, is, js, 1, & - mask = z3 (:,:,:) /= missing_value ) - if (generate_orbital_output) then - used = send_data (id_clcalipso_sat, z3 , Time_diag, is, js, 1, & - mask = (z3 (:,:,:) /= missing_value) .and.& - lflag_array_temp(:,:,:,nsat_time)) - endif - endif - if(cfg%Lradar_sim .and. cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=stradar%lidar_only_freq_cloud, y3 = z3) - used = send_data (id_clcalipso2, z3 , Time_diag, is, js, 1 , & - mask = z3 (:,:,:) /= missing_value ) - if (generate_orbital_output) then - used = send_data (id_clcalipso2_sat, z3 , Time_diag, is, js, 1, & - mask = (z3 (:,:,:) /= missing_value) .and.& - lflag_array_temp(:,:,:,nsat_time)) - endif - endif - else - if (cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, x2=stlidar%lidarcld,& - y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_clcalipso_mdl, y3a, Time_diag, is, js, 1, & - mask = y3a(:,:,:) /= missing_value ) - endif - if(cfg%Lradar_sim .and. cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=stradar%lidar_only_freq_cloud, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_clcalipso2_mdl, y3a, Time_diag, is, js, 1 , & - mask = y3a(:,:,:) /= missing_value ) - endif - endif - -!3d arrays (i,j,columns): - if (cfg%Lisccp_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=isccp%boxtau, y3 = y4) - used = send_data (id_boxtauisccp, y4, Time_diag, is, js, & - mask = y4 /= missing_value ) - do n=1,ncolumns - used = send_data (id_boxtauisccp_n(n), y4(:,:,n), Time_diag, & - is, js, mask = y4(:,:,n) /= missing_value ) - end do - - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=isccp%boxptop, y3 = y4) - used = send_data (id_boxptopisccp, y4, Time_diag, is, js ) - do n=1,ncolumns - used = send_data (id_boxptopisccp_n(n), y4(:,:,n), Time_diag, & - is, js, mask = y4(:,:,n) /= missing_value ) - end do - endif - -!3d arrays (i,j,parasol_nrefl): - if (cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=stlidar%parasolrefl, y3 = y5) - used = send_data (id_parasolrefl, y5, Time_diag, is, js, 1 , & - mask = y5 /= missing_value ) - if (generate_orbital_output) then - used = send_data (id_parasolrefl_sat, y5, Time_diag, is, js, 1 , & - mask = y5 /= missing_value .and. & - lflag_array_parasol(:,:,:,nsat_time)) - endif - call map_point_to_ll (Nlon, Nlat, geomode, & - x2=sglidar%beta_mol, y3 = y3) - call flip_vert_index_3D (y3, nlevels,y3a ) - used = send_data (id_betamol532, y3a, Time_diag, is, js, 1 , & - mask = y3 /= missing_value ) - endif - -!4d array (i,j,columns, levels): - call map_point_to_ll (Nlon, Nlat, geomode, x3=sg%frac_out, y4 = y6) - call flip_vert_index_4D (y6, nlevels,y6a ) - do n=1, size(id_cloud_type,1) - used = send_data (id_cloud_type(n), y6a(:,:,n,:), & - Time_diag, is, js,1 ) - end do - -!4d array (i,j,columns, levels): - if(cfg%Lradar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=sgradar%Ze_tot, y4 = y6) - call flip_vert_index_4D (y6, nlevels,y6a ) - do n=1, size(id_dbze94,1) - used = send_data (id_dbze94(n), y6a(:,:,n,:), Time_diag, is, js,1 ) - end do - -!4d array (i,j, dbze_bins, levels): - if (use_vgrid) then - call map_point_to_ll (Nlon, Nlat, geomode, x3=stradar%cfad_ze, & - y4 = z7) - do n=1, size(id_cloudsatcfad,1) - used = send_data (id_cloudsatcfad(n), z7(:,:,n,:), Time_diag, & - is, js, 1, mask = z7(:,:,n,:) /= missing_value ) - if (generate_orbital_output) then - used = send_data (id_cloudsatcfad_sat(n), z7(:,:,n,:), Time_diag,& - is, js, 1, mask = (z7(:,:,n,:) /= missing_value) .and. & - lflag_array_temp(:,:,:,nsat_time)) - endif - end do - else - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=stradar%cfad_ze, y4 = y7) - call flip_vert_index_4D (y7, nlevels,y7a ) - do n=1, size(id_cloudsatcfad_mdl,1) - used = send_data (id_cloudsatcfad_mdl(n), y7a(:,:,n,:), & - Time_diag, is, js,1 , & - mask = y7a(:,:,n,:) /= missing_value ) - end do - endif -endif - -!4d array (i,j,columns, levels ): - if (cfg%Llidar_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=sglidar%beta_tot, y4 = y6) - call flip_vert_index_4D (y6, nlevels,y6a ) - do n=1, size(id_atb532,1) - used = send_data (id_atb532(n), y6a(:,:,n,:), Time_diag, is, & - js, 1, mask = y6a(:,:,n,:) /= missing_value ) - end do - -!4d array (i,j, sr_bins,levels): - if (use_vgrid) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=stlidar%cfad_sr, y4 = z8) - do n=1, size(id_calipsosrcfad,1) - used = send_data (id_calipsosrcfad(n), z8(:,:,n,:), & - Time_diag, is, js,1 , & - mask = z8 (:,:,n,:) /= missing_value ) - if (generate_orbital_output) then - used = send_data (id_calipsosrcfad_sat(n), z8(:,:,n,:), & - Time_diag, is, js,1 , & - mask = (z8 (:,:,n,:) /= missing_value) .and. & - lflag_array_temp(:,:,:,nsat_time)) - endif - end do - else - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=stlidar%cfad_sr, y4 = y8) - call flip_vert_index_4D (y8, nlevels,y8a ) - do n=1, size(id_calipsosrcfad_mdl,1) - used = send_data (id_calipsosrcfad_mdl(n), y8a (:,:,n,:), & - Time_diag, is, js,1 , & - mask = y8a(:,:,n,:) /= missing_value ) - end do - endif - endif - -!4d array (i,j, isccp_tau,isccp_press): - if (cfg%Lisccp_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=isccp%fq_isccp, y4 = y9) - do n=1, 7 - used = send_data (id_clisccp(n), y9(:,:,:,n), Time_diag, is, & - js, 1, mask = y9(:,:,:,n) /= missing_value ) - end do - - do m=1,7 - do n=1, 7 - used = send_data (id_clisccp_n(m,n), y9(:,:,m,n), Time_diag, & - is, js, mask = y9(:,:,m,n) /= missing_value ) - end do - end do - endif - - -!4d array (i,j, modis_tau,modis_press): - if (cfg%Lmodis_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=modis%Optical_Thickness_vs_Cloud_Top_Pressure, y4 = y12) - do n=1, numPressureHistogramBins - used = send_data (id_tauctpmodis(n), y12(:,:,:,n), Time_diag, is, & - js, 1, mask = y12(:,:,:,n) /= missing_value ) - end do - - do m=1,numTauHistogramBins - do n=1, numPressureHistogramBins - used = send_data (id_tauctpmodis_n(m,n), y12(:,:,m,n), Time_diag, & - is, js, mask = y12(:,:,m,n) /= missing_value ) - end do - end do - endif - -!4d array (i,j, isccp_tau,MISR_N_CTH ): - if (cfg%Lmisr_sim) then - call map_point_to_ll (Nlon, Nlat, geomode, & - x3=misr%fq_misr, y4 = y10) - do n=1, MISR_N_CTH - used = send_data (id_misr(n), y10(:,:,:,n), Time_diag, is, & - js, 1, mask = y10(:,:,:,n) /= missing_value ) - end do - - do m=1,7 - do n=1, MISR_N_CTH - used = send_data (id_misr_n(m,n), y10(:,:,m,n), Time_diag, & - is, js, mask = y10(:,:,m,n) /= missing_value ) - end do - end do - endif - -!------------------------------------------------------------------- - - -end subroutine output_cosp_fields + call cosp_diagnostics_end +end subroutine cosp_driver_end !##################################################################### subroutine produce_cosp_input_fields & - (Npnts, Nl, N_hydro, lon_in, lat_in, daytime_in, p_half_in, p_full_in, & - z_half_in, z_full_in, u_wind_in, v_wind_in, mr_ozone_in, & - T_in, sh_in, tca_in,& - cca_in, lsliq_in, & + (Npnts, Nl, N_hydro, lon_in, lat_in, daytime_in, p_half_in, & + p_full_in, z_half_in, z_full_in, u_wind_in, v_wind_in, & + mr_ozone_in, T_in, sh_in, tca_in, cca_in, lsliq_in, & lsice_in, ccliq_in, ccice_in, fl_lsrain_in, fl_lssnow_in, & - fl_lsgrpl_in, & - fl_ccrain_in, fl_ccsnow_in, reff_lsclliq_in, reff_lsclice_in, & - reff_lsprliq_in, reff_lsprice_in, reff_ccclliq_in, & - reff_ccclice_in, reff_ccprliq_in, reff_ccprice_in, & - tau_stoch_in, lwem_stoch_in, stoch_cloud_type_in, skt_in, & - land_in, & - lon,lat, daytime, p, ph, z, zh, u_wind, v_wind, mr_ozone, T, qv, rh, & - tca, cca, mr_lsliq, & - mr_lsice, mr_ccliq, mr_ccice, fl_lsrain, fl_lssnow, & - fl_lsgrpl, fl_ccrain,& - fl_ccsnow, Reff, dtau_s, dtau_c, dem_s, dem_c, cloud_type, & - skt, landmask, sfc_height) + fl_lsgrpl_in, fl_ccrain_in, fl_ccsnow_in, reff_lsclliq_in, & + reff_lsclice_in, reff_lsprliq_in, reff_lsprice_in, & + reff_ccclliq_in, reff_ccclice_in, reff_ccprliq_in, & + reff_ccprice_in, tau_stoch_in, lwem_stoch_in, & + stoch_cloud_type_in, skt_in, land_in, cloud_type, gbx) !-------------------------------------------------------------------- ! subroutine produce_cosp_input_fields converts inputs from AM3 @@ -2593,17 +652,8 @@ subroutine produce_cosp_input_fields & reff_ccprliq_in, reff_ccprice_in real,dimension(:,:,:,:),intent(in) :: tau_stoch_in, lwem_stoch_in, & stoch_cloud_type_in -real,dimension(Npnts),intent(inout) :: lon,lat, u_wind, v_wind -real,dimension(Npnts),intent(inout) :: daytime -real,dimension(Npnts,Nl), intent(out) :: & - p, ph, z, zh, T, qv, rh, tca, cca, mr_lsliq, mr_lsice, & - mr_ccliq, mr_ccice, fl_lsrain, fl_lssnow, fl_lsgrpl, & - fl_ccrain, mr_ozone, & - fl_ccsnow, dtau_s, dtau_c, dem_s, dem_c -real,dimension(Npnts,Nl,N_hydro), intent(out) :: Reff real,dimension(Npnts,Ncolumns,Nl), intent(out) :: cloud_type -real,dimension(Npnts), intent(out) :: skt,landmask -real,dimension(Npnts), intent(out) :: sfc_height +type(cosp_gridbox), intent(out) :: gbx ! Gridbox information. Input for COSP ! local variables: @@ -2633,37 +683,45 @@ subroutine produce_cosp_input_fields & !--------------------------------------------------------------------- ! map the 2d lon-lat arrays to 1D (npoints). !--------------------------------------------------------------------- - call map_ll_to_point(nxdir,nydir,npts,x2=daytime_in, y1=daytime) - call map_ll_to_point(nxdir,nydir,npts,x2=lat_in, y1=lat) - call map_ll_to_point(nxdir,nydir,npts,x2=lon_in, y1=lon) - call map_ll_to_point(nxdir,nydir,npts,x2=skt_in, y1=skt) - call map_ll_to_point(nxdir,nydir,npts,x2=land_in, y1=landmask) - call map_ll_to_point(nxdir,nydir,npts,x2=u_wind_in, y1=u_wind) - call map_ll_to_point(nxdir,nydir,npts,x2=v_wind_in, y1=v_wind) + call map_ll_to_point(nxdir,nydir,npts,x2=daytime_in, y1=gbx%sunlit) + call map_ll_to_point(nxdir,nydir,npts,x2=lat_in, y1=gbx%latitude) + call map_ll_to_point(nxdir,nydir,npts,x2=lon_in, y1=gbx%longitude) + call map_ll_to_point(nxdir,nydir,npts,x2=skt_in, y1=gbx%skt) + call map_ll_to_point(nxdir,nydir,npts,x2=land_in, y1=gbx%land) + call map_ll_to_point(nxdir,nydir,npts,x2=u_wind_in, y1=gbx%u_wind) + call map_ll_to_point(nxdir,nydir,npts,x2=v_wind_in, y1=gbx%v_wind) !--------------------------------------------------------------------- ! map the 3d lon-lat-k arrays to 2D (npoints,k), and flip their ! vertical indices (index 1 nearest ground in COSP). !--------------------------------------------------------------------- call map_ll_to_point(nxdir,nydir,npts,x3=p_full_in, y2=y2) - call flip_vert_index_2D (y2, nl,p ) + call flip_vert_index (y2, nl,gbx%p ) + call map_ll_to_point(nxdir,nydir,npts,x3=p_half_in, y2=y2) - call flip_vert_index_2D (y2, nl,ph ) + call flip_vert_index (y2, nl,gbx%ph ) + + gbx%psfc = gbx%ph(:,1) + call map_ll_to_point(nxdir,nydir,npts,x3=z_full_in, y2=y2) - call flip_vert_index_2D (y2, nl,z ) + call flip_vert_index (y2, nl,gbx%zlev ) + call map_ll_to_point(nxdir,nydir,npts,x3=z_half_in, y2=y2) - call flip_vert_index_2D (y2, nl,zh ) + call flip_vert_index (y2, nl,gbx%zlev_half ) + call map_ll_to_point(nxdir,nydir,npts,x3=mr_ozone_in, y2=y2) - call flip_vert_index_2D (y2, nl,mr_ozone ) + call flip_vert_index (y2, nl,gbx%mr_ozone ) + call map_ll_to_point(nxdir,nydir,npts,x3=T_in, y2=y2) - call flip_vert_index_2D (y2, nl,T ) + call flip_vert_index (y2, nl,gbx%T ) + call map_ll_to_point(nxdir,nydir,npts,x3=sh_in, y2=y2) - call flip_vert_index_2D (y2, nl,qv ) + call flip_vert_index (y2, nl,gbx%sh ) !--------------------------------------------------------------------- ! define surface height !--------------------------------------------------------------------- - sfc_height(:) = zh(:,1) + gbx%sfc_height(:) = gbx%zlev_half(:,1) !-------------------------------------------------------------------- ! compute qs and then the relative humidity. @@ -2677,59 +735,67 @@ subroutine produce_cosp_input_fields & call compute_qs (T_in, p_full_in, qs_in, q=sh_in) endif call map_ll_to_point(nxdir,nydir,npts,x3=qs_in, y2=y2) - call flip_vert_index_2D (y2, nl,qs ) - rh = qv/qs + call flip_vert_index (y2, nl,qs ) + gbx%q = gbx%sh/qs call map_ll_to_point(nxdir,nydir,npts,x3=tca_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,tca) + call flip_vert_index (y2, nl,gbx%tca) + call map_ll_to_point(nxdir,nydir,npts,x3=cca_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,cca) + call flip_vert_index (y2, nl,gbx%cca) + call map_ll_to_point(nxdir,nydir,npts,x3=lsliq_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,mr_lsliq ) + call flip_vert_index (y2, nl,gbx%mr_hydro(:,:,I_LSCLIQ) ) + call map_ll_to_point(nxdir,nydir,npts,x3=lsice_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,mr_lsice) + call flip_vert_index (y2, nl,gbx%mr_hydro(:,:,I_LSCICE) ) + call map_ll_to_point(nxdir,nydir,npts,x3=ccliq_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,mr_ccliq) + call flip_vert_index (y2, nl,gbx%mr_hydro(:,:,I_CVCLIQ) ) + call map_ll_to_point(nxdir,nydir,npts,x3=ccice_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,mr_ccice) + call flip_vert_index (y2, nl,gbx%mr_hydro(:,:,I_CVCICE) ) + call map_ll_to_point(nxdir,nydir,npts,x3=fl_lsrain_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,fl_lsrain) + call flip_vert_index (y2, nl,gbx%rain_ls) + call map_ll_to_point(nxdir,nydir,npts,x3=fl_lssnow_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,fl_lssnow) + call flip_vert_index (y2, nl,gbx%snow_ls) + call map_ll_to_point(nxdir,nydir,npts,x3=fl_lsgrpl_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,fl_lsgrpl) + call flip_vert_index (y2, nl,gbx%grpl_ls) + call map_ll_to_point(nxdir,nydir,npts,x3=fl_ccrain_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,fl_ccrain) + call flip_vert_index (y2, nl,gbx%rain_cv) + call map_ll_to_point(nxdir,nydir,npts,x3=fl_ccsnow_in, y2=y2 ) - call flip_vert_index_2D (y2, nl,fl_ccsnow) - - - call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsclliq_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_lscliq )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsclice_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_lscice )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsprliq_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_lsrain )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsprice_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_lssnow )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccclliq_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_cvcliq )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccclice_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_cvcice )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccprliq_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_cvrain )) - call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccprice_in, & - y2=y2 ) - call flip_vert_index_2D (y2, nl,reff(:,:,i_cvsnow )) - - reff(:,:,i_lsgrpl) = 0.0 + call flip_vert_index (y2, nl,gbx%snow_cv) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsclliq_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_lscliq )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsclice_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_lscice )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsprliq_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_lsrain )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_lsprice_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_lssnow )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccclliq_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_cvcliq )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccclice_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_cvcice )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccprliq_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_cvrain )) + + call map_ll_to_point(nxdir,nydir,npts,x3=reff_ccprice_in, y2=y2 ) + call flip_vert_index (y2, nl,gbx%reff(:,:,i_cvsnow )) + + gbx%reff(:,:,i_lsgrpl) = 0.0 !--------------------------------------------------------------------- ! the values of tau and lwem are passed in for each stochastic column. @@ -2776,16 +842,16 @@ subroutine produce_cosp_input_fields & end do call map_ll_to_point(nxdir,nydir,npts,x3=tau_s_in(:,:,:), y2=y2) - call flip_vert_index_2D (y2, nl,dtau_s ) + call flip_vert_index (y2, nl,gbx%dtau_s ) call map_ll_to_point(nxdir,nydir,npts,x3=tau_c_in(:,:,:), y2=y2) - call flip_vert_index_2D (y2, nl,dtau_c ) + call flip_vert_index (y2, nl,gbx%dtau_c ) call map_ll_to_point(nxdir,nydir,npts,x3=lwem_s_in(:,:,:), y2=y2) - call flip_vert_index_2D (y2, nl,dem_s) + call flip_vert_index (y2, nl,gbx%dem_s) call map_ll_to_point(nxdir,nydir,npts,x3=lwem_c_in(:,:,:), y2=y2) - call flip_vert_index_2D (y2, nl,dem_c) + call flip_vert_index (y2, nl,gbx%dem_c) !---------------------------------------------------------------------- ! stoch_cloud_type is not flipped here; it will be used in subroutine @@ -2800,346 +866,17 @@ subroutine produce_cosp_input_fields & end do end do -!--------------------------------------------------------------------- -! COSP takes a single, spacially independent value for surface -! emissivity. it may be supplied via namelist. -!--------------------------------------------------------------------- -! emsfc_lw = emsfc_lw_nml - -!-------------------------------------------------------------------- -! variable mode indicates that the grid (i,j) => (lon,lat) -!-------------------------------------------------------------------- -! mode = 2 - -!------------------------------------------------------------------- - +!######################################################################## end subroutine produce_cosp_input_fields - -!##################################################################### -subroutine flip_vert_index_2D (in, dim,out) - real,dimension(:,:), intent(in) :: in - integer, intent(in) :: dim - real,dimension(:,:), intent(out) :: out - integer k, kinv - - do k=1,dim - kinv = dim - k +1 - out(:,k) = in(:,kinv) - end do - -end subroutine flip_vert_index_2D - - - -!##################################################################### - -subroutine flip_vert_index_3D (in, dim,out) - real,dimension(:,:,:), intent(in) :: in - integer, intent(in) :: dim - real,dimension(:,:,:), intent(out) :: out - - integer k, kinv - - do k=1,dim - kinv = dim - k +1 - out(:,:,k) = in(:,:,kinv) - end do - -end subroutine flip_vert_index_3D + !##################################################################### -subroutine flip_vert_index_4D (in, dim,out) - real,dimension(:,:,:,:), intent(in) :: in - integer, intent(in) :: dim - real,dimension(:,:,:,:), intent(out) :: out - - integer k, kinv - - do k=1,dim - kinv = dim - k +1 - out(:,:,:,k) = in(:,:,:,kinv) - end do - -end subroutine flip_vert_index_4D - - -!#################################################################### - - -subroutine read_cloudsat_orbit - -!------------------------------------------------------------------------ -! subroutine read_cloudsat_orbit reads a netcdf file containing the -! orbital position of the satellites as a function of time. -!------------------------------------------------------------------------ - - real*4, dimension(:), allocatable :: lat_in, lon_in - integer*2, dimension(:), allocatable :: year_in - byte, dimension(:), allocatable :: mon_in - byte, dimension(:), allocatable :: day_in, hour_in - byte, dimension(:), allocatable :: min_in - real*4, dimension(:), allocatable :: sec_in - integer, dimension(:), allocatable :: int_year_in - integer, dimension(:), allocatable :: int_mon_in - integer, dimension(:), allocatable :: int_day_in, int_hour_in - integer, dimension(:), allocatable :: int_min_in - real*8, dimension(:,:), allocatable :: lat_out, lon_out - - character (len = *), parameter :: LAT_NAME = "lat" - character (len = *), parameter :: LON_NAME = "lon" - character (len = *), parameter :: YEAR_NAME = "year" - character (len = *), parameter :: MON_NAME = "month" - character (len = *), parameter :: DAY_NAME = "day" - character (len = *), parameter :: HOUR_NAME = "hour" - character (len = *), parameter :: MIN_NAME = "minute" - character (len = *), parameter :: SEC_NAME = "second" - - integer :: lat_varid, lon_varid, year_varid, day_varid, & - mon_varid, hour_varid, min_varid, sec_varid - integer :: ncid - integer :: nlocs - integer (kind=4) :: rcode, recdim - type(time_type) :: Time - integer :: k, mm, ptctr, n, ll, j, i - integer :: yeara, montha, daya, houra, minutea, seconda - integer :: yearb, monthb, dayb, hourb, minuteb, secondb - integer :: is, ie, js, je - real :: UNSET = -500. - integer :: calendar, nstart - logical :: used - integer :: ndims, nvars, ngatts - integer :: ndsize - character*31 :: dummy - -!------------------------------------------------------------------------ -! open the netcdf file. -!------------------------------------------------------------------------ - ncid = ncopn (orbital_filename, 0, rcode) - -!------------------------------------------------------------------------ -! determine number of dimensions (ndims); current file has -! only 1 ("location") -!------------------------------------------------------------------------ - call ncinq (ncid, ndims, nvars, ngatts, recdim, rcode) - -!------------------------------------------------------------------------ -! determine value of the location dimension (nlocs) to use to dimension -! arrays allocated below. -!------------------------------------------------------------------------ - do n=1,ndims - call ncdinq(ncid, n, dummy, ndsize, rcode) - if (trim(dummy) == 'location') then - nlocs = ndsize - endif - end do - -!------------------------------------------------------------------------ -! allocate arrays to hold the data read from the file. -!------------------------------------------------------------------------ - allocate (lat_in(nlocs), lon_in(nlocs), year_in(nlocs), & - mon_in(nlocs), day_in(nlocs), hour_in(nlocs), & - min_in(nlocs), sec_in(nlocs), int_year_in(nlocs), & - int_mon_in(nlocs), int_day_in(nlocs), int_hour_in(nlocs), & - int_min_in(nlocs) ) - allocate (lat_out(num_sat_periods, max_sdgs_per_sat_period), & - lon_out(num_sat_periods, max_sdgs_per_sat_period) ) - -!------------------------------------------------------------------------ -! obtain the var_ids for the needed variables. -!------------------------------------------------------------------------ - - lat_varid = ncvid(ncid, LAT_NAME , rcode) - lon_varid = ncvid(ncid, LON_NAME , rcode) - year_varid = ncvid(ncid, YEAR_NAME , rcode) - mon_varid = ncvid(ncid, MON_NAME , rcode) - day_varid = ncvid(ncid, DAY_NAME , rcode) - hour_varid = ncvid(ncid, HOUR_NAME , rcode) - min_varid = ncvid(ncid, MIN_NAME , rcode) - sec_varid = ncvid(ncid, SEC_NAME , rcode) - -!------------------------------------------------------------------------ -! read the netcdf data. -!------------------------------------------------------------------------ - call ncvgt (ncid, lat_varid, 1, nlocs, lat_in, rcode) - call ncvgt (ncid, lon_varid, 1, nlocs, lon_in, rcode) - call ncvgt (ncid, year_varid, 1, nlocs, year_in, rcode) - call ncvgt (ncid, mon_varid, 1, nlocs, mon_in, rcode) - call ncvgt (ncid, day_varid, 1, nlocs, day_in, rcode) - call ncvgt (ncid, hour_varid, 1, nlocs, hour_in, rcode) - call ncvgt (ncid, min_varid, 1, nlocs, min_in, rcode) - call ncvgt (ncid, sec_varid, 1, nlocs, sec_in, rcode) - - call ncclos (ncid, rcode) - -!------------------------------------------------------------------------ -! convert non-integer fields to integers. -!------------------------------------------------------------------------ - int_year_in = year_in - int_mon_in = mon_in - int_day_in = day_in - int_hour_in = hour_in - int_min_in = min_in - -!------------------------------------------------------------------------ -! convert longitude to lie between 0 --> 360, rather than -180 --> 180. -!------------------------------------------------------------------------ - do mm=1, size(lon_in) - if (lon_in(mm) < 0.) then - lon_in(mm) = lon_in(mm) + 360. - endif - end do - -!------------------------------------------------------------------------ -! define the start and end of each time period for which the satellite -! orbital curtain data is desired. it is centered on sat_begin_time from -! the cosp_input namelist. -!------------------------------------------------------------------------ - Time_start(1) = set_date (sat_begin_time(1), sat_begin_time(2), & - sat_begin_time(3), sat_begin_time(4), & - sat_begin_time(5), sat_begin_time(6)) - & - set_time(sat_period/2,0) - Time_end(1) = Time_start(1) + set_time(sat_period, 0) - - do mm = 2,num_sat_periods - Time_start(mm) = Time_start(mm-1) + set_time(sat_period, 0) - Time_end (mm) = Time_end (mm-1) + set_time(sat_period, 0) - end do - -!------------------------------------------------------------------------ -! initialize output variables. -!------------------------------------------------------------------------ - lat_out = UNSET - lon_out = UNSET - flag_array = 0. - lflag_array = .false. - location = 0. - -!------------------------------------------------------------------------ -! define the latitudes/longitudes coordinates over which the satellite -! passes during each of the requested model sampling periods. -!------------------------------------------------------------------------ - calendar = get_calendar_type() - - nstart = 1 - do k=1,num_sat_periods - ptctr = 0 - do n=nstart, nlocs - if (calendar == NOLEAP) then -!------------------------------------------------------------------------ -! ignore 2/29 when using the noleap calendar -!------------------------------------------------------------------------ - if (int_mon_in(n) == 2 .and. int_day_in(n) == 29) cycle - endif - -!------------------------------------------------------------------------- -! determine if satellite observation time n is in any of the requested -! sampling periods. if it is before the first sampling period, cycle. -! if it is within sampling period k, increment the counter of obser- -! vation times ptctr and enter the satellite location in the output -! arrays as the ptctr occurrence for sampling period k. if the sampling -! period has ended, exit the loop. -!------------------------------------------------------------------------- - Time = set_date(int_year_in(n), int_mon_in(n), int_day_in(n), & - int_hour_in(n), int_min_in(n), INT(sec_in(n))) - if (Time < Time_start(k)) then - cycle - else if (Time > Time_start(k) .and. Time <= Time_end(k)) then - ptctr = ptctr + 1 - if (ptctr >= max_sdgs_per_sat_period) then - call error_mesg ('cosp_driver:read_cloudsat_orbit', & - ' Need to increase &cosp_input variable & - &max_sdgs_per_sat_period', FATAL) - endif - lat_out(k, ptctr) = lat_in(n) - lon_out(k,ptctr) = lon_in(n) - else if (Time > Time_end(k)) then - -!------------------------------------------------------------------------- -! reset starting index into observations for next sampling period. -!------------------------------------------------------------------------- - nstart = n - 1 - exit - endif - end do ! n - -!------------------------------------------------------------------------- -! reset counter for next sampling period. -!------------------------------------------------------------------------- - ptctr = 0 - end do ! k - -!------------------------------------------------------------------------- -! call get_local_indexes2 to map the latitudes/longitudes seen by the -! satellite during sampling period k to the closest model grid point -! (is,js). set a logical to indicate that grid point (is,js) is seen -! during time period k. -!------------------------------------------------------------------------- - do k=1,num_sat_periods - do ll = 1,max_sdgs_per_sat_period - if (lat_out(k,ll) == UNSET .and. lon_out(k,ll) == UNSET) exit - call get_local_indexes2(lat_out(k,ll),lon_out(k,ll), is,js) - if (is /= 0 .and. js /= 0 .and. is <= imax .and. js <= jmax) then - lflag_array(is,js,k) = .true. - location(is,js,k) = ll - endif - end do - -!------------------------------------------------------------------------- -! collect sampling frequency diagnostic, if desired. -!------------------------------------------------------------------------- - if (id_sampling_sat > 0) then - call get_date(Time_end(k), yearb, monthb, dayb, hourb, & - minuteb, secondb) - do j=1,jmax - do i=1,imax - if (lflag_array(i,j,k)) then - flag_array(i,j,monthb) = flag_array(i,j,monthb) + 1. - endif - end do - end do - endif - end do - -!------------------------------------------------------------------------- -! define additional flag arrays for other diagnostics. -!------------------------------------------------------------------------- - do k=1,PARASOL_NREFL - lflag_array_parasol(:,:,k,:) = lflag_array(:,:,:) - end do - do k=1,nlr - lflag_array_temp(:,:,k,:) = lflag_array(:,:,:) - end do - -!------------------------------------------------------------------------- -! output the satellite sampling frequency at each point for each -! month of the year for which data is requested. -!------------------------------------------------------------------------- - used = send_data (id_sampling_sat, flag_array, & - is_in=1, js_in=1, ks_in=1) - -!------------------------------------------------------------------------- -! output the satellite location index for each sampling period -! for which data is requested. -!------------------------------------------------------------------------- - used = send_data (id_location_sat, location, & - is_in=1, js_in=1, ks_in=1, mask = location > 0.) - -!----------------------------------------------------------------------- -! deallocate local variables. -!----------------------------------------------------------------------- - deallocate (lat_in, lon_in, year_in, mon_in,& - day_in, hour_in, min_in, sec_in,& - int_year_in, int_mon_in, int_day_in, & - int_hour_in, int_min_in, lat_out, lon_out ) - -end subroutine read_cloudsat_orbit -!END PROGRAM COSPTEST end module cosp_driver_mod diff --git a/src/atmos_param/cosp/cosp_io.F90 b/src/atmos_param/cosp/cosp_io.F90 index 2bc4ed5f65..cc499fd29d 100644 --- a/src/atmos_param/cosp/cosp_io.F90 +++ b/src/atmos_param/cosp/cosp_io.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: cosp_io.F90,v 19.0 2012/01/06 20:03:25 fms Exp $ -! $Name: siena_201207 $ + +! $Id: cosp_io.F90,v 20.0 2013/12/13 23:15:43 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -38,27 +43,35 @@ ! total was low) ! Sep 2009 - A. Bodas-Salcedo - CMIP5 variable names implemented ! - -#include "cosp_defs.h" + +!#include "cosp_defs.h" +#ifndef COSP_GFDL +#include "cosp_defs.h" +#endif MODULE MOD_COSP_IO USE MOD_COSP_CONSTANTS USE MOD_COSP_TYPES -! USE cmor_users_functions +#ifndef COSP_GFDL + USE cmor_users_functions +#endif USE netcdf use MOD_COSP_Modis_Simulator +#ifdef COSP_GFDL use mpp_mod, only: input_nml_file use fms_mod, only: open_namelist_file, open_file, close_file, & file_exist, mpp_pe, mpp_root_pe, & error_mesg, FATAL, & check_nml_error, write_version_number, stdlog +#endif IMPLICIT NONE -! INCLUDE 'netcdf.inc' +#ifdef COSP_GFDL !--------------------------------------------------------------------- -!----------- version number for this module -------------------------- -character(len=128) :: versiona = '$Id: cosp_io.F90,v 19.0 2012/01/06 20:03:25 fms Exp $' -character(len=128) :: tagnamea = '$Name: siena_201207 $' +!----------- version number for this module -------------------------- +character(len=128) :: versiona = '$Id: cosp_io.F90,v 20.0 2013/12/13 23:15:43 fms Exp $' +character(len=128) :: tagnamea = '$Name: tikal $' +#endif ! Types to be used as arrays of pointers TYPE var1d @@ -182,9 +195,14 @@ SUBROUTINE MAP_POINT_TO_LL(Nx,Ny,geomode,x1,x2,x3,x4,y2,y3,y4,y5) enddo enddo else +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': geomode not supported, ', & - FATAL) + FATAL) +#else + print *, ' -- '//trim(proname)//': geomode not supported, ',geomode + stop +#endif endif if (present(x1).and.present(y2)) then @@ -192,9 +210,14 @@ SUBROUTINE MAP_POINT_TO_LL(Nx,Ny,geomode,x1,x2,x3,x4,y2,y3,y4,y5) Mi = size(y2,1) Mj = size(y2,2) if (Mi*Mj /= Ni) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 1)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 1)' + stop +#endif endif do i=1,Npoints y2(px(i),py(i)) = x1(i) @@ -206,14 +229,24 @@ SUBROUTINE MAP_POINT_TO_LL(Nx,Ny,geomode,x1,x2,x3,x4,y2,y3,y4,y5) Mj = size(y3,2) Mk = size(y3,3) if (Mi*Mj /= Ni) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 2)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 2)' + stop +#endif endif if (Nj /= Mk) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nj /= Mk (opt 2)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nj /= Mk (opt 2)' + stop +#endif endif do k=1,Mk do i=1,Npoints @@ -229,20 +262,34 @@ SUBROUTINE MAP_POINT_TO_LL(Nx,Ny,geomode,x1,x2,x3,x4,y2,y3,y4,y5) Mk = size(y4,3) Ml = size(y4,4) if (Mi*Mj /= Ni) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 3)', & FATAL) - +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 3)' + stop +#endif endif if (Nj /= Mk) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nj /= Mk (opt 3)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nj /= Mk (opt 3)' + stop +#endif endif if (Nk /= Ml) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nk /= Ml (opt 3)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nk /= Ml (opt 3)' + stop +#endif endif do l=1,Ml do k=1,Mk @@ -262,24 +309,44 @@ SUBROUTINE MAP_POINT_TO_LL(Nx,Ny,geomode,x1,x2,x3,x4,y2,y3,y4,y5) Ml = size(y5,4) Mm = size(y5,5) if (Mi*Mj /= Ni) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 4)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat /= Npoints (opt 4)' + stop +#endif endif if (Nj /= Mk) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nj /= Mk (opt 4)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nj /= Mk (opt 4)' + stop +#endif endif if (Nk /= Ml) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nk /= Ml (opt 4)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nk /= Ml (opt 4)' + stop +#endif endif if (Nl /= Mm) then +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': Nl /= Mm (opt 4)', & - FATAL) + FATAL) +#else + print *, ' -- '//trim(proname)//': Nl /= Mm (opt 4)' + stop +#endif endif do m=1,Mm do l=1,Ml @@ -291,9 +358,14 @@ SUBROUTINE MAP_POINT_TO_LL(Nx,Ny,geomode,x1,x2,x3,x4,y2,y3,y4,y5) enddo enddo else +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_point_to_ll', & ' -- '//trim(proname)//': wrong option', & FATAL) +#else + print *, ' -- '//trim(proname)//': wrong option' + stop +#endif endif @@ -319,9 +391,14 @@ SUBROUTINE MAP_LL_TO_POINT(Nx,Ny,Np,x2,x3,x4,x5,y1,y2,y3,y4) px=0 py=0 if (Nx*Ny < Np) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nx*Ny < Np', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nx*Ny < Np' + stop +#endif endif do j=1,Ny do i=1,Nx @@ -336,9 +413,14 @@ SUBROUTINE MAP_LL_TO_POINT(Nx,Ny,Np,x2,x3,x4,x5,y1,y2,y3,y4) Nj = size(x2,2) Mi = size(y1,1) if (Ni*Nj < Mi) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 1)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 1)' + stop +#endif endif do j=1,Np y1(j) = x2(px(j),py(j)) @@ -350,14 +432,24 @@ SUBROUTINE MAP_LL_TO_POINT(Nx,Ny,Np,x2,x3,x4,x5,y1,y2,y3,y4) Mi = size(y2,1) Mj = size(y2,2) if (Ni*Nj < Mi) then - call error_mesg ('cosp_io:map_ll_to_point', & - ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 2)', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & + ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 2)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 2)' + stop +#endif endif if (Nk /= Mj) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nk /= Mj (opt 2)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nk /= Mj (opt 2)' + stop +#endif endif do k=1,Nk do j=1,Np @@ -373,19 +465,34 @@ SUBROUTINE MAP_LL_TO_POINT(Nx,Ny,Np,x2,x3,x4,x5,y1,y2,y3,y4) Mj = size(y3,2) Mk = size(y3,3) if (Ni*Nj < Mi) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 3)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 3)' + stop +#endif endif if (Nk /= Mj) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nk /= Mj (opt 3)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nk /= Mj (opt 3)' + stop +#endif endif if (Nl /= Mk) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nl /= Mk (opt 3)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nl /= Mk (opt 3)' + stop +#endif endif do l=1,Nl do k=1,Nk @@ -405,24 +512,44 @@ SUBROUTINE MAP_LL_TO_POINT(Nx,Ny,Np,x2,x3,x4,x5,y1,y2,y3,y4) Mk = size(y4,3) Ml = size(y4,4) if (Ni*Nj < Mi) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 4)', & - FATAL) + FATAL) +#else + print *, ' -- '//trim(proname)//': Nlon*Nlat < Npoints (opt 4)' + stop +#endif endif if (Nk /= Mj) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nk /= Mj (opt 4)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nk /= Mj (opt 4)' + stop +#endif endif if (Nl /= Mk) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nl /= Mk (opt 4)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nl /= Mk (opt 4)' + stop +#endif endif if (Nm /= Ml) then - call error_mesg ('cosp_io:map_ll_to_point', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': Nm /= Ml (opt 4)', & FATAL) +#else + print *, ' -- '//trim(proname)//': Nm /= Ml (opt 4)' + stop +#endif endif do m=1,Nm do l=1,Nl @@ -434,20 +561,26 @@ SUBROUTINE MAP_LL_TO_POINT(Nx,Ny,Np,x2,x3,x4,x5,y1,y2,y3,y4) enddo enddo else +#ifdef COSP_GFDL call error_mesg ('cosp_io:map_ll_to_point', & ' -- '//trim(proname)//': wrong option', & FATAL) +#else + print *, ' -- '//trim(proname)//': wrong option' + stop +#endif endif END SUBROUTINE MAP_LL_TO_POINT +#ifndef COSP_GFDL !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% !----------------- SUBROUTINE NC_READ_INPUT_FILE ----------------- !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tca,cca, & mr_lsliq,mr_lsice,mr_ccliq,mr_ccice,fl_lsrain,fl_lssnow,fl_lsgrpl, & fl_ccrain,fl_ccsnow,Reff,dtau_s,dtau_c,dem_s,dem_c,skt,landmask,sfc_height, & - mr_ozone,u_wind,v_wind,emsfc_lw,mode,Nlon,Nlat) + mr_ozone,u_wind,v_wind,sunlit,emsfc_lw,mode,Nlon,Nlat,verbosity) !Arguments character(len=512),intent(in) :: fname ! File name @@ -457,10 +590,10 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc mr_lsliq,mr_lsice,mr_ccliq,mr_ccice,fl_lsrain,fl_lssnow,fl_lsgrpl, & fl_ccrain,fl_ccsnow,dtau_s,dtau_c,dem_s,dem_c,mr_ozone real,dimension(Npnts,Nl,Nhydro),intent(out) :: Reff - real,dimension(Npnts),intent(out) :: skt,landmask,sfc_height,u_wind,v_wind + real,dimension(Npnts),intent(out) :: skt,landmask,sfc_height,u_wind,v_wind,sunlit real,intent(out) :: emsfc_lw integer,intent(out) :: mode,Nlon,Nlat - + integer,optional :: verbosity !Local variables integer :: Npoints,Nlevels,i,j,k @@ -475,6 +608,8 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc real,dimension(Npnts) :: ll integer,dimension(:),allocatable :: plon,plat real,allocatable :: x1(:),x2(:,:),x3(:,:,:),x4(:,:,:,:),x5(:,:,:,:,:) ! Temporary arrays + character(len=64) :: routine_name='NC_READ_INPUT_FILE' + character(len=128) :: errmsg,straux mode = 0 Nlon = 0 @@ -485,6 +620,10 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc ! Open file errst = nf90_open(fname, nf90_nowrite, ncid) + if (errst /= 0) then + errmsg="Couldn't open "//trim(fname) + call cosp_error(routine_name,errmsg) + endif ! Get information about dimensions. Curtain mode or lat/lon mode? Llat =.false. @@ -492,29 +631,25 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc Lpoint=.false. errst = nf90_inquire(ncid, ndims, nvars, ngatts, recdim) if (errst /= 0) then - call error_mesg ('cosp_io:nc_read_input_file', & - ' --- NC_READ_INPUT_FILE: error in nf90_inquire', & - FATAL) + errmsg="Error in nf90_inquire" + call cosp_error(routine_name,errmsg,errcode=errst) endif do i = 1,ndims errst = nf90_Inquire_Dimension(ncid,i,name=dimname(i),len=dimsize(i)) if (errst /= 0) then - print *, 'nf90 error, i=', i - call error_mesg ('cosp_io:nc_read_input_file', & - ' --- NC_READ_INPUT_FILE: error in nf90_Inquire_Dimension ', & - FATAL) + write(straux, *) i + errmsg="Error in nf90_Inquire_Dimension, i: "//trim(straux) + call cosp_error(routine_name,errmsg) endif if ((trim(dimname(i)).eq.'level').and.(Nlevels > dimsize(i))) then - call error_mesg ('cosp_io:nc_read_input_file', & - ' --- NC_READ_INPUT_FILE: number of levels selected is greater than in input file '//trim(fname), & - FATAL) + errmsg='Number of levels selected is greater than in input file '//trim(fname) + call cosp_error(routine_name,errmsg) endif if (trim(dimname(i)).eq.'point') then Lpoint = .true. if (Npnts > dimsize(i)) then - call error_mesg ('cosp_io:nc_read_input_file', & - ' --- NC_READ_INPUT_FILE: number of points selected is greater than in input file '//trim(fname), & - FATAL) + errmsg='Number of points selected is greater than in input file '//trim(fname) + call cosp_error(routine_name,errmsg) endif endif if (trim(dimname(i)).eq.'lon') then @@ -538,27 +673,41 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc Nlat = Npoints mode = 1 else - call error_mesg ('cosp_io:nc_read_input_file', & - ' -- NC_READ_INPUT_FILE: '//trim(fname)//' file contains wrong dimensions', & - FATAL) + errmsg= trim(fname)//' file contains wrong dimensions' + call cosp_error(routine_name,errmsg) endif errst = nf90_inq_varid(ncid, 'lon', vid) + if (errst /= 0) then + errmsg="Error in nf90_inq_varid, var: lon" + call cosp_error(routine_name,errmsg,errcode=errst) + endif errst = nf90_get_var(ncid, vid, lon, start = (/1/), count = (/Nlon/)) + if (errst /= 0) then + errmsg="Error in nf90_get_var, var: lon" + call cosp_error(routine_name,errmsg,errcode=errst) + endif errst = nf90_inq_varid(ncid, 'lat', vid) + if (errst /= 0) then + errmsg="Error in nf90_inq_varid, var: lat" + call cosp_error(routine_name,errmsg,errcode=errst) + endif errst = nf90_get_var(ncid, vid, lat, start = (/1/), count = (/Nlat/)) + if (errst /= 0) then + errmsg="Error in nf90_get_var, var: lat" + call cosp_error(routine_name,errmsg,errcode=errst) + endif ! Get all variables do vid = 1,nvars vdimid=0 errst = nf90_Inquire_Variable(ncid, vid, name=vname, ndims=vrank, dimids=vdimid) if (errst /= 0) then - print *, 'vid, errst = ', vid, errst - call error_mesg ('cosp_io:nc_read_input_file', & - ' --- NC_READ_INPUT_FILE: error reading ', & - FATAL) + write(straux, *) vid + errmsg='Error in nf90_Inquire_Variable, vid '//trim(straux) + call cosp_error(routine_name,errmsg,errcode=errst) endif ! Read in into temporary array of correct shape - print *, 'Reading '//trim(vname)//' ...' + if (present(verbosity).and.(verbosity == 1)) print *, 'Reading '//trim(vname)//' ...' if (vrank == 1) then Na = dimsize(vdimid(1)) allocate(x1(Na)) @@ -582,9 +731,8 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc else if ((Na == Nlat).and.(Nb == Nlon)) then mode = 3 else - call error_mesg ('cosp_io:nc_read_input_file', & - ' -- NC_READ_INPUT_FILE: wrong mode for variable '//trim(vname), & - FATAL) + errmsg='Wrong mode for variable '//trim(vname) + call cosp_error(routine_name,errmsg) endif endif endif @@ -605,6 +753,11 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc allocate(x5(Na,Nb,Nc,Nd,Ne)) errst = nf90_get_var(ncid, vid, x5, start=(/1,1,1,1,1/), count=(/Na,Nb,Nc,Nd,Ne/)) endif + if (errst /= 0) then + write(straux, *) vid + errmsg='Error in nf90_get_var, vid '//trim(straux) + call cosp_error(routine_name,errmsg,errcode=errst) + endif ! Map to the right input argument select case (trim(vname)) case ('pfull') @@ -783,6 +936,12 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc else call map_ll_to_point(Na,Nb,Npoints,x2=x2,y1=v_wind) endif + case ('sunlit') + if (Lpoint) then + sunlit(1:Npoints) = x1(1:Npoints) + else + call map_ll_to_point(Na,Nb,Npoints,x2=x2,y1=sunlit) + endif end select ! select case (trim(vname)) ! case ('pfull') @@ -961,6 +1120,12 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc ! else ! call map_ll_to_point(Na,Nb,Npoints,x2=x2,y1=v_wind) ! endif +! case ('sunlit') +! if (Lpoint) then +! sunlit(1:Npoints) = x1(1:Npoints) +! else +! call map_ll_to_point(Na,Nb,Npoints,x2=x2,y1=sunlit) +! endif ! end select ! Free memory if (vrank == 1) deallocate(x1) @@ -971,8 +1136,17 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc enddo ! SFC emissivity - errst = nf90_inq_varid(ncid, 'emsfclw', vid) + errst = nf90_inq_varid(ncid, 'emsfc_lw', vid) + if (errst /= 0) then + errmsg='Error in nf90_inq_varid, var: emsfc_lw' + call cosp_error(routine_name,errmsg,errcode=errst) + endif errst = nf90_get_var(ncid, vid, emsfc_lw) + if (errst /= 0) then + errmsg='Error in nf90_get_var, var: emsfc_lw' + call cosp_error(routine_name,errmsg,errcode=errst) + endif + ! Fill in the lat/lon vectors with the right values for 2D modes ! This might be helpful if the inputs are 2D (gridded) and @@ -1004,11 +1178,828 @@ SUBROUTINE NC_READ_INPUT_FILE(fname,Npnts,Nl,Nhydro,lon,lat,p,ph,z,zh,T,qv,rh,tc deallocate(plon,plat) ! Close file -! call ncclos(ncid,errst) errst = nf90_close(ncid) + if (errst /= 0) then + errmsg='Error in nf90_close' + call cosp_error(routine_name,errmsg,errcode=errst) + endif END SUBROUTINE NC_READ_INPUT_FILE +#endif + +#ifndef COSP_GFDL +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +!--------------- SUBROUTINE NC_WRITE_COSP_1D --------------------- +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef RTTOV + SUBROUTINE NC_WRITE_COSP_1D(cmor_nl,wmode,cfg,vgrid,gb,sg,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) +#else + SUBROUTINE NC_WRITE_COSP_1D(cmor_nl,wmode,cfg,vgrid,gb,sg,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) +#endif + ! Input arguments + character(len=*),intent(in) :: cmor_nl + character(len=*) :: wmode ! Writing mode 'replace' or 'append' + type(cosp_config),intent(in) :: cfg + type(cosp_vgrid),intent(in) :: vgrid + type(cosp_gridbox),intent(in) :: gb + type(cosp_subgrid),intent(in) :: sg + type(cosp_sgradar),intent(in) :: sgradar ! Subgrid radar + type(cosp_sglidar),intent(in) :: sglidar ! Subgrid lidar + type(cosp_isccp),intent(in) :: isccp ! ISCCP outputs + type(cosp_misr),intent(in) :: misr ! MISR outputs + type(cosp_modis),intent(in) :: modis ! MODIS outputs +#ifdef RTTOV + type(cosp_rttov),intent(in) :: rttov ! RTTOV outputs +#endif + type(cosp_radarstats),intent(in) :: stradar ! Summary statistics from radar simulator + type(cosp_lidarstats),intent(inout) :: stlidar ! Summary statistics from lidar simulator + !--- Local variables --- + integer,parameter :: n3d = 8 +#ifdef RTTOV + integer,parameter :: n2d = 7 +#else + integer,parameter :: n2d = 6 +#endif + integer,parameter :: n1d = 29 + integer :: error_flag,i,j, nc_action + logical :: lfound + character(len=512) :: inpath,outpath,start_date,model_id,experiment_id,institution,institute_id,source,calendar, & + contact,history,comment,table,parent_experiment_id,parent_experiment_rip,forcing + character(len=2056) :: references + double precision :: branch_time + integer :: initialization_method,physics_version + integer :: realization,Npoints,Ncolumns,Nlevels,Nlvgrid,maxtsteps,Nchannels + namelist/CMOR/inpath,outpath,start_date,model_id,experiment_id,branch_time,parent_experiment_id,parent_experiment_rip, & + forcing,institution,institute_id,source,calendar,realization,initialization_method,physics_version, & + contact,history,comment,references,table,maxtsteps + real,dimension(:),allocatable :: profile_ax,column_ax,dbze_ax,channel_ax + real,dimension(:,:),allocatable :: dbze_bounds,vgrid_bounds,mgrid_bounds,sratio_bounds + integer :: profile_axid,column_axid,height_axid,dbze_axid,height_mlev_axid,sratio_axid, & + tau_axid,pressure2_axid,time_axid,sza_axid,MISR_CTH_axid,channel_axid + integer :: grid_id, latvar_id, lonvar_id, blatvar_id, blonvar_id + integer :: var3d_id(n3d),var2d_id(n2d),var1d_id(n1d) + type(var1d) :: v1d(n1d) + type(var2d) :: v2d(n2d) + type(var3d) :: v3d(n3d) + integer :: d2(2),d3(3),d4(4),d5(5) + logical,dimension(n1d) :: lout1d = .false. + logical,dimension(n2d) :: lout2d = .false. + logical,dimension(n3d) :: lout3d = .false. + double precision :: tbnds(2,1) + character(len=64) :: pro_name = 'NC_WRITE_COSP_1D' + ! Initialise values of axis ids that may not be used + height_mlev_axid = 0 + column_axid = 0 + channel_axid = 0 + tau_axid = 0 + pressure2_axid = 0 + misr_cth_axid = 0 + + Npoints = gb%Npoints + Ncolumns = gb%Ncolumns + Nlevels = gb%Nlevels + Nchannels = gb%Nchan + Nlvgrid = vgrid%Nlvgrid + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Allocate memory and initialise + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + tbnds(:,1) = gb%time_bnds + allocate(profile_ax(Npoints),column_ax(Ncolumns),dbze_ax(DBZE_BINS), & + dbze_bounds(2,DBZE_BINS),vgrid_bounds(2,Nlvgrid),mgrid_bounds(2,Nlevels), & + sratio_bounds(2,SR_BINS), channel_ax(Nchannels)) + ! Profile + do i=1,Npoints + profile_ax(i) = i + enddo + ! Column + do i=1,Ncolumns + column_ax(i) = i + enddo + ! Channels + channel_ax = float(gb%ichan) + ! Radar Ze + do i=1,DBZE_BINS + dbze_ax(i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i - 0.5) + enddo + do i=1,DBZE_BINS + dbze_bounds(1,i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i - 1) + dbze_bounds(2,i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*i + enddo + ! Height of model levels + do i=1,Nlevels + mgrid_bounds(1,i) = vgrid%mzl(i) + mgrid_bounds(2,i) = vgrid%mzu(i) + enddo + ! Height of std grid + do i=1,Nlvgrid + vgrid_bounds(1,i) = vgrid%zl(i) + vgrid_bounds(2,i) = vgrid%zu(i) + enddo + ! Lidar scattering ratio bounds (They are output by cosp_cfad_sr->diag_lidar in lmd_ipsl_stats.f90) + sratio_bounds(2,:) = stlidar%srbval(:) ! srbval contains the upper limits from lmd_ipsl_stats.f90 + sratio_bounds(1,2:SR_BINS) = stlidar%srbval(1:SR_BINS-1) + sratio_bounds(1,1) = 0.0 + sratio_bounds(2,SR_BINS) = 1.e5 ! This matches with Chepfer et al., JGR, 2009. However, it is not consistent + ! with the upper limit in lmd_ipsl_stats.f90, which is LIDAR_UNDEF-1=998.999 + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Read namelist with information for CMOR output file + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + open(10,file=cmor_nl,status='old') + read(10,nml=cmor) + close(10) + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Specify path for tables and set up other CMOR options + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#ifdef USE_CMOR1 + error_flag = cmor_setup(inpath=trim(inpath),netcdf_file_action=trim(wmode)) +#else + nc_action = CMOR_APPEND_3 + if (trim(wmode) == 'replace') nc_action = CMOR_REPLACE_3 + error_flag = cmor_setup(inpath=trim(inpath),netcdf_file_action=nc_action,create_subdirectories=0) +#endif + + print *, '---------------Define dataset' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define dataset as output from COSP, and other model details + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#ifdef USE_CMOR1 + error_flag = cmor_dataset(outpath=trim(outpath),experiment_id=trim(experiment_id),institution=trim(institution), & + source=trim(source),calendar=trim(calendar),realization=realization,contact=trim(contact), & + history=trim(history),comment=trim(comment),references=trim(references)) +#else + error_flag = cmor_dataset(outpath=trim(outpath),experiment_id=trim(experiment_id),institution=trim(institution), & + source=trim(source),calendar=trim(calendar),realization=realization,contact=trim(contact), & + history=trim(history),comment=trim(comment),references=trim(references),model_id=trim(model_id), & + branch_time=branch_time,parent_experiment_id=trim(parent_experiment_id),forcing=trim(forcing), & + institute_id=trim(institute_id),parent_experiment_rip=trim(parent_experiment_rip), & + initialization_method=initialization_method,physics_version=physics_version) + error_flag = cmor_set_cur_dataset_attribute('cosp_version',trim(COSP_VERSION)) +#endif + + print *, '---------------Define axis' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define axis + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + profile_axid = cmor_axis(table=table, table_entry='location', units='1', length=Npoints, coord_vals=profile_ax) + height_axid = cmor_axis(table=table, table_entry='alt40', units='m', length=Nlvgrid, & + coord_vals=vgrid%z,cell_bounds=vgrid_bounds) + dbze_axid = cmor_axis(table=table, table_entry='dbze', units='dBZ', length=DBZE_BINS, & ! '10 lg(re 1.e-18 m3)' + coord_vals=dbze_ax,cell_bounds=dbze_bounds) + sratio_axid = cmor_axis(table=table, table_entry='scatratio', units='1', length=SR_BINS, & + coord_vals=(sratio_bounds(1,:)+sratio_bounds(2,:))/2.0,cell_bounds=sratio_bounds) + sza_axid = cmor_axis(table=table, table_entry='sza5', units='degree', length=PARASOL_NREFL, coord_vals=PARASOL_SZA) + time_axid = cmor_axis(table=table, table_entry='time1', units='days since '//trim(start_date), length=maxtsteps) + if ((trim(table) /= 'CMIP5_cf3hr').and.(trim(table) /= 'TAMIP_3hr_curt')) then + column_axid = cmor_axis(table=table, table_entry='column', units='1', length=Ncolumns, coord_vals=column_ax) + channel_axid = cmor_axis(table=table, table_entry='channel', units='1', length=Nchannels, coord_vals=channel_ax) + height_mlev_axid = cmor_axis(table=table, table_entry='alevel', & + units='1', length=Nlevels, coord_vals=vgrid%mz,cell_bounds=mgrid_bounds) + tau_axid = cmor_axis(table=table, table_entry='tau', units='1', length=7, & + coord_vals=ISCCP_TAU,cell_bounds=ISCCP_TAU_BNDS) + pressure2_axid = cmor_axis(table=table, table_entry='plev7', units='Pa', length=7, & + coord_vals=ISCCP_PC,cell_bounds=ISCCP_PC_BNDS) + MISR_CTH_axid = cmor_axis(table=table, table_entry='cth16', units='m', length=MISR_N_CTH, & + coord_vals=MISR_CTH,cell_bounds=MISR_CTH_BNDS) + endif + + print *, '---------------Define grid' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define grid + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + grid_id = cmor_grid((/profile_axid, time_axid/)) + latvar_id = cmor_time_varying_grid_coordinate(grid_id,'latitude','degrees_north',R_UNDEF) + lonvar_id = cmor_time_varying_grid_coordinate(grid_id,'longitude','degrees_east' ,R_UNDEF) + if (grid_id > 0) then + print *, '*********** Error, grid_id: ', grid_id + stop + endif + + print *, '---------------Fill in var info' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Fill in variable info and associate pointers + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! 1D variables + d3 = (/grid_id,0,0/) + d2 = (/Npoints,0/) + call construct_var1d('cllcalipso', d3, d2, stlidar%cldlayer(:,1),v1d(1),units='%') ! correction sb + call construct_var1d('clmcalipso', d3, d2, stlidar%cldlayer(:,2),v1d(2),units='%') ! correction sb + call construct_var1d('clhcalipso', d3, d2, stlidar%cldlayer(:,3),v1d(3),units='%') ! correction sb + call construct_var1d('cltcalipso', d3, d2, stlidar%cldlayer(:,4),v1d(4),units='%') ! correction sb + call construct_var1d('cltlidarradar', d3, d2, stradar%radar_lidar_tcc,v1d(5),units='%') + call construct_var1d('cltisccp', d3, d2, isccp%totalcldarea,v1d(6),units='%') + call construct_var1d('pctisccp', d3, d2, isccp%meanptop,v1d(7),units='Pa') + call construct_var1d('tauisccp', d3, d2, isccp%meantaucld,v1d(8),units='1') + call construct_var1d('albisccp', d3, d2, isccp%meanalbedocld,v1d(9),units='1') + call construct_var1d('meantbisccp', d3, d2, isccp%meantb,v1d(10),units='K') + call construct_var1d('meantbclrisccp', d3, d2, isccp%meantbclr,v1d(11),units='K') + call construct_var1d('cltmodis', d3, d2, modis%Cloud_Fraction_Total_Mean,v1d(12),units='%') + call construct_var1d('clwmodis', d3, d2, modis%Cloud_Fraction_Water_Mean,v1d(13),units='%') + call construct_var1d('climodis', d3, d2, modis%Cloud_Fraction_Ice_Mean, v1d(14),units='%') + call construct_var1d('clhmodis', d3, d2, modis%Cloud_Fraction_High_Mean,v1d(15),units='%') + call construct_var1d('clmmodis', d3, d2, modis%Cloud_Fraction_Mid_Mean,v1d(16),units='%') + call construct_var1d('cllmodis', d3, d2, modis%Cloud_Fraction_Low_Mean, v1d(17),units='%') + call construct_var1d('tautmodis', d3, d2, modis%Optical_Thickness_Total_Mean,v1d(18),units='1') + call construct_var1d('tauwmodis', d3, d2, modis%Optical_Thickness_Water_Mean,v1d(19),units='1') + call construct_var1d('tauimodis', d3, d2, modis%Optical_Thickness_Ice_Mean,v1d(20),units='1') + call construct_var1d('tautlogmodis', d3, d2, modis%Optical_Thickness_Total_LogMean,v1d(21),units='1') + call construct_var1d('tauwlogmodis', d3, d2, modis%Optical_Thickness_Water_LogMean,v1d(22),units='1') + call construct_var1d('tauilogmodis', d3, d2, modis%Optical_Thickness_Ice_LogMean,v1d(23),units='1') + call construct_var1d('reffclwmodis', d3, d2, modis%Cloud_Particle_Size_Water_Mean,v1d(24),units='m') + call construct_var1d('reffclimodis', d3, d2, modis%Cloud_Particle_Size_Ice_Mean, v1d(25),units='m') + call construct_var1d('pctmodis', d3, d2, modis%Cloud_Top_Pressure_Total_Mean, v1d(26),units='Pa') + call construct_var1d('lwpmodis', d3, d2, modis%Liquid_Water_Path_Mean, v1d(27),units='kg m-2') + call construct_var1d('iwpmodis', d3, d2, modis%Ice_Water_Path_Mean, v1d(28),units='kg m-2') + call construct_var1d('toffset', d3, d2, gb%toffset, v1d(29),units='day') + ! 2D variables + d4 = (/grid_id,height_axid,0,0/) + d3 = (/Npoints,Nlvgrid,0/) + call construct_var2d('clcalipso', d4, d3, stlidar%lidarcld,v2d(1),units='%') + call construct_var2d('clcalipso2', d4, d3, stradar%lidar_only_freq_cloud,v2d(2),units='%') + d4 = (/grid_id,height_mlev_axid,0,0/) + d3 = (/Npoints,Nlevels,0/) + ! reshape d4 = (/profile_axid,height_mlev_axid,time_axid,0/) + call construct_var2d('lidarBetaMol532', d4, d3, sglidar%beta_mol,v2d(3),units='m-1 sr-1') + d4 = (/grid_id,column_axid,0,0/) + ! reshape d4 = (/profile_axid,column_axid,time_axid,0/) + d3 = (/Npoints,Ncolumns,0/) + call construct_var2d('boxtauisccp', d4, d3, isccp%boxtau,v2d(4),units='1') + call construct_var2d('boxptopisccp', d4, d3, isccp%boxptop,v2d(5),units='Pa') + d4 = (/grid_id,sza_axid,0,0/) + d3 = (/Npoints,PARASOL_NREFL,0/) + call construct_var2d('parasolRefl', d4, d3, stlidar%parasolrefl,v2d(6),units='1') +#ifdef RTTOV + !reshape d4 = (/profile_axid,channel_axid,time_axid,0/) + d4 = (/grid_id,channel_axid,0,0/) + d3 = (/Npoints,Nchannels,0/) + call construct_var2d('tbrttov', d4, d3, rttov%tbs,v2d(7),units='K') +#endif + + ! 3D variables + ! reshape d5 = (/profile_axid,column_axid,height_mlev_axid,time_axid,0/) + d5 = (/grid_id,column_axid,height_mlev_axid,0,0/) + d4 = (/Npoints,Ncolumns,Nlevels,0/) + call construct_var3d('dbze94', d5, d4, sgradar%Ze_tot,v3d(1),units='1') + call construct_var3d('atb532', d5, d4, sglidar%beta_tot,v3d(2),units='m-1 sr-1') + call construct_var3d('fracout', d5, d4, sg%frac_out,v3d(3),units='1') + ! reshape d5 = (/profile_axid,dbze_axid,height_axid,time_axid,0/) + d5 = (/grid_id,dbze_axid,height_axid,0,0/) + d4 = (/Npoints,DBZE_BINS,Nlvgrid,0/) + call construct_var3d('cfadDbze94', d5, d4, stradar%cfad_ze,v3d(4),units='1') + ! reshape d5 = (/profile_axid,sratio_axid,height_axid,time_axid,0/) + d5 = (/grid_id,sratio_axid,height_axid,0,0/) + d4 = (/Npoints,SR_BINS,Nlvgrid,0/) + call construct_var3d('cfadLidarsr532', d5, d4, stlidar%cfad_sr,v3d(5),units='1') + ! reshape d5 = (/profile_axid,tau_axid,pressure2_axid,time_axid,0/) + d5 = (/grid_id,tau_axid,pressure2_axid,0,0/) + d4 = (/Npoints,7,7,0/) + call construct_var3d('clisccp', d5, d4, isccp%fq_isccp,v3d(6),units='%') + call construct_var3d('clmodis', d5, d4, modis%Optical_Thickness_vs_Cloud_Top_Pressure, v3d(7), units='%') + ! reshape d5 = (/profile_axid,tau_axid,MISR_CTH_axid,time_axid,0/) + d5 = (/grid_id,tau_axid,MISR_CTH_axid,0,0/) + d4 = (/Npoints,7,MISR_N_CTH,0/) + call construct_var3d('clMISR', d5, d4, misr%fq_MISR,v3d(8),units='%') + + print *, '---------------Find list' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Find list of outputs to be written + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + do i=1,N_OUT_LIST + lfound = .false. + if (trim(cfg%out_list(i)) /= '') then + do j=1,n1d + if (trim(v1d(j)%name) == trim(cfg%out_list(i))) then + lout1d(j) = .true. + lfound = .true. + exit + endif + enddo + if (.not.lfound) then + do j=1,n2d + if (trim(v2d(j)%name) == trim(cfg%out_list(i))) then + lout2d(j) = .true. + lfound = .true. + exit + endif + enddo + endif + if (.not.lfound) then + do j=1,n3d + if (trim(v3d(j)%name) == trim(cfg%out_list(i))) then + lout3d(j) = .true. + lfound = .true. + exit + endif + enddo + endif + endif + enddo + + print *, '---------------Define variables' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define variables. Fill in dimensions table first if needed + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! 1D variables + do i=1,n1d + if (lout1d(i)) var1d_id(i) = cmor_variable(table=table, table_entry=v1d(i)%name, units=v1d(i)%units, & + axis_ids=v1d(i)%dimsid(1:1), missing_value=R_UNDEF) + enddo + ! 2D variables + do i=1,n2d + if (lout2d(i)) var2d_id(i) = cmor_variable(table=table, table_entry=v2d(i)%name, units=v2d(i)%units, & + axis_ids=v2d(i)%dimsid(1:2), missing_value=R_UNDEF) + enddo + ! 3D variables + do i=1,n3d + if (lout3d(i)) then + var3d_id(i) = cmor_variable(table=trim(table), table_entry=v3d(i)%name, units=v3d(i)%units, & + axis_ids=v3d(i)%dimsid(1:3), missing_value=R_UNDEF) + endif + enddo + + print *, '---------------Write variables' + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Write variables to file + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! 1D variables + do i=1,n1d + if (lout1d(i)) then + error_flag = cmor_write(var_id=var1d_id(i), data=v1d(i)%pntr, & + ntimes_passed=1,time_vals=(/gb%time/),time_bnds=tbnds) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing '//trim(v1d(i)%name) + stop + endif + error_flag = cmor_write(var_id=lonvar_id, data=gb%longitude,store_with=var1d_id(i), & + ntimes_passed=1,time_vals=(/gb%time/)) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing lon for '//trim(v1d(i)%name) + stop + endif + error_flag = cmor_write(var_id=latvar_id, data=gb%latitude,store_with=var1d_id(i), & + ntimes_passed=1,time_vals=(/gb%time/)) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing lat for '//trim(v1d(i)%name) + stop + endif + endif + enddo + ! 2D variables + do i=1,n2d + if (lout2d(i)) then + error_flag = cmor_write(var_id=var2d_id(i), data=v2d(i)%pntr, & + ntimes_passed=1,time_vals=(/gb%time/),time_bnds=tbnds) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing '//trim(v2d(i)%name) + stop + endif + error_flag = cmor_write(var_id=lonvar_id, data=gb%longitude,store_with=var2d_id(i), & + ntimes_passed=1,time_vals=(/gb%time/)) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing lon for '//trim(v2d(i)%name) + stop + endif + error_flag = cmor_write(var_id=latvar_id, data=gb%latitude,store_with=var2d_id(i), & + ntimes_passed=1,time_vals=(/gb%time/)) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing lat for '//trim(v2d(i)%name) + stop + endif + endif + enddo + ! 3D variables + do i=1,n3d + if (lout3d(i)) then + error_flag = cmor_write(var_id=var3d_id(i), data=v3d(i)%pntr, & + ntimes_passed=1,time_vals=(/gb%time/),time_bnds=tbnds) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing '//trim(v3d(i)%name) + stop + endif + error_flag = cmor_write(var_id=lonvar_id, data=gb%longitude,store_with=var3d_id(i), & + ntimes_passed=1,time_vals=(/gb%time/)) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing lon for '//trim(v3d(i)%name) + stop + endif + error_flag = cmor_write(var_id=latvar_id, data=gb%latitude,store_with=var3d_id(i), & + ntimes_passed=1,time_vals=(/gb%time/)) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing lat for '//trim(v3d(i)%name) + stop + endif + endif + enddo + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Close files + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + error_flag = cmor_close() + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Deallocate memory + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + deallocate(profile_ax,column_ax,dbze_ax,dbze_bounds,sratio_bounds, & + vgrid_bounds,mgrid_bounds,channel_ax) + + END SUBROUTINE NC_WRITE_COSP_1D + +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +!--------------- SUBROUTINE NC_WRITE_COSP_2D --------------------- +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef RTTOV + SUBROUTINE NC_WRITE_COSP_2D(cmor_nl,wmode,cfg,vgrid,gb,sg,sgradar,sglidar,isccp,misr,modis,rttov, & + stradar,stlidar,geomode,Nlon,Nlat) +#else + SUBROUTINE NC_WRITE_COSP_2D(cmor_nl,wmode,cfg,vgrid,gb,sg,sgradar,sglidar,isccp,misr,modis, & + stradar,stlidar,geomode,Nlon,Nlat) +#endif + ! Input arguments + character(len=*),intent(in) :: cmor_nl + character(len=*) :: wmode ! Writing mode 'replace' or 'append' + type(cosp_config),intent(in) :: cfg + type(cosp_vgrid),intent(in) :: vgrid + type(cosp_gridbox),intent(in) :: gb + type(cosp_subgrid),intent(in) :: sg + type(cosp_sgradar),intent(in) :: sgradar ! Subgrid radar + type(cosp_sglidar),intent(in) :: sglidar ! Subgrid lidar + type(cosp_isccp),intent(in) :: isccp ! ISCCP outputs + type(cosp_misr),intent(in) :: misr ! MISR outputs + type(cosp_modis),intent(in) :: modis ! MODIS outputs +#ifdef RTTOV + type(cosp_rttov),intent(in) :: rttov ! RTTOV outputs +#endif + type(cosp_radarstats),intent(in) :: stradar ! Summary statistics from radar simulator + type(cosp_lidarstats),intent(in) :: stlidar ! Summary statistics from lidar simulator + integer,intent(in) :: geomode,Nlon,Nlat + !--- Local variables --- + integer,parameter :: n3d = 8 +#ifdef RTTOV + integer,parameter :: n2d = 7 +#else + integer,parameter :: n2d = 6 +#endif + integer,parameter :: n1d = 28 + integer :: error_flag,i,j,Npoints,Ncolumns,Nlevels,Nlvgrid,maxtsteps,Nchannels + logical :: lfound + real :: lon_ax(Nlon),lat_ax(Nlat) + character(len=512) :: inpath,outpath,start_date,model_id,experiment_id,institution,institute_id,source,calendar, & + contact,history,comment,table,parent_experiment_id,parent_experiment_rip,forcing + character(len=2056) :: references + integer :: realization, nc_action,initialization_method,physics_version + double precision :: branch_time + namelist/CMOR/inpath,outpath,start_date,model_id,experiment_id,branch_time,parent_experiment_id,parent_experiment_rip, & + forcing,institution,institute_id,source,calendar,realization,initialization_method,physics_version, & + contact,history,comment,references,table,maxtsteps + real,dimension(:),allocatable :: column_ax,dbze_ax,channel_ax + real,dimension(:,:),allocatable :: dbze_bounds,vgrid_bounds,sratio_bounds, & + lon_bounds,lat_bounds,mgrid_bounds + integer :: column_axid,height_axid,dbze_axid,height_mlev_axid,sratio_axid, & + tau_axid,pressure2_axid,lon_axid,lat_axid,time_axid,sza_axid,MISR_CTH_axid, & + channel_axid + integer :: var3d_id(n3d),var2d_id(n2d),var1d_id(n1d) + type(var1d) :: v1d(n1d) + type(var2d) :: v2d(n2d) + type(var3d) :: v3d(n3d) + integer :: d2(2),d3(3),d4(4),d5(5) + logical,dimension(n1d) :: lout1d = .false. + logical,dimension(n2d) :: lout2d = .false. + logical,dimension(n3d) :: lout3d = .false. + real,allocatable :: y2(:,:),y3(:,:,:),y4(:,:,:,:) + double precision :: tbnds(2,1) + character(len=64) :: pro_name = 'NC_WRITE_COSP_2D' + + Npoints = gb%Npoints + Ncolumns = gb%Ncolumns + Nlevels = gb%Nlevels + Nchannels = gb%Nchan + Nlvgrid = vgrid%Nlvgrid + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Safety checks + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + if (Npoints > Nlon*Nlat) then + Npoints = Nlon*Nlat + print *, ' -- '//trim(pro_name)//' Warning: Npoints > Nlon*Nlat' + endif + if (Npoints < Nlon*Nlat) then + print *, ' -- '//trim(pro_name)//': only Npoints >= Nlon*Nlat is supported' + stop + endif + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Allocate memory and compute axes and bounds + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + tbnds(:,1) = gb%time_bnds + allocate(column_ax(Ncolumns),dbze_ax(DBZE_BINS),channel_ax(Nchannels), & + dbze_bounds(2,DBZE_BINS),vgrid_bounds(2,Nlvgrid),mgrid_bounds(2,Nlevels),sratio_bounds(2,SR_BINS), & + lon_bounds(2,Nlon),lat_bounds(2,Nlat)) + ! Column + do i=1,gb%Ncolumns + column_ax(i) = i + enddo + ! Channels + channel_ax = float(gb%ichan) + ! Radar Ze + do i=1,DBZE_BINS + dbze_ax(i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i - 0.5) + enddo + do i=1,DBZE_BINS + dbze_bounds(1,i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i - 1) + dbze_bounds(2,i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*i + enddo + ! Height of model levels + do i=1,Nlevels + mgrid_bounds(1,i) = vgrid%mzl(i) + mgrid_bounds(2,i) = vgrid%mzu(i) + enddo + ! Height of std grid + do i=1,Nlvgrid + vgrid_bounds(1,i) = vgrid%zl(i) + vgrid_bounds(2,i) = vgrid%zu(i) + enddo + ! Lidar scattering ratio bounds (They are output by cosp_cfad_sr->diag_lidar in lmd_ipsl_stats.f90) + sratio_bounds(2,:) = stlidar%srbval(:) ! srbval contains the upper limits from lmd_ipsl_stats.f90 + sratio_bounds(1,2:SR_BINS) = stlidar%srbval(1:SR_BINS-1) + sratio_bounds(1,1) = 0.0 + sratio_bounds(2,SR_BINS) = 1.e5 ! This matches with Chepfer et al., JGR, 2009. However, it is not consistent + ! with the upper limit in lmd_ipsl_stats.f90, which is LIDAR_UNDEF-1=998.999 + ! Lat lon axes + if (geomode == 2) then + lon_ax = gb%longitude(1:Nlon) + lat_ax = gb%latitude(1:Npoints:Nlon) + else if (geomode == 3) then + lon_ax = gb%longitude(1:Npoints:Nlat) + lat_ax = gb%latitude(1:Nlat) + else if (geomode == 4) then + lon_ax = gb%longitude(1:Nlon) + lat_ax = gb%latitude(1:Nlat) + endif + lon_bounds(1,2:Nlon) = (lon_ax(1:Nlon-1) + lon_ax(2:Nlon))/2.0 + lon_bounds(1,1) = lon_ax(1) - (lon_bounds(1,2) - lon_ax(1)) + lon_bounds(2,1:Nlon-1) = lon_bounds(1,2:Nlon) + lon_bounds(2,Nlon) = lon_ax(Nlon) + (lon_ax(Nlon) - lon_bounds(2,Nlon-1)) + lat_bounds(1,2:Nlat) = (lat_ax(1:Nlat-1) + lat_ax(2:Nlat))/2.0 + lat_bounds(1,1) = lat_ax(1) - (lat_bounds(1,2) - lat_ax(1)) + lat_bounds(2,1:Nlat-1) = lat_bounds(1,2:Nlat) + lat_bounds(2,Nlat) = lat_ax(Nlat) + (lat_ax(Nlat) - lat_bounds(2,Nlat-1)) + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Read namelist with information for CMOR output file + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + open(10,file=cmor_nl,status='old') + read(10,nml=cmor) + close(10) + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Specify path for tables and set up other CMOR options + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#ifdef USE_CMOR1 + error_flag = cmor_setup(inpath=trim(inpath),netcdf_file_action=trim(wmode)) +#else + nc_action = CMOR_APPEND_3 + if (trim(wmode) == 'replace') nc_action = CMOR_REPLACE_3 + error_flag = cmor_setup(inpath=trim(inpath),netcdf_file_action=nc_action,create_subdirectories=0) +#endif + + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define dataset as output from COSP, and other model details + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#ifdef USE_CMOR1 + error_flag = cmor_dataset(outpath=trim(outpath),experiment_id=trim(experiment_id),institution=trim(institution), & + source=trim(source),calendar=trim(calendar),realization=realization,contact=trim(contact), & + history=trim(history),comment=trim(comment),references=trim(references)) +#else + error_flag = cmor_dataset(outpath=trim(outpath),experiment_id=trim(experiment_id),institution=trim(institution), & + source=trim(source),calendar=trim(calendar),realization=realization,contact=trim(contact), & + history=trim(history),comment=trim(comment),references=trim(references),model_id=trim(model_id), & + branch_time=branch_time,parent_experiment_id=trim(parent_experiment_id),forcing=trim(forcing), & + institute_id=trim(institute_id),parent_experiment_rip=trim(parent_experiment_rip), & + initialization_method=initialization_method,physics_version=physics_version) + error_flag = cmor_set_cur_dataset_attribute('cosp_version',trim(COSP_VERSION)) +#endif + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define axis + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + lon_axid = cmor_axis(table=table, table_entry='longitude', units='degrees_east', length=Nlon, coord_vals=lon_ax, & + cell_bounds = lon_bounds) + lat_axid = cmor_axis(table=table, table_entry='latitude', units='degrees_north', length=Nlat, coord_vals=lat_ax, & + cell_bounds = lat_bounds) + column_axid = cmor_axis(table=table, table_entry='column', units='1', length=Ncolumns, coord_vals=column_ax) + channel_axid = cmor_axis(table=table, table_entry='channel', units='1', length=Nchannels, coord_vals=channel_ax) + height_axid = cmor_axis(table=table, table_entry='alt40', units='m', length=Nlvgrid, & + coord_vals=vgrid%z,cell_bounds=vgrid_bounds) + dbze_axid = cmor_axis(table=table, table_entry='dbze', units='dBZ', length=DBZE_BINS, & + coord_vals=dbze_ax,cell_bounds=dbze_bounds) + height_mlev_axid = cmor_axis(table=table, table_entry='alevel', units='1', length=Nlevels, & + coord_vals=vgrid%mz,cell_bounds=mgrid_bounds) + sratio_axid = cmor_axis(table=table, table_entry='scatratio', units='1', length=SR_BINS, & + coord_vals=(sratio_bounds(1,:)+sratio_bounds(2,:))/2.0,cell_bounds=sratio_bounds) + tau_axid = cmor_axis(table=table, table_entry='tau', units='1', length=7, & + coord_vals=ISCCP_TAU,cell_bounds=ISCCP_TAU_BNDS) + pressure2_axid = cmor_axis(table=table, table_entry='plev7', units='Pa', length=7, & + coord_vals=ISCCP_PC,cell_bounds=ISCCP_PC_BNDS) + sza_axid = cmor_axis(table=table, table_entry='sza5', units='degree', length=PARASOL_NREFL, coord_vals=PARASOL_SZA) + MISR_CTH_axid = cmor_axis(table=table, table_entry='cth16', units='m', length=MISR_N_CTH, & + coord_vals=MISR_CTH,cell_bounds=MISR_CTH_BNDS) + time_axid = cmor_axis(table=table, table_entry='time1', units='days since '//trim(start_date), length=maxtsteps) + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Fill in variable info and associate pointers + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! 1D variables + d3 = (/lon_axid,lat_axid,time_axid/) + d2 = (/Nlon,Nlat/) + call construct_var1d('cllcalipso', d3, d2, stlidar%cldlayer(:,1),v1d(1),units='%') ! correction sb + call construct_var1d('clmcalipso', d3, d2, stlidar%cldlayer(:,2),v1d(2),units='%') ! correction sb + call construct_var1d('clhcalipso', d3, d2, stlidar%cldlayer(:,3),v1d(3),units='%') ! correction sb + call construct_var1d('cltcalipso', d3, d2, stlidar%cldlayer(:,4),v1d(4),units='%') ! correction sb + call construct_var1d('cltlidarradar', d3, d2, stradar%radar_lidar_tcc,v1d(5),units='%') + call construct_var1d('cltisccp', d3, d2, isccp%totalcldarea,v1d(6),units='%') + call construct_var1d('pctisccp', d3, d2, isccp%meanptop,v1d(7),units='Pa') + call construct_var1d('tauisccp', d3, d2, isccp%meantaucld,v1d(8),units='1') + call construct_var1d('albisccp', d3, d2, isccp%meanalbedocld,v1d(9),units='1') + call construct_var1d('meantbisccp', d3, d2, isccp%meantb,v1d(10),units='K') + call construct_var1d('meantbclrisccp', d3, d2, isccp%meantbclr,v1d(11),units='K') + call construct_var1d('cltmodis', d3, d2, modis%Cloud_Fraction_Total_Mean,v1d(12),units='%') + call construct_var1d('clwmodis', d3, d2, modis%Cloud_Fraction_Water_Mean,v1d(13),units='%') + call construct_var1d('climodis', d3, d2, modis%Cloud_Fraction_Ice_Mean, v1d(14),units='%') + call construct_var1d('clhmodis', d3, d2, modis%Cloud_Fraction_High_Mean,v1d(15),units='%') + call construct_var1d('clmmodis', d3, d2, modis%Cloud_Fraction_Mid_Mean,v1d(16),units='%') + call construct_var1d('cllmodis', d3, d2, modis%Cloud_Fraction_Low_Mean, v1d(17),units='%') + call construct_var1d('tautmodis', d3, d2, modis%Optical_Thickness_Total_Mean,v1d(18),units='1') + call construct_var1d('tauwmodis', d3, d2, modis%Optical_Thickness_Water_Mean,v1d(19),units='1') + call construct_var1d('tauimodis', d3, d2, modis%Optical_Thickness_Ice_Mean,v1d(20),units='1') + call construct_var1d('tautlogmodis', d3, d2, modis%Optical_Thickness_Total_LogMean,v1d(21),units='1') + call construct_var1d('tauwlogmodis', d3, d2, modis%Optical_Thickness_Water_LogMean,v1d(22),units='1') + call construct_var1d('tauilogmodis', d3, d2, modis%Optical_Thickness_Ice_LogMean,v1d(23),units='1') + call construct_var1d('reffclwmodis', d3, d2, modis%Cloud_Particle_Size_Water_Mean,v1d(24),units='m') + call construct_var1d('reffclimodis', d3, d2, modis%Cloud_Particle_Size_Ice_Mean, v1d(25),units='m') + call construct_var1d('pctmodis', d3, d2, modis%Cloud_Top_Pressure_Total_Mean, v1d(26),units='Pa') + call construct_var1d('lwpmodis', d3, d2, modis%Liquid_Water_Path_Mean, v1d(27),units='kg m-2') + call construct_var1d('iwpmodis', d3, d2, modis%Ice_Water_Path_Mean, v1d(28),units='kg m-2') + ! 2D variables + d4 = (/lon_axid,lat_axid,height_axid,time_axid/) + d3 = (/Nlon,Nlat,Nlvgrid/) + call construct_var2d('clcalipso', d4, d3, stlidar%lidarcld,v2d(1),units='%') + call construct_var2d('clcalipso2', d4, d3, stradar%lidar_only_freq_cloud,v2d(2),units='%') + d4 = (/lon_axid,lat_axid,height_mlev_axid,time_axid/) + d3 = (/Nlon,Nlat,Nlevels/) + call construct_var2d('lidarBetaMol532', d4, d3, sglidar%beta_mol,v2d(3),units='m-1 sr-1') + d4 = (/lon_axid,lat_axid,column_axid,time_axid/) + d3 = (/Nlon,Nlat,Ncolumns/) + call construct_var2d('boxtauisccp', d4, d3, isccp%boxtau,v2d(4),units='1') + call construct_var2d('boxptopisccp', d4, d3, isccp%boxptop,v2d(5),units='Pa') + d4 = (/lon_axid,lat_axid,sza_axid,time_axid/) + d3 = (/Nlon,Nlat,PARASOL_NREFL/) + call construct_var2d('parasolRefl', d4, d3, stlidar%parasolrefl,v2d(6),units='1') +#ifdef RTTOV + d4 = (/lon_axid,lat_axid,channel_axid,time_axid/) + d3 = (/Nlon,Nlat,Nchannels/) + call construct_var2d('tbrttov', d4, d3, rttov%tbs,v2d(7),units='K') +#endif + + ! 3D variables + d5 = (/lon_axid,lat_axid,column_axid,height_mlev_axid,time_axid/) + d4 = (/Nlon,Nlat,Ncolumns,Nlevels/) + call construct_var3d('dbze94', d5, d4, sgradar%Ze_tot,v3d(1),units='1') + call construct_var3d('atb532', d5, d4, sglidar%beta_tot,v3d(2),units='m-1 sr-1') + call construct_var3d('fracout', d5, d4, sg%frac_out,v3d(3),units='1') + d5 = (/lon_axid,lat_axid,dbze_axid,height_axid,time_axid/) + d4 = (/Nlon,Nlat,DBZE_BINS,Nlvgrid/) + call construct_var3d('cfadDbze94', d5, d4, stradar%cfad_ze,v3d(4),units='1') + d5 = (/lon_axid,lat_axid,sratio_axid,height_axid,time_axid/) + d4 = (/Nlon,Nlat,SR_BINS,Nlvgrid/) + call construct_var3d('cfadLidarsr532', d5, d4, stlidar%cfad_sr,v3d(5),units='1') + d5 = (/lon_axid,lat_axid,tau_axid,pressure2_axid,time_axid/) + d4 = (/Nlon,Nlat,7,7/) + call construct_var3d('clisccp', d5, d4, isccp%fq_isccp,v3d(6),units='%') + call construct_var3d('clmodis', d5, d4, modis%Optical_Thickness_vs_Cloud_Top_Pressure, v3d(7), units='%') +! call construct_var3d('clmodis', & +! (/lon_axid, lat_axid, modis_tau_axid, modis_p_axid, time_axid/), & +! (/Nlon, Nlat, numModisTauBins, numModisPressureBins/), & +! modis%Optical_Thickness_vs_Cloud_Top_Pressure, v3d(7), units='%') + d5 = (/lon_axid,lat_axid,tau_axid,MISR_CTH_axid,time_axid/) + d4 = (/Nlon,Nlat,7,MISR_N_CTH/) + call construct_var3d('clMISR', d5, d4, misr%fq_MISR,v3d(8),units='%') + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Find list of outputs to be written + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + do i=1,N_OUT_LIST + lfound = .false. + if (trim(cfg%out_list(i)) /= '') then + do j=1,n1d + if (trim(v1d(j)%name) == trim(cfg%out_list(i))) then + lout1d(j) = .true. + lfound = .true. + exit + endif + enddo + if (.not.lfound) then + do j=1,n2d + if (trim(v2d(j)%name) == trim(cfg%out_list(i))) then + lout2d(j) = .true. + lfound = .true. + exit + endif + enddo + endif + if (.not.lfound) then + do j=1,n3d + if (trim(v3d(j)%name) == trim(cfg%out_list(i))) then + lout3d(j) = .true. + lfound = .true. + exit + endif + enddo + endif + endif + enddo + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Define variables. Fill in dimensions table first if needed + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! 1D variables + do i=1,n1d + if (lout1d(i)) var1d_id(i) = cmor_variable(table=table, table_entry=v1d(i)%name, units=v1d(i)%units, & + axis_ids=v1d(i)%dimsid, missing_value=R_UNDEF) + enddo + ! 2D variables + do i=1,n2d + if (lout2d(i)) var2d_id(i) = cmor_variable(table=table, table_entry=v2d(i)%name, units=v2d(i)%units, & + axis_ids=v2d(i)%dimsid, missing_value=R_UNDEF) + enddo + ! 3D variables + do i=1,n3d + if (lout3d(i)) var3d_id(i) = cmor_variable(table=table, table_entry=v3d(i)%name, units=v3d(i)%units, & + axis_ids=v3d(i)%dimsid, missing_value=R_UNDEF) + enddo + + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Write variables to file + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! 1D variables (2D output) + do i=1,n1d + if (lout1d(i)) then + allocate(y2(v1d(i)%dimssz(1),v1d(i)%dimssz(2))) + call map_point_to_ll(Nlon,Nlat,geomode,x1=v1d(i)%pntr,y2=y2) ! Regridding + error_flag = cmor_write(var_id=var1d_id(i), data=y2, & + ntimes_passed=1,time_vals=(/gb%time/),time_bnds=tbnds) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing '//trim(v1d(i)%name) + stop + endif + deallocate(y2) + endif + enddo + ! 2D variables (3D output) + do i=1,n2d + if (lout2d(i)) then + allocate(y3(v2d(i)%dimssz(1),v2d(i)%dimssz(2),v2d(i)%dimssz(3))) + call map_point_to_ll(Nlon,Nlat,geomode,x2=v2d(i)%pntr,y3=y3) ! Regridding + error_flag = cmor_write(var_id=var2d_id(i), data=y3, & + ntimes_passed=1,time_vals=(/gb%time/),time_bnds=tbnds) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing '//trim(v2d(i)%name) + stop + endif + deallocate(y3) + endif + enddo + ! 3D variables (4D output) + do i=1,n3d + if (lout3d(i)) then + allocate(y4(v3d(i)%dimssz(1),v3d(i)%dimssz(2),v3d(i)%dimssz(3),v3d(i)%dimssz(4))) + call map_point_to_ll(Nlon,Nlat,geomode,x3=v3d(i)%pntr,y4=y4) ! Regridding + error_flag = cmor_write(var_id=var3d_id(i), data=y4, & + ntimes_passed=1,time_vals=(/gb%time/),time_bnds=tbnds) + if (error_flag < 0) then + print *, trim(pro_name)//': Error writing '//trim(v3d(i)%name) + stop + endif + deallocate(y4) + endif + enddo + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Close files + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + error_flag = cmor_close() + + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ! Deallocate memory + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + deallocate(column_ax,dbze_ax,channel_ax,dbze_bounds,sratio_bounds, & + vgrid_bounds,mgrid_bounds,lon_bounds,lat_bounds) + + END SUBROUTINE NC_WRITE_COSP_2D +#endif !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% !--------------- SUBROUTINE READ_COSP_OUTPUT_NL ------------------------- @@ -1019,47 +2010,47 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) ! Local variables integer :: i logical :: Lradar_sim,Llidar_sim,Lisccp_sim,Lmodis_sim,Lmisr_sim,Lrttov_sim, & - Lalbisccp,Latb532,Lboxptopisccp,Lboxtauisccp,Lcfaddbze94, & + Lalbisccp,Latb532,Lboxptopisccp,Lboxtauisccp,LcfadDbze94, & LcfadLidarsr532,Lclcalipso2,Lclcalipso,Lclhcalipso,Lclisccp,Lcllcalipso, & Lclmcalipso,Lcltcalipso,Lcltlidarradar,Lpctisccp,Ldbze94,Ltauisccp,Lcltisccp, & - Llongitude,Llatitude,LparasolRefl,LclMISR,Lmeantbisccp,Lmeantbclrisccp, & + Ltoffset,LparasolRefl,LclMISR,Lmeantbisccp,Lmeantbclrisccp, & Lfracout,LlidarBetaMol532,Ltbrttov, & Lcltmodis,Lclwmodis,Lclimodis,Lclhmodis,Lclmmodis,Lcllmodis,Ltautmodis,Ltauwmodis,Ltauimodis,Ltautlogmodis, & Ltauwlogmodis,Ltauilogmodis,Lreffclwmodis,Lreffclimodis,Lpctmodis,Llwpmodis, & Liwpmodis,Lclmodis + namelist/COSP_OUTPUT/Lradar_sim,Llidar_sim,Lisccp_sim,Lmodis_sim,Lmisr_sim,Lrttov_sim, & - Lalbisccp,Latb532,Lboxptopisccp,Lboxtauisccp,Lcfaddbze94, & + Lalbisccp,Latb532,Lboxptopisccp,Lboxtauisccp,LcfadDbze94, & LcfadLidarsr532,Lclcalipso2,Lclcalipso,Lclhcalipso,Lclisccp, & Lcllcalipso,Lclmcalipso,Lcltcalipso,Lcltlidarradar,Lpctisccp,Ldbze94,Ltauisccp, & - Lcltisccp,Llongitude,Llatitude,LparasolRefl,LclMISR,Lmeantbisccp,Lmeantbclrisccp, & + Lcltisccp,Ltoffset,LparasolRefl,LclMISR,Lmeantbisccp,Lmeantbclrisccp, & Lfracout,LlidarBetaMol532,Ltbrttov, & - Lcltmodis,Lclwmodis,Lclimodis,Lclimodis,Lclhmodis,Lclmmodis,Lcllmodis,Ltautmodis,Ltauwmodis,Ltauimodis,Ltautlogmodis, & + Lcltmodis,Lclwmodis,Lclimodis,Lclhmodis,Lclmmodis,Lcllmodis,Ltautmodis,Ltauwmodis,Ltauimodis,Ltautlogmodis, & Ltauwlogmodis,Ltauilogmodis,Lreffclwmodis,Lreffclimodis,Lpctmodis,Llwpmodis, & Liwpmodis,Lclmodis - +#ifdef COSP_GFDL integer :: unit, io, ierr, logunit - +#endif + do i=1,N_OUT_LIST cfg%out_list(i)='' enddo -! open(10,file=cosp_nl,status='old') -! read(10,nml=cosp_output) -! close(10) +#ifdef COSP_GFDL !--------------------------------------------------------------------- ! read namelist. #ifdef INTERNAL_FILE_NML - read (input_nml_file, nml=cosp_output, iostat=io) - ierr = check_nml_error(io,"cosp_output") + read (input_nml_file, nml=cosp_output, iostat=io) + ierr = check_nml_error(io,"cosp_output") #else !--------------------------------------------------------------------- if ( file_exist('input.nml')) then - unit = open_namelist_file () - ierr=1; do while (ierr /= 0) - read (unit, nml=cosp_output, iostat=io, end=10) - ierr = check_nml_error(io,'cosp_output') - enddo + unit = open_namelist_file () + ierr=1; do while (ierr /= 0) + read (unit, nml=cosp_output, iostat=io, end=10) + ierr = check_nml_error(io,'cosp_output') + enddo 10 call close_file (unit) - endif + endif #endif !--------------------------------------------------------------------- ! write namelist to logfile. @@ -1069,18 +2060,25 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) if (mpp_pe() == mpp_root_pe() ) & write (logunit, nml=cosp_output) + +#else + open(10,file=cosp_nl,status='old') + read(10,nml=cosp_output) + close(10) +#endif ! Deal with dependencies if (.not.Lradar_sim) then - Lcfaddbze94 = .false. + LcfadDbze94 = .false. Lclcalipso2 = .false. - Lcltlidarradar = .false. + Lcltlidarradar = .false. ! Needs radar & lidar Ldbze94 = .false. + Lclcalipso2 = .false. ! Needs radar & lidar endif if (.not.Llidar_sim) then Latb532 = .false. LcfadLidarsr532 = .false. - Lclcalipso2 = .false. + Lclcalipso2 = .false. ! Needs radar & lidar Lclcalipso = .false. Lclhcalipso = .false. Lcllcalipso = .false. @@ -1088,7 +2086,8 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) Lcltcalipso = .false. Lcltlidarradar = .false. LparasolRefl = .false. - LlidarBetaMol532 = .false. + LlidarBetaMol532 = .false. + Lcltlidarradar = .false. ! Needs radar & lidar endif if (.not.Lisccp_sim) then Lalbisccp = .false. @@ -1133,14 +2132,6 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) endif if (Lmodis_sim) Lisccp_sim = .true. - ! Diagnostics that use Radar and Lidar - if (((Lclcalipso2).or.(Lcltlidarradar)).and.((Lradar_sim).or.(Llidar_sim))) then - Lclcalipso2 = .true. - Lcltlidarradar = .true. - Llidar_sim = .true. - Lradar_sim = .true. - endif - cfg%Lstats = .false. if ((Lradar_sim).or.(Llidar_sim).or.(Lisccp_sim)) cfg%Lstats = .true. @@ -1168,9 +2159,9 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) i = i+1 if (Lboxtauisccp) cfg%out_list(i) = 'boxtauisccp' i = i+1 - if (Lcfaddbze94) cfg%out_list(i) = 'cfaddbze94' + if (LcfadDbze94) cfg%out_list(i) = 'cfadDbze94' i = i+1 - if (LcfadLidarsr532) cfg%out_list(i) = 'cfadLidarsr532' + if (LcfadLidarsr532) cfg%out_list(i) = 'cfadLidarsr532' i = i+1 if (Lclcalipso2) cfg%out_list(i) = 'clcalipso2' i = i+1 @@ -1178,7 +2169,7 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) i = i+1 if (Lclhcalipso) cfg%out_list(i) = 'clhcalipso' i = i+1 - if (Lclisccp) cfg%out_list(i) = 'clisccp' + if (Lclisccp) cfg%out_list(i) = 'clisccp' i = i+1 if (Lcllcalipso) cfg%out_list(i) = 'cllcalipso' i = i+1 @@ -1196,11 +2187,9 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) i = i+1 if (Lcltisccp) cfg%out_list(i) = 'cltisccp' i = i+1 - if (Llongitude) cfg%out_list(i) = 'lon' + if (Ltoffset) cfg%out_list(i) = 'toffset' i = i+1 - if (Llatitude) cfg%out_list(i) = 'lat' - i = i+1 - if (LparasolRefl) cfg%out_list(i) = 'parasolRefl' + if (LparasolRefl) cfg%out_list(i) = 'parasolRefl' i = i+1 if (LclMISR) cfg%out_list(i) = 'clMISR' i = i+1 @@ -1208,9 +2197,9 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) i = i+1 if (Lmeantbclrisccp) cfg%out_list(i) = 'meantbclrisccp' i = i+1 - if (Lfracout) cfg%out_list(i) = 'fracout' + if (Lfracout) cfg%out_list(i) = 'fracout' i = i+1 - if (LlidarBetaMol532) cfg%out_list(i) = 'lidarBbetaMol532' + if (LlidarBetaMol532) cfg%out_list(i) = 'lidarBetaMol532' i = i+1 if (Ltbrttov) cfg%out_list(i) = 'tbrttov' i = i+1 @@ -1249,15 +2238,20 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) if (Liwpmodis) cfg%out_list(i) = 'iwpmodis' i = i+1 if (Lclmodis) cfg%out_list(i) = 'clmodis' - + if (i /= N_OUT_LIST) then - call error_mesg ('cosp_io:read_cosp_output_nl', & +#ifdef COSP_GFDL + call error_mesg ('cosp_io:read_cosp_output_nl', & 'COSP_IO: wrong number of output diagnostics', & FATAL) +#else + print *, 'COSP_IO: wrong number of output diagnostics' + stop +#endif endif ! Copy diagnostic flags to cfg structure - ! ISCCP simulator + ! ISCCP simulator cfg%Lalbisccp = Lalbisccp cfg%Latb532 = Latb532 cfg%Lboxptopisccp = Lboxptopisccp @@ -1268,9 +2262,9 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) cfg%Lpctisccp = Lpctisccp cfg%Ltauisccp = Ltauisccp cfg%Lcltisccp = Lcltisccp - ! CloudSat simulator + ! CloudSat simulator cfg%Ldbze94 = Ldbze94 - cfg%Lcfaddbze94 = Lcfaddbze94 + cfg%LcfadDbze94 = LcfadDbze94 ! CALIPSO/PARASOL simulator cfg%LcfadLidarsr532 = LcfadLidarsr532 cfg%Lclcalipso2 = Lclcalipso2 @@ -1284,8 +2278,7 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) ! MISR simulator cfg%LclMISR = LclMISR ! Other - cfg%Llongitude = Llongitude - cfg%Llatitude = Llatitude + cfg%Ltoffset = Ltoffset cfg%Lfracout = Lfracout cfg%LlidarBetaMol532 = LlidarBetaMol532 ! RTTOV @@ -1310,5 +2303,20 @@ SUBROUTINE READ_COSP_OUTPUT_NL(cosp_nl,cfg) cfg%Liwpmodis=Liwpmodis cfg%Lclmodis=Lclmodis END SUBROUTINE READ_COSP_OUTPUT_NL - + +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +!--------------- SUBROUTINE ERROR_CONTROL ------------------------ +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + SUBROUTINE COSP_ERROR(routine_name,message,errcode) + character(len = *), intent(in) :: routine_name + character(len = *), intent(in) :: message + integer,optional :: errcode + + write(6, *) " ********** Failure in ", trim(routine_name) + write(6, *) " ********** ", trim(message) + if (present(errcode)) write(6, *) " ********** errcode: ", errcode + flush(6) + stop + END SUBROUTINE COSP_ERROR + END MODULE MOD_COSP_IO diff --git a/src/atmos_param/cosp/cosp_isccp_simulator.f90 b/src/atmos_param/cosp/cosp_isccp_simulator.F90 similarity index 86% rename from src/atmos_param/cosp/cosp_isccp_simulator.f90 rename to src/atmos_param/cosp/cosp_isccp_simulator.F90 index 6c96e1cbd7..7550cd20a6 100644 --- a/src/atmos_param/cosp/cosp_isccp_simulator.f90 +++ b/src/atmos_param/cosp/cosp_isccp_simulator.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: cosp_isccp_simulator.f90,v 19.0 2012/01/06 20:03:27 fms Exp $ -! $Name: siena_201207 $ +! $Id: cosp_isccp_simulator.F90,v 20.0 2013/12/13 23:15:44 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -48,7 +53,7 @@ SUBROUTINE COSP_ISCCP_SIMULATOR(gbx,sgx,y) type(cosp_isccp),intent(inout) :: y ! ISCCP simulator output ! Local variables - integer :: i,Nlevels,Npoints + integer :: Nlevels,Npoints real :: pfull(gbx%Npoints, gbx%Nlevels) real :: phalf(gbx%Npoints, gbx%Nlevels + 1) real :: qv(gbx%Npoints, gbx%Nlevels) @@ -61,8 +66,6 @@ SUBROUTINE COSP_ISCCP_SIMULATOR(gbx,sgx,y) real :: dem_c(gbx%Npoints, gbx%Nlevels) real :: frac_out(gbx%Npoints, gbx%Ncolumns, gbx%Nlevels) integer :: sunlit(gbx%Npoints) - real :: dum1 (gbx%Npoints, gbx%Ncolumns, gbx%Nlevels) - real :: dum2 (gbx%Npoints, gbx%Ncolumns, gbx%Nlevels) Nlevels = gbx%Nlevels Npoints = gbx%Npoints @@ -80,7 +83,7 @@ SUBROUTINE COSP_ISCCP_SIMULATOR(gbx,sgx,y) dem_c = gbx%dem_c(:,Nlevels:1:-1) frac_out(1:Npoints,:,1:Nlevels) = sgx%frac_out(1:Npoints,:,Nlevels:1:-1) sunlit = int(gbx%sunlit) - +#ifdef COSP_GFDL if (sgx%cols_input_from_model) then call icarus(0,0,gbx%npoints,sunlit,gbx%nlevels,gbx%ncolumns, & pfull,phalf,qv,cc,conv,dtau_s,dtau_c, & @@ -89,7 +92,7 @@ SUBROUTINE COSP_ISCCP_SIMULATOR(gbx,sgx,y) gbx%skt,gbx%isccp_emsfc_lw,at,dem_s,dem_c,y%fq_isccp,y%totalcldarea, & y%meanptop,y%meantaucld,y%meanalbedocld, & y%meantb,y%meantbclr,y%boxtau,y%boxptop, & - sgx%dtau_col, sgx%dem_col, .true.) + sgx%dtau_col, sgx%dem_col) else call icarus(0,0,gbx%npoints,sunlit,gbx%nlevels,gbx%ncolumns, & pfull,phalf,qv,cc,conv,dtau_s,dtau_c, & @@ -97,15 +100,23 @@ SUBROUTINE COSP_ISCCP_SIMULATOR(gbx,sgx,y) gbx%isccp_overlap,frac_out, & gbx%skt,gbx%isccp_emsfc_lw,at,dem_s,dem_c,y%fq_isccp,y%totalcldarea, & y%meanptop,y%meantaucld,y%meanalbedocld, & - y%meantb,y%meantbclr,y%boxtau,y%boxptop, & - dum1, dum2, .false.) - endif + y%meantb,y%meantbclr,y%boxtau,y%boxptop) + endif +#else + call icarus(0,0,gbx%npoints,sunlit,gbx%nlevels,gbx%ncolumns, & + pfull,phalf,qv,cc,conv,dtau_s,dtau_c, & + gbx%isccp_top_height,gbx%isccp_top_height_direction, & + gbx%isccp_overlap,frac_out, & + gbx%skt,gbx%isccp_emsfc_lw,at,dem_s,dem_c,y%fq_isccp,y%totalcldarea, & + y%meanptop,y%meantaucld,y%meanalbedocld, & + y%meantb,y%meantbclr,y%boxtau,y%boxptop) +#endif ! Flip outputs. Levels from surface to TOA ! --- (npoints,tau=7,pressure=7) y%fq_isccp(:,:,:) = y%fq_isccp(:,:,7:1:-1) - + ! Check if there is any value slightly greater than 1 where ((y%totalcldarea > 1.0-1.e-5) .and. (y%totalcldarea < 1.0+1.e-5)) y%totalcldarea = 1.0 diff --git a/src/atmos_param/cosp/cosp_lidar.f90 b/src/atmos_param/cosp/cosp_lidar.F90 similarity index 95% rename from src/atmos_param/cosp/cosp_lidar.f90 rename to src/atmos_param/cosp/cosp_lidar.F90 index a1d908dbd3..24744a0af0 100644 --- a/src/atmos_param/cosp/cosp_lidar.f90 +++ b/src/atmos_param/cosp/cosp_lidar.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: cosp_lidar.f90,v 19.0 2012/01/06 20:03:29 fms Exp $ -! $Name: siena_201207 $ + +! $Id: cosp_lidar.F90,v 20.0 2013/12/13 23:15:45 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -59,7 +64,6 @@ SUBROUTINE COSP_LIDAR(gbx,sgx,sghydro,y) ! Local variables integer :: i real :: presf(sgx%Npoints, sgx%Nlevels + 1) - real :: frac_out(sgx%Npoints, sgx%Nlevels) real,dimension(sgx%Npoints, sgx%Nlevels) :: lsca,mr_ll,mr_li,mr_cl,mr_ci real,dimension(sgx%Npoints, sgx%Nlevels) :: beta_tot,tau_tot real,dimension(sgx%Npoints, PARASOL_NREFL) :: refle @@ -74,6 +78,7 @@ SUBROUTINE COSP_LIDAR(gbx,sgx,sghydro,y) mr_li(:,:) = sghydro%mr_hydro(:,i,:,I_LSCICE) mr_cl(:,:) = sghydro%mr_hydro(:,i,:,I_CVCLIQ) mr_ci(:,:) = sghydro%mr_hydro(:,i,:,I_CVCICE) +#ifdef COSP_GFDL if (sgx%cols_input_from_model) then call lidar_simulator(sgx%Npoints, sgx%Nlevels, 4 & , PARASOL_NREFL, LIDAR_UNDEF & @@ -87,6 +92,7 @@ SUBROUTINE COSP_LIDAR(gbx,sgx,sghydro,y) y%beta_mol, beta_tot, tau_tot & , refle ) ! reflectance else +#endif call lidar_simulator(sgx%Npoints, sgx%Nlevels, 4 & , PARASOL_NREFL, LIDAR_UNDEF & , gbx%p, presf, gbx%T & @@ -94,7 +100,9 @@ SUBROUTINE COSP_LIDAR(gbx,sgx,sghydro,y) , gbx%Reff(:,:,I_LSCLIQ), gbx%Reff(:,:,I_LSCICE), gbx%Reff(:,:,I_CVCLIQ), gbx%Reff(:,:,I_CVCICE) & , sgx%frac_out, gbx%lidar_ice_type, y%beta_mol, beta_tot, tau_tot & , refle ) ! reflectance +#ifdef COSP_GFDL endif +#endif y%beta_tot(:,i,:) = beta_tot(:,:) y%tau_tot(:,i,:) = tau_tot(:,:) diff --git a/src/atmos_param/cosp/cosp_misr_simulator.f90 b/src/atmos_param/cosp/cosp_misr_simulator.F90 similarity index 86% rename from src/atmos_param/cosp/cosp_misr_simulator.f90 rename to src/atmos_param/cosp/cosp_misr_simulator.F90 index 4d4861dad6..4cf3f5f3b6 100644 --- a/src/atmos_param/cosp/cosp_misr_simulator.f90 +++ b/src/atmos_param/cosp/cosp_misr_simulator.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- + +! $Id: cosp_misr_simulator.F90,v 20.0 2013/12/13 23:15:46 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 -! $Id: cosp_misr_simulator.f90,v 19.0 2012/01/06 20:03:31 fms Exp $ -! $Name: siena_201207 $ +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -54,7 +59,7 @@ SUBROUTINE COSP_MISR_SIMULATOR(gbx,sgx,y) type(cosp_misr),intent(inout) :: y ! MISR simulator output ! Local variables - integer :: i,Nlevels,Npoints + integer :: Nlevels,Npoints real :: dtau_s(gbx%Npoints, gbx%Nlevels) real :: dtau_c(gbx%Npoints, gbx%Nlevels) real :: at(gbx%Npoints, gbx%Nlevels) @@ -64,11 +69,8 @@ SUBROUTINE COSP_MISR_SIMULATOR(gbx,sgx,y) real :: zfull(gbx%Npoints, gbx%Nlevels) ! height (in meters) of full model levels (i.e. midpoints) ! zfull(npoints,1) is top level of model ! zfull(npoints,nlev) is bottom level of model - real :: phy_t0p1_mean_ztop ! mean cloud top height(m) of 0.1 tau treshold - real :: fq_phy_t0p1_TAU_v_CTH(7,16) - real :: dum1(gbx%Npoints, gbx%Ncolumns, gbx%Nlevels) - + Nlevels = gbx%Nlevels Npoints = gbx%Npoints ! Levels from TOA to surface @@ -79,19 +81,22 @@ SUBROUTINE COSP_MISR_SIMULATOR(gbx,sgx,y) frac_out(1:Npoints,:,1:Nlevels) = sgx%frac_out(1:Npoints,:,Nlevels:1:-1) sunlit = int(gbx%sunlit) +#ifdef COSP_GFDL if (sgx%cols_input_from_model) then call MISR_simulator(gbx%npoints,gbx%nlevels,gbx%ncolumns,& sunlit,zfull,at,dtau_s,dtau_c,frac_out, & + R_UNDEF, & y%fq_MISR,y%MISR_dist_model_layertops, & y%MISR_meanztop,y%MISR_cldarea, & - sgx%dtau_col, .true.) + sgx%dtau_col) else +#endif call MISR_simulator(gbx%npoints,gbx%nlevels,gbx%ncolumns,& - sunlit,zfull,at,dtau_s,dtau_c,frac_out, & - y%fq_MISR,y%MISR_dist_model_layertops, & - y%MISR_meanztop,y%MISR_cldarea, & - dum1, .false.) + sunlit,zfull,at,dtau_s,dtau_c,frac_out, R_UNDEF, & + y%fq_MISR,y%MISR_dist_model_layertops,y%MISR_meanztop,y%MISR_cldarea) +#ifdef COSP_GFDL endif +#endif END SUBROUTINE COSP_MISR_SIMULATOR diff --git a/src/atmos_param/cosp/cosp_modis_simulator.f90 b/src/atmos_param/cosp/cosp_modis_simulator.F90 similarity index 81% rename from src/atmos_param/cosp/cosp_modis_simulator.f90 rename to src/atmos_param/cosp/cosp_modis_simulator.F90 index e6b413bc5d..6a1091e5fc 100644 --- a/src/atmos_param/cosp/cosp_modis_simulator.f90 +++ b/src/atmos_param/cosp/cosp_modis_simulator.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: cosp_modis_simulator.f90,v 19.0 2012/01/06 20:03:32 fms Exp $ -! $Name: siena_201207 $ + +! $Id: cosp_modis_simulator.F90,v 20.0 2013/12/13 23:15:47 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) 2009, Regents of the Unversity of Colorado ! Author: Robert Pincus, Cooperative Institute for Research in the Environmental Sciences @@ -53,7 +58,9 @@ MODULE MOD_COSP_Modis_Simulator type COSP_MODIS ! Dimensions integer :: Npoints ! Number of gridpoints +#ifdef COSP_GFDL integer :: Ncolumns ! Number of columns +#endif ! ! Grid means; dimension nPoints @@ -66,12 +73,16 @@ MODULE MOD_COSP_Modis_Simulator Cloud_Particle_Size_Water_Mean, Cloud_Particle_Size_Ice_Mean, & Cloud_Top_Pressure_Total_Mean, & Liquid_Water_Path_Mean, Ice_Water_Path_Mean - ! Subcolumn particle sizes, optical thickness and cloud top pressure - ! dimensions (npoints, ncolumns) - real, dimension(:,:), pointer :: & - Column_Particle_Size, Column_Optical_Thickness, & - Column_Cloud_Top_Pressure, & - retrievedPhase + +#ifdef COSP_GFDL + ! Subcolumn particle sizes, optical thickness and cloud top pressure + ! dimensions (npoints, ncolumns) + real, dimension(:,:), pointer :: & + Column_Particle_Size, Column_Optical_Thickness, & + Column_Cloud_Top_Pressure, & + retrievedPhase +#endif + ! ! Also need the ISCCP-type optical thickness/cloud top pressure histogram ! @@ -80,21 +91,32 @@ MODULE MOD_COSP_Modis_Simulator contains !------------------------------------------------------------------------------------------------ +#ifdef COSP_GFDL subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit, modisSim) +#else + subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, modisSim) +#endif ! Arguments type(cosp_gridbox), intent(in ) :: gridBox ! Gridbox info type(cosp_subgrid), intent(in ) :: subCols ! subCol indicators of convective/stratiform type(cosp_sghydro), intent(in ) :: subcolHydro ! subcol hydrometeor contens type(cosp_isccp), intent(in ) :: isccpSim ! ISCCP simulator output - integer, intent(in ) :: nSunlit ! Are there any sunlit points? +#ifdef COSP_GFDL + integer, intent(in ) :: nSunlit ! Are there any sunlit points? +#endif type(cosp_modis), intent( out) :: modisSim ! MODIS simulator subcol output ! ------------------------------------------------------------ ! Local variables ! Leave space only for sunlit points - integer :: nPoints, nSubCols, nLevels, i, j +#ifdef COSP_GFDL + integer :: nPoints, nSubCols, nLevels, i +#else + integer :: nPoints, nSubCols, nLevels, nSunlit, i +#endif +#ifdef COSP_GFDL ! Grid-mean quanties; dimensions nPoints, nLevels real, & dimension(nSunlit, gridBox%nLevels) :: & @@ -102,23 +124,60 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit real, & dimension(nSunlit, gridBox%nLevels + 1) :: & pressureLevels + + ! Subcol quantities, dimension nPoints, nSubCols, nLevels + real, & + dimension(nSunlit, subCols%nColumns, gridBox%nLevels) :: & + opticalThickness, cloudWater, cloudIce, waterSize, iceSize, & + liquid_opticalThickness, ice_opticalThickness + + ! Vertically-integrated subcol quantities; dimensions nPoints, nSubcols + integer, & + dimension(nSunlit, subCols%nColumns) :: & + retrievedPhase + real, & + dimension(nSunlit, subCols%nColumns) :: & + isccpTau, isccpCloudTopPressure, retrievedCloudTopPressure, retrievedTau, retrievedSize + + ! Vertically-integrated results + real, dimension(nSunlit) :: & + cfTotal, cfLiquid, cfIce, & + cfHigh, cfMid, cfLow, & + meanTauTotal, meanTauLiquid, meanTauIce, & + meanLogTauTotal, meanLogTauLiquid, meanLogTauIce , & + meanSizeLiquid, meanSizeIce, & + meanCloudTopPressure, & + meanLiquidWaterPath, meanIceWaterPath + + real, dimension(nSunlit, numModisTauBins, numModisPressureBins) :: & + jointHistogram + + integer, dimension(nSunlit) :: sunlit + integer, dimension(:), allocatable :: notSunlit +#else + ! Grid-mean quanties; dimensions nPoints, nLevels + real, & + dimension(count(gridBox%sunlit(:) > 0), gridBox%nLevels) :: & + temperature, pressureLayers + real, & + dimension(count(gridBox%sunlit(:) > 0), gridBox%nLevels + 1) :: & + pressureLevels ! Subcol quantities, dimension nPoints, nSubCols, nLevels real, & - dimension(nSunlit, subCols%nColumns, gridBox%nLevels) :: & - opticalThickness, cloudWater, cloudIce, waterSize, iceSize, & - liquid_opticalThickness, ice_opticalThickness + dimension(count(gridBox%sunlit(:) > 0), subCols%nColumns, gridBox%nLevels) :: & + opticalThickness, cloudWater, cloudIce, waterSize, iceSize ! Vertically-integrated subcol quantities; dimensions nPoints, nSubcols integer, & - dimension(nSunlit, subCols%nColumns) :: & + dimension(count(gridBox%sunlit(:) > 0), subCols%nColumns) :: & retrievedPhase real, & - dimension(nSunlit, subCols%nColumns) :: & + dimension(count(gridBox%sunlit(:) > 0), subCols%nColumns) :: & isccpTau, isccpCloudTopPressure, retrievedCloudTopPressure, retrievedTau, retrievedSize ! Vertically-integrated results - real, dimension(nSunlit) :: & + real, dimension(count(gridBox%sunlit(:) > 0)) :: & cfTotal, cfLiquid, cfIce, & cfHigh, cfMid, cfLow, & meanTauTotal, meanTauLiquid, meanTauIce, & @@ -127,20 +186,22 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit meanCloudTopPressure, & meanLiquidWaterPath, meanIceWaterPath - real, dimension(nSunlit, numModisTauBins, numModisPressureBins) :: & + real, dimension(count(gridBox%sunlit(:) > 0), numModisTauBins, numModisPressureBins) :: & jointHistogram - integer, dimension(nSunlit) :: sunlit -! integer, dimension(count(gridBox%sunlit(:) <= 0)) :: notSunlit - integer, dimension(:), allocatable :: notSunlit + integer, dimension(count(gridBox%sunlit(:) > 0)) :: sunlit + integer, dimension(count(gridBox%sunlit(:) <= 0)) :: notSunlit +#endif ! ------------------------------------------------------------ ! ! Are there any sunlit points? ! +#ifdef COSP_GFDL allocate(notSunlit(count(gridBox%sunlit(:) <= 0))) - -! nSunlit = count(gridBox%sunlit(:) > 0) +#else + nSunlit = count(gridBox%sunlit(:) > 0) +#endif if(nSunlit > 0) then nLevels = gridBox%Nlevels nPoints = gridBox%Npoints @@ -162,6 +223,8 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit ! ! Subcolumn properties - first stratiform cloud... ! +#ifdef COSP_GFDL + if (subCols%cols_input_from_model) then ! Use stochastic column taus opticalThickness(:, :, :) = subCols%dtau_col(sunlit(:),:,:) where(subCols%frac_out(sunlit(:), :, :) == I_LSC) @@ -174,20 +237,55 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit cloudIce (:, :, :) = 0. waterSize (:, :, :) = 0. iceSize (:, :, :) = 0. + end where + + ! + ! .. then add convective cloud + ! + where(subCols%frac_out(sunlit(:), :, :) == I_CVC) + cloudWater(:, :, :) = subcolHydro%mr_hydro(sunlit(:), :, :, I_CVCLIQ) + waterSize (:, :, :) = subcolHydro%reff (sunlit(:), :, :, I_CVCLIQ) + cloudIce (:, :, :) = subcolHydro%mr_hydro(sunlit(:), :, :, I_CVCICE) + iceSize (:, :, :) = subcolHydro%reff (sunlit(:), :, :, I_CVCICE) + end where + else +#endif + where(subCols%frac_out(sunlit(:), :, :) == I_LSC) + opticalThickness(:, :, :) = & + spread(gridBox%dtau_s (sunlit(:), :), dim = 2, nCopies = nSubCols) + cloudWater(:, :, :) = subcolHydro%mr_hydro(sunlit(:), :, :, I_LSCLIQ) + waterSize (:, :, :) = subcolHydro%reff (sunlit(:), :, :, I_LSCLIQ) + cloudIce (:, :, :) = subcolHydro%mr_hydro(sunlit(:), :, :, I_LSCICE) + iceSize (:, :, :) = subcolHydro%reff (sunlit(:), :, :, I_LSCICE) + elsewhere + opticalThickness(:, :, :) = 0. + cloudWater (:, :, :) = 0. + cloudIce (:, :, :) = 0. + waterSize (:, :, :) = 0. + iceSize (:, :, :) = 0. end where ! ! .. then add convective cloud ! where(subCols%frac_out(sunlit(:), :, :) == I_CVC) + opticalThickness(:, :, :) = & + spread(gridBox%dtau_c( sunlit(:), :), dim = 2, nCopies = nSubCols) cloudWater(:, :, :) = subcolHydro%mr_hydro(sunlit(:), :, :, I_CVCLIQ) waterSize (:, :, :) = subcolHydro%reff (sunlit(:), :, :, I_CVCLIQ) cloudIce (:, :, :) = subcolHydro%mr_hydro(sunlit(:), :, :, I_CVCICE) iceSize (:, :, :) = subcolHydro%reff (sunlit(:), :, :, I_CVCICE) end where +#ifdef COSP_GFDL + endif +#endif ! ! Reverse vertical order - ! Optical thickness need not be reversed when using subcolumn values ! +#ifdef COSP_GFDL + ! Optical thickness need not be reversed when using subcolumn values +#else + opticalThickness(:, :, :) = opticalThickness(:, :, nLevels:1:-1) +#endif cloudWater (:, :, :) = cloudWater (:, :, nLevels:1:-1) waterSize (:, :, :) = waterSize (:, :, nLevels:1:-1) cloudIce (:, :, :) = cloudIce (:, :, nLevels:1:-1) @@ -225,7 +323,7 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit modisSim%Cloud_Fraction_High_Mean(sunlit(:)) = cfHigh modisSim%Cloud_Fraction_Mid_Mean (sunlit(:)) = cfMid modisSim%Cloud_Fraction_Low_Mean (sunlit(:)) = cfLow - + modisSim%Optical_Thickness_Total_Mean(sunlit(:)) = meanTauTotal modisSim%Optical_Thickness_Water_Mean(sunlit(:)) = meanTauLiquid modisSim%Optical_Thickness_Ice_Mean (sunlit(:)) = meanTauIce @@ -242,12 +340,14 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit modisSim%Liquid_Water_Path_Mean(sunlit(:)) = meanLiquidWaterPath modisSim%Ice_Water_Path_Mean (sunlit(:)) = meanIceWaterPath +#ifdef COSP_GFDL modisSim%Column_Particle_Size(sunlit(:),:) = RetrievedSize(:,:) modisSim%retrievedPhase (sunlit(:),:) = RetrievedPhase(:,:) modisSim%Column_Optical_Thickness(sunlit(:),:) = RetrievedTau(:,:) modisSim%Column_Cloud_Top_Pressure(sunlit(:),:) = RetrievedCloudTopPressure(:,:) - modisSim%Optical_Thickness_vs_Cloud_Top_Pressure(sunlit(:), :, :) = jointHistogram(:, :, :) +#endif + modisSim%Optical_Thickness_vs_Cloud_Top_Pressure(sunlit(:), 2:numModisTauBins+1, :) = jointHistogram(:, :, :) ! ! Reorder pressure bins in joint histogram to go from surface to TOA ! @@ -280,12 +380,13 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit modisSim%Liquid_Water_Path_Mean(notSunlit(:)) = R_UNDEF modisSim%Ice_Water_Path_Mean (notSunlit(:)) = R_UNDEF +#ifdef COSP_GFDL + modisSim%Column_Particle_Size(notSunlit(:),:) = R_UNDEF + modisSim%retrievedPhase(notSunlit(:),:) = R_UNDEF + modisSim%Column_Optical_Thickness(notSunlit(:),:) = R_UNDEF + modisSim%Column_Cloud_Top_Pressure(notSunlit(:),:) = R_UNDEF +#endif - modisSim%Column_Particle_Size(notSunlit(:),:) = R_UNDEF - modisSim%retrievedPhase(notSunlit(:),:) = R_UNDEF - modisSim%Column_Optical_Thickness(notSunlit(:),:) = R_UNDEF - modisSim%Column_Cloud_Top_Pressure(notSunlit(:),:) = R_UNDEF - modisSim%Optical_Thickness_vs_Cloud_Top_Pressure(notSunlit(:), :, :) = R_UNDEF end if else @@ -316,32 +417,48 @@ subroutine COSP_Modis_Simulator(gridBox, subCols, subcolHydro, isccpSim, nSunlit modisSim%Liquid_Water_Path_Mean(:) = R_UNDEF modisSim%Ice_Water_Path_Mean (:) = R_UNDEF +#ifdef COSP_GFDL modisSim%Column_Particle_Size(:,:) = R_UNDEF modisSim%retrievedPhase (:,:) = R_UNDEF modisSim%Column_Optical_Thickness(:,:) = R_UNDEF modisSim%Column_Cloud_Top_Pressure(:,:) = R_UNDEF +#endif modisSim%Optical_Thickness_vs_Cloud_Top_Pressure(:, :, :) = R_UNDEF end if +#ifdef COSP_GFDL + deallocate (notSunlit) +#endif + end subroutine COSP_Modis_Simulator !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% !------------- SUBROUTINE CONSTRUCT_COSP_MODIS ------------------ !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef COSP_GFDL SUBROUTINE CONSTRUCT_COSP_MODIS(cfg, nPoints, nColumns, x) +#else + SUBROUTINE CONSTRUCT_COSP_MODIS(cfg, nPoints, x) +#endif type(cosp_config), intent(in) :: cfg ! Configuration options integer, intent(in) :: Npoints ! Number of sampled points +#ifdef COSP_GFDL integer, intent(in) :: Ncolumns ! Number of subgrid columns +#endif type(cosp_MODIS), intent(out) :: x ! ! Allocate minumum storage if simulator not used ! if (cfg%LMODIS_sim) then x%nPoints = nPoints +#ifdef COSP_GFDL x%nColumns = nColumns +#endif else x%Npoints = 1 +#ifdef COSP_GFDL x%Ncolumns = 1 +#endif endif ! --- Allocate arrays --- @@ -349,10 +466,10 @@ SUBROUTINE CONSTRUCT_COSP_MODIS(cfg, nPoints, nColumns, x) allocate(x%Cloud_Fraction_Water_Mean(x%nPoints)) allocate(x%Cloud_Fraction_Ice_Mean(x%nPoints)) - allocate(x%Cloud_Fraction_High_Mean(x%nPoints)) - allocate(x%Cloud_Fraction_Mid_Mean(x%nPoints)) - allocate(x%Cloud_Fraction_Low_Mean(x%nPoints)) - + allocate(x%Cloud_Fraction_High_Mean(x%nPoints)) + allocate(x%Cloud_Fraction_Mid_Mean(x%nPoints)) + allocate(x%Cloud_Fraction_Low_Mean(x%nPoints)) + allocate(x%Optical_Thickness_Total_Mean(x%nPoints)) allocate(x%Optical_Thickness_Water_Mean(x%nPoints)) allocate(x%Optical_Thickness_Ice_Mean(x%nPoints)) @@ -369,12 +486,14 @@ SUBROUTINE CONSTRUCT_COSP_MODIS(cfg, nPoints, nColumns, x) allocate(x%Liquid_Water_Path_Mean(x%nPoints)) allocate(x%Ice_Water_Path_Mean(x%nPoints)) +#ifdef COSP_GFDL allocate(x%Column_Particle_Size(x%nPoints,x%nColumns)) allocate(x%retrievedPhase (x%nPoints,x%nColumns)) allocate(x%Column_Optical_Thickness(x%nPoints,x%nColumns)) allocate(x%Column_Cloud_Top_Pressure(x%nPoints,x%nColumns)) - - allocate(x%Optical_Thickness_vs_Cloud_Top_Pressure(nPoints, numModisTauBins, numModisPressureBins)) +#endif + allocate(x%Optical_Thickness_vs_Cloud_Top_Pressure(nPoints, numModisTauBins+1, numModisPressureBins)) + x%Optical_Thickness_vs_Cloud_Top_Pressure(:, :, :) = R_UNDEF END SUBROUTINE CONSTRUCT_COSP_MODIS !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -390,10 +509,10 @@ SUBROUTINE FREE_COSP_MODIS(x) if(associated(x%Cloud_Fraction_Water_Mean)) deallocate(x%Cloud_Fraction_Water_Mean) if(associated(x%Cloud_Fraction_Ice_Mean )) deallocate(x%Cloud_Fraction_Ice_Mean) - if(associated(x%Cloud_Fraction_High_Mean)) deallocate(x%Cloud_Fraction_High_Mean) - if(associated(x%Cloud_Fraction_Mid_Mean )) deallocate(x%Cloud_Fraction_Mid_Mean) - if(associated(x%Cloud_Fraction_Low_Mean )) deallocate(x%Cloud_Fraction_Low_Mean) - + if(associated(x%Cloud_Fraction_High_Mean)) deallocate(x%Cloud_Fraction_High_Mean) + if(associated(x%Cloud_Fraction_Mid_Mean )) deallocate(x%Cloud_Fraction_Mid_Mean) + if(associated(x%Cloud_Fraction_Low_Mean )) deallocate(x%Cloud_Fraction_Low_Mean) + if(associated(x%Optical_Thickness_Total_Mean)) deallocate(x%Optical_Thickness_Total_Mean) if(associated(x%Optical_Thickness_Water_Mean)) deallocate(x%Optical_Thickness_Water_Mean) if(associated(x%Optical_Thickness_Ice_Mean )) deallocate(x%Optical_Thickness_Ice_Mean) @@ -410,10 +529,12 @@ SUBROUTINE FREE_COSP_MODIS(x) if(associated(x%Liquid_Water_Path_Mean)) deallocate(x%Liquid_Water_Path_Mean ) if(associated(x%Ice_Water_Path_Mean )) deallocate(x%Ice_Water_Path_Mean ) +#ifdef COSP_GFDL if(associated(x%Column_Particle_Size )) deallocate(x%Column_Particle_Size ) if(associated(x%retrievedPhase )) deallocate(x%retrievedPhase ) if(associated(x%Column_Optical_Thickness)) deallocate(x%Column_Optical_Thickness) if(associated(x%Column_Cloud_Top_Pressure)) deallocate(x%Column_Cloud_Top_Pressure ) +#endif if(associated(x%Optical_Thickness_vs_Cloud_Top_Pressure)) deallocate(x%Optical_Thickness_vs_Cloud_Top_Pressure ) END SUBROUTINE FREE_COSP_MODIS @@ -442,7 +563,7 @@ SUBROUTINE COSP_MODIS_CPSECTION(ix, iy, orig, copy) copy%Cloud_Fraction_High_Mean(copy_start:copy_end) = orig%Cloud_Fraction_High_Mean(orig_start:orig_end) copy%Cloud_Fraction_Mid_Mean (copy_start:copy_end) = orig%Cloud_Fraction_Mid_Mean (orig_start:orig_end) copy%Cloud_Fraction_Low_Mean (copy_start:copy_end) = orig%Cloud_Fraction_Low_Mean (orig_start:orig_end) - + copy%Optical_Thickness_Total_Mean(copy_start:copy_end) = orig%Optical_Thickness_Total_Mean(orig_start:orig_end) copy%Optical_Thickness_Water_Mean(copy_start:copy_end) = orig%Optical_Thickness_Water_Mean(orig_start:orig_end) copy%Optical_Thickness_Ice_Mean (copy_start:copy_end) = orig%Optical_Thickness_Ice_Mean (orig_start:orig_end) @@ -462,10 +583,12 @@ SUBROUTINE COSP_MODIS_CPSECTION(ix, iy, orig, copy) copy%Liquid_Water_Path_Mean(copy_start:copy_end) = orig%Liquid_Water_Path_Mean(orig_start:orig_end) copy%Ice_Water_Path_Mean (copy_start:copy_end) = orig%Ice_Water_Path_Mean (orig_start:orig_end) +#ifdef COSP_GFDL copy%Column_Particle_Size (copy_start:copy_end,:) = orig%Column_Particle_Size (orig_start:orig_end,:) copy%retrievedPhase (copy_start:copy_end,:) = orig%retrievedPhase (orig_start:orig_end,:) copy%Column_Optical_Thickness (copy_start:copy_end,:) = orig%Column_Optical_Thickness (orig_start:orig_end,:) copy%Column_Cloud_Top_Pressure (copy_start:copy_end,:) = orig%Column_Cloud_Top_Pressure (orig_start:orig_end,:) +#endif copy%Optical_Thickness_vs_Cloud_Top_Pressure(copy_start:copy_end, :, :) = & orig%Optical_Thickness_vs_Cloud_Top_Pressure(orig_start:orig_end, :, :) diff --git a/src/atmos_param/cosp/cosp_rttov_simulator.F90 b/src/atmos_param/cosp/cosp_rttov_simulator.F90 index 4189aa72fa..b5af770ab6 100644 --- a/src/atmos_param/cosp/cosp_rttov_simulator.F90 +++ b/src/atmos_param/cosp/cosp_rttov_simulator.F90 @@ -1,3 +1,15 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL + +!--------------------------------------------------------------------- +!------------ FMS version number and tagname for this file ----------- + +! $Id: cosp_rttov_simulator.F90,v 20.0 2013/12/13 23:15:49 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif + ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. ! @@ -29,10 +41,16 @@ ! +!#include "cosp_defs.h" +#ifndef COSP_GFDL #include "cosp_defs.h" +#endif MODULE MOD_COSP_RTTOV_SIMULATOR USE MOD_COSP_CONSTANTS USE MOD_COSP_TYPES +#ifdef RTTOV + USE MOD_COSP_RTTOV +#endif IMPLICIT NONE CONTAINS @@ -58,19 +76,19 @@ SUBROUTINE COSP_RTTOV_SIMULATOR(gbx,y) integer, parameter :: MaxLim = 100 ! Local variables - integer :: i,Nlevels,Npoints + integer :: Npoints real :: sh(gbx%Npoints, gbx%Nlevels) real :: pp(gbx%Npoints, gbx%Nlevels) real :: tt(gbx%Npoints, gbx%Nlevels) real :: o3(gbx%Npoints, gbx%Nlevels) - integer :: ichan(gbx%Nchan) real :: co2,ch4,n2o,co real :: tt_surf(gbx%Npoints) ! 1.5 m T real :: sh_surf(gbx%Npoints) ! 1.5 m q - integer :: nprof,nloop,rmod,il + integer :: nloop,rmod,il integer :: istart,istop - + integer :: nprof,nlevels + Nlevels = gbx%Nlevels Npoints = gbx%Npoints ! Reverting Levels from TOA to surface @@ -92,18 +110,6 @@ SUBROUTINE COSP_RTTOV_SIMULATOR(gbx,y) ch4 = ( Mdry / Mch4 ) * gbx%ch4 * 1e6 n2o = ( Mdry / Mn2o ) * gbx%n2o * 1e6 co = ( Mdry / Mco ) * gbx%co * 1e6 -! print *, 'COSP_RTTOV_SIMULATOR: B' -! print *, shape(gbx%ichan) -! print *, shape(gbx%surfem) -! print *, shape(pp) -! print *, shape(tt) -! print *, shape(sh) -! print *, shape(o3) -! print *, shape(gbx%sfc_height) -! print *, shape(gbx%u_wind) -! print *, shape(gbx%v_wind) -! print *, shape(gbx%land) -! print *, shape(y%tbs) !! RTTOV can handle only about 100 profiles at a time (FIXME: Check this with Roger) !! So we are putting a loop of 100 @@ -132,7 +138,7 @@ SUBROUTINE COSP_RTTOV_SIMULATOR(gbx,y) gbx%ichan, & gbx%surfem, & nprof, & - gbx%Nlevels, & + Nlevels, & gbx%Plat, & gbx%Sat, & gbx%Inst, & diff --git a/src/atmos_param/cosp/cosp_simulator.F90 b/src/atmos_param/cosp/cosp_simulator.F90 index 9dbcd85b5e..f633714499 100644 --- a/src/atmos_param/cosp/cosp_simulator.F90 +++ b/src/atmos_param/cosp/cosp_simulator.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: cosp_simulator.F90,v 19.0 2012/01/06 20:04:04 fms Exp $ -! $Name: siena_201207 $ +! $Id: cosp_simulator.F90,v 20.0 2013/12/13 23:15:51 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -35,7 +40,10 @@ ! ! -#include "cosp_defs.h" +!#include "cosp_defs.h" +#ifndef COSP_GFDL +#include "cosp_defs.h" +#endif MODULE MOD_COSP_SIMULATOR USE MOD_COSP_TYPES USE MOD_COSP_RADAR @@ -44,7 +52,7 @@ MODULE MOD_COSP_SIMULATOR USE MOD_COSP_MODIS_SIMULATOR USE MOD_COSP_MISR_SIMULATOR #ifdef RTTOV - USE MOD_COSP_RTTOV_SIMULATOR + USE MOD_COSP_RTTOV_SIMULATOR #endif USE MOD_COSP_STATS IMPLICIT NONE @@ -56,14 +64,17 @@ MODULE MOD_COSP_SIMULATOR !--------------------- SUBROUTINE COSP_SIMULATOR ------------------ !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef RTTOV -SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) +SUBROUTINE COSP_SIMULATOR(gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,rttov,stradar,stlidar) #else -SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) +SUBROUTINE COSP_SIMULATOR(gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,misr,modis,stradar,stlidar) #endif ! Arguments - integer, intent(in) :: me +#ifdef COSP_GFDL type(cosp_gridbox),intent(inout) :: gbx ! Grid-box inputs +#else + type(cosp_gridbox),intent(in) :: gbx ! Grid-box inputs +#endif type(cosp_subgrid),intent(in) :: sgx ! Subgrid inputs type(cosp_sghydro),intent(in) :: sghydro ! Subgrid info for hydrometeors type(cosp_config),intent(in) :: cfg ! Configuration options @@ -74,76 +85,84 @@ SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,mis type(cosp_misr),intent(inout) :: misr ! Output from MISR simulator type(cosp_modis),intent(inout) :: modis ! Output from MODIS simulator #ifdef RTTOV - type(cosp_rttov),intent(inout) :: rttov ! Output from RTTOV + type(cosp_rttov),intent(inout) :: rttov ! Output from RTTOV #endif type(cosp_radarstats),intent(inout) :: stradar ! Summary statistics from radar simulator type(cosp_lidarstats),intent(inout) :: stlidar ! Summary statistics from lidar simulator ! Local variables - integer :: i,j,k,nSunlit - ! ***Timing variables +#ifdef COSP_GFDL + integer :: i,j,k, nSunlit +#else + integer :: i,j,k +#endif + logical :: inconsistent + ! Timing variables integer :: t0,t1,count_rate,count_max - do k=1,gbx%Nhydro - do j=1,gbx%Nlevels - do i=1,gbx%Npoints - if ((gbx%mr_hydro(i,j,k)>0.0).and.(gbx%Reff(i,j,k)<=0.0)) then - print *, '%%%% COSP_SIMULATOR: inconsistency in ',i,j,k,' :',gbx%mr_hydro(i,j,k),gbx%Reff(i,j,k) - endif - enddo - enddo - enddo - + inconsistent=.false. +! do k=1,gbx%Nhydro +! do j=1,gbx%Nlevels +! do i=1,gbx%Npoints +! if ((gbx%mr_hydro(i,j,k)>0.0).and.(gbx%Reff(i,j,k)<=0.0)) inconsistent=.true. +! enddo +! enddo +! enddo + if (inconsistent) print *, '%%%% COSP_SIMULATOR: inconsistency in mr_hydro and Reff' + !+++++++++ Radar model ++++++++++ if (cfg%Lradar_sim) then -! call system_clock(t0,count_rate,count_max) - call cosp_radar(me, gbx,sgx,sghydro,sgradar) -! call system_clock(t1,count_rate,count_max) -! print *, '%%%%%% Radar:', (t1-t0)*1.0/count_rate, ' s' + !call system_clock(t0,count_rate,count_max) + call cosp_radar(gbx,sgx,sghydro,sgradar) + !call system_clock(t1,count_rate,count_max) + !print *, '%%%%%% Radar:', (t1-t0)*1.0/count_rate, ' s' endif !+++++++++ Lidar model ++++++++++ if (cfg%Llidar_sim) then -! call system_clock(t0,count_rate,count_max) + !call system_clock(t0,count_rate,count_max) call cosp_lidar(gbx,sgx,sghydro,sglidar) -! call system_clock(t1,count_rate,count_max) -! print *, '%%%%%% Lidar:', (t1-t0)*1.0/count_rate, ' s' + !call system_clock(t1,count_rate,count_max) + !print *, '%%%%%% Lidar:', (t1-t0)*1.0/count_rate, ' s' endif - !+++++++++ ISCCP simulator ++++++++++ if (cfg%Lisccp_sim) then -! call system_clock(t0,count_rate,count_max) + !call system_clock(t0,count_rate,count_max) call cosp_isccp_simulator(gbx,sgx,isccp) -! call system_clock(t1,count_rate,count_max) -! print *, '%%%%%% ISCCP:', (t1-t0)*1.0/count_rate, ' s' + !call system_clock(t1,count_rate,count_max) + !print *, '%%%%%% ISCCP:', (t1-t0)*1.0/count_rate, ' s' endif - + !+++++++++ MISR simulator ++++++++++ if (cfg%Lmisr_sim) then -! call system_clock(t0,count_rate,count_max) + !call system_clock(t0,count_rate,count_max) call cosp_misr_simulator(gbx,sgx,misr) -! call system_clock(t1,count_rate,count_max) -! print *, '%%%%%% MISR:', (t1-t0)*1.0/count_rate, ' s' + !call system_clock(t1,count_rate,count_max) + !print *, '%%%%%% MISR:', (t1-t0)*1.0/count_rate, ' s' endif !+++++++++ MODIS simulator ++++++++++ if (cfg%Lmodis_sim) then !call system_clock(t0,count_rate,count_max) +#ifdef COSP_GFDL nSunlit = count(gbx%sunlit(:) > 0) call cosp_modis_simulator(gbx,sgx,sghydro,isccp, nSunlit, modis) +#else + call cosp_modis_simulator(gbx,sgx,sghydro,isccp, modis) +#endif !call system_clock(t1,count_rate,count_max) !print *, '%%%%%% MODIS:', (t1-t0)*1.0/count_rate, ' s' endif - + !+++++++++ RTTOV ++++++++++ #ifdef RTTOV - if (cfg%Lrttov_sim) then + if (cfg%Lrttov_sim) then !call system_clock(t0,count_rate,count_max) - call cosp_rttov_simulator(gbx,rttov) + call cosp_rttov_simulator(gbx,rttov) !call system_clock(t1,count_rate,count_max) !print *, '%%%%%% RTTOV:', (t1-t0)*1.0/count_rate, ' s' - endif -#endif + endif +#endif !+++++++++++ Summary statistics +++++++++++ @@ -153,10 +172,10 @@ SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,mis !call system_clock(t1,count_rate,count_max) !print *, '%%%%%% Stats:', (t1-t0)*1.0/count_rate, ' s' endif - + !+++++++++++ Change of units after computation of statistics +++++++++++ ! This avoids using UDUNITS in CMOR - + ! if (cfg%Latb532) then ! where((sglidar%beta_tot > 0.0) .and. (sglidar%beta_tot /= R_UNDEF)) ! sglidar%beta_tot = log10(sglidar%beta_tot) @@ -164,7 +183,7 @@ SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,mis ! sglidar%beta_tot = R_UNDEF ! end where ! endif - + ! Cloud fractions from 1 to % if (cfg%Lclcalipso) then where(stlidar%lidarcld /= R_UNDEF) stlidar%lidarcld = stlidar%lidarcld*100.0 @@ -175,22 +194,22 @@ SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,mis if (cfg%Lclcalipso2) then where(stradar%lidar_only_freq_cloud /= R_UNDEF) stradar%lidar_only_freq_cloud = stradar%lidar_only_freq_cloud*100.0 endif - + if (cfg%Lcltisccp) then where(isccp%totalcldarea /= R_UNDEF) isccp%totalcldarea = isccp%totalcldarea*100.0 - endif + endif if (cfg%Lclisccp) then - where(isccp%fq_isccp /= R_UNDEF) isccp%fq_isccp = isccp%fq_isccp*100.0 + where(isccp%fq_isccp /= R_UNDEF) isccp%fq_isccp = isccp%fq_isccp*100.0 endif - + if (cfg%LclMISR) then where(misr%fq_MISR /= R_UNDEF) misr%fq_MISR = misr%fq_MISR*100.0 endif - + if (cfg%Lcltlidarradar) then where(stradar%radar_lidar_tcc /= R_UNDEF) stradar%radar_lidar_tcc = stradar%radar_lidar_tcc*100.0 endif - + if (cfg%Lclmodis) then where(modis%Optical_Thickness_vs_Cloud_Top_Pressure /= R_UNDEF) modis%Optical_Thickness_vs_Cloud_Top_Pressure = & modis%Optical_Thickness_vs_Cloud_Top_Pressure*100.0 @@ -204,7 +223,7 @@ SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,mis if (cfg%Lclimodis) then where(modis%Cloud_Fraction_Ice_Mean /= R_UNDEF) modis%Cloud_Fraction_Ice_Mean = modis%Cloud_Fraction_Ice_Mean*100.0 endif - + if (cfg%Lclhmodis) then where(modis%Cloud_Fraction_High_Mean /= R_UNDEF) modis%Cloud_Fraction_High_Mean = modis%Cloud_Fraction_High_Mean*100.0 endif @@ -214,15 +233,15 @@ SUBROUTINE COSP_SIMULATOR(me,gbx,sgx,sghydro,cfg,vgrid,sgradar,sglidar,isccp,mis if (cfg%Lcllmodis) then where(modis%Cloud_Fraction_Low_Mean /= R_UNDEF) modis%Cloud_Fraction_Low_Mean = modis%Cloud_Fraction_Low_Mean*100.0 endif - -! Change pressure from hPa to Pa. + + ! Change pressure from hPa to Pa. if (cfg%Lboxptopisccp) then where(isccp%boxptop /= R_UNDEF) isccp%boxptop = isccp%boxptop*100.0 endif if (cfg%Lpctisccp) then where(isccp%meanptop /= R_UNDEF) isccp%meanptop = isccp%meanptop*100.0 endif - + END SUBROUTINE COSP_SIMULATOR diff --git a/src/atmos_param/cosp/cosp_stats.f90 b/src/atmos_param/cosp/cosp_stats.F90 similarity index 75% rename from src/atmos_param/cosp/cosp_stats.f90 rename to src/atmos_param/cosp/cosp_stats.F90 index ae4cf30e14..5437a95485 100644 --- a/src/atmos_param/cosp/cosp_stats.f90 +++ b/src/atmos_param/cosp/cosp_stats.F90 @@ -1,32 +1,37 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: cosp_stats.f90,v 19.0 2012/01/06 20:04:06 fms Exp $ -! $Name: siena_201207 $ +! $Id: cosp_stats.F90,v 20.0 2013/12/13 23:15:52 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. -! -! Redistribution and use in source and binary forms, with or without modification, are permitted +! +! Redistribution and use in source and binary forms, with or without modification, are permitted ! provided that the following conditions are met: -! -! * Redistributions of source code must retain the above copyright notice, this list +! +! * Redistributions of source code must retain the above copyright notice, this list ! of conditions and the following disclaimer. ! * Redistributions in binary form must reproduce the above copyright notice, this list -! of conditions and the following disclaimer in the documentation and/or other materials +! of conditions and the following disclaimer in the documentation and/or other materials ! provided with the distribution. -! * Neither the name of the Met Office nor the names of its contributors may be used -! to endorse or promote products derived from this software without specific prior written +! * Neither the name of the Met Office nor the names of its contributors may be used +! to endorse or promote products derived from this software without specific prior written ! permission. -! -! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ! OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! @@ -35,8 +40,13 @@ ! Jul 2008 - A. Bodas-Salcedo - Added capability of producing outputs in standard grid ! Oct 2008 - J.-L. Dufresne - Bug fixed. Assignment of Npoints,Nlevels,Nhydro,Ncolumns in COSP_STATS ! Oct 2008 - H. Chepfer - Added PARASOL reflectance arguments +! Jun 2010 - T. Yokohata, T. Nishimura and K. Ogochi - Added NEC SXs optimisations ! -! +! +!#include "cosp_defs.h" +#ifndef COSP_GFDL +#include "cosp_defs.h" +#endif MODULE MOD_COSP_STATS USE MOD_COSP_CONSTANTS USE MOD_COSP_TYPES @@ -50,7 +60,7 @@ MODULE MOD_COSP_STATS !------------------- SUBROUTINE COSP_STATS ------------------------ !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SUBROUTINE COSP_STATS(gbx,sgx,cfg,sgradar,sglidar,vgrid,stradar,stlidar) - + ! Input arguments type(cosp_gridbox),intent(in) :: gbx type(cosp_subgrid),intent(in) :: sgx @@ -60,9 +70,9 @@ SUBROUTINE COSP_STATS(gbx,sgx,cfg,sgradar,sglidar,vgrid,stradar,stlidar) type(cosp_vgrid),intent(in) :: vgrid ! Output arguments type(cosp_radarstats),intent(inout) :: stradar ! Summary statistics for radar - type(cosp_lidarstats),intent(inout) :: stlidar ! Summary statistics for lidar - - ! Local variables + type(cosp_lidarstats),intent(inout) :: stlidar ! Summary statistics for lidar + + ! Local variables integer :: Npoints !# of grid points integer :: Nlevels !# of levels integer :: Nhydro !# of hydrometeors @@ -71,14 +81,14 @@ SUBROUTINE COSP_STATS(gbx,sgx,cfg,sgradar,sglidar,vgrid,stradar,stlidar) logical :: ok_lidar_cfad = .false. real,dimension(:,:,:),allocatable :: Ze_out,betatot_out,betamol_in,betamol_out,ph_in,ph_out real,dimension(:,:),allocatable :: ph_c,betamol_c - + Npoints = gbx%Npoints Nlevels = gbx%Nlevels Nhydro = gbx%Nhydro Ncolumns = gbx%Ncolumns Nlr = vgrid%Nlvgrid - - if (cfg%LcfadLidarsr532) ok_lidar_cfad=.true. + + if (cfg%LcfadLidarsr532) ok_lidar_cfad=.true. if (vgrid%use_vgrid) then ! Statistics in a different vertical grid allocate(Ze_out(Npoints,Ncolumns,Nlr),betatot_out(Npoints,Ncolumns,Nlr), & @@ -119,7 +129,7 @@ SUBROUTINE COSP_STATS(gbx,sgx,cfg,sgradar,sglidar,vgrid,stradar,stlidar) !++++++++++++ Lidar-only cloud amount and lidar&radar total cloud mount ++++++++++++++++ if (cfg%Lradar_sim.and.cfg%Llidar_sim) call cosp_lidar_only_cloud(Npoints,Ncolumns,Nlr, & betatot_out,betamol_c,Ze_out, & - stradar%lidar_only_freq_cloud,stradar%radar_lidar_tcc) + stradar%lidar_only_freq_cloud,stradar%radar_lidar_tcc) ! Deallocate arrays at coarse resolution deallocate(Ze_out,betatot_out,betamol_in,betamol_out,betamol_c,ph_in,ph_out,ph_c) else ! Statistics in model levels @@ -136,13 +146,13 @@ SUBROUTINE COSP_STATS(gbx,sgx,cfg,sgradar,sglidar,vgrid,stradar,stlidar) !++++++++++++ Lidar-only cloud amount and lidar&radar total cloud mount ++++++++++++++++ if (cfg%Lradar_sim.and.cfg%Llidar_sim) call cosp_lidar_only_cloud(Npoints,Ncolumns,Nlr, & sglidar%beta_tot,sglidar%beta_mol,sgradar%Ze_tot, & - stradar%lidar_only_freq_cloud,stradar%radar_lidar_tcc) + stradar%lidar_only_freq_cloud,stradar%radar_lidar_tcc) endif ! Replace undef - where (stlidar%cfad_sr == LIDAR_UNDEF) stlidar%cfad_sr = R_UNDEF - where (stlidar%lidarcld == LIDAR_UNDEF) stlidar%lidarcld = R_UNDEF - where (stlidar%cldlayer == LIDAR_UNDEF) stlidar%cldlayer = R_UNDEF - where (stlidar%parasolrefl == LIDAR_UNDEF) stlidar%parasolrefl = R_UNDEF + where (stlidar%cfad_sr == LIDAR_UNDEF) stlidar%cfad_sr = R_UNDEF + where (stlidar%lidarcld == LIDAR_UNDEF) stlidar%lidarcld = R_UNDEF + where (stlidar%cldlayer == LIDAR_UNDEF) stlidar%cldlayer = R_UNDEF + where (stlidar%parasolrefl == LIDAR_UNDEF) stlidar%parasolrefl = R_UNDEF END SUBROUTINE COSP_STATS @@ -169,6 +179,13 @@ SUBROUTINE COSP_CHANGE_VERTICAL_GRID(Npoints,Ncolumns,Nlevels,zfull,zhalf,y,M,zl ! Local variables integer :: i,j,k logical :: lunits +#ifdef SYS_SX + integer :: l + real,dimension(Npoints) :: ws,sumwyp + real,dimension(Npoints,Nlevels) :: xl,xu + real,dimension(Npoints,Nlevels) :: w + real,dimension(Npoints,Ncolumns,Nlevels) :: yp +#else real :: ws real,dimension(Nlevels) :: xl,xu ! Lower and upper boundaries of model grid real,dimension(M) :: dz ! Layer depth @@ -176,10 +193,86 @@ SUBROUTINE COSP_CHANGE_VERTICAL_GRID(Npoints,Ncolumns,Nlevels,zfull,zhalf,y,M,zl real,dimension(Ncolumns,Nlevels) :: yp ! Variable to be changed to a different grid. ! Local copy at a particular point. ! This allows for change of units. - +#endif + lunits=.false. if (present(log_units)) lunits=log_units - + +#ifdef SYS_SX + r(:,:,:) = R_GROUND + ! Vertical grid at that point + xl(:,:) = zhalf(:,:) + xu(:,1:Nlevels-1) = xl(:,2:Nlevels) + xu(:,Nlevels) = zfull(:,Nlevels) + zfull(:,Nlevels) - zhalf(:,Nlevels) ! Top level symmetric + yp(:,:,:) = y(:,:,:) ! Temporary variable to regrid + ! Check for dBZ and change if necessary + if (lunits) then + where (y /= R_UNDEF) + yp = 10.0**(y/10.0) + elsewhere + yp = 0.0 + end where + endif + do k=1,M + ! Find weights + w(:,:) = 0.0 + do j=1,Nlevels + do i=1,Npoints + if ((xl(i,j) < zl(k)).and.(xu(i,j) > zl(k)).and.(xu(i,j) <= zu(k))) then + !xl(j)-----------------xu(j) + ! zl(k)------------------------------zu(k) + w(i,j) = xu(i,j) - zl(k) + else if ((xl(i,j) >= zl(k)).and.(xu(i,j) <= zu(k))) then + ! xl(j)-----------------xu(j) + ! zl(k)------------------------------zu(k) + w(i,j) = xu(i,j) - xl(i,j) + else if ((xl(i,j) >= zl(k)).and.(xl(i,j) < zu(k)).and.(xu(i,j) >= zu(k))) then + ! xl(j)-----------------xu(j) + ! zl(k)------------------------------zu(k) + w(i,j) = zu(k) - xl(i,j) + else if ((xl(i,j) <= zl(k)).and.(xu(i,j) >= zu(k))) then + ! xl(j)---------------------------xu(j) + ! zl(k)--------------zu(k) + w(i,j) = zu(k) - zl(k) + endif + enddo + enddo + ! Do the weighted mean + do j=1,Ncolumns + ws (:) = 0.0 + sumwyp(:) = 0.0 + do l=1,Nlevels + do i=1,Npoints + if (zu(k) > zhalf(i,1)) then ! Level above model bottom level + ws (i) = ws (i) + w(i,l) + sumwyp(i) = sumwyp(i) + w(i,l)*yp(i,j,l) + endif + enddo + enddo + do i=1,Npoints + if (zu(k) > zhalf(i,1)) then ! Level above model bottom level + if (ws(i) > 0.0) r(i,j,k) = sumwyp(i)/ws(i) + endif + enddo + enddo + enddo + ! Check for dBZ and change if necessary + if (lunits) then + do k=1,M + do j=1,Ncolumns + do i=1,Npoints + if (zu(k) > zhalf(i,1)) then ! Level above model bottom level + if (r(i,j,k) <= 0.0) then + r(i,j,k) = R_UNDEF + else + r(i,j,k) = 10.0*log10(r(i,j,k)) + endif + endif + enddo + enddo + enddo + endif +#else r = R_UNDEF do i=1,Npoints ! Vertical grid at that point @@ -226,7 +319,7 @@ SUBROUTINE COSP_CHANGE_VERTICAL_GRID(Npoints,Ncolumns,Nlevels,zfull,zhalf,y,M,zl r(i,j,k) = R_GROUND else ws = sum(w(:,k)) - if ((ws > 0.0).and.(r(i,j,k) /= R_GROUND)) r(i,j,k) = sum(w(:,k) *yp(j,:))/ws + if ((ws > 0.0).and.(r(i,j,k) /= R_GROUND)) r(i,j,k) = sum(w(:,k)*yp(j,:))/ws ! Check for dBZ and change if necessary if ((lunits).and.(r(i,j,k) /= R_GROUND)) then if (r(i,j,k) <= 0.0) then @@ -239,9 +332,10 @@ SUBROUTINE COSP_CHANGE_VERTICAL_GRID(Npoints,Ncolumns,Nlevels,zfull,zhalf,y,M,zl enddo enddo enddo - - - -END SUBROUTINE COSP_CHANGE_VERTICAL_GRID +#endif + + + +END SUBROUTINE COSP_CHANGE_VERTICAL_GRID END MODULE MOD_COSP_STATS diff --git a/src/atmos_param/cosp/cosp_types.f90 b/src/atmos_param/cosp/cosp_types.F90 similarity index 93% rename from src/atmos_param/cosp/cosp_types.f90 rename to src/atmos_param/cosp/cosp_types.F90 index 071e81a6e4..a44e6c7375 100644 --- a/src/atmos_param/cosp/cosp_types.f90 +++ b/src/atmos_param/cosp/cosp_types.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: cosp_types.f90,v 19.0 2012/01/06 20:04:08 fms Exp $ -! $Name: siena_201207 $ + +! $Id: cosp_types.F90,v 20.0 2013/12/13 23:15:53 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -42,7 +47,7 @@ MODULE MOD_COSP_TYPES USE MOD_COSP_CONSTANTS USE MOD_COSP_UTILS - use radar_simulator_types, only: class_param, mie, nd, mt_nd, dmax, dmin, mt_ttl, mt_tti, cnt_liq, cnt_ice ! added by roj Feb 2008 + use radar_simulator_types, only: class_param, mie, nd, mt_nd, dmax, dmin, mt_ttl, mt_tti, cnt_liq, cnt_ice ! added by roj Feb 2008 IMPLICIT NONE @@ -53,10 +58,10 @@ MODULE MOD_COSP_TYPES ! Configuration choices (simulators, variables) TYPE COSP_CONFIG logical :: Lradar_sim,Llidar_sim,Lisccp_sim,Lmodis_sim,Lmisr_sim,Lrttov_sim,Lstats,Lwrite_output, & - Lalbisccp,Latb532,Lboxptopisccp,Lboxtauisccp,Lcfaddbze94, & + Lalbisccp,Latb532,Lboxptopisccp,Lboxtauisccp,LcfadDbze94, & LcfadLidarsr532,Lclcalipso2,Lclcalipso,Lclhcalipso,Lclisccp,Lcllcalipso, & Lclmcalipso,Lcltcalipso,Lcltlidarradar,Lpctisccp,Ldbze94,Ltauisccp,Lcltisccp, & - Llongitude,Llatitude,LparasolRefl,LclMISR,Lmeantbisccp,Lmeantbclrisccp, & + Ltoffset,LparasolRefl,LclMISR,Lmeantbisccp,Lmeantbclrisccp, & Lfracout,LlidarBetaMol532,Ltbrttov, & Lcltmodis,Lclwmodis,Lclimodis,Lclhmodis,Lclmmodis,Lcllmodis,Ltautmodis,Ltauwmodis,Ltauimodis,Ltautlogmodis, & Ltauwlogmodis,Ltauilogmodis,Lreffclwmodis,Lreffclimodis,Lpctmodis,Llwpmodis, & @@ -207,7 +212,7 @@ MODULE MOD_COSP_TYPES ! Arrays with dimensions (Npoints,Nlevels) real, dimension(:,:),pointer :: lidarcld ! 3D "lidar" cloud fraction ! Arrays with dimensions (Npoints,LIDAR_NCAT) - real, dimension(:,:),pointer :: cldlayer ! low, mid, high-level lidar cloud cover + real, dimension(:,:),pointer :: cldlayer ! low, mid, high-level, total lidar cloud cover ! Arrays with dimensions (Npoints,PARASOL_NREFL) real, dimension(:,:),pointer :: parasolrefl ! mean parasol reflectance @@ -222,12 +227,16 @@ MODULE MOD_COSP_TYPES integer :: Ncolumns ! Number of columns integer :: Nlevels ! Number of levels integer :: Nhydro ! Number of hydrometeors +#ifdef COSP_GFDL logical :: cols_input_from_model ! is column data input from model ? +#endif real,dimension(:,:,:),pointer :: prec_frac ! Subgrid precip array. Dimensions (Npoints,Ncolumns,Nlevels) real,dimension(:,:,:),pointer :: frac_out ! Subgrid cloud array. Dimensions (Npoints,Ncolumns,Nlevels) +#ifdef COSP_GFDL real,dimension(:,:,:),pointer :: dtau_col ! Subgrid tau array. Dimensions (Npoints,Ncolumns,Nlevels) real,dimension(:,:,:),pointer :: dem_col ! Subgrid emiss array. Dimensions (Npoints,Ncolumns,Nlevels) +#endif END TYPE COSP_SUBGRID ! Input data for simulator at Subgrid scale. @@ -265,15 +274,15 @@ MODULE MOD_COSP_TYPES real :: radar_freq, & ! Radar frequency [GHz] k2 ! |K|^2, -1=use frequency dependent default integer :: surface_radar, & ! surface=1, spaceborne=0 - use_mie_tables, & ! use a precomputed loopup table? yes=1,no=0 - use_gas_abs, & ! include gaseous absorption? yes=1,no=0 - do_ray, & ! calculate/output Rayleigh refl=1, not=0 - melt_lay ! melting layer model off=0, on=1 + use_mie_tables, & ! use a precomputed loopup table? yes=1,no=0 + use_gas_abs, & ! include gaseous absorption? yes=1,no=0 + do_ray, & ! calculate/output Rayleigh refl=1, not=0 + melt_lay ! melting layer model off=0, on=1 ! structures used by radar simulator that need to be set only ONCE per radar configuration (e.g. freq, pointing direction) ... added by roj Feb 2008 - type(class_param) :: hp ! structure used by radar simulator to store Ze and N scaling constants and other information - type(mie):: mt ! structure used by radar simulator to store mie LUT information - integer :: nsizes ! number of discrete drop sizes (um) used to represent the distribution + type(class_param) :: hp ! structure used by radar simulator to store Ze and N scaling constants and other information + type(mie):: mt ! structure used by radar simulator to store mie LUT information + integer :: nsizes ! number of discrete drop sizes (um) used to represent the distribution real*8, dimension(:), pointer :: D ! array of discrete drop sizes (um) used to represent the distribution real*8, dimension(:), pointer :: mt_ttl, mt_tti ! array of temperatures used with Ze_scaling (also build into mie LUT) @@ -286,6 +295,7 @@ MODULE MOD_COSP_TYPES logical :: use_reff ! True if Reff is to be used by radar ! Geolocation (Npoints) + real,dimension(:),pointer :: toffset ! Time offset of esch point from the value in time real,dimension(:),pointer :: longitude ! longitude [degrees East] real,dimension(:),pointer :: latitude ! latitude [deg North] ! Gridbox information (Npoints,Nlevels) @@ -546,7 +556,7 @@ SUBROUTINE CONSTRUCT_COSP_VGRID(gbx,Nlvgrid,use_vgrid,cloudsat,x) ! --- Model vertical levels --- ! Use height levels of first model gridbox - x%mz = gbx%zlev(1,:) + x%mz =gbx%zlev(1,:) x%mzl = gbx%zlev_half(1,:) x%mzu(1:x%Nlevels-1) = gbx%zlev_half(1,2:x%Nlevels) x%mzu(x%Nlevels) = gbx%zlev(1,x%Nlevels) + (gbx%zlev(1,x%Nlevels) - x%mzl(x%Nlevels)) @@ -816,8 +826,10 @@ SUBROUTINE CONSTRUCT_COSP_SUBGRID(Npoints,Ncolumns,Nlevels,y) ! --- Allocate arrays --- allocate(y%frac_out(Npoints,Ncolumns,Nlevels)) +#ifdef COSP_GFDL allocate (y%dtau_col(Npoints,Ncolumns,Nlevels), & y%dem_col(Npoints,Ncolumns,Nlevels) ) +#endif if (Ncolumns > 1) then allocate(y%prec_frac(Npoints,Ncolumns,Nlevels)) else ! CRM mode, not needed @@ -826,8 +838,10 @@ SUBROUTINE CONSTRUCT_COSP_SUBGRID(Npoints,Ncolumns,Nlevels,y) ! --- Initialise to zero --- y%prec_frac = 0.0 y%frac_out = 0.0 +#ifdef COSP_GFDL y%dtau_col = 0.0 y%dem_col = 0.0 +#endif ! The following line gives a compilation error on the Met Office NEC ! call zero_real(y%mr_hydro) ! f90: error(666): cosp_types.f90, line nnn: @@ -845,7 +859,11 @@ SUBROUTINE FREE_COSP_SUBGRID(y) type(cosp_subgrid),intent(inout) :: y ! --- Deallocate arrays --- +#ifdef COSP_GFDL deallocate(y%prec_frac, y%frac_out, y%dtau_col, y%dem_col) +#else + deallocate(y%prec_frac, y%frac_out) +#endif END SUBROUTINE FREE_COSP_SUBGRID @@ -896,7 +914,7 @@ SUBROUTINE CONSTRUCT_COSP_GRIDBOX(time,time_bnds,radar_freq,surface_radar,use_mi Plat,Sat,Inst,Nchan,ZenAng,Ichan,SurfEm,co2,ch4,n2o,co,& y) double precision,intent(in) :: time ! Time since start of run [days] - double precision, intent(in) :: time_bnds(2) ! Time boundaries + double precision,intent(in) :: time_bnds(2) ! Time boundaries real,intent(in) :: radar_freq, & ! Radar frequency [GHz] k2 ! |K|^2, -1=use frequency dependent default integer,intent(in) :: & @@ -931,9 +949,7 @@ SUBROUTINE CONSTRUCT_COSP_GRIDBOX(time,time_bnds,radar_freq,surface_radar,use_mi ! local variables -! integer i, cnt_ice, cnt_liq - integer i - character*200 :: mie_table_name ! Mie table name + integer i, cnt_ice, cnt_liq real*8 :: delt, deltp ! Dimensions and scalars @@ -960,7 +976,7 @@ SUBROUTINE CONSTRUCT_COSP_GRIDBOX(time,time_bnds,radar_freq,surface_radar,use_mi y%use_precipitation_fluxes = use_precipitation_fluxes y%use_reff = use_reff - y%time = time + y%time = time y%time_bnds = time_bnds ! RTTOV parameters @@ -987,7 +1003,7 @@ SUBROUTINE CONSTRUCT_COSP_GRIDBOX(time,time_bnds,radar_freq,surface_radar,use_mi ! Surface information and geolocation (Npoints) - allocate(y%longitude(Npoints),y%latitude(Npoints),y%psfc(Npoints), y%land(Npoints), & + allocate(y%toffset(Npoints), y%longitude(Npoints),y%latitude(Npoints),y%psfc(Npoints), y%land(Npoints), & y%sunlit(Npoints),y%skt(Npoints),y%sfc_height(Npoints),y%u_wind(Npoints),y%v_wind(Npoints)) ! Hydrometeors concentration and distribution parameters allocate(y%mr_hydro(Npoints,Nlevels,Nhydro), & @@ -1032,6 +1048,7 @@ SUBROUTINE CONSTRUCT_COSP_GRIDBOX(time,time_bnds,radar_freq,surface_radar,use_mi ! (Npoints) ! call zero_real(y%psfc, y%land) + y%toffset = 0.0 y%longitude = 0.0 y%latitude = 0.0 y%psfc = 0.0 @@ -1097,37 +1114,36 @@ SUBROUTINE CONSTRUCT_COSP_GRIDBOX(time,time_bnds,radar_freq,surface_radar,use_mi ! load mie tables ? if (y%use_mie_tables == 1) then -! This problem taken care of in cosp_driver prior to this call -! print *, '%%% COSP: Mie tables option for Quickbem not supported' -! stop -! ! ----- Mie tables ---- -! mie_table_name='mie_table.dat' -! call load_mie_table(mie_table_name,y%mt) -! -! ! :: D specified by table ... not must match that used when mie LUT generated! -! y%nsizes = mt_nd -! allocate(y%D(y%nsizes)) -! y%D = y%mt%D + print *, '%%% COSP: Mie tables option for Quickbem not supported' + stop +! ! ----- Mie tables ---- +! mie_table_name='mie_table.dat' +! call load_mie_table(mie_table_name,y%mt) +! +! ! :: D specified by table ... not must match that used when mie LUT generated! +! y%nsizes = mt_nd +! allocate(y%D(y%nsizes)) +! y%D = y%mt%D else - ! otherwise we still need to initialize temperature arrays for Ze scaling (which is only done when not using mie table) - -! cnt_ice=19 -! cnt_liq=20 -! if (.not.(allocated(mt_ttl).and.allocated(mt_tti))) then -! allocate(mt_ttl(cnt_liq),mt_tti(cnt_ice)) ! note needed as this is global array ... - ! which should be changed in the future -! endif - -! do i=1,cnt_ice -! mt_tti(i)=(i-1)*5-90 -! enddo - -! do i=1,cnt_liq -! mt_ttl(i)=(i-1)*5 - 60 -! enddo - - allocate(y%mt_ttl(cnt_liq),y%mt_tti(cnt_ice)) + ! otherwise we still need to initialize temperature arrays for Ze scaling (which is only done when not using mie table) + + cnt_ice=19 + cnt_liq=20 +! if (.not.(allocated(mt_ttl).and.allocated(mt_tti))) then +! allocate(mt_ttl(cnt_liq),mt_tti(cnt_ice)) ! note needed as this is global array ... +! ! which should be changed in the future +! endif + + do i=1,cnt_ice + mt_tti(i)=(i-1)*5-90 + enddo + + do i=1,cnt_liq + mt_ttl(i)=(i-1)*5 - 60 + enddo + + allocate(y%mt_ttl(cnt_liq),y%mt_tti(cnt_ice)) y%mt_ttl = mt_ttl y%mt_tti = mt_tti @@ -1165,8 +1181,8 @@ SUBROUTINE FREE_COSP_GRIDBOX(y,dglobal) logical,intent(in),optional :: dglobal ! --- Free arrays --- - deallocate(y%D,y%mt_ttl,y%mt_tti) ! added by roj Feb 2008 -! if (.not.present(dglobal)) deallocate(mt_ttl,mt_tti) + deallocate(y%D,y%mt_ttl,y%mt_tti) ! added by roj Feb 2008 +! if (.not.present(dglobal)) deallocate(mt_ttl,mt_tti) ! deallocate(y%hp%p1,y%hp%p2,y%hp%p3,y%hp%dmin,y%hp%dmax,y%hp%apm,y%hp%bpm,y%hp%rho, & ! y%hp%dtype,y%hp%col,y%hp%cp,y%hp%phase,y%hp%scaled, & @@ -1176,7 +1192,7 @@ SUBROUTINE FREE_COSP_GRIDBOX(y,dglobal) deallocate(y%zlev, y%zlev_half, y%dlev, y%p, y%ph, y%T, y%q, & y%sh, y%dtau_s, y%dtau_c, y%dem_s, y%dem_c, & - y%longitude,y%latitude,y%psfc, y%land, y%tca, y%cca, & + y%toffset, y%longitude,y%latitude,y%psfc, y%land, y%tca, y%cca, & y%mr_hydro, y%dist_prmts_hydro, & y%conc_aero, y%dist_type_aero, y%dist_prmts_aero, & y%rain_ls, y%rain_cv, y%snow_ls, y%snow_cv, y%grpl_ls, & @@ -1237,8 +1253,6 @@ SUBROUTINE COSP_GRIDBOX_CPSECTION(ix,iy,x,y) type(cosp_gridbox),intent(in) :: x type(cosp_gridbox),intent(inout) :: y - integer :: i,j,k,sz(3) - ! --- Copy arrays without Npoints as dimension --- y%dist_prmts_hydro = x%dist_prmts_hydro y%dist_type_aero = x%dist_type_aero @@ -1425,15 +1439,15 @@ SUBROUTINE COSP_GRIDBOX_PRINT(x) print *, x%radar_freq, & x%k2 print *, x%surface_radar, & - x%use_mie_tables, & - x%use_gas_abs, & - x%do_ray, & - x%melt_lay + x%use_mie_tables, & + x%use_gas_abs, & + x%do_ray, & + x%melt_lay ! print *, 'shape(x%): ',shape(x%) -! type(class_param) :: hp ! structure used by radar simulator to store Ze and N scaling constants and other information -! type(mie):: mt ! structure used by radar simulator to store mie LUT information +! type(class_param) :: hp ! structure used by radar simulator to store Ze and N scaling constants and other information +! type(mie):: mt ! structure used by radar simulator to store mie LUT information print *, x%nsizes print *, 'shape(x%D): ',shape(x%D) print *, 'shape(x%mt_ttl): ',shape(x%mt_ttl) @@ -1667,5 +1681,4 @@ SUBROUTINE COSP_SGHYDRO_PRINT(x) print *, 'shape(x%Reff): ',shape(x%Reff) END SUBROUTINE COSP_SGHYDRO_PRINT - END MODULE MOD_COSP_TYPES diff --git a/src/atmos_param/cosp/cosp_utils.f90 b/src/atmos_param/cosp/cosp_utils.F90 similarity index 72% rename from src/atmos_param/cosp/cosp_utils.f90 rename to src/atmos_param/cosp/cosp_utils.F90 index 15fd0e64ed..4102e63695 100644 --- a/src/atmos_param/cosp/cosp_utils.f90 +++ b/src/atmos_param/cosp/cosp_utils.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: cosp_utils.f90,v 19.0 2012/01/06 20:04:10 fms Exp $ -! $Name: siena_201207 $ +! $Id: cosp_utils.F90,v 20.0 2013/12/13 23:15:54 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -45,71 +50,61 @@ MODULE MOD_COSP_UTILS INTERFACE COSP_CHECK_INPUT MODULE PROCEDURE COSP_CHECK_INPUT_1D,COSP_CHECK_INPUT_2D,COSP_CHECK_INPUT_3D END INTERFACE +#ifdef COSP_GFDL + INTERFACE flip_vert_index + MODULE PROCEDURE flip_vert_index_2d, flip_vert_index_3d, & + flip_vert_index_4d + END INTERFACE +#endif CONTAINS +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +!------------------- SUBROUTINE COSP_PRECIP_MXRATIO -------------- +!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SUBROUTINE COSP_PRECIP_MXRATIO(Npoints,Nlevels,Ncolumns,p,T,prec_frac,prec_type, & + n_ax,n_bx,alpha_x,c_x,d_x,g_x,a_x,b_x,gamma1,gamma2,gamma3,gamma4, & + flux,mxratio,reff) + + ! Input arguments, (IN) + integer,intent(in) :: Npoints,Nlevels,Ncolumns + real,intent(in),dimension(Npoints,Nlevels) :: p,T,flux + real,intent(in),dimension(Npoints,Ncolumns,Nlevels) :: prec_frac + real,intent(in) :: n_ax,n_bx,alpha_x,c_x,d_x,g_x,a_x,b_x,gamma1,gamma2,gamma3,gamma4,prec_type + ! Input arguments, (OUT) + real,intent(out),dimension(Npoints,Ncolumns,Nlevels) :: mxratio + real,intent(inout),dimension(Npoints,Ncolumns,Nlevels) :: reff + ! Local variables + integer :: i,j,k + real :: sigma,one_over_xip1,xi,rho0,rho,lambda_x,gamma_4_3_2,delta + + mxratio = 0.0 -! ! FUNCTION GAMMA(Y) -! ! real,intent(in) :: y -! ! integer :: i,m -! ! real gg,g,pare,x -! ! real :: gamma -! ! -! ! gg=1. -! ! m=y -! ! x=y-m -! ! if (m /= 1) then -! ! do i=1,m-1 -! ! g=y-i -! ! gg=gg*g -! ! end do -! ! end if -! ! pare=-0.5748646*x+0.9512363*x*x-0.6998588*x*x*x & -! ! +0.4245549*x*x*x*x-0.1010678*x*x*x*x*x+1. -! ! gamma=pare*gg -! ! -! ! END FUNCTION GAMMA - -! ! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! ! !------------------- SUBROUTINE COSP_PRECIP_MXRATIO -------------- -! ! !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! ! SUBROUTINE COSP_PRECIP_MXRATIO(Npoints,Nlevels,Ncolumns,rho,prec_frac,prec_type, & -! ! n_ax,n_bx,alpha_x,lambda_x,c_x,d_x,g_x,a_x,b_x, & -! ! flux,mxratio) -! ! -! ! ! Input arguments, (IN) -! ! integer,intent(in) :: Npoints,Nlevels,Ncolumns,Nprecip -! ! real,intent(in),dimension(Npoints,Nlevels) :: rho,flux -! ! real,intent(in),dimension(Npoints,Ncolumns,Nlevels) :: prec_frac -! ! real,intent(in) :: n_ax,n_bx,alpha_x,lambda_x, & -! ! c_x,d_x,g_x,a_x,b_x,prec_type -! ! ! Input arguments, (OUT) -! ! real,intent(out),dimension(Npoints,Ncolumns,Nlevels),mxratio -! ! ! Local variables -! ! integer :: i,j,k -! ! real :: gamma1,gamma2,sigma,one_over_xip1 -! ! real :: ,dimension(Npoints,Nlevels) :: rho -! ! -! ! gamma1 = gamma(alpha_x + b_x + d_x + 1.0) -! ! gamma2 = gamma(alpha_x + b_x + 1.0) -! ! xi = 1.0/(alpha_x + b_x + d_x - n_bx + 1.0) -! ! rho0 = 1.29 -! ! mxratio = 0.0 -! ! sigma = (gamma2/(gamma1*c_x))*(n_ax*a_x*gamma2)**xi -! ! one_over_xip1 = 1.0/(xi + 1.0) -! ! -! ! -! ! do k=1,Nlev -! ! do j=1,Ncolumns -! ! do i=1,Npoints -! ! if ((prec_frac(i,j,k)==prec_type).or.(prec_frac(i,j,k)==3.)) then -! ! mxratio(i,j,k)=(flux(i,k)*((rho(i,k)/rho0)**g_x)*sigma)**one_over_xip1 -! ! mxratio(i,j,k)=mxratio(i,j,k)/rho(i,k) -! ! endif -! ! enddo -! ! enddo -! ! enddo -! ! -! ! END SUBROUTINE COSP_PRECIP_MXRATIO + if (n_ax >= 0.0) then ! N_ax is used to control which hydrometeors need to be computed + xi = d_x/(alpha_x + b_x - n_bx + 1.0) + rho0 = 1.29 + sigma = (gamma2/(gamma1*c_x))*(n_ax*a_x*gamma2)**xi + one_over_xip1 = 1.0/(xi + 1.0) + gamma_4_3_2 = 0.5*gamma4/gamma3 + delta = (alpha_x + b_x + d_x - n_bx + 1.0) + + do k=1,Nlevels + do j=1,Ncolumns + do i=1,Npoints + if ((prec_frac(i,j,k)==prec_type).or.(prec_frac(i,j,k)==3.)) then + rho = p(i,k)/(287.05*T(i,k)) + mxratio(i,j,k)=(flux(i,k)*((rho/rho0)**g_x)*sigma)**one_over_xip1 + mxratio(i,j,k)=mxratio(i,j,k)/rho + ! Compute effective radius + if ((reff(i,j,k) <= 0.0).and.(flux(i,k) /= 0.0)) then + lambda_x = (a_x*c_x*((rho0/rho)**g_x)*n_ax*gamma1/flux(i,k))**(1./delta) + reff(i,j,k) = gamma_4_3_2/lambda_x + endif + endif + enddo + enddo + enddo + endif +END SUBROUTINE COSP_PRECIP_MXRATIO !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -361,5 +356,60 @@ SUBROUTINE COSP_CHECK_INPUT_3D(vname,x,min_val,max_val) if (l_max) print *,'----- WARNING: '//trim(pro_name)//': maximum value of '//trim(vname)//' set to: ',max_val END SUBROUTINE COSP_CHECK_INPUT_3D +#ifdef COSP_GFDL + +!######################################################################## + +subroutine flip_vert_index_2D (in, dim,out) + real,dimension(:,:), intent(in) :: in + integer, intent(in) :: dim + real,dimension(:,:), intent(out) :: out + + integer k, kinv + + do k=1,dim + kinv = dim - k +1 + out(:,k) = in(:,kinv) + end do + +end subroutine flip_vert_index_2D + + + +!##################################################################### + +subroutine flip_vert_index_3D (in, dim,out) + real,dimension(:,:,:), intent(in) :: in + integer, intent(in) :: dim + real,dimension(:,:,:), intent(out) :: out + + integer k, kinv + + do k=1,dim + kinv = dim - k +1 + out(:,:,k) = in(:,:,kinv) + end do + +end subroutine flip_vert_index_3D + +!##################################################################### + +subroutine flip_vert_index_4D (in, dim,out) + real,dimension(:,:,:,:), intent(in) :: in + integer, intent(in) :: dim + real,dimension(:,:,:,:), intent(out) :: out + + integer k, kinv + + do k=1,dim + kinv = dim - k +1 + out(:,:,:,k) = in(:,:,:,kinv) + end do + +end subroutine flip_vert_index_4D + +#endif + +!################################################################### END MODULE MOD_COSP_UTILS diff --git a/src/atmos_param/cosp/icarus-scops-3.7/congvec.H b/src/atmos_param/cosp/icarus-scops-3.7/congvec.H new file mode 100644 index 0000000000..e0b9ccdab1 --- /dev/null +++ b/src/atmos_param/cosp/icarus-scops-3.7/congvec.H @@ -0,0 +1,66 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL + +!--------------------------------------------------------------------- +!------------ FMS version number and tagname for this file ----------- + +! $Id: congvec.H,v 20.0 2013/12/13 23:16:00 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif + + +! *****************************COPYRIGHT**************************** +! (c) British Crown Copyright 2009, the Met Office. +! All rights reserved. +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the +! following conditions are met: +! +! * Redistributions of source code must retain the above +! copyright notice, this list of conditions and the following +! disclaimer. +! * Redistributions in binary form must reproduce the above +! copyright notice, this list of conditions and the following +! disclaimer in the documentation and/or other materials +! provided with the distribution. +! * Neither the name of the Met Office nor the names of its +! contributors may be used to endorse or promote products +! derived from this software without specific prior written +! permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +! A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +! OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +! LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +! +! *****************************COPYRIGHT******************************* +! *****************************COPYRIGHT******************************* + + do irand = 1, npoints + ! Marsaglia CONG algorithm + seed(irand)=69069*seed(irand)+1234567 + ! mod 32 bit overflow + seed(irand)=mod(seed(irand),2**30) + ran(irand)=seed(irand)*0.931322574615479E-09 + enddo + + ! convert to range 0-1 (32 bit only) + overflow_32=i2_16*i2_16 + if ( overflow_32 .le. huge32 ) then + do irand = 1, npoints + ran(irand)=ran(irand)+1 + ran(irand)=(ran(irand))-int(ran(irand)) + enddo + endif + + diff --git a/src/atmos_param/cosp/icarus-scops-3.7/congvec.inc b/src/atmos_param/cosp/icarus-scops-3.7/congvec.inc index 3a2f2a6f11..0bf07e4499 100644 --- a/src/atmos_param/cosp/icarus-scops-3.7/congvec.inc +++ b/src/atmos_param/cosp/icarus-scops-3.7/congvec.inc @@ -3,7 +3,7 @@ !------------ FMS version number and tagname for this file ----------- ! $Id: congvec.inc,v 19.0 2012/01/06 20:04:19 fms Exp $ -! $Name: siena_201207 $ +! $Name: tikal $ ! *****************************COPYRIGHT**************************** diff --git a/src/atmos_param/cosp/icarus-scops-3.7/icarus.f90 b/src/atmos_param/cosp/icarus-scops-3.7/icarus.F90 similarity index 73% rename from src/atmos_param/cosp/icarus-scops-3.7/icarus.f90 rename to src/atmos_param/cosp/icarus-scops-3.7/icarus.F90 index 1611c30d8d..aaba89184a 100644 --- a/src/atmos_param/cosp/icarus-scops-3.7/icarus.f90 +++ b/src/atmos_param/cosp/icarus-scops-3.7/icarus.F90 @@ -1,10 +1,16 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: icarus.f90,v 19.0 2012/01/06 20:04:20 fms Exp $ -! $Name: siena_201207 $ +! $Id: icarus.F90,v 20.0 2013/12/13 23:16:02 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 +#endif + +#ifdef COSP_GFDL SUBROUTINE ICARUS( & & debug, & & debugcol, & @@ -38,11 +44,47 @@ SUBROUTINE ICARUS( & & boxtau, & & boxptop, & & dtau_col, & - & dem_col, & - & passing_in_column_data & + & dem_col & + &) +#else + SUBROUTINE ICARUS( + & debug, + & debugcol, + & npoints, + & sunlit, + & nlev, + & ncol, + & pfull, + & phalf, + & qv, + & cc, + & conv, + & dtau_s, + & dtau_c, + & top_height, + & top_height_direction, + & overlap, + & frac_out, + & skt, + & emsfc_lw, + & at, + & dem_s, + & dem_c, + & fq_isccp, + & totalcldarea, + & meanptop, + & meantaucld, + & meanalbedocld, + & meantb, + & meantbclr, + & boxtau, + & boxptop &) +#endif -!$Id: icarus.f90,v 19.0 2012/01/06 20:04:20 fms Exp $ +#ifndef COSP_GFDL +!$Id: icarus.F90,v 20.0 2013/12/13 23:16:02 fms Exp $ +#endif ! *****************************COPYRIGHT**************************** ! (c) 2009, Lawrence Livermore National Security Limited Liability @@ -81,9 +123,12 @@ SUBROUTINE ICARUS( & ! *****************************COPYRIGHT******************************* ! *****************************COPYRIGHT******************************* ! *****************************COPYRIGHT******************************* - use mpp_mod,only: get_unit - use fms_mod,only: stdlog, error_mesg, FATAL +! *****************************COPYRIGHT******************************* +#ifdef COSP_GFDL +use mpp_mod,only: get_unit +use fms_mod,only: stdlog, error_mesg, FATAL +#endif implicit none ! NOTE: the maximum number of levels and columns is set by @@ -194,17 +239,17 @@ SUBROUTINE ICARUS( & ! indexed by column then row, rather than ! by row then column - REAL dtau_col(npoints,ncol,nlev) +#ifdef COSP_GFDL + REAL, optional :: dtau_col(npoints,ncol,nlev) ! tau values obtained from model ! stochastic columns - - REAL dem_col(npoints,ncol,nlev) + + REAL, optional :: dem_col(npoints,ncol,nlev) ! lw emissivity values obtained ! from model stochastic columns + - LOGICAL passing_in_column_data - ! tau and emissivity from model columns - ! is passed in ? +#endif ! ------ @@ -276,7 +321,11 @@ SUBROUTINE ICARUS( & real rh20s(npoints), rfrgn(npoints) real tmpexp(npoints),tauwv(npoints) +#ifdef COSP_GFDL character(len=1) :: cchar(6),cchar_realtops(6) +#else + character*1 cchar(6),cchar_realtops(6) +#endif integer icycle REAL tau(npoints,ncol) LOGICAL box_cloudy(npoints,ncol) @@ -294,11 +343,18 @@ SUBROUTINE ICARUS( & ! decomposition with step debugcol integer rangevec(npoints),rangeerror - integer index1(npoints),num1,jj,k1,k2, funit, logunit + integer index1(npoints),num1,jj,k1,k2 +#ifdef COSP_GFDL + integer funit, logunit +#endif real rec2p13,tauchk,logp,logp1,logp2,atd real output_missing_value +#ifdef COSP_GFDL character(len=10) :: ftn09 +#else + character*10 ftn09 +#endif DATA isccp_taumin / 0.3 / DATA output_missing_value / -1.E+30 / @@ -312,9 +368,12 @@ SUBROUTINE ICARUS( & ncolprint=0 +#ifdef COSP_GFDL logunit = stdlog() +#endif if ( debug.ne.0 ) then j=1 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write(logunit,'(a10)') 'debug=' @@ -329,7 +388,7 @@ SUBROUTINE ICARUS( & write(logunit,'(8I10)') ncol write(logunit,'(a11)') 'top_height=' write(logunit,'(8I10)') top_height - write(logunit,'(a21)') 'top_height_direction=' + write(logunit,'(a21)') 'top_height_direction=' write(logunit,'(8I10)') top_height_direction write(logunit,'(a10)') 'overlap=' write(logunit,'(8I10)') overlap @@ -363,14 +422,69 @@ SUBROUTINE ICARUS( & write(logunit,'(a10)') 'dem_c=' write(logunit,'(8f10.3)') (dem_c(j,i),i=1,nlev) enddo +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write(6,'(a10)') 'debug=' + write(6,'(8I10)') debug + write(6,'(a10)') 'debugcol=' + write(6,'(8I10)') debugcol + write(6,'(a10)') 'npoints=' + write(6,'(8I10)') npoints + write(6,'(a10)') 'nlev=' + write(6,'(8I10)') nlev + write(6,'(a10)') 'ncol=' + write(6,'(8I10)') ncol + write(6,'(a11)') 'top_height=' + write(6,'(8I10)') top_height + write(6,'(a21)') 'top_height_direction=' + write(6,'(8I10)') top_height_direction + write(6,'(a10)') 'overlap=' + write(6,'(8I10)') overlap + write(6,'(a10)') 'emsfc_lw=' + write(6,'(8f10.2)') emsfc_lw + do j=1,npoints,debug + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write(6,'(a10)') 'sunlit=' + write(6,'(8I10)') sunlit(j) + write(6,'(a10)') 'pfull=' + write(6,'(8f10.2)') (pfull(j,i),i=1,nlev) + write(6,'(a10)') 'phalf=' + write(6,'(8f10.2)') (phalf(j,i),i=1,nlev+1) + write(6,'(a10)') 'qv=' + write(6,'(8f10.3)') (qv(j,i),i=1,nlev) + write(6,'(a10)') 'cc=' + write(6,'(8f10.3)') (cc(j,i),i=1,nlev) + write(6,'(a10)') 'conv=' + write(6,'(8f10.2)') (conv(j,i),i=1,nlev) + write(6,'(a10)') 'dtau_s=' + write(6,'(8g12.5)') (dtau_s(j,i),i=1,nlev) + write(6,'(a10)') 'dtau_c=' + write(6,'(8f10.2)') (dtau_c(j,i),i=1,nlev) + write(6,'(a10)') 'skt=' + write(6,'(8f10.2)') skt(j) + write(6,'(a10)') 'at=' + write(6,'(8f10.2)') (at(j,i),i=1,nlev) + write(6,'(a10)') 'dem_s=' + write(6,'(8f10.3)') (dem_s(j,i),i=1,nlev) + write(6,'(a10)') 'dem_c=' + write(6,'(8f10.3)') (dem_c(j,i),i=1,nlev) + enddo +#endif endif ! ---------------------------------------------------! if (ncolprint.ne.0) then do j=1,npoints,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j +#endif enddo endif @@ -386,9 +500,15 @@ SUBROUTINE ICARUS( & do 12 ilev=1,nlev do j=1,npoints - if (pfull(j,ilev) .lt. 40000. .and. & +#ifdef COSP_GFDL + if (pfull(j,ilev) .lt. 40000. .and. & & pfull(j,ilev) .gt. 5000. .and. & & at(j,ilev) .lt. attropmin(j)) then +#else + if (pfull(j,ilev) .lt. 40000. .and. + & pfull(j,ilev) .gt. 5000. .and. + & at(j,ilev) .lt. attropmin(j)) then +#endif ptrop(j) = pfull(j,ilev) attropmin(j) = at(j,ilev) attrop(j) = attropmin(j) @@ -398,11 +518,17 @@ SUBROUTINE ICARUS( & 12 continue do 13 ilev=1,nlev - do j=1,npoints - if (at(j,ilev) .gt. atmax(j) .and. & - & ilev .ge. itrop(j)) atmax(j) = at(j,ilev) + do j=1,npoints +#ifdef COSP_GFDL + if (at(j,ilev) .gt. atmax(j) .and. & + & ilev .ge. itrop(j)) atmax(j)=at(j,ilev) +#else + if (at(j,ilev) .gt. atmax(j) .and. + & ilev .ge. itrop(j)) atmax(j)=at(j,ilev) +#endif enddo 13 continue + end if @@ -467,15 +593,23 @@ SUBROUTINE ICARUS( & rangeerror=rangeerror+rangevec(j) enddo - if (rangeerror.ne.0) then +#ifdef COSP_GFDL + if (rangeerror.ne.0) then write (logunit,*) 'Input variable out of range' write (logunit,*) 'rangevec:' write (logunit,*) rangevec -! call flush(6) -! STOP call error_mesg('ICARUS','Input variable out of range',FATAL) endif +#else + if (rangeerror.ne.0) then + write (6,*) 'Input variable out of range' + write (6,*) 'rangevec:' + write (6,*) rangevec + call flush(6) + STOP + endif +#endif enddo ! @@ -499,40 +633,55 @@ SUBROUTINE ICARUS( & 15 continue !compute total cloud optical depth for each column - if (passing_in_column_data) then +#ifdef COSP_GFDL + if (present(dtau_col) ) then do ilev=1,nlev !increment tau for each of the boxes do ibox=1,ncol do j=1,npoints tau(j,ibox)=tau(j,ibox) & - & + dtau_col(j,ibox,ilev) + & + dtau_col(j,ibox,ilev) enddo enddo ! ibox enddo ! ilev - - else - + else do ilev=1,nlev !increment tau for each of the boxes do ibox=1,ncol do j=1,npoints if (frac_out(j,ibox,ilev).eq.1) then - tau(j,ibox)=tau(j,ibox) & + tau(j,ibox)=tau(j,ibox) & & + dtau_s(j,ilev) endif if (frac_out(j,ibox,ilev).eq.2) then - tau(j,ibox)=tau(j,ibox) & + tau(j,ibox)=tau(j,ibox) & & + dtau_c(j,ilev) end if enddo enddo ! ibox enddo ! ilev - - endif - + endif +#else + do ilev=1,nlev + !increment tau for each of the boxes + do ibox=1,ncol + do j=1,npoints + if (frac_out(j,ibox,ilev).eq.1) then + tau(j,ibox)=tau(j,ibox) + & + dtau_s(j,ilev) + endif + if (frac_out(j,ibox,ilev).eq.2) then + tau(j,ibox)=tau(j,ibox) + & + dtau_c(j,ilev) + end if + enddo + enddo ! ibox + enddo ! ilev +#endif if (ncolprint.ne.0) then +#ifdef COSP_GFDL do j=1,npoints ,1000 write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j @@ -540,6 +689,15 @@ SUBROUTINE ICARUS( & & ilev, & & (tau(j,ibox),ibox=1,ncolprint) enddo +#else + do j=1,npoints ,1000 + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write(6,'(i2,1X,8(f7.2,1X))') + & ilev, + & (tau(j,ibox),ibox=1,ncolprint) + enddo +#endif endif ! ! ---------------------------------------------------! @@ -578,8 +736,13 @@ SUBROUTINE ICARUS( & grav = 9.806650E+02 pstd = 1.013250E+06 t0 = 296. +#ifdef COSP_GFDL if (ncolprint .ne. 0) & & write(logunit,*) 'ilev pw (kg/m2) tauwv(j) dem_wv' +#else + if (ncolprint .ne. 0) + & write(6,*) 'ilev pw (kg/m2) tauwv(j) dem_wv' +#endif do 125 ilev=1,nlev do j=1,npoints !press and dpress are dyne/cm2 = Pascals *10 @@ -593,18 +756,32 @@ SUBROUTINE ICARUS( & rh20s(j) = rvh20(j)*rhoave(j) rfrgn(j) = rhoave(j)-rh20s(j) tmpexp(j) = exp(-0.02*(at(j,ilev)-t0)) +#ifdef COSP_GFDL tauwv(j) = wk(j)*1.e-20*( & & (0.0224697*rh20s(j)*tmpexp(j)) + & & (3.41817e-7*rfrgn(j)) )*0.98 +#else + tauwv(j) = wk(j)*1.e-20*( + & (0.0224697*rh20s(j)*tmpexp(j)) + + & (3.41817e-7*rfrgn(j)) )*0.98 +#endif dem_wv(j,ilev) = 1. - exp( -1. * tauwv(j)) enddo if (ncolprint .ne. 0) then do j=1,npoints ,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write(logunit,'(i2,1X,3(f8.3,3X))') ilev, & & qv(j,ilev)*(phalf(j,ilev+1)-phalf(j,ilev))/(grav/100.), & & tauwv(j),dem_wv(j,ilev) +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write(6,'(i2,1X,3(f8.3,3X))') ilev, + & qv(j,ilev)*(phalf(j,ilev+1)-phalf(j,ilev))/(grav/100.), + & tauwv(j),dem_wv(j,ilev) +#endif enddo endif 125 continue @@ -626,28 +803,50 @@ SUBROUTINE ICARUS( & ! increase TOA flux by flux emitted from layer ! times total transmittance in layers above +#ifdef COSP_GFDL fluxtop_clrsky(j) = fluxtop_clrsky(j) & + & + dem_wv(j,ilev)*bb(j)*trans_layers_above_clrsky(j) +#else + fluxtop_clrsky(j) = fluxtop_clrsky(j) & + dem_wv(j,ilev)*bb(j)*trans_layers_above_clrsky(j) +#endif ! update trans_layers_above with transmissivity ! from this layer for next time around loop +#ifdef COSP_GFDL trans_layers_above_clrsky(j)= & & trans_layers_above_clrsky(j)*(1.-dem_wv(j,ilev)) +#else + trans_layers_above_clrsky(j)= + & trans_layers_above_clrsky(j)*(1.-dem_wv(j,ilev)) +#endif enddo if (ncolprint.ne.0) then do j=1,npoints ,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write (logunit,'(a)') 'ilev:' write (logunit,'(I2)') ilev - + write (logunit,'(a)') & & 'emiss_layer,100.*bb(j),100.*f,total_trans:' write (logunit,'(4(f7.2,1X))') dem_wv(j,ilev),100.*bb(j), & & 100.*fluxtop_clrsky(j),trans_layers_above_clrsky(j) +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write (6,'(a)') 'ilev:' + write (6,'(I2)') ilev + + write (6,'(a)') + & 'emiss_layer,100.*bb(j),100.*f,total_trans:' + write (6,'(4(f7.2,1X))') dem_wv(j,ilev),100.*bb(j), + & 100.*fluxtop_clrsky(j),trans_layers_above_clrsky(j) +#endif enddo endif @@ -658,8 +857,13 @@ SUBROUTINE ICARUS( & bb(j)=1/( exp(1307.27/skt(j)) - 1. ) !bb(j)=5.67e-8*skt(j)**4 +#ifdef COSP_GFDL fluxtop_clrsky(j) = fluxtop_clrsky(j) + emsfc_lw * bb(j) & & * trans_layers_above_clrsky(j) +#else + fluxtop_clrsky(j) = fluxtop_clrsky(j) + emsfc_lw * bb(j) + & * trans_layers_above_clrsky(j) +#endif !clear sky brightness temperature meantbclr(j) = 1307.27/(log(1.+(1./fluxtop_clrsky(j)))) @@ -668,15 +872,27 @@ SUBROUTINE ICARUS( & if (ncolprint.ne.0) then do j=1,npoints ,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write (logunit,'(a)') 'id:' write (logunit,'(a)') 'surface' - + write (logunit,'(a)') 'emsfc,100.*bb(j),100.*f,total_trans:' write (logunit,'(5(f7.2,1X))') emsfc_lw,100.*bb(j), & & 100.*fluxtop_clrsky(j), & & trans_layers_above_clrsky(j), meantbclr(j) +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write (6,'(a)') 'id:' + write (6,'(a)') 'surface' + + write (6,'(a)') 'emsfc,100.*bb(j),100.*f,total_trans:' + write (6,'(5(f7.2,1X))') emsfc_lw,100.*bb(j), + & 100.*fluxtop_clrsky(j), + & trans_layers_above_clrsky(j), meantbclr(j) +#endif enddo endif @@ -691,14 +907,25 @@ SUBROUTINE ICARUS( & if (ncolprint.ne.0) then do j=1,npoints ,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write (logunit,'(a)') 'ts:' write (logunit,'(8f7.2)') (skt(j),ibox=1,ncolprint) - + write (logunit,'(a)') 'ta_rev:' write (logunit,'(8f7.2)') & & ((at(j,ilev2),ibox=1,ncolprint),ilev2=1,nlev) +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write (6,'(a)') 'ts:' + write (6,'(8f7.2)') (skt(j),ibox=1,ncolprint) + + write (6,'(a)') 'ta_rev:' + write (6,'(8f7.2)') + & ((at(j,ilev2),ibox=1,ncolprint),ilev2=1,nlev) +#endif enddo endif @@ -721,7 +948,8 @@ SUBROUTINE ICARUS( & do ibox=1,ncol do j=1,npoints - if (passing_in_column_data) then +#ifdef COSP_GFDL + if (present(dem_col) ) then ! emissivity for point in this layer if (frac_out(j,ibox,ilev).eq.1 .or. & & frac_out(j,ibox,ilev).eq.2) then @@ -744,44 +972,88 @@ SUBROUTINE ICARUS( & end if endif +#else + ! emissivity for point in this layer + if (frac_out(j,ibox,ilev).eq.1) then + dem(j,ibox)= 1. - + & ( (1. - dem_wv(j,ilev)) * (1. - dem_s(j,ilev)) ) + else if (frac_out(j,ibox,ilev).eq.2) then + dem(j,ibox)= 1. - + & ( (1. - dem_wv(j,ilev)) * (1. - dem_c(j,ilev)) ) + else + dem(j,ibox)= dem_wv(j,ilev) + end if +#endif ! increase TOA flux by flux emitted from layer ! times total transmittance in layers above +#ifdef COSP_GFDL fluxtop(j,ibox) = fluxtop(j,ibox) & & + dem(j,ibox) * bb(j) & + & * trans_layers_above(j,ibox) +#else + fluxtop(j,ibox) = fluxtop(j,ibox) + & + dem(j,ibox) * bb(j) & * trans_layers_above(j,ibox) +#endif ! update trans_layers_above with transmissivity ! from this layer for next time around loop +#ifdef COSP_GFDL trans_layers_above(j,ibox)= & & trans_layers_above(j,ibox)*(1.-dem(j,ibox)) +#else + trans_layers_above(j,ibox)= + & trans_layers_above(j,ibox)*(1.-dem(j,ibox)) +#endif enddo ! j enddo ! ibox if (ncolprint.ne.0) then do j=1,npoints,1000 +#ifdef COSP_GFDL write (logunit,'(a)') 'ilev:' write (logunit,'(I2)') ilev - + write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write (logunit,'(a)') 'emiss_layer:' write (logunit,'(8f7.2)') (dem(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') '100.*bb(j):' write (logunit,'(8f7.2)') (100.*bb(j),ibox=1,ncolprint) - + write (logunit,'(a)') '100.*f:' write (logunit,'(8f7.2)') & & (100.*fluxtop(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'total_trans:' write (logunit,'(8f7.2)') & & (trans_layers_above(j,ibox),ibox=1,ncolprint) +#else + write (6,'(a)') 'ilev:' + write (6,'(I2)') ilev + + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write (6,'(a)') 'emiss_layer:' + write (6,'(8f7.2)') (dem(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') '100.*bb(j):' + write (6,'(8f7.2)') (100.*bb(j),ibox=1,ncolprint) + + write (6,'(a)') '100.*f:' + write (6,'(8f7.2)') + & (100.*fluxtop(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'total_trans:' + write (6,'(8f7.2)') + & (trans_layers_above(j,ibox),ibox=1,ncolprint) +#endif enddo endif @@ -799,9 +1071,15 @@ SUBROUTINE ICARUS( & !add in surface emission +#ifdef COSP_GFDL fluxtop(j,ibox) = fluxtop(j,ibox) & & + emsfc_lw * bb(j) & + & * trans_layers_above(j,ibox) +#else + fluxtop(j,ibox) = fluxtop(j,ibox) + & + emsfc_lw * bb(j) & * trans_layers_above(j,ibox) +#endif end do end do @@ -819,6 +1097,7 @@ SUBROUTINE ICARUS( & if (ncolprint.ne.0) then do j=1,npoints ,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j write (logunit,'(a)') 'id:' @@ -826,15 +1105,33 @@ SUBROUTINE ICARUS( & write (logunit,'(a)') 'emiss_layer:' write (logunit,'(8f7.2)') (dem(1,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') '100.*bb(j):' write (logunit,'(8f7.2)') (100.*bb(j),ibox=1,ncolprint) - + write (logunit,'(a)') '100.*f:' write (logunit,'(8f7.2)') (100.*fluxtop(j,ibox),ibox=1,ncolprint) - - write (logunit,'(a)') 'meantb(j):' + + write (logunit,'(a)') 'meantb(j):' write (logunit,'(8f7.2)') (meantb(j),ibox=1,ncolprint) +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + write (6,'(a)') 'id:' + write (6,'(a)') 'surface' + + write (6,'(a)') 'emiss_layer:' + write (6,'(8f7.2)') (dem(1,ibox),ibox=1,ncolprint) + + write (6,'(a)') '100.*bb(j):' + write (6,'(8f7.2)') (100.*bb(j),ibox=1,ncolprint) + + write (6,'(a)') '100.*f:' + write (6,'(8f7.2)') (100.*fluxtop(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'meantb(j):' + write (6,'(8f7.2)') (meantb(j),ibox=1,ncolprint) +#endif end do endif @@ -861,8 +1158,13 @@ SUBROUTINE ICARUS( & enddo do ibox=1,ncol do j=1,npoints +#ifdef COSP_GFDL transmax(j) = (fluxtop(j,ibox)-btcmin(j)) & & /(fluxtop_clrsky(j)-btcmin(j)) +#else + transmax(j) = (fluxtop(j,ibox)-btcmin(j)) + & /(fluxtop_clrsky(j)-btcmin(j)) +#endif !note that the initial setting of tauir(j) is needed so that !tauir(j) has a realistic value should the next if block be !bypassed @@ -873,8 +1175,13 @@ SUBROUTINE ICARUS( & if (top_height .eq. 1) then do j=1,npoints +#ifdef COSP_GFDL if (transmax(j) .gt. 0.001 .and. & & transmax(j) .le. 0.9999999) then +#else + if (transmax(j) .gt. 0.001 .and. + & transmax(j) .le. 0.9999999) then +#endif fluxtopinit(j) = fluxtop(j,ibox) tauir(j) = tau(j,ibox) *rec2p13 endif @@ -882,6 +1189,7 @@ SUBROUTINE ICARUS( & do icycle=1,2 do j=1,npoints if (tau(j,ibox) .gt. (tauchk )) then +#ifdef COSP_GFDL if (transmax(j) .gt. 0.001 .and. & & transmax(j) .le. 0.9999999) then emcld(j,ibox) = 1. - exp(-1. * tauir(j) ) @@ -890,7 +1198,18 @@ SUBROUTINE ICARUS( & fluxtop(j,ibox)=max(1.E-06, & & (fluxtop(j,ibox)/emcld(j,ibox))) tb(j,ibox)= 1307.27 & + & / (log(1. + (1./fluxtop(j,ibox)))) +#else + if (transmax(j) .gt. 0.001 .and. + & transmax(j) .le. 0.9999999) then + emcld(j,ibox) = 1. - exp(-1. * tauir(j) ) + fluxtop(j,ibox) = fluxtopinit(j) - + & ((1.-emcld(j,ibox))*fluxtop_clrsky(j)) + fluxtop(j,ibox)=max(1.E-06, + & (fluxtop(j,ibox)/emcld(j,ibox))) + tb(j,ibox)= 1307.27 & / (log(1. + (1./fluxtop(j,ibox)))) +#endif if (tb(j,ibox) .gt. 260.) then tauir(j) = tau(j,ibox) / 2.56 end if @@ -921,45 +1240,87 @@ SUBROUTINE ICARUS( & if (ncolprint.ne.0) then do j=1,npoints,1000 +#ifdef COSP_GFDL write(logunit,'(a10)') 'j=' write(logunit,'(8I10)') j - + write (logunit,'(a)') 'attrop:' write (logunit,'(8f7.2)') (attrop(j)) - + write (logunit,'(a)') 'btcmin:' write (logunit,'(8f7.2)') (btcmin(j)) - + write (logunit,'(a)') 'fluxtop_clrsky*100:' write (logunit,'(8f7.2)') & & (100.*fluxtop_clrsky(j)) write (logunit,'(a)') '100.*f_adj:' write (logunit,'(8f7.2)') (100.*fluxtop(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'transmax:' write (logunit,'(8f7.2)') (transmax(ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'tau:' write (logunit,'(8f7.2)') (tau(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'emcld:' write (logunit,'(8f7.2)') (emcld(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'total_trans:' write (logunit,'(8f7.2)') & & (trans_layers_above(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'total_emiss:' write (logunit,'(8f7.2)') & & (1.0-trans_layers_above(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'total_trans:' write (logunit,'(8f7.2)') & & (trans_layers_above(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'ppout:' write (logunit,'(8f7.2)') (tb(j,ibox),ibox=1,ncolprint) +#else + write(6,'(a10)') 'j=' + write(6,'(8I10)') j + + write (6,'(a)') 'attrop:' + write (6,'(8f7.2)') (attrop(j)) + + write (6,'(a)') 'btcmin:' + write (6,'(8f7.2)') (btcmin(j)) + + write (6,'(a)') 'fluxtop_clrsky*100:' + write (6,'(8f7.2)') + & (100.*fluxtop_clrsky(j)) + + write (6,'(a)') '100.*f_adj:' + write (6,'(8f7.2)') (100.*fluxtop(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'transmax:' + write (6,'(8f7.2)') (transmax(ibox),ibox=1,ncolprint) + + write (6,'(a)') 'tau:' + write (6,'(8f7.2)') (tau(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'emcld:' + write (6,'(8f7.2)') (emcld(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'total_trans:' + write (6,'(8f7.2)') + & (trans_layers_above(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'total_emiss:' + write (6,'(8f7.2)') + & (1.0-trans_layers_above(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'total_trans:' + write (6,'(8f7.2)') + & (trans_layers_above(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'ppout:' + write (6,'(8f7.2)') (tb(j,ibox),ibox=1,ncolprint) +#endif enddo ! j endif @@ -994,10 +1355,17 @@ SUBROUTINE ICARUS( & !cdir nodep do j=1,npoints if (ilev .ge. itrop(j)) then +#ifdef COSP_GFDL if ((at(j,ilev) .ge. tb(j,ibox) .and. & & at(j,ilev+1) .le. tb(j,ibox)) .or. & & (at(j,ilev) .le. tb(j,ibox) .and. & + & at(j,ilev+1) .ge. tb(j,ibox))) then +#else + if ((at(j,ilev) .ge. tb(j,ibox) .and. + & at(j,ilev+1) .le. tb(j,ibox)) .or. + & (at(j,ilev) .le. tb(j,ibox) .and. & at(j,ilev+1) .ge. tb(j,ibox))) then +#endif nmatch(j)=nmatch(j)+1 match(j,nmatch(j))=ilev end if @@ -1014,8 +1382,13 @@ SUBROUTINE ICARUS( & atd = max(tauchk,abs(at(j,k2) - at(j,k1))) logp=logp1+(logp2-logp1)*abs(tb(j,ibox)-at(j,k1))/atd ptop(j,ibox) = exp(logp) - if(abs(pfull(j,k1)-ptop(j,ibox)) .lt. & +#ifdef COSP_GFDL + if(abs(pfull(j,k1)-ptop(j,ibox)) .lt. & + & abs(pfull(j,k2)-ptop(j,ibox))) then +#else + if(abs(pfull(j,k1)-ptop(j,ibox)) .lt. & abs(pfull(j,k2)-ptop(j,ibox))) then +#endif levmatch(j,ibox)=k1 else levmatch(j,ibox)=k2 @@ -1039,8 +1412,13 @@ SUBROUTINE ICARUS( & enddo do ilev=1,nlev do j=1,npoints +#ifdef COSP_GFDL if ((ptop(j,ibox) .eq. 0. ) & & .and.(frac_out(j,ibox,ilev) .ne. 0)) then +#else + if ((ptop(j,ibox) .eq. 0. ) + & .and.(frac_out(j,ibox,ilev) .ne. 0)) then +#endif ptop(j,ibox)=phalf(j,ilev) levmatch(j,ibox)=ilev end if @@ -1115,8 +1493,13 @@ SUBROUTINE ICARUS( & do 39 ibox=1,ncol do j=1,npoints +#ifdef COSP_GFDL if (tau(j,ibox) .gt. (tauchk ) & & .and. ptop(j,ibox) .gt. 0.) then +#else + if (tau(j,ibox) .gt. (tauchk ) + & .and. ptop(j,ibox) .gt. 0.) then +#endif box_cloudy(j,ibox)=.true. endif @@ -1130,12 +1513,21 @@ SUBROUTINE ICARUS( & totalcldarea(j) = totalcldarea(j) + boxarea !convert optical thickness to albedo - albedocld(j,ibox) & +#ifdef COSP_GFDL + albedocld(j,ibox) & + & = (tau(j,ibox)**0.895)/((tau(j,ibox)**0.895)+6.82) + + !contribute to averaging + meanalbedocld(j) = meanalbedocld(j) & + & +albedocld(j,ibox)*boxarea +#else + albedocld(j,ibox) & = (tau(j,ibox)**0.895)/((tau(j,ibox)**0.895)+6.82) !contribute to averaging - meanalbedocld(j) = meanalbedocld(j) & + meanalbedocld(j) = meanalbedocld(j) & +albedocld(j,ibox)*boxarea +#endif end if @@ -1162,6 +1554,7 @@ SUBROUTINE ICARUS( & ipres(j) = 0 !determine optical depth category +#ifdef COSP_GFDL if (tau(j,ibox) .lt. isccp_taumin) then itau(j)=1 else if (tau(j,ibox) .ge. isccp_taumin & @@ -1186,7 +1579,7 @@ SUBROUTINE ICARUS( & !determine cloud top pressure category if ( ptop(j,ibox) .gt. 0. & & .and.ptop(j,ibox) .lt. 180.) then - ipres(j)=1 + ipres(j)=1 else if(ptop(j,ibox) .ge. 180. & & .and.ptop(j,ibox) .lt. 310.) then ipres(j)=2 @@ -1200,16 +1593,67 @@ SUBROUTINE ICARUS( & & .and.ptop(j,ibox) .lt. 680.) then ipres(j)=5 else if(ptop(j,ibox) .ge. 680. & + & .and.ptop(j,ibox) .lt. 800.) then + ipres(j)=6 + else if(ptop(j,ibox) .ge. 800.) then + ipres(j)=7 + end if +#else + if (tau(j,ibox) .lt. isccp_taumin) then + itau(j)=1 + else if (tau(j,ibox) .ge. isccp_taumin + & + & .and. tau(j,ibox) .lt. 1.3) then + itau(j)=2 + else if (tau(j,ibox) .ge. 1.3 + & .and. tau(j,ibox) .lt. 3.6) then + itau(j)=3 + else if (tau(j,ibox) .ge. 3.6 + & .and. tau(j,ibox) .lt. 9.4) then + itau(j)=4 + else if (tau(j,ibox) .ge. 9.4 + & .and. tau(j,ibox) .lt. 23.) then + itau(j)=5 + else if (tau(j,ibox) .ge. 23. + & .and. tau(j,ibox) .lt. 60.) then + itau(j)=6 + else if (tau(j,ibox) .ge. 60.) then + itau(j)=7 + end if + + !determine cloud top pressure category + if ( ptop(j,ibox) .gt. 0. + & .and.ptop(j,ibox) .lt. 180.) then + ipres(j)=1 + else if(ptop(j,ibox) .ge. 180. + & .and.ptop(j,ibox) .lt. 310.) then + ipres(j)=2 + else if(ptop(j,ibox) .ge. 310. + & .and.ptop(j,ibox) .lt. 440.) then + ipres(j)=3 + else if(ptop(j,ibox) .ge. 440. + & .and.ptop(j,ibox) .lt. 560.) then + ipres(j)=4 + else if(ptop(j,ibox) .ge. 560. + & .and.ptop(j,ibox) .lt. 680.) then + ipres(j)=5 + else if(ptop(j,ibox) .ge. 680. & .and.ptop(j,ibox) .lt. 800.) then ipres(j)=6 else if(ptop(j,ibox) .ge. 800.) then ipres(j)=7 end if +#endif !update frequencies if(ipres(j) .gt. 0.and.itau(j) .gt. 0) then +#ifdef COSP_GFDL fq_isccp(j,itau(j),ipres(j))= & & fq_isccp(j,itau(j),ipres(j))+ boxarea +#else + fq_isccp(j,itau(j),ipres(j))= + & fq_isccp(j,itau(j),ipres(j))+ boxarea +#endif end if end if @@ -1258,8 +1702,13 @@ SUBROUTINE ICARUS( & do ilev=1,nlev do ibox=1,ncol acc(ilev,ibox)=frac_out(j,ibox,ilev)*2 +#ifdef COSP_GFDL if (levmatch(j,ibox) .eq. ilev) & & acc(ilev,ibox)=acc(ilev,ibox)+1 +#else + if (levmatch(j,ibox) .eq. ilev) + & acc(ilev,ibox)=acc(ilev,ibox)+1 +#endif enddo enddo @@ -1267,6 +1716,7 @@ SUBROUTINE ICARUS( & write(ftn09,11) j 11 format('ftn09.',i4.4) +#ifdef COSP_GFDL funit = get_unit() open(funit, FILE=ftn09, FORM='FORMATTED') @@ -1274,15 +1724,31 @@ SUBROUTINE ICARUS( & write(funit,'(10i5)') & & (ilev,ilev=5,nlev,5) write(funit,'(a1)') ' ' - + do ibox=1,ncol write(funit,'(40(a1),1x,40(a1))') & & (cchar_realtops(acc(ilev,ibox)+1),ilev=1,nlev) & - & ,(cchar(acc(ilev,ibox)+1),ilev=1,nlev) + & ,(cchar(acc(ilev,ibox)+1),ilev=1,nlev) end do close(funit) +#else + open(9, FILE=ftn09, FORM='FORMATTED') + + write(9,'(a1)') ' ' + write(9,'(10i5)') + & (ilev,ilev=5,nlev,5) + write(9,'(a1)') ' ' + + do ibox=1,ncol + write(9,'(40(a1),1x,40(a1))') + & (cchar_realtops(acc(ilev,ibox)+1),ilev=1,nlev) + & ,(cchar(acc(ilev,ibox)+1),ilev=1,nlev) + end do + close(9) +#endif if (ncolprint.ne.0) then +#ifdef COSP_GFDL write(logunit,'(a1)') ' ' write(logunit,'(a2,1X,5(a7,1X),a50)') & & 'ilev', & @@ -1292,7 +1758,7 @@ SUBROUTINE ICARUS( & ! do 4012 ilev=1,nlev ! write(logunit,'(60i2)') (box(i,ilev),i=1,ncolprint) -! write(logunit,'(i2,1X,5(f7.2,1X),50(a1))') +! write(logunit,'(i2,1X,5(f7.2,1X),50(a1))') ! & ilev, ! & pfull(j,ilev)/100.,at(j,ilev), ! & cc(j,ilev)*100.0,dem_s(j,ilev),dtau_s(j,ilev) @@ -1300,17 +1766,47 @@ SUBROUTINE ICARUS( & !4012 continue write (logunit,'(a)') 'skt(j):' write (logunit,'(8f7.2)') skt(j) - + write (logunit,'(8I7)') (ibox,ibox=1,ncolprint) - + write (logunit,'(a)') 'tau:' write (logunit,'(8f7.2)') (tau(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'tb:' write (logunit,'(8f7.2)') (tb(j,ibox),ibox=1,ncolprint) - + write (logunit,'(a)') 'ptop:' write (logunit,'(8f7.2)') (ptop(j,ibox),ibox=1,ncolprint) +#else + write(6,'(a1)') ' ' + write(6,'(a2,1X,5(a7,1X),a50)') + & 'ilev', + & 'pfull','at', + & 'cc*100','dem_s','dtau_s', + & 'cchar' + +! do 4012 ilev=1,nlev +! write(6,'(60i2)') (box(i,ilev),i=1,ncolprint) +! write(6,'(i2,1X,5(f7.2,1X),50(a1))') +! & ilev, +! & pfull(j,ilev)/100.,at(j,ilev), +! & cc(j,ilev)*100.0,dem_s(j,ilev),dtau_s(j,ilev) +! & ,(cchar(acc(ilev,ibox)+1),ibox=1,ncolprint) +!4012 continue + write (6,'(a)') 'skt(j):' + write (6,'(8f7.2)') skt(j) + + write (6,'(8I7)') (ibox,ibox=1,ncolprint) + + write (6,'(a)') 'tau:' + write (6,'(8f7.2)') (tau(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'tb:' + write (6,'(8f7.2)') (tb(j,ibox),ibox=1,ncolprint) + + write (6,'(a)') 'ptop:' + write (6,'(8f7.2)') (ptop(j,ibox),ibox=1,ncolprint) +#endif endif enddo diff --git a/src/atmos_param/cosp/icarus-scops-3.7/isccp_cloud_types.f b/src/atmos_param/cosp/icarus-scops-3.7/isccp_cloud_types.F similarity index 88% rename from src/atmos_param/cosp/icarus-scops-3.7/isccp_cloud_types.f rename to src/atmos_param/cosp/icarus-scops-3.7/isccp_cloud_types.F index 519a14e375..1478be8a45 100644 --- a/src/atmos_param/cosp/icarus-scops-3.7/isccp_cloud_types.f +++ b/src/atmos_param/cosp/icarus-scops-3.7/isccp_cloud_types.F @@ -1,11 +1,17 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- + +! $Id: isccp_cloud_types.F,v 20.0 2013/12/13 23:16:03 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 -! $Id: isccp_cloud_types.f,v 19.0 2012/01/06 20:04:22 fms Exp $ -! $Name: siena_201207 $ +#endif - SUBROUTINE ISCCP_CLOUD_TYPES( +#ifdef COSP_GFDL + SUBROUTINE ISCCP_CLOUD_TYPES( & debug, & debugcol, & npoints, @@ -39,11 +45,48 @@ SUBROUTINE ISCCP_CLOUD_TYPES( & boxtau, & boxptop, & dtau_col, - & dem_col, - & passing_in_column_data + & dem_col + &) +#else + SUBROUTINE ISCCP_CLOUD_TYPES( + & debug, + & debugcol, + & npoints, + & sunlit, + & nlev, + & ncol, + & seed, + & pfull, + & phalf, + & qv, + & cc, + & conv, + & dtau_s, + & dtau_c, + & top_height, + & top_height_direction, + & overlap, + & frac_out, + & skt, + & emsfc_lw, + & at, + & dem_s, + & dem_c, + & fq_isccp, + & totalcldarea, + & meanptop, + & meantaucld, + & meanalbedocld, + & meantb, + & meantbclr, + & boxtau, + & boxptop &) +#endif -!$Id: isccp_cloud_types.f,v 19.0 2012/01/06 20:04:22 fms Exp $ +#ifndef COSP_GFDL +!$Id: isccp_cloud_types.F,v 20.0 2013/12/13 23:16:03 fms Exp $ +#endif ! *****************************COPYRIGHT**************************** ! (c) British Crown Copyright 2009, the Met Office. @@ -200,18 +243,17 @@ SUBROUTINE ISCCP_CLOUD_TYPES( ! Equivalent of BOX in original version, but ! indexed by column then row, rather than ! by row then column - - REAL dtau_col(npoints,ncol,nlev) +#ifdef COSP_GFDL + REAL dtau_col(npoints,ncol,nlev) ! tau values obtained from model ! stochastic columns - REAL dem_col(npoints,ncol,nlev) + REAL dem_col(npoints,ncol,nlev) ! lw emissivity values obtained ! from model stochastic columns + +#endif - LOGICAL passing_in_column_data - ! tau and emissivity from model columns - ! is passed in ? ! ------ @@ -327,6 +369,7 @@ SUBROUTINE ISCCP_CLOUD_TYPES( & ncolprint &) +#ifdef COSP_GFDL CALL ICARUS( & debug, & debugcol, @@ -358,11 +401,45 @@ SUBROUTINE ISCCP_CLOUD_TYPES( & meantb, & meantbclr, & boxtau, - & boxptop, + & boxptop, & dtau_col, - & dem_col, - & passing_in_column_data + & dem_col + &) +#else + CALL ICARUS( + & debug, + & debugcol, + & npoints, + & sunlit, + & nlev, + & ncol, + & pfull, + & phalf, + & qv, + & cc, + & conv, + & dtau_s, + & dtau_c, + & top_height, + & top_height_direction, + & overlap, + & frac_out, + & skt, + & emsfc_lw, + & at, + & dem_s, + & dem_c, + & fq_isccp, + & totalcldarea, + & meanptop, + & meantaucld, + & meanalbedocld, + & meantb, + & meantbclr, + & boxtau, + & boxptop &) +#endif return end diff --git a/src/atmos_param/cosp/icarus-scops-3.7/scops.f b/src/atmos_param/cosp/icarus-scops-3.7/scops.F similarity index 93% rename from src/atmos_param/cosp/icarus-scops-3.7/scops.f rename to src/atmos_param/cosp/icarus-scops-3.7/scops.F index df1c66479e..0391bc7324 100644 --- a/src/atmos_param/cosp/icarus-scops-3.7/scops.f +++ b/src/atmos_param/cosp/icarus-scops-3.7/scops.F @@ -1,13 +1,16 @@ - - subroutine scops(npoints,nlev,ncol,seed,cc,conv, - & overlap,frac_out,ncolprint) +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: scops.f,v 19.0 2012/01/06 20:04:24 fms Exp $ -! $Name: siena_201207 $ - + +! $Id: scops.F,v 20.0 2013/12/13 23:16:04 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif + subroutine scops(npoints,nlev,ncol,seed,cc,conv, + & overlap,frac_out,ncolprint) ! *****************************COPYRIGHT**************************** @@ -182,7 +185,11 @@ subroutine scops(npoints,nlev,ncol,seed,cc,conv, enddo ELSE DO ibox=1,ncol - include 'congvec.inc' +#ifdef COSP_GFDL +#include "congvec.H" +#else + include 'congvec.f' +#endif ! select random pixels from the non-convective ! part the gridbox ( some will be converted into ! convective pixels below ) @@ -251,28 +258,32 @@ subroutine scops(npoints,nlev,ncol,seed,cc,conv, ! Reset threshold - include 'congvec.inc' +#ifdef COSP_GFDL +#include "congvec.H" +#else + include 'congvec.f' +#endif do j=1,npoints threshold(j,ibox)= !if max overlapped conv cloud - & maxocc(j,ibox) * ( - & boxpos(j,ibox) - & ) + + & maxocc(j,ibox) * ( + & boxpos(j,ibox) + & ) + !else & (1-maxocc(j,ibox)) * ( !if max overlapped strat cloud & (maxosc(j,ibox)) * ( !threshold=boxpos - & threshold(j,ibox) - & ) + + & threshold(j,ibox) + & ) + !else & (1-maxosc(j,ibox)) * ( !threshold_min=random[thrmin,1] & threshold_min(j,ibox)+ - & (1-threshold_min(j,ibox))*ran(j) + & (1-threshold_min(j,ibox))*ran(j) + & ) & ) - & ) enddo ENDDO ! ibox @@ -331,7 +342,7 @@ subroutine scops(npoints,nlev,ncol,seed,cc,conv, write (6,'(8f5.2)') (threshold(j,ibox),ibox=1,ncolprint) write (6,'(a)') 'frac_out_pp_rev:' - write (6,'(8f5.2)') + write (6,'(8f5.2)') & ((frac_out(j,ibox,ilev2),ibox=1,ncolprint),ilev2=1,nlev) enddo endif diff --git a/src/atmos_param/cosp/llnl/cosp_radar.f90 b/src/atmos_param/cosp/llnl/cosp_radar.F90 similarity index 83% rename from src/atmos_param/cosp/llnl/cosp_radar.f90 rename to src/atmos_param/cosp/llnl/cosp_radar.F90 index 37bffb902a..1ec3a61899 100644 --- a/src/atmos_param/cosp/llnl/cosp_radar.f90 +++ b/src/atmos_param/cosp/llnl/cosp_radar.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: cosp_radar.f90,v 19.0 2012/01/06 20:04:26 fms Exp $ -! $Name: siena_201207 $ + +! $Id: cosp_radar.F90,v 20.0 2013/12/13 23:16:05 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) British Crown Copyright 2008, the Met Office. ! All rights reserved. @@ -40,7 +45,7 @@ MODULE MOD_COSP_RADAR IMPLICIT NONE INTERFACE - subroutine radar_simulator(me,freq,k2,do_ray,use_gas_abs,use_mie_table,mt, & + subroutine radar_simulator(freq,k2,do_ray,use_gas_abs,use_mie_table,mt, & nhclass,hp,nprof,ngate,nsizes,D,hgt_matrix,hm_matrix,re_matrix,p_matrix,t_matrix, & rh_matrix,Ze_non,Ze_ray,h_atten_to_vol,g_atten_to_vol,dBZe, & g_to_vol_in,g_to_vol_out) @@ -52,10 +57,14 @@ subroutine radar_simulator(me,freq,k2,do_ray,use_gas_abs,use_mie_table,mt, & use radar_simulator_types implicit none ! ----- INPUTS ----- - integer, intent(in) :: me type(mie), intent(in) :: mt type(class_param) :: hp +#ifdef COSP_GFDL + real*8, intent(in) :: freq + real*8, intent(inout) :: k2 +#else real*8, intent(in) :: freq,k2 +#endif integer, intent(in) :: do_ray,use_gas_abs,use_mie_table, & nhclass,nprof,ngate,nsizes real*8, dimension(nsizes), intent(in) :: D @@ -77,45 +86,45 @@ end subroutine radar_simulator !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% !------------------- SUBROUTINE COSP_RADAR ------------------------ !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -SUBROUTINE COSP_RADAR(me, gbx,sgx,sghydro,z) +SUBROUTINE COSP_RADAR(gbx,sgx,sghydro,z) IMPLICIT NONE ! Arguments - integer, intent(in) :: me +#ifdef COSP_GFDL type(cosp_gridbox),intent(inout) :: gbx ! Gridbox info +#else + type(cosp_gridbox),intent(in) :: gbx ! Gridbox info +#endif type(cosp_subgrid),intent(in) :: sgx ! Subgrid info type(cosp_sghydro),intent(in) :: sghydro ! Subgrid info for hydrometeors type(cosp_sgradar),intent(inout) :: z ! Output from simulator, subgrid ! Local variables - integer :: & - nsizes ! num of discrete drop sizes - real*8 :: & - freq, & ! radar frequency (GHz) - k2 ! |K|^2, -1=use frequency dependent default + freq, & ! radar frequency (GHz) + k2 ! |K|^2, -1=use frequency dependent default real*8, dimension(:,:), allocatable :: & g_to_vol ! integrated atten due to gases, r>v (dB) real*8, dimension(:,:), allocatable :: & - Ze_non, & ! radar reflectivity withOUT attenuation (dBZ) - Ze_ray, & ! Rayleigh reflectivity (dBZ) - h_atten_to_vol, & ! attenuation by hydromets, radar to vol (dB) - g_atten_to_vol, & ! gaseous atteunation, radar to vol (dB) - dBZe, & ! effective radar reflectivity factor (dBZ) - hgt_matrix, & ! height of hydrometeors (km) + Ze_non, & ! radar reflectivity withOUT attenuation (dBZ) + Ze_ray, & ! Rayleigh reflectivity (dBZ) + h_atten_to_vol, & ! attenuation by hydromets, radar to vol (dB) + g_atten_to_vol, & ! gaseous atteunation, radar to vol (dB) + dBZe, & ! effective radar reflectivity factor (dBZ) + hgt_matrix, & ! height of hydrometeors (km) t_matrix, & !temperature (k) p_matrix, & !pressure (hPa) rh_matrix !relative humidity (%) real*8, dimension(:,:,:), allocatable :: & - hm_matrix, & ! hydrometeor mixing ratio (g kg^-1) + hm_matrix, & ! hydrometeor mixing ratio (g kg^-1) re_matrix integer, parameter :: one = 1 logical :: hgt_reversed - integer :: pr,i,j,k,unt + integer :: pr,i ! ----- main program settings ------ @@ -177,12 +186,12 @@ SUBROUTINE COSP_RADAR(me, gbx,sgx,sghydro,z) ! ----- call radar simulator ----- if (pr == 1) then ! Compute gaseous attenuation for all profiles - call radar_simulator(me,freq,k2,gbx%do_ray,gbx%use_gas_abs,gbx%use_mie_tables,gbx%mt, & ! v0.2: mt changed to gbx%mt, roj + call radar_simulator(freq,k2,gbx%do_ray,gbx%use_gas_abs,gbx%use_mie_tables,gbx%mt, & ! v0.2: mt changed to gbx%mt, roj gbx%Nhydro,gbx%hp,gbx%Npoints,gbx%Nlevels,gbx%nsizes,gbx%D, & ! v0.2: hp->gbx%hp, D->gbx%d, nsizes->gbx%nsizes, roj hgt_matrix,hm_matrix,re_matrix,p_matrix,t_matrix,rh_matrix, & Ze_non,Ze_ray,h_atten_to_vol,g_atten_to_vol,dBZe,g_to_vol_out=g_to_vol) else ! Use gaseous atteunuation for pr = 1 - call radar_simulator(me, freq,k2,gbx%do_ray,gbx%use_gas_abs,gbx%use_mie_tables,gbx%mt, & + call radar_simulator(freq,k2,gbx%do_ray,gbx%use_gas_abs,gbx%use_mie_tables,gbx%mt, & gbx%Nhydro,gbx%hp,gbx%Npoints,gbx%Nlevels,gbx%nsizes,gbx%D, & hgt_matrix,hm_matrix,re_matrix,p_matrix,t_matrix,rh_matrix, & Ze_non,Ze_ray,h_atten_to_vol,g_atten_to_vol,dBZe,g_to_vol_in=g_to_vol) @@ -199,13 +208,13 @@ SUBROUTINE COSP_RADAR(me, gbx,sgx,sghydro,z) ! Change undefined value to one defined in COSP where (z%Ze_tot == -999.0) z%Ze_tot = R_UNDEF - + deallocate(hgt_matrix,p_matrix,t_matrix,rh_matrix) deallocate(hm_matrix,re_matrix, & Ze_non,Ze_ray,h_atten_to_vol,g_atten_to_vol,dBZe) deallocate(g_to_vol) - ! deallocate(mt_ttl,mt_tti) !v0.2: roj feb 2008 can not be done here, + ! deallocate(mt_ttl,mt_tti) !v0.2: roj feb 2008 can not be done here, !these variables now part of gbx structure and dealocated later END SUBROUTINE COSP_RADAR diff --git a/src/atmos_param/cosp/llnl/llnl_stats.f90 b/src/atmos_param/cosp/llnl/llnl_stats.F90 similarity index 96% rename from src/atmos_param/cosp/llnl/llnl_stats.f90 rename to src/atmos_param/cosp/llnl/llnl_stats.F90 index a03c19cc9f..490d1f7f01 100644 --- a/src/atmos_param/cosp/llnl/llnl_stats.f90 +++ b/src/atmos_param/cosp/llnl/llnl_stats.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: llnl_stats.f90,v 19.0 2012/01/06 20:04:28 fms Exp $ -! $Name: siena_201207 $ +! $Id: llnl_stats.F90,v 20.0 2013/12/13 23:16:06 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) 2008, Lawrence Livermore National Security Limited Liability Corporation. ! All rights reserved. @@ -69,7 +74,7 @@ FUNCTION COSP_CFAD(Npoints,Ncolumns,Nlevels,Nbins,x,xmin,xmax,bmin,bwidth) ! into the smallest bin and largest bin, respectively. do j = 1, Nlevels, 1 do k = 1, Ncolumns, 1 - do i = 1, Npoints, 1 + do i = 1, Npoints, 1 if (x(i,k,j) == R_GROUND) then cosp_cfad(i,:,j) = R_UNDEF elseif ((x(i,k,j) >= xmin) .and. (x(i,k,j) <= xmax)) then @@ -107,8 +112,8 @@ SUBROUTINE COSP_LIDAR_ONLY_CLOUD(Npoints,Ncolumns,Nlevels,beta_tot,beta_mol,Ze_t integer :: flag_cld !cloudy column integer :: pr,i,j - lidar_only_freq_cloud = 0.0 - tcc = 0.0 + lidar_only_freq_cloud = 0.0 + tcc = 0.0 do pr=1,Npoints do i=1,Ncolumns flag_sat = 0 diff --git a/src/atmos_param/cosp/llnl/pf_to_mr.f b/src/atmos_param/cosp/llnl/pf_to_mr.F similarity index 86% rename from src/atmos_param/cosp/llnl/pf_to_mr.f rename to src/atmos_param/cosp/llnl/pf_to_mr.F index 70e63eb906..97c4f3be02 100644 --- a/src/atmos_param/cosp/llnl/pf_to_mr.f +++ b/src/atmos_param/cosp/llnl/pf_to_mr.F @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: pf_to_mr.f,v 19.0 2012/01/06 20:04:30 fms Exp $ -! $Name: siena_201207 $ +! $Id: pf_to_mr.F,v 20.0 2013/12/13 23:16:07 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) 2008, Lawrence Livermore National Security Limited Liability Corporation. ! All rights reserved. @@ -29,7 +34,7 @@ ! IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ! OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - subroutine pf_to_mr(me,npoints,nlev,ncol,rain_ls,snow_ls,grpl_ls, + subroutine pf_to_mr(npoints,nlev,ncol,rain_ls,snow_ls,grpl_ls, & rain_cv,snow_cv,prec_frac, & p,t,mx_rain_ls,mx_snow_ls,mx_grpl_ls, & mx_rain_cv,mx_snow_cv) @@ -37,16 +42,15 @@ subroutine pf_to_mr(me,npoints,nlev,ncol,rain_ls,snow_ls,grpl_ls, implicit none - integer me INTEGER npoints ! number of model points in the horizontal INTEGER nlev ! number of model levels in column INTEGER ncol ! number of subcolumns - INTEGER i,j,ilev,ibox + INTEGER j,ilev,ibox - REAL rain_ls(npoints,nlev),snow_ls(npoints,nlev) ! large-scale precipitation flux + REAL rain_ls(npoints,nlev),snow_ls(npoints,nlev) ! large-scale precip. flux REAL grpl_ls(npoints,nlev) - REAL rain_cv(npoints,nlev),snow_cv(npoints,nlev) ! convective precipitation flux + REAL rain_cv(npoints,nlev),snow_cv(npoints,nlev) ! convective precip. flux REAL prec_frac(npoints,ncol,nlev) ! 0 -> clear sky ! 1 -> LS precipitation @@ -61,7 +65,7 @@ subroutine pf_to_mr(me,npoints,nlev,ncol,rain_ls,snow_ls,grpl_ls, REAL term4r_ls,term4s_ls,term4g_ls,term4r_cv,term4s_cv REAL term1x2r,term1x2s,term1x2g,t123r,t123s,t123g - ! method from Khairoutdinov and Randall (2003 JAS) + ! method from Khairoutdinov and Randall (2003 JAS) ! --- List of constants from Appendix B ! Constant in fall speed formula @@ -114,19 +118,19 @@ subroutine pf_to_mr(me,npoints,nlev,ncol,rain_ls,snow_ls,grpl_ls, mx_snow_cv(j,ibox,ilev)=0. if ((prec_frac(j,ibox,ilev) .eq. 1.) .or. & (prec_frac(j,ibox,ilev) .eq. 3.)) then - mx_rain_ls(j,ibox,ilev)= - & (term4r_ls**(1./(1.+br/4.)))/rho + mx_rain_ls(j,ibox,ilev)= + & (term4r_ls**(1./(1.+br/4.)))/rho mx_snow_ls(j,ibox,ilev)= - & (term4s_ls**(1./(1.+bs/4.)))/rho - mx_grpl_ls(j,ibox,ilev)= - & (term4g_ls**(1./(1.+bg/4.)))/rho + & (term4s_ls**(1./(1.+bs/4.)))/rho + mx_grpl_ls(j,ibox,ilev)= + & (term4g_ls**(1./(1.+bg/4.)))/rho endif if ((prec_frac(j,ibox,ilev) .eq. 2.) .or. & (prec_frac(j,ibox,ilev) .eq. 3.)) then - mx_rain_cv(j,ibox,ilev)= - & (term4r_cv**(1./(1.+br/4.)))/rho + mx_rain_cv(j,ibox,ilev)= + & (term4r_cv**(1./(1.+br/4.)))/rho mx_snow_cv(j,ibox,ilev)= - & (term4s_cv**(1./(1.+bs/4.)))/rho + & (term4s_cv**(1./(1.+bs/4.)))/rho endif enddo ! loop over ncol enddo ! loop over npoints diff --git a/src/atmos_param/cosp/llnl/prec_scops.f b/src/atmos_param/cosp/llnl/prec_scops.F similarity index 55% rename from src/atmos_param/cosp/llnl/prec_scops.f rename to src/atmos_param/cosp/llnl/prec_scops.F index cbff5b6436..4b681dc52c 100644 --- a/src/atmos_param/cosp/llnl/prec_scops.f +++ b/src/atmos_param/cosp/llnl/prec_scops.F @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- -! $Id: prec_scops.f,v 19.0 2012/01/06 20:04:32 fms Exp $ -! $Name: siena_201207 $ +! $Id: prec_scops.F,v 20.0 2013/12/13 23:16:08 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! (c) 2008, Lawrence Livermore National Security Limited Liability Corporation. ! All rights reserved. @@ -51,9 +56,9 @@ subroutine prec_scops(npoints,nlev,ncol,ls_p_rate,cv_p_rate, REAL prec_frac(npoints,ncol,nlev) ! 0 -> clear sky ! 1 -> LS precipitation ! 2 -> CONV precipitation - ! 3 -> both + ! 3 -> both !TOA to SURFACE!!!!!!!!!!!!!!!!!! - + INTEGER flag_ls, flag_cv INTEGER frac_out_ls(npoints,ncol),frac_out_cv(npoints,ncol) !flag variables for ! stratiform cloud and convective cloud in the vertical column @@ -62,32 +67,32 @@ subroutine prec_scops(npoints,nlev,ncol,ls_p_rate,cv_p_rate, if (cv_col .eq. 0) cv_col=1 do ilev=1,nlev - do ibox=1,ncol - do j=1,npoints - prec_frac(j,ibox,ilev) = 0 + do ibox=1,ncol + do j=1,npoints + prec_frac(j,ibox,ilev) = 0 + enddo enddo enddo - enddo do j=1,npoints do ibox=1,ncol - frac_out_ls(j,ibox)=0 - frac_out_cv(j,ibox)=0 - flag_ls=0 - flag_cv=0 + frac_out_ls(j,ibox)=0 + frac_out_cv(j,ibox)=0 + flag_ls=0 + flag_cv=0 do ilev=1,nlev - if (frac_out(j,ibox,ilev) .eq. 1) then - flag_ls=1 - endif - if (frac_out(j,ibox,ilev) .eq. 2) then - flag_cv=1 - endif + if (frac_out(j,ibox,ilev) .eq. 1) then + flag_ls=1 + endif + if (frac_out(j,ibox,ilev) .eq. 2) then + flag_cv=1 + endif enddo !loop over nlev if (flag_ls .eq. 1) then - frac_out_ls(j,ibox)=1 + frac_out_ls(j,ibox)=1 endif if (flag_cv .eq. 1) then - frac_out_cv(j,ibox)=1 + frac_out_cv(j,ibox)=1 endif enddo ! loop over ncol enddo ! loop over npoints @@ -96,87 +101,87 @@ subroutine prec_scops(npoints,nlev,ncol,ls_p_rate,cv_p_rate, do j=1,npoints flag_ls=0 flag_cv=0 - + if (ls_p_rate(j,1) .gt. 0.) then - do ibox=1,ncol ! possibility ONE - if (frac_out(j,ibox,1) .eq. 1) then - prec_frac(j,ibox,1) = 1 - flag_ls=1 - endif - enddo ! loop over ncol - if (flag_ls .eq. 0) then ! possibility THREE - do ibox=1,ncol - if (frac_out(j,ibox,2) .eq. 1) then - prec_frac(j,ibox,1) = 1 - flag_ls=1 - endif - enddo ! loop over ncol - endif - if (flag_ls .eq. 0) then ! possibility Four - do ibox=1,ncol - if (frac_out_ls(j,ibox) .eq. 1) then + do ibox=1,ncol ! possibility ONE + if (frac_out(j,ibox,1) .eq. 1) then + prec_frac(j,ibox,1) = 1 + flag_ls=1 + endif + enddo ! loop over ncol + if (flag_ls .eq. 0) then ! possibility THREE + do ibox=1,ncol + if (frac_out(j,ibox,2) .eq. 1) then + prec_frac(j,ibox,1) = 1 + flag_ls=1 + endif + enddo ! loop over ncol + endif + if (flag_ls .eq. 0) then ! possibility Four + do ibox=1,ncol + if (frac_out_ls(j,ibox) .eq. 1) then prec_frac(j,ibox,1) = 1 flag_ls=1 - endif - enddo ! loop over ncol - endif - if (flag_ls .eq. 0) then ! possibility Five - do ibox=1,ncol -! prec_frac(j,1:ncol,1) = 1 - prec_frac(j,ibox,1) = 1 - enddo ! loop over ncol - endif + endif + enddo ! loop over ncol + endif + if (flag_ls .eq. 0) then ! possibility Five + do ibox=1,ncol + ! prec_frac(j,1:ncol,1) = 1 + prec_frac(j,ibox,1) = 1 + enddo ! loop over ncol + endif endif ! There is large scale precipitation - + if (cv_p_rate(j,1) .gt. 0.) then do ibox=1,ncol ! possibility ONE if (frac_out(j,ibox,1) .eq. 2) then if (prec_frac(j,ibox,1) .eq. 0) then + prec_frac(j,ibox,1) = 2 + else + prec_frac(j,ibox,1) = 3 + endif + flag_cv=1 + endif + enddo ! loop over ncol + if (flag_cv .eq. 0) then ! possibility THREE + do ibox=1,ncol + if (frac_out(j,ibox,2) .eq. 2) then + if (prec_frac(j,ibox,1) .eq. 0) then prec_frac(j,ibox,1) = 2 - else - prec_frac(j,ibox,1) = 3 - endif - flag_cv=1 - endif - enddo ! loop over ncol - if (flag_cv .eq. 0) then ! possibility THREE - do ibox=1,ncol - if (frac_out(j,ibox,2) .eq. 2) then - if (prec_frac(j,ibox,1) .eq. 0) then - prec_frac(j,ibox,1) = 2 else - prec_frac(j,ibox,1) = 3 + prec_frac(j,ibox,1) = 3 endif flag_cv=1 - endif - enddo ! loop over ncol - endif - if (flag_cv .eq. 0) then ! possibility Four - do ibox=1,ncol - if (frac_out_cv(j,ibox) .eq. 1) then - if (prec_frac(j,ibox,1) .eq. 0) then - prec_frac(j,ibox,1) = 2 + endif + enddo ! loop over ncol + endif + if (flag_cv .eq. 0) then ! possibility Four + do ibox=1,ncol + if (frac_out_cv(j,ibox) .eq. 1) then + if (prec_frac(j,ibox,1) .eq. 0) then + prec_frac(j,ibox,1) = 2 else - prec_frac(j,ibox,1) = 3 + prec_frac(j,ibox,1) = 3 endif flag_cv=1 - endif - enddo ! loop over ncol - endif - if (flag_cv .eq. 0) then ! possibility Five - do ibox=1,cv_col - if (prec_frac(j,ibox,1) .eq. 0) then - prec_frac(j,ibox,1) = 2 + endif + enddo ! loop over ncol + endif + if (flag_cv .eq. 0) then ! possibility Five + do ibox=1,cv_col + if (prec_frac(j,ibox,1) .eq. 0) then + prec_frac(j,ibox,1) = 2 else - prec_frac(j,ibox,1) = 3 + prec_frac(j,ibox,1) = 3 + endif + enddo !loop over cv_col endif - enddo !loop over cv_col endif - endif - ! There is convective precipitation - - enddo ! loop over npoints + ! There is convective precipitation + + enddo ! loop over npoints ! end of initializing the top layer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -186,7 +191,7 @@ subroutine prec_scops(npoints,nlev,ncol,ls_p_rate,cv_p_rate, do j=1,npoints flag_ls=0 flag_cv=0 - + if (ls_p_rate(j,ilev) .gt. 0.) then do ibox=1,ncol ! possibility ONE&TWO if ((frac_out(j,ibox,ilev) .eq. 1) .or. @@ -195,81 +200,81 @@ subroutine prec_scops(npoints,nlev,ncol,ls_p_rate,cv_p_rate, prec_frac(j,ibox,ilev) = 1 flag_ls=1 endif - enddo ! loop over ncol - if ((flag_ls .eq. 0) .and. (ilev .lt. nlev)) then ! possibility THREE - do ibox=1,ncol - if (frac_out(j,ibox,ilev+1) .eq. 1) then + enddo ! loop over ncol + if ((flag_ls .eq. 0) .and. (ilev .lt. nlev)) then ! possibility THREE + do ibox=1,ncol + if (frac_out(j,ibox,ilev+1) .eq. 1) then prec_frac(j,ibox,ilev) = 1 flag_ls=1 - endif - enddo ! loop over ncol - endif - if (flag_ls .eq. 0) then ! possibility Four - do ibox=1,ncol - if (frac_out_ls(j,ibox) .eq. 1) then + endif + enddo ! loop over ncol + endif + if (flag_ls .eq. 0) then ! possibility Four + do ibox=1,ncol + if (frac_out_ls(j,ibox) .eq. 1) then prec_frac(j,ibox,ilev) = 1 flag_ls=1 - endif - enddo ! loop over ncol - endif - if (flag_ls .eq. 0) then ! possibility Five - do ibox=1,ncol -! prec_frac(j,1:ncol,ilev) = 1 - prec_frac(j,ibox,ilev) = 1 - enddo ! loop over ncol + endif + enddo ! loop over ncol + endif + if (flag_ls .eq. 0) then ! possibility Five + do ibox=1,ncol +! prec_frac(j,1:ncol,ilev) = 1 + prec_frac(j,ibox,ilev) = 1 + enddo ! loop over ncol endif - endif ! There is large scale precipitation - + endif ! There is large scale precipitation + if (cv_p_rate(j,ilev) .gt. 0.) then do ibox=1,ncol ! possibility ONE&TWO if ((frac_out(j,ibox,ilev) .eq. 2) .or. & ((prec_frac(j,ibox,ilev-1) .eq. 2) & .or. (prec_frac(j,ibox,ilev-1) .eq. 3))) then if (prec_frac(j,ibox,ilev) .eq. 0) then - prec_frac(j,ibox,ilev) = 2 - else - prec_frac(j,ibox,ilev) = 3 - endif - flag_cv=1 - endif - enddo ! loop over ncol - if ((flag_cv .eq. 0) .and. (ilev .lt. nlev)) then ! possibility THREE - do ibox=1,ncol - if (frac_out(j,ibox,ilev+1) .eq. 2) then - if (prec_frac(j,ibox,ilev) .eq. 0) then - prec_frac(j,ibox,ilev) = 2 + prec_frac(j,ibox,ilev) = 2 + else + prec_frac(j,ibox,ilev) = 3 + endif + flag_cv=1 + endif + enddo ! loop over ncol + if ((flag_cv .eq. 0) .and. (ilev .lt. nlev)) then ! possibility THREE + do ibox=1,ncol + if (frac_out(j,ibox,ilev+1) .eq. 2) then + if (prec_frac(j,ibox,ilev) .eq. 0) then + prec_frac(j,ibox,ilev) = 2 else - prec_frac(j,ibox,ilev) = 3 + prec_frac(j,ibox,ilev) = 3 endif flag_cv=1 - endif - enddo ! loop over ncol - endif - if (flag_cv .eq. 0) then ! possibility Four - do ibox=1,ncol - if (frac_out_cv(j,ibox) .eq. 1) then - if (prec_frac(j,ibox,ilev) .eq. 0) then - prec_frac(j,ibox,ilev) = 2 + endif + enddo ! loop over ncol + endif + if (flag_cv .eq. 0) then ! possibility Four + do ibox=1,ncol + if (frac_out_cv(j,ibox) .eq. 1) then + if (prec_frac(j,ibox,ilev) .eq. 0) then + prec_frac(j,ibox,ilev) = 2 else - prec_frac(j,ibox,ilev) = 3 + prec_frac(j,ibox,ilev) = 3 endif flag_cv=1 - endif - enddo ! loop over ncol - endif - if (flag_cv .eq. 0) then ! possibility Five - do ibox=1,cv_col - if (prec_frac(j,ibox,ilev) .eq. 0) then - prec_frac(j,ibox,ilev) = 2 + endif + enddo ! loop over ncol + endif + if (flag_cv .eq. 0) then ! possibility Five + do ibox=1,cv_col + if (prec_frac(j,ibox,ilev) .eq. 0) then + prec_frac(j,ibox,ilev) = 2 else - prec_frac(j,ibox,ilev) = 3 + prec_frac(j,ibox,ilev) = 3 + endif + enddo !loop over cv_col endif - enddo !loop over cv_col - endif endif ! There is convective precipitation - - enddo ! loop over npoints - enddo ! loop over nlev + + enddo ! loop over npoints + enddo ! loop over nlev end diff --git a/src/atmos_param/cosp/null/cosp_driver.F90 b/src/atmos_param/cosp/null/cosp_driver.F90 deleted file mode 100644 index 3d3313a09e..0000000000 --- a/src/atmos_param/cosp/null/cosp_driver.F90 +++ /dev/null @@ -1,89 +0,0 @@ -module cosp_driver_mod - -use time_manager_mod, only: time_type - -use fms_mod, only: error_mesg, FATAL, WARNING - -implicit none -private - -character(len=128) :: version = '$Id: cosp_driver.F90,v 19.0 2012/01/06 20:04:34 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - -public cosp_driver, cosp_driver_init, cosp_driver_end - -contains - -!###################################################################### - -subroutine cosp_driver_init (lonb, latb, Time_diag, axes,kd_in, ncol_in) - - real, dimension(:,:), intent(in) :: lonb, latb - type(time_type), intent(in) :: Time_diag - integer, dimension(4), intent(in) :: axes - integer, intent(in) :: kd_in, ncol_in - -call error_mesg('cosp_driver_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cosp_driver_init - - - -!##################################################################### - - -subroutine cosp_driver & - (lat_in, lon_in, daytime_in, phalf_plus, p_full_in, zhalf_plus,& - z_full_in, u_wind_in, v_wind_in, mr_ozone_in, & - T_in, sh_in, tca_in, cca_in, lsliq_in, lsice_in, ccliq_in, & - ccice_in, fl_lsrain_in, fl_lssnow_in, fl_lsgrpl_in, & - fl_ccrain_in, & - fl_ccsnow_in, reff_lsclliq_in, reff_lsclice_in, & - reff_lsprliq_in, reff_lsprice_in, reff_ccclliq_in, & - reff_ccclice_in, reff_ccprliq_in, reff_ccprice_in, & - skt_in, land_in, Time_diag, is, js, stoch_mr_liq_in, & - stoch_mr_ice_in, stoch_size_liq_in, stoch_size_frz_in, & - tau_stoch_in, lwem_stoch_in, stoch_cloud_type_in) -!-------------------------------------------------------------------- -! subroutine cosp_driver is the interface between the cosp simulator -! code and the AM model. -!-------------------------------------------------------------------- -real, dimension(:,:), intent(in) :: lat_in, lon_in, skt_in, land_in, & - u_wind_in, v_wind_in -real, dimension(:,:), intent(in) :: daytime_in -real, dimension(:,:,:), intent(in) :: phalf_plus, p_full_in, & - zhalf_plus, z_full_in, T_in, sh_in, & - tca_in, cca_in, lsliq_in, lsice_in, ccliq_in, ccice_in, & - fl_lsrain_in, fl_lssnow_in, fl_lsgrpl_in, fl_ccrain_in, & - fl_ccsnow_in, mr_ozone_in, & - reff_lsclliq_in, reff_lsclice_in, reff_lsprliq_in, & - reff_lsprice_in, reff_ccclliq_in, reff_ccclice_in, & - reff_ccprliq_in, reff_ccprice_in -real, dimension(:,:,:,:), intent(in), optional :: & - tau_stoch_in, lwem_stoch_in, stoch_cloud_type_in, & - stoch_mr_liq_in, stoch_mr_ice_in, stoch_size_liq_in, & - stoch_size_frz_in -type(time_type), intent(in) :: Time_diag -integer, intent(in) :: is, js - -call error_mesg('cosp_driver', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cosp_driver - - - -!##################################################################### - -subroutine cosp_driver_end - -call error_mesg('cosp_driver_end', & - 'This module is not supported as part of the public release', FATAL) - - -end subroutine cosp_driver_end - -!#################################################################### - -end module cosp_driver_mod diff --git a/src/atmos_param/cosp/quickbeam/array_lib.f90 b/src/atmos_param/cosp/quickbeam/array_lib.F90 similarity index 96% rename from src/atmos_param/cosp/quickbeam/array_lib.f90 rename to src/atmos_param/cosp/quickbeam/array_lib.F90 index 58d5cb6754..476b885da5 100644 --- a/src/atmos_param/cosp/quickbeam/array_lib.f90 +++ b/src/atmos_param/cosp/quickbeam/array_lib.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: array_lib.f90,v 19.0 2012/01/06 20:04:36 fms Exp $ -! $Name: siena_201207 $ + +! $Id: array_lib.F90,v 20.0 2013/12/13 23:16:11 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! ARRAY_LIB: Array procedures for F90 ! Compiled/Modified: diff --git a/src/atmos_param/cosp/quickbeam/atmos_lib.f90 b/src/atmos_param/cosp/quickbeam/atmos_lib.F90 similarity index 97% rename from src/atmos_param/cosp/quickbeam/atmos_lib.f90 rename to src/atmos_param/cosp/quickbeam/atmos_lib.F90 index b161be8612..dedcce180b 100644 --- a/src/atmos_param/cosp/quickbeam/atmos_lib.f90 +++ b/src/atmos_param/cosp/quickbeam/atmos_lib.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: atmos_lib.f90,v 19.0 2012/01/06 20:04:38 fms Exp $ -! $Name: siena_201207 $ + +! $Id: atmos_lib.F90,v 20.0 2013/12/13 23:16:12 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! ATMOS_LIB: Atmospheric science procedures for F90 ! Compiled/Modified: @@ -70,7 +75,7 @@ subroutine mcclatchey(stype,hgt,prs,tk,rh) 81.2000, 69.5000, 59.5000, 51.0000, 43.7000, 37.6000, & 32.2000, 27.7000, 13.2000, 6.52000, 3.33000, 1.76000, & 0.951000,0.0671000,0.000300000/) - + tk = (/294.000, 290.000, 285.000, 279.000, 273.000, 267.000, & 261.000, 255.000, 248.000, 242.000, 235.000, 229.000, & 222.000, 216.000, 216.000, 216.000, 216.000, 216.000, & @@ -130,7 +135,7 @@ subroutine mcclatchey(stype,hgt,prs,tk,rh) 17.1606, 9.53422, 5.10154, 3.45407, 2.11168, 1.76247, & 1.55162,1.37966,0.229799,0.0245943,0.00373686,0.000702138, & 0.000162076,0.000362055,7.68645e-06/) - + case default print *, 'Must enter a profile type' stop diff --git a/src/atmos_param/cosp/quickbeam/dsd.f90 b/src/atmos_param/cosp/quickbeam/dsd.F90 similarity index 82% rename from src/atmos_param/cosp/quickbeam/dsd.f90 rename to src/atmos_param/cosp/quickbeam/dsd.F90 index 2d74a076fd..0dc20b334a 100644 --- a/src/atmos_param/cosp/quickbeam/dsd.f90 +++ b/src/atmos_param/cosp/quickbeam/dsd.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: dsd.f90,v 19.0 2012/01/06 20:04:40 fms Exp $ -! $Name: siena_201207 $ + +! $Id: dsd.F90,v 20.0 2013/12/13 23:16:13 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & dmin,dmax,apm,bpm,rho_c,p1,p2,p3,fc,scaled) @@ -68,13 +73,13 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & ! ----- INTERNAL ----- real*8 :: & - N0,D0,vu,np,dm,ld, & ! gamma, exponential variables - dmin_mm,dmax_mm,ahp,bhp, & ! power law variables - rg,log_sigma_g, & ! lognormal variables - rho_e ! particle density (kg m^-3) + N0,D0,vu,np,dm,ld, & ! gamma, exponential variables + dmin_mm,dmax_mm,ahp,bhp, & ! power law variables + rg,log_sigma_g, & ! lognormal variables + rho_e ! particle density (kg m^-3) real*8 :: tmp1, tmp2 - real*8 :: pi,rc + real*8 :: pi integer k,lidx,uidx @@ -104,10 +109,10 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & vu = p3 if(Re.le.0) then - dm = p2 - D0 = gamma(vu)/gamma(vu+1)*dm + dm = p2 + D0 = gamma(vu)/gamma(vu+1)*dm else - D0 = 2.0*Re*gamma(vu+2)/gamma(vu+3) + D0 = 2.0*Re*gamma(vu+2)/gamma(vu+3) endif if (scaled .eqv. .false.) then @@ -115,10 +120,10 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & fc = ( & ((D*1E-6)**(vu-1)*exp(-1*D/D0)) / & (apm*((D0*1E-6)**(vu+bpm))*gamma(vu+bpm)) & - ) * 1E-12 - scaled = .true. + ) * 1E-12 + scaled = .true. - endif + endif N = fc*rho_a*(Q*1E-3) @@ -133,7 +138,7 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & fc = (D*1E-6 / (gamma(vu)/(apm*np*gamma(vu+bpm)))** & (1./bpm))**vu - + scaled = .true. endif @@ -141,7 +146,7 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & N = ( & (rho_a*np*fc*(D*1E-6)**(-1.))/(gamma(vu)*tmp1**vu) * & exp(-1.*fc**(1./vu)/tmp1) & - ) * 1E-12 + ) * 1E-12 else @@ -165,33 +170,33 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & if(Re>0) then - ! if Re is set and No is set than the distribution is fully defined. - ! so we assume Re and No have already been chosen consistant with - ! the water content, Q. + ! if Re is set and No is set than the distribution is fully defined. + ! so we assume Re and No have already been chosen consistant with + ! the water content, Q. - ! print *,'using Re pass ...' + ! print *,'using Re pass ...' - ld = 1.5/Re ! units 1/um + ld = 1.5/Re ! units 1/um - N = ( & - N0*exp(-1*ld*D) & + N = ( & + N0*exp(-1*ld*D) & ) * 1E-12 else - tmp1 = 1./(1.+bpm) + tmp1 = 1./(1.+bpm) - if (scaled .eqv. .false.) then - fc = ((apm*gamma(1.+bpm)*N0)**tmp1)*(D*1E-6) - scaled = .true. + if (scaled .eqv. .false.) then + fc = ((apm*gamma(1.+bpm)*N0)**tmp1)*(D*1E-6) + scaled = .true. - endif + endif - N = ( & - N0*exp(-1.*fc*(1./(rho_a*Q*1E-3))**tmp1) & - ) * 1E-12 + N = ( & + N0*exp(-1.*fc*(1./(rho_a*Q*1E-3))**tmp1) & + ) * 1E-12 - endif + endif elseif (abs(p2+1) > 1E-8) then @@ -263,7 +268,7 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & dmax_mm = dmax*1E-3 ! :: commented lines are original method with constant density - ! rc = 500. ! (kg/m^3) + ! rc = 500. ! (kg/m^3) ! tmp1 = 6*rho_a*(bhp+4) ! tmp2 = pi*rc*(dmax_mm**(bhp+4))*(1-(dmin_mm/dmax_mm)**(bhp+4)) ! ahp = (Q*1E-3)*1E12*tmp1/tmp2 @@ -279,13 +284,13 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & uidx = infind(D,dmax) do k=lidx,uidx - N(k) = ( & + N(k) = ( & ahp*(D(k)*1E-3)**bhp & - ) * 1E-12 + ) * 1E-12 enddo - ! print *,'test=',ahp,bhp,ahp/(rho_a*Q),D(100),N(100),bpm,dmin_mm,dmax_mm + ! print *,'test=',ahp,bhp,ahp/(rho_a*Q),D(100),N(100),bpm,dmin_mm,dmax_mm ! ---------------------------------------------------------! ! // monodisperse ! @@ -320,22 +325,22 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & log_sigma_g = p3 tmp2 = (bpm*log_sigma_g)**2. if(Re.le.0) then - rg = p2 + rg = p2 else - rg =Re*exp(-2.5*(log_sigma_g**2)) + rg =Re*exp(-2.5*(log_sigma_g**2)) endif if (scaled .eqv. .false.) then fc = 0.5 * ( & - (1./((2.*rg*1E-6)**(bpm)*apm*(2.*pi)**(0.5) * & - log_sigma_g*D*0.5*1E-6)) * & - exp(-0.5*((log(0.5*D/rg)/log_sigma_g)**2.+tmp2)) & - ) * 1E-12 - scaled = .true. - + (1./((2.*rg*1E-6)**(bpm)*apm*(2.*pi)**(0.5) * & + log_sigma_g*D*0.5*1E-6)) * & + exp(-0.5*((log(0.5*D/rg)/log_sigma_g)**2.+tmp2)) & + ) * 1E-12 + scaled = .true. + endif - + N = fc*rho_a*(Q*1E-3) elseif (abs(p2+1) < 1E-8) then @@ -350,8 +355,8 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & N = 0.5*( & N0 / ((2.*pi)**(0.5)*log_sigma_g*D*0.5*1E-6) * & - exp((-0.5*(log(0.5*D/rg)/log_sigma_g)**2.)) & - ) * 1E-12 + exp((-0.5*(log(0.5*D/rg)/log_sigma_g)**2.)) & + ) * 1E-12 else @@ -360,7 +365,7 @@ subroutine dsd(Q,Re,D,N,nsizes,dtype,rho_a,tc, & stop endif - + end select end subroutine dsd diff --git a/src/atmos_param/cosp/quickbeam/format_input.f90 b/src/atmos_param/cosp/quickbeam/format_input.F90 similarity index 93% rename from src/atmos_param/cosp/quickbeam/format_input.f90 rename to src/atmos_param/cosp/quickbeam/format_input.F90 index 225444cbf9..592c886052 100644 --- a/src/atmos_param/cosp/quickbeam/format_input.f90 +++ b/src/atmos_param/cosp/quickbeam/format_input.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: format_input.f90,v 19.0 2012/01/06 20:04:42 fms Exp $ -! $Name: siena_201207 $ + +! $Id: format_input.F90,v 20.0 2013/12/13 23:16:44 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! FORMAT_INPUT: Procedures to prepare data for input to the simulator ! Compiled/Modified: diff --git a/src/atmos_param/cosp/quickbeam/gases.f90 b/src/atmos_param/cosp/quickbeam/gases.F90 similarity index 96% rename from src/atmos_param/cosp/quickbeam/gases.f90 rename to src/atmos_param/cosp/quickbeam/gases.F90 index 2162783b6c..e84bc6f5b8 100644 --- a/src/atmos_param/cosp/quickbeam/gases.f90 +++ b/src/atmos_param/cosp/quickbeam/gases.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: gases.f90,v 19.0 2012/01/06 20:04:44 fms Exp $ -! $Name: siena_201207 $ + +! $Id: gases.F90,v 20.0 2013/12/13 23:16:45 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif function gases(PRES_mb,T,RH,f) implicit none @@ -116,9 +121,9 @@ function gases(PRES_mb,T,RH,f) 0.0253000,0.0240000,0.0286000/ ! // conversions - th = 300./T ! unitless - e = (RH*th**5)/(41.45*10**(9.834*th-10)) ! kPa - p = PRES_mb/10.-e ! kPa + th = 300./T ! unitless + e = (RH*th**5)/(41.45*10**(9.834*th-10)) ! kPa + p = PRES_mb/10.-e ! kPa ! // term1 sumo = 0. diff --git a/src/atmos_param/cosp/quickbeam/load_hydrometeor_classes.f90 b/src/atmos_param/cosp/quickbeam/load_hydrometeor_classes.F90 similarity index 89% rename from src/atmos_param/cosp/quickbeam/load_hydrometeor_classes.f90 rename to src/atmos_param/cosp/quickbeam/load_hydrometeor_classes.F90 index baf975d289..45df414d65 100644 --- a/src/atmos_param/cosp/quickbeam/load_hydrometeor_classes.f90 +++ b/src/atmos_param/cosp/quickbeam/load_hydrometeor_classes.F90 @@ -1,9 +1,14 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: load_hydrometeor_classes.f90,v 19.0 2012/01/06 20:04:46 fms Exp $ -! $Name: siena_201207 $ + +! $Id: load_hydrometeor_classes.F90,v 20.0 2013/12/13 23:16:46 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif subroutine load_hydrometeor_classes(Nprmts_max,dist_prmts_hydro,hp,nhclass) use radar_simulator_types @@ -31,7 +36,7 @@ subroutine load_hydrometeor_classes(Nprmts_max,dist_prmts_hydro,hp,nhclass) ! ----- INTERNAL ----- integer :: i - + hp%rho(:) = -1 do i = 1,nhclass,1 @@ -51,7 +56,7 @@ subroutine load_hydrometeor_classes(Nprmts_max,dist_prmts_hydro,hp,nhclass) ! // setup scaling arrays hp%fc = -999. - hp%scaled = .false. + hp%scaled = .false. hp%z_flag = .false. hp%rho_eff = -999. hp%ifc = -9 diff --git a/src/atmos_param/cosp/quickbeam/load_mie_table.f90 b/src/atmos_param/cosp/quickbeam/load_mie_table.F90 similarity index 57% rename from src/atmos_param/cosp/quickbeam/load_mie_table.f90 rename to src/atmos_param/cosp/quickbeam/load_mie_table.F90 index 40794c3cb5..74a1686897 100644 --- a/src/atmos_param/cosp/quickbeam/load_mie_table.f90 +++ b/src/atmos_param/cosp/quickbeam/load_mie_table.F90 @@ -1,13 +1,20 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: load_mie_table.f90,v 19.0 2012/01/06 20:04:48 fms Exp $ -! $Name: siena_201207 $ + +! $Id: load_mie_table.F90,v 20.0 2013/12/13 23:16:47 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif subroutine load_mie_table(mie_table_name,mt) use radar_simulator_types - use mpp_mod,only: get_unit +#ifdef COSP_GFDL + use mpp_mod,only: get_unit +#endif implicit none ! Purpose: @@ -30,26 +37,35 @@ subroutine load_mie_table(mie_table_name,mt) type(mie), intent(out) :: mt ! ----- INTERNAL ----- +#ifdef COSP_GFDL integer :: i, funit +#else + integer :: i +#endif integer*4 :: dummy_in(4) - + +#ifdef COSP_GFDL funit = get_unit() open(funit,file=mie_table_name,action='read') + read(funit,*) dummy_in +#else + open(51,file=mie_table_name,action='read') + read(51,*) dummy_in +#endif - read(funit,*) dummy_in - - if(dummy_in(1).ne. mt_nfreq .or. & - dummy_in(2).ne. mt_ntt .or. & - dummy_in(3).ne. mt_nf .or. & - dummy_in(4).ne. mt_nd) then + if(dummy_in(1).ne. mt_nfreq .or. & + dummy_in(2).ne. mt_ntt .or. & + dummy_in(3).ne. mt_nf .or. & + dummy_in(4).ne. mt_nd) then - print *,'Mie file is of size :',dummy_in(:) - print *,' expected a size of:',mt_nfreq, mt_ntt,mt_nf,mt_nf - print *,' change paramters in radar_simulator_types.f90 ?? ' - stop - endif + print *,'Mie file is of size :',dummy_in(:) + print *,' expected a size of:',mt_nfreq, mt_ntt,mt_nf,mt_nf + print *,' change paramters in radar_simulator_types.f90 ?? ' + stop + endif +#ifdef COSP_GFDL read(funit,*) mt%freq read(funit,*) mt%tt read(funit,*) mt%f @@ -57,8 +73,21 @@ subroutine load_mie_table(mie_table_name,mt) read(funit,*) mt%D read(funit,*) mt%qext read(funit,*) mt%qbsca +#else + read(51,*) mt%freq + read(51,*) mt%tt + read(51,*) mt%f + read(51,*) mt%phase + read(51,*) mt%D + read(51,*) mt%qext + read(51,*) mt%qbsca +#endif +#ifdef COSP_GFDL close(funit) +#else + close(51) +#endif ! // create arrays of liquid/ice temperature cnt_liq = 0 @@ -67,7 +96,9 @@ subroutine load_mie_table(mie_table_name,mt) if (mt%phase(i) == 0) cnt_liq = cnt_liq + 1 if (mt%phase(i) == 1) cnt_ice = cnt_ice + 1 enddo +#ifndef COSP_GFDL allocate(mt_ttl(cnt_liq),mt_tti(cnt_ice)) +#endif do i=1,cnt_liq mt_ttl(i) = mt%tt(i) enddo diff --git a/src/atmos_param/cosp/quickbeam/math_lib.f90 b/src/atmos_param/cosp/quickbeam/math_lib.F90 similarity index 98% rename from src/atmos_param/cosp/quickbeam/math_lib.f90 rename to src/atmos_param/cosp/quickbeam/math_lib.F90 index 01d15c6a77..d6d5fd06b4 100644 --- a/src/atmos_param/cosp/quickbeam/math_lib.f90 +++ b/src/atmos_param/cosp/quickbeam/math_lib.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: math_lib.f90,v 19.0 2012/01/06 20:04:50 fms Exp $ -! $Name: siena_201207 $ + +! $Id: math_lib.F90,v 20.0 2013/12/13 23:16:48 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif ! MATH_LIB: Mathematics procedures for F90 ! Compiled/Modified: @@ -48,7 +53,7 @@ function gamma(x) real*8 :: g(26) integer :: k,m1,m - pi = acos(-1.) + pi = acos(-1.) if (x ==int(x)) then if (x > 0.0) then ga=1.0 diff --git a/src/atmos_param/cosp/quickbeam/mrgrnk.f90 b/src/atmos_param/cosp/quickbeam/mrgrnk.F90 similarity index 96% rename from src/atmos_param/cosp/quickbeam/mrgrnk.f90 rename to src/atmos_param/cosp/quickbeam/mrgrnk.F90 index 5b80643997..274e15817e 100644 --- a/src/atmos_param/cosp/quickbeam/mrgrnk.f90 +++ b/src/atmos_param/cosp/quickbeam/mrgrnk.F90 @@ -1,15 +1,17 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: mrgrnk.f90,v 19.0 2012/01/06 20:04:52 fms Exp $ -! $Name: siena_201207 $ + +! $Id: mrgrnk.F90,v 20.0 2013/12/13 23:16:49 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif Module m_mrgrnk Integer, Parameter :: kdp = selected_real_kind(15) -!RSH ADD since FMS default real is 64bit -! See note in subroutine R_mrgrnk -Integer, Parameter :: ksp = selected_real_kind( 6) public :: mrgrnk private :: kdp private :: R_mrgrnk, I_mrgrnk, D_mrgrnk @@ -225,11 +227,17 @@ Subroutine R_mrgrnk (XDONT, IRNGT) ! out of the standard loop, and use dedicated coding. ! __________________________________________________________ ! _________________________________________________________ - Real (kind=ksp), Dimension (:), Intent (In) :: XDONT -!RSH above needed since FMS default real is 64 bit, handled by D_mrgrnk -! without this mod R_mrgrnk and D_mrgrnk are duplicates, which -! compiler dislikes -! Real, Dimension (:), Intent (In) :: XDONT +#ifdef COSP_GFDL +!RSH: +! this declaration is needed because "REAL" in FMS has been set to +! 64bit. Without use of the kind keyword, the interfaces to module +! procedures D_mrgrnk and R_mrgrnk become identical, which upsets at +! least some compilers. + Integer, Parameter :: ksp = selected_real_kind(6) + Real(kind=ksp), Dimension (:), Intent (In) :: XDONT +#else + Real, Dimension (:), Intent (In) :: XDONT +#endif Integer*4, Dimension (:), Intent (Out) :: IRNGT ! __________________________________________________________ Real :: XVALA, XVALB diff --git a/src/atmos_param/cosp/quickbeam/optics_lib.f90 b/src/atmos_param/cosp/quickbeam/optics_lib.F90 similarity index 99% rename from src/atmos_param/cosp/quickbeam/optics_lib.f90 rename to src/atmos_param/cosp/quickbeam/optics_lib.F90 index c82212f408..f115980346 100644 --- a/src/atmos_param/cosp/quickbeam/optics_lib.f90 +++ b/src/atmos_param/cosp/quickbeam/optics_lib.F90 @@ -1,10 +1,15 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: optics_lib.f90,v 19.0 2012/01/06 20:04:54 fms Exp $ -! $Name: siena_201207 $ - + +! $Id: optics_lib.F90,v 20.0 2013/12/13 23:16:50 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif + ! OPTICS_LIB: Optical proecures for for F90 ! Compiled/Modified: ! 07/01/06 John Haynes (haynes@atmos.colostate.edu) @@ -75,7 +80,7 @@ subroutine m_wat(freq, t, n_r, n_i) n_r = real(sq) n_i = aimag(sq) - + return end subroutine m_wat @@ -712,7 +717,7 @@ Subroutine MieInt(Dx, SCm, Inp, Dqv, Dqxt, Dqsc, Dbsc, Dg, Xs1, Xs2, DPh, Error) Dqxt = Tnp1 * Dble(A + B) + Dqxt Dqsc = Tnp1 * (A*Conjg(A) + B*Conjg(B)) + Dqsc If (N.Gt.1) then - Dg = Dg + (dN*dN - 1) * Dble(ANM1*Conjg(A) + BNM1 * Conjg(B)) / dN + TNM1 * Dble(ANM1*Conjg(BNM1)) / (dN*dN - dN) + Dg = Dg + (dN*dN - 1) * Dble(ANM1*Conjg(A) + BNM1 * Conjg(B)) / dN + TNM1 * Dble(ANM1*Conjg(BNM1)) / (dN*dN - dN) End If Anm1 = A Bnm1 = B diff --git a/src/atmos_param/cosp/quickbeam/radar_simulator.F90 b/src/atmos_param/cosp/quickbeam/radar_simulator.F90 new file mode 100644 index 0000000000..d5a6d122a4 --- /dev/null +++ b/src/atmos_param/cosp/quickbeam/radar_simulator.F90 @@ -0,0 +1,557 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL + +!--------------------------------------------------------------------- +!------------ FMS version number and tagname for this file ----------- + +! $Id: radar_simulator.F90,v 20.0 2013/12/13 23:16:51 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif + + subroutine radar_simulator(freq,k2,do_ray,use_gas_abs,use_mie_table,mt, & + nhclass,hp,nprof,ngate,nsizes,D,hgt_matrix,hm_matrix,re_matrix,p_matrix,t_matrix, & + rh_matrix,Ze_non,Ze_ray,h_atten_to_vol,g_atten_to_vol,dBZe, & + g_to_vol_in,g_to_vol_out) + +! rh_matrix,Ze_non,Ze_ray,kr_matrix,g_atten_to_vol,dBZe) + + use m_mrgrnk + use array_lib + use math_lib + use optics_lib + use radar_simulator_types + implicit none + +! Purpose: +! Simulates a vertical profile of radar reflectivity +! Part of QuickBeam v1.04 by John Haynes & Roger Marchand +! +! Inputs: +! [freq] radar frequency (GHz), can be anything unless +! use_mie_table=1, in which case one of 94,35,13.8,9.6,3 +! [k2] |K|^2, the dielectric constant, set to -1 to use the +! frequency dependent default +! [do_ray] 1=do Rayleigh calcs, 0=not +! [use_gas_abs] 1=do gaseous abs calcs, 0=not, +! 2=use same as first profile (undocumented) +! [use_mie_table] 1=use Mie tables, 0=not +! [mt] Mie look up table +! [nhclass] number of hydrometeor types +! [hp] structure that defines hydrometeor types +! [nprof] number of hydrometeor profiles +! [ngate] number of vertical layers +! [nsizes] number of discrete particles in [D] +! [D] array of discrete particles (um) +! +! (The following 5 arrays must be in order from closest to the radar +! to farthest...) +! [hgt_matrix] height of hydrometeors (km) +! [hm_matrix] table of hydrometeor mixing rations (g/kg) +! [re_matrix] OPTIONAL table of hydrometeor effective radii (microns) +! [p_matrix] pressure profile (hPa) +! [t_matrix] temperature profile (C) +! [rh_matrix] relative humidity profile (%) +! +! Outputs: +! [Ze_non] radar reflectivity without attenuation (dBZ) +! [Ze_ray] Rayleigh reflectivity (dBZ) +! [h_atten_to_vol] attenuation by hydromets, radar to vol (dB) +! [g_atten_to_vol] gaseous atteunation, radar to vol (dB) +! [dBZe] effective radar reflectivity factor (dBZ) +! +! Optional: +! [g_to_vol_in] integrated atten due to gases, r>v (dB). +! If present then is used as gaseous absorption, independently of the +! value in use_gas_abs +! [g_to_vol_out] integrated atten due to gases, r>v (dB). +! If present then gaseous absorption for each profile is returned here. +! +! Created: +! 11/28/2005 John Haynes (haynes@atmos.colostate.edu) +! Modified: +! 09/2006 placed into subroutine form, scaling factors (Roger Marchand,JMH) +! 08/2007 added equivalent volume spheres, Z and N scalling most distrubtion types (Roger Marchand) +! 01/2008 'Do while' to determine if hydrometeor(s) present in volume +! changed for vectorization purposes (A. Bodas-Salcedo) + +! ----- INPUTS ----- + type(mie), intent(in) :: mt + type(class_param), intent(inout) :: hp +#ifdef COSP_GFDL + real*8, intent(in) :: freq + real*8, intent(inout) :: k2 +#else + real*8, intent(in) :: freq,k2 +#endif + integer, intent(in) :: do_ray,use_gas_abs,use_mie_table, & + nhclass,nprof,ngate,nsizes + real*8, dimension(nsizes), intent(in) :: D + real*8, dimension(nprof,ngate), intent(in) :: hgt_matrix, p_matrix, & + t_matrix,rh_matrix + real*8, dimension(nhclass,nprof,ngate), intent(in) :: hm_matrix + real*8, dimension(nhclass,nprof,ngate), intent(inout) :: re_matrix + +! ----- OUTPUTS ----- + real*8, dimension(nprof,ngate), intent(out) :: Ze_non,Ze_ray, & + g_atten_to_vol,dBZe,h_atten_to_vol + +! ----- OPTIONAL ----- + real*8, optional, dimension(ngate,nprof) :: & + g_to_vol_in,g_to_vol_out ! integrated atten due to gases, r>v (dB). This allows to output and then input + ! the same gaseous absorption in different calls. Optional to allow compatibility + ! with original version. A. Bodas April 2008. + +! real*8, dimension(nprof,ngate) :: kr_matrix + +! ----- INTERNAL ----- + integer :: & + phase, & ! 0=liquid, 1=ice + ns ! number of discrete drop sizes + + integer*4, dimension(ngate) :: & + hydro ! 1=hydrometeor in vol, 0=none + real*8 :: & + rho_a, & ! air density (kg m^-3) + gases ! function: 2-way gas atten (dB/km) + + real*8, dimension(:), allocatable :: & + Di, Deq, & ! discrete drop sizes (um) + Ni, Ntemp, & ! discrete concentrations (cm^-3 um^-1) + rhoi ! discrete densities (kg m^-3) + + real*8, dimension(ngate) :: & + z_vol, & ! effective reflectivity factor (mm^6/m^3) + z_ray, & ! reflectivity factor, Rayleigh only (mm^6/m^3) + kr_vol, & ! attenuation coefficient hydro (dB/km) + g_vol, & ! attenuation coefficient gases (dB/km) + a_to_vol, & ! integrated atten due to hydometeors, r>v (dB) + g_to_vol ! integrated atten due to gases, r>v (dB) + + + integer,parameter :: KR8 = selected_real_kind(15,300) + real*8, parameter :: xx = -1.0_KR8 + real*8, dimension(:), allocatable :: xxa + real*8 :: kr, ze, zr, pi, scale_factor, Re, ld, tmp1, apm,bpm + integer*4 :: tp, i, j, k, pr, itt, iff + + real*8 bin_length,step,base,step_list(25),base_list(25) + integer*4 iRe_type,n,max_bin + + logical :: g_to_vol_in_present, g_to_vol_out_present + + ! Logicals to avoid calling present within the loops + g_to_vol_in_present = present(g_to_vol_in) + g_to_vol_out_present = present(g_to_vol_out) + + ! set up Re bins for z_scalling + bin_length=50; + max_bin=25 + + step_list(1)=1 + base_list(1)=75 + do j=2,max_bin + step_list(j)=3*(j-1); + if(step_list(j)>bin_length) then + step_list(j)=bin_length; + endif + base_list(j)=base_list(j-1)+floor(bin_length/step_list(j-1)); + enddo + + + pi = acos(-1.0) + if (use_mie_table == 1) iff = infind(mt%freq,freq,sort=1) + + + ! // loop over each profile (nprof) + do pr=1,nprof +! ----- calculations for each volume ----- + z_vol(:) = 0 + z_ray(:) = 0 + kr_vol(:) = 0 + hydro(:) = 0 + +! // loop over eacho range gate (ngate) + do k=1,ngate + +! :: determine if hydrometeor(s) present in volume + hydro(k) = 0 + do j=1,nhclass ! Do while changed for vectorization purposes (A. B-S) + if ((hm_matrix(j,pr,k) > 1E-12) .and. (hp%dtype(j) > 0)) then + hydro(k) = 1 + exit + endif + enddo + + if (hydro(k) == 1) then +! :: if there is hydrometeor in the volume + + rho_a = (p_matrix(pr,k)*100.)/(287*(t_matrix(pr,k)+273.15)) + +! :: loop over hydrometeor type + do tp=1,nhclass + + if (hm_matrix(tp,pr,k) <= 1E-12) cycle + + phase = hp%phase(tp) + if(phase==0) then + itt = infind(mt_ttl,t_matrix(pr,k)) + else + itt = infind(mt_tti,t_matrix(pr,k)) + endif + + ! calculate Re if we have an exponential distribution with fixed No ... precipitation type particle + if( hp%dtype(tp)==2 .and. abs(hp%p2(tp)+1) < 1E-8) then + + apm=hp%apm(tp) + bpm=hp%bpm(tp) + + if ((hp%rho(tp) > 0) .and. (apm < 0)) then + apm = (pi/6)*hp%rho(tp) + bpm = 3. + endif + + tmp1 = 1./(1.+bpm) + ld = ((apm*gamma(1.+bpm)*hp%p1(tp))/(rho_a*hm_matrix(tp,pr,k)*1E-3))**tmp1 + + Re = 1.5E6/ld + + re_matrix(tp,pr,k) = Re; + + endif + + if(re_matrix(tp,pr,k).eq.0) then + + iRe_type=1 + Re=0 + else + iRe_type=1 + Re=re_matrix(tp,pr,k) + + n=floor(Re/bin_length) + if(n==0) then + if(Re<25) then + step=0.5 + base=0 + else + step=1 + base=25 + endif + else + if(n>max_bin) then + n=max_bin + endif + + step=step_list(n) + base=base_list(n) + endif + + iRe_type=floor(Re/step) + + if(iRe_type.lt.1) then + iRe_type=1 + endif + + Re=step*(iRe_type+0.5) + iRe_type=iRe_type+base-floor(n*bin_length/step) + + ! make sure iRe_type is within bounds + if(iRe_type.ge.nRe_types) then + + ! print *, tp, re_matrix(tp,pr,k), Re, iRe_type + + ! no scaling allowed + Re=re_matrix(tp,pr,k) + + iRe_type=nRe_types + hp%z_flag(tp,itt,iRe_type)=.false. + hp%scaled(tp,iRe_type)=.false. + endif + endif + + ! use Ze_scaled, Zr_scaled, and kr_scaled ... if know them + ! if not we will calculate Ze, Zr, and Kr from the distribution parameters +#ifdef COSP_GFDL +!RSH: +! In order to get reproducibility across physics windows, the "else" branch +! of the following if block must be removed. However doing so increases +! total model time by over a factor of 2. Therefore I have left the loop +! in place for now, pending a response to this issue from the COSP +! developers. Instead, to avoid generating incorrect diagnostics, the +! following diagnostics must be removed from the diag_table: +! "cloudsatcfad_x", where x=1,15 +! "cloudsatcfad_mdl_x", where x=1,15 +! "cloudsatcfad_sat_x", where x=1,15 +! "clcalipso2_sat" +! "clcalipso2_mdl" +! "clcalipso2" +! +! If these diagnostics are required, they may be correctly obtained +! (at great cost) by removing the else block (see !RSH section below) and +! always executing the first part of this if loop. +#endif + if( .not. hp%z_flag(tp,itt,iRe_type) ) then + +! :: create a distribution of hydrometeors within volume + select case(hp%dtype(tp)) + case(4) + ns = 1 + allocate(Di(ns),Ni(ns),rhoi(ns),xxa(ns),Deq(ns)) + if (use_mie_table == 1) allocate(mt_qext(ns),mt_qbsca(ns),Ntemp(ns)) + Di = hp%p1(tp) + Ni = 0. + case default + ns = nsizes + allocate(Di(ns),Ni(ns),rhoi(ns),xxa(ns),Deq(ns)) + if (use_mie_table == 1) allocate(mt_qext(ns),mt_qbsca(ns),Ntemp(ns)) + Di = D + Ni = 0. + end select + +! :: create a DSD (using scaling factor if applicable) +! hp%scaled(tp,iRe_type)=.false. ! turn off N scaling + + call dsd(hm_matrix(tp,pr,k),Re,Di,Ni,ns,hp%dtype(tp),rho_a, & + t_matrix(pr,k),hp%dmin(tp),hp%dmax(tp),hp%apm(tp),hp%bpm(tp), & + hp%rho(tp),hp%p1(tp),hp%p2(tp),hp%p3(tp),hp%fc(tp,1:ns,iRe_type), & + hp%scaled(tp,iRe_type)) + +! :: calculate particle density + ! if ((hp%rho_eff(tp,1,iRe_type) < 0) .and. (phase == 1)) then + if (phase == 1) then + if (hp%rho(tp) < 0) then + + ! MG Mie approach - adjust density of sphere with D = D_characteristic to match particle density + ! hp%rho_eff(tp,1:ns,iRe_type) = (6/pi)*hp%apm(tp)*(Di*1E-6)**(hp%bpm(tp)-3) !MG Mie approach + + ! as the particle size gets small it is possible that the mass to size relationship of + ! (given by power law in hclass.data) can produce impossible results + ! where the mass is larger than a solid sphere of ice. + ! This loop ensures that no ice particle can have more mass/density larger than an ice sphere. + ! do i=1,ns + ! if(hp%rho_eff(tp,i,iRe_type) > 917 ) then + ! hp%rho_eff(tp,i,iRe_type) = 917 + !endif + !enddo + + ! alternative is to use equivalent volume spheres. + hp%rho_eff(tp,1:ns,iRe_type) = 917 ! solid ice == equivalent volume approach + Deq = ( ( 6/pi*hp%apm(tp)/917 ) ** (1.0/3.0) ) * & + ( (Di*1E-6) ** (hp%bpm(tp)/3.0) ) * 1E6 ! Di now really Deq in microns. + + else + + ! hp%rho_eff(tp,1:ns,iRe_type) = hp%rho(tp) !MG Mie approach + + ! Equivalent volume sphere (solid ice rho_ice=917 kg/m^3). + hp%rho_eff(tp,1:ns,iRe_type) = 917 + Deq=Di * ((hp%rho(tp)/917)**(1.0/3.0)) + + endif + + ! if using equivalent volume spheres + if (use_mie_table == 1) then + + Ntemp=Ni + + ! Find N(Di) from N(Deq) which we know + do i=1,ns + j=infind(Deq,Di(i)) + Ni(i)=Ntemp(j) + enddo + else + ! just use Deq and D variable input to mie code + Di=Deq; + endif + + endif + rhoi = hp%rho_eff(tp,1:ns,iRe_type) + +! :: calculate effective reflectivity factor of volume + if (use_mie_table == 1) then + +#ifndef COSP_GFDL + if ((hp%dtype(tp) == 4) .and. (hp%idd(tp) < 0)) then + hp%idd(tp) = infind(mt%D,Di(1)) + endif + + if (phase == 0) then + + ! itt = infind(mt_ttl,t_matrix(pr,k)) + select case(hp%dtype(tp)) + case(4) + mt_qext(1) = mt%qext(hp%idd(tp),itt,1,iff) + mt_qbsca(1) = mt%qbsca(hp%idd(tp),itt,1,iff) + case default + mt_qext = mt%qext(:,itt,1,iff) + mt_qbsca = mt%qbsca(:,itt,1,iff) + end select + + call zeff(freq,Di,Ni,ns,k2,mt_ttl(itt),0,do_ray, & + ze,zr,kr,mt_qext,mt_qbsca,xx) + + else + + ! itt = infind(mt_tti,t_matrix(pr,k)) + select case(hp%dtype(tp)) + case(4) + if (hp%ifc(tp,1,iRe_type) < 0) then + hp%ifc(tp,1,iRe_type) = infind(mt%f,rhoi(1)/917.) + endif + mt_qext(1) = & + mt%qext(hp%idd(tp),itt+cnt_liq,hp%ifc(tp,1,iRe_type),iff) + mt_qbsca(1) = & + mt%qbsca(hp%idd(tp),itt+cnt_liq,hp%ifc(tp,1,iRe_type),iff) + case default + do i=1,ns + if (hp%ifc(tp,i,iRe_type) < 0) then + hp%ifc(tp,i,iRe_type) = infind(mt%f,rhoi(i)/917.) + endif + mt_qext(i) = mt%qext(i,itt+cnt_liq,hp%ifc(tp,i,iRe_type),iff) + mt_qbsca(i) = mt%qbsca(i,itt+cnt_liq,hp%ifc(tp,i,iRe_type),iff) + enddo + end select + + call zeff(freq,Di,Ni,ns,k2,mt_tti(itt),1,do_ray, & + ze,zr,kr,mt_qext,mt_qbsca,xx) + + endif +#endif + + else + + xxa = -9.9 + call zeff(freq,Di,Ni,ns,k2,t_matrix(pr,k),phase,do_ray, & + ze,zr,kr,xxa,xxa,rhoi) + + + endif ! end of use mie table + + ! xxa = -9.9 + !call zeff(freq,Di,Ni,ns,k2,t_matrix(pr,k),phase,do_ray, & + ! ze2,zr,kr2,xxa,xxa,rhoi) + + ! if(abs(ze2-ze)/ze2 > 0.1) then + ! if(abs(kr2-kr)/kr2 > 0.1) then + + ! write(*,*) pr,k,tp,ze2,ze2-ze,abs(ze2-ze)/ze2,itt+cnt_liq,iff + ! write(*,*) pr,k,tp,ze2,kr2,kr2-kr,abs(kr2-kr)/kr2 + ! stop + + !endif + + deallocate(Di,Ni,rhoi,xxa,Deq) + if (use_mie_table == 1) deallocate(mt_qext,mt_qbsca,Ntemp) + +#ifdef COSP_GFDL +!RSH +! the following lines need be removed for reproducible execution. +!with these lines retained the diagnostics listed above will not reproduce +!across physics_windows. +#endif + else ! can use z scaling + + if( hp%dtype(tp)==2 .and. abs(hp%p2(tp)+1) < 1E-8 ) then + + ze = hp%Ze_scaled(tp,itt,iRe_type) + zr = hp%Zr_scaled(tp,itt,iRe_type) + kr = hp%kr_scaled(tp,itt,iRe_type) + + else + scale_factor=rho_a*hm_matrix(tp,pr,k) + + zr = hp%Zr_scaled(tp,itt,iRe_type) * scale_factor + ze = hp%Ze_scaled(tp,itt,iRe_type) * scale_factor + kr = hp%kr_scaled(tp,itt,iRe_type) * scale_factor + endif + + endif ! end z_scaling +#ifdef COSP_GFDL +!RSH end of lines to remove +#endif + + ! kr=0 + + kr_vol(k) = kr_vol(k) + kr + z_vol(k) = z_vol(k) + ze + z_ray(k) = z_ray(k) + zr + + ! construct Ze_scaled, Zr_scaled, and kr_scaled ... if we can + if( .not. hp%z_flag(tp,itt,iRe_type) .and. 1.eq.1 ) then + + if( ( (hp%dtype(tp)==1 .or. hp%dtype(tp)==5 .or. hp%dtype(tp)==2) .and. abs(hp%p1(tp)+1) < 1E-8 ) .or. & + ( hp%dtype(tp)==3 .or. hp%dtype(tp)==4 ) & + ) then + + scale_factor=rho_a*hm_matrix(tp,pr,k) + + hp%Ze_scaled(tp,itt,iRe_type) = ze/ scale_factor + hp%Zr_scaled(tp,itt,iRe_type) = zr/ scale_factor + hp%kr_scaled(tp,itt,iRe_type) = kr/ scale_factor + + hp%z_flag(tp,itt,iRe_type)=.True. + + elseif( hp%dtype(tp)==2 .and. abs(hp%p2(tp)+1) < 1E-8 ) then + + hp%Ze_scaled(tp,itt,iRe_type) = ze + hp%Zr_scaled(tp,itt,iRe_type) = zr + hp%kr_scaled(tp,itt,iRe_type) = kr + + hp%z_flag(tp,itt,iRe_type)=.True. + endif + + endif + + enddo ! end loop of tp (hydrometeor type) + + else +! :: volume is hydrometeor-free + + kr_vol(k) = 0 + z_vol(k) = -999 + z_ray(k) = -999 + + endif + +! :: attenuation due to hydrometeors between radar and volume + a_to_vol(k) = 2*path_integral(kr_vol,hgt_matrix(pr,:),1,k-1) + +! :: attenuation due to gaseous absorption between radar and volume + if (g_to_vol_in_present) then + g_to_vol(k) = g_to_vol_in(k,pr) + else + if ( (use_gas_abs == 1) .or. ((use_gas_abs == 2) .and. (pr == 1)) ) then + g_vol(k) = gases(p_matrix(pr,k),t_matrix(pr,k)+273.15, & + rh_matrix(pr,k),freq) + g_to_vol(k) = path_integral(g_vol,hgt_matrix(pr,:),1,k-1) + elseif (use_gas_abs == 0) then + g_to_vol(k) = 0 + endif + endif + +! kr_matrix(pr,:)=kr_vol + +! :: store results in matrix for return to calling program + h_atten_to_vol(pr,k)=a_to_vol(k) + g_atten_to_vol(pr,k)=g_to_vol(k) + if ((do_ray == 1) .and. (z_ray(k) > 0)) then + Ze_ray(pr,k) = 10*log10(z_ray(k)) + else + Ze_ray(pr,k) = -999 + endif + if (z_vol(k) > 0) then + dBZe(pr,k) = 10*log10(z_vol(k))-a_to_vol(k)-g_to_vol(k) + Ze_non(pr,k) = 10*log10(z_vol(k)) + else + dBZe(pr,k) = -999 + Ze_non(pr,k) = -999 + endif + + enddo ! end loop of k (range gate) + ! Output array with gaseous absorption + if (g_to_vol_out_present) g_to_vol_out(:,pr) = g_to_vol + enddo ! end loop over pr (profile) + + end subroutine radar_simulator + diff --git a/src/atmos_param/cosp/quickbeam/radar_simulator.f90 b/src/atmos_param/cosp/quickbeam/radar_simulator.f90 deleted file mode 100644 index 4d4e5cc866..0000000000 --- a/src/atmos_param/cosp/quickbeam/radar_simulator.f90 +++ /dev/null @@ -1,522 +0,0 @@ - -!--------------------------------------------------------------------- -!------------ FMS version number and tagname for this file ----------- - -! $Id: radar_simulator.f90,v 19.0 2012/01/06 20:04:56 fms Exp $ -! $Name: siena_201207 $ - - subroutine radar_simulator(me,freq,k2,do_ray,use_gas_abs,use_mie_table,mt, & - nhclass,hp,nprof,ngate,nsizes,D,hgt_matrix,hm_matrix,re_matrix,p_matrix,t_matrix, & - rh_matrix,Ze_non,Ze_ray,h_atten_to_vol,g_atten_to_vol,dBZe, & - g_to_vol_in,g_to_vol_out) - -! rh_matrix,Ze_non,Ze_ray,kr_matrix,g_atten_to_vol,dBZe) - - use m_mrgrnk - use array_lib - use math_lib - use optics_lib - use radar_simulator_types - implicit none - -! Purpose: -! Simulates a vertical profile of radar reflectivity -! Part of QuickBeam v1.04 by John Haynes & Roger Marchand -! -! Inputs: -! [freq] radar frequency (GHz), can be anything unless -! use_mie_table=1, in which case one of 94,35,13.8,9.6,3 -! [k2] |K|^2, the dielectric constant, set to -1 to use the -! frequency dependent default -! [do_ray] 1=do Rayleigh calcs, 0=not -! [use_gas_abs] 1=do gaseous abs calcs, 0=not, -! 2=use same as first profile (undocumented) -! [use_mie_table] 1=use Mie tables, 0=not -! [mt] Mie look up table -! [nhclass] number of hydrometeor types -! [hp] structure that defines hydrometeor types -! [nprof] number of hydrometeor profiles -! [ngate] number of vertical layers -! [nsizes] number of discrete particles in [D] -! [D] array of discrete particles (um) -! -! (The following 5 arrays must be in order from closest to the radar -! to farthest...) -! [hgt_matrix] height of hydrometeors (km) -! [hm_matrix] table of hydrometeor mixing rations (g/kg) -! [re_matrix] OPTIONAL table of hydrometeor effective radii (microns) -! [p_matrix] pressure profile (hPa) -! [t_matrix] temperature profile (C) -! [rh_matrix] relative humidity profile (%) -! -! Outputs: -! [Ze_non] radar reflectivity without attenuation (dBZ) -! [Ze_ray] Rayleigh reflectivity (dBZ) -! [h_atten_to_vol] attenuation by hydromets, radar to vol (dB) -! [g_atten_to_vol] gaseous atteunation, radar to vol (dB) -! [dBZe] effective radar reflectivity factor (dBZ) -! -! Optional: -! [g_to_vol_in] integrated atten due to gases, r>v (dB). -! If present then is used as gaseous absorption, independently of the -! value in use_gas_abs -! [g_to_vol_out] integrated atten due to gases, r>v (dB). -! If present then gaseous absorption for each profile is returned here. -! -! Created: -! 11/28/2005 John Haynes (haynes@atmos.colostate.edu) -! Modified: -! 09/2006 placed into subroutine form, scaling factors (Roger Marchand,JMH) -! 08/2007 added equivalent volume spheres, Z and N scalling most distrubtion types (Roger Marchand) -! 01/2008 'Do while' to determine if hydrometeor(s) present in volume -! changed for vectorization purposes (A. Bodas-Salcedo) - -! ----- INPUTS ----- - integer, intent(in) :: me - type(mie), intent(in) :: mt - type(class_param), intent(inout) :: hp - real*8, intent(in) :: freq - real*8, intent(inout) :: k2 - integer, intent(in) :: do_ray,use_gas_abs,use_mie_table, & - nhclass,nprof,ngate,nsizes - real*8, dimension(nsizes), intent(in) :: D - real*8, dimension(nprof,ngate), intent(in) :: hgt_matrix, p_matrix, & - t_matrix,rh_matrix - real*8, dimension(nhclass,nprof,ngate), intent(in) :: hm_matrix - real*8, dimension(nhclass,nprof,ngate), intent(inout) :: re_matrix - -! ----- OUTPUTS ----- - real*8, dimension(nprof,ngate), intent(out) :: Ze_non,Ze_ray, & - g_atten_to_vol,dBZe,h_atten_to_vol - -! ----- OPTIONAL ----- - real*8, optional, dimension(ngate,nprof) :: & - g_to_vol_in,g_to_vol_out ! integrated atten due to gases, r>v (dB). This allows to output and then input - ! the same gaseous absorption in different calls. Optional to allow compatibility - ! with original version. A. Bodas April 2008. - -! real*8, dimension(nprof,ngate) :: kr_matrix - -! ----- INTERNAL ----- - integer :: & - phase, & ! 0=liquid, 1=ice - ns ! number of discrete drop sizes - - integer*4, dimension(ngate) :: & - hydro ! 1=hydrometeor in vol, 0=none - real*8 :: & - rho_a, & ! air density (kg m^-3) - gases ! function: 2-way gas atten (dB/km) - - real*8, dimension(:), allocatable :: & - Di, Deq, & ! discrete drop sizes (um) - Ni, Ntemp, & ! discrete concentrations (cm^-3 um^-1) - rhoi, & ! discrete densities (kg m^-3) - xx_rhoi ! to expand parameter xx to array parameter - - real*8, dimension(ngate) :: & - z_vol, & ! effective reflectivity factor (mm^6/m^3) - z_ray, & ! reflectivity factor, Rayleigh only (mm^6/m^3) - kr_vol, & ! attenuation coefficient hydro (dB/km) - g_vol, & ! attenuation coefficient gases (dB/km) - a_to_vol, & ! integrated atten due to hydometeors, r>v (dB) - g_to_vol ! integrated atten due to gases, r>v (dB) - - - integer,parameter :: KR8 = selected_real_kind(15,300) - real*8, parameter :: xx = -1.0_KR8 - real*8, dimension(:), allocatable :: xxa - real*8 :: kr, ze, zr, pi, scale_factor, tc, Re, ld, tmp1, ze2, kr2,apm,bpm - integer*4 :: tp, i, j, k, pr, itt, iff - - real*8 bin_length,step,base,step_list(25),base_list(25) - integer*4 iRe_type,n,max_bin - - logical :: g_to_vol_in_present, g_to_vol_out_present - - ! Logicals to avoid calling present within the loops - g_to_vol_in_present = present(g_to_vol_in) - g_to_vol_out_present = present(g_to_vol_out) - - ! set up Re bins for z_scalling - bin_length=50; - max_bin=25 - - step_list(1)=1 - base_list(1)=75 - do j=2,max_bin - step_list(j)=3*(j-1); - if(step_list(j)>bin_length) then - step_list(j)=bin_length; - endif - base_list(j)=base_list(j-1)+floor(bin_length/step_list(j-1)); - enddo - - - pi = acos(-1.0) - if (use_mie_table == 1) iff = infind(mt%freq,freq,sort=1) - - - ! // loop over each profile (nprof) - do pr=1,nprof - -! ----- calculations for each volume ----- - z_vol(:) = 0 - z_ray(:) = 0 - kr_vol(:) = 0 - hydro(:) = 0 - -! // loop over eacho range gate (ngate) - do k=1,ngate - -! :: determine if hydrometeor(s) present in volume - hydro(k) = 0 - do j=1,nhclass ! Do while changed for vectorization purposes (A. B-S) - if ((hm_matrix(j,pr,k) > 1E-12) .and. (hp%dtype(j) > 0)) then - hydro(k) = 1 - exit - endif - enddo - - if (hydro(k) == 1) then -! :: if there is hydrometeor in the volume - - rho_a = (p_matrix(pr,k)*100.)/(287*(t_matrix(pr,k)+273.15)) - -! :: loop over hydrometeor type - do tp=1,nhclass - - if (hm_matrix(tp,pr,k) <= 1E-12) cycle - - phase = hp%phase(tp) - if(phase==0) then - itt = infind(mt_ttl,t_matrix(pr,k)) - else - itt = infind(mt_tti,t_matrix(pr,k)) - endif - - ! calculate Re if we have an exponential distribution with fixed No ... precipitation type particle - if( hp%dtype(tp)==2 .and. abs(hp%p2(tp)+1) < 1E-8) then - - apm=hp%apm(tp) - bpm=hp%bpm(tp) - - if ((hp%rho(tp) > 0) .and. (apm < 0)) then - apm = (pi/6)*hp%rho(tp) - bpm = 3. - endif - - tmp1 = 1./(1.+bpm) - ld = ((apm*gamma(1.+bpm)*hp%p1(tp))/(rho_a*hm_matrix(tp,pr,k)*1E-3))**tmp1 - - Re = 1.5E6/ld - - re_matrix(tp,pr,k) = Re; - - endif - - if(re_matrix(tp,pr,k).eq.0) then - - iRe_type=1 - Re=0 - else - iRe_type=1 - Re=re_matrix(tp,pr,k) - - n=floor(Re/bin_length) - if(n==0) then - if(Re<25) then - step=0.5 - base=0 - else - step=1 - base=25 - endif - else - if(n>max_bin) then - n=max_bin - endif - - step=step_list(n) - base=base_list(n) - endif - - iRe_type=floor(Re/step) - - if(iRe_type.lt.1) then - iRe_type=1 - endif - - Re=step*(iRe_type+0.5) - iRe_type=iRe_type+base-floor(n*bin_length/step) - - ! make sure iRe_type is within bounds - if(iRe_type.ge.nRe_types) then - - ! print *, tp, re_matrix(tp,pr,k), Re, iRe_type - - ! no scaling allowed - Re=re_matrix(tp,pr,k) - - iRe_type=nRe_types - hp%z_flag(tp,itt,iRe_type)=.false. - hp%scaled(tp,iRe_type)=.false. - endif - endif - - ! use Ze_scaled, Zr_scaled, and kr_scaled ... if know them - ! if not we will calculate Ze, Zr, and Kr from the distribution parameters - if( .not. hp%z_flag(tp,itt,iRe_type) ) then - -! :: create a distribution of hydrometeors within volume - select case(hp%dtype(tp)) - case(4) - ns = 1 - allocate(Di(ns),Ni(ns),rhoi(ns),xx_rhoi(ns),xxa(ns),Deq(ns)) - if (use_mie_table == 1) allocate(mt_qext(ns),mt_qbsca(ns),Ntemp(ns)) - Di = hp%p1(tp) - Ni = 0. - case default - ns = nsizes - allocate(Di(ns),Ni(ns),rhoi(ns),xx_rhoi(ns),xxa(ns),Deq(ns)) - if (use_mie_table == 1) allocate(mt_qext(ns),mt_qbsca(ns),Ntemp(ns)) - Di = D - Ni = 0. - end select - xx_rhoi = xx - -! :: create a DSD (using scaling factor if applicable) - ! hp%scaled(tp,iRe_type)=.false. ! turn off N scaling - - call dsd(hm_matrix(tp,pr,k),Re,Di,Ni,ns,hp%dtype(tp),rho_a, & - t_matrix(pr,k),hp%dmin(tp),hp%dmax(tp),hp%apm(tp),hp%bpm(tp), & - hp%rho(tp),hp%p1(tp),hp%p2(tp),hp%p3(tp),hp%fc(tp,1:ns,iRe_type), & - hp%scaled(tp,iRe_type)) - -! :: calculate particle density - ! if ((hp%rho_eff(tp,1,iRe_type) < 0) .and. (phase == 1)) then - if (phase == 1) then - if (hp%rho(tp) < 0) then - - ! MG Mie approach - adjust density of sphere with D = D_characteristic to match particle density - ! hp%rho_eff(tp,1:ns,iRe_type) = (6/pi)*hp%apm(tp)*(Di*1E-6)**(hp%bpm(tp)-3) !MG Mie approach - - ! as the particle size gets small it is possible that the mass to size relationship of - ! (given by power law in hclass.data) can produce impossible results - ! where the mass is larger than a solid sphere of ice. - ! This loop ensures that no ice particle can have more mass/density larger than an ice sphere. - ! do i=1,ns - ! if(hp%rho_eff(tp,i,iRe_type) > 917 ) then - ! hp%rho_eff(tp,i,iRe_type) = 917 - !endif - !enddo - - ! alternative is to use equivalent volume spheres. - hp%rho_eff(tp,1:ns,iRe_type) = 917 ! solid ice == equivalent volume approach - Deq = ( ( 6/pi*hp%apm(tp)/917 ) ** (1.0/3.0) ) * & - ( (Di*1E-6) ** (hp%bpm(tp)/3.0) ) * 1E6 ! Di now really Deq in microns. - - else - - ! hp%rho_eff(tp,1:ns,iRe_type) = hp%rho(tp) !MG Mie approach - - ! Equivalent volume sphere (solid ice rho_ice=917 kg/m^3). - hp%rho_eff(tp,1:ns,iRe_type) = 917 - Deq=Di * ((hp%rho(tp)/917)**(1.0/3.0)) - - endif - - ! if using equivalent volume spheres - if (use_mie_table == 1) then - - Ntemp=Ni - - ! Find N(Di) from N(Deq) which we know - do i=1,ns - j=infind(Deq,Di(i)) - Ni(i)=Ntemp(j) - enddo - else - ! just use Deq and D variable input to mie code - Di=Deq; - endif - - endif - rhoi = hp%rho_eff(tp,1:ns,iRe_type) - -! :: calculate effective reflectivity factor of volume - if (use_mie_table == 1) then - - if ((hp%dtype(tp) == 4) .and. (hp%idd(tp) < 0)) then - hp%idd(tp) = infind(mt%D,Di(1)) - endif - - if (phase == 0) then - - ! itt = infind(mt_ttl,t_matrix(pr,k)) - select case(hp%dtype(tp)) - case(4) - mt_qext(1) = mt%qext(hp%idd(tp),itt,1,iff) - mt_qbsca(1) = mt%qbsca(hp%idd(tp),itt,1,iff) - case default - mt_qext = mt%qext(:,itt,1,iff) - mt_qbsca = mt%qbsca(:,itt,1,iff) - end select - - call zeff(freq,Di,Ni,ns,k2,mt_ttl(itt),0,do_ray, & - ze,zr,kr,mt_qext,mt_qbsca,xx_rhoi) - - else - - ! itt = infind(mt_tti,t_matrix(pr,k)) - select case(hp%dtype(tp)) - case(4) - if (hp%ifc(tp,1,iRe_type) < 0) then - hp%ifc(tp,1,iRe_type) = infind(mt%f,rhoi(1)/917.) - endif - mt_qext(1) = & - mt%qext(hp%idd(tp),itt+cnt_liq,hp%ifc(tp,1,iRe_type),iff) - mt_qbsca(1) = & - mt%qbsca(hp%idd(tp),itt+cnt_liq,hp%ifc(tp,1,iRe_type),iff) - case default - do i=1,ns - if (hp%ifc(tp,i,iRe_type) < 0) then - hp%ifc(tp,i,iRe_type) = infind(mt%f,rhoi(i)/917.) - endif - mt_qext(i) = mt%qext(i,itt+cnt_liq,hp%ifc(tp,i,iRe_type),iff) - mt_qbsca(i) = mt%qbsca(i,itt+cnt_liq,hp%ifc(tp,i,iRe_type),iff) - enddo - end select - - call zeff(freq,Di,Ni,ns,k2,mt_tti(itt),1,do_ray, & - ze,zr,kr,mt_qext,mt_qbsca,xx_rhoi) - - endif - - else - - xxa = -9.9 - call zeff(freq,Di,Ni,ns,k2,t_matrix(pr,k),phase,do_ray, & - ze,zr,kr,xxa,xxa,rhoi) - - - endif ! end of use mie table - - ! xxa = -9.9 - !call zeff(freq,Di,Ni,ns,k2,t_matrix(pr,k),phase,do_ray, & - ! ze2,zr,kr2,xxa,xxa,rhoi) - - ! if(abs(ze2-ze)/ze2 > 0.1) then - ! if(abs(kr2-kr)/kr2 > 0.1) then - - ! write(*,*) pr,k,tp,ze2,ze2-ze,abs(ze2-ze)/ze2,itt+cnt_liq,iff - ! write(*,*) pr,k,tp,ze2,kr2,kr2-kr,abs(kr2-kr)/kr2 - ! stop - - !endif - - deallocate(Di,Ni,rhoi,xx_rhoi,xxa,Deq) - if (use_mie_table == 1) deallocate(mt_qext,mt_qbsca,Ntemp) - - else ! can use z scaling - - if( hp%dtype(tp)==2 .and. abs(hp%p2(tp)+1) < 1E-8 ) then - - ze = hp%Ze_scaled(tp,itt,iRe_type) - zr = hp%Zr_scaled(tp,itt,iRe_type) - kr = hp%kr_scaled(tp,itt,iRe_type) - - else - scale_factor=rho_a*hm_matrix(tp,pr,k) - - zr = hp%Zr_scaled(tp,itt,iRe_type) * scale_factor - ze = hp%Ze_scaled(tp,itt,iRe_type) * scale_factor - kr = hp%kr_scaled(tp,itt,iRe_type) * scale_factor - endif - - endif ! end z_scaling - - ! kr=0 - - kr_vol(k) = kr_vol(k) + kr - z_vol(k) = z_vol(k) + ze - z_ray(k) = z_ray(k) + zr - - ! construct Ze_scaled, Zr_scaled, and kr_scaled ... if we can - if( .not. hp%z_flag(tp,itt,iRe_type) .and. 1.eq.1 ) then - - if( ( (hp%dtype(tp)==1 .or. hp%dtype(tp)==5 .or. hp%dtype(tp)==2) .and. abs(hp%p1(tp)+1) < 1E-8 ) .or. & - ( hp%dtype(tp)==3 .or. hp%dtype(tp)==4 ) & - ) then - - scale_factor=rho_a*hm_matrix(tp,pr,k) - - hp%Ze_scaled(tp,itt,iRe_type) = ze/ scale_factor - hp%Zr_scaled(tp,itt,iRe_type) = zr/ scale_factor - hp%kr_scaled(tp,itt,iRe_type) = kr/ scale_factor - - hp%z_flag(tp,itt,iRe_type)=.True. - - elseif( hp%dtype(tp)==2 .and. abs(hp%p2(tp)+1) < 1E-8 ) then - - hp%Ze_scaled(tp,itt,iRe_type) = ze - hp%Zr_scaled(tp,itt,iRe_type) = zr - hp%kr_scaled(tp,itt,iRe_type) = kr - - hp%z_flag(tp,itt,iRe_type)=.True. - endif - - endif - - enddo ! end loop of tp (hydrometeor type) - - else -! :: volume is hydrometeor-free - - kr_vol(k) = 0 - z_vol(k) = -999 - z_ray(k) = -999 - - endif - -! :: attenuation due to hydrometeors between radar and volume - a_to_vol(k) = 2*path_integral(kr_vol,hgt_matrix(pr,:),1,k-1) - -! :: attenuation due to gaseous absorption between radar and volume - if (g_to_vol_in_present) then - g_to_vol(k) = g_to_vol_in(k,pr) - else - if ( (use_gas_abs == 1) .or. ((use_gas_abs == 2) .and. (pr == 1)) ) then - g_vol(k) = gases(p_matrix(pr,k),t_matrix(pr,k)+273.15, & - rh_matrix(pr,k),freq) - g_to_vol(k) = path_integral(g_vol,hgt_matrix(pr,:),1,k-1) - elseif (use_gas_abs == 0) then - g_to_vol(k) = 0 - endif - endif - -! kr_matrix(pr,:)=kr_vol - -! :: store results in matrix for return to calling program - h_atten_to_vol(pr,k)=a_to_vol(k) - g_atten_to_vol(pr,k)=g_to_vol(k) - if ((do_ray == 1) .and. (z_ray(k) > 0)) then - Ze_ray(pr,k) = 10*log10(z_ray(k)) - else - Ze_ray(pr,k) = -999 - endif - if (z_vol(k) > 0) then - dBZe(pr,k) = 10*log10(z_vol(k))-a_to_vol(k)-g_to_vol(k) - Ze_non(pr,k) = 10*log10(z_vol(k)) - else - dBZe(pr,k) = -999 - Ze_non(pr,k) = -999 - endif - - enddo ! end loop of k (range gate) - ! Output array with gaseous absorption - if (g_to_vol_out_present) g_to_vol_out(:,pr) = g_to_vol - enddo ! end loop over pr (profile) - - end subroutine radar_simulator - diff --git a/src/atmos_param/cosp/quickbeam/radar_simulator_types.F90 b/src/atmos_param/cosp/quickbeam/radar_simulator_types.F90 new file mode 100644 index 0000000000..b36079b52a --- /dev/null +++ b/src/atmos_param/cosp/quickbeam/radar_simulator_types.F90 @@ -0,0 +1,67 @@ +#include "cosp_defs.H" +#ifdef COSP_GFDL + +!--------------------------------------------------------------------- +!------------ FMS version number and tagname for this file ----------- + +! $Id: radar_simulator_types.F90,v 20.0 2013/12/13 23:16:52 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif + + module radar_simulator_types + +! Collection of common variables and types +! Part of QuickBeam v1.03 by John Haynes +! http://reef.atmos.colostate.edu/haynes/radarsim + + integer, parameter :: & + maxhclass = 20 ,& ! max number of hydrometeor classes + nd = 85 ,& ! number of discrete particles + nRe_types = 250 ! number or Re size bins allowed in N and Z_scaled look up table + + real*8, parameter :: & + dmin = 0.1 ,& ! min size of discrete particle + dmax = 10000. ! max size of discrete particle + + integer, parameter :: & + mt_nfreq = 5 , & + mt_ntt = 39 , & ! num temperatures in table + mt_nf = 14 , & ! number of ice fractions in table + mt_nd = 85 ! num discrete mode-p drop sizes in table + + +! ---- hydrometeor class type ----- + + type class_param + real*8, dimension(maxhclass) :: p1,p2,p3,dmin,dmax,apm,bpm,rho + integer, dimension(maxhclass) :: dtype,col,cp,phase + logical, dimension(maxhclass,nRe_types) :: scaled + logical, dimension(maxhclass,mt_ntt,nRe_types) :: z_flag + real*8, dimension(maxhclass,mt_ntt,nRe_types) :: Ze_scaled,Zr_scaled,kr_scaled + real*8, dimension(maxhclass,nd,nRe_types) :: fc, rho_eff + integer, dimension(maxhclass,nd,nRe_types) :: ifc + integer, dimension(maxhclass) :: idd + end type class_param + +! ----- mie table structure ----- + + type mie + real*8 :: freq(mt_nfreq), tt(mt_ntt), f(mt_nf), D(mt_nd) + real*8, dimension(mt_nd,mt_ntt,mt_nf,mt_nfreq) :: qext, qbsca + integer :: phase(mt_ntt) + end type mie + + real*8, dimension(:), allocatable :: & + mt_qext, mt_qbsca ! extincion/backscatter efficiency + + real*8 :: & + mt_ttl(20), & ! liquid temperatures (C) + mt_tti(19) ! ice temperatures (C) + + integer*4 :: & + cnt_liq, & ! liquid temperature count + cnt_ice ! ice temperature count + + end module radar_simulator_types diff --git a/src/atmos_param/cosp/quickbeam/radar_simulator_types.f90 b/src/atmos_param/cosp/quickbeam/radar_simulator_types.f90 deleted file mode 100644 index dfe6c08062..0000000000 --- a/src/atmos_param/cosp/quickbeam/radar_simulator_types.f90 +++ /dev/null @@ -1,91 +0,0 @@ - -!--------------------------------------------------------------------- -!------------ FMS version number and tagname for this file ----------- - -! $Id: radar_simulator_types.f90,v 19.0 2012/01/06 20:04:58 fms Exp $ -! $Name: siena_201207 $ - - module radar_simulator_types - - public radar_simulator_types_init - -! Collection of common variables and types -! Part of QuickBeam v1.03 by John Haynes -! http://reef.atmos.colostate.edu/haynes/radarsim - - integer, parameter :: & - maxhclass = 20 ,& ! max number of hydrometeor classes - nd = 85 ,& ! number of discrete particles - nRe_types = 250 ! number or Re size bins allowed in N and Z_scaled look up table - - real*8, parameter :: & - dmin = 0.1 ,& ! min size of discrete particle - dmax = 10000. ! max size of discrete particle - - integer, parameter :: & - mt_nfreq = 5 , & - mt_ntt = 39 , & ! num temperatures in table - mt_nf = 14 , & ! number of ice fractions in table - mt_nd = 85 ! num discrete mode-p drop sizes in table - - -! ---- hydrometeor class type ----- - - type class_param - real*8, dimension(maxhclass) :: p1,p2,p3,dmin,dmax,apm,bpm,rho - integer, dimension(maxhclass) :: dtype,col,cp,phase - logical, dimension(maxhclass,nRe_types) :: scaled - logical, dimension(maxhclass,mt_ntt,nRe_types) :: z_flag - real*8, dimension(maxhclass,mt_ntt,nRe_types) :: Ze_scaled,Zr_scaled,kr_scaled - real*8, dimension(maxhclass,nd,nRe_types) :: fc, rho_eff - integer, dimension(maxhclass,nd,nRe_types) :: ifc - integer, dimension(maxhclass) :: idd - end type class_param - -! ----- mie table structure ----- - - type mie - real*8 :: freq(mt_nfreq), tt(mt_ntt), f(mt_nf), D(mt_nd) - real*8, dimension(mt_nd,mt_ntt,mt_nf,mt_nfreq) :: qext, qbsca - integer :: phase(mt_ntt) - end type mie - - real*8, dimension(:), allocatable :: & - mt_ttl, & ! liquid temperatures (C) - mt_tti, & ! ice temperatures (C) - mt_qext, mt_qbsca ! extincion/backscatter efficiency - - integer*4 :: & - cnt_liq, & ! liquid temperature count - cnt_ice ! ice temperature count - - contains - -subroutine radar_simulator_types_init - - - integer :: i - -! otherwise we still need to initialize temperature arrays for Ze -! scaling (which is only done when not using mie table) - - cnt_ice=19 - cnt_liq=20 -! if (.not.(allocated(mt_ttl).and.allocated(mt_tti))) then - allocate(mt_ttl(cnt_liq),mt_tti(cnt_ice)) ! note needed as th is is global array ... - ! which should be c hanged in the future -! endif - - do i=1,cnt_ice - mt_tti(i)=(i-1)*5-90 - enddo - - do i=1,cnt_liq - mt_ttl(i)=(i-1)*5 - 60 - enddo - - -end subroutine radar_simulator_types_init - - - end module radar_simulator_types diff --git a/src/atmos_param/cosp/quickbeam/zeff.f90 b/src/atmos_param/cosp/quickbeam/zeff.F90 similarity index 83% rename from src/atmos_param/cosp/quickbeam/zeff.f90 rename to src/atmos_param/cosp/quickbeam/zeff.F90 index 98c0b87a5b..f7001264ee 100644 --- a/src/atmos_param/cosp/quickbeam/zeff.f90 +++ b/src/atmos_param/cosp/quickbeam/zeff.F90 @@ -1,9 +1,14 @@ - +#include "cosp_defs.H" +#ifdef COSP_GFDL + !--------------------------------------------------------------------- !------------ FMS version number and tagname for this file ----------- - -! $Id: zeff.f90,v 19.0 2012/01/06 20:05:00 fms Exp $ -! $Name: siena_201207 $ + +! $Id: zeff.F90,v 20.0 2013/12/13 23:16:53 fms Exp $ +! $Name: tikal $ +! cosp_version = 1.3.2 + +#endif subroutine zeff(freq,D,N,nsizes,k2,tt,ice,xr,z_eff,z_ray,kr,qe,qs,rho_e) use math_lib @@ -48,27 +53,27 @@ subroutine zeff(freq,D,N,nsizes,k2,tt,ice,xr,z_eff,z_ray,kr,qe,qs,rho_e) ! ----- INTERNAL ----- integer :: & - correct_for_rho ! correct for density flag + correct_for_rho ! correct for density flag real*8, dimension(nsizes) :: & - D0, & ! D in (m) - N0, & ! N in m^-3 m^-1 - sizep, & ! size parameter - qext, & ! extinction efficiency - qbsca, & ! backscatter efficiency - rho_ice, & ! bulk density ice (kg m^-3) - f ! ice fraction + D0, & ! D in (m) + N0, & ! N in m^-3 m^-1 + sizep, & ! size parameter + qext, & ! extinction efficiency + qbsca, & ! backscatter efficiency + rho_ice, & ! bulk density ice (kg m^-3) + f ! ice fraction real*8 :: & - wl, & ! wavelength (m) + wl, & ! wavelength (m) cr ! kr(dB/km) = cr * kr(1/km) complex*16 :: & - m ! complex index of refraction of bulk form + m ! complex index of refraction of bulk form complex*16, dimension(nsizes) :: & - m0 ! complex index of refraction + m0 ! complex index of refraction integer*4 :: i,one real*8 :: pi real*8 :: eta_sum, eta_mie, const, z0_eff, z0_ray, k_sum, & - n_r, n_i, dqv(1), dqxt, dqsc, dbsc, dg, dph(1) + n_r, n_i, dqv(1), dqsc, dg, dph(1) integer*4 :: err complex*16 :: Xs1(1), Xs2(1) @@ -78,9 +83,9 @@ subroutine zeff(freq,D,N,nsizes,k2,tt,ice,xr,z_eff,z_ray,kr,qe,qs,rho_e) z0_ray = 0.0 ! // conversions - D0 = d*1E-6 ! m - N0 = n*1E12 ! 1/(m^3 m) - wl = 2.99792458/(freq*10) ! m + D0 = d*1E-6 ! m + N0 = n*1E12 ! 1/(m^3 m) + wl = 2.99792458/(freq*10) ! m ! // dielectric constant |k^2| defaults if (k2 < 0) then @@ -150,7 +155,7 @@ subroutine zeff(freq,D,N,nsizes,k2,tt,ice,xr,z_eff,z_ray,kr,qe,qs,rho_e) endif cr = 10./log(10.) kr = k_sum*0.25*pi*(1000.*cr) - + ! // z_ray = sum[D^6*N(D)*deltaD] if (xr == 1) then z0_ray = 0. diff --git a/src/atmos_param/cu_mo_trans/cu_mo_trans.F90 b/src/atmos_param/cu_mo_trans/cu_mo_trans.F90 index c5865d39ab..a3f422fe75 100644 --- a/src/atmos_param/cu_mo_trans/cu_mo_trans.F90 +++ b/src/atmos_param/cu_mo_trans/cu_mo_trans.F90 @@ -101,7 +101,7 @@ module cu_mo_trans_mod !--------------------- version number --------------------------------- character(len=128) :: version = '$Id: cu_mo_trans.F90,v 19.0 2012/01/06 20:05:02 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' contains diff --git a/src/atmos_param/damping_driver/damping_driver.F90 b/src/atmos_param/damping_driver/damping_driver.F90 index 8d91ce51d0..1d451a1b2c 100644 --- a/src/atmos_param/damping_driver/damping_driver.F90 +++ b/src/atmos_param/damping_driver/damping_driver.F90 @@ -100,7 +100,7 @@ module damping_driver_mod ! rfactr = coeff. for damping momentum at the top level character(len=128) :: version = '$Id: damping_driver.F90,v 19.0 2012/01/06 20:05:04 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- diff --git a/src/atmos_param/diag_cloud/diag_cloud.F90 b/src/atmos_param/diag_cloud/diag_cloud.F90 index b3b3bbb7e8..b342c5eb1a 100644 --- a/src/atmos_param/diag_cloud/diag_cloud.F90 +++ b/src/atmos_param/diag_cloud/diag_cloud.F90 @@ -45,7 +45,7 @@ MODULE DIAG_CLOUD_MOD !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: diag_cloud.F90,v 19.0 2012/01/06 20:05:06 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/diag_cloud/null/diag_cloud.F90 b/src/atmos_param/diag_cloud/null/diag_cloud.F90 deleted file mode 100644 index e66aadea20..0000000000 --- a/src/atmos_param/diag_cloud/null/diag_cloud.F90 +++ /dev/null @@ -1,366 +0,0 @@ -MODULE DIAG_CLOUD_MOD - - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! DIAGNOSTIC CLOUD PREDICTION - Gordon (1992) -! -! 1999 Feb -> 2000 July -! Contact persons: Bill Stern (for code structure information) -! Tony Gordon (for cloud scheme information) -! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!------------------------------------------------------------------- -! Calculates cloud fractions diagnostically using relative humidity, -! omega and stability -!------------------------------------------------------------------- - - use fms_mod, only: error_mesg, FATAL, file_exist, & - check_nml_error, open_namelist_file, & - mpp_pe, mpp_root_pe, close_file, & - write_version_number, stdlog - use Constants_Mod, only: Cp_Air, rdgas, rvgas, Kappa, HLv - use time_manager_mod, only: TIME_TYPE - use cloud_zonal_mod, only: CLOUD_ZONAL_INIT, GETCLD - use diag_cloud_rad_mod, only: CLOUD_TAU_DRIVER, diag_cloud_rad_INIT,& - cloud_pres_thick_for_tau, & - cloud_opt_prop_tg_lw, & - cloud_opt_prop_tg_sw, & - cloud_optical_depths, & - cloud_optical_depths2 - use sat_vapor_pres_mod, ONLY: ESCOMP - use shallow_conv_mod, ONLY: SHALLOW_CONV_INIT,MYLCL - -!----------------------------------------------------------------------- - implicit none -!----------------------------------------------------------------------- - - private - - -!--------------------- version number ---------------------------------- - character(len=128) :: version = '$Id: diag_cloud.F90,v 17.0 2009/07/21 02:54:10 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' -!----------------------------------------------------------------------- - - logical :: module_is_initialized = .false. - - - public diag_cloud_driver, diag_cloud_init, diag_cloud_end - public diag_cloud_driver2 - public diag_cloud_sum, diag_cloud_avg, diag_cloud_avg2, do_diag_cloud - public diag_cloud_restart - - contains - -!############################################################################# - - SUBROUTINE DIAG_CLOUD_DRIVER (is,js, & - temp,qmix,rhum,omega,lgscldelq,cnvcntq,convprc, & - pfull,phalf,psfc,coszen,lat,time, & - nclds,cldtop,cldbas,cldamt,r_uv,r_nir,ab_uv,ab_nir, & - em_lw, conc_drop, conc_ice, size_drop, size_ice, & - kbot) - -! Arguments (intent in) - - integer, intent(in) :: is,js - type(time_type), intent(in) :: time - real, intent(in) :: lat(:,:) - real, intent(in), dimension (:,:,:) :: temp,qmix,rhum,omega - real, intent(in), dimension (:,:,:) :: lgscldelq,cnvcntq,pfull, phalf - real, intent(in), dimension (:,:) :: convprc,psfc, coszen - - integer, intent(in), OPTIONAL, dimension(:,:) :: kbot - - -! INPUT -! ------ - -! IS,JS starting i,j indices from the full horizontal grid -! IX, IY Horizontal dimensions for global storage arrays -! TEMP Temperature (Deg K) at full model levels -! (dimensioned IDIM x JDIM x kx) -! QMIX Mixing Ratio at full model levels -! (dimensioned IDIM x JDIM x kx) -! RHUM Relative humidity fraction at full model levels -! (dimensioned IDIM x JDIM x kx) -! OMEGA Pressure vertical velocity at full model levels -! (dimensioned IDIM x JDIM x kx) -! LGSCLDELQ Averaged rate of change in mix ratio due to lg scale precip -! at full model levels -! (dimensioned IDIM x JDIM x kx) -! CNVCNTQ Accumulated count of change in mix ratio due to conv precip -! at full model levels -! (dimensioned IDIM x JDIM x kx) -! convprc Accumulated conv precip rate summed over all -! full model levels (mm/day ) -! (dimensioned IDIM x JDIM) -! PFULL Pressure at full model levels -! (dimensioned IDIM x JDIM x kx) -! PHALF Pressure at half model levels -! (dimensioned IDIM x JDIM x kx+1) -! PSFC Surface pressure field -! (dimensioned IDIM x JDIM) -! COSZEN cosine of the zenith angle -! (dimensioned IDIM x JDIM) -! TIME time of year (time_type) -! LAT latitudes in radians, dimensioned by (1xJDIM) -! KBOT OPTIONAL; lowest model level index array -! (dimensioned IDIM x JDIM) -!=================================================================== -! Arguments (intent out) - - integer, intent(out), dimension(:,:,:) :: cldtop,cldbas - integer, intent(out), dimension(:,:) :: nclds - - real, intent(out), dimension(:,:,:), optional :: r_uv,r_nir,ab_uv, & - ab_nir,em_lw, & - conc_drop, conc_ice, & - size_drop, size_ice - real, intent(out), dimension(:,:,:) :: cldamt - -! OUTPUT -! ------ - -! NCLDS number of (random overlapping) clouds in column and also -! the current # for clouds to be operating on -! (dimensioned IDIM x JDIM ) -! CLDTOP index of cloud tops (at cloud levels) -! (dimensioned IDIM x JDIM x kx) -! CLDBAS index of cloud bottoms (at cloud levels) -! (dimensioned IDIM x JDIM x kx) -! CLDAMT cloud amount (fraction) (at cloud levels) -! (dimensioned IDIM x JDIM x kx) -! R_UV fractional amount of ultraviolet radiation -! reflected by the clouds (at cloud levels) -! R_NIRfractional amount of near inrared radiation -! reflected by the clouds (at cloud levels) -! AB_UVfractional amount of ultraviolet radiation -! absorbed by the clouds (at cloud levels) -! AB_NIRfractional amount of near inrared radiation -! absorbed by the clouds (at cloud levels) -! EM_LWemissivity for the clouds (at cloud levels) - - - -end SUBROUTINE DIAG_CLOUD_DRIVER - -!--------------------------------------------------------------------- - -subroutine diag_cloud_driver2 (is, js, press, pflux, lat, time, nclds, & - cldtop, cldbas, cldamt, liq_frac, tau, & - ice_cloud, kbot) - -!--------------------------------------------------------------------- -! diag_cloud_driver2 returns the cloud specification arrays for the -! gordon diag cloud scheme. returned are the number of clouds per -! column, the cloud top, cloud base and fractional coverage of each -! cloud, the amount of the cloud which is liquid, its optical depth -! and an indicator as to whether it is ice or liquid (a different -! criterion than is used for the liquid fraction determination). -!---------------------------------------------------------------------- - -integer, intent(in) :: is,js -real, dimension (:,:,:), intent(in) :: press, pflux -real, dimension(:,:), intent(in) :: lat -type(time_type), intent(in) :: time -integer, dimension(:,:), intent(inout) :: nclds -integer, dimension(:,:,:), intent(out) :: cldtop,cldbas -real, dimension(:,:,:), intent(out) :: cldamt, liq_frac -real, dimension(:,:,:,:), intent(out) :: tau -logical, dimension(:,:,:), intent(out) :: ice_cloud -integer, dimension(:,:), intent(in), optional :: kbot - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,js starting subdomain i,j indices of data -! in the physics_window being integrated -! press pressure at model levels (1:nlev), surface -! pressure is stored at index value nlev+1 -! [ (kg /( m s^2) ] -! pflux average of pressure at adjacent model levels -! [ (kg /( m s^2) ] -! lat latitude of model points [ radians ] -! time time at which radiation calculation is to apply -! [ time_type (days, seconds) ] -! -! intent(inout) variables: -! -! nclds total number of clouds in each grid column -! -! intent(out) variables: -! -! cldtop k index of cloud top for each cloud -! cldbas k index of cloud base for each cloud -! cldamt fractional cloudiness for each cloud -! [ dimensionless ] -! liq_frac fraction of cloud which is liquid -! [ dimensionless ] -! tau cloud optical depth [ dimensionless ] -! ice_cloud logical flag indicating whether cloud is liquid -! or ice -! -! intent(in), optional variables: -! -! kbot present when running eta vertical coordinate, -! index of lowest model level above ground -! -!--------------------------------------------------------------------- - - - -end subroutine diag_cloud_driver2 - - -!####################################################################### - - SUBROUTINE DIAG_CLOUD_INIT( ix,iy,kx, ierr ) - -!======================================================================= -! ***** INITIALIZE Predicted Cloud Scheme -!======================================================================= - - -!--------------------------------------------------------------------- -! Arguments (Intent in) -! parmameter mxband = max number of radiative bands to be considered for some -! cloud properties (defined at top of module) -!--------------------------------------------------------------------- - integer, intent(in) :: ix, iy, kx -! INPUT -! ------ - -! IX, IY, KX Dimensions for global storage arrays (2- horiz, vert) -!--------------------------------------------------------------------- -! Arguments (Intent out) -!--------------------------------------------------------------------- - integer, intent(out) :: ierr - -! OUTPUT -! ------ - -! IERR Error flag - - -!===================================================================== - end SUBROUTINE DIAG_CLOUD_INIT - -!####################################################################### - - SUBROUTINE DIAG_CLOUD_END - - -!===================================================================== - end SUBROUTINE DIAG_CLOUD_END - -!####################################################################### - - function do_diag_cloud ( ) result (answer) - logical :: answer - -! returns logical value for whether diag_cloud has been initialized -! presumably if initialized then diag_cloud will be used - - answer = module_is_initialized - - end function do_diag_cloud - -!####################################################################### - - SUBROUTINE DIAG_CLOUD_SUM (is,js, & - temp,qmix,rhum,omega,lgscldelq,cnvcntq,convprc,kbot) - -!----------------------------------------------------------------------- - integer, intent(in) :: is,js - real, intent(in), dimension (:,:,:) :: temp,qmix,rhum,omega - real, intent(in), dimension (:,:,:) :: lgscldelq,cnvcntq - real, intent(in), dimension (:,:) :: convprc - - integer, intent(in), OPTIONAL, dimension(:,:) :: kbot - -! INPUT -! ------ - -! IS,JS starting i,j indices from the full horizontal grid -! TEMP Temperature (Deg K) at full model levels -! (dimensioned IDIM x JDIM x kx) -! QMIX Mixing Ratio at full model levels -! (dimensioned IDIM x JDIM x kx) -! RHUM Relative humidity fraction at full model levels -! (dimensioned IDIM x JDIM x kx) -! OMEGA Pressure vertical velocity at full model levels -! (dimensioned IDIM x JDIM x kx) -! LGSCLDELQ Averaged rate of change in mix ratio due to lg scale precip -! at full model levels -! (dimensioned IDIM x JDIM x kx) -! CNVCNTQ Accumulated count of change in mix ratio due to conv precip -! at full model levels -! (dimensioned IDIM x JDIM x kx) -! convprc Accumulated conv precip rate summed over all -! full model levels (mm/day ) -! (dimensioned IDIM x JDIM) -! KBOT OPTIONAL; lowest model level index array -! (dimensioned IDIM x JDIM) -! ******* kbot will be used to select only those qmix values that are really -! ******* needed (typically this will be the bottom level except for -! ******* step mountains -!----------------------------------------------------------------------- - - - end SUBROUTINE DIAG_CLOUD_SUM - -!####################################################################### - - subroutine DIAG_CLOUD_AVG (is, js, temp,qmix,rhum,omega, & - lgscldelq,cnvcntq,convprc, ierr) - -!----------------------------------------------------------------------- - integer, intent(in) :: is, js - real, intent(inout), dimension(:,:,:) :: temp,qmix,rhum,omega - real, intent(inout), dimension(:,:,:) :: lgscldelq,cnvcntq - real, intent(inout), dimension(:,:) :: convprc - integer, intent(out) :: ierr -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- - - end SUBROUTINE DIAG_CLOUD_AVG - -!####################################################################### - - subroutine DIAG_CLOUD_AVG2 (is, js, qmix, ierr) - -!----------------------------------------------------------------------- - integer, intent(in) :: is, js - real, intent(inout), dimension(:,:) :: qmix - integer, intent(out) :: ierr -!----------------------------------------------------------------------- - -!----------------------------------------------------------------------- - - end SUBROUTINE DIAG_CLOUD_AVG2 - -!####################################################################### - -!####################################################################### -! -! -! NAME="diag_cloud_restart" - - -end MODULE DIAG_CLOUD_MOD diff --git a/src/atmos_param/diag_cloud_rad/diag_cloud_rad.F90 b/src/atmos_param/diag_cloud_rad/diag_cloud_rad.F90 index 036c4582db..14bc869ee9 100644 --- a/src/atmos_param/diag_cloud_rad/diag_cloud_rad.F90 +++ b/src/atmos_param/diag_cloud_rad/diag_cloud_rad.F90 @@ -157,7 +157,7 @@ MODULE DIAG_CLOUD_RAD_MOD !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: diag_cloud_rad.F90,v 19.0 2012/01/06 20:05:09 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/diag_cloud_rad/null/diag_cloud_rad.F90 b/src/atmos_param/diag_cloud_rad/null/diag_cloud_rad.F90 deleted file mode 100644 index f1750d8b27..0000000000 --- a/src/atmos_param/diag_cloud_rad/null/diag_cloud_rad.F90 +++ /dev/null @@ -1,605 +0,0 @@ -MODULE DIAG_CLOUD_RAD_MOD - - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -!CLOUD RADIATIVE PROPERTIES -! -! May-Oct 1998 -> Sep 2000 -! Contact persons: Tony Gordon, Bill Stern (for modified code) -! Steve Klein (for original Fotran 90 code) -! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -!This module solves for the radiative properties of -! every cloud. In particular it uses either the -! two stream approach or the delta-Eddington approach -! to solve for the longwave emissivity, the ultra-violet- -! visible reflectivities and absorptions, and the -! near-infrared reflectivities and absorptions. -! -! Modifications to Steve Klein's version have been made -! to accomodate the empirical diagnostic cloud scheme of Tony Gordon, -! frozen version v197 as discussed below. -! -! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!------------------------------------------------------------------- - -use fms_mod, only: error_mesg, FATAL, file_exist, & - check_nml_error, open_namelist_file, & - mpp_pe, mpp_root_pe, close_file, & - write_version_number, stdlog - -! Steve Klein's Cloud_Rad module - use Cloud_Rad_Mod, ONLY: CLOUD_RAD, CLOUD_RAD_INIT, & - cloud_rad_k_diag - - -!------------------------------------------------------------------- - - implicit none - -!------------------------------------------------------------------- - -! The module contains the following: -! -!SUBROUTINES -! -! CLOUD_TAU_DRIVER -! calls a sequence of suboutines to compute -! cloud optical and radiative properties, as detailed -! below --> -! CLOUD_PRES_THICK_FOR_TAU -! computes cloud-type dependent set of pressure -! thicknesses for each distinct cloud layer, which are -! used to parameterize cloud optical depths -! CLOUD_OPTICAL_DEPTHS -! Specify / crudely parameterize cloud optical depths -! for distinct cloud layers,incorporating a -! parameterization scheme for non-anvil cirrus -! proposed by Harshvardhan, based upon observations by -! Platt and Harshvardhan -! -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! -! - - private - - - -!--------------------- version number ---------------------------------- - character(len=128) :: version = '$Id: diag_cloud_rad.F90,v 17.0 2009/07/21 02:54:14 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. -!----------------------------------------------------------------------- - - -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public cloud_tau_driver, diag_cloud_rad_init, diag_cloud_rad_end, & - cloud_pres_thick_for_tau, cloud_optical_depths, & - cloud_optical_depths2, & - cloud_opt_prop_tg_lw, cloud_opt_prop_tg_sw, cloud_opt_prop_tg2 - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - contains - - -!######################################################################## -!######################################################################## - -SUBROUTINE CLOUD_TAU_DRIVER (qmix_kx, tempcld, tau, coszen, & - r_uv, r_nir, ab_uv, ab_nir, em_lw) - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! This subroutine returns the following radiative properties of clouds -! -! 1. r_uv: cloud reflectance in uv band -! 2. r_nir: cloud reflectance in nir band -! 3. ab_uv: cloud absorption in uv band -! 4. ab_nir: cloud absorption in nir band -! 5. em_lw: longwave cloud emissivity -! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! ------ -!INPUT: -! ------ -! -! TEMPCLD cloud layer mean temperature (degrees Kelvin) of distinct -! cloud layers -! COSZEN cosine of the zenith angle - - -! ----------------------------------------------------------------------------- -! -! ------------- -!OUTPUT: -! ------------- -! -! r_uv cloud reflectance in uv band -! r_nir cloud reflectance in nir band -! ab_uv cloud absorption in uv band -! ab_nir cloud absorption in nir band -! em_lw longwave cloud emissivity -! -! ------------- -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! User Interface variables -! ------------------------ - -real, intent(in), dimension(:,:,:) :: tempcld -real, intent(in), dimension(:,:) :: qmix_kx -real, intent(in), dimension(:,:) :: coszen -real, intent(in), dimension(:,:,:,:) :: tau - - -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -real, intent (out), dimension(:,:,:), optional :: r_uv,r_nir, & - ab_uv,ab_nir,em_lw - -! ***************************************************************** - - - -!-------------------------------------------------------------------- - - call error_mesg('CLOUD_TAU_DRIVER', & - 'This module is not supported as part of the public release', FATAL) - -END SUBROUTINE CLOUD_TAU_DRIVER - - - - - -!######################################################################## -subroutine cloud_pres_thick_for_tau (nclds,icld,cldtop,cldbas, & - & delp_true,lhight,lhighb, lmidt, lmidb, llowt,lk,delp, & - & phalf, psfc ) - -! This subroutine calculates a special cloud-type dependent set of -! cloud pressure thicknesses that will be employed to compute cloud optical -! depths. - -!=================================================================== - -! Arguments (intent in) - -real, intent(in), dimension(:,:,:) :: phalf, delp_true -integer, intent(in), dimension(:,:,:) :: cldtop,cldbas,icld -integer, intent(in), dimension(:,:) :: nclds -integer, intent(in), dimension(:,:) :: lhight, lhighb, lmidt, lmidb, llowt -integer, intent(in) :: lk -real, intent(in), dimension(:,:) :: psfc - -! INPUT -! ------ - -! PHALF pressure at half levels (Pascals) -! NOTE: it is assumed that phalf(j+1) > phalf(j) -! PSFC Surface pressure field -! NCLDS number of (random overlapping) clouds in column and also -! the current # for clouds to be operating on -! ICLD marker array of cloud types/heights (at cloud levels) -! CLDTOP index of cloud tops (at cloud levels) -! CLDBAS index of cloud bottoms (at cloud levels) -! DELP_TRUE true cloud pressure thickness of distinct cloud layers -! (at cloud levels - in Pa) -! LHIGHT vertical level index upper limit for high cloud tops -! LHIGHB vertical level index lower limit for high cloud bases -! LMIDT vertical level index upper limit for mid cloud tops -! LMIDB vertical level index lower limit for mid cloud bases -! LLOWT vertical level index upper limit for low cloud tops -! LK vertical level below which no low cloud bases can exist - -!=================================================================== - -! Arguments (intent out) - -real, intent(out), dimension(:,:,:) :: delp - -! OUTPUT -! ------ - -! DELP cloud pressure thickness used to calculate cloud optical depths -! of distinct cloud layers -!======================================================================= - - - - - call error_mesg('cloud_pres_thick_for_tau', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cloud_pres_thick_for_tau - -!######################################################################## - -subroutine cloud_optical_depths2 (nclds,icld,cldtop,cldbas,tempcld,delp, & - & tau,phalf, liq_frac ) - -! This subroutine specifies/crudely parameterizes cloud optical depths -! of non-anvil cirrus clouds based upon a parameterization scheme -! resembling that proposed by Harshvardhan, -! (which is based on observations by Platt and Harshvardhan). - -!=================================================================== - -! Arguments (intent in) - -real, intent(in), dimension(:,:,:) :: phalf, delp, tempcld -integer, intent(in), dimension(:,:,:) :: cldtop, cldbas, icld -integer, intent(in), dimension(:,:) :: nclds - -! INPUT -! ------ - -! PHALF pressure at half levels (Pascals) -! NOTE: it is assumed that phalf(j+1) > phalf(j) -! NCLDS number of (random overlapping) clouds in column and also -! the current # for clouds to be operating on -! ICLD marker array of cloud types (at cloud levels) -! CLDTOP index of cloud tops (at cloud levels) -! CLDBAS index of cloud bottoms (at cloud levels) -! TEMPCLD cloud layer mean temperature -! (degrees Kelvin, at cloud levels) -! DELP cloud pressure thickness used for cloud optical depth -! (at cloud levels) - -!=================================================================== - -! Arguments (intent out) - -real, intent(inout), dimension(:,:,:,:) :: tau -real, intent(inout), dimension(:,:,:) :: liq_frac - -! OUTPUT -! ------ - -! TAU cloud optical depth (at cloud levels) - -!======================================================================= - - - - call error_mesg('cloud_optical_depths2', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cloud_optical_depths2 - -subroutine cloud_optical_depths (nclds,icld,cldtop,cldbas,tempcld,delp, & - & tau,phalf ) - -! This subroutine specifies/crudely parameterizes cloud optical depths -! of non-anvil cirrus clouds based upon a parameterization scheme -! resembling that proposed by Harshvardhan, -! (which is based on observations by Platt and Harshvardhan). - -!=================================================================== - -! Arguments (intent in) - -real, intent(in), dimension(:,:,:) :: phalf, delp, tempcld -integer, intent(in), dimension(:,:,:) :: cldtop, cldbas ,icld -integer, intent(in), dimension(:,:) :: nclds - -! INPUT -! ------ - -! PHALF pressure at half levels (Pascals) -! NOTE: it is assumed that phalf(j+1) > phalf(j) -! NCLDS number of (random overlapping) clouds in column and also -! the current # for clouds to be operating on -! ICLD marker array of cloud types (at cloud levels) -! CLDTOP index of cloud tops (at cloud levels) -! CLDBAS index of cloud bottoms (at cloud levels) -! TEMPCLD cloud layer mean temperature -! (degrees Kelvin, at cloud levels) -! DELP cloud pressure thickness used for cloud optical depth -! (at cloud levels) - -!=================================================================== - -! Arguments (intent out) - -real, intent(out), dimension(:,:,:,:) :: tau - -! OUTPUT -! ------ - -! TAU cloud optical depth (at cloud levels) - -!======================================================================= - - call error_mesg('cloud_optical_depths', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cloud_optical_depths - -!######################################################################## - -subroutine CLOUD_OPT_PROP_tg_lw( tau, liq_frac, em_lw) - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! This subroutine calculates the following optical properties -! for each cloud: -! -! 1. tau :optical depth in each band -! 2. w0 :single scattering albedo for each band -! 3. gg :asymmetry parameter for each band -! 4. em_lw :longwave cloud emissivity -! -! The formulas for optical depth come from Slingo (1989) for liquid -! clouds and from Ebert and Curry (1992) for ice clouds. -! -! Slingo (1989) is at J. Atmos. Sci., vol. 46, pp. 1419-1427 -! Ebert and Curry (1992) is at J. Geophys. Res., vol. 97, pp. 3831-3836 -! -! -! The mixed phase optical properties are based upon equation 14 -! of Rockel et al. 1991, Contributions to Atmospheric Physics, -! volume 64, pp.1-12. These equations are: -! -! (1) tau = tau_liq + tau_ice -! -! (2) w0 = ( w0_liq * tau_liq + w0_ice * tau_ice ) / -! ( tau_liq + tau_ice ) -! -! w0(:,:,1) = 0.99999; w0(:,:,2) = 0.9942 (in v197 - standard) -! w0(:,:,1) = 0.99999; w0(:,:,2) = F(Z.M. mixing ratio at lowest model level) -! (in v197 - anomalous absorption) -! -! (3) g = ( g_liq * w0_liq * tau_liq + g_ice * w0_ice * tau_ice ) / -! ( w0_liq * tau_liq + w0_ice * tau_ice ) -! -! g(:,:,1:2) = 0.85 in v197 -! -! -! (4) transmivvity_lw = transmissivity_lw_ice * transmissivity_lw_liq -! -! The last equation could be rewritten, after algebraic manipulation, as: -! -! (5) em_lw = em_lw_liq + em_lw_ice - (em_lw_liq * em_lw_ice ) -! -! However, the other form of the equation, i.e., -! 1 - exp(tau_liq + tau_ice) will actually be solved. - -! ******************************************************************* -! -! -! (6) v197 only: Must first solve for LWP and IWP knowing -! tau, k_sw_liq, k_sw_ice, wgt_liq and wgt_ice. -! -! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -!VARIABLES -! -! ------------ -!INPUT/OUTPUT: -! ------------ -! -! tau optical depth in each band -! w0 single scattering albedo for each band -! gg asymmetry parameter for each band -! em_lw longwave cloud emissivity - -! NOTE: In tg's version, LWP and IWP are effective cloud -! water paths. They could be computed either in this -! subroutine or in subroutine cloud_water_path. - -! LWP cloud liquid water path (kg of condensate per square meter) -! IWP cloud ice path (kg of condensate per square meter) -! -! -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -! -! - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! User Interface variables -! ------------------------ - -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! - -real, intent (in), dimension(:,:,:) :: liq_frac -real, intent (in), dimension(:,:,:,:) :: tau -real, intent (out), dimension(:,:,:) :: em_lw - - call error_mesg('CLOUD_OPT_PROP_tg_lw', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine CLOUD_OPT_PROP_tg_lw - -subroutine CLOUD_OPT_PROP_tg_sw( liq_frac, & - tau, direct, & - qmix_kx, cosz, cuvrf, cirrf, & - cuvab, cirab) - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! This subroutine calculates the following optical properties -! for each cloud: -! -! 1. tau :optical depth in each band -! 2. w0 :single scattering albedo for each band -! 3. gg :asymmetry parameter for each band -! 4. em_lw :longwave cloud emissivity -! -! The formulas for optical depth come from Slingo (1989) for liquid -! clouds and from Ebert and Curry (1992) for ice clouds. -! -! Slingo (1989) is at J. Atmos. Sci., vol. 46, pp. 1419-1427 -! Ebert and Curry (1992) is at J. Geophys. Res., vol. 97, pp. 3831-3836 -! -! -! The mixed phase optical properties are based upon equation 14 -! of Rockel et al. 1991, Contributions to Atmospheric Physics, -! volume 64, pp.1-12. These equations are: -! -! (1) tau = tau_liq + tau_ice -! -! (2) w0 = ( w0_liq * tau_liq + w0_ice * tau_ice ) / -! ( tau_liq + tau_ice ) -! -! w0(:,:,1) = 0.99999; w0(:,:,2) = 0.9942 (in v197 - standard) -! w0(:,:,1) = 0.99999; w0(:,:,2) = F(Z.M. mixing ratio at lowest model level) -! (in v197 - anomalous absorption) -! -! (3) g = ( g_liq * w0_liq * tau_liq + g_ice * w0_ice * tau_ice ) / -! ( w0_liq * tau_liq + w0_ice * tau_ice ) -! -! g(:,:,1:2) = 0.85 in v197 -! -! -! (4) transmivvity_lw = transmissivity_lw_ice * transmissivity_lw_liq -! -! The last equation could be rewritten, after algebraic manipulation, as: -! -! (5) em_lw = em_lw_liq + em_lw_ice - (em_lw_liq * em_lw_ice ) -! -! However, the other form of the equation, i.e., -! 1 - exp(tau_liq + tau_ice) will actually be solved. - -! ******************************************************************* -! -! -! (6) v197 only: Must first solve for LWP and IWP knowing -! tau, k_sw_liq, k_sw_ice, wgt_liq and wgt_ice. -! -! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -!VARIABLES -! -! ------------ -!INPUT/OUTPUT: -! ------------ -! -! tau optical depth in each band -! w0 single scattering albedo for each band -! gg asymmetry parameter for each band -! em_lw longwave cloud emissivity - -! NOTE: In tg's version, LWP and IWP are effective cloud -! water paths. They could be computed either in this -! subroutine or in subroutine cloud_water_path. - -! LWP cloud liquid water path (kg of condensate per square meter) -! IWP cloud ice path (kg of condensate per square meter) -! -! -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -! -! -! User Interface variables -! ------------------------ - -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! - -! -real, intent (in), dimension(:,:) :: qmix_kx, cosz -logical, intent (in), dimension(:,:,:) :: direct -real, intent (in), dimension(:,:,:,:) :: tau -real, intent (in), dimension(:,:,:) :: liq_frac -real, intent (out), dimension(:,:,:) :: cuvrf, cirrf, & - cuvab, cirab - - call error_mesg('CLOUD_OPT_PROP_tg_sw', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine CLOUD_OPT_PROP_tg_sw - - - - -subroutine CLOUD_OPT_PROP_tg2 (tau, tempcld, liq_frac) - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! -! tempcld cloud layer mean temperature (degrees Kelvin), with -! compressed cloud layer index. -! -! -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! -! User Interface variables -! ------------------------ - -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! - -real, intent (in), dimension(:,:,:,:) :: tau -real, intent (in), dimension(:,:,:) :: tempcld - -! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! - -real, intent (out), dimension(:,:,:) :: liq_frac - - - call error_mesg('CLOUD_OPT_PROP_tg2', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine CLOUD_OPT_PROP_tg2 - - -!####################################################################### - - SUBROUTINE DIAG_CLOUD_RAD_INIT(do_crad_init) - -!======================================================================= -! ***** INITIALIZE Predicted Cloud Scheme -!======================================================================= - -!--------------------------------------------------------------------- -! Argument (Intent inout) -! do_crad_init - logical switch to be set = .true. after init is done -!--------------------------------------------------------------------- - logical, intent(inout) :: do_crad_init - -!--------------------------------------------------------------------- -! --- Output version -!--------------------------------------------------------------------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - -!------------------------------------------------------------------- - module_is_initialized = .true. - - call error_mesg('DIAG_CLOUD_RAD_INIT', & - 'This module is not supported as part of the public release', FATAL) - -END SUBROUTINE DIAG_CLOUD_RAD_INIT - -!####################################################################### - -SUBROUTINE DIAG_CLOUD_RAD_END - -!------------------------------------------------------------------- - - module_is_initialized = .false. - - - call error_mesg('DIAG_CLOUD_RAD_END', & - 'This module is not supported as part of the public release', FATAL) - -END SUBROUTINE DIAG_CLOUD_RAD_END - -end MODULE DIAG_CLOUD_RAD_MOD - - - diff --git a/src/atmos_param/diag_integral/diag_integral.F90 b/src/atmos_param/diag_integral/diag_integral.F90 index 74ba81d82a..ff1f28a04e 100644 --- a/src/atmos_param/diag_integral/diag_integral.F90 +++ b/src/atmos_param/diag_integral/diag_integral.F90 @@ -1,4 +1,5 @@ module diag_integral_mod +#include-! Dummy interface. -! Arguments: -! timestamp (optional, intent(in)) : A character string that represents the model time, -! used for writing restart. timestamp will append to -! the any restart file name as a prefix. -! -! -subroutine diag_cloud_restart(timestamp) - character(len=*), intent(in), optional :: timestamp - -end subroutine diag_cloud_restart -!! ! fil ! @@ -41,8 +42,8 @@ module diag_integral_mod !--------------------------------------------------------------------- !----------- version number for this module ------------------- -character(len=128) :: version = '$Id: diag_integral.F90,v 19.0 2012/01/06 20:05:41 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: diag_integral.F90,v 20.0 2013/12/13 23:17:05 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -1190,7 +1191,7 @@ subroutine write_field_averages (Time) real :: xtime, rcount integer :: nn, ninc, nst, nend, fields_to_print integer :: i, kount - + integer(LONG_KIND) :: icount !-------------------------------------------------------------------- ! local variables: ! @@ -1222,22 +1223,23 @@ subroutine write_field_averages (Time) rcount = real(field_count(i)) call mpp_sum (rcount) call mpp_sum (field_sum(i)) - field_count(i) = nint(rcount) + icount = rcount !-------------------------------------------------------------------- ! verify that all the data expected for an integral has been ! obtained. !-------------------------------------------------------------------- - if (field_count(i) == 0 ) call error_mesg & + if (icount == 0 ) call error_mesg & ('diag_integral_mod', & 'field_count equals zero for field_name ' // & field_name(i)(1:len_trim(field_name(i))), FATAL ) - kount = field_count(i)/field_size - if ((field_size)*kount /= field_count(i)) & - call error_mesg & + kount = icount/field_size + if ((field_size*1.0)*kount /= rcount) then + print*,"name,pe,kount,field_size,icount,rcount=",trim(field_name(i)),mpp_pe(),kount,field_size,icount,rcount + call error_mesg & ('diag_integral_mod', & 'field_count not a multiple of field_size', FATAL ) - + endif !---------------------------------------------------------------------- ! define the global integral for field i. reinitialize the point ! and data accumulators. diff --git a/src/atmos_param/diffusivity/diffusivity.F90 b/src/atmos_param/diffusivity/diffusivity.F90 index 59c23dc832..f01102be79 100644 --- a/src/atmos_param/diffusivity/diffusivity.F90 +++ b/src/atmos_param/diffusivity/diffusivity.F90 @@ -96,7 +96,7 @@ module diffusivity_mod !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: diffusivity.F90,v 19.0 2012/01/06 20:05:43 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !======================================================================= diff --git a/src/atmos_param/diffusivity/null/diffusivity.F90 b/src/atmos_param/diffusivity/null/diffusivity.F90 deleted file mode 100644 index 661d59a237..0000000000 --- a/src/atmos_param/diffusivity/null/diffusivity.F90 +++ /dev/null @@ -1,185 +0,0 @@ - -module diffusivity_mod - -!======================================================================= -! -! DIFFUSIVITY MODULE -! -! Routines for computing atmospheric diffusivities in the -! planetary boundary layer and in the free atmosphere -! -!======================================================================= - - -use constants_mod, only : grav, vonkarm, cp_air, rdgas, rvgas - -use fms_mod, only: error_mesg, FATAL, file_exist, & - check_nml_error, open_namelist_file, & - mpp_pe, mpp_root_pe, close_file, & - write_version_number, stdlog - -use monin_obukhov_mod, only : mo_diff - -implicit none -private - -! public interfaces -!======================================================================= - - public diffusivity, pbl_depth, molecular_diff, & - diffusivity_init, diffusivity_end - -! -!======================================================================= - - -!--------------------- version number ---------------------------------- - -character(len=128) :: version = '$Id: diffusivity.F90,v 10.0 2003/10/24 22:00:28 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' -logical :: module_is_initialized = .false. - -!======================================================================= - -contains - -!======================================================================= - -subroutine diffusivity_init - - -!---------- output namelist to log------------------------------------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('diffusivity_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine diffusivity_init - -!======================================================================= - -subroutine diffusivity_end - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('diffusivity_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine diffusivity_end - -!======================================================================= - -subroutine diffusivity(t, q, u, v, p_full, p_half, z_full, z_half, & - u_star, b_star, h, k_m, k_t, kbot) - -real, intent(in), dimension(:,:,:) :: t, q, u, v -real, intent(in), dimension(:,:,:) :: p_full, p_half -real, intent(in), dimension(:,:,:) :: z_full, z_half -real, intent(in), dimension(:,:) :: u_star, b_star -real, intent(inout), dimension(:,:,:) :: k_m, k_t -real, intent(out), dimension(:,:) :: h -integer, intent(in), optional, dimension(:,:) :: kbot - -! input: - -! t : real, dimension(:,:,:) -- (:,:,pressure), third index running -! from top of atmosphere to bottom -! temperature (K) -! -! q : real, dimension(:,:,:) -! water vapor specific humidity (nondimensional) -! -! u : real, dimension(:,:) -! zonal wind (m/s) -! -! v : real, dimension(:,:,:) -! meridional wind (m/s) -! -! z_full : real, dimension(:,:,: -! height of full levels (m) -! 1 = top of atmosphere; size(p_half,3) = surface -! size(z_full,3) = size(t,3) -! -! z_half : real, dimension(:,:,:) -! height of half levels (m) -! size(z_half,3) = size(t,3) +1 -! z_half(:,:,size(z_half,3)) must be height of surface! -! (if you are not using eta-model) -! -! u_star: real, dimension(:,:) -! friction velocity (m/s) -! -! b_star: real, dimension(:,:) -! buoyancy scale (m/s**2) - -! (u_star and b_star can be obtained by calling -! mo_drag in monin_obukhov_mod) - -! output: - -! h : real, dimension(:,:,) -! depth of planetary boundary layer (m) -! -! k_m : real, dimension(:,:,:) -! diffusivity for momentum (m**2/s) -! -! defined at half-levels -! size(k_m,3) should be at least as large as size(t,3) -! only the returned values at -! levels 2 to size(t,3) are meaningful -! other values will be returned as zero -! -! k_t : real, dimension(:,:,:) -! diffusivity for temperature and scalars (m**2/s) -! -!--------------------------------------------------------------------- - - call error_mesg('diffusivity', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine diffusivity - -!======================================================================= - -subroutine pbl_depth(t, u, v, z, u_star, b_star, h, kbot) - - -real, intent(in) , dimension(:,:,:) :: t, u, v, z -real, intent(in) , dimension(:,:) :: u_star,b_star -real, intent(out), dimension(:,:) :: h -integer,intent(in) , optional, dimension(:,:) :: kbot - -!--------------------------------------------------------------------- - - call error_mesg('pbl_depth', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine pbl_depth - -!======================================================================= - -subroutine molecular_diff ( temp, press, k_m, k_t) - -real, intent(in), dimension (:,:,:) :: temp, press -real, intent(inout), dimension (:,:,:) :: k_m, k_t - -!--------------------------------------------------------------------- - - call error_mesg('molecular_diff', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine molecular_diff - -!======================================================================= - -end module diffusivity_mod - diff --git a/src/atmos_param/donner_deep/donner_deep.F90 b/src/atmos_param/donner_deep/donner_deep.F90 index dabfcc583a..fa34ae3865 100644 --- a/src/atmos_param/donner_deep/donner_deep.F90 +++ b/src/atmos_param/donner_deep/donner_deep.F90 @@ -61,8 +61,8 @@ module donner_deep_mod !----------- ****** VERSION NUMBER ******* --------------------------- -character(len=128) :: version = '$Id: donner_deep.F90,v 19.0 2012/01/06 20:06:52 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: donner_deep.F90,v 20.0 2013/12/13 23:17:16 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !-------------------------------------------------------------------- @@ -1601,27 +1601,30 @@ subroutine donner_deep (is, ie, js, je, dt, temp, mixing_ratio, pfull, & ! precip associated with the cell and meso circulations. ! UNITS KG / KG/ DAY !-------------------------------------------------------------------- - do k=1,nlev_lsm - frz_meso(:,:,k) = (Don_budgets%precip_budget(:,:,k,2,2) + & + if (Initialized%do_conservation_checks .or. & + Nml%do_budget_analysis) then + do k=1,nlev_lsm + frz_meso(:,:,k) = (Don_budgets%precip_budget(:,:,k,2,2) + & Don_budgets%precip_budget(:,:,k,2,3) + & Don_budgets%precip_budget(:,:,k,4,2) + & Don_budgets%precip_budget(:,:,k,4,3))* & Don_conv%a1(:,:) - liq_meso(:,:,k) = (Don_budgets%precip_budget(:,:,k,1,2) + & + liq_meso(:,:,k) = (Don_budgets%precip_budget(:,:,k,1,2) + & Don_budgets%precip_budget(:,:,k,1,3) + & Don_budgets%precip_budget(:,:,k,3,2) + & Don_budgets%precip_budget(:,:,k,3,3) + & Don_budgets%precip_budget(:,:,k,5,2) + & Don_budgets%precip_budget(:,:,k,5,3))* & Don_conv%a1(:,:) - frz_cell(:,:,k) = (Don_budgets%precip_budget(:,:,k,2,1) + & + frz_cell(:,:,k) = (Don_budgets%precip_budget(:,:,k,2,1) + & Don_budgets%precip_budget(:,:,k,4,1))* & Don_conv%a1(:,:) - liq_cell(:,:,k) = (Don_budgets%precip_budget(:,:,k,1,1) + & + liq_cell(:,:,k) = (Don_budgets%precip_budget(:,:,k,1,1) + & Don_budgets%precip_budget(:,:,k,3,1) + & Don_budgets%precip_budget(:,:,k,5,1))* & Don_conv%a1(:,:) - end do + end do + endif !-------------------------------------------------------------------- ! call deallocate_local_variables to deallocate space used by the diff --git a/src/atmos_param/donner_deep/donner_deep_k.F90 b/src/atmos_param/donner_deep/donner_deep_k.F90 index efb37ffff5..4e6c81daa1 100644 --- a/src/atmos_param/donner_deep/donner_deep_k.F90 +++ b/src/atmos_param/donner_deep/donner_deep_k.F90 @@ -1,6 +1,6 @@ !#VERSION NUMBER: -! $Name: siena_201207 $ -! $Id: donner_deep_k.F90,v 19.0 2012/01/06 20:07:24 fms Exp $ +! $Name: tikal $ +! $Id: donner_deep_k.F90,v 20.0 2013/12/13 23:17:18 fms Exp $ !module donner_deep_inter_mod @@ -4187,6 +4187,7 @@ subroutine don_d_integ_cu_ensemble_k & endif pmelt_lsm = 2.0e05 + if( temp_c(1) > Param%KELVIN ) then do k=1,nlev_lsm-1 if ((temp_c(k) >= Param%KELVIN) .and. & (temp_c(k+1) <= Param%KELVIN)) then @@ -4194,6 +4195,7 @@ subroutine don_d_integ_cu_ensemble_k & exit endif end do + endif if (debug_ijt) then write (diag_unit, '(a, 2f19.10)') & diff --git a/src/atmos_param/donner_deep/donner_lite_k.F90 b/src/atmos_param/donner_deep/donner_lite_k.F90 index 1f92c5e587..9ff2b048e8 100644 --- a/src/atmos_param/donner_deep/donner_lite_k.F90 +++ b/src/atmos_param/donner_deep/donner_lite_k.F90 @@ -1,5 +1,5 @@ !VERSION NUMBER: -! $Id: donner_lite_k.F90,v 19.0 2012/01/06 20:07:26 fms Exp $ +! $Id: donner_lite_k.F90,v 20.0 2013/12/13 23:17:21 fms Exp $ !###################################################################### !###################################################################### @@ -979,6 +979,7 @@ subroutine don_d_integ_cu_ensemble_miz & endif pmelt_lsm = 2.0e05 + if( temp_c(1) > Param%KELVIN ) then do k=1,nlev_lsm-1 if ((temp_c(k) >= Param%KELVIN) .and. & (temp_c(k+1) <= Param%KELVIN)) then @@ -986,6 +987,7 @@ subroutine don_d_integ_cu_ensemble_miz & exit endif end do + endif if (debug_ijt) then write (diag_unit, '(a, 2f19.10)') & @@ -3755,12 +3757,12 @@ subroutine don_m_meso_updraft_miz & do_donner_tracer = .false. endif !miz -!!$ do i=1,nlev_hires -!!$ if (p_hires(i) < pt_ens) then -!!$ ncc = i -!!$ exit -!!$ endif -!!$ end do + do k=1,nlev_hires + if (p_hires(k) < pt_ens) then + ncc = k + exit + endif + end do !!$ do i=1,nlev_hires !!$ if (p_hires(i) < pztm) then !!$ ncztm = i + 1 diff --git a/src/atmos_param/donner_deep/fms_donner.F90 b/src/atmos_param/donner_deep/fms_donner.F90 index 75873c4c73..535e2f8c87 100644 --- a/src/atmos_param/donner_deep/fms_donner.F90 +++ b/src/atmos_param/donner_deep/fms_donner.F90 @@ -65,8 +65,8 @@ module fms_donner_mod !----------- ****** VERSION NUMBER ******* --------------------------- -character(len=128) :: version = '$Id: fms_donner.F90,v 19.0 2012/01/06 20:08:38 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: fms_donner.F90,v 20.0 2013/12/13 23:17:30 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !-------------------------------------------------------------------- @@ -1100,8 +1100,8 @@ subroutine register_fields (Time, axes, Don_save, Nml, & if (Nml%do_budget_analysis) then allocate (id_water_budget (n_water_budget)) allocate (id_ci_water_budget (n_water_budget)) - allocate (id_enthalpy_budget (n_water_budget)) - allocate (id_ci_enthalpy_budget (n_water_budget)) + allocate (id_enthalpy_budget (n_enthalpy_budget)) + allocate (id_ci_enthalpy_budget (n_enthalpy_budget)) allocate (id_precip_budget (n_precip_paths, n_precip_types)) allocate (id_ci_precip_budget (n_precip_paths, n_precip_types)) id_water_budget(1) = register_diag_field & diff --git a/src/atmos_param/donner_deep/nonfms_donner.F90 b/src/atmos_param/donner_deep/nonfms_donner.F90 index 0bfd587876..ec66790e12 100644 --- a/src/atmos_param/donner_deep/nonfms_donner.F90 +++ b/src/atmos_param/donner_deep/nonfms_donner.F90 @@ -29,7 +29,7 @@ module nonfms_donner_mod character(len=128) :: version = '$Id: nonfms_donner.F90,v 19.0 2012/01/06 20:08:40 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !-------------------------------------------------------------------- diff --git a/src/atmos_param/donner_deep/null/donner_deep.F90 b/src/atmos_param/donner_deep/null/donner_deep.F90 deleted file mode 100644 index 640178a00d..0000000000 --- a/src/atmos_param/donner_deep/null/donner_deep.F90 +++ /dev/null @@ -1,179 +0,0 @@ - module donner_deep_mod - -use time_manager_mod, only: time_type - -use fms_mod, only: error_mesg, FATAL, WARNING - -implicit none -private - -character(len=128) :: version = '$Id: donner_deep.F90,v 19.0 2012/01/06 20:09:14 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - -public :: donner_deep_init, donner_deep, donner_deep_end, & - donner_deep_restart, donner_deep_time_vary, donner_deep_endts - - contains - -!##################################################################### -subroutine donner_deep_init (lonb, latb, pref, axes, secs, days, & - tracers_in_donner, do_conservation_checks,& - using_unified_closure, using_fms_code) -real, dimension(:,:), intent(in) :: lonb, latb -real, dimension(:), intent(in) :: pref -integer, dimension(4), intent(in) :: axes -integer, intent(in) :: secs, days -logical, dimension(:), intent(in) :: tracers_in_donner -logical, intent(in) :: do_conservation_checks -logical, intent(in) :: using_unified_closure -logical, intent(in), optional :: & - using_fms_code - -call error_mesg('donner_deep_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine donner_deep_init - -!################################################################### - -subroutine donner_deep (is, ie, js, je, dt, temp, mixing_ratio, pfull, & - phalf, zfull, zhalf, omega, pblht, tkemiz, & - qstar, cush, coldT, land, sfc_sh_flux, & - sfc_vapor_flux, tr_flux, tracers, secs, days, & - cbmf, cell_cld_frac, & - cell_liq_amt, cell_liq_size, cell_ice_amt, & - cell_ice_size, cell_droplet_number, & - meso_cld_frac, meso_liq_amt, & - meso_liq_size, meso_ice_amt, meso_ice_size, & - meso_droplet_number, & - nsum, precip, delta_temp, delta_vapor, detf, & - uceml_inter, mtot, mfluxup, mhalf_3d,& - donner_humidity_area, & - donner_humidity_factor, qtrtnd, donner_wetdep,& - lheat_precip, vert_motion, & - total_precip, liquid_precip, frozen_precip, & - frz_meso, liq_meso, frz_cell, liq_cell, & - qlin, qiin, qain, & ! optional - delta_ql, delta_qi, delta_qa) ! optional - -!------------------------------------------------------------------- -! donner_deep is the prognostic driver subroutine of donner_deep_mod. -! it takes as input the temperature (temp), vapor mixing ratio -! (mixing_ratio), pressure at full and half-levels (pfull, phalf), -! vertical velocity at full levels (omega), the large scale cloud -! variables (qlin, qiin, qain), the land fraction (land), the heat -! (sfc_sh_flux) , moisture (sfc_vapor_flux) and tracer (tr_flux) -! fluxes across the surface that are to be seen by this parameter- -! ization, the tracers to be transported by the donner convection -! parameterization (tracers), and the current time (as time_type -! variable Time). the routine returns the precipitation (precip), -! increments to the temperature (delta_temp) and mixing ratio -! (delta_vapor), the detrained mass flux (detf), upward cell mass -! flux at interface levels (uceml_inter) and total mass flux at full -! levels (mtot), two arrays needed to connect the donner convection -! and strat cloud parameterizations (donner_humidity_area, -! donner_humidity_ratio), increments to the cloudwater (delta_ql), -! cloudice (delta_qi) and cloud area (delta_qa) fields and tendencies -! for those tracers that are to be transported by the donner convect- -! ion parameterization (qtrtnd). there are an additional eleven arrays -! defining the donner scheme cloud characteristics needed by the rad- -! iation package, which are passed in and updated on donner calcul- -! ation steps. -!------------------------------------------------------------------- - -!-------------------------------------------------------------------- -integer, intent(in) :: is, ie, js, je -real, intent(in) :: dt -real, dimension(:,:,:), intent(in) :: temp, mixing_ratio, & - pfull, phalf, zfull, zhalf, omega -real, dimension(:,:), intent(in) :: pblht, tkemiz, qstar,cush -real, dimension(:,:), intent(in) :: land -logical, dimension(:,:), intent(in) :: coldT -real, dimension(:,:), intent(in) :: sfc_sh_flux, & - sfc_vapor_flux -real, dimension(:,:,:), intent(in) :: tr_flux -real, dimension(:,:,:,:), intent(in) :: tracers -integer, intent(in) :: secs, days -real, dimension(:,:), intent(inout) :: cbmf -real, dimension(:,:,:), intent(inout) :: cell_cld_frac, & - cell_liq_amt, & - cell_liq_size, & - cell_ice_amt, & - cell_ice_size, & - cell_droplet_number, & - meso_cld_frac, & - meso_liq_amt, & - meso_liq_size, & - meso_ice_amt, & - meso_ice_size, & - meso_droplet_number -integer, dimension(:,:), intent(inout) :: nsum -real, dimension(:,:), intent(out) :: precip, & - lheat_precip, & - vert_motion, & - total_precip -real, dimension(:,:,:), intent(out) :: delta_temp, delta_vapor,& - detf, uceml_inter, & - mtot, mfluxup, & - mhalf_3d, & - donner_humidity_area,& - donner_humidity_factor, & - liquid_precip, & - frozen_precip, frz_meso,& - liq_meso, frz_cell, liq_cell -real, dimension(:,:,:,:), intent(out) :: qtrtnd -real, dimension(:,:,:), intent(out) :: donner_wetdep -real, dimension(:,:,:), intent(in), & - optional :: qlin, qiin, qain -real, dimension(:,:,:), intent(out), & - optional :: delta_ql, delta_qi, & - delta_qa - - -call error_mesg('donner_deep', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine donner_deep - -!#################################################################### - -subroutine donner_deep_end - -call error_mesg('donner_deep', & - 'This module is not supported as part of the public release', WARNING) - -end subroutine donner_deep_end - -!###################################################################### - -!####################################################################### -!-! -! NAME="donner_deep_restart" - -!###################################################################### -subroutine donner_deep_time_vary (dt) - -real, intent(in) :: dt - -end subroutine donner_deep_time_vary - -!###################################################################### -subroutine donner_deep_endts - -end subroutine donner_deep_endts - -end module donner_deep_mod - diff --git a/src/atmos_param/donner_deep/wet_deposition_0D.F90 b/src/atmos_param/donner_deep/wet_deposition_0D.F90 index 9e7a55b71f..4d696cf717 100644 --- a/src/atmos_param/donner_deep/wet_deposition_0D.F90 +++ b/src/atmos_param/donner_deep/wet_deposition_0D.F90 @@ -1,6 +1,6 @@ !VERSION NUMBER: -! $Name: siena_201207 $ +! $Name: tikal $ ! $Id: wet_deposition_0D.F90,v 19.0 2012/01/06 20:09:12 fms Exp $ !-! Dummy interface. -! Arguments: -! timestamp (optional, intent(in)) : A character string that represents the model time, -! used for writing restart. timestamp will append to -! the any restart file name as a prefix. -! -! -subroutine donner_deep_restart(timestamp) - character(len=*), intent(in), optional :: timestamp - -end subroutine donner_deep_restart -!diff --git a/src/atmos_param/dry_adj/dry_adj.F90 b/src/atmos_param/dry_adj/dry_adj.F90 index c6dc902c5e..a723c5ee2c 100644 --- a/src/atmos_param/dry_adj/dry_adj.F90 +++ b/src/atmos_param/dry_adj/dry_adj.F90 @@ -19,7 +19,7 @@ MODULE DRY_ADJ_MOD !--------------------------------------------------------------------- character(len=128) :: version = '$Id: dry_adj.F90,v 19.0 2012/01/06 20:09:16 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !--------------------------------------------------------------------- diff --git a/src/atmos_param/dry_adj/null/dry_adj.F90 b/src/atmos_param/dry_adj/null/dry_adj.F90 deleted file mode 100644 index 4980d977ee..0000000000 --- a/src/atmos_param/dry_adj/null/dry_adj.F90 +++ /dev/null @@ -1,127 +0,0 @@ - MODULE DRY_ADJ_MOD - -!======================================================================= -! DRY ADIABATIC ADJUSTMENT -!======================================================================= - - use fms_Mod, ONLY: FILE_EXIST, ERROR_MESG, OPEN_NAMELIST_FILE, & - CHECK_NML_ERROR, write_version_number, stdlog, & - mpp_pe, mpp_root_pe, FATAL, WARNING, CLOSE_FILE - use Constants_Mod, ONLY: Grav, Kappa -!--------------------------------------------------------------------- - implicit none - private - - public :: dry_adj, dry_adj_init, dry_adj_end, dry_adj_bdgt - -!--------------------------------------------------------------------- - - character(len=128) :: version = '$Id: dry_adj.F90,v 10.0 2003/10/24 22:00:29 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -!--------------------------------------------------------------------- - - contains - -!####################################################################### -!####################################################################### - - SUBROUTINE DRY_ADJ ( temp0, pres, pres_int, dtemp, mask ) - -!======================================================================= -! DRY ADIABATIC ADJUSTMENT -!======================================================================= -!--------------------------------------------------------------------- -! Arguments (Intent in) -! temp0 - Temperature -! pres - Pressure -! pres_int - Pressure at layer interface -! mask - OPTIONAL; floating point mask (0. or 1.) designating -! where data is present -!--------------------------------------------------------------------- - real, intent(in), dimension(:,:,:) :: temp0, pres, pres_int - - real, intent(in), OPTIONAL, dimension(:,:,:) :: mask - -!--------------------------------------------------------------------- -! Arguments (Intent out) -! dtemp - Change in temperature -!--------------------------------------------------------------------- - real, intent(out), dimension(:,:,:) :: dtemp - -!--------------------------------------------------------------------- - - call error_mesg('DRY_ADJ', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE DRY_ADJ - -!##################################################################### -!##################################################################### - - SUBROUTINE DRY_ADJ_INIT() - -!--------------------------------------------------------------------- -! --- WRITE NAMELIST -!--------------------------------------------------------------------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - -!------------------------------------------------------------------- - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('DRY_ADJ_INIT', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE DRY_ADJ_INIT - - -!####################################################################### -!####################################################################### - SUBROUTINE DRY_ADJ_END - -!------------------------------------------------------------------- - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('DRY_ADJ_END', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE DRY_ADJ_END - - -!####################################################################### -!####################################################################### - - SUBROUTINE DRY_ADJ_BDGT ( dtemp, pres_int ) - -!======================================================================= -! Budget check for dry adiabatic adjustment - a debugging tool -!======================================================================= - -!--------------------------------------------------------------------- -! Arguments (Intent in) -! dtemp - Temperature change -! pres_int - Pressure at layer interface -!--------------------------------------------------------------------- - real, intent(in), dimension(:,:,:) :: dtemp, pres_int - -!--------------------------------------------------------------------- - - call error_mesg('DRY_ADJ_BDGT', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE DRY_ADJ_BDGT - -!####################################################################### -!####################################################################### - end MODULE DRY_ADJ_MOD diff --git a/src/atmos_param/edt/edt.F90 b/src/atmos_param/edt/edt.F90 index cb58b2afd0..c1b0624b30 100644 --- a/src/atmos_param/edt/edt.F90 +++ b/src/atmos_param/edt/edt.F90 @@ -263,7 +263,7 @@ module edt_mod ! character(len=128) :: Version = '$Id: edt.F90,v 19.0 2012/01/06 20:09:18 fms Exp $' -character(len=128) :: Tagname = '$Name: siena_201207 $' +character(len=128) :: Tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- ! diff --git a/src/atmos_param/edt/null/edt.F90 b/src/atmos_param/edt/null/edt.F90 deleted file mode 100644 index d8e34abaf9..0000000000 --- a/src/atmos_param/edt/null/edt.F90 +++ /dev/null @@ -1,291 +0,0 @@ -module edt_mod - -!======================================================================= -! -! -! -! EDT (Entrainment and Diagnostic Turbulence) MODULE -! -! -! February 2002 -! Contact person: Steve Klein -! -! -! These routines calculate the diffusivity coefficients for -! momentum and temperature-moisture-scalars using the moist -! thermodynamcs modules based on: -! -! H. Grenier and C. Bretherton, 2001: A moist PBL parameterization -! for large-scale models and its application to subtropical -! cloud-topped marine boundary layers. Mon. Wea. Rev., 129, -! 357-377. -! -! The actual routine is not described in this paper but is -! a simplified extension of the parameterization discussed -! here. The original code, given to Steve Klein from -! Chris Bretherton in May 2001, was tested in the NCAR -! atmospheric model, formerly known as CCM. The code has -! been adapted for the FMS system by Steve Klein and Paul -! Kushner. -! -! -! To quote the Bretherton and Grenier description: -! -! Driver routine to compute eddy diffusion coefficients for -! momentum, moisture, trace constituents and static energy. Uses -! first order closure for stable turbulent layers. For convective -! layers, an entrainment closure is used, coupled to a diagnosis -! of layer-average TKE from the instantaneous thermodynamic and -! velocity profiles. Convective layers are diagnosed by extending -! layers of moist static instability into adjacent weakly stably -! stratified interfaces, stopping if the stability is too strong. -! This allows a realistic depiction of dry convective boundary -! layers with a downgradient approach." -! -! Authors: Herve Grenier, 06/2000, Chris Bretherton 09/2000 -! -!----------------------------------------------------------------------- -! -!----------------------------------------------------------------------- -! -! outside modules used -! - -use constants_mod, only: grav,vonkarm,cp_air,rdgas,rvgas,hlv,hls, & - tfreeze,radian - -use fms_mod, only: file_exist, open_namelist_file, error_mesg, FATAL,& - NOTE, mpp_pe, mpp_root_pe, close_file, & - write_version_number, stdlog - -use diag_manager_mod, only: register_diag_field, send_data - -use time_manager_mod, only: time_type, get_date, month_name - -use monin_obukhov_mod, only: mo_diff - -use sat_vapor_pres_mod, only: lookup_es, lookup_des - -implicit none -private - -!----------------------------------------------------------------------- -! -! public interfaces - -public edt, edt_init, edt_end, edt_on, qaturb, qcturb,tblyrtau - -!----------------------------------------------------------------------- -! -! declare version number -! - -character(len=128) :: Version = '$Id: edt.F90,v 17.0 2009/07/21 02:55:02 fms Exp $' -character(len=128) :: Tagname = '$Name: siena_201207 $' -logical :: module_is_initialized = .false. -logical :: edt_on = .false. - -!----------------------------------------------------------------------- -! -! global storage variable -! - -real, allocatable, dimension(:,:,:) :: qaturb ! cloud fraction diagnosed - ! from turbulence model - ! (fraction) -real, allocatable, dimension(:,:,:) :: qcturb ! cloud condensate - ! diagnosed from turb. - ! model (kg liq/kg air) -real, allocatable, dimension(:,:,:) :: tblyrtau ! turbulent layer - ! time scale - - -contains - -!======================================================================= -! -! subroutine edt_init -! -! -! this subroutine reads the namelist file and restart data -! and initializes some constants. -! - -subroutine edt_init(lonb, latb, axes,time,idim,jdim,kdim) - -!----------------------------------------------------------------------- -! -! variables -! -! ----- -! input -! ----- -! -! idim,jdim,kdim size of the first 3 dimensions -! axes, time variables needed for netcdf diagnostics -! latb, lonb latitudes and longitudes at grid box boundaries -! -! -! -------- -! internal -! -------- -! -! unit unit number for namelist and restart file -! io internal variable for reading of namelist file -! full indices for full level axes coordinates -! half indices for half level axes coordinates -! -!----------------------------------------------------------------------- - -integer, intent(in) :: idim,jdim,kdim,axes(4) -type(time_type), intent(in) :: time -real, dimension(:,:),intent(in) :: lonb, latb - - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - -!----------------------------------------------------------------------- -! -! initialize edt_on - - module_is_initialized = .true. -end subroutine edt_init - -! -!======================================================================= - - - - -!======================================================================= -! -! subroutine edt -! -! -! this subroutine is the main driver program to the routines -! provided by Chris Bretherton -! - -subroutine edt(is,ie,js,je,dt,time,tdtlw_in, u_star,b_star,q_star,t,qv,ql,qi,qa, & - u,v,z_full,p_full,z_half,p_half,stbltop,k_m,k_t,pblh, & - kbot,tke) - -!----------------------------------------------------------------------- -! -! variables -! -! ----- -! input -! ----- -! -! is,ie,js,je i,j indices marking the slab of model working on -! dt physics time step (seconds) -! time variable needed for netcdf diagnostics -! u_star friction velocity (m/s) -! b_star buoyancy scale (m/(s**2)) -! q_star moisture scale (kg vapor/kg air) -! -! three dimensional fields on model full levels, reals dimensioned -! (:,:,pressure), third index running from top of atmosphere to -! bottom -! -! t temperature (K) -! qv water vapor specific humidity (kg vapor/kg air) -! ql liquid water specific humidity (kg cond/kg air) -! qi ice water specific humidity (kg cond/kg air) -! qa cloud fraction -! u zonal wind (m/s) -! v meridional wind (m/s) -! z_full height of full levels (m) -! p_full pressure (Pa) -! -! the following two fields are on the model half levels, with -! size(z_half,3) = size(t,3) +1, z_half(:,:,size(z_half,3)) -! must be height of surface (if you are not using eta-model) -! -! z_half height at half levels (m) -! p_half pressure at half levels (Pa) -! -! ------ -! output -! ------ -! -! stbltop maximum altitude the very stable boundary layer -! is permitted to operate -! -! The following variables are defined at half levels and are -! dimensions 1:nlev+1. -! -! k_m diffusivity for momentum (m**2/s) -! k_t diffusivity for temperature and scalars (m**2/s) -! -! k_m and k_t are defined at half-levels so that size(k_m,3) -! should be at least as large as size(t,3). Note, however, that -! only the returned values at levels 2 to size(t,3) are -! meaningful; other values will be returned as zero. -! -! -------------- -! optional input -! -------------- -! -! kbot integer indicating the lowest true layer of atmosphere -! -! --------------- -! optional output -! --------------- -! -! pblh depth of planetary boundary layer (m) -! tke turbulent kinetic energy (m*m)/(s*s) -! -!----------------------------------------------------------------------- - -integer, intent(in) :: is,ie,js,je -real, intent(in) :: dt -type(time_type), intent(in) :: time -real, intent(in), dimension(:,:,:) :: tdtlw_in -real, intent(in), dimension(:,:) :: u_star,b_star -real, intent(in), dimension(:,:) :: q_star -real, intent(in), dimension(:,:,:) :: t,qv,ql,qi,qa -real, intent(in), dimension(:,:,:) :: u, v -real, intent(in), dimension(:,:,:) :: z_full, p_full -real, intent(in), dimension(:,:,:) :: z_half, p_half -real, intent(out), dimension(:,:) :: stbltop -real, intent(out), dimension(:,:,:) :: k_m,k_t -integer, intent(in), dimension(:,:), optional :: kbot -!real, intent(out), dimension(:,:), optional :: pblh -real, intent(out), dimension(:,:) :: pblh -real, intent(out), dimension(:,:,:),optional:: tke - -end subroutine edt - -! -!======================================================================= - -!======================================================================= -! -! subroutine edt_end -! -! -! this subroutine writes out the restart field -! - -subroutine edt_end() - -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- -! -! subroutine end -! - module_is_initialized = .false. - -end subroutine edt_end - -! -!======================================================================= - -end module edt_mod diff --git a/src/atmos_param/entrain/entrain.F90 b/src/atmos_param/entrain/entrain.F90 index e462c6834b..ff0f0780e1 100644 --- a/src/atmos_param/entrain/entrain.F90 +++ b/src/atmos_param/entrain/entrain.F90 @@ -247,7 +247,7 @@ module entrain_mod ! character(len=128) :: Version = '$Id: entrain.F90,v 19.0 2012/01/06 20:09:20 fms Exp $' -character(len=128) :: Tagname = '$Name: siena_201207 $' +character(len=128) :: Tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- ! diff --git a/src/atmos_param/fsrad/co2_data.F90 b/src/atmos_param/fsrad/co2_data.F90 index cc6d7b9840..8292311730 100644 --- a/src/atmos_param/fsrad/co2_data.F90 +++ b/src/atmos_param/fsrad/co2_data.F90 @@ -115,7 +115,7 @@ Module CO2_Data_Mod !------------ VERSION NUMBER ---------------- character(len=128) :: version = '$Id: co2_data.F90,v 13.0 2006/03/28 21:09:22 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/fsrad/co2int.F90 b/src/atmos_param/fsrad/co2int.F90 index f5f97fef52..0704dfaa24 100644 --- a/src/atmos_param/fsrad/co2int.F90 +++ b/src/atmos_param/fsrad/co2int.F90 @@ -268,7 +268,7 @@ Module co2int_mod !------------ VERSION NUMBER ---------------- character(len=128) :: version = '$Id: co2int.F90,v 13.0 2006/03/28 21:09:25 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/fsrad/fs_profile.F90 b/src/atmos_param/fsrad/fs_profile.F90 index b8251f3a5f..da4b854e2f 100644 --- a/src/atmos_param/fsrad/fs_profile.F90 +++ b/src/atmos_param/fsrad/fs_profile.F90 @@ -37,7 +37,7 @@ module fs_profile_mod !------------ VERSION NUMBER ---------------- character(len=128) :: version = '$Id: fs_profile.F90,v 10.0 2003/10/24 22:00:30 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_param/fsrad/fsrad.F90 b/src/atmos_param/fsrad/fsrad.F90 index d7a5df8a8b..dcd7a77bbc 100644 --- a/src/atmos_param/fsrad/fsrad.F90 +++ b/src/atmos_param/fsrad/fsrad.F90 @@ -23,7 +23,7 @@ Module FSrad_Mod !----------------------------------------------------------------------- character(len=128) :: version = '$Id: fsrad.F90,v 14.0 2007/03/15 22:03:19 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. real, parameter :: Day_Length=86400. diff --git a/src/atmos_param/fsrad/longwave.F90 b/src/atmos_param/fsrad/longwave.F90 index da0e2467da..1a02f5db37 100644 --- a/src/atmos_param/fsrad/longwave.F90 +++ b/src/atmos_param/fsrad/longwave.F90 @@ -763,7 +763,7 @@ MODULE LONGWAVE_MOD !------------ VERSION NUMBER ---------------- character(len=128) :: version = '$Id: longwave.F90,v 13.0 2006/03/28 21:09:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/fsrad/mcm_lw.F90 b/src/atmos_param/fsrad/mcm_lw.F90 index 65abbb40e2..7eafbafc60 100644 --- a/src/atmos_param/fsrad/mcm_lw.F90 +++ b/src/atmos_param/fsrad/mcm_lw.F90 @@ -20,7 +20,7 @@ module mcm_lw_mod !------------ VERSION NUMBER ---------------- character(len=128) :: version = '$Id: mcm_lw.F90,v 13.0 2006/03/28 21:09:36 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. public :: MCM_LW_RAD, mcm_lw_init, mcm_lw_end diff --git a/src/atmos_param/fsrad/mcm_sw_driver.F90 b/src/atmos_param/fsrad/mcm_sw_driver.F90 index ce56372958..154722568a 100644 --- a/src/atmos_param/fsrad/mcm_sw_driver.F90 +++ b/src/atmos_param/fsrad/mcm_sw_driver.F90 @@ -27,7 +27,7 @@ MODULE MCM_SW_DRIVER_MOD integer :: kx, kp character(len=128) :: version = '$Id: mcm_sw_driver.F90,v 10.0 2003/10/24 22:00:31 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. public :: mcm_shortwave_driver, mcm_sw_driver_init, & diff --git a/src/atmos_param/fsrad/mcm_swnew.F90 b/src/atmos_param/fsrad/mcm_swnew.F90 index d8c9af128a..74959302eb 100644 --- a/src/atmos_param/fsrad/mcm_swnew.F90 +++ b/src/atmos_param/fsrad/mcm_swnew.F90 @@ -8,7 +8,7 @@ module mcm_swnew_mod private character(len=128) :: version = '$Id: mcm_swnew.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. public mcm_swnew, mcm_swnew_init, mcm_swnew_end diff --git a/src/atmos_param/fsrad/null/co2_data.F90 b/src/atmos_param/fsrad/null/co2_data.F90 deleted file mode 100644 index 57d47203d3..0000000000 --- a/src/atmos_param/fsrad/null/co2_data.F90 +++ /dev/null @@ -1,217 +0,0 @@ - - Module CO2_Data_Mod - -!----------------------------------------------------------------------- - - use fs_profile_mod, ONLY: fs_profile - Use co2int_mod, ONLY: co2int, TRNS - Use fms_mod, ONLY: open_namelist_file, mpp_pe, & - Error_Mesg, FATAL, close_file, & - write_version_number, mpp_root_pe - -implicit none -private - -! Private -!----------------------------------------------------------------------- -! -! Pretabulated co2 transmission functions, evaluated using the -! methods of Fels and Schwarzkopf (1981) and Schwarzkopf and -! Fels (1985). -! -!----------------------------------------------------------------------- -! -! co2 transmission functions and temperature and pressure -! derivatives for the 560-800 cm-1 band. also included are the -! standard temperatures and the weighting function. -! This data was formerly in COMMON /CO2BD3/. -! -! CO251 = TRANSMISSION FCTNS FOR T0 (STD. PROFILE) -! WITH P(SFC)=1013.25 MB -! CO258 = TRANSMISSION FCTNS. FOR T0 (STD. PROFILE) -! WITH P(SFC)= ^810 MB -! CDT51 = FIRST TEMPERATURE DERIVATIVE OF CO251 -! CDT58 = FIRST TEMPERATURE DERIVATIVE OF CO258 -! C2D51 = SECOND TEMPERATURE DERIVATIVE OF CO251 -! C2D58 = SECOND TEMPERATURE DERIVATIVE OF CO251 -! CO2M51 = TRANSMISSION FCTNS FOR T0 FOR ADJACENT PRESSURE -! LEVELS, WITH NO PRESSURE QUADRATURE. USED FOR -! NEARBY LAYER COMPUTATIONS. P(SFC)=1013.25 MB -! CO2M58 = SAME AS CO2M51,WITH P(SFC)= ^810 MB -! CDTM51 = FIRST TEMPERATURE DERIVATIVE OF CO2M51 -! CDTM58 = FIRST TEMPERATURE DERIVATIVE OF CO2M58 -! C2DM51 = SECOND TEMPERATURE DERIVATIVE OF CO2M51 -! C2DM58 = SECOND TEMPERATURE DERIVATIVE OF CO2M58 -! STEMP = STANDARD TEMPERATURES FOR MODEL PRESSURE LEVEL -! STRUCTURE WITH P(SFC)=1013.25 MB -! GTEMP = WEIGHTING FUNCTION FOR MODEL PRESSURE LEVEL -! STRUCTURE WITH P(SFC)=1013.25 MB. -! B0 = TEMP. COEFFICIENT USED FOR CO2 TRANS. FCTN. -! CORRECTION FOR T(K). (SEE REF. 4 AND BD3) -! B1 = TEMP. COEFFICIENT, USED ALONG WITH B0 -! B2 = TEMP. COEFFICIENT, USED ALONG WITH B0 -! B3 = TEMP. COEFFICIENT, USED ALONG WITH B0 - - Real, Allocatable, Dimension(:,:) :: CO251,CO258,CDT51,CDT58 - Real, Allocatable, Dimension(:,:) :: C2D51,C2D58 - Real, Allocatable, Dimension(:) :: CO2M51,CO2M58,CDTM51,CDTM58 - Real, Allocatable, Dimension(:) :: C2DM51,C2DM58 - Real, Allocatable, Dimension(:) :: STEMP,GTEMP - Real :: B0,B1,B2,B3 - -!----------------------------------------------------------------------- -! -! co2 transmission functions and temperature and pressure -! derivatives for the 560-670 cm-1 part of the 15 um co2 band. -! This data was formerly in COMMON /CO2BD2/. -! -! CO231 = TRANSMISSION FCTNS FOR T0 (STD. PROFILE) -! WITH P(SFC)=1013.25 MB -! CO238 = TRANSMISSION FCTNS. FOR T0 (STD. PROFILE) -! WITH P(SFC)= ^810 MB -! CDT31 = FIRST TEMPERATURE DERIVATIVE OF CO231 -! CDT38 = FIRST TEMPERATURE DERIVATIVE OF CO238 -! C2D31 = SECOND TEMPERATURE DERIVATIVE OF CO231 -! C2D38 = SECOND TEMPERATURE DERIVATIVE OF CO231 - - Real, Allocatable, Dimension(:) :: CO231,CO238,CDT31,CDT38 - Real, Allocatable, Dimension(:) :: C2D31,C2D38 - -!----------------------------------------------------------------------- -! -! co2 transmission functions and temperature and pressure -! derivatives for the 670-800 part of the 15 um co2 band. -! This data was formerly in COMMON /CO2BD4/. -! -! CO271 = TRANSMISSION FCTNS FOR T0 (STD. PROFILE) -! WITH P(SFC)=1013.25 MB -! CO278 = TRANSMISSION FCTNS. FOR T0 (STD. PROFILE) -! WITH P(SFC)= ^810 MB -! CDT71 = FIRST TEMPERATURE DERIVATIVE OF CO271 -! CDT78 = FIRST TEMPERATURE DERIVATIVE OF CO278 -! C2D71 = SECOND TEMPERATURE DERIVATIVE OF CO271 -! C2D78 = SECOND TEMPERATURE DERIVATIVE OF CO271 - - Real, Allocatable, Dimension(:) :: CO271,CO278,CDT71,CDT78 - Real, Allocatable, Dimension(:) :: C2D71,C2D78 - -!----------------------------------------------------------------------- -! -! co2 transmission functions for the 2270-2380 part of the -! 4.3 um co2 band. THis data was formerly in COMMON /CO2BD5/. -! -! CO211 = TRANSMISSION FCTNS FOR T0 (STD. PROFILE) -! WITH P(SFC)=1013.25 MB -! CO218 = TRANSMISSION FCTNS. FOR T0 (STD. PROFILE) -! WITH P(SFC)= ^810 MB - - Real, Allocatable, Dimension(:) :: CO211,CO218 - - -!----------------------------------------------------------------------- -!------------ VERSION NUMBER ---------------- - - character(len=128) :: version = '$Id: co2_data.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. -!----------------------------------------------------------------------- - - Public CO2_Data, Write_CO2_Data, Read_CO2_Data, & - co2_data_init, co2_data_end - - Public CO251, CO258, CDT51, CDT58, C2D51, C2D58, & - CO2M51, CO2M58, CDTM51, CDTM58, C2DM51, C2DM58, & - STEMP, GTEMP, B0, B1, B2, B3, & - CO231, CO238, CDT31, CDT38, C2D31, C2D38, & - CO271, CO278, CDT71, CDT78, C2D71, C2D78, & - CO211, CO218 - - CONTAINS - -!####################################################################### - - Subroutine CO2_Data (co2std, ratio, Pref) - - Implicit None -!----------------------------------------------------------------------- - Real, Intent(IN) :: co2std, ratio - Real, Intent(IN) :: Pref(:,:) -!----------------------------------------------------------------------- -! CO2STD = standard co2 vol. mixing ratio (either 300 or 330 ppmv) -! RATIO = co2 vol. mixing ratio in units of the standard vol. -! mixing ratio (must lie between 0.5 and 4.0) -! PREF = reference pressure levels -!----------------------------------------------------------------------- - - call error_mesg('CO2_Data', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine CO2_Data - -!####################################################################### - - Subroutine Write_CO2_Data - - -!--------------------------------------------------------------------- - - call error_mesg('Write_CO2_Data', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine Write_CO2_Data - -!####################################################################### - - Subroutine Read_CO2_Data (nlev) - - Implicit None -!----------------------------------------------------------------------- -! Reads co2 transmission functions from file = INPUT/CO2.data -!----------------------------------------------------------------------- - Integer, Intent(IN) :: nlev - - -!--------------------------------------------------------------------- - - call error_mesg('Read_CO2_Data', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine Read_CO2_Data - -!####################################################################### - - Subroutine co2_data_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('co2_data_init', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine co2_data_init - -!####################################################################### - - Subroutine co2_data_end - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('co2_data_end', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine co2_data_end - -!####################################################################### - - - - End Module CO2_Data_Mod - diff --git a/src/atmos_param/fsrad/null/co2int.F90 b/src/atmos_param/fsrad/null/co2int.F90 deleted file mode 100644 index 7c82d96bb2..0000000000 --- a/src/atmos_param/fsrad/null/co2int.F90 +++ /dev/null @@ -1,211 +0,0 @@ - - Module co2int_mod - -!----------------------------------------------------------------------- -! -! CO2INT INTERPOLATES CARBON DIOXIDE TRANSMISSION FUNCTIONS -! FROM THE 109 LEVEL GRID,FOR WHICH THE TRANSMISSION FUNCTIONS -! HAVE BEEN PRE-CALCULATED, TO THE GRID STRUCTURE SPECIFIED BY THE -! USER. -! -! METHOD: -! -! CO2INT IS EMPLOYABLE FOR TWO PURPOSES: 1) TO OBTAIN TRANSMIS- -! SIVITIES BETWEEN ANY 2 OF AN ARRAY OF USER-DEFINED PRESSURES; AND -! 2) TO OBTAIN LAYER-MEAN TRANSMISSIVITIES BETWEEN ANY 2 OF AN ARRAY -! OF USER-DEFINED PRESSURE LAYERS.TO CLARIFY THESE TWO PURPOSES,SEE -! THE DIAGRAM AND DISCUSSION BELOW. -! CO2INT MAY BE USED TO EXECUTE ONLY ONE PURPOSE AT ONE TIME. -! -! LET P BE AN ARRAY OF USER-DEFINED PRESSURES -! AND PD BE USER-DEFINED PRESSURE LAYERS. -! -! - - - - - - - - - PD(I-1) --- -! ! -! ----------------- P(I) ! PRESSURE LAYER I (PLM(I)) -! ! -! - - - - - - - - - PD(I) --- -! ! -! ----------------- P(I+1) ! PRESSURE LAYER I+1 (PLM(I+1)) -! ! -! - - - - - - - - - PD(I+1)--- -! ... (THE NOTATION USED IS -! ... CONSISTENT WITH THE CODE) -! ... -! - - - - - - - - - PD(J-1) -! -! ----------------- P(J) -! -! - - - - - - - - - PD(J) -! -! PURPOSE 1: THE TRANSMISSIVITY BETWEEN SPECIFIC PRESSURES -! P(I) AND P(J) ,TAU(P(I),P(J)) IS COMPUTED BY THIS PROGRAM. -! IN THIS MODE,THERE IS NO REFERENCE TO LAYER PRESSURES PD -! (PD,PLM ARE NOT INPUTTED). -! -! PURPOSE 2: THE LAYER-MEAN TRANSMISSIVITY BETWEEN A LAYER- -! MEAN PRESSURE PLM(J) AND PRESSURE LAYER I IS GIVEN BY -! TAULM(PLM(I),PLM(J)). IT IS COMPUTED BY THE INTEGRAL -! -! PD(I) -! ---- -! 1 ! -! ------------- * ! TAU ( P',PLM(J) ) DP' -! PD(I)-PD(I-1) ! -! ---- -! PD(I-1) -! -! THE LAYER-MEAN PRESSURE PLM(I) IS SPECIFIED BY THE USER. -! FOR MANY PURPOSES,PLM WILL BE CHOSEN TO BE THE AVERAGE -! PRESSURE IN THE LAYER-IE,PLM(I)=0.5*(PD(I-1)+PD(I)). -! FOR LAYER-MEAN TRANSMISSIVITIES,THE USER THUS INPUTS -! A PRESSURE ARRAY (PD) DEFINING THE PRESSURE LAYERS AND AN -! ARRAY (PLM) DEFINING THE LAYER-MEAN PRESSURES.THE CALCULATION -! DOES NOT DEPEND ON THE P ARRAY USED FOR PURPOSE 1 (P IS NOT -! INPUTTED). -! -! THE FOLLOWING PARAGRAPHS DEPICT THE UTILIZATION OF THIS -! CODE WHEN USED TO COMPUTE TRANSMISSIVITIES BETWEEN SPECIFIC -! PRESSURES. LATER PARAGRAPHS DESCRIBE ADDITIONAL FEATURES NEEDED -! FOR LAYER-MEAN TRANSMISSIVITIES. -! -! FOR A GIVEN CO2 MIXING RATIO AND STANDARD TEMPERATURE -! PROFILE,A TABLE OF TRANSMISSION FUNCTIONS FOR A FIXED GRID -! OF ATMOSPHERIC PRESSURES HAS BEEN PRE-CALCULATED. -! THE STANDARD TEMPERATURE PROFILE IS COMPUTED FROM THE US -! STANDARD ATMOSPHERE (1977) TABLE.ADDITIONALLY, THE -! SAME TRANSMISSION FUNCTIONS HAVE BEEN PRE-CALCULATED FOR A -! TEMPERATURE PROFILE INCREASED AND DECREASED (AT ALL LEVELS) -! BY 25 DEGREES. -! THIS PROGRAM READS IN THE PRESPECIFIED TRANSMISSION FUNCTIONS -! AND A USER-SUPPLIED PRESSURE GRID (P(I)) AND CALCULATES TRANS- -! MISSION FUNCTIONS ,TAU(P(I),P(J)), FOR ALL P(I)'S AND P(J)'S. -! A LOGARITHMIC INTERPOLATION SCHEME IS USED. -! THIS METHOD IS REPEATED FOR THE THREE TEMPERATURE PROFILES -! GIVEN ABOVE .THEREFORE OUTPUTS FROM THE PROGRAM ARE THREE TABLES -! OF TRANSMISSION FUNCTIONS FOR THE USER-SUPPLIED PRESSURE GRID. -! THE EXISTENCE OF THE THREE TABLES PERMITS SUBSEQUENT INTERPO- -! LATION TO A USER-SUPPLIED TEMPERATURE PROFILE USING THE METHOD -! DESCRIBED IN THE REFERENCE.SEE LIMITATIONS SECTION IF THE -! USER DESIRES TO OBTAIN ONLY 1 TABLE OF TRANSMISSIVITIES. -! -! MODIFICATIONS FOR LAYER-MEAN TRANSMISSIVITIES: -! THE PRESSURES INPUTTED ARE THE LAYER-MEAN PRESSURES,PD, -! AND THE LAYER-MEAN PRESSURES ,PLM. A SERIES OF TRANSMISSIVITIES -! (TAU(P',PLM(J)) ARE COMPUTED AND THE INTEGRAL GIVEN IN THE -! DISCUSSION OF PURPOSE 2 IS COMPUTED.FOR PLM(I) NOT EQUAL TO -! PLM(J) SIMPSON'S RULE IS USED WITH 5 POINTS. IF PLM(I)=PLM(J) -! (THE "NEARBY LAYER" CASE) A 49-POINT QUADRATURE IS USED FOR -! GREATER ACCURACY.THE OUTPUT IS IN TAULM(PLM(I),PLM(J)). -! NOTE: -! TAULM IS NOT A SYMMETRICAL MATRIX. FOR THE ARRAY ELEMENT -! TAULM(PLM(I),PLM(J)),THE INNER(FIRST,MOST RAPIDLY VARYING) -! DIMENSION IS THE VARYING LAYER-MEAN PRESSURE,PLM(I);THE OUTER -! (SECOND) DIMENSION IS THE FIXED LAYER-MEAN PRESSURE PLM(J). -! THUS THE ELEMENT TAULM(2,3) IS THE TRANSMISSION FUNCTION BETWEEN -! THE FIXED PRESSURE PLM(3) AND THE PRESSURE LAYER HAVING AN AVERAGE -! PRESSURE OF PLM(2). -! ALSO NOTE THAT NO QUADRATURE IS PERFORMED OVER THE LAYER -! BETWEEN THE SMALLEST NONZERO PRESSURE AND ZERO PRESSURE; -! TAULM IS TAULM(0,PLM(J)) IN THIS CASE,AND TAULM(0,0)=1. -! -! -! REFERENCE: -! S.B.FELS AND M.D.SCHWARZKOPF,"AN EFFICIENT,ACCURATE -! ALGORITHM FOR CALCULATING CO2 15 UM BAND COOLING RATES",JOURNAL -! OF GEOPHYSICAL RESEARCH,VOL.86,NO. C2, PP.1205-1232,1981. -! MODIFICATIONS TO THE ALGORITHM HAVE BEEN MADE BY THE AUTHORS; -! CONTACT S.B.F.OR M.D.S. FOR FURTHER DETAILS.A NOTE TO J.G.R. -! IS PLANNED TO DOCUMENT THESE CHANGES. -! -! AUTHOR: M.DANIEL SCHWARZKOPF -! -! DATE: 14 JULY 1983 -! -! ADDRESS: -! -! G.F.D.L. -! P.O.BOX 308 -! PRINCETON,N.J.08540 -! U.S.A. -! TELEPHONE: (609) 452-6521 -! -!----------------------------------------------------------------------- - - Use fs_profile_mod, ONLY: pd1013,plm1013,pd810,plm810 - Use fms_mod, ONLY: ERROR_MESG, FATAL, WARNING, & - mpp_pe, mpp_root_pe, write_version_number - -implicit none -private -! Integer,Parameter :: kind_type = selected_real_kind(15,307) - - Real, Allocatable, Dimension(:,:,:,:) :: TRNS - -!----------------------------------------------------------------------- - - Public co2int, co2int_init, co2int_end, TRNS - -!------------ VERSION NUMBER ---------------- - - character(len=128) :: version = '$Id: co2int.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. -!----------------------------------------------------------------------- - - CONTAINS - -!####################################################################### - - Subroutine co2int (nlev,ir,npurp,nkkk,unit1,unit2,ratio) - - Implicit None -!----------------------------------------------------------------------- -! -! ------------ FUNCTION INTERPOLATER ROUTINE ------------ -! -!----------------------------------------------------------------------- - Integer, Intent(IN) :: nlev,ir,npurp,nkkk,unit1,unit2 - Real, Intent(IN) :: ratio -!----------------------------------------------------------------------- - - call error_mesg('co2int', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine co2int - -!####################################################################### - - Subroutine co2int_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('co2int_init', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine co2int_init - -!####################################################################### - - Subroutine co2int_end - - module_is_initialized = .false. -!--------------------------------------------------------------------- - - call error_mesg('co2int_end', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine co2int_end - -!####################################################################### - - - End Module co2int_mod - diff --git a/src/atmos_param/fsrad/null/fs_profile.F90 b/src/atmos_param/fsrad/null/fs_profile.F90 deleted file mode 100644 index 00d53bc8e4..0000000000 --- a/src/atmos_param/fsrad/null/fs_profile.F90 +++ /dev/null @@ -1,93 +0,0 @@ - -module fs_profile_mod - -use fms_mod, only : mpp_pe, mpp_root_pe, write_version_number, & - error_mesg, FATAL - -implicit none -private - -!----------------------------------------------------------------------- -! ** THIS PROGRAM CALCULATES TEMPERATURES ,H2O MIXING RATIOS ** -! ** AND O3 MIXING RATIOS BY USING AN ANALYTICAL ** -! ** FUNCTION WHICH APPROXIMATES ** -! ** THE US STANDARD (1976). THIS IS ** -! ** CALCULATED IN FUNCTION 'ANTEMP', WHICH IS CALLED BY THE ** -! ** MAIN PROGRAM. THE FORM OF THE ANALYTICAL FUNCTION WAS ** -! ** SUGGESTED TO ME IN 1971 BY RICHARD S. LINDZEN. ** -! -!*****THIS VERSION IS ONLY USABLE FOR 1976 US STD ATM AND OBTAINS -! QUANTITIES FOR CO2 INTERPOLATION AND INSERTION INTO OPERA- -! TIONAL RADIATION CODES -! -! definitions: -! ----------- -! pd,pd8: pressures (mb) for data levels. pd is for the case where -! p(sfc)=1013.25 mb; pd8 applies when p(sfc)=810.6 mb. -! in either case, index (nlev+1) is at the sfc. -! press: same as pd, but with indices reversed,index 1 at the -! surface, and index (nlev+1) at the top (nonzero) data -! level. -!----------------------------------------------------------------------- - - Public fs_profile, fs_profile_init, fs_profile_end - - Real, Public, Allocatable, Dimension(:) :: pd1013,plm1013,pd810,plm810 - -!------------ VERSION NUMBER ---------------- - - character(len=128) :: version = '$Id: fs_profile.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -CONTAINS - -!####################################################################### - - subroutine fs_profile (Pref,stemp,gtemp) - -!----------------------------------------------------------------------- - Real, Intent(IN) , Dimension(:,:) :: Pref - Real, Intent(OUT), Dimension(:) :: stemp,gtemp -!----------------------------------------------------------------------- - - call error_mesg('fs_profile', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine fs_profile - -!####################################################################### - - Subroutine fs_profile_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('fs_profile_init', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine fs_profile_init - -!####################################################################### - - Subroutine fs_profile_end - - module_is_initialized = .false. -!--------------------------------------------------------------------- - - call error_mesg('fs_profile_end', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine fs_profile_end - -!####################################################################### - - -end module fs_profile_mod - diff --git a/src/atmos_param/fsrad/null/fsrad.F90 b/src/atmos_param/fsrad/null/fsrad.F90 deleted file mode 100644 index b11f7c05be..0000000000 --- a/src/atmos_param/fsrad/null/fsrad.F90 +++ /dev/null @@ -1,102 +0,0 @@ - - Module FSrad_Mod - -!----------------------------------------------------------------------- -!-------------------- PUBLIC Radiation routines ------------------------ - - Use MCM_LW_Mod, ONLY: MCM_LW_Rad - Use MCM_SW_Driver_Mod, ONLY: mcm_shortwave_driver - - Use ShortWave_Mod, ONLY: SWRad - Use LongWave_Mod, ONLY: LWRad, Rad_DeAlloc - Use RdParm_Mod, ONLY: RdParm_Init - Use Rad_Diag_Mod, ONLY: Radiag - Use CO2_Data_Mod, ONLY: CO2_Data - - Use Fms_Mod, ONLY: mpp_pe, mpp_root_pe, write_version_number, & - error_mesg, FATAL - Use Constants_Mod, ONLY: stefan - - implicit none - private - - public FSrad, RdParm_Init, CO2_Data, fsrad_init, fsrad_end -!----------------------------------------------------------------------- - - character(len=128) :: version = '$Id: fsrad.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -!----------------------------------------------------------------------- - -CONTAINS - -!####################################################################### - - Subroutine FSrad (ip,jp,Press,Temp,Rh2o,Qo3, & - phalf,do_mcm_radiation, & - Nclds,KtopSW,KbtmSW,Ktop,Kbtm,CldAmt, & - EmCld,CUVRF,CIRRF,CIRAB,Albedo,RVco2, & - CosZ,Solar, & - SWin,SWout,OLR,SWupS,SWdnS,LWupS,LWdnS, & - TdtSW,TdtLW, Ksfc,Psfc) - -!----------------------------------------------------------------------- -Integer, Intent(IN) :: ip,jp - Real, Intent(IN), Dimension(:,:,:) :: Press,Temp,Rh2o,Qo3 - Real, Intent(IN), Dimension(:,:,:) :: phalf -Logical, Intent(IN) :: do_mcm_radiation -Integer, Intent(IN), Dimension(:,:) :: Nclds -Integer, Intent(IN), Dimension(:,:,:) :: KtopSW,KbtmSW,Ktop,Kbtm - Real, Intent(IN), Dimension(:,:,:) :: CldAmt,EmCld,CUVRF,CIRRF,CIRAB - Real, Intent(IN), Dimension(:,:) :: Albedo,CosZ,Solar - Real, Intent(IN) :: RVco2 - - Real, Intent(OUT), Dimension(:,:) :: SWin,SWout,OLR,SWupS,SWdnS, & - LWupS,LWdnS - Real, Intent(OUT), Dimension(:,:,:) :: TdtSW,TdtLW - -Integer, Intent(IN), Dimension(:,:), Optional :: Ksfc - Real, Intent(IN), Dimension(:,:), Optional :: Psfc -!--------------------------------------------------------------------- - - call error_mesg('FSrad', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine FSrad - -!####################################################################### - - Subroutine fsrad_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('fsrad_init', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine fsrad_init - -!####################################################################### - - Subroutine fsrad_end - - module_is_initialized = .false. -!--------------------------------------------------------------------- - - call error_mesg('fsrad_end', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine fsrad_end - -!####################################################################### - - - End Module FSrad_Mod - diff --git a/src/atmos_param/fsrad/null/hconst.F90 b/src/atmos_param/fsrad/null/hconst.F90 deleted file mode 100644 index f15260ab33..0000000000 --- a/src/atmos_param/fsrad/null/hconst.F90 +++ /dev/null @@ -1,31 +0,0 @@ - - MODULE HCONST_MOD - -!----------------------------------------------------------------------- -! ----- The following are physical constants ----- - - REAL,PARAMETER :: AMOLWT = 28.9644 - REAL,PARAMETER :: CSUBP = 1.00484E7 - REAL,PARAMETER :: DIFFCTR = 1.66 - REAL,PARAMETER :: GRAV = 980.665 - REAL,PARAMETER :: GINV = 1./GRAV - REAL,PARAMETER :: GRAVDR = 980.0 - REAL,PARAMETER :: O3DIFCTR = 1.90 - REAL,PARAMETER :: P0 = 1013250. - REAL,PARAMETER :: P0INV = 1./P0 - REAL,PARAMETER :: GP0INV = GINV*P0INV - REAL,PARAMETER :: P0XZP2 = 202649.902 - REAL,PARAMETER :: P0XZP8 = 810600.098 - REAL,PARAMETER :: P0X2 = 2.*1013250. - REAL,PARAMETER :: RADCON = 8.427 - REAL,PARAMETER :: RADCON1 = 1./8.427 - REAL,PARAMETER :: RATCO2MW = 1.519449738 - REAL,PARAMETER :: RATH2OMW = 0.622 - REAL,PARAMETER :: RGAS = 8.3142E7 - REAL,PARAMETER :: RGASSP = 8.31432E7 - REAL,PARAMETER :: SECPDA = 8.64E4 - -!----------------------------------------------------------------------- - - END MODULE HCONST_MOD - diff --git a/src/atmos_param/fsrad/null/longwave.F90 b/src/atmos_param/fsrad/null/longwave.F90 deleted file mode 100644 index 9688e6a761..0000000000 --- a/src/atmos_param/fsrad/null/longwave.F90 +++ /dev/null @@ -1,382 +0,0 @@ - - MODULE LONGWAVE_MOD - -!----------------------------------------------------------------------- - - USE RDPARM_MOD, ONLY: LMAX - USE RDPARM_MOD, ONLY: LM1,LP1,LP2,LL,LLP1,LLM1,LP1M,LP1V,LL3P - USE RDPARM_MOD, ONLY: NBLW,NBLX,NBLY,NBLM,INLTE,INLTEP,NNLTE - - USE HCONST_MOD, ONLY: DIFFCTR,GINV,P0,P0INV,GP0INV,P0XZP2,P0XZP8 - USE HCONST_MOD, ONLY: RADCON,RADCON1,RATH2OMW,SECPDA - - Use FMS_Mod, ONLY: Error_Mesg, FATAL, NOTE, mpp_pe, & - mpp_root_pe, write_version_number - - Use CO2_Data_Mod, ONLY: CO251,CO258,CDT51,CDT58,C2D51,C2D58, & - CO2M51,CO2M58,CDTM51,CDTM58,C2DM51, & - C2DM58, STEMP,GTEMP, B0,B1,B2,B3 - Use CO2_Data_Mod, ONLY: CO231,CO238,CDT31,CDT38,C2D31,C2D38 - Use CO2_Data_Mod, ONLY: CO271,CO278,CDT71,CDT78,C2D71,C2D78 - Use CO2_Data_Mod, ONLY: CO211,CO218 - - -! ----------------------------------------------------------- -implicit none -private - -!----------------------------------------------------------------------- -!--------------------- G L O B A L D A T A --------------------------- -!----------------------------------------------------------------------- -! -! Random band parameters for the longwave calcualtions using -! 10 cm-1 wide bands. The 15 um co2 complex is 2 bands, -! 560-670 and 670-800 cm-1. Ozone coefficients are in 3 bands, -! 670-800 (14.1 um), 990-1070 and 1070-1200 (9.6 um). -! The (NBLW) bands now include: -! -! 56 BANDS, 10 CM-1 WIDE 0 - 560 CM-1 -! 2 BANDS, 15 UM COMPLEX 560 - 670 CM-1 -! 670 - 800 CM-1 -! 3 "CONTINUUM" BANDS 800 - 900 CM-1 -! 900 - 990 CM-1 -! 1070 - 1200 CM-1 -! 1 BAND FOR 9.6 UM BAND 990 - 1070 CM-1 -! 100 BANDS, 10 CM-1 WIDE 1200 - 2200 CM-1 -! 1 BAND FOR 4.3 UM SRC 2270 - 2380 CM-1 -! -! Thus NBLW presently equals 163 -! All bands are arranged in order of increasing wavenumbers. -! -! ARNDM = RANDOM "A" PARAMETER FOR (NBLW) BANDS -! BRNDM = RANDOM "B" PARAMETER FOR (NBLW) BANDS -! BETAD = CONTINUUM COEFFICIENTS FOR (NBLW) BANDS -! AP,BP = CAPPHI COEFFICIENTS FOR (NBLW) BANDS -! ATP,BTP = CAPPSI COEFFICIENTS FOR (NBLW) BANDS -! BANDLO = LOWEST FREQUENCY IN EACH OF (NBLW) FREQ. BANDS -! BANDHI = HIGHEST FREQUENCY IN EACH OF (NBLW) FREQ. BANDS -! AO3RND = RANDOM "A" PARAMETER FOR OZONE IN (3) OZONE -! BANDS. -! BO3RND = RANDOM "B" PARAMETER FOR OZONE IN (3) OZONE -! BANDS -! AB15 = THE PRODUCT ARNDM*BRNDM FOR THE TWO BANDS -! REPRESENTING THE 15 UM BAND COMPLEX OF CO2 -! -! Data for ARNDM,BRNDM,AP,BP,ATP,BTP,AO3RND,BO3RND are obtained -! by using the AFGL 1982 catalog. Continuum coefficients are from -! Roberts (1976). This data was formerly in COMMON /BANDTA/. - - REAL ARNDM(NBLW),BRNDM(NBLW),BETAD(NBLW),AP(NBLW), & - BP(NBLW),ATP(NBLW),BTP(NBLW),BANDLO(NBLW), & - BANDHI(NBLW),AO3RND(3),BO3RND(3),AB15(2) - -!----------------------------------------------------------------------- -! -! Random band parameters for the longwave calculations using -! comboned wide frequency bands between 160 and 1200 cm-1, -! as well as the 2270-2380 band for source calculations. -! -! BANDS 1-8: COMBINED WIDE FREQUENCY BANDS FOR 160-560 CM-1 -! BANDS 9-14: FREQUENCY BANDS,AS IN BANDTA (NARROW BANDS) -! FOR 560-1200 CM-1 -! BAND 15: FREQUENCY BAND 2270-2380 CM-1,USED FOR SOURCE -! CALCULATION ONLY -! -! Thus NBLY presently equals 15 -! -! Bands are arranged in order of increasing wavenumber. -! -! ACOMB = RANDOM "A" PARAMETER FOR (NBLY) BANDS -! BCOMB = RANDOM "B" PARAMETER FOR (NBLY) BANDS -! BETACM = CONTINUUM COEFFICIENTS FOR (NBLY) BANDS -! APCM,BPCM = CAPPHI COEFFICIENTS FOR (NBLY) BANDS -! ATPCM,BTPCM = CAPPSI COEFFICIENTS FOR (NBLY) BANDS -! BDLOCM = LOWEST FREQUENCY IN EACH OF (NBLY) FREQ. BANDS -! BDHICM = HIGHEST FREQUENCY IN EACH OF (NBLY) FREQ. BANDS -! AO3CM = RANDOM "A" PARAMETER FOR OZONE IN (3) OZONE -! BANDS. -! BO3CM = RANDOM "B" PARAMETER FOR OZONE IN (3) OZONE -! BANDS -! AB15CM = THE PRODUCT ARNDM*BRNDM FOR THE TWO BANDS -! REPRESENTING THE 15 UM BAND COMPLEX OF CO2 -! BETINC = CONT.COEFFICIENT FOR A SPECIFIED WIDE -! FREQ.BAND (800-990 AND 1070-1200 CM-1). -! IBAND = INDEX NO OF THE 40 WIDE BANDS USED IN -! COMBINED WIDE BAND CALCULATIONS. IN OTHER -! WORDS,INDEX TELLING WHICH OF THE 40 WIDE -! BANDS BETWEEN 160-560 CM-1 ARE INCLUDED IN -! EACH OF THE FIRST 8 COMBINED WIDE BANDS -! -! Data for ACOMB,BCOMB,APCM,BPCM,ATPCM,BTPCM,AO3CM,BO3CM are -! obtained by using the AFGL 1982 catalog. Continuum coefficients -! are from Roberts (1976). IBAND index values are obtained by -! experimentation. This data was formerly in COMMON /BDCOMB/. - - INTEGER IBAND(40) - REAL ACOMB(NBLY),BCOMB(NBLY), & - BETACM(NBLY),APCM(NBLY),BPCM(NBLY),ATPCM(NBLY), & - BTPCM(NBLY),BDLOCM(NBLY),BDHICM(NBLY),BETINC, & - AO3CM(3),BO3CM(3),AB15CM(2) - - -!----------------------------------------------------------------------- -! -! Random band parameters for specific wide bands. At present, -! the information consists of: 1) random model parameters for -! the 15 um band, 560-800 cm-1; 2) the continuum coefficient for -! the 800-990, 1070-1200 cm-1 band. -! -! specifically: -! AWIDE = RANDOM "A" PARAMETER FOR BAND -! BWIDE = RANDOM "B" PARAMETER FOR BAND -! BETAWD = CONTINUUM COEFFICIENTS FOR BAND -! APWD,BPWD = CAPPHI COEFFICIENTS FOR BAND -! ATPWD,BTPWD = CAPPSI COEFFICIENTS FOR BAND -! BDLOWD = LOWEST FREQUENCY IN EACH FREQ BAND -! BDHIWD = HIGHEST FREQUENCY IN EACH FREQ BAND -! AB15WD = THE PRODUCT ARNDM*BRNDM FOR THE ONE BAND -! REPRESENTING THE 15 UM BAND COMPLEX OF CO2 -! BETINW = CONT.COEFFICIENT FOR A SPECIFIED WIDE -! FREQ.BAND (800-990 AND 1070-1200 CM-1). -! SKO2D = 1./BETINW, USED IN SPA88 FOR CONT. COEFFS -! SKC1R = BETAWD/BETINW, USED FOR CONT. COEFF. FOR -! 15 UM BAND IN FST88 -! SKO3R = RATIO OF CONT. COEFF. FOR 9.9 UM BAND TO -! BETINW, USED FOR 9.6 UM CONT COEFF IN FST88 -! -! Data for AWIDE,BWIDE,APWD,BPWD,ATPWD,BTPWD,AO3WD,BO3WD are -! obtained by using the AFGL 1982 catalog. Continuum coefficients -! are from Roberts (1976). This data was formerly in -! COMMON /BDWIDE/. - - REAL AWIDE,BWIDE,BETAWD, & - APWD,BPWD,ATPWD,BTPWD, & - BDLOWD,BDHIWD,BETINW, & - AB15WD,SKO2D,SKC1R,SKO3R - - -!----------------------------------------------------------------------- -! -! CLDFAC = CLOUD TRANSMISSION FUNCTION,ASSUMING RANDOM -! OVERLAP - - REAL, ALLOCATABLE, DIMENSION(:,:,:) :: CLDFAC - -!----------------------------------------------------------------------- -! -! Basic quantities computed in SUBROUTINE LWRAD and used in -! the remaining longwave routines (formally COMMON /KDACOM/): -! -! QH2O = H2O MASS MIXING RATIO,MULTIPLIED BY THE -! DIFFUSIVITY FACTOR (DIFFCTR) -! P = PRESSURE AT FLUX LEVELS OF MODEL -! DELP2 = PRESSURE DIFFERENCE BETWEEN FLUX LEVELS -! DELP = INVERSE OF DELP2 -! TTTT = TEMPERATURE ASSIGNED TO MODEL FLUX LEVELS -! VAR1 = H2O OPTICAL PATH IN MODEL LAYERS (BETWEEN -! FLUX LEVELS) -! VAR2 = PRESSURE-WEIGHTED H2O OPTICAL PATH IN MODEL LAYERS -! VAR3 = O3 OPTICAL PATH IN MODEL LAYERS -! VAR4 = PRESSURE-WEIGHTED O3 OPTICAL PATH IN MODEL LAYERS -! CNTVAL = H2O CONTINUUM PATH IN MODEL LAYERS FOR THE -! 800-990 AND 1070-1200 CM-1 COMBINED BAND - - REAL, ALLOCATABLE, DIMENSION(:,:) :: QH2O,P,DELP2,DELP,TTTT - REAL, ALLOCATABLE, DIMENSION(:,:) :: VAR1,VAR2,VAR3,VAR4,CNTVAL - -!----------------------------------------------------------------------- -! -! Flux quantities computed by the radiation code, used for -! diagnostic purposes (formally COMMON /RDFLUX/): -! -! FLX1E1 = FLUX AT TOP FOR 0-160,1200-2200 CM-1 RANGE -! GXCTS = FLUX AT TOP FOR 160-1200 CM-1 RANGE -! FCTSG = CTS FLUX AT GROUND. USED TO OBTAIN GXCTS -! BY BANDS. - - REAL, ALLOCATABLE, DIMENSION(:) :: FLX1E1,GXCTS - REAL, ALLOCATABLE, DIMENSION(:,:) :: FCTSG - -!----------------------------------------------------------------------- -! -! Planck function values used for the radiative calculations -! (formally COMMON /SRCCOM/): -! -! SORC = PLANCK FCTN, AT MODEL TEMPERATURES, FOR ALL BANDS -! USED IN CTS CALCULATIONS -! CSOUR1 = PLANCK FCTN FOR 560-670 CM-1 BAND -! CSOUR2 = PLANCK FCTN FOR 670-800 CM-1 BAND -! CSOUR = PLANCK FCTN FOR 560-800 CM-1 BANDS -! OSOUR = PLANCK FCTN FOR 990-1070 CM-1 BAND -! SS1 = PLANCK FCTN FOR 800-990,1070-1200 CM-1 BANDS - - REAL, ALLOCATABLE, DIMENSION(:,:,:) :: SORC - REAL, ALLOCATABLE, DIMENSION(:,:) :: CSOUR1,CSOUR2,OSOUR,CSOUR,SS1 - -!----------------------------------------------------------------------- -! -! Quantities precomputed in subroutine TABLE for use in -! the longwave radiation module (formally COMMON /TABCOM/): -! -! EM1 = E1 FUNCTION, EVALUATED OVER THE 0-560 AND -! 1200-2200 CM-1 INTERVALS -! EM1WDE = E1 FUNCTION, EVALUATED OVER THE 160-560 CM-1 -! INTERVAL -! TABLE1 = E2 FUNCTION, EVALUATED OVER THE 0-560 AND -! 1200-2200 CM-1 INTERVALS -! TABLE2 = TEMPERATURE DERIVATIVE OF TABLE1 -! TABLE3 = MASS DERIVATIVE OF TABLE1 -! EM3 = E3 FUNCTION, EVALUATED OVER THE 0-560 AND -! 1200-2200 CM-1 INTERVALS -! SOURCE = PLANCK FUNCTION, EVALUATED AT SPECIFIED TEMPS. FOR -! BANDS USED IN CTS CALCULATIONS -! DSRCE = TEMPERATURE DERIVATIVE OF SOURCE -! INDX2 = INDEX VALUES USED IN OBTAINING "LOWER TRIANGLE" -! ELEMENTS OF AVEPHI,ETC.,IN FST88 -! KMAXV = INDEX VALUES USED IN OBTAINING "UPPER TRIANGLE" -! ELEMENTS OF AVEPHI,ETC.,IN FST88 -! KMAXVM = KMAXV(LMAX),USED FOR DO LOOP INDICES - - INTEGER, ALLOCATABLE, DIMENSION(:) :: INDX1,INDX2,KMAXV - - INTEGER :: KMAXVM - - REAL, DIMENSION(28,NBLY) :: SOURCE,DSRCE - -! REAL EM1 (28,180),EM1WDE(28,180),TABLE1(28,180), -! COMMON /TABCOM/ EM1 (28,180),EM1WDE(28,180),TABLE1(28,180), -! & TABLE2(28,180),TABLE3(28,180),EM3 (28,180) - -!----------------------------------------------------------------------- -! -! Transmission functions used for radiative computations, and -! output heating rates and fluxes, except those needed out of -! the radiative module (formally COMMON /TFCOM/): -! -! TO3 = TRANSMISSION FCTN FOR THE 990-1070 CM-1 BAND -! O3(9.6 UM) + H2O CONTINUUM (NO LINES) -! CO21 = TRANSMISSION FCTN FOR THE 560-800 CM-1 BAND -! (AS 1 BAND). INCLUDES CO2 (IN LWRAD) AND -! H2O(L+C) AFTER MULTIPLICATION WITH "OVER" -! IN FST88 -! EMISS = E2 EMISSIVITYY FCTN FOR H2O LINES (0-560,1200-2200 -! CM-1). OBTAINED IN E1E288. -! EMISS2 = TRANSMISSION FCTN FOR H2O CONTINUUM IN THE 800-990 -! AND 1070-1200 CM-1 REGION, TAKEN AS 1 BAND -! AVEPHI = H2O OPTICAL PATHS BET. FLUX PRESSURES: INPUT TO -! EMISSIVITY CALCULATIONS. -! TTEMP = TEMPERATURES USED AS INPUT FOR EMISSIVITY CALCS. -! CTS = APPROX CTS HEATING RATES FOR 160-560 AND 800-990, -! 1070-1200 CM-1 RANGES -! CTSO3 = APPROX CTS HEATING RATES FOR 560-800,990-1070 CM-1 -! RANGES -! EXCTS = EXACT CTS HEATING RATES FOR 160-1200 CM-1 RANGE -! EXCTSN = EXACT CTS HEATING RATES, BY BANDS -! E1FLX = E1 EMISSIVITY FCTN FOR H2O LINES (0-560,1200-CM-1) -! CO2NBL = CO2 TRANS. FCTNS. (NOT PRESSURE-INTEGRATED) FOR -! ADJACENT LEVELS,OVER THE 560-800 CM-1 RANGE. -! CO2SP1 = CO2 TRANS. FCTNS. (NOT PRESSURE-INTEGRATED) BET. -! A FLUX LEVEL AND SPACE, FOR THE 560-670 CM-1 -! RANGE. USED FOR EXACT CTS CALCS. -! CO2SP2 = SAME AS CO2SP1, BUT FOR THE 670-800 CM-1 RANGE. -! CO2SP = SAME AS CO2SP1, BUT FOR THE 560-800 CM-1 BAND. -! USED FOR APPROX CTS CALCS. -! TO3SPC = O3 OPTICAL DEPTHS BET. A LEVEL AND SPACE. USED FOR -! EXACT CTS CALCS. -! TOTVO2 = H2O CONTINUUM OPTICAL PATHS BET. SPACE AND A -! LEVEL, USING THE CNT. COEFFICIENT FOR THE -! 1-BAND 800-990,1070-1200 CM-1 BAND. USED FOR -! CTS CALCS. - - REAL,ALLOCATABLE,DIMENSION(:,:,:) :: TO3,CO21,EMISS,EMISS2,AVEPHI - REAL,ALLOCATABLE,DIMENSION(:,:) :: CTS,CTSO3,EXCTS - REAL,ALLOCATABLE,DIMENSION(:,:,:) :: EXCTSN - REAL,ALLOCATABLE,DIMENSION(:,:) :: E1FLX,CO2NBL,CO2SP1,CO2SP2 - REAL,ALLOCATABLE,DIMENSION(:,:) :: CO2SP,TO3SPC,TOTVO2 - -!------------ VERSION NUMBER ---------------- - - character(len=128) :: version = '$Id: longwave.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -!----------------------------------------------------------------------- - -public LWRad, Rad_DeAlloc, longwave_init, longwave_end -public OSOUR, CSOUR, SS1, FLX1E1, GXCTS, FCTSG, CLDFAC, DELP2, DELP, & - TO3, CO21, EMISS, EMISS2, CTS, EXCTS, EXCTSN, E1FLX, CO2SP, & - IBAND, BANDLO, BANDHI - - CONTAINS - -!####################################################################### -!####################################################################### - Subroutine longwave_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('longwave_init', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine longwave_init - -!####################################################################### -!####################################################################### - - Subroutine longwave_end - - module_is_initialized = .false. -!--------------------------------------------------------------------- - - call error_mesg('longwave_end', & - 'This module is not supported as part of the public release', FATAL) - - End Subroutine longwave_end - -!####################################################################### -!####################################################################### - - SUBROUTINE LWRAD (KTOP,KBTM,NCLDS,EMCLD,PRES,TEMP,RH2O,QO3,CAMT, & - RRVCO2, HEATRA,GRNFLX,TOPFLX, LSFC,PSFC) - - INTEGER, INTENT(IN), DIMENSION(:,:,:) :: KTOP,KBTM - INTEGER, INTENT(IN), DIMENSION(:,:) :: NCLDS - REAL, INTENT(IN), DIMENSION(:,:,:) :: EMCLD - REAL, INTENT(IN), DIMENSION(:,:,:) :: PRES,TEMP,RH2O,QO3,CAMT - REAL, INTENT(IN) :: RRVCO2 - - REAL, INTENT(OUT), DIMENSION(:,:,:) :: HEATRA - REAL, INTENT(OUT), DIMENSION(:,:) :: GRNFLX,TOPFLX - - INTEGER, INTENT(IN),OPTIONAL, DIMENSION(:,:) :: LSFC - REAL , INTENT(IN),OPTIONAL, DIMENSION(:,:) :: PSFC - -!--------------------------------------------------------------------- - - call error_mesg('LWRAD', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE LWRAD - -!####################################################################### - - SUBROUTINE RAD_DEALLOC - -!--------------------------------------------------------------------- - - call error_mesg('RAD_DEALLOC', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE RAD_DEALLOC - -!####################################################################### - - END MODULE LONGWAVE_MOD - diff --git a/src/atmos_param/fsrad/null/mcm_lw.F90 b/src/atmos_param/fsrad/null/mcm_lw.F90 deleted file mode 100644 index 858427ea7b..0000000000 --- a/src/atmos_param/fsrad/null/mcm_lw.F90 +++ /dev/null @@ -1,90 +0,0 @@ - MODULE MCM_LW_MOD - -! Added interface routine (lw_rad_ss) which is called by -! fsrad and which calls lwcool in this -! module after constructing the appropriate inputs. - - USE Constants_Mod, ONLY: grav, tfreeze - - Use Fms_Mod, ONLY: Error_Mesg, FATAL, & - write_version_number, mpp_pe, mpp_root_pe - -implicit none - private - -!------------ VERSION NUMBER ---------------- - - character(len=128) :: version = '$Id: mcm_lw.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - - public MCM_LW_RAD, mcm_lw_init, mcm_lw_end - -! ------------------------------------------------- - -!----------------------------------------------------------------------- -!--------------------- G L O B A L D A T A --------------------------- -!----------------------------------------------------------------------- - - - contains - -!####################################################################### - subroutine mcm_lw_init(ix_in, jx_in, kx_in) - integer, intent(in) :: ix_in, jx_in, kx_in - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('mcm_lw_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_lw_init -!####################################################################### - - subroutine MCM_LW_END - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('MCM_LW_END', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine MCM_LW_END - -!####################################################################### - SUBROUTINE MCM_LW_RAD (KTOP,KBTM,NCLDS,EMCLD, & - PRES,TEMP,RH2O,QO3,CAMT, & - RRVCO2, HEATRA,GRNFLX,TOPFLX, phalf) - - INTEGER, INTENT(IN), DIMENSION(:,:,:) :: KTOP,KBTM - INTEGER, INTENT(IN), DIMENSION(:,:) :: NCLDS - REAL, INTENT(IN), DIMENSION(:,:,:) :: EMCLD - REAL, INTENT(IN), DIMENSION(:,:,:) :: PRES,TEMP - REAL, INTENT(IN), DIMENSION(:,:,:) :: RH2O,QO3 - REAL, INTENT(IN), DIMENSION(:,:,:) :: CAMT - REAL, INTENT(IN) :: RRVCO2 - - REAL, INTENT(OUT), DIMENSION(:,:,:) :: HEATRA - REAL, INTENT(OUT), DIMENSION(:,:) :: GRNFLX,TOPFLX - - REAL, INTENT(IN), DIMENSION(:,:,:) :: phalf - - - -!--------------------------------------------------------------------- - - call error_mesg('MCM_LW_RAD', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE MCM_LW_RAD - - end module mcm_lw_mod diff --git a/src/atmos_param/fsrad/null/mcm_sw_driver.F90 b/src/atmos_param/fsrad/null/mcm_sw_driver.F90 deleted file mode 100644 index a10e26df5c..0000000000 --- a/src/atmos_param/fsrad/null/mcm_sw_driver.F90 +++ /dev/null @@ -1,76 +0,0 @@ - MODULE MCM_SW_DRIVER_MOD -! - Use Fms_Mod, ONLY: Error_Mesg, FATAL, & - write_version_number, mpp_pe, mpp_root_pe - - use mcm_swnew_mod, only: mcm_swnew - -implicit none - private - - character(len=128) :: version = '$Id: mcm_sw_driver.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - - public :: mcm_shortwave_driver, mcm_sw_driver_init, & - mcm_sw_driver_end - -contains - - subroutine mcm_shortwave_driver( & - Nclds, KtopSW, KbtmSW, Press, Rh2o, Qo3, CldAmt, & - CUVRF, CIRRF, CIRAB, Rco2, CosZ, SSolar, & - Albedo, FSW, DFSW, UFSW, TdtSW, Phalf) - - - integer, intent (in), dimension(:,:) :: Nclds - integer, intent (in), dimension(:,:,:) :: KtopSW, KbtmSW - real, intent (in) , dimension(:,:,:) :: Press, Phalf - real, intent (in) , dimension(:,:,:) :: CldAmt, CUVRF,& - & CIRRF, CIRAB - real, intent (in) , dimension(:,:,:) :: Rh2o, Qo3 - - real, intent (in) :: Rco2 - real, intent (in) , dimension(:,:) :: CosZ - real, intent (in) , dimension(:,:) :: SSolar - real, intent (in) , dimension(:,:) :: Albedo - - REAL, INTENT(OUT), DIMENSION(:,:,:) :: FSW, DFSW, UFSW - REAL, INTENT(OUT), DIMENSION(:,:,:) :: TdtSW - - -!--------------------------------------------------------------------- - - call error_mesg('mcm_shortwave_driver', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_shortwave_driver -! --------------------------------------------------------------------------------------- - subroutine mcm_sw_driver_init(kx_in) - integer, intent(in) :: kx_in - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. -!--------------------------------------------------------------------- - - call error_mesg('mcm_sw_driver_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_sw_driver_init -! --------------------------------------------------------------------------------------- - subroutine mcm_sw_driver_end - - module_is_initialized = .false. -!--------------------------------------------------------------------- - - call error_mesg('mcm_sw_driver_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_sw_driver_end -! --------------------------------------------------------------------------------------- - end module MCM_SW_DRIVER_MOD diff --git a/src/atmos_param/fsrad/null/mcm_swnew.F90 b/src/atmos_param/fsrad/null/mcm_swnew.F90 deleted file mode 100644 index a62e5c3155..0000000000 --- a/src/atmos_param/fsrad/null/mcm_swnew.F90 +++ /dev/null @@ -1,69 +0,0 @@ - module mcm_swnew_mod - - use mcm_swtbls_mod, only: aaa, aab - Use Fms_Mod, ONLY: write_version_number, mpp_pe, mpp_root_pe, & - error_mesg, FATAL - -implicit none -private - - character(len=128) :: version = '$Id: mcm_swnew.F90,v 11.0 2004/09/28 19:18:44 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -public mcm_swnew, mcm_swnew_init, mcm_swnew_end - -contains - - subroutine mcm_swnew( cosz, rco2, rh2o, ro3, pp, & - cwca, cwcb, coca, cloudy, kthsw, kbhsw, ssolar, pr2, & - flx, heat, grdflx, ncv, kx, UF, DF) - - integer, intent (in) :: ncv, kx - real , intent (in) :: cosz, rco2, Ssolar - - real , intent (in), dimension(kx) :: rh2o, ro3 - real , intent (in), dimension(0:kx) :: pp - real , intent (in), dimension(1:kx+2) :: cwca, cwcb, coca, cloudy - real , intent (in), dimension(1:kx+1) :: pr2 - - integer, intent (in), dimension(1:kx+2) :: kthsw, kbhsw - - real , intent (out) :: grdflx - real , intent (out), dimension(1:kx+1) :: flx, heat, UF, DF - -!--------------------------------------------------------------------- - - call error_mesg('mcm_swnew', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_swnew -! --------------------------------------------------------------------------------------- - subroutine mcm_swnew_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('mcm_swnew_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_swnew_init -! --------------------------------------------------------------------------------------- - subroutine mcm_swnew_end - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('mcm_swnew_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine mcm_swnew_end - - end module mcm_swnew_mod diff --git a/src/atmos_param/fsrad/null/mcm_swtbls.F90 b/src/atmos_param/fsrad/null/mcm_swtbls.F90 deleted file mode 100644 index a18b62571f..0000000000 --- a/src/atmos_param/fsrad/null/mcm_swtbls.F90 +++ /dev/null @@ -1,11 +0,0 @@ -module mcm_swtbls_mod - -implicit none -private - -public :: aaa, aab - -real :: aaa(2000), aab(1000) - - -end module mcm_swtbls_mod diff --git a/src/atmos_param/fsrad/null/rad_diag.F90 b/src/atmos_param/fsrad/null/rad_diag.F90 deleted file mode 100644 index 43493d71bb..0000000000 --- a/src/atmos_param/fsrad/null/rad_diag.F90 +++ /dev/null @@ -1,104 +0,0 @@ - - MODULE RAD_DIAG_MOD - -!----------------------------------------------------------------------- - - USE RDPARM_MOD, ONLY: LMAX, LP1, NBLW, NBLY, NBLM - - USE HCONST_MOD, ONLY: RADCON, RADCON1 - - USE LONGWAVE_MOD, ONLY: OSOUR, CSOUR, SS1 - USE LONGWAVE_MOD, ONLY: FLX1E1, GXCTS, FCTSG - USE LONGWAVE_MOD, ONLY: CLDFAC - USE LONGWAVE_MOD, ONLY: DELP2, DELP - USE LONGWAVE_MOD, ONLY: TO3, CO21, EMISS, EMISS2, CTS, EXCTS, & - EXCTSN, E1FLX, CO2SP - USE LONGWAVE_MOD, ONLY: IBAND, BANDLO, BANDHI - -! ------------------------------------------------------------- - Use Fms_Mod, ONLY: write_version_number, mpp_pe, mpp_root_pe, & - error_mesg, FATAL - - -implicit none -private - -!----------------------------------------------------------------------- - character(len=128) :: version = '$Id: rad_diag.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -public RADIAG, RAD_DIAG_init, RAD_DIAG_end - - CONTAINS - -!####################################################################### -!####################################################################### - - SUBROUTINE RADIAG & - ( PRESS,TEMP,RH2O,RRVCO2,QO3,CAMT,KTOP,KBTM,NCLDS, & - HEATRA,GRNFLX, & - FSW,DFSW,UFSW,HSW, & - KTOPSW,KBTMSW,EMCLD,CUVRF,CIRRF,CIRAB, & - SALB,COSZRO,SSOLAR, ip,jp) - -!----------------------------------------------------------------------- - REAL, INTENT(IN), DIMENSION(:,:,:) :: PRESS,TEMP,RH2O - REAL, INTENT(IN) :: RRVCO2 - REAL, INTENT(IN), DIMENSION(:,:,:) :: QO3,CAMT - INTEGER, INTENT(IN), DIMENSION(:,:,:) :: KTOP,KBTM - INTEGER, INTENT(IN), DIMENSION(:,:) :: NCLDS - - REAL, INTENT(IN), DIMENSION(:,:,:) :: HEATRA - REAL, INTENT(IN), DIMENSION(:,:) :: GRNFLX - - REAL, INTENT(IN), DIMENSION(:,:,:) :: FSW,DFSW,UFSW,HSW - - INTEGER, INTENT(IN), DIMENSION(:,:,:) :: KTOPSW,KBTMSW - REAL, INTENT(IN), DIMENSION(:,:,:) :: EMCLD,CUVRF,CIRRF,CIRAB - - REAL, INTENT(IN), DIMENSION(:,:) :: SALB,COSZRO,SSOLAR - INTEGER, INTENT(IN) :: ip,jp -!----------------------------------------------------------------------- - - call error_mesg('RADIAG', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE RADIAG - -!####################################################################### -!####################################################################### - - subroutine RAD_DIAG_init -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('RAD_DIAG_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine RAD_DIAG_init - -!####################################################################### -!####################################################################### - - subroutine RAD_DIAG_end - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('RAD_DIAG_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine RAD_DIAG_end - - - END MODULE RAD_DIAG_MOD - diff --git a/src/atmos_param/fsrad/null/rdparm.F90 b/src/atmos_param/fsrad/null/rdparm.F90 deleted file mode 100644 index 6927ec8a76..0000000000 --- a/src/atmos_param/fsrad/null/rdparm.F90 +++ /dev/null @@ -1,94 +0,0 @@ - - MODULE RDPARM_MOD - -!----------------------------------------------------------------------- -! -! PARAMETER SETTINGS FOR THE LONGWAVE AND SHORTWAVE RADIATION CODE: -! ----------------------------------------------------------------- -! -! IMAX = NO. POINTS ALONG THE LAT. CIRCLE USED IN CALCS. -! JMAX = NO. POINTS ALONG THE MERIDIONAL AXIS -! LMAX = NO. VERTICAL LEVELS (ALSO LAYERS) IN MODEL -! -! *** NOTE: THE USER NORMALLY WILL MODIFY ONLY THE -! IMAX AND LMAX VARIABLES -! -! NBLW = NO. FREQ. BANDS FOR APPROX COMPUTATIONS. SEE -! BANDTA FOR DEFINITION -! NBLX = NO. FREQ BANDS FOR APPROX CTS COMPUTATIONS -! NBLY = NO. FREQ. BANDS FOR EXACT CTS COMPUTATIONS. SEE -! BDCOMB FOR DEFINITION -! INLTE = NO. LEVELS USED FOR NLTE CALCS. -! NNLTE = INDEX NO. OF FREQ. BAND IN NLTE CALCS. -! -! NB,KO2 ARE SHORTWAVE PARAMETERS; OTHER QUANTITIES ARE -! DERIVED FROM THE ABOVE PARAMETERS. -! -!----------------------------------------------------------------------- - - Use Fms_Mod, ONLY: write_version_number, mpp_pe, mpp_root_pe, & - error_mesg, FATAL - -implicit none -private - - INTEGER, PUBLIC, SAVE :: LMAX=0 - INTEGER, PUBLIC, SAVE :: LP1,LP2,LP3,LM1,LM2,LM3 - INTEGER, PUBLIC, SAVE :: LL,LLP1,LLP2,LLP3,LLM1,LLM2,LLM3 - INTEGER, PUBLIC, SAVE :: LP1M,LP1M1,LP1V,LP121,LL3P - INTEGER, PUBLIC, SAVE :: LP1I,LLP1I,LL3PI - - INTEGER, PUBLIC, PARAMETER :: NBLW=163,NBLX=47,NBLY=15,NBLM=NBLY-1 - INTEGER, PUBLIC, PARAMETER :: NB=9,NB1=NB-1 - INTEGER, PUBLIC, PARAMETER :: INLTE=3,INLTEP=INLTE+1 - INTEGER, PUBLIC, PARAMETER :: NNLTE=56 - INTEGER, PUBLIC, PARAMETER :: KO2=12,KO21=KO2+1,KO2M=KO2-1 - - - - character(len=128) :: version = '$Id: rdparm.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - -public RDPARM_INIT, RDPARM_END - - CONTAINS - -!####################################################################### - - SUBROUTINE RDPARM_INIT (KDIM) - - INTEGER,INTENT(IN) :: KDIM - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('RDPARM_INIT', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE RDPARM_INIT - -!####################################################################### - - SUBROUTINE RDPARM_END - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('RDPARM_END', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE RDPARM_END - -!####################################################################### - - END MODULE RDPARM_MOD - diff --git a/src/atmos_param/fsrad/null/shortwave.F90 b/src/atmos_param/fsrad/null/shortwave.F90 deleted file mode 100644 index a60bc094df..0000000000 --- a/src/atmos_param/fsrad/null/shortwave.F90 +++ /dev/null @@ -1,89 +0,0 @@ - - MODULE SHORTWAVE_MOD - -!----------------------------------------------------------------------- - - USE RDPARM_MOD, ONLY: LMAX,LP1,LLP1,LP2,LLP2,NB - USE HCONST_MOD, ONLY: DIFFCTR,GINV,O3DIFCTR,RADCON - - Use Fms_Mod, ONLY: Error_Mesg, FATAL, & - write_version_number, mpp_pe, mpp_root_pe - -implicit none -private - -!------- interfaces ------- - PUBLIC SWRAD, SHORTWAVE_INIT, SHORTWAVE_END - - character(len=128) :: version = '$Id: shortwave.F90,v 10.0 2003/10/24 22:00:33 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - - CONTAINS - -!####################################################################### - - SUBROUTINE SWRAD (NCLDS,KTOPSW,KBTMSW,PRESS,RH2O,QO3,CAMT, & - CUVRF,CIRRF,CIRAB,RRCO2,COSZRO,SSOLAR, & - SALB, FSW,DFSW,UFSW,HSW, LSFC,PSFC) - -!----------------------------------------------------------------------- -! WRAPPER FOR SHORT WAVE RADIATION CODE -! inserts surface albedo into appropriate cloud property arrays -!----------------------------------------------------------------------- - - INTEGER, INTENT(IN), DIMENSION(:,:) :: NCLDS - INTEGER, INTENT(IN), DIMENSION(:,:,:) :: KTOPSW,KBTMSW - REAL, INTENT(IN), DIMENSION(:,:,:) :: PRESS,RH2O,QO3 - REAL, INTENT(IN), DIMENSION(:,:,:) :: CAMT,CUVRF,CIRRF,CIRAB - REAL, INTENT(IN) :: RRCO2 - REAL, INTENT(IN), DIMENSION(:,:) :: COSZRO,SSOLAR - REAL, INTENT(IN), DIMENSION(:,:) :: SALB - - REAL, INTENT(OUT), DIMENSION(:,:,:) :: FSW,DFSW,UFSW,HSW - - INTEGER, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: LSFC - REAL, INTENT(IN), OPTIONAL, DIMENSION(:,:) :: PSFC - -!--------------------------------------------------------------------- - - call error_mesg('SWRAD', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE SWRAD - -!####################################################################### - - SUBROUTINE SHORTWAVE_INIT - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('SHORTWAVE_INIT', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE SHORTWAVE_INIT - -!####################################################################### - - SUBROUTINE SHORTWAVE_END - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('SHORTWAVE_END', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE SHORTWAVE_END - -!####################################################################### - - END MODULE SHORTWAVE_MOD diff --git a/src/atmos_param/fsrad/rad_diag.F90 b/src/atmos_param/fsrad/rad_diag.F90 index 25345399b5..3df0351273 100644 --- a/src/atmos_param/fsrad/rad_diag.F90 +++ b/src/atmos_param/fsrad/rad_diag.F90 @@ -25,7 +25,7 @@ MODULE RAD_DIAG_MOD !----------------------------------------------------------------------- character(len=128) :: version = '$Id: rad_diag.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. public RADIAG, RAD_DIAG_init, RAD_DIAG_end diff --git a/src/atmos_param/fsrad/rdparm.F90 b/src/atmos_param/fsrad/rdparm.F90 index d34aad9238..05f169a04a 100644 --- a/src/atmos_param/fsrad/rdparm.F90 +++ b/src/atmos_param/fsrad/rdparm.F90 @@ -47,7 +47,7 @@ MODULE RDPARM_MOD INTEGER, PARAMETER :: KO2=12,KO21=KO2+1,KO2M=KO2-1 character(len=128) :: version = '$Id: rdparm.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. public RDPARM_INIT, RDPARM_END diff --git a/src/atmos_param/fsrad/shortwave.F90 b/src/atmos_param/fsrad/shortwave.F90 index 5eb8a1be5b..7e87cd9e23 100644 --- a/src/atmos_param/fsrad/shortwave.F90 +++ b/src/atmos_param/fsrad/shortwave.F90 @@ -16,7 +16,7 @@ MODULE SHORTWAVE_MOD PUBLIC SWRAD, SHORTWAVE_INIT, SHORTWAVE_END character(len=128) :: version = '$Id: shortwave.F90,v 10.0 2003/10/24 22:00:32 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. integer :: IMAX diff --git a/src/atmos_param/grey_radiation/grey_radiation.F90 b/src/atmos_param/grey_radiation/grey_radiation.F90 index 293fccf7f3..9306350d80 100644 --- a/src/atmos_param/grey_radiation/grey_radiation.F90 +++ b/src/atmos_param/grey_radiation/grey_radiation.F90 @@ -35,7 +35,7 @@ module grey_radiation_mod character(len=128), parameter :: version = & '$Id: grey_radiation.F90,v 19.0 2012/01/06 20:09:59 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_param/lin_cloud_microphys/lin_cloud_microphys.F90 b/src/atmos_param/lin_cloud_microphys/lin_cloud_microphys.F90 index 1669dc49ac..900a8c414f 100644 --- a/src/atmos_param/lin_cloud_microphys/lin_cloud_microphys.F90 +++ b/src/atmos_param/lin_cloud_microphys/lin_cloud_microphys.F90 @@ -1,181 +1,30 @@ ! ! Cloud micro-physics package for GFDL global cloud resolving model -! The algorithms are originally based on Lin et al 1983. Many key +! The algorithms are originally based on Lin et al 1983. Many key ! elements have been changed/improved based on several other publications ! Developer: Shian-Jiann Lin ! module lin_cld_microphys_mod - use mpp_mod, only: stdlog, mpp_pe, mpp_root_pe, mpp_clock_id, & - mpp_clock_begin, mpp_clock_end, CLOCK_ROUTINE, & - input_nml_file - use diag_manager_mod, only: register_diag_field, send_data - use time_manager_mod, only: time_type, get_date, get_time - use constants_mod, only: grav, rdgas, rvgas, cp_air, hlv, hlf, kappa + use time_manager_mod, only: time_type use fms_mod, only: write_version_number, open_namelist_file, & check_nml_error, file_exist, close_file, & - error_mesg, FATAL + error_mesg, FATAL implicit none private - public lin_cld_microphys_driver, lin_cld_microphys_init, lin_cld_microphys_end, sg_conv - public qsmith_init, qsmith, es2_table1d, es3_table1d, esw_table1d - real :: missing_value = -1.e10 - logical :: module_is_initialized = .false. - character(len=17) :: mod_name = 'lin_cld_microphys' - -!==== fms constants ==================== -!real :: rdgas = 287.04 -!real :: rvgas = 461.50 - real, parameter :: cp = cp_air ! heat capacity at constant pressure (j/kg/k) - real, parameter :: eps = rdgas/rvgas ! = 0.621971831 - real, parameter :: zvir = rvgas/rdgas-1. ! = 0.607789855 - real, parameter :: latv = hlv ! = 2.500e6 - real, parameter :: lati = hlf ! = 3.34e5 - real, parameter :: lats = hlv+hlf ! = 2.834E6 -!==== fms constants ==================== - - real, parameter :: qrmin = 1.e-9 - real, parameter :: qvmin = 1.e-20 ! min value for water vapor (treated as zero) - real, parameter :: qcmin = 1.e-12 ! min value for cloud condensates - real, parameter :: sfcrho = 1.20 ! surface air density - real, parameter :: vmin = 1.e-2 ! minimum fall speed for rain/graupel - real, parameter :: tice = 273.16 ! melting starts above tice - real, parameter :: tice0 = 273.15 ! freezing starts below tice0 - real, parameter :: rhor = 1.0e3 ! LFO83 - real, parameter :: f_l2s = 50. - real, parameter:: dz_min = 1.e-2 - - real :: cracs, csacr, cgacr, cgacs, acco(3,4), csacw, & - craci, csaci, cgacw, cgaci, cracw, cssub(5), cgsub(5), & - crevp(5), cgfr(2), csmlt(5), cgmlt(5) - real :: rmi50, es0, ces0, c1brg, c2brg - - - real :: dts, rdts, pie ! these variables have been left unchanged - real :: lcp, icp, tcp, rgrav - real :: fac_rc - real :: mp_count = 0. - - logical :: do_setup=.true. - logical :: master - logical :: g_sum_initialized - real, allocatable, dimension(:,:) :: l_area - - real, allocatable:: vt_r(:,:,:), vt_s(:,:,:), vt_g(:,:,:), vt_i(:,:,:) - real, allocatable:: prec0(:,:), rain0(:,:), snow0(:,:), ice0(:,:), graupel0(:,:) - real, allocatable:: prec1(:,:), prec_mp(:,:), cond(:,:), w_var(:,:) - real, allocatable:: table(:), table2(:), table3(:), tablew(:), des(:), des2(:), des3(:), desw(:) - - integer:: isc, iec, jsc, jec - integer:: id_vtr, id_vts, id_vtg, id_vti, id_rain, id_snow, id_graupel, & - id_ice, id_prec, id_cond, id_var - - real, parameter :: dt_fr = 6. ! homogeneous freezing of all cloud water at t_wfr - dt_fr - real, parameter :: t_wfr = tice-42. ! supercooled water can exist down to -48 C, which is the "absolute" - ! minimum temperature water can exist (Moore & Molinero Nov. 2011, Nature) - ! dt_fr can be considered as the error bar - real, parameter :: t_00 = t_wfr - dt_fr ! This is the absolute freezing point for super-cooled cloud water - integer, parameter:: ng = 0 ! NO ghost zones required as "area" is passed from the phys driver - integer :: lin_cld_mp_clock ! clock for timing of driver routine - - real :: t_snow_melt = 10. ! snow melt tempearture scale factor - real :: q00 = 1.0e-3 -!---------------------- -! namelist parameters: -!---------------------- - real :: qc_crt = 1.0e-7 ! minimum condensate mixing ratio to allow partial cloudiness - real :: t_min = 165. ! Min temperature for ice-phase micro phys - real :: mp_time = 120. ! maximum micro-physics time step (sec) - -! The following 3 time scales are for terminal falls - real :: tau_s = 120. ! snow melt - real :: tau_g = 150. ! graupel melt - -! Ice: - real :: tau_frz = 600. ! cloud water freezing time-scale (mixed phase) - real :: tau_mlt = 10. ! ice melting time-scale - real :: tau_i2v = 30. ! ice ---> vapor - real :: tau_v2i = 150. ! vapor ---> ice -! cloud water - real :: tau_l2v = 30. ! cloud water --> vapor (evaporation) time scale - real :: tau_v2l = 150. ! vapor --> cloud water (condensation) time scale -! Snow - real :: tau_s2v = 600. ! snow to vapor (after liquid/ice sat adj) - real :: tau_v2s = 600. ! vapor to snow -! Graupel - real :: tau_g2v = 1200. ! Grapuel sublimation time scale - real :: tau_v2g = 1200. ! Grapuel deposition -- make it a slow process - - real :: dw_land = 0.18 ! base value for subgrid deviation/variability over land - real :: dw_ocean = 0.14 ! base value for ocean - real :: rh_inc = 0.05 ! parameter to control instant evap of condensates - real :: ccn_o = 70. - real :: ccn_l = 200. - real :: rthresh = 8.0e-6 ! critical cloud drop radius (micro m) - -!------------------------------------------------------------- - real :: qi0_crt = 1.0e-4 ! ice --> snow autocon mixing ratio threshold - real :: qr0_crt = 2.0e-4 ! rain --> snow or graupel/hail threshold - ! LFO used *mixing ratio* = 1.E-4 (hail in LFO) - real :: c_psaut = 1.0e-3 ! autoconversion rate: cloud_ice -> snow - real :: c_psaci = 0.1 ! accretion: cloud ice --> snow (was 0.1 in Zetac) - real :: c_piacr = 1. ! accretion: rain --> ice: - real :: c_cracw = 1.0 ! rain accretion efficiency - -! Decreasing clin to reduce csacw (so as to reduce cloud water ---> snow) - real:: alin = 842.0 - real:: clin = 4.8 ! 4.8 --> 2.4? - -!----------------- -! Graupel control: -!----------------- - real :: qs0_crt = 1.0e-3 ! snow --> graupel density threshold (6.0e-4 in Purdue Lin scheme) - real :: c_pgacs = 0.01 ! snow --> graupel "accretion" eff. (was 0.1 in Zetac) - -! fall velocity tuning constants: - real :: den_ref = sfcrho ! Reference (surface) density for fall speed - ! Larger value produce larger fall speed - real :: vr_fac = 1. - real :: vs_fac = 1. - real :: vg_fac = 1. - real :: vi_fac = 1. - - logical :: z_slope = .false. ! use linear mono slope for autocconversions - logical :: use_deng_mace = .true. ! Helmfield-Donner ice speed - logical :: do_subgrid_z = .false. ! 2X resolution sub-grid saturation/cloud scheme - logical :: use_ccn = .true. - logical :: use_ppm = .true. - logical :: ppm_rain_fall = .true. - logical :: mono_prof = .true. ! perform terminal fall with mono ppm scheme - logical :: mp_debug = .false. - logical :: mp_print = .true. - - real :: p_crt = 200.E2 ! - integer :: k_moist = 20 - real:: rh_adj - real:: fac_l2v, fac_v2l, fac_mlt, fac_sno, fac_i2v, fac_v2i - real:: fac_s2v, fac_v2s, fac_g2v, fac_v2g - - namelist /lin_cld_microphys_nml/mp_time, t_min, tau_s, tau_g, dw_land, dw_ocean, & - tau_frz, vr_fac, vs_fac, vg_fac, vi_fac, & - qs0_crt, qi0_crt, qr0_crt, & - rh_inc, den_ref, use_deng_mace, use_ccn, do_subgrid_z, & - rthresh, ccn_l, ccn_o, qc_crt, & - c_piacr, tau_mlt, tau_i2v, tau_v2i, tau_l2v, tau_v2l, & - c_psaut, c_psaci, c_pgacs, z_slope, & - c_cracw, alin, clin, & - use_ppm, ppm_rain_fall, mono_prof, mp_debug, mp_print + public lin_cld_microphys_driver, lin_cld_microphys_init, lin_cld_microphys_end + public qsmith_init, qsmith, g_sum, wqsat_moist, wqsat2_moist, sat_adj2 !---- version number ----- - character(len=128) :: version = '$Id: lin_cloud_microphys.F90,v 19.0.2.1 2012/06/10 04:47:37 Rusty.Benson Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: lin_cloud_microphys.F90,v 20.0.2.1 2013/12/17 19:46:01 Niki.Zadeh Exp $' + character(len=128) :: tagname = '$Name: nullify_rab_nnz $' contains - + subroutine lin_cld_microphys_driver(qv, ql, qr, qi, qs, qg, qa, & - qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, & + qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, & pt_dt, pt, p3, dz, delp, area, dt_in, & land, rain, snow, ice, graupel, & hydrostatic, phys_hydrostatic, & @@ -197,3505 +46,90 @@ subroutine lin_cld_microphys_driver(qv, ql, qr, qi, qs, qg, qa real, intent(inout), dimension(:,:,:):: qv_dt, ql_dt, qr_dt, qi_dt, & qs_dt, qg_dt + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) -! local: - logical used - real :: mpdt, rdt, convt, tot_prec - integer :: i,j,k - integer :: is,ie, js,je ! physics window - integer :: ks,ke ! vertical dimension - integer :: seconds, days, ntimes - - is = 1 - js = 1 - ks = 1 - ie = iie-iis+1 - je = jje-jjs+1 - ke = kke-kks+1 - - call mpp_clock_begin (lin_cld_mp_clock) - -! tendency zero out for am moist processes should be done outside the driver - - mpdt = min(dt_in, mp_time) - rdt = 1. / dt_in - ntimes = nint( dt_in/mpdt ) -! small time step: - dts = dt_in / real(ntimes) - rdts = 1./dts - - fac_l2v = 1. - exp( -dts/tau_l2v ) ! exact-in-time integration - fac_v2l = 1. - exp( -dts/tau_v2l ) ! exact-in-time integration - - fac_mlt = 1. - exp( -dts/tau_mlt ) ! - fac_i2v = 1. - exp( -dts/tau_i2v ) ! - fac_v2i = 1. - exp( -dts/tau_v2i ) ! - - fac_sno = 1. - exp( -dts/tau_s ) ! - - fac_s2v = 1. - exp( -dts/tau_s2v ) - fac_v2s = 1. - exp( -dts/tau_v2s ) - - fac_g2v = 1. - exp( -dts/tau_g2v ) - fac_v2g = 1. - exp( -dts/tau_v2g ) - - call get_time (time, seconds, days) - - - do j=js, je - do i=is, ie - graupel(i,j) = 0. - rain(i,j) = 0. - snow(i,j) = 0. - ice(i,j) = 0. - cond(i,j) = 0. - enddo - enddo - do j=js,je - call mpdrv( delp, pt, qv, ql, qr, qi, qs, qg, qa, dz, & - is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, & - ntimes, rain(:,j), snow(:,j), graupel(:,j), & - ice(:,j), cond(:,j), area(:,j), land(:,j), & - pt_dt, qv_dt, ql_dt, qr_dt, qi_dt, & - qs_dt, qg_dt, qa_dt ) - enddo - -! no clouds allowed above ktop - if ( ks < ktop ) then - do k=ks, ktop - do j=js,je - do i=is,ie -! qa(i,j,k) = 0. - qa_dt(i,j,k) = -qa(i,j,k) * rdt - enddo - enddo - enddo - endif - -#ifdef SIM_PHYS - if ( id_vtr> 0 ) used=send_data(id_vtr, vt_r, time) - if ( id_vts> 0 ) used=send_data(id_vts, vt_s, time) - if ( id_vtg> 0 ) used=send_data(id_vtg, vt_g, time) - if ( id_vti> 0 ) used=send_data(id_vti, vt_i, time) - if ( id_var> 0 ) used=send_data(id_var, w_var,time) -#else - if ( id_vtr> 0 ) used=send_data(id_vtr, vt_r, time, iis, jjs) - if ( id_vts> 0 ) used=send_data(id_vts, vt_s, time, iis, jjs) - if ( id_vtg> 0 ) used=send_data(id_vtg, vt_g, time, iis, jjs) - if ( id_vti> 0 ) used=send_data(id_vti, vt_i, time, iis, jjs) - if ( id_var> 0 ) used=send_data(id_var, w_var,time, iis, jjs) -#endif - -! Convert to mm/day - convt = 86400.*rdt*rgrav - do j=js,je - do i=is,ie - rain(i,j) = rain(i,j) * convt - snow(i,j) = snow(i,j) * convt - ice(i,j) = ice(i,j) * convt - graupel(i,j) = graupel(i,j) * convt - prec_mp(i,j) = rain(i,j) + snow(i,j) + ice(i,j) + graupel(i,j) - enddo - enddo - - if ( id_cond>0 ) then - do j=js,je - do i=is,ie - cond(i,j) = cond(i,j)*rgrav - enddo - enddo -#ifdef SIM_PHYS - used=send_data(id_cond, cond, time) -#else - used=send_data(id_cond, cond, time, iis, jjs) -#endif - endif - - if ( id_snow>0 ) then -#ifdef SIM_PHYS - used=send_data(id_snow, snow, time) -#else - used=send_data(id_snow, snow, time, iis, jjs) -#endif - if ( seconds==0 ) then - tot_prec = g_sum(snow, is, ie, js, je, ng, area, 1) - if(master) write(*,*) 'mean snow=', tot_prec - endif - snow0(:,:) = snow0(:,:) + snow(:,:) - endif - - if ( id_graupel>0 ) then -#ifdef SIM_PHYS - used=send_data(id_graupel, graupel, time) -#else - used=send_data(id_graupel, graupel, time, iis, jjs) -#endif - if ( seconds==0 ) then - tot_prec = g_sum(graupel, is, ie, js, je, ng, area, 1) - if(master) write(*,*) 'mean graupel=', tot_prec - endif - graupel0(:,:) = graupel0(:,:) + graupel(:,:) - endif - - if ( id_ice>0 ) then -#ifdef SIM_PHYS - used=send_data(id_ice, ice, time) -#else - used=send_data(id_ice, ice, time, iis, jjs) -#endif - if ( seconds==0 ) then - tot_prec = g_sum(ice, is, ie, js, je, ng, area, 1) - if(master) write(*,*) 'mean ice_mp=', tot_prec - endif - ice0(:,:) = ice0(:,:) + ice(:,:) - endif - - if ( id_rain>0 ) then -#ifdef SIM_PHYS - used=send_data(id_rain, rain, time) -#else - used=send_data(id_rain, rain, time, iis, jjs) -#endif - if ( seconds==0 ) then -! tot_prec = g_sum(rain, is, ie, js, je, ng, area, 1) -! if(master) write(*,*) 'mean rain=', tot_prec - endif - rain0(:,:) = rain0(:,:) + rain(:,:) - endif - - - if ( id_prec>0 ) then -#ifdef SIM_PHYS - used=send_data(id_prec, prec_mp, time) -#else - used=send_data(id_prec, prec_mp, time, iis, jjs) -#endif - endif - -!---------------------------------------------------------------------------- - - prec0(:,:) = prec0(:,:) + prec_mp(:,:) - prec1(:,:) = prec1(:,:) + prec_mp(:,:) - mp_count = mp_count + 1. - - if ( seconds==0 .and. mp_print ) then - tot_prec = g_sum(prec1*dt_in/86400., is, ie, js, je, ng, area, 1) - if(master) write(*,*) 'Daily prec_mp=', tot_prec -! call prt_maxmin('prec_mp', prec1*dt_in/86400., is, ie, js, je, 0, 1, 1., master) - prec1(:,:) = 0. - endif -!---------------------------------------------------------------------------- - - -!rab if ( mp_debug ) then -!rab call prt_maxmin('T_a_mp', pt, is, ie, js, je, 0, kbot, 1., master) -!rab call prt_maxmin('qg_dt_a_mp', qg_dt, is, ie, js, je, 0, kbot, 1., master) -!rab call prt_maxmin('prec', prec_mp, is, ie, js, je, 0, 1, 1., master) -!rab endif - - call mpp_clock_end (lin_cld_mp_clock) - - end subroutine lin_cld_microphys_driver - - - - subroutine mpdrv( delp, pt, qv, ql, qr, qi, qs, qg, qa, dz, & - is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, ntimes, & - rain, snow, graupel, ice, & - cond, area1, land, pt_dt, qv_dt, ql_dt, qr_dt, qi_dt, & - qs_dt, qg_dt, qa_dt ) - -!------------------------------------------------------------------- -! lin et al., 1983, jam, 1065-1092, and -! rutledge and hobbs, 1984, jas, 2949-2972 -!------------------------------------------------------------------- -! terminal fall is handled lagrangianly by conservative fv algorithm -! -! pt: temperature (k) -! 6 water species: -! 1) qv: water vapor (kg/kg) -! 2) ql: cloud water (kg/kg) -! 3) qr: rain (kg/kg) -! 4) qi: cloud ice (kg/kg) -! 5) qs: snow (kg/kg) -! 6) qg: graupel (kg/kg) - - integer, intent(in):: j, is,ie, js,je, ks,ke - integer, intent(in):: ntimes, ktop, kbot - real, intent(in):: dt_in - - real, intent(in), dimension(is:ie,js:je,ks:ke) :: delp - real, intent(in), dimension(is:ie):: area1, land - real, intent(in ), dimension(is:ie,js:je,ks:ke):: pt, qv, ql, qr, qi, qs, qg, qa, dz - real, intent(inout), dimension(is:ie,js:je,ks:ke):: pt_dt, qa_dt, & - qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt - real, intent(out), dimension(is:ie):: rain, snow, ice, graupel, cond -!---------- -! local var -!---------- - real, dimension(ktop:kbot):: qvz, qlz, qrz, qiz, qsz, qgz, qaz, & - vtiz, vtsz, vtgz, vtrz, & - dp1, qv0, ql0, qr0, qi0, qs0, qg0, qa0, t0, den, & - den0, tz, p1, dz0, dz1, denfac - - real :: r1, s1, i1, g1, rdt, omq - real :: cpaut, ccn, c_praut - real :: dt_rain - real :: h_var, s_leng, t_land, t_ocean - integer :: i,k,n -! real:: x, pexp -! pexp(x) = 1.+x*(1.+x*(0.5+x/6.*(1.+x*(0.25+0.05*x)))) - - dt_rain = dts * 0.5 - - rdt = 1. / dt_in - - cpaut = 0.55*0.104*grav/1.717e-5 - - do 2000 i=is, ie - - do k=ktop, kbot - t0(k) = pt(i,j,k) - tz(k) = t0(k) -!----------------------------------- - qvz(k) = max(qvmin, qv(i,j,k)) - qlz(k) = max(qvmin, ql(i,j,k)) - qrz(k) = max(qvmin, qr(i,j,k)) - qiz(k) = max(qvmin, qi(i,j,k)) - qsz(k) = max(qvmin, qs(i,j,k)) - qgz(k) = max(qvmin, qg(i,j,k)) -!----------------------------------- - qa0(k) = qa(i,j,k) - qaz(k) = 0. - dz0(k) = dz(i,j,k) -!-------------------------- - omq = 1. - (qvz(k)+qlz(k)+qrz(k)+qiz(k)+qsz(k)+qgz(k)) - dp1(k) = delp(i,j,k) * omq ! dry air mass * grav - den0(k) = -dp1(k)/(grav*dz0(k)) ! density of dry air - p1(k) = den0(k)*rdgas*t0(k) ! dry pressure -!------------------------------ -! convert to dry mixing ratios: -!------------------------------ - omq = 1. / omq - qvz(k) = qvz(k)*omq - qv0(k) = qvz(k) - qlz(k) = qlz(k)*omq - ql0(k) = qlz(k) - qrz(k) = qrz(k)*omq - qr0(k) = qrz(k) - qiz(k) = qiz(k)*omq - qi0(k) = qiz(k) - qsz(k) = qsz(k)*omq - qs0(k) = qsz(k) - qgz(k) = qgz(k)*omq - qg0(k) = qgz(k) - enddo - -! Compute dry pressure for non-hydrostatic case -!----------------------------------------------- -! if ( .not. phys_hydrostatic ) then -! do k=ktop, kbot -! p1(k) = den0(k)*rdgas*t0(k) -! enddo -! endif -!----------------------------------------------- - -! Based on Klein Eq. 15 - ccn = (ccn_l*land(i) + ccn_o*(1.-land(i))) * 1.e6 - if ( use_ccn ) then -! CCN is formulted as CCN = CCN_surface * (den/den_surface) - ccn = ccn * rdgas*tz(kbot)/p1(kbot) - endif - c_praut = cpaut * (ccn*rhor)**(-1./3.) - -!-------------------------------------------------------- -! Total water subgrid deviation in horizontal direction -!-------------------------------------------------------- -! default area dependent form: use dx ~ 100 km as the base - s_leng = sqrt(sqrt(area1(i)/1.E10)) - t_land = dw_land * s_leng - t_ocean = dw_ocean * s_leng - h_var = t_land*land(i) + t_ocean*(1.-land(i)) - h_var = min(0.22, max(0.001, h_var)) ! cap: - if ( id_var>0 ) w_var(i,j) = h_var - - rh_adj = 1. - h_var - rh_inc - -!------------------------- -! * fix all negatives -!------------------------- - - call neg_adj(ktop, kbot, p1, tz, dp1, qvz, qlz, qrz, qiz, qsz, qgz) - - do 1000 n=1,ntimes - - do k=ktop, kbot - dz1(k) = dz0(k)*tz(k)/t0(k) - den(k) = den0(k)*dz0(k)/dz1(k) - denfac(k) = sqrt(sfcrho/den(k)) - enddo - -!------------------------------------------- -! Time-split warm rain processes: first pass -!------------------------------------------- -! call timing_on (" warm_rain") - call warm_rain(dt_rain, ktop, kbot, p1, dp1, dz1, tz, qvz, qlz, qrz, p1, den, denfac, ccn, c_praut, h_var, vtrz, r1) -! call timing_off(" warm_rain") - rain(i) = rain(i) + r1 - -!------------------------------------------------ -! * sedimentation of cloud ice, snow, and graupel -!------------------------------------------------ -! call timing_on (" terminal_fall") - call fall_speed(ktop, kbot, den, qsz, qiz, qgz, qlz, tz, vtsz, vtiz, vtgz) - - call terminal_fall ( dts, ktop, kbot, tz, qvz, qlz, qrz, qgz, qsz, qiz, p1, & - dz1, dp1, den, vtgz, vtsz, vtiz, & - r1, g1, s1, i1 ) -! call timing_off(" terminal_fall") - - rain(i) = rain(i) + r1 ! from melted snow & ice that reached the ground - snow(i) = snow(i) + s1 - graupel(i) = graupel(i) + g1 - ice(i) = ice(i) + i1 - -!------------------------------------------- -! Time-split warm rain processes: 2nd pass -!------------------------------------------- -! call timing_on (" warm_rain") - call warm_rain(dt_rain, ktop, kbot, p1, dp1, dz1, tz, qvz, qlz, qrz, p1, den, denfac, ccn, c_praut, h_var, vtrz, r1) -! call timing_off(" warm_rain") - rain(i) = rain(i) + r1 - -!------------------------- -! * ice-phase microphysics -!------------------------- - -! call timing_on (" icloud") - call icloud( ktop, kbot, tz, p1, qvz, qlz, qrz, qiz, qsz, qgz, & - dp1, den, denfac, vtsz, vtgz, vtrz, qaz, h_var ) -! call timing_off(" icloud") -1000 continue ! sub-cycle - - do k = ktop, kbot - omq = dp1(k) / delp(i,j,k) - pt_dt(i,j,k) = pt_dt(i,j,k) + rdt*(tz(k)- t0(k)) *omq - qv_dt(i,j,k) = qv_dt(i,j,k) + rdt*(qvz(k)-qv0(k))*omq - ql_dt(i,j,k) = ql_dt(i,j,k) + rdt*(qlz(k)-ql0(k))*omq - qr_dt(i,j,k) = qr_dt(i,j,k) + rdt*(qrz(k)-qr0(k))*omq - qi_dt(i,j,k) = qi_dt(i,j,k) + rdt*(qiz(k)-qi0(k))*omq - qs_dt(i,j,k) = qs_dt(i,j,k) + rdt*(qsz(k)-qs0(k))*omq - qg_dt(i,j,k) = qg_dt(i,j,k) + rdt*(qgz(k)-qg0(k))*omq - qa_dt(i,j,k) = qa_dt(i,j,k) + rdt*( qaz(k)/real(ntimes)-qa0(k)) -! dz(i,j,k) = dz1(k) - enddo - -!----------------- -! fms diagnostics: -!----------------- - - if ( id_cond>0 ) then - do k=ktop,kbot ! total condensate - cond(i) = cond(i) + dp1(k)*(qlz(k)+qrz(k)+qsz(k)+qiz(k)+qgz(k)) - enddo - endif - - if ( id_vtr> 0 ) then - do k=ktop, kbot - vt_r(i,j,k) = vtrz(k) - enddo - endif - if ( id_vts> 0 ) then - do k=ktop, kbot - vt_s(i,j,k) = vtsz(k) - enddo - endif - if ( id_vtg> 0 ) then - do k=ktop, kbot - vt_g(i,j,k) = vtgz(k) - enddo - endif - if ( id_vts> 0 ) then - do k=ktop, kbot - vt_i(i,j,k) = vtiz(k) - enddo - endif - -2000 continue - - end subroutine mpdrv - - - - subroutine warm_rain( dt, ktop, kbot, p1, dp, dz, tz, qv, ql, qr, pm, & - den, denfac, ccn, c_praut, h_var, vtr, r1) - - integer, intent(in):: ktop, kbot - real, intent(in):: dt ! time step (s) - real, intent(in), dimension(ktop:kbot):: p1, dp, dz, pm, den, denfac - real, intent(in):: ccn, c_praut, h_var - real, intent(inout), dimension(ktop:kbot):: tz, qv, ql, qr, vtr - real, intent(out):: r1 - -! local: - real, parameter:: so3 = 7./3. - real, dimension(ktop:kbot):: dl - real, dimension(ktop:kbot+1):: ze, zt - real:: sink, dq, qc0, qc, q_plus, q_minus - real:: rho0, qden - real:: zs = 0. - real:: dt5 - integer k -!----------------------------------------------------------------------- -! fall velocity constants: -!----------------------------------------------------------------------- - real, parameter :: vconr = 2503.23638966667 - real, parameter :: normr = 25132741228.7183 - real, parameter :: thr=1.e-10 - logical no_fall - -!--------------------- -! warm-rain processes: -!--------------------- - - dt5 = 0.5*dt - -!------------------------ -! Terminal speed of rain: -!------------------------ - - call check_column(ktop, kbot, qr, no_fall) - if ( no_fall ) then - vtr(:) = vmin - r1 = 0. - go to 999 ! jump to auto-conversion - endif - - if ( den_ref < 0. ) then - rho0 = -den_ref*den(kbot) - else - rho0 = den_ref ! default=1.2 - endif - - do k=ktop, kbot - qden = qr(k)*den(k) - if ( qr(k) < thr ) then - vtr(k) = vmin - else - vtr(k) = max(vmin, vr_fac*vconr*sqrt(min(10., rho0/den(k)))*exp(0.2*log(qden/normr))) - endif - enddo - - ze(kbot+1) = zs - do k=kbot, ktop, -1 - ze(k) = ze(k+1) - dz(k) ! dz<0 - enddo - zt(ktop) = ze(ktop) - - - do k=ktop+1,kbot - zt(k) = ze(k) - dt5*(vtr(k-1)+vtr(k)) - enddo - zt(kbot+1) = zs - dt*vtr(kbot) - - do k=ktop,kbot - if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min - enddo - -! Evap_acc of rain for 1/2 time step - call revap_racc( ktop, kbot, dt5, tz, qv, ql, qr, pm, den, denfac, h_var ) - - if ( ppm_rain_fall ) then - call lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, qr, r1, mono_prof) - else - call lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, qr, r1) - endif - -! Finish the remaing 1/2 time step - call revap_racc( ktop, kbot, dt5, tz, qv, ql, qr, pm, den, denfac, h_var ) - -999 continue - -!------------------- -! * auto-conversion -!------------------- -! Assuming linear subgrid vertical distribution of cloud water -! following Lin et al. 1994, MWR - - call linear_prof( kbot-ktop+1, p1(ktop), ql(ktop), dl(ktop), z_slope, h_var ) - - qc0 = fac_rc*ccn - -! * Auto conversion - - do k=ktop,kbot - if ( tz(k) > t_wfr ) then -!---------------------------------------------------------------- -! As in Klein's GFDL AM2 stratiform scheme. -!---------------------------------------------------------------- - dl(k) = max( qrmin, dl(k) ) - q_plus = ql(k) + dl(k) - if ( use_ccn ) then -! CCN is formulted as CCN = CCN_surface * (den/den_surface) - qc = qc0 - else - qc = qc0/den(k) - endif - if ( q_plus > qc ) then - sink = dt*c_praut*den(k) - q_minus = ql(k) - dl(k) - if ( qc > q_minus ) then - dq = 0.25*(q_plus-qc)**2 / dl(k) -! autoconversion rate computed using average of qc and q_plus - sink = min(dq, sink*(q_plus-qc)/(2.*dl(k))*(0.5*(qc+q_plus))**so3) - else ! qc < q_minus - sink = min(ql(k)-qc, sink*ql(k)**so3) - endif - ql(k) = ql(k) - sink - qr(k) = qr(k) + sink - endif - endif - enddo - - - end subroutine warm_rain - - - subroutine revap_racc( ktop, kbot, dt, tz, qv, ql, qr, pm, den, denfac, h_var ) - integer, intent(in):: ktop, kbot - real, intent(in):: dt ! time step (s) - real, intent(in), dimension(ktop:kbot):: pm, den, denfac - real, intent(in) :: h_var - real, intent(inout), dimension(ktop:kbot):: tz, qv, qr, ql -! local: - real:: qsat, dqsdt, evap, tsq, qden, q_plus, q_minus, sink - real:: qpz, dq, dqh, tin - integer k - - do k=ktop,kbot - if ( tz(k) > t_wfr ) then - if ( qr(k) > qrmin ) then - qden = qr(k)*den(k) - tin = tz(k) - lcp*ql(k) ! presence of clouds suppresses the rain evap - qsat = ws1d(tin, pm(k), dqsdt) - qpz = qv(k) + ql(k) - dqh = h_var*max(qpz, qvmin) - q_minus = qpz - dqh - q_plus = qpz + dqh - -! qsat must be > q_minus to activate evaporation -! qsat must be < q_plus to activate accretion - -!------------------- -! * Rain evaporation -!------------------- - if ( qsat > q_minus ) then - if ( qsat > q_plus ) then - dq = qsat - qpz - else -! q_minus < qsat < q_plus -! dq == dqh if qsat == q_minus - dq = 0.25*(q_minus-qsat)**2 / dqh - endif - tsq = tin*tin - evap = crevp(1)*tsq*dq*(crevp(2)*sqrt(qden)+crevp(3)*exp(0.725*log(qden))) & - / (crevp(4)*tsq + crevp(5)*qsat*den(k)) - evap = min( qr(k), dt*evap, dq/(1.+lcp*dqsdt) ) - qr(k) = qr(k) - evap - qv(k) = qv(k) + evap - tz(k) = tz(k) - evap*lcp - endif - -!------------------- -! * Accretion: pracc -!------------------- -! if ( ql(k)>1.E-8 .and. qsat ! -subroutine physics_driver_init (Time, lonb, latb, axes, pref, & +!-->cjg +!subroutine physics_driver_init (Time, lonb, latb, axes, pref, & +subroutine physics_driver_init (Time, lonb, latb, lon, lat, axes, pref, & trs, Surf_diff, phalf, mask, kbot, & diffm, difft ) - +!<--cjg !--------------------------------------------------------------------- ! physics_driver_init is the constructor for physics_driver_mod. !--------------------------------------------------------------------- type(time_type), intent(in) :: Time real,dimension(:,:), intent(in) :: lonb, latb +real,dimension(:,:), intent(in) :: lon, lat ! cjg integer,dimension(4), intent(in) :: axes real,dimension(:,:), intent(in) :: pref real,dimension(:,:,:,:), intent(inout) :: trs @@ -595,6 +639,9 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & integer :: id, jd, kd, n integer :: ierr, io, unit, logunit, outunit integer :: ndum + character(len=16):: cloud_type_form_out ! indicator of radiatively + ! active clouds + character(len=16):: cosp_precip_sources_modified integer :: moist_processes_init_clock, damping_init_clock, & turb_init_clock, diff_init_clock, & @@ -732,15 +779,20 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & !----------------------------------------------------------------------- call mpp_clock_begin ( moist_processes_init_clock ) - call moist_processes_init (id, jd, kd, lonb, latb, pref(:,1),& + +!---> h1g +! call moist_processes_init (id, jd, kd, lonb, latb, pref(:,1),& + call moist_processes_init (id, jd, kd, lonb, latb, lon, lat, phalf, pref(:,1),& axes, Time, doing_donner, & doing_uw_conv, & num_uw_tracers, do_strat, & + do_clubb_in=do_clubb, &! cjg do_cosp_in=do_cosp, & donner_meso_is_largescale_in= & donner_meso_is_largescale, & include_donmca_in_cosp_out = & include_donmca_in_cosp) +!<--- h1g call mpp_clock_end ( moist_processes_init_clock ) @@ -757,14 +809,17 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & !----------------------------------------------------------------------- call mpp_clock_begin ( turb_init_clock ) call vert_turb_driver_init (lonb, latb, id, jd, kd, axes, Time, & - doing_edt, doing_entrain) + doing_edt, doing_entrain, do_clubb) call mpp_clock_end ( turb_init_clock ) !----------------------------------------------------------------------- ! initialize vert_diff_driver_mod. !----------------------------------------------------------------------- call mpp_clock_begin ( diff_init_clock ) - call vert_diff_driver_init (Surf_diff, id, jd, kd, axes, Time ) +!-->cjg +! call vert_diff_driver_init (Surf_diff, id, jd, kd, axes, Time ) + call vert_diff_driver_init (Surf_diff, id, jd, kd, axes, Time, do_clubb ) +!<--cjg call mpp_clock_end ( diff_init_clock ) if (do_radiation) then @@ -772,7 +827,16 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & ! initialize cloud_spec_mod. !----------------------------------------------------------------------- call mpp_clock_begin ( cloud_spec_init_clock ) - call cloud_spec_init (pref, lonb, latb, axes, Time) + call cloud_spec_init (pref, lonb, latb, axes, Time, & + cloud_type_form_out) + if (trim(cosp_precip_sources) == ' ') then + cosp_precip_sources_modified = cloud_type_form_out + else + cosp_precip_sources_modified = cosp_precip_sources + if (trim(cloud_type_form_out) /= trim(cosp_precip_sources)) & + call error_mesg ('physics_driver_init', & + 'cloud_type_form does not match cosp_precip_sources', NOTE) + endif call mpp_clock_end ( cloud_spec_init_clock ) !----------------------------------------------------------------------- @@ -793,6 +857,7 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & !----------------------------------------------------------------------- call mpp_clock_begin ( radiation_init_clock ) call radiation_driver_init (lonb, latb, pref, axes, time, & + donner_meso_is_largescale, & aerosol_names, & aerosol_family_names, do_cosp, ncol) call mpp_clock_end ( radiation_init_clock ) @@ -840,6 +905,18 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & allocate ( lw_tendency(id, jd, kd)) ; lw_tendency = 0.0 allocate ( r_convect (id, jd) ) ; r_convect = 0.0 +! ---> h1g, cjg + if (do_clubb > 0 ) then + allocate ( dcond_ls_liquid(id, jd, kd) ); dcond_ls_liquid = 0.0 + allocate ( dcond_ls_ice(id, jd, kd) ); dcond_ls_ice = 0.0 + allocate ( Ndrop_act_CLUBB(id, jd, kd) ); Ndrop_act_CLUBB = 0.0 + allocate ( Icedrop_act_CLUBB(id, jd, kd) ); Icedrop_act_CLUBB = 0.0 + allocate ( ndust(id, jd, kd) ); ndust = 0.0 + allocate ( rbar_dust(id, jd, kd) ); rbar_dust = 0.0 + allocate ( diff_t_clubb(id, jd, kd) ); diff_t_clubb = 0.0 + end if +! <--- h1g, cjg + !-------------------------------------------------------------------- ! these variables needed to preserve rain fluxes, q and T from end ! of one step for use in COSP simulator on next step. @@ -1061,11 +1138,14 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & 'temperature tendency from physics ', & 'K/s', missing_value=missing_value) - id_qdt_phys = register_diag_field ( mod_name, & - 'qdt_phys', axes(1:3), Time, & - 'specific humidity tendency from physics ', & - 'kg/kg/s', missing_value=missing_value) - +!-->cjg +! id_qdt_phys = register_diag_field ( mod_name, & +! 'qdt_phys', axes(1:3), Time, & +! 'specific humidity tendency from physics ', & +! 'kg/kg/s', missing_value=missing_value) +!<--cjg + + allocate (id_tracer_phys(nt)) ! cjg allocate (id_tracer_phys_vdif_dn(nt)) allocate (id_tracer_phys_vdif_up(nt)) allocate (id_tracer_phys_turb(nt)) @@ -1075,7 +1155,17 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & call get_tracer_names (MODEL_ATMOS, n, name = tracer_name, & units = tracer_units) - +!-->cjg + diaglname = trim(tracer_name)// & + ' tendency from physics' + id_tracer_phys(n) = & + register_diag_field ( mod_name, & + TRIM(tracer_name)//'_phys', & + axes(1:3), Time, trim(diaglname), & + TRIM(tracer_units)//'/s', & + missing_value=missing_value) +!<--cjg + diaglname = trim(tracer_name)// & ' tendency from physics driver vdif down' id_tracer_phys_vdif_dn(n) = & @@ -1120,6 +1210,7 @@ subroutine physics_driver_init (Time, lonb, latb, axes, pref, & if (do_cosp) then call mpp_clock_begin ( cosp_init_clock ) call cosp_driver_init (lonb, latb, Time, axes, kd, ncol) + call set_cosp_precip_sources (cosp_precip_sources_modified) call mpp_clock_end ( cosp_init_clock ) endif @@ -1208,6 +1299,7 @@ subroutine physics_driver_down_time_vary (Time, Time_next, gavg_rrv, dt) call damping_driver_time_vary (dt) call atmos_tracer_driver_time_vary (Time) + !------------------------------------------------------------------------- end subroutine physics_driver_down_time_vary @@ -1245,7 +1337,7 @@ end subroutine physics_driver_down_endts !################################################################### -subroutine physics_driver_up_time_vary (Time, dt) +subroutine physics_driver_up_time_vary (Time, Time_next, dt) !--------------------------------------------------------------------- ! physics_driver_up_time_vary makes sure that all time-dependent, @@ -1255,10 +1347,13 @@ subroutine physics_driver_up_time_vary (Time, dt) !----------------------------------------------------------------------- type(time_type), intent(in) :: Time +type(time_type), intent(in) :: Time_next real, intent(in) :: dt + call aerosol_time_vary (Time) call moist_processes_time_vary (dt) + if (do_cosp) call cosp_driver_time_vary (Time_next) !---------------------------------------------------------------------- @@ -1271,6 +1366,7 @@ subroutine physics_driver_up_endts (is,js) integer, intent(in) :: is,js + if (do_cosp) call cosp_driver_endts call moist_processes_endts (is,js) call aerosol_endts @@ -1279,13 +1375,22 @@ end subroutine physics_driver_up_endts !##################################################################### -subroutine physics_driver_moist_init (ix,jx,kx,lx) +!--> cjg: code modification to allow diagnostic tracers in physics_up (20120508) +! +!subroutine physics_driver_moist_init (ix,jx,kx,lx) +! +!integer, intent(in) :: ix,jx, kx, lx +! +! call moist_alloc_init (ix,jx,kx,lx) + +subroutine physics_driver_moist_init (ix,jx,kx,lx,mx) -integer, intent(in) :: ix,jx, kx, lx +integer, intent(in) :: ix,jx, kx, lx, mx - call moist_alloc_init (ix,jx,kx,lx) + call moist_alloc_init (ix,jx,kx,lx,mx) +!<--cjg call moistproc_init (ix,jx,kx, num_uw_tracers, do_strat) end subroutine physics_driver_moist_init @@ -2374,6 +2479,7 @@ subroutine physics_driver_down (is, ie, js, je, & dtau_du, dtau_dv, tau_x, tau_y, & udt, vdt, tdt, qdt, rdt, & Surf_diff, & + diff_t_clubb=diff_t_clubb(is:ie,js:je,:), & ! cjg mask=mask, kbot=kbot ) if (id_tdt_phys_vdif_dn > 0) then @@ -2555,7 +2661,7 @@ subroutine physics_driver_up (is, ie, js, je, & z_half, z_full, & u , v , t , q , & um, vm, tm, qm -real,dimension(:,:,:,:),intent(in) :: r,rm +real,dimension(:,:,:,:),intent(inout) :: r,rm ! cjg: inout real,dimension(:,:), intent(in) :: frac_land real,dimension(:,:), intent(in) :: u_star, b_star, q_star real,dimension(:,:,:), intent(inout) :: udt,vdt,tdt,qdt @@ -2660,7 +2766,12 @@ subroutine physics_driver_up (is, ie, js, je, & integer :: flag_ls, flag_cc integer :: kmax logical :: used - + +! ---> h1g, 2012-08-28, +! save the temperature and moisture tendencies from sensible and latent heat fluxes + real, dimension(size(t,1), size(t,2)) :: tdt_shf, qdt_lhf +! <--- h1g, 2012-08-28 + !--------------------------------------------------------------------- ! local variables: ! @@ -2710,10 +2821,28 @@ subroutine physics_driver_up (is, ie, js, je, & endif end do +! ---> h1g, 2012-08-28, save temperature and moisture tendencies due to surface fluxes at lowest-level + if( .not. l_host_applies_sfc_fluxes ) then + tdt_shf(:,:) = tdt(:, :, kmax) + qdt_lhf(:,:) = qdt(:, :, kmax) + endif +! <--- h1g, 2012-08-28 + call mpp_clock_begin ( diff_up_clock ) call vert_diff_driver_up (is, js, Time_next, dt, p_half, & Surf_diff, tdt, qdt, rdt, mask=mask, & kbot=kbot) + +! ---> h1g, 2012-08-28, save temperature and moisture tendencies due to surface fluxes at lowest-level + if( .not. l_host_applies_sfc_fluxes ) then + tdt_shf(:,:) = tdt(:, :, kmax) - tdt_shf(:,:) + qdt_lhf(:,:) = qdt(:, :, kmax) - qdt_lhf(:,:) + + tdt(:, :, kmax) = tdt(:, :, kmax) - tdt_shf(:,:) + qdt(:, :, kmax) = qdt(:, :, kmax) - qdt_lhf(:,:) + endif +! <--- h1g, 2012-08-28 + radturbten(is:ie,js:je,:) = radturbten(is:ie,js:je,:) + tdt(:,:,:) call mpp_clock_end ( diff_up_clock ) @@ -2791,7 +2920,7 @@ subroutine physics_driver_up (is, ie, js, je, & fprec, fl_lsrain(is:ie,js:je,:), fl_lssnow(is:ie,js:je,:), & fl_ccrain(is:ie,js:je,:), fl_ccsnow(is:ie,js:je,:), & fl_donmca_rain(is:ie,js:je,:), fl_donmca_snow(is:ie,js:je,:), & - gust_cv, area, lat, lsc_cloud_area(is:ie,js:je,:), & + gust_cv, area, lon, lat, lsc_cloud_area(is:ie,js:je,:), & lsc_liquid(is:ie,js:je,:), lsc_ice(is:ie,js:je,:), & lsc_droplet_number(is:ie,js:je,:), & lsc_ice_number(is:ie,js:je,:), & @@ -2800,7 +2929,15 @@ subroutine physics_driver_up (is, ie, js, je, & lsc_rain(is:ie,js:je,:), & lsc_snow_size(is:ie,js:je,:), & lsc_rain_size(is:ie,js:je,:), & - Aerosol, mask=mask, & +! ---> h1g + dcond_ls_liquid=dcond_ls_liquid, dcond_ls_ice=dcond_ls_ice, & + Ndrop_act_CLUBB=Ndrop_act_CLUBB, Icedrop_act_CLUBB=Icedrop_act_CLUBB, & + ndust=ndust, rbar_dust= rbar_dust, & + diff_t_clubb =diff_t_clubb, & + tdt_shf = tdt_shf, & + qdt_lhf = qdt_lhf, & +! <--- h1g + Aerosol=Aerosol, mask=mask, & kbot=kbot, shallow_cloud_area=shallow_cloud_area(is:ie,js:je,:), & shallow_liquid=shallow_liquid(is:ie,js:je,:), & shallow_ice= shallow_ice(is:ie,js:je,:), & @@ -2835,7 +2972,7 @@ subroutine physics_driver_up (is, ie, js, je, & fl_lsrain(is:ie,js:je,:), fl_lssnow(is:ie,js:je,:), & fl_ccrain(is:ie,js:je,:), fl_ccsnow(is:ie,js:je,:), & fl_donmca_rain(is:ie,js:je,:), fl_donmca_snow(is:ie,js:je,:), & - gust_cv, area, lat, & + gust_cv, area, lon, lat, & lsc_cloud_area(is:ie,js:je,:), & lsc_liquid(is:ie,js:je,:), & lsc_ice(is:ie,js:je,:), & @@ -2846,8 +2983,15 @@ subroutine physics_driver_up (is, ie, js, je, & lsc_rain(is:ie,js:je,:), & lsc_snow_size(is:ie,js:je,:), & lsc_rain_size(is:ie,js:je,:), & - - Aerosol, mask=mask, kbot=kbot, & +! ---> h1g + dcond_ls_liquid=dcond_ls_liquid, dcond_ls_ice=dcond_ls_ice, & + Ndrop_act_CLUBB=Ndrop_act_CLUBB, Icedrop_act_CLUBB=Icedrop_act_CLUBB, & + ndust=ndust, rbar_dust= rbar_dust, & + diff_t_clubb =diff_t_clubb, & + tdt_shf = tdt_shf, & + qdt_lhf = qdt_lhf, & +! <--- h1g + Aerosol=Aerosol, mask=mask, kbot=kbot, & cell_cld_frac= cell_cld_frac(is:ie,js:je,:), & cell_liq_amt=cell_liq_amt(is:ie,js:je,:), & cell_liq_size=cell_liq_size(is:ie,js:je,:), & @@ -2878,7 +3022,7 @@ subroutine physics_driver_up (is, ie, js, je, & fl_lsrain(is:ie,js:je,:), fl_lssnow(is:ie,js:je,:), & fl_ccrain(is:ie,js:je,:), fl_ccsnow(is:ie,js:je,:), & fl_donmca_rain(is:ie,js:je,:), fl_donmca_snow(is:ie,js:je,:), & - gust_cv, area, lat, & + gust_cv, area, lon, lat, & lsc_cloud_area(is:ie,js:je,:), & lsc_liquid(is:ie,js:je,:), & lsc_ice(is:ie,js:je,:), & @@ -2889,7 +3033,15 @@ subroutine physics_driver_up (is, ie, js, je, & lsc_rain(is:ie,js:je,:), & lsc_snow_size(is:ie,js:je,:), & lsc_rain_size(is:ie,js:je,:), & - Aerosol, mask=mask, kbot= kbot, & +! ---> h1g + dcond_ls_liquid=dcond_ls_liquid, dcond_ls_ice=dcond_ls_ice, & + Ndrop_act_CLUBB=Ndrop_act_CLUBB, Icedrop_act_CLUBB=Icedrop_act_CLUBB, & + ndust=ndust, rbar_dust= rbar_dust, & + diff_t_clubb =diff_t_clubb, & + tdt_shf = tdt_shf, & + qdt_lhf = qdt_lhf, & +! <--- h1g + Aerosol=Aerosol, mask=mask, kbot= kbot, & shallow_cloud_area= shallow_cloud_area(is:ie,js:je,:), & shallow_liquid=shallow_liquid(is:ie,js:je,:), & shallow_ice= shallow_ice(is:ie,js:je,:), & @@ -2912,7 +3064,7 @@ subroutine physics_driver_up (is, ie, js, je, & fl_lsrain(is:ie,js:je,:), fl_lssnow(is:ie,js:je,:), & fl_ccrain(is:ie,js:je,:), fl_ccsnow(is:ie,js:je,:), & fl_donmca_rain(is:ie,js:je,:), fl_donmca_snow(is:ie,js:je,:), & - gust_cv, area, lat, & + gust_cv, area, lon, lat, & lsc_cloud_area(is:ie,js:je,:), & lsc_liquid(is:ie,js:je,:), & lsc_ice(is:ie,js:je,:), & @@ -2923,8 +3075,15 @@ subroutine physics_driver_up (is, ie, js, je, & lsc_rain(is:ie,js:je,:), & lsc_snow_size(is:ie,js:je,:), & lsc_rain_size(is:ie,js:je,:), & - - Aerosol, mask=mask, kbot=kbot, & +! ---> h1g + dcond_ls_liquid=dcond_ls_liquid, dcond_ls_ice=dcond_ls_ice, & + Ndrop_act_CLUBB=Ndrop_act_CLUBB, Icedrop_act_CLUBB=Icedrop_act_CLUBB, & + ndust=ndust, rbar_dust= rbar_dust, & + diff_t_clubb =diff_t_clubb, & + tdt_shf = tdt_shf, & + qdt_lhf = qdt_lhf, & +! <--- h1g + Aerosol=Aerosol, mask=mask, kbot=kbot, & hydrostatic=hydrostatic, phys_hydrostatic=phys_hydrostatic ) endif call mpp_clock_end ( moist_processes_clock ) @@ -2953,10 +3112,18 @@ subroutine physics_driver_up (is, ie, js, je, & used = send_data ( id_tdt_phys, tdt(:,:,:), & Time_next, is, js, 1, rmask=mask ) endif - if (id_qdt_phys > 0) then - used = send_data ( id_qdt_phys, qdt(:,:,:), & - Time_next, is, js, 1, rmask=mask ) - endif +!--> cjg +! if (id_qdt_phys > 0) then +! used = send_data ( id_qdt_phys, qdt(:,:,:), & +! Time_next, is, js, 1, rmask=mask ) +! endif + do n=1,nt + if (id_tracer_phys(n) > 0) then + used = send_data ( id_tracer_phys(n), rdt(:,:,:,n), & + Time_next, is, js, 1, rmask=mask ) + endif + end do +!<--cjg endif ! do_moist_processes @@ -3010,8 +3177,8 @@ subroutine physics_driver_up (is, ie, js, je, & ! to mixing ratios. !-------------------------------------------------------------------- do k=1, size(stoch_cloud_type,3) - do j=1, size(stoch_cloud_type,2) - do i=1, size(stoch_cloud_type,1) + do j=1, size(t,2) + do i=1, size(t,1) rhoi(i,j,k) = RDGAS*temp_last(i+is-1,j+js-1,k)/ & p_full(i,j,k) end do @@ -3024,8 +3191,8 @@ subroutine physics_driver_up (is, ie, js, je, & !-------------------------------------------------------------------- do n=1,ncol do k=1, size(stoch_cloud_type,3) - do j=1, size(stoch_cloud_type,2) - do i=1, size(stoch_cloud_type,1) + do j=1, size(t,2) + do i=1, size(t,1) stoch_mr_liq(i,j,k,n) = 1.0e-03* & stoch_conc_drop(i+is-1,j+js-1,k,n)*rhoi(i,j,k) stoch_mr_ice(i,j,k,n) = 1.0e-03* & @@ -3058,8 +3225,8 @@ subroutine physics_driver_up (is, ie, js, je, & reff_ccprliq = 0. reff_ccprice = 0. do k=1, size(stoch_cloud_type,3) - do j=1, size(stoch_cloud_type,2) - do i=1, size(stoch_cloud_type,1) + do j=1, size(t,2) + do i=1, size(t,1) nls = 0 ncc = 0 do n=1,ncol @@ -3129,8 +3296,8 @@ subroutine physics_driver_up (is, ie, js, je, & ! allow ls precip only in columns containing ls cloud. allow ! convective precip only in columns with convective cloud, !-------------------------------------------------------------------- - do j=1, size(stoch_cloud_type,2) - do i=1, size(stoch_cloud_type,1) + do j=1, size(t,2) + do i=1, size(t,1) flag_ls = 0 flag_cc = 0 do k=1, size(stoch_cloud_type,3) @@ -3248,6 +3415,14 @@ subroutine physics_driver_end (Time) grey_radiation_term_clock, radiative_gases_term_clock, & radiation_term_clock, tracer_term_clock, cosp_term_clock +! ---> h1g +integer :: clubb_term_clock +!-------------------------------------------------------------------- + clubb_term_clock = & + mpp_clock_id( ' Phys_driver_term: clubb: Termination', & + grain=CLOCK_MODULE_DRIVER ) +! <--- h1g + moist_processes_term_clock = & mpp_clock_id( ' Phys_driver_term: MP: Termination', & grain=CLOCK_MODULE_DRIVER ) @@ -3321,7 +3496,7 @@ subroutine physics_driver_end (Time) call mpp_clock_end ( grey_radiation_term_clock ) call mpp_clock_begin ( moist_processes_term_clock ) - call moist_processes_end + call moist_processes_end( clubb_term_clock ) call mpp_clock_end ( moist_processes_term_clock ) call mpp_clock_begin ( tracer_term_clock ) call atmos_tracer_driver_end @@ -3346,6 +3521,16 @@ subroutine physics_driver_end (Time) deallocate (lsc_cloud_area, lsc_liquid, lsc_ice, & lsc_droplet_number, lsc_ice_number) deallocate (lsc_snow, lsc_rain, lsc_snow_size, lsc_rain_size) + if (do_clubb > 0) then + deallocate ( dcond_ls_liquid ) + deallocate ( dcond_ls_ice ) + deallocate ( Ndrop_act_CLUBB ) + deallocate ( Icedrop_act_CLUBB ) + deallocate ( ndust ) + deallocate ( rbar_dust ) + deallocate ( diff_t_clubb ) + end if + if (doing_donner) then deallocate (cell_cld_frac, cell_liq_amt, cell_liq_size, & cell_ice_amt, cell_ice_size, cell_droplet_number, & @@ -3609,6 +3794,11 @@ subroutine physics_driver_register_restart id_restart = register_restart_field(Til_restart, fname, 'cbmf', cbmf, mandatory = .false.) id_restart = register_restart_field(Til_restart, fname, 'diff_t', diff_t) id_restart = register_restart_field(Til_restart, fname, 'diff_m', diff_m) +!-->cjg + if (do_clubb > 0) then + id_restart = register_restart_field(Til_restart, fname, 'diff_t_clubb', diff_t_clubb, mandatory = .false.) + end if +!<--cjg id_restart = register_restart_field(Til_restart, fname, 'convect', r_convect) if (doing_strat()) then id_restart = register_restart_field(Til_restart, fname, 'radturbten', radturbten) diff --git a/src/atmos_param/radiation_driver/radiation_driver.F90 b/src/atmos_param/radiation_driver/radiation_driver.F90 index 781dfed379..9928f05057 100644 --- a/src/atmos_param/radiation_driver/radiation_driver.F90 +++ b/src/atmos_param/radiation_driver/radiation_driver.F90 @@ -226,8 +226,8 @@ module radiation_driver_mod !---------------------------------------------------------------------- !------------ version number for this module -------------------------- -character(len=128) :: version = '$Id: radiation_driver.F90,v 18.0.2.1.2.2.2.1.2.1.6.1.2.1.4.1.2.1 2012/04/04 15:06:36 z1l Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: radiation_driver.F90,v 20.0 2013/12/13 23:18:44 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -1095,6 +1095,7 @@ module radiation_driver_mod ! ! subroutine radiation_driver_init (lonb, latb, pref, axes, Time, & + donner_meso_is_largescale, & aerosol_names, aerosol_family_names,& do_cosp, ncol) @@ -1107,6 +1108,7 @@ subroutine radiation_driver_init (lonb, latb, pref, axes, Time, & real, dimension(:,:), intent(in) :: pref integer, dimension(4), intent(in) :: axes type(time_type), intent(in) :: Time +logical, intent(in) :: donner_meso_is_largescale character(len=*), dimension(:), intent(in) :: aerosol_names character(len=*), dimension(:), intent(in) :: aerosol_family_names logical, intent(in) :: do_cosp @@ -2021,7 +2023,8 @@ subroutine radiation_driver_init (lonb, latb, pref, axes, Time, & !--------------------------------------------------------------------- call sea_esf_rad_init (lonb, latb, pref(ks:ke+1,:)) call cloudrad_package_init (pref(ks:ke+1,:), lonb, latb, & - axes, Time) + axes, Time, & + donner_meso_is_largescale) call aerosolrad_package_init (kmax, aerosol_names, lonb, latb) call rad_output_file_init (axes, Time, aerosol_names, & aerosol_family_names) diff --git a/src/atmos_param/ras/ras.F90 b/src/atmos_param/ras/ras.F90 index 3b1d31615a..3fb25b99fa 100644 --- a/src/atmos_param/ras/ras.F90 +++ b/src/atmos_param/ras/ras.F90 @@ -42,7 +42,7 @@ MODULE RAS_MOD ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% character(len=128) :: version = '$Id: ras.F90,v 19.0 2012/01/06 20:11:58 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% real :: cp_div_grav diff --git a/src/atmos_param/rh_clouds/null/rh_clouds.F90 b/src/atmos_param/rh_clouds/null/rh_clouds.F90 deleted file mode 100644 index de62f2d04c..0000000000 --- a/src/atmos_param/rh_clouds/null/rh_clouds.F90 +++ /dev/null @@ -1,179 +0,0 @@ - -module rh_clouds_mod - -!======================================================================= -! -! RH_CLOUDS MODULE -! -!======================================================================= - -use fms_mod, only: error_mesg, FATAL, file_exist, & - check_nml_error, open_namelist_file, & - close_file, & - read_data, write_data, mpp_pe, mpp_root_pe, & - write_version_number, stdlog - -!======================================================================= - -implicit none -private - -public rh_clouds, rh_clouds_init, rh_clouds_end, & - rh_clouds_sum, rh_clouds_avg, do_rh_clouds - - -interface rh_clouds - module procedure rh_clouds_3d, rh_clouds_2d, rh_clouds_1d -end interface - -!--------------------- version number ---------------------------------- - -character(len=128) :: version = '$Id: rh_clouds.F90,v 10.0 2003/10/24 22:00:39 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' -logical :: module_is_initialized = .false. - -contains - -!####################################################################### - -subroutine rh_clouds_init (nlon, nlat, nlev) - -integer, intent(in) :: nlon, nlat, nlev - -!---------- output namelist to log------------------------------------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_clouds_init - -!####################################################################### - -subroutine rh_clouds_end - - module_is_initialized = .true. -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_clouds_end - -!####################################################################### - - function do_rh_clouds ( ) result (answer) - logical :: answer - -! returns logical value for whether rh_clouds has been initialized -! presumably if initialized then rh_cloud will be used - - answer = module_is_initialized - -!--------------------------------------------------------------------- - - call error_mesg('do_rh_clouds', & - 'This module is not supported as part of the public release', FATAL) - - end function do_rh_clouds - -!####################################################################### - - subroutine rh_clouds_sum (is, js, rh) - -!----------------------------------------------------------------------- - integer, intent(in) :: is, js - real, intent(in), dimension(:,:,:) :: rh -!----------------------------------------------------------------------- -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_sum', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine rh_clouds_sum - -!####################################################################### - - subroutine rh_clouds_avg (is, js, rh, ierr) - -!----------------------------------------------------------------------- - integer, intent(in) :: is, js - real, intent(out), dimension(:,:,:) :: rh - integer, intent(out) :: ierr -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_avg', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine rh_clouds_avg - -!####################################################################### - -subroutine rh_clouds_3d(rh, p_full, p_surf, zenith, deg_lat,& - n_cloud,top,bot,cldamt,alb_uv,alb_nir,abs_uv,abs_nir,emiss) - -real , intent(in) , dimension(:,:,:) :: rh, p_full -real , intent(in) , dimension(:,:) :: p_surf, zenith, deg_lat -integer, intent(out), dimension(:,:,:) :: top, bot -integer, intent(out), dimension(:,:) :: n_cloud -real , intent(out), dimension(:,:,:) :: cldamt,emiss -real , intent(out), dimension(:,:,:) :: alb_uv,alb_nir,abs_uv,abs_nir - -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_3d', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_clouds_3d - -!####################################################################### -! THE FOLLOWING CODE ALLOWS RH_CLOUDS TO BE USED IN 2D AND 1D MODELS -!####################################################################### - -subroutine rh_clouds_2d(rh, p_full, p_surf, zenith, deg_lat,& - n_cloud,top,bot,cldamt,alb_uv,alb_nir,abs_uv,abs_nir,emiss) - -real , intent(in) , dimension(:,:) :: rh, p_full -real , intent(in) , dimension(:) :: p_surf,zenith,deg_lat -integer, intent(out), dimension(:,:) :: top, bot -integer, intent(out), dimension(:) :: n_cloud -real , intent(out), dimension(:,:) :: cldamt,alb_uv,alb_nir,abs_uv -real , intent(out), dimension(:,:) :: abs_nir,emiss - -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_2d', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_clouds_2d - -!####################################################################### - -subroutine rh_clouds_1d(rh, p_full, p_surf, zenith, deg_lat,& - n_cloud,top,bot,cldamt,alb_uv,alb_nir,abs_uv,abs_nir,emiss) - -real , intent(in) , dimension(:) :: rh, p_full -real , intent(in) :: p_surf,zenith,deg_lat -integer, intent(out), dimension(:) :: top, bot -integer, intent(out) :: n_cloud -real , intent(out), dimension(:) :: cldamt,alb_uv,alb_nir,abs_uv -real , intent(out), dimension(:) :: abs_nir,emiss - -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_1d', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_clouds_1d - - -!####################################################################### - -end module rh_clouds_mod - diff --git a/src/atmos_param/rh_clouds/rh_clouds.F90 b/src/atmos_param/rh_clouds/rh_clouds.F90 index fd46d68da6..077354c37e 100644 --- a/src/atmos_param/rh_clouds/rh_clouds.F90 +++ b/src/atmos_param/rh_clouds/rh_clouds.F90 @@ -87,7 +87,7 @@ module rh_clouds_mod !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: rh_clouds.F90,v 19.0 2012/01/06 20:12:00 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !======================================================================= diff --git a/src/atmos_param/sea_esf_rad/aerosol.F90 b/src/atmos_param/sea_esf_rad/aerosol.F90 index 256c8841e5..f6419fc10c 100644 --- a/src/atmos_param/sea_esf_rad/aerosol.F90 +++ b/src/atmos_param/sea_esf_rad/aerosol.F90 @@ -77,8 +77,8 @@ module aerosol_mod !--------------------------------------------------------------------- !----------- version number for this module ------------------- -character(len=128) :: version = '$Id: aerosol.F90,v 19.0 2012/01/06 20:12:33 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: aerosol.F90,v 20.0 2013/12/13 23:18:53 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- @@ -1041,9 +1041,11 @@ subroutine aerosol_endts integer :: n - do n=1, size(Aerosol_interp,1) - call unset_interpolator_time_flag (Aerosol_interp(n)) - end do + if (allocated(Aerosol_interp)) then + do n=1, size(Aerosol_interp,1) + call unset_interpolator_time_flag (Aerosol_interp(n)) + end do + endif override_counter = override_counter + 1 if (override_counter == 2) then diff --git a/src/atmos_param/sea_esf_rad/aerosolrad_package.F90 b/src/atmos_param/sea_esf_rad/aerosolrad_package.F90 index be0fd29313..d4ac0ee456 100644 --- a/src/atmos_param/sea_esf_rad/aerosolrad_package.F90 +++ b/src/atmos_param/sea_esf_rad/aerosolrad_package.F90 @@ -57,8 +57,8 @@ module aerosolrad_package_mod !--------------------------------------------------------------------- !----------- version number for this module ------------------- -character(len=128) :: version = '$Id: aerosolrad_package.F90,v 19.0 2012/01/06 20:13:05 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: aerosolrad_package.F90,v 20.0 2013/12/13 23:18:56 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -1100,6 +1100,9 @@ subroutine aerosolrad_package_time_vary (Time) integer :: yr, mo, dy, hr, mn, sc + integer :: na, ni, nw + type(aerosol_properties_type) :: Aerosol_props_tem + !--------------------------------------------------------------------- ! define the time for which the volcanic properties will be obtained. @@ -1234,6 +1237,61 @@ subroutine aerosolrad_package_time_vary (Time) endif endif + if (force_to_repro_quebec) then + if (.not. band_calculation_completed) then + allocate (Aerosol_props_tem%aerextbandlw & + (N_AEROSOL_BANDS, naermodels)) + allocate (Aerosol_props_tem%aerssalbbandlw & + (N_AEROSOL_BANDS, naermodels)) + allocate (Aerosol_props_tem%aerextbandlw_cn & + (N_AEROSOL_BANDS_CN, naermodels)) + allocate (Aerosol_props_tem%aerssalbbandlw_cn & + (N_AEROSOL_BANDS_CN, naermodels)) + aerextbandlw_MOD = 0.0 + aerssalbbandlw_MOD = 0.0 + aerextbandlw_cn_MOD = 0.0 + aerssalbbandlw_cn_MOD = 0.0 + Aerosol_props_tem%aerextbandlw = 0.0 + Aerosol_props_tem%aerssalbbandlw = 0.0 + Aerosol_props_tem%aerextbandlw_cn = 0.0 + Aerosol_props_tem%aerssalbbandlw_cn = 0.0 + do nw=1,naermodels + do na=1,N_AEROSOL_BANDS + do ni=1,num_wavenumbers + Aerosol_props_tem%aerextbandlw(na,nw) = & + Aerosol_props_tem%aerextbandlw(na,nw) + & + aeroextivl(ni,nw)*sflwwts(na,ni)*1.0E+03 + Aerosol_props_tem%aerssalbbandlw(na,nw) = & + Aerosol_props_tem%aerssalbbandlw(na,nw) + & + aerossalbivl(ni,nw)*sflwwts(na,ni) + end do + end do + end do + do nw=1,naermodels + do na=1,N_AEROSOL_BANDS_CN + do ni=1,num_wavenumbers + Aerosol_props_tem%aerextbandlw_cn(na,nw) = & + Aerosol_props_tem%aerextbandlw_cn(na,nw) + & + aeroextivl(ni,nw)*sflwwts_cn(na,ni)*1.0E+03 + Aerosol_props_tem%aerssalbbandlw_cn(na,nw) = & + Aerosol_props_tem%aerssalbbandlw_cn(na,nw) +& + aerossalbivl(ni,nw)*sflwwts_cn(na,ni) + end do + end do + end do + + aerextbandlw_MOD = Aerosol_props_tem%aerextbandlw + aerssalbbandlw_MOD = Aerosol_props_tem%aerssalbbandlw + aerextbandlw_cn_MOD = Aerosol_props_tem%aerextbandlw_cn + aerssalbbandlw_cn_MOD = Aerosol_props_tem%aerssalbbandlw_cn + band_calculation_completed = .true. + deallocate (Aerosol_props_tem%aerextbandlw) + deallocate (Aerosol_props_tem%aerssalbbandlw) + deallocate (Aerosol_props_tem%aerextbandlw_cn) + deallocate (Aerosol_props_tem%aerssalbbandlw_cn) + endif + endif + !--------------------------------------------------------------------------- @@ -1713,49 +1771,6 @@ subroutine aerosol_radiative_properties (is, ie, js, je, & !--------------------------------------------------------------------- if (Rad_control%do_lwaerosol_forcing .or. & Lw_control%do_lwaerosol) then -!$OMP MASTER - if (force_to_repro_quebec) then - if (.not. band_calculation_completed) then - Aerosol_props%aerextbandlw = 0.0 - Aerosol_props%aerssalbbandlw = 0.0 - Aerosol_props%aerextbandlw_cn = 0.0 - Aerosol_props%aerssalbbandlw_cn = 0.0 - do nw=1,naermodels - do na=1,N_AEROSOL_BANDS - do ni=1,num_wavenumbers - Aerosol_props%aerextbandlw(na,nw) = & - Aerosol_props%aerextbandlw(na,nw) + & - aeroextivl(ni,nw)*sflwwts(na,ni)*1.0E+03 - Aerosol_props%aerssalbbandlw(na,nw) = & - Aerosol_props%aerssalbbandlw(na,nw) + & - aerossalbivl(ni,nw)*sflwwts(na,ni) - end do - end do - end do - do nw=1,naermodels - do na=1,N_AEROSOL_BANDS_CN - do ni=1,num_wavenumbers - Aerosol_props%aerextbandlw_cn(na,nw) = & - Aerosol_props%aerextbandlw_cn(na,nw) + & - aeroextivl(ni,nw)*sflwwts_cn(na,ni)*1.0E+03 - Aerosol_props%aerssalbbandlw_cn(na,nw) = & - Aerosol_props%aerssalbbandlw_cn(na,nw) +& - aerossalbivl(ni,nw)*sflwwts_cn(na,ni) - end do - end do - end do - - aerextbandlw_MOD = Aerosol_props%aerextbandlw - aerssalbbandlw_MOD = Aerosol_props%aerssalbbandlw - aerextbandlw_cn_MOD = Aerosol_props%aerextbandlw_cn - aerssalbbandlw_cn_MOD = Aerosol_props%aerssalbbandlw_cn - band_calculation_completed = .true. - endif - endif -!$OMP END MASTER -#ifndef IBM_FIX -!$OMP BARRIER -#endif Aerosol_props%aerextbandlw = aerextbandlw_MOD Aerosol_props%aerssalbbandlw = aerssalbbandlw_MOD Aerosol_props%aerextbandlw_cn = aerextbandlw_cn_MOD diff --git a/src/atmos_param/sea_esf_rad/bulkphys_rad.F90 b/src/atmos_param/sea_esf_rad/bulkphys_rad.F90 index f7f09237c9..83a8261b23 100644 --- a/src/atmos_param/sea_esf_rad/bulkphys_rad.F90 +++ b/src/atmos_param/sea_esf_rad/bulkphys_rad.F90 @@ -63,7 +63,7 @@ module bulkphys_rad_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: bulkphys_rad.F90,v 19.0 2012/01/06 20:13:07 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/cloud_spec.F90 b/src/atmos_param/sea_esf_rad/cloud_spec.F90 index b8dd4a0209..c33b3826d7 100644 --- a/src/atmos_param/sea_esf_rad/cloud_spec.F90 +++ b/src/atmos_param/sea_esf_rad/cloud_spec.F90 @@ -103,8 +103,8 @@ module cloud_spec_mod !--------------------------------------------------------------------- !----------- version number for this module -------------------------- -character(len=128) :: version = '$Id: cloud_spec.F90,v 17.0.8.1.2.1.2.1.2.1.2.1.2.1.2.1 2012/01/05 22:49:33 wfc Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: cloud_spec.F90,v 20.0 2013/12/13 23:19:01 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -155,12 +155,26 @@ module cloud_spec_mod ! random number generator ! (needed for some ! specialized applications) +logical :: ignore_donner_cells = .false.! when set to .true., the effects + ! of donner cell clouds in the + ! radiation code are ignored +logical :: do_legacy_seed_generation = .false. + ! setting this variable to .true. + ! (not recommended except to + ! reproduce previous results) will + ! activate the seed generation + ! scheme used previously (through + ! the siena code). this scheme may + ! exhibit flaws at hi-res or when + ! time is held fixed in the + ! radiation calculation. namelist /cloud_spec_nml / cloud_type_form, wtr_cld_reff, & ice_cld_reff, rain_reff, overlap_type, & doing_data_override, do_fu2007, & do_rain, do_snow, do_graupel, & - force_use_of_temp_for_seed + do_legacy_seed_generation, & + force_use_of_temp_for_seed, ignore_donner_cells !---------------------------------------------------------------------- !---- public data ------- @@ -262,7 +276,8 @@ module cloud_spec_mod ! ! ! -subroutine cloud_spec_init (pref, lonb, latb, axes, Time) +subroutine cloud_spec_init (pref, lonb, latb, axes, Time, & + cloud_type_form_out) !--------------------------------------------------------------------- ! cloud_spec_init is the constructor for cloud_spec_mod. @@ -272,6 +287,7 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) real, dimension(:,:), intent(in) :: lonb, latb integer, dimension(4), intent(in) :: axes type(time_type), intent(in) :: Time +character(len=16), intent(out) :: cloud_type_form_out !------------------------------------------------------------------- ! intent(in) variables: @@ -348,6 +364,11 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) jd = size(latb,2) - 1 kmax = size(pref,1) - 1 +!----------------------------------------------------------------------- +! define output field. +!----------------------------------------------------------------------- + cloud_type_form_out = cloud_type_form + !-------------------------------------------------------------------- ! verify a valid type of cloud overlap. set logical variables ! based on the namelist value. @@ -414,6 +435,10 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) Cldrad_control%do_donner_deep_clouds = .true. call donner_deep_clouds_W_init (pref, lonb, latb, & axes, Time) +!RSH 3/6/13: The following call added to allow stochastic clouds to be +! run for this case. Ultimately, the do_stochastic_clouds nml +! variable should be moved to cloud_spec_nml. + call strat_clouds_W_init(latb, lonb) !------------------------------------------------------------------ ! cloud fractions, heights are provided by the uw_conv shallow @@ -423,6 +448,10 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) Cldrad_control%do_uw_clouds = .true. call uw_clouds_W_init (pref, lonb, latb, & axes, Time) +!RSH 3/6/13: The following call added to allow stochastic clouds to be +! run for this case. Ultimately, the do_stochastic_clouds nml +! variable should be moved to cloud_spec_nml. + call strat_clouds_W_init(latb, lonb) !------------------------------------------------------------------- ! cloud fractions, heights are a combination of the donner @@ -448,6 +477,10 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) axes, Time) call uw_clouds_W_init (pref, lonb, latb, & axes, Time) +!RSH 3/6/13: The following call added to allow stochastic clouds to be +! run for this case. Ultimately, the do_stochastic_clouds nml +! variable should be moved to cloud_spec_nml. + call strat_clouds_W_init(latb, lonb) !------------------------------------------------------------------- ! cloud fractions, heights are provided by the klein large-scale @@ -643,28 +676,35 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) call cloud_generator_init !--------------------------------------------------------------------- +! determine the source of the random number seed generator to be used +! for the stochastic cloud generation. the legacy scheme may fail to +! provide spacially unique seeds at hi-res (above c48) or if the time +! provided the radiation package does not monotonically advance (as in +! some specialized sensitivity / assessment studies). +!--------------------------------------------------------------------- + if (do_legacy_seed_generation) then +!--------------------------------------------------------------------- ! if it is desired to force the use of the temperature-based ! random number seed (as is used when time is not always advancing ! as seen by the radiation package, or when model resolution is ! less than 1 degree), set the logical control variable in ! Cldrad_control to so indicate. !--------------------------------------------------------------------- - if ( force_use_of_temp_for_seed) then - Cldrad_control%use_temp_for_seed = .true. - Cldrad_control%use_temp_for_seed_iz = .true. - call error_mesg ('cloud_spec_init', & + if ( force_use_of_temp_for_seed) then + Cldrad_control%use_temp_for_seed = .true. + Cldrad_control%use_temp_for_seed_iz = .true. + call error_mesg ('cloud_spec_init', & 'Will use temp as basis for stochastic cloud seed; & &force_use_of_temp_for_seed is set true', NOTE) - else - call error_mesg ('cloud_spec_init', & - ' If model resolution is between c48 and c180, it is & + else + call error_mesg ('cloud_spec_init', & + ' If model resolution is above c48, it is & &HIGHLY RECOMMENDED that you set cloud_spec_nml variable & &force_use_of_temp_for_seed to true to assure & &reproducibility across pe count and domain layout', NOTE) - call error_mesg ('cloud_spec_init', & - 'No action is needed at or below c48 resolution and at or & - &above c180 resolution.', NOTE) - endif + call error_mesg ('cloud_spec_init', & + 'No action is needed at or below c48 resolution.', NOTE) + endif !--------------------------------------------------------------------- ! if the latitude and longitude of adjacent points on a pe have the @@ -675,40 +715,48 @@ subroutine cloud_spec_init (pref, lonb, latb, axes, Time) ! Note that for model resolutions of ~ 1 degree, some pes may use ! lat and lon, while others use temperature, and that this may change ! as the domain decomposition or npes used for the problem are changed. -! It is recommended that for resolutions between c48 and c180 that -! nml variable force_use_of_temp_for_seed be set to .true.; it may -! remain the default value of .false. for lower resolution runs to -! preserve legacy results, or if reproducibility over npes or layout -! is not essential. At c180 and above the loop below will set -! the value to .true. on all pes, so nothing need explicitly be done. -!--------------------------------------------------------------------- - if (.not. Cldrad_control%use_temp_for_seed) then - jLoop: do j=1,jd - do i=1,id - do jj=j+1,jd+1 - do ii=i+1,id+1 - if (NINT(lats(ii,jj)) == NINT(lats(i,j))) then - if (NINT(lons(ii,jj)) == NINT(lons(i,j))) then - Cldrad_control%use_temp_for_seed = .true. - Cldrad_control%use_temp_for_seed_iz = .true. - call error_mesg ('cloud_spec_init', & - 'Found grid point within 1 degree of & - &another',NOTE) - call error_mesg ('cloud_spec_init', & - 'if reproducibility across npes and layout is & - &desired and model res is between c48 and c180, & - &you must set cloud_spec_nml variable force_use_& - &of_temp_for_seed to true., and restart the & - &model.', NOTE) - exit jLoop +! Therefore it is HIGHLY RECOMMENDED that for resolutions above c48 +! that nml variable force_use_of_temp_for_seed be set to .true.; +! it may remain the default value of .false. for lower resolution runs +! or to preserve legacy results, or if reproducibility over npes or +! layout is not essential. +!--------------------------------------------------------------------- + if (.not. Cldrad_control%use_temp_for_seed) then + jLoop: do j=1,jd + do i=1,id + do jj=j+1,jd+1 + do ii=i+1,id+1 + if (NINT(lats(ii,jj)) == NINT(lats(i,j))) then + if (NINT(lons(ii,jj)) == NINT(lons(i,j))) then + Cldrad_control%use_temp_for_seed = .true. + Cldrad_control%use_temp_for_seed_iz = .true. + call error_mesg ('cloud_spec_init', & + 'Found grid point within 1 degree of & + &another',NOTE) + call error_mesg ('cloud_spec_init', & + 'if reproducibility across npes and layout is & + &desired, you must set cloud_spec_nml variable & + &force_use_of_temp_for_seed to true., and & + &restart the model.', NOTE) + exit jLoop + endif endif - endif + end do end do end do - end do - end do jLoop + end do jLoop + endif + +!------------------------------------------------------------------------- +! set seed generation source to be the temperature field (current +! default). +!------------------------------------------------------------------------- + else + Cldrad_control%use_temp_for_seed = .true. + Cldrad_control%use_temp_for_seed_iz = .true. endif endif + else call error_mesg ('microphys_rad_mod', & ' attempt to use Cldrad_control%do_stochastic_clouds before & @@ -959,6 +1007,40 @@ subroutine cloud_spec (is, ie, js, je, lat, z_half, z_full, Rad_time, & endif endif + if (Cldrad_control%do_uw_clouds) then + if ( present (shallow_cloud_area) .and. & + present (shallow_liquid) .and. & + present (shallow_ice) .and. & + present (shallow_droplet_number) .and. & + present (shallow_ice_number) ) then + else + call error_mesg ('cloud_spec_mod', & + 'optional argument(s) required when shallow clouds & + &are active is missing', FATAL) + endif + endif + + if (Cldrad_control%do_donner_deep_clouds) then + if ( present (cell_cld_frac) .and. & + present (cell_liq_amt) .and. & + present (cell_liq_size) .and. & + present (cell_ice_amt) .and. & + present (cell_ice_size) .and. & + present (cell_droplet_number) .and. & + present (meso_cld_frac) .and. & + present (meso_liq_amt) .and. & + present (meso_liq_size) .and. & + present (meso_ice_amt) .and. & + present (meso_ice_size) .and. & + present (meso_droplet_number) .and. & + present (nsum_out) ) then + else + call error_mesg ('cloud_spec_mod', & + 'optional argument(s) required when donner clouds & + &are active is missing', FATAL) + endif + endif + !---------------------------------------------------------------------- ! define model dimensions. !---------------------------------------------------------------------- @@ -2424,6 +2506,24 @@ subroutine combine_cloud_properties (is, js, temp, Rad_time, & !---------------------------------------------------------------------- ! assign cloud types, band by band !---------------------------------------------------------------------- + IF (ignore_donner_cells) then + do n=1,nsubcols + do k=1,size(Lsc_microphys%cldamt,3) ! Levels + do j=1,size(Lsc_microphys%cldamt,2) ! Lons + do i=1,size(Lsc_microphys%cldamt,1) ! Lats + if (randomNumbers(i,j,k,n) > & + (1. - Meso_microphys%cldamt(i, j, k))) then + +!---------------------------------------------------------------------- +! it's a meso-scale. +!---------------------------------------------------------------------- + Cld_spec%stoch_cloud_type(i,j,k,n) = 2 + endif + end do + end do + end do + end do + ELSE do n=1,nsubcols do k=1,size(Lsc_microphys%cldamt,3) ! Levels do j=1,size(Lsc_microphys%cldamt,2) ! Lons @@ -2448,6 +2548,7 @@ subroutine combine_cloud_properties (is, js, temp, Rad_time, & end do end do end do + ENDIF endif !---------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/cloudrad_diagnostics.F90 b/src/atmos_param/sea_esf_rad/cloudrad_diagnostics.F90 index 236605a078..6f9212b9e1 100644 --- a/src/atmos_param/sea_esf_rad/cloudrad_diagnostics.F90 +++ b/src/atmos_param/sea_esf_rad/cloudrad_diagnostics.F90 @@ -65,8 +65,8 @@ module cloudrad_diagnostics_mod !--------------------------------------------------------------------- !----------- version number for this module -------------------------- -character(len=128) :: version = '$Id: cloudrad_diagnostics.F90,v 19.0 2012/01/06 20:14:11 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: cloudrad_diagnostics.F90,v 20.0 2013/12/13 23:19:04 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -154,6 +154,13 @@ module cloudrad_diagnostics_mod min_cld_ice_size, max_cld_ice_size, & mn_drp_diam, mx_drp_diam +!----------------------------------------------------------------------- +! if true, then donner meso clouds are treated as largescale in the +! optical depth diagnostic; if false, then they are included with +! convective clouds +!----------------------------------------------------------------------- +logical :: donner_meso_is_largescale + !---------------------------------------------------------------------- ! number of stochastic subcolumns !---------------------------------------------------------------------- @@ -207,7 +214,10 @@ module cloudrad_diagnostics_mod id_ext_cld_uv, id_sct_cld_uv, id_asymm_cld_uv, & id_ext_cld_vis, id_sct_cld_vis, id_asymm_cld_vis, & id_ext_cld_nir, id_sct_cld_nir, id_asymm_cld_nir, & - id_alb_uv_cld, id_alb_nir_cld, id_abs_uv_cld, id_abs_nir_cld + id_alb_uv_cld, id_alb_nir_cld, id_abs_uv_cld, id_abs_nir_cld, & + id_strat_opdepth, id_meso_opdepth, id_cell_opdepth, & + id_shallow_opdepth, id_largescale_opdepth, id_convect_opdepth,& + id_total_opdepth ! strat cloud microphysical properties diagnostics integer:: id_strat_area_liq, id_strat_conc_drop, id_strat_size_drop,& @@ -311,6 +321,7 @@ module cloudrad_diagnostics_mod id_droplet_number_cols_only_lsc, id_lwp_cols_only_lsc, & id_iwp_cols_only_lsc +logical :: output_opdepth_diagnostics = .false. logical :: module_is_initialized = .false. ! module initialized ? @@ -354,7 +365,8 @@ module cloudrad_diagnostics_mod subroutine cloudrad_diagnostics_init (min_cld_drop_rad_in, & max_cld_drop_rad_in, & min_cld_ice_size_in, & - max_cld_ice_size_in, axes, Time) + max_cld_ice_size_in, axes, Time, & + donner_meso_is_largescale_in) !--------------------------------------------------------------------- ! cloudrad_diagnostics_init is the constructor for @@ -367,6 +379,7 @@ subroutine cloudrad_diagnostics_init (min_cld_drop_rad_in, & max_cld_ice_size_in integer, dimension(4), intent(in) :: axes type(time_type), intent(in) :: Time +logical, intent(in) :: donner_meso_is_largescale_in !--------------------------------------------------------------------- ! intent(in) variables: @@ -442,6 +455,8 @@ subroutine cloudrad_diagnostics_init (min_cld_drop_rad_in, & if (mpp_pe() == mpp_root_pe() ) & write (logunit, nml=cloudrad_diagnostics_nml) + donner_meso_is_largescale = donner_meso_is_largescale_in + !--------------------------------------------------------------------- ! define module variables to retain the smallest and largest ! allowable droplet and ice particle sizes which can be processed @@ -631,6 +646,10 @@ subroutine cloudrad_diagnostics_init (min_cld_drop_rad_in, & 'Cldrad_control%do_lw_micro not yet defined', FATAL) endif + if (id_largescale_opdepth + id_convect_opdepth + id_strat_opdepth + & + id_meso_opdepth + id_cell_opdepth + id_shallow_opdepth + & + id_total_opdepth > 0) output_opdepth_diagnostics = .true. + !-------------------------------------------------------------------- ! mark the module initialized. !-------------------------------------------------------------------- @@ -1155,12 +1174,19 @@ subroutine cloudrad_netcdf (is, js, Time, Time_diag, Atmos_input, cosz, & real, dimension(size(Atmos_input%rh2o,1), & size(Atmos_input%rh2o,2), & - size(Atmos_input%rh2o,3)) :: Tau, LwEm + size(Atmos_input%rh2o,3)) :: Tau, LwEm, & + tau_c, tau_s, & + tau_strat, tau_meso, tau_cell, & + tau_uw, tau_tot logical :: used integer :: ix, jx, kx integer :: i, j, k, n integer :: nn + integer :: ctr_s, ctr_c, ctr_strat, ctr_meso, ctr_cell, ctr_uw, & + ctr_tot + real :: sum_s1, sum_c1, sum_strat, sum_meso, sum_cell, sum_uw, & + sum_tot @@ -1495,10 +1521,124 @@ subroutine cloudrad_netcdf (is, js, Time, Time_diag, Atmos_input, cosz, & ! when running strat_clouds. !--------------------------------------------------------------------- - if (do_isccp) then + if (do_isccp .or. output_opdepth_diagnostics) then call obtain_cloud_tau_and_em (is, js, Model_microphys, & - Atmos_input, & - Tau_stoch, Lwem_stoch) + Atmos_input, Tau_stoch, Lwem_stoch) + if (output_opdepth_diagnostics) then +!--------------------------------------------------------------------- +! the values of tau and lwem are available for each stochastic column. +! here grid box mean values are obtained for the convective and +! large-scale components. +!--------------------------------------------------------------------- + do k=1, size(Tau_stoch,3) + do j=1, size(Tau_stoch,2) + do i=1, size(Tau_stoch,1) + ctr_s = 0 + ctr_c = 0 + ctr_strat = 0 + ctr_meso = 0 + ctr_cell = 0 + ctr_uw = 0 + ctr_tot = 0 + sum_s1 = 0. + sum_c1 = 0. + sum_strat = 0. + sum_meso = 0. + sum_cell = 0. + sum_uw = 0. + sum_tot = 0. + do n=1, size(Tau_stoch,4) + if (Model_microphys%stoch_cloud_type(i,j,k,n) == 1.) then + ctr_s = ctr_s + 1 + sum_s1 = sum_s1 + tau_stoch(i,j,k,n) + ctr_strat = ctr_strat + 1 + sum_strat = sum_strat + tau_stoch(i,j,k,n) + ctr_tot = ctr_tot + 1 + sum_tot = sum_tot + tau_stoch(i,j,k,n) + else if & + (Model_microphys%stoch_cloud_type(i,j,k,n) == 2. ) then + ctr_meso = ctr_meso + 1 + sum_meso = sum_meso + tau_stoch(i,j,k,n) + if (donner_meso_is_largescale) then + ctr_s = ctr_s + 1 + sum_s1 = sum_s1 + tau_stoch(i,j,k,n) + else + ctr_c = ctr_c + 1 + sum_c1 = sum_c1 + tau_stoch(i,j,k,n) + endif + ctr_tot = ctr_tot + 1 + sum_tot = sum_tot + tau_stoch(i,j,k,n) + else if & + (Model_microphys%stoch_cloud_type(i,j,k,n) == 3. ) then + ctr_cell = ctr_cell + 1 + sum_cell = sum_cell + tau_stoch(i,j,k,n) + ctr_c = ctr_c + 1 + sum_c1 = sum_c1 + tau_stoch(i,j,k,n) + ctr_tot = ctr_tot + 1 + sum_tot = sum_tot + tau_stoch(i,j,k,n) + else if & + (Model_microphys%stoch_cloud_type(i,j,k,n) == 4. ) then + ctr_uw = ctr_uw + 1 + sum_uw = sum_uw + tau_stoch(i,j,k,n) + ctr_c = ctr_c + 1 + sum_c1 = sum_c1 + tau_stoch(i,j,k,n) + ctr_tot = ctr_tot + 1 + sum_tot = sum_tot + tau_stoch(i,j,k,n) + endif + end do + if (ctr_s > 0) then + tau_s(i,j,k) = sum_s1/ctr_s + else + tau_s(i,j,k) = 0. + endif + if (ctr_c > 0) then + tau_c(i,j,k) = sum_c1/ctr_c + else + tau_c(i,j,k) = 0. + endif + if (ctr_strat > 0) then + tau_strat(i,j,k) = sum_strat/ctr_strat + else + tau_strat(i,j,k) = 0. + endif + if (ctr_meso > 0) then + tau_meso(i,j,k) = sum_meso/ctr_meso + else + tau_meso(i,j,k) = 0. + endif + if (ctr_cell > 0) then + tau_cell(i,j,k) = sum_cell/ctr_cell + else + tau_cell(i,j,k) = 0. + endif + if (ctr_uw > 0) then + tau_uw(i,j,k) = sum_uw/ctr_uw + else + tau_uw(i,j,k) = 0. + endif + if (ctr_tot > 0) then + tau_tot(i,j,k) = sum_tot/ctr_tot + else + tau_tot(i,j,k) = 0. + endif + end do + end do + end do + used = send_data (id_largescale_opdepth, tau_s(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + used = send_data (id_convect_opdepth, tau_c(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + used = send_data (id_strat_opdepth, tau_strat(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + used = send_data (id_meso_opdepth, tau_meso(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + used = send_data (id_cell_opdepth, tau_cell(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + used = send_data (id_shallow_opdepth, tau_uw(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + used = send_data (id_total_opdepth, tau_tot(:,:,:), & + Time_diag, is, js, 1, rmask=mask) + endif endif ! (do_isccp ) !-------------------------------------------------------------------- @@ -1664,9 +1804,10 @@ subroutine cloudrad_netcdf (is, js, Time, Time_diag, Atmos_input, cosz, & ! wise it is 0.0. define high cloud percentage by summing over all ! bands. !--------------------------------------------------------------------- - if (id_high_cld_amt > 0) then + if (id_high_cld_amt > 0) then + nn=size(tmplmask4,3) do n=1,ncol - tmplmask4(:,:,:,n) = (Atmos_input%pflux(:,:,:) <= high_btm) + tmplmask4(:,:,:,n) = (Atmos_input%pflux(:,:,1:nn) <= high_btm) end do cloud2n(:,:,:) = & @@ -1687,10 +1828,11 @@ subroutine cloudrad_netcdf (is, js, Time, Time_diag, Atmos_input, cosz, & ! bands. !--------------------------------------------------------------------- if (id_mid_cld_amt > 0) then + nn=size(tmplmask4,3) do n=1,ncol tmplmask4(:,:,:,n) = & - (Atmos_input%pflux(:,:,:) <= mid_btm .and. & - Atmos_input%pflux(:,:,:) > high_btm) + (Atmos_input%pflux(:,:,1:nn) <= mid_btm .and. & + Atmos_input%pflux(:,:,1:nn) > high_btm) end do cloud2n(:,:,:) = & @@ -1711,8 +1853,9 @@ subroutine cloudrad_netcdf (is, js, Time, Time_diag, Atmos_input, cosz, & ! bands. !--------------------------------------------------------------------- if (id_low_cld_amt > 0) then + nn=size(tmplmask4,3) do n=1,ncol - tmplmask4(:,:,:,n) = (Atmos_input%pflux(:,:,: ) > mid_btm) + tmplmask4(:,:,:,n) = (Atmos_input%pflux(:,:,1:nn) > mid_btm) end do cloud2n(:,:,:) = & @@ -1733,8 +1876,9 @@ subroutine cloudrad_netcdf (is, js, Time, Time_diag, Atmos_input, cosz, & ! summing over all bands. !--------------------------------------------------------------------- if (id_lam_cld_amt > 0) then + nn=size(tmplmask4,3) do n=1,ncol - tmplmask4(:,:,:,n) = (Atmos_input%pflux(:,:,: ) > high_btm) + tmplmask4(:,:,:,n) = (Atmos_input%pflux(:,:,1:nn) > high_btm) end do cloud2n(:,:,:) = & @@ -4022,6 +4166,25 @@ subroutine diag_field_init (Time, axes ) '1.4um cloud asymmetry parameter', & 'percent', missing_value=missing_value) + id_largescale_opdepth = register_diag_field & + (mod_name, 'largescale_opdepth', axes(1:3), & + Time, '.55um cloud optical depth avgd over & + &subcolumns with ls cloud', & + 'none', missing_value=missing_value) + + id_convect_opdepth = register_diag_field & + (mod_name, 'convect_opdepth', axes(1:3), & + Time, '.55um cloud optical depth avgd over & + &subcolumns with convective clouds', & + 'none', missing_value=missing_value) + + id_total_opdepth = register_diag_field & + (mod_name, 'total_opdepth', axes(1:3), & + Time, '.55um cloud optical depth avgd over & + &all subcolumns with cloud', & + 'none', missing_value=missing_value) + + !--------------------------------------------------------------------- ! register the microphysically-based cloud radiative property ! diagnostics resulting from the large-scale clouds only. @@ -4036,6 +4199,12 @@ subroutine diag_field_init (Time, axes ) Time, '.55um lsc cloud ext coeff', & 'km-1', missing_value=missing_value) + id_strat_opdepth = register_diag_field & + (mod_name, 'strat_opdepth', axes(1:3), & + Time, '.55um cloud optical depth avgd over & + &subcolumns with strat clouds', & + 'none', missing_value=missing_value) + id_lsc_cld_ext_nir = register_diag_field & (mod_name, 'lsc_cld_ext_nir', axes(1:3), & Time, '1.4um lsc cloud ext coeff', & @@ -4113,6 +4282,12 @@ subroutine diag_field_init (Time, axes ) Time, '.55um cell cloud ext coeff', & 'km-1', missing_value=missing_value) + id_cell_opdepth = register_diag_field & + (mod_name, 'cell_opdepth', axes(1:3), & + Time, '.55um cloud optical depth avgd over & + &subcolumns with cell clouds', & + 'none', missing_value=missing_value) + id_cell_cld_ext_nir = register_diag_field & (mod_name, 'cell_cld_ext_nir', axes(1:3), & Time, '1.4um cell cloud ext coeff', & @@ -4177,6 +4352,12 @@ subroutine diag_field_init (Time, axes ) Time, '.55um meso cloud ext coeff', & 'km-1', missing_value=missing_value) + id_meso_opdepth = register_diag_field & + (mod_name, 'meso_opdepth', axes(1:3), & + Time, '.55um cloud optical depth avgd over & + &subcolumns with meso clouds', & + 'none', missing_value=missing_value) + id_meso_cld_ext_nir = register_diag_field & (mod_name, 'meso_cld_ext_nir', axes(1:3), & Time, '1.4um meso cloud ext coeff', & @@ -4251,6 +4432,13 @@ subroutine diag_field_init (Time, axes ) '.55um uw shallow cloud ext coeff',& 'km-1', missing_value=missing_value) + id_shallow_opdepth = register_diag_field & + (mod_name, 'uw_shallow_opdepth',& + axes(1:3), Time, & + '.55um cloud optical depth avgd over & + &subcolumns with uw shallow clouds',& + 'none', missing_value=missing_value) + id_shallow_cld_ext_nir = register_diag_field & (mod_name, 'uw_shallow_cld_ext_nir',& axes(1:3), Time, & diff --git a/src/atmos_param/sea_esf_rad/cloudrad_package.F90 b/src/atmos_param/sea_esf_rad/cloudrad_package.F90 index 374b6bd5f4..2b88a17a23 100644 --- a/src/atmos_param/sea_esf_rad/cloudrad_package.F90 +++ b/src/atmos_param/sea_esf_rad/cloudrad_package.F90 @@ -61,8 +61,8 @@ module cloudrad_package_mod !--------------------------------------------------------------------- !----------- version number for this module -------------------------- -character(len=128) :: version = '$Id: cloudrad_package.F90,v 19.0 2012/01/06 20:14:13 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: cloudrad_package.F90,v 20.0 2013/12/13 23:19:07 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -161,7 +161,8 @@ module cloudrad_package_mod ! ! ! -subroutine cloudrad_package_init (pref, lonb, latb, axes, Time) +subroutine cloudrad_package_init (pref, lonb, latb, axes, Time, & + donner_meso_is_largescale) !--------------------------------------------------------------------- ! cloudrad_package_init is the constructor for cloudrad_package_mod. @@ -171,6 +172,7 @@ subroutine cloudrad_package_init (pref, lonb, latb, axes, Time) real, dimension(:,:), intent(in) :: lonb, latb integer, dimension(4), intent(in) :: axes type(time_type), intent(in) :: Time +logical, intent(in) :: donner_meso_is_largescale !--------------------------------------------------------------------- ! intent(in) variables: @@ -443,7 +445,8 @@ subroutine cloudrad_package_init (pref, lonb, latb, axes, Time) call cloudrad_diagnostics_init (min_cld_drop_rad, & max_cld_drop_rad, & min_cld_ice_size, max_cld_ice_size, & - axes, Time) + axes, Time, & + donner_meso_is_largescale) endif !-------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/diag_clouds_W.F90 b/src/atmos_param/sea_esf_rad/diag_clouds_W.F90 index 0c39c39b95..02773300ed 100644 --- a/src/atmos_param/sea_esf_rad/diag_clouds_W.F90 +++ b/src/atmos_param/sea_esf_rad/diag_clouds_W.F90 @@ -50,7 +50,7 @@ module diag_clouds_W_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: diag_clouds_W.F90,v 19.0 2012/01/06 20:14:45 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/donner_deep_clouds_W.F90 b/src/atmos_param/sea_esf_rad/donner_deep_clouds_W.F90 index fca038fcbd..2bc56f0693 100644 --- a/src/atmos_param/sea_esf_rad/donner_deep_clouds_W.F90 +++ b/src/atmos_param/sea_esf_rad/donner_deep_clouds_W.F90 @@ -41,7 +41,7 @@ module donner_deep_clouds_W_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: donner_deep_clouds_W.F90,v 19.0 2012/01/06 20:15:19 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/esfsw_driver.F90 b/src/atmos_param/sea_esf_rad/esfsw_driver.F90 index 955592f730..ce73790a44 100644 --- a/src/atmos_param/sea_esf_rad/esfsw_driver.F90 +++ b/src/atmos_param/sea_esf_rad/esfsw_driver.F90 @@ -64,7 +64,7 @@ module esfsw_driver_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: esfsw_driver.F90,v 19.0 2012/01/06 20:15:51 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/esfsw_parameters.F90 b/src/atmos_param/sea_esf_rad/esfsw_parameters.F90 index 1072fbad57..56ec071408 100644 --- a/src/atmos_param/sea_esf_rad/esfsw_parameters.F90 +++ b/src/atmos_param/sea_esf_rad/esfsw_parameters.F90 @@ -50,7 +50,7 @@ module esfsw_parameters_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: esfsw_parameters.F90,v 19.0 2012/01/06 20:16:23 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !-------------------------------------------------------------------- !----- interfaces ------ diff --git a/src/atmos_param/sea_esf_rad/gas_tf.F90 b/src/atmos_param/sea_esf_rad/gas_tf.F90 index 7410b41169..b3a0626e1c 100644 --- a/src/atmos_param/sea_esf_rad/gas_tf.F90 +++ b/src/atmos_param/sea_esf_rad/gas_tf.F90 @@ -42,7 +42,7 @@ module gas_tf_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: gas_tf.F90,v 19.0 2012/01/06 20:16:25 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/isccp_clouds.F90 b/src/atmos_param/sea_esf_rad/isccp_clouds.F90 index 01a24fa3ed..c0cd23dbed 100644 --- a/src/atmos_param/sea_esf_rad/isccp_clouds.F90 +++ b/src/atmos_param/sea_esf_rad/isccp_clouds.F90 @@ -42,7 +42,7 @@ module isccp_clouds_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: isccp_clouds.F90,v 19.0 2012/01/06 20:16:57 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -862,14 +862,14 @@ subroutine isccp_cloudtypes (sunlit, pfull, phalf, qv, at, skt, cc, & qv(:, j, :), at(:, j, :), dem_wv) ! Call Icarus... - call isccp_clouds_icarus(dtau, pFull(:, j, :), & + call icarus(dtau, pFull(:, j, :), & dem, dem_wv, at(:, j, :), skt(:, j), & (/ (emsfclw, j = 1, nPoints) /), & boxtau = boxtau, boxptop = boxptop) else ! We're asking for the real cloud tops. ! We don't correct very optically thin clouds either. - call isccp_clouds_icarus(dtau, pFull(:, j, :), & + call icarus(dtau, pFull(:, j, :), & boxtau = boxtau, boxptop = boxptop) end if @@ -1140,14 +1140,14 @@ subroutine isccp_cloudtypes_stochastic (sunlit, pfull, phalf, qv, at, skt, cc, & qv(:, j, :), at(:, j, :), dem_wv) ! Call Icarus... - call isccp_clouds_icarus(dtau, pFull(:, j, :), & + call icarus(dtau, pFull(:, j, :), & dem, dem_wv, at(:, j, :), skt(:, j), & (/ (emsfclw, j = 1, nPoints) /), & boxtau = boxtau, boxptop = boxptop) else ! We're asking for the real cloud tops. ! We don't correct very optically thin clouds either. - call isccp_clouds_icarus(dtau, pFull(:, j, :), & + call icarus(dtau, pFull(:, j, :), & boxtau = boxtau, boxptop = boxptop) end if @@ -1725,7 +1725,7 @@ subroutine scops(cc, conv, seed, frac_out) end subroutine scops ! ------------------------------------------------------------------- - subroutine isccp_clouds_icarus(dtau, pfull, & ! Required + subroutine icarus(dtau, pfull, & ! Required dem, dem_wv, at, skt, emsfc_lw, iTrop, & ! Optional boxtau, boxptop) ! @@ -1987,7 +1987,7 @@ subroutine isccp_clouds_icarus(dtau, pfull, & ! Req boxptop(:, :) = ptop(:, :) / 100. boxtau(:, :) = tau(:, :) - end subroutine isccp_clouds_icarus + end subroutine icarus ! ------------------------------------------------------------------- ! ------------------------------------------------------ function computeIsccpJointHistograms(tau, ptop, sunlit) result(isccpJointHistogram) diff --git a/src/atmos_param/sea_esf_rad/lhsw_driver.F90 b/src/atmos_param/sea_esf_rad/lhsw_driver.F90 index 16d1200802..8829545d5f 100644 --- a/src/atmos_param/sea_esf_rad/lhsw_driver.F90 +++ b/src/atmos_param/sea_esf_rad/lhsw_driver.F90 @@ -47,7 +47,7 @@ module lhsw_driver_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: lhsw_driver.F90,v 19.0 2012/01/06 20:17:29 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_param/sea_esf_rad/longwave_clouds.F90 b/src/atmos_param/sea_esf_rad/longwave_clouds.F90 index ff904d960d..9dbe09ed16 100644 --- a/src/atmos_param/sea_esf_rad/longwave_clouds.F90 +++ b/src/atmos_param/sea_esf_rad/longwave_clouds.F90 @@ -46,7 +46,7 @@ module longwave_clouds_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: longwave_clouds.F90,v 19.0 2012/01/06 20:17:31 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/longwave_driver.F90 b/src/atmos_param/sea_esf_rad/longwave_driver.F90 index e255ccfb94..367b51cf57 100644 --- a/src/atmos_param/sea_esf_rad/longwave_driver.F90 +++ b/src/atmos_param/sea_esf_rad/longwave_driver.F90 @@ -52,7 +52,7 @@ module longwave_driver_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: longwave_driver.F90,v 19.0 2012/01/06 20:18:03 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- diff --git a/src/atmos_param/sea_esf_rad/longwave_fluxes.F90 b/src/atmos_param/sea_esf_rad/longwave_fluxes.F90 index 5998b21baa..6b06bbf705 100644 --- a/src/atmos_param/sea_esf_rad/longwave_fluxes.F90 +++ b/src/atmos_param/sea_esf_rad/longwave_fluxes.F90 @@ -43,7 +43,7 @@ module longwave_fluxes_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: longwave_fluxes.F90,v 19.0 2012/01/06 20:15:17 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/longwave_params.F90 b/src/atmos_param/sea_esf_rad/longwave_params.F90 index 27ed0a0113..f99e159b62 100644 --- a/src/atmos_param/sea_esf_rad/longwave_params.F90 +++ b/src/atmos_param/sea_esf_rad/longwave_params.F90 @@ -39,7 +39,7 @@ module longwave_params_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: longwave_params.F90,v 19.0 2012/01/06 20:18:35 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !-------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/longwave_tables.F90 b/src/atmos_param/sea_esf_rad/longwave_tables.F90 index a11630d42d..e2cea91edb 100644 --- a/src/atmos_param/sea_esf_rad/longwave_tables.F90 +++ b/src/atmos_param/sea_esf_rad/longwave_tables.F90 @@ -51,7 +51,7 @@ module longwave_tables_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: longwave_tables.F90,v 19.0 2012/01/06 20:18:37 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/lw_gases_stdtf.F90 b/src/atmos_param/sea_esf_rad/lw_gases_stdtf.F90 index 5f20f9f430..4a45c6d1cf 100644 --- a/src/atmos_param/sea_esf_rad/lw_gases_stdtf.F90 +++ b/src/atmos_param/sea_esf_rad/lw_gases_stdtf.F90 @@ -57,7 +57,7 @@ module lw_gases_stdtf_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: lw_gases_stdtf.F90,v 19.0 2012/01/06 20:19:09 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/mgrp_prscr_clds.F90 b/src/atmos_param/sea_esf_rad/mgrp_prscr_clds.F90 index 519c5e22d3..21559a8425 100644 --- a/src/atmos_param/sea_esf_rad/mgrp_prscr_clds.F90 +++ b/src/atmos_param/sea_esf_rad/mgrp_prscr_clds.F90 @@ -50,7 +50,7 @@ module mgrp_prscr_clds_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: mgrp_prscr_clds.F90,v 19.0 2012/01/06 20:19:41 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/microphys_cloud.F90 b/src/atmos_param/sea_esf_rad/microphys_cloud.F90 index 76b3763d34..432ea32c12 100644 --- a/src/atmos_param/sea_esf_rad/microphys_cloud.F90 +++ b/src/atmos_param/sea_esf_rad/microphys_cloud.F90 @@ -46,7 +46,7 @@ module microphys_cloud_mod !----------------------------------------------------------------------- character(len=128) :: version = '$Id: microphys_cloud.F90,v 19.0 2012/01/06 20:19:43 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_param/sea_esf_rad/microphys_rad.F90 b/src/atmos_param/sea_esf_rad/microphys_rad.F90 index c69d3ca8fa..8823980c32 100644 --- a/src/atmos_param/sea_esf_rad/microphys_rad.F90 +++ b/src/atmos_param/sea_esf_rad/microphys_rad.F90 @@ -55,8 +55,8 @@ module microphys_rad_mod !--------------------------------------------------------------------- !----------- version number for this module ------------------- -character(len=128) :: version = '$Id: microphys_rad.F90,v 19.0 2012/01/06 20:20:15 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: microphys_rad.F90,v 20.0 2013/12/13 23:20:12 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -95,13 +95,16 @@ module microphys_rad_mod ! frequency-independent parameter for absorption due ! to cloud drops in the infrared. this value is given ! in held et al, JAS, 1993. [ m**2 / g ] +logical :: ignore_donner_cells = .false. + ! when set to .true., the effects of donner cell clouds + ! in the radiation code are ignored namelist /microphys_rad_nml / & lwem_form, & do_orig_donner_stoch, & do_delta_adj, & do_const_asy, val_const_asy, & - alpha + alpha, ignore_donner_cells !---------------------------------------------------------------------- !---- public data ------- @@ -2739,9 +2742,15 @@ subroutine comb_cldprops_calc ( is, js, Rad_time, Time_next, deltaz, & !---------------------------------------------------------------------- ! it's a cell. !---------------------------------------------------------------------- + IF (ignore_donner_cells) then + cldext(i,j,k,n,1) = 0. + cldsct(i,j,k,n,1) = 0. + cldasymm(i,j,k,n,1) = 1. + ELSE cldext(i,j,k,n,1) = Cellrad_props%cldext(i,j,k,n) cldsct(i,j,k,n,1) = Cellrad_props%cldsct(i,j,k,n) cldasymm(i,j,k,n, 1) = Cellrad_props%cldasymm(i,j,k,n) + ENDIF else if ( stoch_cloud_type(i,j,k,n) == 2) then !---------------------------------------------------------------------- @@ -2777,11 +2786,15 @@ subroutine comb_cldprops_calc ( is, js, Rad_time, Time_next, deltaz, & do j=1,size(cldext,2) ! Lons do i=1,size(cldext,1) ! Lats if ( stoch_cloud_type(i,j,k,nn) == 3) then + IF (ignore_donner_cells) then + abscoeff(i,j,k,n,1) = 0. + ELSE !---------------------------------------------------------------------- ! it's a cell. !---------------------------------------------------------------------- abscoeff(i,j,k,n,1) = Cellrad_props%abscoeff(i,j,k,n) + ENDIF else if ( stoch_cloud_type(i,j,k,nn) == 2) then !---------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/null/bulkphys_rad.F90 b/src/atmos_param/sea_esf_rad/null/bulkphys_rad.F90 deleted file mode 100644 index 84c47963c4..0000000000 --- a/src/atmos_param/sea_esf_rad/null/bulkphys_rad.F90 +++ /dev/null @@ -1,237 +0,0 @@ - module bulkphys_rad_mod - -! shared modules: - -use fms_mod, only: write_version_number,& - error_mesg, & - FATAL -! shared radiation package modules: - -use rad_utilities_mod, only: cldrad_properties_type, & - cld_specification_type - -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! bulkphys_rad_mod defines cloud radiative properties based on -! bulk cloud physics values in contrast to microphysically-based -! properties. -!-------------------------------------------------------------------- - - -!--------------------------------------------------------------------- -!----------- version number for this module -------------------------- - -character(len=128) :: version = '$Id: bulkphys_rad.F90,v 15.0 2007/08/14 03:55:05 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public & - bulkphys_rad_init, bulkphys_lw_driver, & - bulkphys_sw_driver, bulkphys_rad_end - -!------------------------------------------------------------------- -! logical flag. -!------------------------------------------------------------------- -logical :: module_is_initialized = .false. - -!------------------------------------------------------------------- -!------------------------------------------------------------------- - - - - contains - - - -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! -! PUBLIC SUBROUTINES -! -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -!##################################################################### - -subroutine bulkphys_rad_init (min_cld_drop_rad_in, max_cld_drop_rad_in,& - min_cld_ice_size_in, max_cld_ice_size_in,& - pref, lonb, latb) - -!--------------------------------------------------------------------- -! subroutine bulkphys_rad_init is the constructor for -! bulkphys_rad_mod. -!--------------------------------------------------------------------- - -!-------------------------------------------------------------------- -real, intent(in) :: min_cld_drop_rad_in, & - max_cld_drop_rad_in,& - min_cld_ice_size_in, & - max_cld_ice_size_in -real, dimension(:,:), intent(in) :: pref -real, dimension(:,:), intent(in) :: lonb, latb - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! pref array containing two reference pressure profiles -! for use in defining transmission functions [ Pa ] -! lonb array of model longitudes on cell boundaries -! [ radians ] -! latb array of model latitudes at cell boundaries [radians] -! -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! write namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - -!--------------------------------------------------------------------- -! mark the module as initialized. -!--------------------------------------------------------------------- - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('bulkphys_rad_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine bulkphys_rad_init - - - -!################################################################# - -subroutine bulkphys_sw_driver (is, ie, js, je, cosz, Cld_spec, & - Cldrad_props) - -!--------------------------------------------------------------------- -! bulkphys_sw_driver obtains bulk shortwave cloud radiative -! properties for the active cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:), intent(in) :: cosz -type(cld_specification_type), intent(in) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! cosz cosine of the zenith angle [ dimensionless ] -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! -! intent(inout) variables: -! -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %cirabsw absorptivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cirrfsw reflectivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cvisrfsw reflectivity of clouds in the -! visible frequency band -! [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('bulkphys_sw_driver', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine bulkphys_sw_driver - - - -!#################################################################### - -subroutine bulkphys_lw_driver (is, ie, js, je, Cld_spec, Cldrad_props) - -!--------------------------------------------------------------------- -! bulkphys_lw_driver defines bulk longwave cloud radiative -! properties for the active cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cld_specification_type), intent(in) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! -! intent(inout) variables: -! -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %emrndlw longwave cloud emissivity for -! randomly overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! %emmxolw longwave cloud emissivity for -! maximally overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('bulkphys_lw_driver', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine bulkphys_lw_driver - - - -!################################################################### - -subroutine bulkphys_rad_end - -!------------------------------------------------------------------- -! bulkphys_rad_end is the destructor for bulkphys_rad_mod. -!-------------------------------------------------------------------- - -!-------------------------------------------------------------------- -! mark the module as not initialized. -!-------------------------------------------------------------------- - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('bulkphys_rad_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine bulkphys_rad_end - - - - end module bulkphys_rad_mod - - diff --git a/src/atmos_param/sea_esf_rad/null/diag_clouds_W.F90 b/src/atmos_param/sea_esf_rad/null/diag_clouds_W.F90 deleted file mode 100644 index 56ee1f1d94..0000000000 --- a/src/atmos_param/sea_esf_rad/null/diag_clouds_W.F90 +++ /dev/null @@ -1,289 +0,0 @@ - - module diag_clouds_W_mod - -use time_manager_mod, only: time_type -use fms_mod, only: error_mesg, FATAL,& - mpp_pe, mpp_root_pe, & - write_version_number -use rad_utilities_mod, only: microphysics_type, & - cld_specification_type, & - cldrad_properties_type - -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! diag cloud radiative properties module -! currently a wrapper until SKYHI goes away and this -! module can be consolidated with diag_cloud_mod -! -!-------------------------------------------------------------------- - - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: diag_clouds_W.F90,v 12.0 2005/04/14 15:49:30 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public & - diag_clouds_W_init, & - diag_clouds_W_end, & - diag_clouds_amt, & - obtain_bulk_lw_diag, & - obtain_bulk_sw_diag - -!---------------------------------------------------------------------- -!---- private data ------- - -logical :: module_is_initialized = .false. -!---------------------------------------------------------------------- -!---------------------------------------------------------------------- - - - - -contains - - - - - -subroutine diag_clouds_W_init (num_slingo_bands_out) - - -integer, intent(out) :: num_slingo_bands_out - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('diag_clouds_W_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine diag_clouds_W_init - - -!##################################################################### - -subroutine diag_clouds_W_end - -!---------------------------------------------------------------------- -! diag_clouds_end is the destructor for diag_clouds_W_mod. -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! mark the module as not initialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - -!-------------------------------------------------------------------- - - call error_mesg('diag_clouds_W_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine diag_clouds_W_end - - - -!################################################################# - -subroutine diag_clouds_amt (is, ie, js, je, lat, pflux, press, & - Rad_time, Cld_spec, Lsc_microphys) - -!---------------------------------------------------------------------- -! diag_clouds_amt defines the location, amount (cloud fraction), -! number, optical depth, thickness and liquid percentage of clouds -! present on the model grid. -!---------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:), intent(in) :: lat -real, dimension(:,:,:), intent(in) :: pflux, press -type(time_type), intent(in) :: Rad_time -type(cld_specification_type), intent(inout) :: Cld_spec -type(microphysics_type), intent(inout) :: Lsc_microphys - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! lat latitude of model points [ radians ] -! pflux average of pressure at adjacent model levels -! [ (kg /( m s^2) ] -! press pressure at model levels (1:nlev), surface -! pressure is stored at index value nlev+1 -! [ (kg /( m s^2) ] -! Rad_time time at which the climatologically-determined, -! time-varying zonal cloud fields should apply -! [ time_type, days and seconds] -! -! intent(inout) variables: -! -! Cld_spec cld_specification_type variable containing the -! cloud specification input fields needed by the -! radiation package -! -! the following elements of Cld_spec are defined here: -! -! %cmxolw fraction of maximally overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %crndlw fraction of randomly overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %camtsw cloud fraction seen by the shortwave -! radiation; the sum of the maximally -! overlapped and randomly overlapped -! longwave cloud fractions [ dimensionless ] -! %nmxolw number of maximally overlapped longwave -! clouds in each grid column. -! %nrndlw number of randomly overlapped longwave -! clouds in each grid column. -! %ncldsw number of clouds seen by he shortwave -! radiation in each grid column. -! %liq_frac -! percentage of cloud condensate in a grid -! box which is liquid [ dimensionless ] -! %tau cloud optical depth [ dimensionless ] -! %cloud_thickness -! number of model layers over which the cloud -! in this grid box extends -! %ice_cloud -! logical variable, which if true, indicates -! that the grid box will contain ice cloud; -! if false, the box will contain liquid cloud -! -!--------------------------------------------------------------------- - - call error_mesg('diag_clouds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine diag_clouds_amt - - -!##################################################################### - -subroutine obtain_bulk_lw_diag (is, ie, js, je, Cld_spec, Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_lw_diag defines bulk longwave cloud radiative -! properties for the gordon diag cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cld_specification_type), intent(in ) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %emrndlw longwave cloud emissivity for -! randomly overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! %emmxolw longwave cloud emissivity for -! maximally overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_lw_diag', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_lw_diag - - - - -!##################################################################### - -subroutine obtain_bulk_sw_diag (is, ie, js, je, cosz, Cld_spec, & - Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_sw_diag defines bulk shortwave cloud radiative -! properties for the gordon diag cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:), intent(in) :: cosz -type(cld_specification_type), intent(in ) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! cosz cosine of the zenith angle [ dimensionless ] -! -! intent(inout) variables: -! -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %cirabsw absorptivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cirrfsw reflectivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cvisrfsw reflectivity of clouds in the -! visible frequency band -! [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_sw_diag', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_sw_diag - - - -!#################################################################### - - - end module diag_clouds_W_mod - diff --git a/src/atmos_param/sea_esf_rad/null/donner_deep_clouds_W.F90 b/src/atmos_param/sea_esf_rad/null/donner_deep_clouds_W.F90 deleted file mode 100644 index d0b0419f2a..0000000000 --- a/src/atmos_param/sea_esf_rad/null/donner_deep_clouds_W.F90 +++ /dev/null @@ -1,68 +0,0 @@ - module donner_deep_clouds_W_mod - -use time_manager_mod, only: time_type -use fms_mod, only: error_mesg, FATAL, WARNING -use rad_utilities_mod, only: microphysics_type - -implicit none -private - - character(len=128) :: version = '$Id: donner_deep_clouds_W.F90,v 15.0 2007/08/14 03:55:08 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - -public :: donner_deep_clouds_W_init, & - donner_deep_clouds_W_end , donner_deep_clouds_amt - -contains - -subroutine donner_deep_clouds_W_init (pref, lonb, latb, axes, Time) - -real, dimension(:,:), intent(in) :: pref -real, dimension(:,:), intent(in) :: lonb, latb -integer, dimension(4), intent(in) :: axes -type(time_type), intent(in) :: Time - - call error_mesg('donner_deep_clouds_W_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine donner_deep_clouds_W_init - -!################################################################# - -subroutine donner_deep_clouds_W_end - - call error_mesg('donner_deep_clouds_W_end', & - 'This module is not supported as part of the public release', WARNING) - -end subroutine donner_deep_clouds_W_end - -!################################################################# - -subroutine donner_deep_clouds_amt (is, ie, js, je, & - cell_cloud_frac, cell_liquid_amt, cell_liquid_size, & - cell_ice_amt, cell_ice_size, & - cell_droplet_number, & - meso_cloud_frac, meso_liquid_amt, meso_liquid_size, & - meso_ice_amt, meso_ice_size, & - meso_droplet_number, nsum_out, & - Cell_microphys, Meso_microphys) - -integer, intent(in) :: is,ie,js,je -real, dimension(:,:,:), intent(inout) :: & - cell_cloud_frac, cell_liquid_amt, cell_liquid_size, & - cell_ice_amt, cell_ice_size, & - cell_droplet_number, & - meso_cloud_frac, meso_liquid_amt, meso_liquid_size, & - meso_ice_amt, meso_ice_size, & - meso_droplet_number -integer, dimension(:,:), intent(inout) :: nsum_out -type(microphysics_type), intent(inout) :: Cell_microphys, Meso_microphys - - call error_mesg('donner_deep_clouds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine donner_deep_clouds_amt - -!#################################################################### - - end module donner_deep_clouds_W_mod diff --git a/src/atmos_param/sea_esf_rad/null/lhsw_driver.F90 b/src/atmos_param/sea_esf_rad/null/lhsw_driver.F90 deleted file mode 100644 index 644a1dc239..0000000000 --- a/src/atmos_param/sea_esf_rad/null/lhsw_driver.F90 +++ /dev/null @@ -1,163 +0,0 @@ - module lhsw_driver_mod - -use rad_utilities_mod, only: astronomy_type, & - atmos_input_type, & - surface_type, & - sw_output_type, & - cld_space_properties_type, & - radiative_gases_type, & - cld_specification_type, & - cldrad_properties_type -use fms_mod, only: error_mesg, & - FATAL, & - mpp_pe, mpp_root_pe, & - write_version_number - -!-------------------------------------------------------------------- - -implicit none -private - - -!-------------------------------------------------------------------- -! lacis-hansen shortwave parameterization -! -!------------------------------------------------------------------ - - -!-------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: lhsw_driver.F90,v 12.0 2005/04/14 15:49:39 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public lhsw_driver_init, lhsw_driver_end, swrad - -!------------------------------------------------------------------ -!------------------------------------------------------------------ - -contains - - -subroutine lhsw_driver_init ( pref ) - -real, dimension(:,:), intent(in) :: pref - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - -!------------------------------------------------------------------- - module_is_initialized = .true. -!--------------------------------------------------------------------- - - call error_mesg('lhsw_driver_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine lhsw_driver_init - - - - - -!###################################################################### -subroutine lhsw_driver_end - -!------------------------------------------------------------------- - module_is_initialized = .true. -!--------------------------------------------------------------------- - - call error_mesg('lhsw_driver_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine lhsw_driver_end - - - - - -!###################################################################### - -subroutine swrad ( is, ie, js, je, & - Astro, with_clouds, Atmos_input, & - Surface, & - Rad_gases, & - Cldrad_props, Cld_spec, Sw_output, Cldspace_rad, gwt) - -!----------------------------------------------------------------------- -! -! Swrad solves for shortwave radiation. -! -! references: -! -! (1) lacis, a. a. and j. e. hansen, "a parameterization for the -! absorption of solar radiation in the earth's atmosphere," -! journal of the atmospheric sciences, 31 (1974), 118-133. -! -! author: m. d. schwarzkopf -! -! revised: 1/1/93 -! -! certified: radiation version 1.0 -! -!----------------------------------------------------------------------- -! intent in: -! -! fracday = fraction of day (or timestep) that sun is above -! horizon. -! -! press = pressure at data levels of model. -! -! qo3 = mass mixing ratio of o3 at model data levels. -! -! rh2o = mass mixing ratio of h2o at model data levels. -! -! ssolar = solar constant (may vary over one year). units: Wm-2. -! -! cosangsolar = zenith angle at grid point. -!----------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -logical, intent(in) :: with_clouds -type(cldrad_properties_type), intent(in) :: Cldrad_props -type(cld_specification_type), intent(in) :: Cld_spec -real, dimension(:), optional, intent(in) :: gwt -type(astronomy_type), intent(in) :: Astro -type(atmos_input_type), intent(in) :: Atmos_input -type(surface_type), intent(in) :: Surface -type(radiative_gases_type), intent(in) :: Rad_gases - -type(sw_output_type), intent(inout) :: Sw_output -type(cld_space_properties_type), intent(inout) :: Cldspace_rad - -!----------------------------------------------------------------------- -! intent out: -! -! dfsw = downward radiation at all pressure levels. -! -! fsw = net radiation (up-down) at all pressure levels. -! -! hsw = radiation heating rates at all pressure layers. -! -! ufsw = upward radiation at all pressure levels. -!----------------------------------------------------------------------- - - -!--------------------------------------------------------------------- - - call error_mesg('swrad', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine swrad - - - end module lhsw_driver_mod - diff --git a/src/atmos_param/sea_esf_rad/null/mgrp_prscr_clds.F90 b/src/atmos_param/sea_esf_rad/null/mgrp_prscr_clds.F90 deleted file mode 100644 index 25f05fad39..0000000000 --- a/src/atmos_param/sea_esf_rad/null/mgrp_prscr_clds.F90 +++ /dev/null @@ -1,264 +0,0 @@ - - module mgrp_prscr_clds_mod - -use fms_mod, only: error_mesg, & - FATAL, & - mpp_pe, mpp_root_pe, & - write_version_number - -use rad_utilities_mod, only: cldrad_properties_type, & - cld_specification_type - - -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! mgroup prescribed cloud properties module -! (this module runnable in SKYHI and FMS; -! zonal_clouds_mod is FMS native equivalent) -! -!!-------------------------------------------------------------------- - - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: mgrp_prscr_clds.F90,v 15.0 2007/08/14 03:55:11 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public mgrp_prscr_clds_init, & - mgrp_prscr_clds_end, & - prscr_clds_amt, & - obtain_bulk_lw_prscr, & - obtain_bulk_sw_prscr - - -logical :: module_is_initialized = .false. - -!---------------------------------------------------------------------- -!---------------------------------------------------------------------- - - contains - - -subroutine mgrp_prscr_clds_init ( pref, latb ) - -!------------------------------------------------------------------ -real, dimension(:), intent(in) :: latb -real, dimension(:,:), intent(in) :: pref -!-------------------------------------------------------------------- - - call write_version_number (version, tagname) - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('mgrp_prscr_clds_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine mgrp_prscr_clds_init - -!###################################################################### - -subroutine mgrp_prscr_clds_end - -!---------------------------------------------------------------------- -! mgrp_prscr_clds_end is the destructor for mgrp_prscr_clds_mod. -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! mark the module as not initialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - -!-------------------------------------------------------------------- - - -!--------------------------------------------------------------------- - - call error_mesg('mgrp_prscr_clds_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine mgrp_prscr_clds_end - - - - -!##################################################################### - -subroutine prscr_clds_amt (is, ie, js, je, Cld_spec) - -!--------------------------------------------------------------------- -! prscr_clds_amt defines the location, amount (cloud fraction), -! number and type (hi, mid, low) of clouds present on the model grid. -!---------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cld_specification_type), intent(inout) :: Cld_spec - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cld_spec cld_specification_type variable containing the -! cloud specification input fields needed by the -! radiation package -! -! the following elements of Cld_spec are defined here: -! -! %cmxolw fraction of maximally overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %crndlw fraction of randomly overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %camtsw cloud fraction seen by the shortwave -! radiation; the sum of the maximally -! overlapped and randomly overlapped -! longwave cloud fractions [ dimensionless ] -! %nmxolw number of maximally overlapped longwave -! clouds in each grid column. -! %nrndlw number of randomly overlapped longwave -! clouds in each grid column. -! %ncldsw number of clouds seen by he shortwave -! radiation in each grid column. -! %hi_cld logical flag indicating the presence of -! high clouds in a grid box -! %mid_cld logical flag indicating the presence of -! middle clouds in a grid box -! %low_cld logical flag indicating the presence of -! low clouds in a grid box -! -!--------------------------------------------------------------------- - - call error_mesg('prscr_clds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine prscr_clds_amt - - -!###################################################################### - -subroutine obtain_bulk_lw_prscr (is, ie, js, je, Cld_spec, Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_lw_prscr defines bulk longwave cloud radiative -! properties for the mgrp_prscr_clds cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cld_specification_type), intent(inout) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %emrndlw longwave cloud emissivity for -! randomly overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! %emmxolw longwave cloud emissivity for -! maximally overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! -!--------------------------------------------------------------------- - -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_lw_prscr', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_lw_prscr - - - -!##################################################################### - -subroutine obtain_bulk_sw_prscr (is, ie, js, je, Cld_spec, Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_sw_zonal defines bulk shortwave cloud radiative -! properties for the zonal cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cld_specification_type), intent(inout) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props -!------------------------------------------------------------------- - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %cirabsw absorptivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cirrfsw reflectivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cvisrfsw reflectivity of clouds in the -! visible frequency band -! [ dimensionless ] -! -!--------------------------------------------------------------------- - -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_sw_prscr', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_sw_prscr - -!#################################################################### - - end module mgrp_prscr_clds_mod - - - - diff --git a/src/atmos_param/sea_esf_rad/null/original_fms_rad.F90 b/src/atmos_param/sea_esf_rad/null/original_fms_rad.F90 deleted file mode 100644 index ec4a2687e5..0000000000 --- a/src/atmos_param/sea_esf_rad/null/original_fms_rad.F90 +++ /dev/null @@ -1,122 +0,0 @@ - module original_fms_rad_mod - - -!----------------------------------------------------------------------- -! radiation interface module -!----------------------------------------------------------------------- - -use time_manager_mod, only: time_type -use fms_mod, only: FATAL,& - error_mesg, & - mpp_pe, mpp_root_pe,& - write_version_number - -use rad_utilities_mod, only: radiative_gases_type, & - cldrad_properties_type, & - cld_specification_type, & - astronomy_type, & - atmos_input_type, & - surface_type, & - fsrad_output_type - -implicit none -private - -!----------- public interfaces in this module ----------------------- - -public original_fms_rad_init, original_fms_rad_end, original_fms_rad - -!----------------------------------------------------------------------- -!------------ version number for this module --------------------------- -character(len=128) :: version = '$Id: original_fms_rad.F90,v 15.0 2007/08/14 03:55:13 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' - - logical :: module_is_initialized = .false. - -!--------------------------------------------------------------------- -!--------------------------------------------------------------------- - - contains - -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -! -! PUBLIC SUBROUTINES -! -!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -!#################################################################### - - subroutine original_fms_rad_init ( lonb, latb, pref, axes, Time , & - kmax) - -!----------------------------------------------------------------------- - integer, intent(in) :: kmax - real, intent(in), dimension(:,:) :: lonb, latb - real, intent(in), dimension(:,:) :: pref - integer, intent(in), dimension(4) :: axes -type(time_type), intent(in) :: Time - -!--------------------------------------------------------------------- -! write namelist to logfile. -!--------------------------------------------------------------------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('original_fms_rad_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine original_fms_rad_init - -!####################################################################### - -subroutine original_fms_rad_end - -!----------------------------------------------------------------------- -module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('original_fms_rad_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine original_fms_rad_end - -!################################################################### - -subroutine original_fms_rad (is, ie, js, je, phalf, lat_in, lon_in, & - do_clear_sky_pass, & - Rad_time, Time_diag, Atmos_input, & - Surface, & - Astro, Rad_gases, Cldrad_props, Cld_spec, & - Fsrad_output, mask, kbot) - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:,:), intent(in) :: phalf -real, dimension(:,:), intent(in) :: lat_in, lon_in -type(time_type), intent(in) :: Rad_time, Time_diag -logical, intent(in) :: do_clear_sky_pass -type(atmos_input_type), intent(in) :: Atmos_input -type(surface_type), intent(in) :: Surface -type(astronomy_type), intent(in) :: Astro -type(radiative_gases_type), intent(in) :: Rad_gases -type(cldrad_properties_type), intent(in) :: Cldrad_props -type(cld_specification_type), intent(in) :: Cld_spec -type(fsrad_output_type), intent(inout) :: Fsrad_output -real, dimension(:,:,:), intent(in), optional :: mask -integer, dimension(:,:), intent(in), optional :: kbot -!-------------------------------------------------------------------- - - call error_mesg('original_fms_rad', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine original_fms_rad - -!##################################################################### - - end module original_fms_rad_mod diff --git a/src/atmos_param/sea_esf_rad/null/rh_based_clouds.F90 b/src/atmos_param/sea_esf_rad/null/rh_based_clouds.F90 deleted file mode 100644 index 3b1458f4cb..0000000000 --- a/src/atmos_param/sea_esf_rad/null/rh_based_clouds.F90 +++ /dev/null @@ -1,331 +0,0 @@ - - module rh_based_clouds_mod - -use fms_mod, only: mpp_pe, & - mpp_root_pe, & - write_version_number, & - error_mesg, & - FATAL -use rad_utilities_mod, only: cldrad_properties_type, & - cld_specification_type - - -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! module which defines cloud locations -! based on model relative humidity -! -!-------------------------------------------------------------------- - - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: rh_based_clouds.F90,v 12.0 2005/04/14 15:49:51 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public & - rh_based_clouds_init, & - rh_clouds_amt, & - obtain_bulk_lw_rh, obtain_bulk_sw_rh, & - rh_based_clouds_end, & - cldalb, albcld_lw, albcld_sw - -!---------------------------------------------------------------------- -!---- private data ------- - -logical :: module_is_initialized = .false. - -!---------------------------------------------------------------------- -!---------------------------------------------------------------------- - - contains - - -subroutine rh_based_clouds_init - - - -!-------------------------------------------------------------------- - integer :: unit, ierr, io - - -!---------------------------------------------------------------------- -! write version number and namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('rh_based_clouds_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_based_clouds_init - -!#################################################################### - -subroutine rh_based_clouds_end - -!---------------------------------------------------------------------- -! rh_clouds_end is the destructor for rh_based_cloouds_mod. -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! mark the module as not initialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('rh_based_clouds_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_based_clouds_end - - - -!###################################################################### - -subroutine rh_clouds_amt (is, ie, js, je, press, lat, Cld_spec) - -!---------------------------------------------------------------------- -! rh_clouds_amt defines the location, amount (cloud fraction), number -! and type (hi, mid, low) of clouds present on the model grid. -!---------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:,:), intent(in) :: press -real, dimension(:,:), intent(in) :: lat -type(cld_specification_type), intent(inout) :: Cld_spec - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! press pressure at model levels (1:nlev), surface -! pressure is stored at index value nlev+1 -! [ (kg /( m s^2) ] -! lat latitude of model points [ radians ] -! -! intent(inout) variables: -! -! Cld_spec cld_specification_type variable containing the -! cloud specification input fields needed by the -! radiation package -! -! the following elements of Cld_spec are defined here: -! -! %cmxolw fraction of maximally overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %crndlw fraction of randomly overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %camtsw cloud fraction seen by the shortwave -! radiation; the sum of the maximally -! overlapped and randomly overlapped -! longwave cloud fractions [ dimensionless ] -! %nmxolw number of maximally overlapped longwave -! clouds in each grid column. -! %nrndlw number of randomly overlapped longwave -! clouds in each grid column. -! %ncldsw number of clouds seen by he shortwave -! radiation in each grid column. -! %hi_cld logical flag indicating the presence of -! high clouds in a grid box -! %mid_cld logical flag indicating the presence of -! middle clouds in a grid box -! %low_cld logical flag indicating the presence of -! low clouds in a grid box -! -!--------------------------------------------------------------------- - - call error_mesg('rh_clouds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine rh_clouds_amt - -!#################################################################### - -subroutine obtain_bulk_lw_rh (is, ie, js, je, Cld_spec, Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_lw_rh defines bulk longwave cloud radiative -! properties for the rh cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cld_specification_type), intent(in ) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %emrndlw longwave cloud emissivity for -! randomly overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! %emmxolw longwave cloud emissivity for -! maximally overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! -!--------------------------------------------------------------------- - - - call error_mesg('obtain_bulk_lw_rh', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_lw_rh - -!###################################################################### - -subroutine obtain_bulk_sw_rh (is, ie, js, je, cosz, Cld_spec, & - Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_sw_rh defines bulk shortwave cloud radiative -! properties for the rh cloud scheme. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:), intent(in) :: cosz -type(cld_specification_type), intent(in ) :: Cld_spec -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! cosz cosine of the zenith angle [ dimensionless ] -! -! intent(inout) variables: -! -! Cld_spec cloud specification arrays defining the -! location, amount and type (hi, middle, lo) -! of clouds that are present, provides input -! to this subroutine -! [ cld_specification_type ] -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %cirabsw absorptivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cirrfsw reflectivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cvisrfsw reflectivity of clouds in the -! visible frequency band -! [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_sw_rh', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_sw_rh - -!#################################################################### - -subroutine cldalb (zenith) - -!--------------------------------------------------------------------- -! cldalb calculates a zenith angle dependency for the cloud albedos. -! the cloud albedos are interpolated using data adapted from fritz -! (1954). the solar zenith angle is the only input required. -!----------------------------------------------------------------------- - -real, intent(in) :: zenith - -!--------------------------------------------------------------------- - - call error_mesg('cldalb', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine cldalb - -!################################################################## - -subroutine albcld_lw(hi_cloud, mid_cloud, low_cloud, & - cmxolw, crndlw, emmxolw, emrndlw) - -!----------------------------------------------------------------------- -! albcld_lw computes the lw cloud emissivities. This calculation is -! based on sigma and cloud thickness in the old scheme (cldht60) -! and sigma, cloud thickness and latitude in the new scheme -! (cldht93). -!----------------------------------------------------------------------- - -real, dimension(:,:,:), intent(in) :: cmxolw, crndlw -real, dimension(:,:,:,:), intent(inout) :: emmxolw, emrndlw -logical, dimension(:,:,:), intent(in) :: hi_cloud, mid_cloud, & - low_cloud -!--------------------------------------------------------------------- - - call error_mesg('albcld_lw', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine albcld_lw - -!#################################################################### - -subroutine albcld_sw(i,j, hi_cloud, mid_cloud, low_cloud, & - camtsw, cmxolw, crndlw, cvisrfsw, cirrfsw, cirabsw) - -!----------------------------------------------------------------------- -! albcld_sw computes the cloud albedos. This calculation is based on -! sigma and cloud thickness in the old scheme (cldht60) and sigma, -! cloud thickness and latitude in the new scheme (cldht93). -!----------------------------------------------------------------------- - -real, dimension(:,:,:), intent(in) :: camtsw, cmxolw, crndlw -real, dimension(:,:,:), intent(inout) :: cvisrfsw, cirrfsw, cirabsw -logical, dimension(:,:,:), intent(in) :: hi_cloud, mid_cloud, & - low_cloud -integer, intent(in) :: i, j -!--------------------------------------------------------------------- - - call error_mesg('albcld_sw', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine albcld_sw - - - - end module rh_based_clouds_mod - - diff --git a/src/atmos_param/sea_esf_rad/null/specified_clouds_W.F90 b/src/atmos_param/sea_esf_rad/null/specified_clouds_W.F90 deleted file mode 100644 index 6acd476cac..0000000000 --- a/src/atmos_param/sea_esf_rad/null/specified_clouds_W.F90 +++ /dev/null @@ -1,162 +0,0 @@ - - module specified_clouds_W_mod - -use time_manager_mod, only: time_type -use fms_mod, only: error_mesg, FATAL, & - mpp_pe, mpp_root_pe, & - write_version_number -use rad_utilities_mod, only: cld_specification_type - -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! specified clouds radiative properties module; -! used with cloud_obs_mod and cloud_zonal_mod -! -!-------------------------------------------------------------------- - - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: specified_clouds_W.F90,v 15.0 2007/08/14 03:55:16 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public & - specified_clouds_W_init, specified_clouds_amt, & - specified_clouds_W_end - -logical :: module_is_initialized = .false. - -!------------------------------------------------------------------ -!------------------------------------------------------------------ - - - -contains - -subroutine specified_clouds_W_init (lonb, latb) - - -real, dimension(:,:), intent(in) :: lonb, latb - - - integer :: unit, ierr, io - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('specified_clouds_W_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine specified_clouds_W_init - -subroutine specified_clouds_W_end - -!---------------------------------------------------------------------- -! specified_clouds_end is the destructor for specified_clouds_W_mod. -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! mark the module as not initialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('specified_clouds_W_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine specified_clouds_W_end - - -!###################################################################### - -subroutine specified_clouds_amt (is, ie, js, je, Rad_time, lat, pflux, & - Cld_spec) - -!---------------------------------------------------------------------- -! specified_clouds_amt defines the location, amount (cloud fraction), -! number and type (hi, mid, low) of clouds present on the model grid. -!---------------------------------------------------------------------- - -!-------------------------------------------------------------------- -integer, intent(in) :: is, ie, js, je -type(time_type), intent(in) :: Rad_time -real, dimension(:,:), intent(in) :: lat -real, dimension(:,:,:), intent(in) :: pflux -type(cld_specification_type), intent(inout) :: Cld_spec -!------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! Rad_time time at which the climatologically-determined, -! time-varying specified cloud fields should apply -! [ time_type, days and seconds] -! lat latitude of model points [ radians ] -! pflux average of pressure at adjacent model levels -! [ (kg /( m s^2) ] -! -! intent(inout) variables: -! -! Cld_spec cld_specification_type variable containing the -! cloud specification input fields needed by the -! radiation package -! -! the following elements of Cld_spec are defined here: -! -! %cmxolw fraction of maximally overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %crndlw fraction of randomly overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %camtsw cloud fraction seen by the shortwave -! radiation; the sum of the maximally -! overlapped and randomly overlapped -! longwave cloud fractions [ dimensionless ] -! %nmxolw number of maximally overlapped longwave -! clouds in each grid column. -! %nrndlw number of randomly overlapped longwave -! clouds in each grid column. -! %ncldsw number of clouds seen by he shortwave -! radiation in each grid column. -! %hi_cld logical flag indicating the presence of -! high clouds in a grid box -! %mid_cld logical flag indicating the presence of -! middle clouds in a grid box -! %low_cld logical flag indicating the presence of -! low clouds in a grid box -! -!--------------------------------------------------------------------- - - call error_mesg('specified_clouds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine specified_clouds_amt - -!###################################################################### - - end module specified_clouds_W_mod - - - diff --git a/src/atmos_param/sea_esf_rad/null/standalone_clouds.F90 b/src/atmos_param/sea_esf_rad/null/standalone_clouds.F90 deleted file mode 100644 index 4d603a26a5..0000000000 --- a/src/atmos_param/sea_esf_rad/null/standalone_clouds.F90 +++ /dev/null @@ -1,417 +0,0 @@ - - module standalone_clouds_mod - -use fms_mod, only: mpp_pe, mpp_root_pe, & - error_mesg, FATAL, & - write_version_number -use rad_utilities_mod, only: cld_specification_type, & - cldrad_properties_type, & - microphysics_type, & - microrad_properties_type -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! standalone cloud radiative properties module -! -!-------------------------------------------------------------------- - - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: standalone_clouds.F90,v 15.0 2007/08/14 03:55:18 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public & - standalone_clouds_init, & - standalone_clouds_end, & - define_column_properties, & - standalone_clouds_amt, obtain_micro_lw_sa, obtain_micro_sw_sa, & - obtain_bulk_lw_sa, obtain_bulk_sw_sa - -logical :: module_is_initialized = .false. -!---------------------------------------------------------------------- -!---------------------------------------------------------------------- - contains - - -!#################################################################### - -subroutine standalone_clouds_init (pref, lonb, latb) - -!-------------------------------------------------------------------- -! subroutine standalone_clouds_init is the constructor for the -! standalone_clouds_mod. -!--------------------------------------------------------------------- - -real, dimension(:,:), intent(in) :: pref -real, dimension(:,:), intent(in) :: lonb, latb - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! pref array containing two reference pressure profiles -! for use in defining transmission functions [ Pa ] -! lonb array of model longitudes on cell boundaries -! [ radians ] -! latb array of model latitudes at cell boundaries [radians] -! -!--------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! write namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) - -!-------------------------------------------------------------------- -! mark the module as initialized. -!-------------------------------------------------------------------- - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('standalone_clouds_init', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine standalone_clouds_init - - - -!#################################################################### - -subroutine define_column_properties (pref, lonb, latb) - -!--------------------------------------------------------------------- -! subroutine define_column_properties defines values for lw emiss- -! ivity, visible and nir reflectivity and nir absorption to be used -! with standalone clouds. -!--------------------------------------------------------------------- - -!-------------------------------------------------------------------- -real, dimension(:,:), intent(in) :: pref -real, dimension(:,:), intent(in) :: lonb, latb - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! pref array containing two reference pressure profiles -! for use in defining transmission functions [ Pa ] -! lonb array of model longitudes on cell boundaries -! [ radians ] -! latb array of model latitudes at cell boundaries [radians] -! -!---------------------------------------------------------------------- - - call error_mesg('define_column_properties', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine define_column_properties - -!###################################################################### - -subroutine standalone_clouds_end - -!---------------------------------------------------------------------- -! standalone_clouds_end is the destructor for standalone_clouds_mod. -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! mark the module as not initialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - - call error_mesg('standalone_clouds_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine standalone_clouds_end - -!################################################################# - -subroutine standalone_clouds_amt (is, ie, js, je, lat, press_mks, & - Cld_spec) - -!--------------------------------------------------------------------- -! standalone_clouds_amt defines the number, amount (cloud fraction), -! and type (hi, mid, low) of clouds present on the model grid. -!---------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -real, dimension(:,:), intent(in) :: lat -real, dimension(:,:,:), intent(in) :: press_mks -type(cld_specification_type), intent(inout) :: Cld_spec - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! lat latitude of model points [ radians ] -! press_mks pressure at model levels (1:nlev), surface -! pressure is stored at index value nlev+1 -! [ (kg /( m s^2) ] -! -! intent(inout) variables: -! -! Cld_spec cld_specification_type variable containing the -! cloud specification input fields needed by the -! radiation package -! -! the following elements of Cld_spec are defined here: -! -! %cmxolw fraction of maximally overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %crndlw fraction of randomly overlapped clouds -! seen by the longwave radiation -! [ dimensionless ] -! %camtsw cloud fraction seen by the shortwave -! radiation; the sum of the maximally -! overlapped and randomly overlapped -! longwave cloud fractions [ dimensionless ] -! %nmxolw number of maximally overlapped longwave -! clouds in each grid column. -! %nrndlw number of randomly overlapped longwave -! clouds in each grid column. -! %ncldsw number of clouds seen by he shortwave -! radiation in each grid column. -! %hi_cld logical flag indicating the presence of -! high clouds in a grid box -! %mid_cld logical flag indicating the presence of -! middle clouds in a grid box -! %low_cld logical flag indicating the presence of -! low clouds in a grid box -! -!--------------------------------------------------------------------- - - call error_mesg('standalone_clouds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine standalone_clouds_amt - - - -!##################################################################### - -subroutine obtain_micro_lw_sa (is, ie, js, je, Lsc_microphys, & - Meso_microphys, Cell_microphys, & - Lscrad_props, Mesorad_props, & - Cellrad_props) - -!--------------------------------------------------------------------- -! obtain_micro_lw_sa defines microphysically-based longwave cloud -! radiative properties when the code is executed in standalone -! columns mode. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(microphysics_type), intent(inout) :: Lsc_microphys, & - Meso_microphys, & - Cell_microphys -type(microrad_properties_type), intent(inout) :: Lscrad_props, & - Mesorad_props, & - Cellrad_props - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Lsc_microphys microphysical specification for large-scale -! clouds, provides input to this subroutine -! [ microphysics_type ] -! Meso_microphys microphysical specification for meso-scale -! clouds, provides input to this subroutine -! [ microphysics_type ] -! Cell_microphys microphysical specification for cell-scale -! clouds, provides input to this subroutine -! [ microphysics_type ] -! Lscrad_props cloud radiative properties on model grid, -! [ microrad_properties_type ] -! Mesorad_props meso-scale cloud radiative properties on -! model grid, [ microrad_properties_type ] -! Cellrad_props cell-scale cloud radiative properties on -! model grid, [ microrad_properties_type ] -! -! the following component of the **_props variables is -! output from this routine: -! -! %abscoeff absorption coefficient for -! clouds in each of the longwave -! frequency bands [ km **(-1) ] -! -!--------------------------------------------------------------------- - - call error_mesg('obtain_micro_lw_sa', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_micro_lw_sa - -!##################################################################### - -subroutine obtain_micro_sw_sa (is, ie, js, je, Lsc_microphys, & - Meso_microphys, Cell_microphys, & - Lscrad_props, Mesorad_props, & - Cellrad_props) - -!-------------------------------------------------------------------- -! obtain_micro_sw_sa defines microphysically-based shortwave cloud -! radiative properties for the standalone cloud scheme when run in -! columns mode. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(microphysics_type), intent(inout) :: Lsc_microphys, & - Meso_microphys, & - Cell_microphys -type(microrad_properties_type), intent(inout) :: Lscrad_props, & - Mesorad_props, & - Cellrad_props - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Lsc_microphys microphysical specification for large-scale -! clouds, provides input to this subroutine -! [ microphysics_type ] -! Meso_microphys microphysical specification for meso-scale -! clouds, provides input to this subroutine -! [ microphysics_type ] -! Cell_microphys microphysical specification for cell-scale -! clouds, provides input to this subroutine -! [ microphysics_type ] -! Lscrad_props large-scale cloud radiative properties on -! model grid, [ microrad_properties_type ] -! Mesorad_props meso-scale cloud radiative properties on -! model grid, [ microrad_properties_type ] -! Cellrad_props cell-scale cloud radiative properties on -! model grid, [ microrad_properties_type ] -! -! the following components of the microrad_properties -! variables are output from this routine: -! -! %cldext sw extinction coefficient for -! clouds in each of the shortwave -! frequency bands [ km **(-1) ] -! %cldsct sw scattering coefficient for -! clouds in each of the shortwave -! frequency bands [ km **(-1) ] -! %cldasymm sw asymmetry factor for -! clouds in each of the shortwave -! frequency bands [ dimensionless ] -! -!----------------------------------------------------------------- - - call error_mesg('obtain_micro_sw_sa', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_micro_sw_sa - -!##################################################################### - -subroutine obtain_bulk_lw_sa (is, ie, js, je, Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_lw_sa defines bulk longwave cloud radiative properties -! when using specified clouds in the standalone columns mode. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!-------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! the following components of this variable are output -! from this routine: -! -! %emrndlw longwave cloud emissivity for -! randomly overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! %emmxolw longwave cloud emissivity for -! maximally overlapped clouds -! in each of the longwave -! frequency bands [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_lw_sa', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_lw_sa - - -!##################################################################### - -subroutine obtain_bulk_sw_sa (is, ie, js, je, Cldrad_props) - -!--------------------------------------------------------------------- -! obtain_bulk_sw_sa defines bulk shortwave cloud radiative -! properties for the specified cloud scheme when running in -! standalone columns mode. -!--------------------------------------------------------------------- - -integer, intent(in) :: is, ie, js, je -type(cldrad_properties_type), intent(inout) :: Cldrad_props - -!--------------------------------------------------------------------- -! intent(in) variables: -! -! is,ie,js,je starting/ending subdomain i,j indices of data in -! the physics_window being integrated -! -! intent(inout) variables: -! -! Cldrad_props cloud radiative properties on model grid, -! [ cldrad_properties_type ] -! -! %cirabsw absorptivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cirrfsw reflectivity of clouds in the -! infrared frequency band -! [ dimensionless ] -! %cvisrfsw reflectivity of clouds in the -! visible frequency band -! [ dimensionless ] -! -!--------------------------------------------------------------------- - - call error_mesg('obtain_bulk_sw_sa', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine obtain_bulk_sw_sa - -!##################################################################### - - end module standalone_clouds_mod - - - - - diff --git a/src/atmos_param/sea_esf_rad/null/uw_clouds_W.F90 b/src/atmos_param/sea_esf_rad/null/uw_clouds_W.F90 deleted file mode 100644 index c2198b802f..0000000000 --- a/src/atmos_param/sea_esf_rad/null/uw_clouds_W.F90 +++ /dev/null @@ -1,241 +0,0 @@ -!FDOC_TAG_GFDL - - module uw_clouds_W_mod -!tice ) then - if ( qr(k)>qrmin .and. ql(k)>1.E-8 .and. qsat ql & ql --> qr -! Edges: qE == qbar +/- dm - integer, intent(in):: km - real, intent(in ):: p1(km), q(km) - real, intent(out):: dm(km) - logical, intent(in):: z_var - real, intent(in):: h_var -! - real:: dq(km) - integer:: k - - if ( z_var ) then - do k=2,km - dq(k) = 0.5*(q(k) - q(k-1)) - enddo - dm(1) = 0. - do k=2, km-1 -! Use twice the strength of the positive definiteness limiter (Lin et al 1994) - dm(k) = 0.5*min(abs(dq(k) + dq(k+1)), 0.5*q(k)) - if ( dq(k)*dq(k+1) <= 0. ) then - if ( dq(k) > 0. ) then ! Local max - dm(k) = min( dm(k), dq(k), -dq(k+1) ) - else - dm(k) = 0. - endif - endif - enddo - dm(km) = 0. -! impose a presumed background horizontal variability that is proportional to the value itself - do k=1, km - dm(k) = max( dm(k), qvmin, h_var*q(k) ) - enddo - else - do k=1, km - dm(k) = max( qvmin, h_var*q(k) ) - enddo - endif - - end subroutine linear_prof - - - subroutine icloud(ktop, kbot, tzk, p1, qvk, qlk, qrk, qik, qsk, qgk, dp1, & - den, denfac, vts, vtg, vtr, qak, h_var) - -!---------------------------------------------------- -! Bulk cloud micro-physics; processes splitting -! with some un-split sub-grouping -! Time implicit (when possible) accretion and autoconversion -! Author: Shian-Jiann Lin, GFDL -!------------------------------------------------------- - - integer, intent(in) :: ktop, kbot - real, intent(in), dimension(ktop:kbot):: p1, dp1, den, denfac, vts, vtg, vtr - real, intent(inout), dimension(ktop:kbot):: tzk, qvk, qlk, qrk, qik, qsk, qgk, qak - real, intent(in) :: h_var -! local: - real, parameter:: rhos = 0.1e3 ! snow density (1/10 of water) - real, dimension(2*(kbot-ktop-1)):: p2, den2, tz2, qv2, ql2, qr2, qs2, qi2, qg2, qa2 - real, dimension(ktop:kbot) :: lcpk, icpk, tcpk, di - real :: tz, qv, ql, qr, qi, qs, qg, melt - real :: praut, pracw, pracs, psacw, pgacw, pgmlt, & - psmlt, prevp, psacr, pgacr, pgfr, pgacs, & - pgaut, pgaci, praci, psaut, psaci, piacr - real :: tc, tsq, dqs0, qden, qim, qsm - real :: factor, sink - real :: tmp1, qsw, qsi, dqsdt, dq - real :: n0s, lamda - real :: qc, q_plus, q_minus - integer :: km, kn - integer :: i, j, k, k1 - - do k=ktop,kbot -!-------------------------------------- -! tmp = cp - rdgas*ptop/p1(k) -! lcpk(k) = latv / tmp -! icpk(k) = lati / tmp -! tcpk(k) = lcpk(k) + icpk(k) -!-------------------------------------- - lcpk(k) = lcp - icpk(k) = icp - tcpk(k) = tcp - enddo - -! Sources of cloud ice: pihom, cold rain, and the sat_adj -! (initiation plus deposition) - -! Sources of snow: cold rain, auto conversion + accretion (from cloud ice) -! sat_adj (deposition; requires pre-existing snow); initial snow comes from auto conversion - - do k=ktop, kbot -!-------------------------------------- -! * pimlt: instant melting of cloud ice -!-------------------------------------- - if( tzk(k) > tice .and. qik(k) > qcmin ) then - melt = min( qik(k), (tzk(k)-tice)/icpk(k) ) -! qim = qi0_crt / den(k) - qim = qi0_crt -! min rain due to melted snow autoconversion - tmp1 = min( melt, dim(qik(k),qim) ) -! limit max ql amount to no greater than snow autocon threshold - tmp1 = min( melt-tmp1, dim(qim, qlk(k)) ) - qlk(k) = qlk(k) + tmp1 - qrk(k) = qrk(k) + melt - tmp1 - qik(k) = qik(k) - melt - tzk(k) = tzk(k) - melt*icpk(k) - endif - enddo - - call linear_prof( kbot-ktop+1, p1(ktop), qik(ktop), di(ktop), .false., h_var ) - - do 3000 k=ktop, kbot - - if( tzk(k) < t_min ) goto 3000 - - tz = tzk(k) - qv = qvk(k) - ql = qlk(k) - qi = qik(k) - qr = qrk(k) - qs = qsk(k) - qg = qgk(k) - -!-------------------------------------- -! *** Split-micro_physics_processes *** -!-------------------------------------- -! Zetac: excluded (from LFO83) term: psdep -! pgwet and realidw removed by SJL - - pgacr = 0. - pgacw = 0. - - tc = tz-tice -if ( tc > 0. ) then - -!----------------------------- -!* Melting of snow and graupel -!----------------------------- - dqs0 = ces0/p1(k) - qv - -#ifdef MORE_SNOW_MELT - if ( qs>qvmin ) then -! Melting of snow into rain - factor = min( 1., tc/t_snow_melt ) - sink = min( fac_sno*qs, factor*tc/icpk(k) ) - qs = qs - sink - qr = qr + sink - tz = tz - sink*icpk(k) ! cooling due to snow melting - tc = tz-tice - endif -#endif - - if( qs>qcmin ) then - -! * accretion: cloud water --> snow -! only rate is used (for snow melt) since tc > 0. - if( ql>qrmin ) then - factor = denfac(k)*csacw*exp(0.8125*log(qs*den(k))) - psacw = factor/(1.+dts*factor)*ql ! rate - else - psacw = 0. - endif - - if ( qr>qrmin ) then -! * accretion: melted snow --> rain: - psacr = min(acr3d(vts(k), vtr(k), qr, qs, csacr, acco(1,2), den(k)), qr*rdts) -! * accretion: snow --> rain - pracs = acr3d(vtr(k), vts(k), qs, qr, cracs, acco(1,1), den(k)) - else - psacr = 0. - pracs = 0. - endif - -! Total snow sink: -! * Snow melt (due to rain accretion): snow --> rain - psmlt = max(0., smlt(tc, dqs0, qs*den(k), psacw, psacr, csmlt, den(k), denfac(k))) - sink = min(qs, dts*(psmlt+pracs), tc/icpk(k)) - - qs = qs - sink - qr = qr + sink - tz = tz - sink*icpk(k) ! cooling due to snow melting - tc = tz-tice - endif - - if ( qg>qcmin .and. tc>0. ) then - if ( qr>qrmin ) then -! * accretion: rain --> graupel - pgacr = min(acr3d(vtg(k), vtr(k), qr, qg, cgacr, acco(1,3), den(k)), rdts*qr) - endif - - qden = qg*den(k) - if( ql>qrmin ) then -! * accretion: cloud water --> graupel -! factor = cgacw/sqrt(den(k))*(qg*den(k))**0.875 - factor = cgacw*qden/sqrt(den(k)*sqrt(sqrt(qden))) - pgacw = factor/(1.+dts*factor) * ql ! rate - endif - -! * melting: graupel --> rain - pgmlt = dts*gmlt(tc, dqs0, qden, pgacw, pgacr, cgmlt, den(k)) - pgmlt = min( max(0., pgmlt), qg, tc/icpk(k) ) - qg = qg - pgmlt - qr = qr + pgmlt - tz = tz - pgmlt*icpk(k) - endif ! graupel existed - -elseif( tc < 0.0 ) then - -!------------------ -! Cloud ice proc: -!------------------ - if ( qi>1.E-8 ) then - -!---------------------------------------- -! * accretion (pacr): cloud ice --> snow -!---------------------------------------- - if ( qs>1.E-8 ) then -! The following is originally from the "Lin Micro-physics" in Zetac -! SJL added (following Lin Eq. 23) the temperature dependency -! To reduce accretion, use Esi = exp(0.05*tc) as in Hong et al 2004 -! To increase ice/reduce snow: exp(0.025*tc) - factor = dts*denfac(k)*csaci*exp(0.05*tc + 0.8125*log(qs*den(k))) - psaci = factor/(1.+factor) * qi - else - psaci = 0. - endif - -!------------------------------------- -! * autoconversion: cloud ice --> snow -!------------------------------------- -! Similar to LFO 1983: Eq. 21 solved implicitly -! Threshold from WSM6 scheme, Hong et al 2004, Eq(13) : qi0_crt ~0.8E-4 -! qim = qi0_crt / den(k) - qim = qi0_crt - -! Assuming linear subgrid vertical distribution of cloud ice -! The mismatch computation following Lin et al. 1994, MWR - di(k) = max( di(k), qrmin ) - q_plus = qi + di(k) - if ( q_plus > (qim+qrmin) ) then - if ( qim > (qi - di(k)) ) then - dq = 0.25*(q_plus-qim)**2 / di(k) - else - dq = qi - qim - endif - factor = dts*c_psaut*exp(0.025*tc) - psaut = factor/(1.+factor) * dq - else - psaut = 0. - endif - - sink = min( qi, psaci+psaut ) - qi = qi - sink - qs = qs + sink - -!----------------------------------- -! * accretion: cloud ice --> graupel -!----------------------------------- - if ( qg>qrmin .and. qi>1.E-7 ) then -! factor = dts*cgaci/sqrt(den(k))*(qg*den(k))**0.875 -! SJL added exp(0.025*tc) efficiency factor - factor = dts*cgaci/sqrt(den(k))*exp(0.025*tc + 0.875*log(qg*den(k))) - pgaci = factor/(1.+factor)*qi - qi = qi - pgaci - qg = qg + pgaci - endif - - endif ! cloud ice existed - -!---------------- -! Cold-Rain proc: -!---------------- -! rain to ice, snow, graupel processes: - - tc = tz-tice - - if ( qr>qrmin .and. tc < 0. ) then - -! * accretion: accretion of cloud ice by rain to produce snow or graupel -! (LFO: produces snow or graupel; cloud ice sink.. via psacr & pgfr) -! ice --> snow OR graupel (due to falling rain) -! No change to qr and tz - if ( qi > qrmin ) then -! SJL added exp(0.025*tc) efficiency factor as follows: -! factor = dts*denfac(k)*craci*exp(0.025*tc + 0.95*log(qr*den(k))) - factor = dts*denfac(k)*craci*exp(0.95*log(qr*den(k))) - praci = factor/(1.+factor)*qi -! if ( qr > qr0_crt/den(k) ) then - if ( qr > qr0_crt ) then - qg = qg + praci - else - qs = qs + praci - endif - qi = qi - praci - endif - -! *sink* terms to qr: psacr + piacr + pgfr -! source terms to qs: psacr -! source terms to qi: piacr -! source terms to qg: pgfr - -! * accretion of rain by snow - if ( qs > 1.E-8 ) then ! if snow exists - psacr = dts*acr3d(vts(k), vtr(k), qr, qs, csacr, acco(1,2), den(k)) - else - psacr = 0. - endif - -! The following added by SJL (missing from Zetac) -! * piacr: accretion of rain by cloud ice [simplified from lfo 26] -! The value of c_piacr needs to be near order(1) to have significant effect -!------------------------------------------------------------------- -! rain --> ice - if ( qi > qrmin ) then - factor = dts*denfac(k)*qi * c_piacr - piacr = factor/(1.+factor)*qr - else - piacr = 0. - endif - -!------------------------------------------------------------------- -! * rain freezing --> graupel -!----------------------------------------------------------------------------------- - pgfr = dts*cgfr(1)*(exp(-cgfr(2)*tc)-1.)*(qr*den(k))**1.75/den(k) - qden = qr*den(k) - pgfr = dts*cgfr(1)*(exp(-cgfr(2)*tc)-1.)*qden*qden/(sqrt(sqrt(qden))*den(k)) -!----------------------------------------------------------------------------------- - -!--- Total sink to qr - sink = psacr + piacr + pgfr - factor = min( sink, qr, -0.5*tc/icpk(k) ) / max( sink, qrmin ) - - psacr = factor * psacr - piacr = factor * piacr - pgfr = factor * pgfr - - sink = psacr + piacr + pgfr - tz = tz + sink*icpk(k) - qr = qr - sink - qs = qs + psacr - qi = qi + piacr - qg = qg + pgfr - tc = tz - tice - endif ! qr existed - -!------------------ -! Cloud water sink: -!------------------ - if( ql>qcmin ) then - -! * pihom * homogeneous Freezing of cloud water into cloud ice: -! This is the 1st occurance of liquid water freezing in the split MP process -! done here to prevents excessive snow production -#ifdef USE_T_WFR - if( tz < t_00 + dt_fr ) then - factor = min( 1., (t_00 + dt_fr - tz)/dt_fr ) - sink = min( ql*factor, (t_00+dt_fr-tz)/icpk(k) ) - ql = ql - sink - qi = qi + sink - tz = tz + sink*icpk(k) - endif -#else - if( tz < t_00 ) then - sink = min( ql, (t_00-tz)/icpk(k) ) - ql = ql - sink - qi = qi + sink - tz = tz + sink*icpk(k) - endif -#endif - -! * cloud water --> Snow (requires pre-existing cloud ice) - - if( qs>1.E-8 .and. ql>1.E-8 .and. qi>1.E-8 ) then -! The following originally from Zetac: PSACW - factor = dts*denfac(k)*csacw*exp(0.8125*log(qs*den(k))) - psacw = min( factor/(1.+factor)*ql, -tc/icpk(k) ) - qs = qs + psacw - ql = ql - psacw - tz = tz + psacw*icpk(k) - endif - - endif ! (significant) cloud water existed - -!-------------------------- -! Graupel production terms: -!-------------------------- - - if( qs > qrmin ) then -! * accretion: snow --> graupel - if ( qg > qrmin ) then - sink = dts*acr3d(vtg(k), vts(k), qs, qg, cgacs, acco(1,4), den(k)) - else - sink = 0. - endif - - qsm = qs0_crt / den(k) - if ( qs > qsm ) then -! * Autoconversion Snow --> graupel - factor = dts*1.e-3*exp(0.09*(tz-tice)) - sink = sink + factor/(1.+factor)*(qs-qsm) - endif - sink = min( qs, sink ) - qs = qs - sink - qg = qg + sink - - endif ! snow existed - - if ( qg>qrmin .and. tz < tice ) then - -#ifndef PGACW_OFF -! * accretion: cloud water --> graupel - if( ql>1.E-8 ) then -! factor = dts*cgacw/sqrt(den(k))*(qg*den(k))**0.875 -! Optimized form: - qden = qg*den(k) - factor = dts*cgacw*qden/sqrt(den(k)*sqrt(sqrt(qden))) - pgacw = factor/(1.+factor)*ql - else - pgacw = 0. - endif -#else - pgacw = 0. -#endif - -! * accretion: rain --> graupel - if ( qr>qrmin ) then - pgacr = min(dts*acr3d(vtg(k), vtr(k), qr, qg, cgacr, acco(1,3), den(k)), qr) - else - pgacr = 0. - endif - - sink = pgacr + pgacw - factor = min( sink, 0.5*(tice-tz)/icpk(k) ) / max( sink, qrmin ) - pgacr = factor * pgacr - pgacw = factor * pgacw - - sink = pgacr + pgacw - tz = tz + sink*icpk(k) - qg = qg + sink - qr = qr - pgacr - ql = ql - pgacw - - endif ! graupel existed - -endif ! end ice-physics - - tzk(k) = tz - qvk(k) = qv - qlk(k) = ql - qik(k) = qi - qrk(k) = qr - qsk(k) = qs - qgk(k) = qg - -3000 continue ! k-loop - - if ( do_subgrid_z ) then - -! Except top 2 and bottom 2 layers (4 layers total), using subgrid PPM distribution -! to perform saturation adjustment at 2X the vertical resolution - - kn = kbot - ktop + 1 - km = 2*(kbot-ktop-1) - - p2(1) = p1(ktop ) - p2(2) = p1(ktop+1) - do k=3,km-3,2 - k1 = ktop+1 + k/2 - p2(k ) = p1(k1) - 0.25*dp1(k1) - p2(k+1) = p1(k1) + 0.25*dp1(k1) - enddo - - if ( mp_debug ) then - if (k1 /= (kbot-2)) then - write(*,*) 'FATAL: k1=', k1 - call error_mesg ('LIN_CLD_MICROPHYS:', 'DO_MAP2_SAT', FATAL) - endif - endif - - p2(km-1) = p1(kbot-1) - p2(km ) = p1(kbot) - - call remap2(ktop, kbot, kn, km, dp1, tzk, tz2, 1) - call remap2(ktop, kbot, kn, km, dp1, qvk, qv2, 1) - call remap2(ktop, kbot, kn, km, dp1, qlk, ql2, 1) - call remap2(ktop, kbot, kn, km, dp1, qik, qi2, 1) - call remap2(ktop, kbot, kn, km, dp1, qsk, qs2, 1) - call remap2(ktop, kbot, kn, km, dp1, qgk, qg2, 1) - - do k=1,km - den2(k) = p2(k)/(rdgas*tz2(k)) - qa2(k) = 0. - enddo - - call subgrid_z_proc(1, km, p2, den2, h_var, tz2, qv2, ql2, qi2, qs2, qg2, qa2) - -! Remap back to original larger volumes: - qak(ktop ) = qak(ktop ) + qa2(1) - qak(ktop+1) = qak(ktop+1) + qa2(2) - - tzk(ktop ) = tz2(1) - tzk(ktop+1) = tz2(2) - - qvk(ktop ) = qv2(1) - qvk(ktop+1) = qv2(2) - - qlk(ktop ) = ql2(1) - qlk(ktop+1) = ql2(2) - - qik(ktop ) = qi2(1) - qik(ktop+1) = qi2(2) - - qsk(ktop ) = qs2(1) - qsk(ktop+1) = qs2(2) - - qgk(ktop ) = qg2(1) - qgk(ktop+1) = qg2(2) - - do k=3,km-3,2 - k1 = ktop+1 + k/2 - qak(k1) = qak(k1) + max(qa2(k), qa2(k+1)) ! Maximum only -! Subgrid overlap schemes: max and random parts weighted by subgrid horizontal deviation -!------------------------------------------------------------------------------------- -! Random cloud fraction = 1 - (1-a1)*(1-a2) = a1 + a2 - a1*a2 -! RAND_CLOUD -! qak(k1) = qak(k1) + (1.-h_var)*max(qa2(k), qa2(k+1)) & ! Maximum fraction -! + h_var*(qa2(k)+qa2(k+1)-qa2(k)*qa2(k+1)) ! Random fraction -!------------------------------------------------------------------------------------- - tzk(k1) = 0.5*(tz2(k) + tz2(k+1)) - qvk(k1) = 0.5*(qv2(k) + qv2(k+1)) - qlk(k1) = 0.5*(ql2(k) + ql2(k+1)) - qik(k1) = 0.5*(qi2(k) + qi2(k+1)) - qsk(k1) = 0.5*(qs2(k) + qs2(k+1)) - qgk(k1) = 0.5*(qg2(k) + qg2(k+1)) - enddo - - qak(kbot-1) = qak(kbot-1) + qa2(km-1) - qak(kbot ) = qak(kbot ) + qa2(km ) - - tzk(kbot-1) = tz2(km-1) - tzk(kbot ) = tz2(km ) - - qvk(kbot-1) = qv2(km-1) - qvk(kbot ) = qv2(km ) - - qlk(kbot-1) = ql2(km-1) - qlk(kbot ) = ql2(km ) - - qik(kbot-1) = qi2(km-1) - qik(kbot ) = qi2(km ) - - qsk(kbot-1) = qs2(km-1) - qsk(kbot ) = qs2(km ) - - qgk(kbot-1) = qg2(km-1) - qgk(kbot ) = qg2(km ) - else - call subgrid_z_proc(ktop, kbot, p1, den, h_var, tzk, qvk, qlk, qik, qsk, qgk, qak) - endif - - end subroutine icloud - - - subroutine remap2(ktop, kbot, kn, km, dp, q1, q2, id) - integer, intent(in):: ktop, kbot, kn, km , id -! constant distribution if id ==0 - real, intent(in), dimension(ktop:kbot):: q1, dp - real, intent(out):: q2(km) -! local - real:: a4(4,ktop:kbot) - real:: tmp - integer:: k, k1 - - q2(1) = q1(ktop ) - q2(2) = q1(ktop+1) - - if ( id==1 ) then - - do k=ktop,kbot - a4(1,k) = q1(k) - enddo - call cs_profile( a4(1,ktop), dp(ktop), kn, mono_prof ) ! non-monotonic - - do k=3,km-3,2 - k1 = ktop+1 + k/2 - q2(k ) = min( 2.*q1(k1), max( qvmin, a4(1,k1) + 0.25*(a4(2,k1)-a4(3,k1)) ) ) - q2(k+1) = 2.*q1(k1) - q2(k) - enddo - - else - do k=3,km-3,2 - k1 = ktop+1 + k/2 - q2(k ) = q1(k1) - q2(k+1) = q1(k1) - enddo - endif - - q2(km-1) = q1(kbot-1) - q2(km ) = q1(kbot) - - end subroutine remap2 - - - - subroutine subgrid_z_proc(ktop, kbot, p1, den, h_var, tz, qv, ql, qi, qs, qg, qa) - -! Temperature sentive high vertical resolution processes: - - integer, intent(in):: ktop, kbot - real, intent(in), dimension(ktop:kbot):: p1, den - real, intent(in) :: h_var - real, intent(inout), dimension(ktop:kbot):: tz, qv, ql, qi, qs, qg, qa -! local: -! qstar over water may be accurate only down to -80 C with ~10% uncertainty -! must not be too large to allow PSC - real:: denf, rh, clouds, rqi, tin, qsw, qsi, qpz, qstar - real:: dqsdt, dwsdt, dq, qimin, pidep, factor, tmp, pgsub - real:: qlv, q_plus, q_minus, qi_crt, dqh, qlt - real:: evap, sink, qden, tc, tsq, pisub, pssub, iwt, q_adj, qq, f_frz - integer :: k - - do 4000 k=ktop,kbot - -! Quick pass check -!----------------- - if ( tz(k) < t_min ) goto 4000 - -! Instant evaporation/sublimation of all clouds if RH cloud free -! This segment is the only true "saturation adjustment" in this code, and it -! operates only for low RH (set by rh_adj) - -! iwt = qi(k) + qs(k) -! Do not include snow - iwt = qi(k) - clouds = ql(k) + iwt - - tin = tz(k) - ( lcp*clouds + icp*iwt ) ! minimum temperature - qpz = qv(k) + clouds ! conserved within subgrid_z_proc - rh = qpz*p1(k)/(eps*es2_table(tin)) ! 2-phase (pure ice & water) - - if ( rh evap < ql; therefore ql will never be completely evaporated within this step -! Complete evaporation happens in the pre-conditioner if conditions are met -!--------------------------------------------------------------------------------------------------- - qsw = ws1d(tz(k), p1(k), dwsdt) - evap = 0. - dq = qsw - qv(k) - q_adj = dq / (1.+lcp*dwsdt) ! maximum possible change amount to qv - - if( dq > 0.0 .and. ql(k)>qcmin ) then -! Evaporation of ql: - evap = min( fac_l2v*(dq/qsw)*ql(k), q_adj ) - endif - if( dq < 0.0 ) then -! Condensation: - evap = max( fac_v2l*dq, q_adj ) - endif - - if ( abs(evap) > qvmin ) then - qv(k) = qv(k) + evap - ql(k) = ql(k) - evap - tz(k) = tz(k) - evap*lcp - endif - - tc = tz(k) - tice - - if ( tc < 0. ) then - -! *********** freezing of cloud water ******** -! -- pihom -- - - if( ql(k) > qcmin ) then -! SJL, May 21, 2012 -! Complete freezing below t_00 (-48 C) -! tmp = estimated maximum warming (deg K) due to freezing - tmp = ql(k)*icp*min( 1., tc/(t_00 - tice)) - tmp = min( tmp, -tc ) - factor = tc/(t_00 - tice - tmp) - if ( factor > 0.999 ) then - sink = min( ql(k), (t_wfr-tz(k))/icp ) - else -! freezing time scale = tau_frz*(1-factor)/factor -! Biggs form ~ qq**2 * density * [exp(-0.66tc)-1] -! qq = ql(k)/q00 -! f_frz = 1. - exp( -dts*qq*qq*den(k)*factor/(tau_frz*(1.-factor)) ) -!------------------------------------------------------------------- - f_frz = 1. - exp( -dts*factor/(tau_frz*(1.-factor)) ) - sink = min( f_frz*ql(k), -tc/icp ) - endif - ql(k) = ql(k) - sink - qi(k) = qi(k) + sink - tz(k) = tz(k) + sink*icp - endif ! significant ql existed - -!-------------------------------------------------------------- -! Simplified ice <--> vapor exchange scheme -!-------------------------------------------------------------- -! Fowler, Randall, and Rutledge 1996, solved exactly in time - tc = tz(k) - tice - qsi = qs1d(tz(k), p1(k), dqsdt) - dq = qv(k) - qsi - - if ( dq > 0. ) then -! vapor ---> ice (does not require pre-existing ice) - pisub = min( fac_v2i*dq, dq/(1.+tcp*dqsdt), -tc/tcp ) - qi(k) = qi(k) + pisub - qv(k) = qv(k) - pisub - tz(k) = tz(k) + pisub*tcp - elseif ( qi(k) > qcmin ) then ! qi --> qv - pisub = -max( fac_i2v*dq*qi(k)/qsi, dq/(1.+tcp*dqsdt) ) - qv(k) = qv(k) + pisub - qi(k) = qi(k) - pisub - tz(k) = tz(k) - pisub*tcp - endif - -!------------------------------ -! * Snow sublimation-deposition -!------------------------------ - tc = tz(k) - tice - if ( qs(k) > qcmin .and. tc < 0. ) then - qsi = qs1d(tz(k), p1(k), dqsdt) - dq = qv(k) - qsi - sink = dq/(1.+tcp*dqsdt) - if ( dq > 0. ) then -! vapor --> snow - pssub = min( fac_v2s*dq*qs(k)/qsi, sink, -tc/tcp ) - qs(k) = qs(k) + pssub - qv(k) = qv(k) - pssub - tz(k) = tz(k) + pssub*tcp - else -! snow --> vapor -! This is not sufficient to completely evaporate snow - pssub = -max( fac_s2v*dq*qs(k)/qsi, sink ) - qv(k) = qv(k) + pssub - qs(k) = qs(k) - pssub - tz(k) = tz(k) - pssub*tcp - endif - endif ! snow existed - -!--------------------------------- -! * Grapuel sublimation-deposition -!--------------------------------- - if ( qg(k) > qcmin ) then - qsi = qs1d(tz(k), p1(k), dqsdt) - dq = qv(k) - qsi - sink = dq/(1.+tcp*dqsdt) - pgsub = (qv(k)/qsi-1.) * qg(k) - - if ( pgsub > 0. ) then ! deposition - pgsub = min( fac_v2g*pgsub, sink, (tice-tz(k))/tcp ) - else ! submilation - pgsub = max( fac_g2v*pgsub, sink ) - endif - - qg(k) = qg(k) + pgsub - qv(k) = qv(k) - pgsub - tz(k) = tz(k) + pgsub*tcp - endif ! graupel existed - - endif ! sub-freezing check - -! use cloud condensates at true temperature to determine the water/ice partition -! iwt = qi(k) + qs(k) - - iwt = qi(k) - clouds = ql(k) + iwt - qpz = qv(k) + clouds - tin = tz(k) - ( lcp*clouds + icp*iwt ) ! minimum temperature - -!-------------------- -! * determine qstar -!-------------------- -! Using the "liquid-frozen water temperature": tin - if( tin <= t_wfr ) then - qstar = iqsat(tin, p1(k)) - elseif ( tin >= tice ) then - qstar = wqsat(tin, p1(k)) - else -! mixed phase: - qsi = iqsat(tin, p1(k)) - qsw = wqsat(tin, p1(k)) - if( clouds > 3.E-6 ) then - rqi = iwt / clouds - else -! Mostly liquid water clouds at initial cloud development stage - rqi = (tice-tin)/(tice-t_wfr) -! rqi = rqi ** 2 ! biased towards water phase when little condensates exist - endif - qstar = rqi*qsi + (1.-rqi)*qsw - endif - -!------------------------- -! * cloud fraction -!------------------------- -! Assuming subgrid linear distribution in horizontal; this is effectively a smoother for the -! binary cloud scheme - - if ( qpz > qrmin ) then -! Partial cloudiness by PDF: - dq = max(qcmin, h_var*qpz) - q_plus = qpz + dq ! cloud free if qstar > q_plus - q_minus = qpz - dq - if ( qstar < q_minus ) then - qa(k) = qa(k) + 1. ! Air fully saturated; 100 % cloud cover - elseif ( qstar qc_crt ) then - qa(k) = qa(k) + (q_plus-qstar)/(dq+dq) - endif - endif - -4000 continue - - end subroutine subgrid_z_proc - - - - subroutine terminal_fall(dtm, ktop, kbot, tz, qv, ql, qr, qg, qs, qi, pm, dz, dp, & - den, vtg, vts, vti, r1, g1, s1, i1) - -! lagrangian control-volume method: - - real, intent(in):: dtm ! time step (s) - integer, intent(in):: ktop, kbot - real, intent(in), dimension(ktop:kbot):: dp, vtg, vts, vti, pm, den - real, intent(inout), dimension(ktop:kbot):: dz, qv, ql, qr, qg, qs, qi, tz - real, intent(out):: r1, g1, s1, i1 -! local: - real, dimension(ktop:kbot+1):: ze, zt - real:: qsat, dqsdt, dt5, melt, evap, dtime - real:: factor, frac - real:: tmp1, qim, precip, tc, sink - real, dimension(ktop:kbot):: lcpk, icpk - real:: zs = 0. - integer k, k0, m - logical no_fall - - do k=ktop,kbot -! tmp1 = cp - rdgas*ptop/pm(k) -! lcpk(k) = latv / tmp1 -! icpk(k) = lati / tmp1 - lcpk(k) = lcp - icpk(k) = icp - enddo + end subroutine lin_cld_microphys_driver - dt5 = 0.5*dtm + subroutine sat_adj2(mdt, is, ie, js, je, ng, km, k, hydrostatic, consv_te, & + te0, qv, ql, qi, qr, qs, qa, area, peln, delz, pt, dp, last_step) +! This is designed for 6-class micro-physics schemes +! input pt is T_vir + real, intent(in):: mdt + integer, intent(in):: is, ie, js, je, km, ng, k + logical, intent(in):: hydrostatic, last_step + logical, intent(in):: consv_te + real, intent(in), dimension(is-ng:ie+ng,js-ng:je+ng):: dp, area + real, intent(in):: delz(is:ie,js:je) ! Delta p at each model level + real, intent(in):: peln(is:ie,km+1,js:je) ! ln(pe) + real, intent(inout), dimension(is-ng:ie+ng,js-ng:je+ng):: pt, qv, ql, qi, qr, qs, qa + real, intent(inout):: te0(is:ie,js:je) -! Melting of cloud_ice and snow (before fall): + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) -! find significant melting level - k0 = kbot - do k=ktop, kbot-1 - if ( tz(k) > tice ) then - k0 = k - go to 11 - endif - enddo -11 continue - - do k=k0, kbot -!------ -! * ice -!------ - tc = tz(k) - tice - if( qi(k) > qcmin .and. tc>0. ) then - melt = min( fac_mlt*qi(k), tc/icpk(k) ) -! qim = qi0_crt / den(k) - qim = qi0_crt -! min rain due to melted snow autoconversion - tmp1 = min( melt, dim(qi(k),qim) ) -! limit max ql amount to no greater than ice-->snow autocon threshold - tmp1 = min( melt-tmp1, dim(qim, ql(k)) ) - ql(k) = ql(k) + tmp1 - qr(k) = qr(k) + melt - tmp1 - qi(k) = qi(k) - melt - tz(k) = tz(k) - melt*icpk(k) - tc = tz(k) - tice - endif -!------ -! Snow -!------ - if ( qs(k)>qvmin .and. tc>0. ) then - factor = min( 1., tc/t_snow_melt) - sink = min(qs(k)*fac_sno, factor*tc/icpk(k)) - qs(k) = qs(k) - sink - qr(k) = qr(k) + sink - tz(k) = tz(k) - sink*icpk(k) ! cooling due to snow melting - endif - - enddo - - if ( dts < 75. ) k0 = kbot - -!----- -! ice: -!----- - - ze(kbot+1) = zs - do k=kbot, ktop, -1 - ze(k) = ze(k+1) - dz(k) ! dz<0 - enddo - - zt(ktop) = ze(ktop) - - call check_column(ktop, kbot, qi, no_fall) - - if ( vi_fac < 1.e-5 .or. no_fall ) then - i1 = 0. - else - - do k=ktop+1,kbot - zt(k) = ze(k) - dt5*(vti(k-1)+vti(k)) - enddo - zt(kbot+1) = zs - dtm*vti(kbot) - - do k=ktop,kbot - if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min - enddo - - if ( k0 < kbot ) then - do k=kbot-1,k0,-1 - if ( qi(k) > qrmin ) then - do m=k+1, kbot - if ( zt(k+1)>=ze(m) ) exit - if ( zt(k) tice ) then - dtime = min( 1.0, (ze(m)-ze(m+1))/(max(vmin,vti(k))*tau_mlt) ) - melt = min( qi(k)*dp(k)/dp(m), dtime*(tz(m)-tice)/icpk(m) ) -! qim = qi0_crt / den(m) - qim = qi0_crt - tmp1 = min( melt, dim(qi(k), qim) ) ! min rain (snow autoconversion) - tmp1 = min( melt-tmp1, dim(qim, ql(m)) ) ! limit max ql amount -! - ql(m) = ql(m) + tmp1 - qr(m) = qr(m) - tmp1 + melt - tz(m) = tz(m) - melt*icpk(m) - qi(k) = qi(k) - melt*dp(m)/dp(k) - endif - enddo - endif - enddo - endif - - if ( use_ppm ) then - call lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, qi, i1, mono_prof) - else - call lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, qi, i1) - endif - - endif - -!-------------------------------------------- -! melting of falling snow (qs) into rain(qr) -!-------------------------------------------- - r1 = 0. - - call check_column(ktop, kbot, qs, no_fall) - - if ( no_fall ) then - s1 = 0. - else - - do k=ktop+1,kbot - zt(k) = ze(k) - dt5*(vts(k-1)+vts(k)) - enddo - zt(kbot+1) = zs - dtm*vts(kbot) - - do k=ktop,kbot - if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min - enddo - - if ( k0 < kbot ) then - do k=kbot-1,k0,-1 - if ( qs(k) > qrmin ) then - do m=k+1, kbot - if ( zt(k+1)>=ze(m) ) exit - dtime = min( dtm, (ze(m)-ze(m+1))/(vmin+vts(k)) ) - if ( zt(k) tice ) then - dtime = min(1., dtime/tau_s) - melt = min(qs(k)*dp(k)/dp(m), dtime*(tz(m)-tice)/icpk(m)) - tz(m) = tz(m) - melt*icpk(m) - qs(k) = qs(k) - melt*dp(m)/dp(k) - if ( zt(k) =zt(k) ) zt(k+1) = zt(k) - dz_min - enddo - - if ( k0 < kbot ) then - do k=kbot-1,k0,-1 - if ( qg(k) > qrmin ) then - do m=k+1, kbot - if ( zt(k+1)>=ze(m) ) exit - dtime = min( dtm, (ze(m)-ze(m+1))/vtg(k) ) - if ( zt(k) tice ) then - dtime = min(1., dtime/tau_g) - melt = min(qg(k)*dp(k)/dp(m), dtime*(tz(m)-tice)/icpk(m)) - tz(m) = tz(m) - melt*icpk(m) - qg(k) = qg(k) - melt*dp(m)/dp(k) - if ( zt(k) qrmin ) then - no_fall = .false. - exit - endif - enddo - - end subroutine check_column - - - subroutine lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, q, precip) - real, intent(in):: zs - integer, intent(in):: ktop, kbot - real, intent(in), dimension(ktop:kbot):: dp - real, intent(in), dimension(ktop:kbot+1):: ze, zt - real, intent(inout), dimension(ktop:kbot):: q - real, intent(out):: precip -! local: - real, dimension(ktop:kbot):: qm1, qm2 - integer k, k0, n, m - -! density: - do k=ktop,kbot - qm1(k) = q(k)*dp(k) / (zt(k)-zt(k+1)) - qm2(k) = 0. - enddo - - k0 = ktop - do k=ktop,kbot - do n=k0,kbot - if(ze(k) <= zt(n) .and. ze(k) >= zt(n+1)) then - if(ze(k+1) >= zt(n+1)) then -! entire new grid is within the original grid - qm2(k) = qm1(n)*(ze(k)-ze(k+1)) - k0 = n - goto 555 - else - qm2(k) = qm1(n)*(ze(k)-zt(n+1)) ! fractional area - do m=n+1,kbot -! locate the bottom edge: ze(k+1) - if(ze(k+1) < zt(m+1) ) then - qm2(k) = qm2(k) + q(m)*dp(m) - else - qm2(k) = qm2(k) + qm1(m)*(zt(m)-ze(k+1)) - k0 = m - goto 555 - endif - enddo - goto 555 - endif - endif - enddo -555 continue - enddo - - precip = 0. -! direct algorithm (prevent small negatives) - do k=ktop,kbot - if ( zt(k+1) < zs ) then - precip = qm1(k)*(zs-zt(k+1)) - if ( (k+1) > kbot ) goto 777 - do m=k+1,kbot - precip = precip + q(m)*dp(m) - enddo - goto 777 - endif - enddo -777 continue - - do k=ktop,kbot - q(k) = qm2(k) / dp(k) - enddo - - end subroutine lagrangian_fall_pcm - - - - subroutine lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, q, precip, mono) - integer, intent(in):: ktop, kbot - real, intent(in):: zs - logical, intent(in):: mono - real, intent(in), dimension(ktop:kbot):: dp - real, intent(in), dimension(ktop:kbot+1):: ze, zt - real, intent(inout), dimension(ktop:kbot):: q - real, intent(out):: precip -! local: - real, dimension(ktop:kbot):: qm0, qm1, qm2, dz - real a4(4,ktop:kbot) - real pl, pr, delz, esl - integer k, k0, n, m - real, parameter:: r3 = 1./3., r23 = 2./3. - -! density: - do k=ktop,kbot - dz(k) = zt(k) - zt(k+1) ! note: dz is positive - qm0(k) = q(k)*dp(k) - qm1(k) = qm0(k) / dz(k) - qm2(k) = 0. - a4(1,k) = qm1(k) - enddo - -! Construct qm1 profile with zt as coordinate - - call cs_profile(a4(1,ktop), dz(ktop), kbot-ktop+1, mono) - - k0 = ktop - do k=ktop,kbot - do n=k0,kbot - if(ze(k) <= zt(n) .and. ze(k) >= zt(n+1)) then - pl = (zt(n)-ze(k)) / dz(n) - if( zt(n+1) <= ze(k+1) ) then -! entire new grid is within the original grid - pr = (zt(n)-ze(k+1)) / dz(n) - qm2(k) = a4(2,n) + 0.5*(a4(4,n)+a4(3,n)-a4(2,n))*(pr+pl) - & - a4(4,n)*r3*(pr*(pr+pl)+pl**2) - qm2(k) = qm2(k)*(ze(k)-ze(k+1)) - k0 = n - goto 555 - else - qm2(k) = (ze(k)-zt(n+1)) * (a4(2,n)+0.5*(a4(4,n)+ & - a4(3,n)-a4(2,n))*(1.+pl) - a4(4,n)*( r3*(1.+pl*(1.+pl))) ) - if ( n 0. ) then - q(k) = min( q(k), max(a4(1,k-1),a4(1,k)) ) - q(k) = max( q(k), min(a4(1,k-1),a4(1,k)) ) - else - if ( gam(k-1) > 0. ) then -! There exists a local max - q(k) = max( q(k), min(a4(1,k-1),a4(1,k)) ) - else -! There exists a local min - q(k) = min( q(k), max(a4(1,k-1),a4(1,k)) ) - q(k) = max( q(k), 0.0 ) - endif - endif - enddo - - q(km ) = min( q(km), max(a4(1,km-1), a4(1,km)) ) - q(km ) = max( q(km), min(a4(1,km-1), a4(1,km)), 0. ) -! q(km+1) = max( q(km+1), 0.) - -!----------------------------------------------------------- -! f(s) = AL + s*[(AR-AL) + A6*(1-s)] ( 0 <= s <= 1 ) -!----------------------------------------------------------- - do k=1,km-1 - a4(2,k) = q(k ) - a4(3,k) = q(k+1) - enddo - - do k=2,km-1 - if ( gam(k)*gam(k+1) > 0.0 ) then - extm(k) = .false. - else - extm(k) = .true. - endif - enddo - - if ( do_mono ) then - do k=3,km-2 - if ( extm(k) ) then -! positive definite constraint ONLY if true local extrema - if ( extm(k-1) .or. extm(k+1) ) then - a4(2,k) = a4(1,k) - a4(3,k) = a4(1,k) - endif - else - a4(4,k) = 6.*a4(1,k) - 3.*(a4(2,k)+a4(3,k)) - if( abs(a4(4,k)) > abs(a4(2,k)-a4(3,k)) ) then -! Check within the smooth region if subgrid profile is non-monotonic - pmp_1 = a4(1,k) - 2.0*gam(k+1) - lac_1 = pmp_1 + 1.5*gam(k+2) - a4(2,k) = min( max(a4(2,k), min(a4(1,k), pmp_1, lac_1)), & - max(a4(1,k), pmp_1, lac_1) ) - pmp_2 = a4(1,k) + 2.0*gam(k) - lac_2 = pmp_2 - 1.5*gam(k-1) - a4(3,k) = min( max(a4(3,k), min(a4(1,k), pmp_2, lac_2)), & - max(a4(1,k), pmp_2, lac_2) ) - endif - endif - enddo - else - do k=3,km-2 - if ( extm(k) .and. (extm(k-1) .or. extm(k+1)) ) then - a4(2,k) = a4(1,k) - a4(3,k) = a4(1,k) - endif - enddo - endif - - do k=1,km-1 - a4(4,k) = 6.*a4(1,k) - 3.*(a4(2,k)+a4(3,k)) - enddo - - k = km-1 - if( extm(k) ) then - a4(2,k) = a4(1,k) - a4(3,k) = a4(1,k) - a4(4,k) = 0. - else - da1 = a4(3,k) - a4(2,k) - da2 = da1**2 - a6da = a4(4,k)*da1 - if(a6da < -da2) then - a4(4,k) = 3.*(a4(2,k)-a4(1,k)) - a4(3,k) = a4(2,k) - a4(4,k) - elseif(a6da > da2) then - a4(4,k) = 3.*(a4(3,k)-a4(1,k)) - a4(2,k) = a4(3,k) - a4(4,k) - endif - endif - - call cs_limiters(km-1, a4) - -! Bottom layer: - a4(2,km) = a4(1,km) - a4(3,km) = a4(1,km) - a4(4,km) = 0. - - end subroutine cs_profile - - - - subroutine cs_limiters(km, a4) - integer, intent(in) :: km - real, intent(inout) :: a4(4,km) ! PPM array -! !LOCAL VARIABLES: - real, parameter:: r12 = 1./12. - integer k - -! Positive definite constraint - - do k=1,km - if( abs(a4(3,k)-a4(2,k)) < -a4(4,k) ) then - if( (a4(1,k)+0.25*(a4(3,k)-a4(2,k))**2/a4(4,k)+a4(4,k)*r12) < 0. ) then - if( a4(1,k) a4(2,k) ) then - a4(4,k) = 3.*(a4(2,k)-a4(1,k)) - a4(3,k) = a4(2,k) - a4(4,k) - else - a4(4,k) = 3.*(a4(3,k)-a4(1,k)) - a4(2,k) = a4(3,k) - a4(4,k) - endif - endif - endif - enddo - - end subroutine cs_limiters - - - - subroutine fall_speed(ktop, kbot, den, qs, qi, qg, ql, tk, vts, vti, vtg) - integer, intent(in) :: ktop, kbot - real, intent(in ), dimension(ktop:kbot) :: den, qs, qi, qg, ql, tk - real, intent(out), dimension(ktop:kbot) :: vts, vti, vtg -! fall velocity constants: - real, parameter :: thi = 1.0e-9 ! cloud ice threshold for terminal fall - real, parameter :: thg = 1.0e-9 - real, parameter :: ths = 1.0e-9 - real, parameter :: vf_min = 1.0E-6 - real, parameter :: vs_max = 7. ! max fall speed for snow -!----------------------------------------------------------------------- -! marshall-palmer constants -!----------------------------------------------------------------------- - real :: vcons = 6.6280504, vcong = 87.2382675, vconi = 3.29 - real :: norms = 942477796.076938, & - normg = 5026548245.74367 - real, dimension(ktop:kbot) :: ri, qden, tc -!real :: aa = -1.70704e-5, bb = -0.00319109, cc = -0.0169876, dd = 0.00410839, ee = 1.93644 - real :: aa = -4.14122e-5, bb = -0.00538922, cc = -0.0516344, dd = 0.00216078, ee = 1.9714 - - real :: rhof, rho0 - integer:: k -!----------------------------------------------------------------------- -! marshall-palmer formula -!----------------------------------------------------------------------- - -! try the local air density -- for global model; the true value could be -! much smaller than sfcrho over high mountains - - if ( den_ref < 0. ) then - rho0 = -den_ref*den(kbot) - else - rho0 = den_ref ! default=1.2 - endif - - do k=ktop, kbot - rhof = sqrt( min(100., rho0/den(k)) ) -! snow: - if ( qs(k) < ths ) then - vts(k) = vf_min - else - vts(k) = max(vf_min, vcons*rhof*exp(0.0625*log(qs(k)*den(k)/norms))) -!-------------------------------------------------------------------------------------- -! What if ql == 0 (ri---> 0?) -! ri(k) = 1./(1. + 6.e-5/(max(qcmin,ql(k)) * den(k)**1.235 * qs(k)**0.235)) !--- riming intensity -! vts(k) = max(vf_min, vconi*rhof*exp( 0.16*log((1.0-ri(k))*qs(k)*den(k)) ) + & -! 19.3*rhof*exp( 0.37*log( ri(k) *qs(k)*den(k)) ) ) -!-------------------------------------------------------------------------------------- - vts(k) = min( vs_max, vs_fac*vts(k) ) - endif - -! graupel: - if ( qg(k) < thg ) then - vtg(k) = vf_min - else - vtg(k) = max(vf_min, max(vmin, vg_fac*vcong*rhof*sqrt(sqrt(sqrt(qg(k)*den(k)/normg))))) - endif - enddo - -! ice: - if ( use_deng_mace ) then -! ice use Deng and Mace (2008, GRL), which gives smaller fall speed than HD90 formula - do k=ktop, kbot - if ( qi(k) < thi ) then - vti(k) = vf_min - else - qden(k) = log10( 1000.*qi(k)*den(k) ) !--- used in DM formula, in g/m^-3 - tc(k) = tk(k) - tice - vti(k) = qden(k)*( tc(k)*(aa*tc(k) + bb) + cc ) + dd*tc(k) + ee - vti(k) = max( vf_min, vi_fac*0.01*10.**vti(k) ) - endif - enddo - else -! HD90 ice speed: - do k=ktop, kbot - if ( qi(k) < thi ) then - vti(k) = vf_min - else - rhof = sqrt( min(100., rho0/den(k)) ) - vti(k) = max( vf_min, vconi*rhof*exp(0.16*log(qi(k)*den(k))) ) - endif - enddo - endif - - end subroutine fall_speed - - - subroutine setupm - - real :: gcon, cd, scm3, pisq, act(8), acc(3) - real :: vdifu, tcond - real :: visk - real :: ch2o, hltf - real :: hlts, hltc, ri50 - - real :: gam263, gam275, gam290, & - gam325, gam350, gam380, & - gam425, gam450, gam480, & - gam625, gam680 - - data gam263/1.456943/, gam275/1.608355/, gam290/1.827363/ & - gam325/2.54925/, gam350/3.323363/, gam380/4.694155/ & - gam425/8.285063/, gam450/11.631769/, gam480/17.837789/ & - gam625/184.860962/, gam680/496.604067/ -! -! physical constants (mks) -! lin's constants(mks) except rmi50,rmi40 (cgs) -! - real :: rnzr, rnzs, rnzg, rhos, rhog -!data alin, clin /842.0, 4.80/ - data rnzr /8.0e6/ ! lin83 - data rnzs /3.0e6/ ! lin83 - data rnzg /4.0e6/ ! rh84 - data rhos /0.1e3/ ! lin83 (snow density; 1/10 of water) - data rhog /0.4e3/ ! rh84 (graupel density) - data acc/5.0,2.0,0.5/ - - real den_rc - integer :: k, i - - pie = 4.*atan(1.0) - -! S. Klein's formular (EQ 16) from AM2 - fac_rc = (4./3.)*pie*rhor*rthresh**3 - den_rc = fac_rc * ccn_o*1.e6 - if(master) write(*,*) 'MP: rthresh=', rthresh, 'vi_fac=', vi_fac - if(master) write(*,*) 'MP: for ccn_o=', ccn_o, 'ql_rc=', den_rc - den_rc = fac_rc * ccn_l*1.e6 - if(master) write(*,*) 'MP: for ccn_l=', ccn_l, 'ql_rc=', den_rc - - vdifu=2.11e-5 - tcond=2.36e-2 - - visk=1.259e-5 - hlts=2.8336e6 - hltc=2.5e6 - hltf=3.336e5 - - ch2o=4.1855e3 - rmi50=3.84e-6 ! Purdue Lin scheme 4.8e-7 [g] -! rmi40=2.46e-7 - ri50=1.e-4 - - pisq = pie*pie - scm3 = (visk/vdifu)**(1./3.) -! - cracs = pisq*rnzr*rnzs*rhos - csacr = pisq*rnzr*rnzs*rhor - cgacr = pisq*rnzr*rnzg*rhor - cgacs = pisq*rnzg*rnzs*rhos - cgacs = cgacs*c_pgacs -! -! act: 1-2:racs(s-r); 3-4:sacr(r-s); -! 5-6:gacr(r-g); 7-8:gacs(s-g) -! - act(1) = pie * rnzs * rhos - act(2) = pie * rnzr * rhor - act(6) = pie * rnzg * rhog - act(3) = act(2) - act(4) = act(1) - act(5) = act(2) - act(7) = act(1) - act(8) = act(6) - - do i=1,3 - do k=1,4 - acco(i,k) = acc(i)/(act(2*k-1)**((7-i)*0.25)*act(2*k)**(i*0.25)) - enddo - enddo -! - gcon = 40.74 * sqrt( sfcrho ) ! 44.628 -! - csacw = pie*rnzs*clin*gam325/(4.*act(1)**0.8125) -! Decreasing csacw to reduce cloud water ---> snow - - craci = pie*rnzr*alin*gam380/(4.*act(2)**0.95) - csaci = csacw * c_psaci -! - cgacw = pie*rnzg*gam350*gcon/(4.*act(6)**0.875) - cgaci = cgacw*0.1 -! - cracw = craci ! cracw= 3.27206196043822 - cracw = c_cracw * cracw -! -! subl and revp: five constants for three separate processes -! - cssub(1) = 2.*pie*vdifu*tcond*rvgas*rnzs - cgsub(1) = 2.*pie*vdifu*tcond*rvgas*rnzg - crevp(1) = 2.*pie*vdifu*tcond*rvgas*rnzr - cssub(2) = 0.78/sqrt(act(1)) - cgsub(2) = 0.78/sqrt(act(6)) - crevp(2) = 0.78/sqrt(act(2)) - cssub(3) = 0.31*scm3*gam263*sqrt(clin/visk)/act(1)**0.65625 - cgsub(3) = 0.31*scm3*gam275*sqrt(gcon/visk)/act(6)**0.6875 - crevp(3) = 0.31*scm3*gam290*sqrt(alin/visk)/act(2)**0.725 - cssub(4) = tcond*rvgas - cssub(5) = hlts**2*vdifu - cgsub(4) = cssub(4) - crevp(4) = cssub(4) - cgsub(5) = cssub(5) - crevp(5) = hltc**2*vdifu -! - cgfr(1) = 20.e2*pisq*rnzr*rhor/act(2)**1.75 - cgfr(2) = 0.66 -! -!sk ******************************************************************** -!sk smlt: five constants ( lin et al. 1983 ) - csmlt(1) = 2.*pie*tcond*rnzs/hltf - csmlt(2) = 2.*pie*vdifu*rnzs*hltc/hltf - csmlt(3) = cssub(2) - csmlt(4) = cssub(3) - csmlt(5) = ch2o/hltf -!sk ******************************************************************** -! gmlt: five constants - cgmlt(1) = 2.*pie*tcond*rnzg/hltf - cgmlt(2) = 2.*pie*vdifu*rnzg*hltc/hltf - cgmlt(3) = cgsub(2) - cgmlt(4) = cgsub(3) - cgmlt(5) = ch2o/hltf -!sk ******************************************************************** - es0 = 6.107799961e2 ! ~6.1 mb - ces0 = eps*es0 -! -! c2brg has conversion factor of 10**3 - c1brg = dts/rmi50 -!lin c2brg = ri50**2*1.e3 ! error - c2brg = pie*ri50**2*1.e3 - - end subroutine setupm + end subroutine sat_adj2 subroutine lin_cld_microphys_init(id, jd, kd, axes, time) - + integer, intent(in) :: id, jd, kd integer, intent(in) :: axes(4) type(time_type), intent(in) :: time - - integer :: unit, io, ierr, k, logunit - integer :: is, ie, js, je, ks, ke - logical :: flag - real :: tmp, q1, q2 - - master = (mpp_pe().eq.mpp_root_pe()) - -#ifdef INTERNAL_FILE_NML - read( input_nml_file, nml = lin_cld_microphys_nml, iostat = io ) - ierr = check_nml_error(io,'lin_cloud_microphys_nml') -#else - if( file_exist( 'input.nml' ) ) then - unit = open_namelist_file () - io = 1 - do while ( io .ne. 0 ) - read( unit, nml = lin_cld_microphys_nml, iostat = io, end = 10 ) - ierr = check_nml_error(io,'lin_cloud_microphys_nml') - end do -10 call close_file ( unit ) - end if -#endif - call write_version_number (version, tagname) - logunit = stdlog() - - if ( do_setup ) then - is = 1 - js = 1 - ks = 1 - ie = id - je = jd - ke = kd - - call setup_con (is, ie, js, je, ks, ke) - call setupm - do_setup = .false. - endif - - if (master) write( logunit, nml = lin_cld_microphys_nml ) - - id_vtr = register_diag_field ( mod_name, 'vt_r', axes(1:3), time, & - 'rain fall speed', 'm/sec', missing_value=missing_value ) - id_vts = register_diag_field ( mod_name, 'vt_s', axes(1:3), time, & - 'snow fall speed', 'm/sec', missing_value=missing_value ) - id_vtg = register_diag_field ( mod_name, 'vt_g', axes(1:3), time, & - 'graupel fall speed', 'm/sec', missing_value=missing_value ) - id_vti = register_diag_field ( mod_name, 'vt_i', axes(1:3), time, & - 'ice fall speed', 'm/sec', missing_value=missing_value ) - - id_rain = register_diag_field ( mod_name, 'rain_lin', axes(1:2), time, & - 'rain_lin', 'mm/day', missing_value=missing_value ) - id_snow = register_diag_field ( mod_name, 'snow_lin', axes(1:2), time, & - 'snow_lin', 'mm/day', missing_value=missing_value ) - id_graupel = register_diag_field ( mod_name, 'graupel_lin', axes(1:2), time, & - 'graupel_lin', 'mm/day', missing_value=missing_value ) - id_ice = register_diag_field ( mod_name, 'ice_lin', axes(1:2), time, & - 'ice_lin', 'mm/day', missing_value=missing_value ) - id_prec = register_diag_field ( mod_name, 'prec_lin', axes(1:2), time, & - 'prec_lin', 'mm/day', missing_value=missing_value ) -! if ( master ) write(*,*) 'prec_lin diagnostics initialized.', id_prec - - id_cond = register_diag_field ( mod_name, 'cond_lin', axes(1:2), time, & - 'total condensate', 'kg/m**2', missing_value=missing_value ) - id_var = register_diag_field ( mod_name, 'var_lin', axes(1:2), time, & - 'subgrid variance', 'n/a', missing_value=missing_value ) + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) -!------------------------ -! fall speed diagnostics: -!------------------------ - if ( id_vtr> 0 ) then - allocate ( vt_r(is:ie, js:je, ks:ke) ) - vt_r = 0. - endif - if ( id_vts> 0 ) then - allocate ( vt_s(is:ie, js:je, ks:ke) ) - vt_s = 0. - endif - if ( id_vtg> 0 ) then - allocate ( vt_g(is:ie, js:je, ks:ke) ) - vt_g = 0. - endif - if ( id_vti> 0 ) then - allocate ( vt_i(is:ie, js:je, ks:ke) ) - vt_i = 0. - endif - if ( id_var>0 ) then - allocate ( w_var(is:ie, js:je) ) - w_var = 0. - endif - - allocate ( cond(is:ie, js:je) ) - allocate ( prec_mp(is:ie, js:je) ) - allocate ( prec0(is:ie, js:je) ) - allocate ( prec1(is:ie, js:je) ) - allocate ( rain0(is:ie, js:je) ) - allocate ( snow0(is:ie, js:je) ) - allocate ( ice0(is:ie, js:je) ) - allocate ( graupel0(is:ie, js:je) ) - - cond = 0. - prec0 = 0. - prec1 = 0. - rain0 = 0. - snow0 = 0. - ice0 = 0. - graupel0 = 0. - -! call qsmith_init - -! TESTING the water vapor tables - if ( mp_debug .and. master ) then - write(*,*) 'TESTING water vapor tables in lin_cld_microphys' - tmp = tice - 90. - do k=1,25 - q1 = wqsat(tmp, 1.E5) - q2 = iqsat(tmp, 1.E5) - write(*,*) NINT(tmp-tice), q1, q2, 'dq=', q1-q2 - tmp = tmp + 5. - enddo - endif - - if ( master ) write(*,*) 'lin_cld_micrphys diagnostics initialized.' - - lin_cld_mp_clock = mpp_clock_id('Lin_cld_microphys', grain=CLOCK_ROUTINE) - g_sum_initialized = .false. - module_is_initialized = .true. - end subroutine lin_cld_microphys_init - subroutine lin_cld_microphys_end - real gmp - if ( mp_print ) then -! the g_sum call does not work if physics window is used ***** - if ( id_ice> 0 ) then - gmp = g_sum(ice0, isc, iec, jsc, jec, ng, l_area, 1) - if(master) write(*,*) 'total ice=', gmp/mp_count - endif - if ( id_graupel> 0 ) then - gmp = g_sum(graupel0, isc, iec, jsc, jec, ng, l_area, 1) - if(master) write(*,*) 'total graupel=', gmp/mp_count - endif - if ( id_snow> 0 ) then - gmp = g_sum(snow0, isc, iec, jsc, jec, ng, l_area, 1) - if(master) write(*,*) 'total snow=', gmp/mp_count - endif - if ( id_rain> 0 ) then - gmp = g_sum(rain0, isc, iec, jsc, jec, ng, l_area, 1) - if(master) write(*,*) 'total rain=', gmp/mp_count - endif -! if ( id_prec> 0 ) then - gmp = g_sum(prec0, isc, iec, jsc, jec, ng, l_area, 1) - if(master) write(*,*) 'total prec=', gmp/mp_count -! endif - endif + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) - if ( id_vtr> 0 ) deallocate ( vt_r ) - if ( id_vts> 0 ) deallocate ( vt_s ) - if ( id_vti> 0 ) deallocate ( vt_i ) - if ( id_vtg> 0 ) deallocate ( vt_g ) - if ( id_var> 0 ) deallocate ( w_var ) - - deallocate ( prec_mp ) - deallocate ( prec0 ) - deallocate ( prec1 ) - deallocate ( rain0 ) - deallocate ( snow0 ) - deallocate ( ice0 ) - deallocate ( graupel0 ) - deallocate ( cond ) - - deallocate ( table ) - deallocate ( table2 ) - deallocate ( table3 ) - deallocate ( tablew ) - deallocate ( des ) - deallocate ( des2 ) - deallocate ( des3 ) - deallocate ( desw ) - end subroutine lin_cld_microphys_end - - subroutine setup_con( is, ie, js, je, ks, ke ) - integer, intent(in) :: is,ie, js,je, ks, ke - - master = (mpp_pe().eq.mpp_root_pe()) - - isc = is; iec = ie - jsc = js; jec = je - - lcp = latv / cp - icp = lati / cp - tcp = (latv+lati) / cp - - rgrav = 1./ grav - - call qsmith_init - - - end subroutine setup_con - - - - real function acr3d(v1, v2, q1, q2, c, cac, rho) - real, intent(in) :: v1, v2, c, rho - real, intent(in) :: q1, q2 ! mixing ratio!!! - real, intent(in) :: cac(3) - real :: t1, s1, s2 -!integer :: k -! real:: a -! a=0.0 -! do k=1,3 -! a = a + cac(k)*( (q1*rho)**((7-k)*0.25) * (q2*rho)**(k*0.25) ) -! enddo -! acr3d = c * abs(v1-v2) * a/rho -!---------- -! Optimized -!---------- - t1 = sqrt(q1*rho) - s1 = sqrt(q2*rho) - s2 = sqrt(s1) ! s1 = s2**2 - acr3d = c*abs(v1-v2)*q1*s2*(cac(1)*t1 + cac(2)*sqrt(t1)*s2 + cac(3)*s1) - - end function acr3d - - - - - real function smlt(tc, dqs, qsrho,psacw,psacr,c,rho, rhofac) - real, intent(in):: tc,dqs,qsrho,psacw,psacr,c(5),rho, rhofac - - smlt = (c(1)*tc/rho-c(2)*dqs) * (c(3)*sqrt(qsrho)+ & - c(4)*qsrho**0.65625*sqrt(rhofac)) + c(5)*tc*(psacw+psacr) - - end function smlt - - - real function gmlt(tc, dqs,qgrho,pgacw,pgacr,c, rho) - real, intent(in):: tc,dqs,qgrho,pgacw,pgacr,c(5),rho - -! note: pgacw and pgacr must be calc before gmlt is called -! - gmlt = (c(1)*tc/rho-c(2)*dqs) * (c(3)*sqrt(qgrho)+ & - c(4)*qgrho**0.6875/rho**0.25) + c(5)*tc*(pgacw+pgacr) - end function gmlt - - subroutine qsmith_init - integer, parameter:: length=2621 - integer i - - if( .not. allocated(table) ) then -! generate es table (dt = 0.1 deg. c) - allocate ( table( length) ) - allocate ( table2(length) ) - allocate ( table3(length) ) - allocate ( tablew(length) ) - allocate ( des (length) ) - allocate ( des2(length) ) - allocate ( des3(length) ) - allocate ( desw(length) ) - call qs_table (length ) - call qs_table2(length ) - call qs_table3(length ) - call qs_tablew(length ) + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) - do i=1,length-1 - des(i) = max(0., table(i+1) - table(i)) - des2(i) = max(0., table2(i+1) - table2(i)) - des3(i) = max(0., table3(i+1) - table3(i)) - desw(i) = max(0., tablew(i+1) - tablew(i)) - enddo - des(length) = des(length-1) - des2(length) = des2(length-1) - des3(length) = des3(length-1) - desw(length) = desw(length-1) - endif - end subroutine qsmith_init - - - real function qs1d(ta, pa, dqdt) -! 2-phase tabel - real, intent(in):: ta, pa - real, intent(out):: dqdt -! local: - real es, ap1 - real, parameter:: tmin=tice - 160. - real, parameter:: eps10 = 10.*eps - integer it - - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es = table2(it) + (ap1-it)*des2(it) - qs1d = eps*es/pa - it = ap1 - 0.5 - dqdt = eps10*(des2(it) + (ap1-it)*(des2(it+1)-des2(it)))/pa - - end function qs1d - real function ws1d(ta, pa, dqdt) -! Pure water phase - real, intent(in):: ta, pa + real function wqsat2_moist(ta, qv, pa, dqdt) + real, intent(in):: ta, pa, qv real, intent(out):: dqdt -! local: - real es, ap1 - real, parameter:: tmin=tice - 160. - real, parameter:: eps10 = 10.*eps - integer it - - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es = tablew(it) + (ap1-it)*desw(it) - ws1d = eps*es/pa - it = ap1 - 0.5 - dqdt = eps10*(desw(it) + (ap1-it)*(desw(it+1)-desw(it)))/pa - - end function ws1d - - - real function wqsat(ta, pa) -! Pure water phase - real, intent(in):: ta, pa -! local: - real es, ap1 - real, parameter:: tmin=tice - 160. - integer it - - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es = tablew(it) + (ap1-it)*desw(it) - wqsat = eps*es/pa - - end function wqsat - - real function iqsat(ta, pa) - real, intent(in):: ta, pa -! local: - real es, ap1 - real, parameter:: tmin=tice - 160. - integer it - - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es = table2(it) + (ap1-it)*des2(it) - iqsat = eps*es/pa - - end function iqsat - - real function d_sat(ta) -! Computes the difference in saturation vapor *density* between water and ice - real, intent(in):: ta - real, parameter:: tmin=tice - 160. - real es_w, es_i, ap1 - integer it - - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 -! over Water: - es_w = tablew(it) + (ap1-it)*desw(it) -! over Ice: - es_i = table2(it) + (ap1-it)*des2(it) - d_sat = dim(es_w, es_i)/(rvgas*ta) ! Take positive difference - - end function d_sat - - - real function esw_table(ta) -! pure water phase table - real, intent(in):: ta - real, parameter:: tmin=tice - 160. - real ap1 - integer it - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - esw_table = tablew(it) + (ap1-it)*desw(it) - end function esw_table - - - real function es2_table(ta) -! two-phase table - real, intent(in):: ta - real, parameter:: tmin=tice - 160. - real ap1 - integer it - ap1 = 10.*dim(ta, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es2_table = table2(it) + (ap1-it)*des2(it) - end function es2_table - - - subroutine esw_table1d(ta, es, n) - integer, intent(in):: n -! For waterphase only - real, intent(in):: ta(n) - real, intent(out):: es(n) - real, parameter:: tmin=tice - 160. - real ap1 - integer i, it - - do i=1, n - ap1 = 10.*dim(ta(i), tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es(i) = tablew(it) + (ap1-it)*desw(it) - enddo - end subroutine esw_table1d - - - - subroutine es2_table1d(ta, es, n) - integer, intent(in):: n -! two-phase table with -2C as the transition point for ice-water phase -! For sea ice model - real, intent(in):: ta(n) - real, intent(out):: es(n) - real, parameter:: tmin=tice - 160. - real ap1 - integer i, it - - do i=1, n - ap1 = 10.*dim(ta(i), tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es(i) = table2(it) + (ap1-it)*des2(it) - enddo - end subroutine es2_table1d - - - subroutine es3_table1d(ta, es, n) - integer, intent(in):: n -! two-phase table with -2C as the transition point for ice-water phase - real, intent(in):: ta(n) - real, intent(out):: es(n) - real, parameter:: tmin=tice - 160. - real ap1 - integer i, it - - do i=1, n - ap1 = 10.*dim(ta(i), tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es(i) = table3(it) + (ap1-it)*des3(it) - enddo - end subroutine es3_table1d - - - - subroutine qs_tablew(n) -! 2-phase table - integer, intent(in):: n - real:: delt=0.1 - real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e - integer i - -! constants - esbasw = 1013246.0 - tbasw = 373.16 - esbasi = 6107.1 - tbasi = 273.16 - tmin = tbasi - 160. - - do i=1,n - tem = tmin+delt*real(i-1) -! compute es over water -! see smithsonian meteorological tables page 350. - aa = -7.90298*(tbasw/tem-1.) - b = 5.02808*alog10(tbasw/tem) - c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.) - d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.) - e = alog10(esbasw) - tablew(i) = 0.1 * 10**(aa+b+c+d+e) - enddo - - end subroutine qs_tablew - - - subroutine qs_table2(n) -! 2-phase table - integer, intent(in):: n - real:: delt=0.1 - real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e - integer :: i0, i1 - real :: tem0, tem1 - integer i - -! constants - esbasw = 1013246.0 - tbasw = 373.16 - esbasi = 6107.1 - tbasi = 273.16 - tmin = tbasi - 160. - - do i=1,n - tem = tmin+delt*real(i-1) - if ( i<= 1600 ) then -! compute es over ice between -160c and 0 c. -! see smithsonian meteorological tables page 350. - aa = -9.09718 *(tbasi/tem-1.) - b = -3.56654 *alog10(tbasi/tem) - c = 0.876793*(1.-tem/tbasi) - e = alog10(esbasi) - table2(i) = 0.1 * 10**(aa+b+c+e) - else -! compute es over water between 0c and 102c. -! see smithsonian meteorological tables page 350. - aa = -7.90298*(tbasw/tem-1.) - b = 5.02808*alog10(tbasw/tem) - c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.) - d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.) - e = alog10(esbasw) - table2(i) = 0.1 * 10**(aa+b+c+d+e) - endif - enddo -!---------- -! smoother -!---------- - i0 = 1600; i1 = 1601 - tem0 = 0.25*(table2(i0-1) + 2.*table(i0) + table2(i0+1)) - tem1 = 0.25*(table2(i1-1) + 2.*table(i1) + table2(i1+1)) - table2(i0) = tem0 - table2(i1) = tem1 + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) - end subroutine qs_table2 + end function wqsat2_moist + real function wqsat_moist(ta, qv, pa) + real, intent(in):: ta, pa, qv + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) - subroutine qs_table3(n) -! 2-phase table with "-2 C" as the transition point - integer, intent(in):: n - real:: delt=0.1 - real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e - integer :: i0, i1 - real :: tem0, tem1 - integer i - -! constants - esbasw = 1013246.0 - tbasw = 373.16 - esbasi = 6107.1 - tbasi = 273.16 - tmin = tbasi - 160. - - do i=1,n - tem = tmin+delt*real(i-1) -! if ( i<= 1600 ) then - if ( i<= 1580 ) then ! to -2 C -! compute es over ice between -160c and 0 c. -! see smithsonian meteorological tables page 350. - aa = -9.09718 *(tbasi/tem-1.) - b = -3.56654 *alog10(tbasi/tem) - c = 0.876793*(1.-tem/tbasi) - e = alog10(esbasi) - table3(i) = 0.1 * 10**(aa+b+c+e) - else -! compute es over water between -2c and 102c. -! see smithsonian meteorological tables page 350. - aa = -7.90298*(tbasw/tem-1.) - b = 5.02808*alog10(tbasw/tem) - c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.) - d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.) - e = alog10(esbasw) - table3(i) = 0.1 * 10**(aa+b+c+d+e) - endif - enddo - -!---------- -! smoother -!---------- - i0 = 1580 - tem0 = 0.25*(table3(i0-1) + 2.*table(i0) + table3(i0+1)) - i1 = 1581 - tem1 = 0.25*(table3(i1-1) + 2.*table(i1) + table3(i1+1)) - table3(i0) = tem0 - table3(i1) = tem1 - - end subroutine qs_table3 - - - real function qs1d_blend(t, p, q) -! Note: this routine is based on "moist" mixing ratio -! Blended mixed phase table - real, intent(in):: t, p, q - real es, ap1 - real, parameter:: tmin=tice - 160. - integer it - - ap1 = 10.*dim(t, tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es = table(it) + (ap1-it)*des(it) - qs1d_blend = eps*es*(1.+zvir*q)/p - - end function qs1d_blend - - subroutine qs_table(n) - integer, intent(in):: n - real esupc(200) - real:: delt=0.1 - real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e, esh20 - real wice, wh2o - integer i - -! constants - esbasw = 1013246.0 - tbasw = 373.16 - esbasi = 6107.1 - tbasi = 273.16 - -! compute es over ice between -160c and 0 c. - tmin = tbasi - 160. -! see smithsonian meteorological tables page 350. - do i=1,1600 - tem = tmin+delt*real(i-1) - aa = -9.09718 *(tbasi/tem-1.) - b = -3.56654 *alog10(tbasi/tem) - c = 0.876793*(1.-tem/tbasi) - e = alog10(esbasi) - table(i)=10**(aa+b+c+e) - enddo - -! compute es over water between -20c and 102c. -! see smithsonian meteorological tables page 350. - do i=1,1221 - tem = 253.16+delt*real(i-1) - aa = -7.90298*(tbasw/tem-1.) - b = 5.02808*alog10(tbasw/tem) - c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.) - d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.) - e = alog10(esbasw) - esh20 = 10**(aa+b+c+d+e) - if (i <= 200) then - esupc(i) = esh20 - else - table(i+1400) = esh20 - endif - enddo - -! derive blended es over ice and supercooled water between -20c and 0c - do i=1,200 - tem = 253.16+delt*real(i-1) - wice = 0.05*(273.16-tem) - wh2o = 0.05*(tem-253.16) - table(i+1400) = wice*table(i+1400)+wh2o*esupc(i) - enddo - - do i=1,n - table(i) = table(i)*0.1 - enddo - - end subroutine qs_table + end function wqsat_moist subroutine qsmith(im, km, ks, t, p, q, qs, dqdt) -! input t in deg k; p (pa) : moist pressure integer, intent(in):: im, km, ks real, intent(in),dimension(im,km):: t, p, q real, intent(out),dimension(im,km):: qs real, intent(out), optional:: dqdt(im,km) -! local: - real, parameter:: eps10 = 10.*eps - real es(im,km) - real ap1 - real tmin - integer i, k, it - - tmin = tice-160. - - if( .not. allocated(table) ) then - call qsmith_init - endif - - do k=ks,km - do i=1,im - ap1 = 10.*dim(t(i,k), tmin) + 1. - ap1 = min(2621., ap1) - it = ap1 - es(i,k) = table(it) + (ap1-it)*des(it) - qs(i,k) = eps*es(i,k)*(1.+zvir*q(i,k))/p(i,k) - enddo - enddo - - if ( present(dqdt) ) then - do k=ks,km - do i=1,im - ap1 = 10.*dim(t(i,k), tmin) + 1. - ap1 = min(2621., ap1) - 0.5 - it = ap1 - dqdt(i,k) = eps10*(des(it)+(ap1-it)*(des(it+1)-des(it)))*(1.+zvir*q(i,k))/p(i,k) - enddo - enddo - endif - - end subroutine qsmith - - - subroutine neg_adj(ktop, kbot, p1, pt, dp, qv, ql, qr, qi, qs, qg) -! 1d version: -! this is designed for 6-class micro-physics schemes - integer, intent(in):: ktop, kbot - real, intent(in):: dp(ktop:kbot), p1(ktop:kbot) - real, intent(inout), dimension(ktop:kbot):: & - pt, qv, ql, qr, qi, qs, qg -! local: - real lcpk(ktop:kbot), icpk(ktop:kbot) - real dq, tmp1 - integer k - - do k=ktop,kbot -! tmp1 = cp - rdgas*ptop/p1(k) -! lcpk(k) = latv / tmp1 -! icpk(k) = lati / tmp1 - lcpk(k) = latv / cp - icpk(k) = lati / cp - enddo - - do k=ktop, kbot -!----------- -! ice-phase: -!----------- -! if ice<0 borrow from snow - if( qi(k) < 0. ) then - qs(k) = qs(k) + qi(k) - qi(k) = 0. - endif -! if snow<0 borrow from graupel - if( qs(k) < 0. ) then - qg(k) = qg(k) + qs(k) - qs(k) = 0. - endif -! if graupel < 0 then borrow from rain - if ( qg(k) < 0. ) then - qr(k) = qr(k) + qg(k) - pt(k) = pt(k) - qg(k)*icpk(k) ! heating - qg(k) = 0. - endif - -! liquid phase: -! fix negative rain by borrowing from cloud water - if ( qr(k) < 0. ) then - ql(k) = ql(k) + qr(k) - qr(k) = 0. - endif -! fix negative cloud water with vapor - if ( ql(k) < 0. ) then - qv(k) = qv(k) + ql(k) - pt(k) = pt(k) - ql(k)*lcpk(k) - ql(k) = 0. - endif - enddo - -!----------------------------------- -! fix water vapor; borrow from below -!----------------------------------- - do k=ktop,kbot-1 - if( qv(k) < 0. ) then - qv(k+1) = qv(k+1) + qv(k)*dp(k)/dp(k+1) - qv(k ) = 0. - endif - enddo - -! bottom layer; borrow from above - if( qv(kbot) < 0. .and. qv(kbot-1)>0.) then - dq = min(-qv(kbot)*dp(kbot), qv(kbot-1)*dp(kbot-1)) - qv(kbot-1) = qv(kbot-1) - dq/dp(kbot-1) - qv(kbot ) = qv(kbot ) + dq/dp(kbot ) - endif -! if qv is still < 0 - - end subroutine neg_adj - - - - - subroutine sg_conv(is, ie, js, je, isd, ied, jsd, jed, & - isc, iec, jsc, jec, km, nq, dt, tau, & - delp, phalf, pm, zfull, zhalf, ta, qa, ua, va, w, & - u_dt, v_dt, t_dt, q_dt, mcond, nqv, nql, nqi, & - hydrostatic, phys_hydrostatic) -! Non-precipitating sub-grid scale convective adjustment-mixing -!------------------------------------------- - logical, intent(in):: hydrostatic, phys_hydrostatic - integer, intent(in):: is, ie, js, je, km, nq - integer, intent(in):: mcond - integer, intent(in):: isc, iec, jsc, jec - integer, intent(in):: isd, ied, jsd, jed - integer, intent(in):: tau ! Relaxation time scale - integer, intent(in):: nqv, nql, nqi ! vapor, liquid, ice - real, intent(in):: dt ! model time step - real, intent(in):: phalf(is:ie,js:je,km+1) - real, intent(in):: pm(is:ie,js:je,km) - real, intent(in):: zfull(is:ie,js:je,km) - real, intent(in):: zhalf(is:ie,js:je,km+1) - real, intent(in):: delp(isd:ied,jsd:jed,km) ! Delta p at each model level - real, intent(in):: ta(isd:ied,jsd:jed,km) ! Temperature - real, intent(in):: qa(isd:ied,jsd:jed,km,nq) ! Specific humidity & tracers - real, intent(in):: ua(isd:ied,jsd:jed,km) - real, intent(in):: va(isd:ied,jsd:jed,km) - real, intent(inout):: w(isd:ied,jsd:jed,km) -! Output: -! Updated fields: - real, intent(out):: u_dt(isd:ied,jsd:jed,km) ! updated u-wind field - real, intent(out):: v_dt(isd:ied,jsd:jed,km) ! v-wind - real, intent(out):: t_dt(isc:iec,jsc:jec,km) ! temperature - real, intent(out):: q_dt(isc:iec,jsc:jec,km,nq) ! -!---------------------------Local variables----------------------------- - real, dimension(is:ie,km):: tvm, u0, v0, w0, t0, gz, hd, pkz - real, dimension(is:ie,km+1):: pk, peln - real q0(is:ie,km,nq) - real gzh(is:ie) - real pbot, ri, pt1, pt2, lf, ratio - real rdt, dh, dh0, dhs, dq, tv, h0, mc, mx, fra, rk, rz, rcp - real qs1, detn - real clouds, rqi - integer kcond - integer i, j, k, n, m, iq, kk, ik - real, parameter:: ustar2 = 1.E-8 - real, parameter:: dh_min = 1.E-4 - - if ( nqv /= 1 .or. nql/=2 ) then - call error_mesg ('sg_conv', 'Tracer indexing error', FATAL) - endif - - - - rz = rvgas - rdgas ! rz = zvir * rdgas - rk = cp_air/rdgas + 1. - rcp = 1./cp_air - - m = 4 - rdt = 1. / dt - fra = dt/real(tau) - -!------------ -! Compute gz: center -!------------ - do 1000 j=js,je ! this main loop can be OpneMPed in j - - do k=mcond,km+1 - do i=is,ie - peln(i,k) = log(phalf(i,j,k)) -! pk(i,k) = phalf(i,j,k)**kappa - pk(i,k) = exp(kappa*peln(i,k)) - enddo - enddo - - do k=mcond,km - do i=is,ie - u0(i,k) = ua(i,j,k) - v0(i,k) = va(i,j,k) - t0(i,k) = ta(i,j,k) - pkz(i,k) = (pk(i,k+1)-pk(i,k))/(kappa*(peln(i,k+1)-peln(i,k))) - enddo - enddo - - if ( .not.hydrostatic ) then - do k=mcond,km - do i=is,ie - w0(i,k) = w(i,j,k) - enddo - enddo - endif - - do iq=1,nq - do k=mcond,km - do i=is,ie - q0(i,k,iq) = qa(i,j,k,iq) - enddo - enddo - enddo - - -!----------------- -! K-H instability: -!----------------- - kcond = mcond - - do n=1,m - ratio = real(n)/real(m) - - if( phys_hydrostatic ) then - do i=is,ie - gzh(i) = 0. - enddo - do k=km, mcond,-1 - do i=is,ie - tvm(i,k) = t0(i,k)*(1.+zvir*q0(i,k,nqv)) - tv = rdgas*tvm(i,k) - gz(i,k) = gzh(i) + tv*(1.-phalf(i,j,k)/pm(i,j,k)) - hd(i,k) = cp_air*tvm(i,k)+gz(i,k)+0.5*(u0(i,k)**2+v0(i,k)**2) - gzh(i) = gzh(i) + tv*(peln(i,k+1)-peln(i,k)) - enddo - enddo - do i=is,ie - gzh(i) = 0. - enddo - else - do k=mcond,km - do i=is,ie - gz(i,k) = grav*zfull(i,j,k) - hd(i,k) = cp_air*t0(i,k)+gz(i,k)+0.5*(u0(i,k)**2+v0(i,k)**2+w0(i,k)**2) - enddo - enddo - endif - - do k=km,kcond+1,-1 - do i=is,ie -! Richardson number at interface: g*delz * (del_theta/theta) / (del_u**2 + del_v**2) - pt1 = t0(i,k-1)/pkz(i,k-1) - pt2 = t0(i,k )/pkz(i,k ) - ri = (gz(i,k-1)-gz(i,k))*(pt1-pt2)/( 0.5*(pt1+pt2)* & - ((u0(i,k-1)-u0(i,k))**2+(v0(i,k-1)-v0(i,k))**2+ustar2) ) -! Dry convective mixing for K-H instability & CAT (Clear Air Turbulence): -! Compute equivalent mass flux: mc -#ifndef USE_RIP1 - if ( ri < 0.25 ) then - mc = ratio * (1.-max(0.0, 4.*ri)) ** 2 -#else - if ( ri < 1. ) then - mc = ratio * (1.-max(0.0, ri)) ** 2 -#endif - mc = mc*delp(i,j,k-1)*delp(i,j,k)/(delp(i,j,k-1)+delp(i,j,k)) - do iq=1,nq - h0 = mc*(q0(i,k,iq)-q0(i,k-1,iq)) - q0(i,k-1,iq) = q0(i,k-1,iq) + h0/delp(i,j,k-1) - q0(i,k ,iq) = q0(i,k ,iq) - h0/delp(i,j,k ) - enddo -! u: - h0 = mc*(u0(i,k)-u0(i,k-1)) - u0(i,k-1) = u0(i,k-1) + h0/delp(i,j,k-1) - u0(i,k ) = u0(i,k ) - h0/delp(i,j,k ) -! v: - h0 = mc*(v0(i,k)-v0(i,k-1)) - v0(i,k-1) = v0(i,k-1) + h0/delp(i,j,k-1) - v0(i,k ) = v0(i,k ) - h0/delp(i,j,k ) -! h: - h0 = mc*(hd(i,k)-hd(i,k-1)) - hd(i,k-1) = hd(i,k-1) + h0/delp(i,j,k-1) - hd(i,k ) = hd(i,k ) - h0/delp(i,j,k ) - if ( .not.hydrostatic ) then - h0 = mc*(w0(i,k)-w0(i,k-1)) - w0(i,k-1) = w0(i,k-1) + h0/delp(i,j,k-1) - w0(i,k ) = w0(i,k ) - h0/delp(i,j,k ) - endif - endif - enddo -!-------------- -! Retrive Temp: -!-------------- - if ( phys_hydrostatic ) then - kk = k - do i=is,ie - t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) & - / ( rk - phalf(i,j,kk)/pm(i,j,kk) ) - gzh(i) = gzh(i) + t0(i,kk)*(peln(i,kk+1)-peln(i,kk)) - t0(i,kk) = t0(i,kk) / ( rdgas + rz*q0(i,kk,nqv) ) - enddo - kk = k-1 - do i=is,ie - t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) & - / ((rk-phalf(i,j,kk)/pm(i,j,kk))*(rdgas+rz*q0(i,kk,nqv))) - enddo - else -! Non-hydrostatic under constant volume heating/cooling - do kk=k-1,k - do i=is,ie - t0(i,kk) = rcp*(hd(i,kk)-gz(i,kk)-0.5*(u0(i,kk)**2+v0(i,kk)**2+w0(i,kk)**2)) - enddo - enddo - endif - enddo - enddo ! n-loop - - -!------------------------- -! Moist adjustment/mixing: -!------------------------- - m = 3 - - if( km>k_moist+1 ) then - do n=1,m - - ratio = real(n)/real(m) - - if ( phys_hydrostatic ) then - do i=is,ie - gzh(i) = 0. - enddo - endif - - do k=km,max(kcond,k_moist)+1,-1 - do i=is,ie - if ( phalf(i,j,k) > p_crt ) then -!-------------------------------------------------------------------- -! qs1 = qs1d_blend(t0(i,k-1), pm(i,j,k-1), q0(i,k-1,nqv)) -! lf = hlv + hlf*min(1.0, max(0.0, (tice-t0(i,k-1))/30.)) -!-------------------------------------------------------------------- - clouds = q0(i,k-1,nql) + q0(i,k-1,nqi) - if( clouds > 1.e-5 ) then - rqi = q0(i,k-1,nqi) / clouds - else - rqi = max(0., min(1., (tice-t0(i,k-1))/30.)) - end if - qs1 = rqi*es2_table(t0(i,k-1)) + (1.-rqi)*esw_table(t0(i,k-1)) - qs1 = eps*qs1*(1.+zvir*q0(i,k-1,nqv))/pm(i,j,k-1) - lf = hlv + rqi*hlf - - dh0 = hd(i,k) - hd(i,k-1) - dhs = dh0 + lf*(q0(i,k,nqv)-qs1 ) - dh = dh0 + lf*(q0(i,k,nqv)-q0(i,k-1,nqv)) -! if ( dhs>0.0 .and. dh>dh_min ) then - if ( dhs>0.0 .and. dh>dh_min .and. q0(i,k,nqv)>q0(i,k-1,nqv) ) then - mc = ratio*min(1.0, 0.5*dhs/dh)* & - delp(i,j,k-1)*delp(i,j,k)/(delp(i,j,k-1)+delp(i,j,k)) - h0 = mc*dh0 - hd(i,k-1) = hd(i,k-1) + h0/delp(i,j,k-1) - hd(i,k ) = hd(i,k ) - h0/delp(i,j,k ) -! Perform local mixing of all advected tracers: -#ifdef DET_CON - if ( zhalf(i,j,k) > (1.E3+zhalf(i,j,km+1)) ) then - detn = min(1., zhalf(i,j,k)/7.e3) -! specific humidity: - h0 = mc*(q0(i,k,nqv)-q0(i,k-1,nqv)) - dq = h0/delp(i,j,k-1) - q0(i,k-1,nqv) = q0(i,k-1,nqv) + dq*(1.-detn) - q0(i,k ,nqv) = q0(i,k ,nqv) - h0/delp(i,j,k ) - do iq=2,nq - h0 = mc*(q0(i,k,iq)-q0(i,k-1,iq)) - q0(i,k-1,iq) = q0(i,k-1,iq) + h0/delp(i,j,k-1) - q0(i,k ,iq) = q0(i,k ,iq) - h0/delp(i,j,k ) - enddo -!-------------- -! Condensation: -!-------------- - dq = dq * detn - q0(i,k-1,nql) = q0(i,k-1,nql) + dq*(1.-rqi) - q0(i,k-1,nqi) = q0(i,k-1,nqi) + dq*rqi - hd(i,k-1) = hd(i,k-1) + dq*lf - - else - do iq=1,nq - h0 = mc*(q0(i,k,iq)-q0(i,k-1,iq)) - q0(i,k-1,iq) = q0(i,k-1,iq) + h0/delp(i,j,k-1) - q0(i,k ,iq) = q0(i,k ,iq) - h0/delp(i,j,k ) - enddo - endif -#else - do iq=1,nq - h0 = mc*(q0(i,k,iq)-q0(i,k-1,iq)) - q0(i,k-1,iq) = q0(i,k-1,iq) + h0/delp(i,j,k-1) - q0(i,k ,iq) = q0(i,k ,iq) - h0/delp(i,j,k ) - enddo -#endif -! u: - h0 = mc*(u0(i,k)-u0(i,k-1)) - u0(i,k-1) = u0(i,k-1) + h0/delp(i,j,k-1) - u0(i,k ) = u0(i,k ) - h0/delp(i,j,k ) -! v: - h0 = mc*(v0(i,k)-v0(i,k-1)) - v0(i,k-1) = v0(i,k-1) + h0/delp(i,j,k-1) - v0(i,k ) = v0(i,k ) - h0/delp(i,j,k ) -! *** Non-hydrostatic: - if ( .not.hydrostatic ) then - h0 = mc*(w0(i,k)-w0(i,k-1)) - w0(i,k-1) = w0(i,k-1) + h0/delp(i,j,k-1) - w0(i,k ) = w0(i,k ) - h0/delp(i,j,k ) - endif -! *** - endif ! dh check - endif ! p_crt check - enddo -!-------------- -! Retrive Temp: -!-------------- - if ( phys_hydrostatic ) then - kk = k - do i=is,ie - t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) & - / ( rk - phalf(i,j,kk)/pm(i,j,kk) ) - gzh(i) = gzh(i) + t0(i,kk)*(peln(i,kk+1)-peln(i,kk)) - t0(i,kk) = t0(i,kk) / ( rdgas + rz*q0(i,kk,nqv) ) - enddo - kk = k-1 - do i=is,ie - t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) & - / ((rk-phalf(i,j,kk)/pm(i,j,kk))*(rdgas+rz*q0(i,kk,nqv))) - enddo - else -! Non-hydrostatic under constant volume heating/cooling - do kk=k-1,k - do i=is,ie - t0(i,kk) = rcp*(hd(i,kk)-gz(i,kk)-0.5*(u0(i,kk)**2+v0(i,kk)**2+w0(i,kk)**2)) - enddo - enddo - endif - enddo - enddo ! n-loop - endif ! k_moist check - - if ( fra < 1. ) then - do k=mcond,km - do i=is,ie - t0(i,k) = ta(i,j,k) + (t0(i,k) - ta(i,j,k))*fra - u0(i,k) = ua(i,j,k) + (u0(i,k) - ua(i,j,k))*fra - v0(i,k) = va(i,j,k) + (v0(i,k) - va(i,j,k))*fra - enddo - enddo - - if ( .not.hydrostatic ) then - do k=mcond,km - do i=is,ie - w0(i,k) = w(i,j,k) + (w0(i,k) - w(i,j,k))*fra - enddo - enddo - endif - - do iq=1,nq - do k=mcond,km - do i=is,ie - q0(i,k,iq) = qa(i,j,k,iq) + (q0(i,k,iq) - qa(i,j,k,iq))*fra - enddo - enddo - enddo - endif - -!-------------------- -! Update fields: -!-------------------- - do k=1,mcond-1 - do i=is,ie - u_dt(i,j,k) = ua(i,j,k) - v_dt(i,j,k) = va(i,j,k) - t_dt(i,j,k) = ta(i,j,k) - enddo - enddo - do k=mcond,km - do i=is,ie - u_dt(i,j,k) = u0(i,k) - v_dt(i,j,k) = v0(i,k) - t_dt(i,j,k) = t0(i,k) - enddo - enddo - - if ( .not.hydrostatic ) then - do k=mcond,km - do i=is,ie - w(i,j,k) = w0(i,k) - enddo - enddo - endif - - do iq=1,nq - do k=1,mcond-1 - do i=is,ie - q_dt(i,j,k,iq) = qa(i,j,k,iq) - enddo - enddo - do k=mcond,km - do i=is,ie - q_dt(i,j,k,iq) = q0(i,k,iq) - enddo - enddo - enddo - -1000 continue - - - end subroutine sg_conv - - - real function g_sum(p, ifirst, ilast, jfirst, jlast, ngc, area, mode) - use mpp_mod, only: mpp_sum - real, save :: global_area -! Fast version of globalsum - integer, intent(IN) :: ifirst, ilast - integer, intent(IN) :: jfirst, jlast, ngc - integer, intent(IN) :: mode ! if ==1 divided by area - real, intent(IN) :: p(ifirst:ilast,jfirst:jlast) ! field to be summed - real, intent(IN) :: area(ifirst-ngc:ilast+ngc,jfirst-ngc:jlast+ngc) - integer :: i,j - real gsum + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) -!------------------------- -! Quick local sum algorithm -!------------------------- - if ( .not. g_sum_initialized ) then - allocate (l_area(ifirst:ilast,jfirst:jlast)) - global_area = 0. - do j=jfirst,jlast - do i=ifirst,ilast - global_area = global_area + area(i,j) - l_area(i,j) = area(i,j) - enddo - enddo - call mpp_sum(global_area) -! if ( mpp_pe().eq.mpp_root_pe() ) write(*,*) 'Global Area=',global_area - g_sum_initialized = .true. - end if + end subroutine qsmith - gsum = 0. - do j=jfirst,jlast - do i=ifirst,ilast - gsum = gsum + p(i,j)*l_area(i,j) - enddo - enddo - call mpp_sum(gsum) + real function g_sum(p, ifirst, ilast, jfirst, jlast, area, mode) + use mpp_mod, only: mpp_sum + integer, intent(IN) :: ifirst, ilast + integer, intent(IN) :: jfirst, jlast + integer, intent(IN) :: mode ! if ==1 divided by area + real, intent(IN) :: p(ifirst:ilast,jfirst:jlast) ! field to be summed + real, intent(IN) :: area(ifirst:ilast,jfirst:jlast) - if ( mode==1 ) then - g_sum = gsum / global_area - else - g_sum = gsum - endif + call error_mesg ('lin_cloud_microphys_mod', 'lin_cloud_microphysics should not be active', FATAL) end function g_sum diff --git a/src/atmos_param/lscale_cond/lscale_cond.F90 b/src/atmos_param/lscale_cond/lscale_cond.F90 index 6f8c3adf92..946409cb9f 100644 --- a/src/atmos_param/lscale_cond/lscale_cond.F90 +++ b/src/atmos_param/lscale_cond/lscale_cond.F90 @@ -20,7 +20,7 @@ module lscale_cond_mod ! ---- version number ---- character(len=128) :: version = '$Id: lscale_cond.F90,v 19.0 2012/01/06 20:10:05 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized=.false. !----------------------------------------------------------------------- diff --git a/src/atmos_param/lscale_cond/null/lscale_cond.F90 b/src/atmos_param/lscale_cond/null/lscale_cond.F90 deleted file mode 100644 index 43a71bcac9..0000000000 --- a/src/atmos_param/lscale_cond/null/lscale_cond.F90 +++ /dev/null @@ -1,114 +0,0 @@ - -module lscale_cond_mod - -!----------------------------------------------------------------------- -use fms_mod, only: file_exist, error_mesg, open_namelist_file, & - check_nml_error, mpp_pe, mpp_root_pe, FATAL, & - close_file, write_version_number, stdlog -use sat_vapor_pres_mod, only: escomp, descomp -use constants_mod, only: HLv,HLs,Cp_Air,Grav,rdgas,rvgas - -implicit none -private -!----------------------------------------------------------------------- -! ---- public interfaces ---- - - public lscale_cond, lscale_cond_init, lscale_cond_end - -!----------------------------------------------------------------------- -! ---- version number ---- - - character(len=128) :: version = '$Id: lscale_cond.F90,v 10.0 2003/10/24 22:00:34 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized=.false. - - -contains - -!####################################################################### - - subroutine lscale_cond (tin, qin, pfull, phalf, coldT, & - rain, snow, tdel, qdel, mask, conv) - -!----------------------------------------------------------------------- -! -! large scale condensation -! -!----------------------------------------------------------------------- -! -! input: tin temperature at full model levels -! qin specific humidity of water vapor at full -! model levels -! pfull pressure at full model levels -! phalf pressure at half (interface) model levels -! coldT should precipitation be snow at this point? -! optional: -! mask optional mask (0 or 1.) -! conv logical flag; if true then no large-scale -! adjustment is performed at that grid-point or -! model level -! -! output: rain liquid precipitation (kg/m2) -! snow frozen precipitation (kg/m2) -! tdel temperature tendency at full model levels -! qdel specific humidity tendency (of water vapor) at -! full model levels -! -!----------------------------------------------------------------------- -!--------------------- interface arguments ----------------------------- - - real , intent(in) , dimension(:,:,:) :: tin, qin, pfull, phalf - logical , intent(in) , dimension(:,:):: coldT - real , intent(out), dimension(:,:) :: rain,snow - real , intent(out), dimension(:,:,:) :: tdel, qdel - real , intent(in) , dimension(:,:,:), optional :: mask - logical, intent(in) , dimension(:,:,:), optional :: conv -!----------------------------------------------------------------------- - - call error_mesg('lscale_cond', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine lscale_cond - -!####################################################################### - - subroutine lscale_cond_init () - -!----------------------------------------------------------------------- -! -! initialization for large scale condensation -! -!----------------------------------------------------------------------- - -!---------- output namelist -------------------------------------------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized=.true. - -!--------------------------------------------------------------------- - - call error_mesg('lscale_cond_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine lscale_cond_init - -!####################################################################### - - subroutine lscale_cond_end - - module_is_initialized=.false. - -!--------------------------------------------------------------------- - - call error_mesg('lscale_cond_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine lscale_cond_end - -!####################################################################### - -end module lscale_cond_mod - diff --git a/src/atmos_param/mg_drag/mg_drag.F90 b/src/atmos_param/mg_drag/mg_drag.F90 index 7d4bb03952..eb85e3c988 100644 --- a/src/atmos_param/mg_drag/mg_drag.F90 +++ b/src/atmos_param/mg_drag/mg_drag.F90 @@ -26,7 +26,7 @@ module mg_drag_mod private character(len=128) :: version = '$Id: mg_drag.F90,v 19.0 2012/01/06 20:10:07 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' real, parameter :: p00 = 1.e5 diff --git a/src/atmos_param/moist_conv/moist_conv.F90 b/src/atmos_param/moist_conv/moist_conv.F90 index 7cd9f24cf5..b26569871f 100644 --- a/src/atmos_param/moist_conv/moist_conv.F90 +++ b/src/atmos_param/moist_conv/moist_conv.F90 @@ -50,7 +50,7 @@ module moist_conv_mod !---- VERSION NUMBER ----- character(len=128) :: version = '$Id: moist_conv.F90,v 19.0 2012/01/06 20:10:09 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !---------- initialize constants used by this module ------------------- diff --git a/src/atmos_param/moist_conv/null/moist_conv.F90 b/src/atmos_param/moist_conv/null/moist_conv.F90 deleted file mode 100644 index fc92338f48..0000000000 --- a/src/atmos_param/moist_conv/null/moist_conv.F90 +++ /dev/null @@ -1,67 +0,0 @@ -module moist_conv_mod - -use time_manager_mod, only: time_type -use fms_mod, only: error_mesg, FATAL, WARNING - -implicit none -private - -public :: moist_conv, moist_conv_init, moist_conv_end - -CONTAINS - -!####################################################################### - - subroutine moist_conv ( Tin, Qin, Pfull, Phalf, coldT, & - Tdel, Qdel, Rain, Snow, & - dtinv, Time, is, js, tracers, qtrmca, & - Lbot, mask, Conv, & - ql, qi, cf, qldel, qidel, cfdel) - - real, intent(INOUT), dimension(:,:,:) :: Tin, Qin - real, intent(IN) , dimension(:,:,:) :: Pfull, Phalf - logical, intent(IN) , dimension(:,:) :: coldT - real, intent(OUT), dimension(:,:,:) :: Tdel, Qdel - real, intent(OUT), dimension(:,:) :: Rain, Snow - real, intent(IN) :: dtinv -type(time_type), intent(in) :: Time -integer, intent(IN) :: is, js - real, dimension(:,:,:,:), intent(in) :: tracers - real, dimension(:,:,:,:), intent(out) :: qtrmca - integer, intent(IN) , dimension(:,:), optional :: Lbot - real, intent(IN) , dimension(:,:,:), optional :: mask - logical, intent(OUT), dimension(:,:,:), optional :: Conv - real, intent(INOUT), dimension(:,:,:), optional :: ql, qi, cf - real, intent(OUT), dimension(:,:,:), optional :: qldel, qidel, cfdel - - - call error_mesg('moist_conv', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine moist_conv - -!####################################################################### - - subroutine moist_conv_init (axes, Time, tracers_in_mca) - - integer, intent(in) :: axes(4) - type(time_type), intent(in) :: Time - logical, dimension(:), intent(in), optional :: tracers_in_mca - - call error_mesg('moist_conv_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine moist_conv_init - - -!####################################################################### - subroutine moist_conv_end - - call error_mesg('donner_deep', & - 'This module is not supported as part of the public release', WARNING) - - end subroutine moist_conv_end - -!####################################################################### - -end module moist_conv_mod diff --git a/src/atmos_param/moist_processes/detr_ice_num.F90 b/src/atmos_param/moist_processes/detr_ice_num.F90 index a573f87d9e..fd6d79ed01 100644 --- a/src/atmos_param/moist_processes/detr_ice_num.F90 +++ b/src/atmos_param/moist_processes/detr_ice_num.F90 @@ -18,7 +18,7 @@ module detr_ice_num_mod !----------------------------------------------------------------------- !----version number----------------------------------------------------- character(len=128) :: version = '$Id: detr_ice_num.F90,v 19.0 2012/01/06 20:10:40 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !------------------------------------------------------------------------ !--namelist-------------------------------------------------------------- diff --git a/src/atmos_param/moist_processes/moist_processes.F90 b/src/atmos_param/moist_processes/moist_processes.F90 index ffdd46a009..9f218eb9ff 100644 --- a/src/atmos_param/moist_processes/moist_processes.F90 +++ b/src/atmos_param/moist_processes/moist_processes.F90 @@ -56,9 +56,18 @@ module moist_processes_mod use ras_mod, only: ras_end, ras_init use dry_adj_mod, only: dry_adj, dry_adj_init use strat_cloud_mod, only: strat_cloud_init, strat_cloud_end, & - strat_cloud_restart + strat_cloud_restart, strat_cloud_time_vary use detr_ice_num_mod, only: detr_ice_num, detr_ice_num_init, & detr_ice_num_end + +! ---> h1g +use mpp_mod, only: mpp_chksum +use MG_microp_3D_mod, only: MG_microp_3D_init, MG_microp_3D, & + MG_microp_3D_end + +use clubb_driver_mod, only: clubb_init, clubb, clubb_end +! <--- h1g + use rh_clouds_mod, only: rh_clouds_init, rh_clouds_end, & rh_clouds_sum use diag_cloud_mod, only: diag_cloud_init, diag_cloud_end, & @@ -89,7 +98,7 @@ module moist_processes_mod !-------------------- public data/interfaces --------------------------- public moist_processes, moist_processes_init, moist_processes_end, & - moist_alloc_init, moist_alloc_end, & + moist_alloc_init, moist_alloc_end, set_cosp_precip_sources, & moist_processes_time_vary, moist_processes_endts, & doing_strat, moist_processes_restart @@ -99,8 +108,8 @@ module moist_processes_mod !--------------------- version number ---------------------------------- character(len=128) :: & - version = '$Id: moist_processes.F90,v 19.0 2012/01/06 20:10:42 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + version = '$Id: moist_processes.F90,v 20.0 2013/12/13 23:18:25 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' character(len=5), private :: mod_name = 'moist' logical :: moist_allocated = .false. @@ -223,6 +232,13 @@ module moist_processes_mod logical :: use_updated_profiles_for_uw = .false. logical :: only_one_conv_scheme_per_column = .false. logical :: limit_conv_cloud_frac = .false. + +! ---> h1g + real :: conv_frac_max = 0.99 + logical :: use_updated_profiles_for_clubb = .false. + logical :: remain_detrain_bug = .false. +! <--- h1g + logical :: include_donmca_in_cosp = .true. logical :: use_tau=.false. logical :: do_gust_cv = .false. @@ -260,7 +276,8 @@ module moist_processes_mod do_limit_uw, do_limit_donner, using_fms, & do_bm, do_bmmass, do_bmomp, do_simple, & do_ice_num, do_legacy_strat_cloud, & - detrain_liq_num, detrain_ice_num + detrain_liq_num, detrain_ice_num, & + conv_frac_max, use_updated_profiles_for_clubb, remain_detrain_bug !h1g !-------------------- clock definitions -------------------------------- @@ -269,6 +286,9 @@ module moist_processes_mod stratcloud_clock, shallowcu_clock !-------------------- diagnostics fields ------------------------------- +! ---> h1g, dump cell and neso cloud fraction from donner-deep, 2011-08-08 +integer :: id_cell_cld_frac, id_meso_cld_frac, id_donner_humidity_area +! <--- h1g, dump cell and neso cloud fraction from donner-deep, 2011-08-08 integer :: id_tdt_conv, id_qdt_conv, id_prec_conv, id_snow_conv, & id_snow_tot, id_tot_cld_amt, id_conv_freq, & @@ -324,9 +344,10 @@ module moist_processes_mod id_uw_freq, & id_prod_no, id_m_cdet_donner, id_m_cellup, & id_conv_rain3d, id_conv_snow3d, & - id_lscale_rain3d, id_lscale_snow3d + id_lscale_rain3d, id_lscale_snow3d, id_lscale_precip3d integer :: id_qvout, id_qaout, id_qlout, id_qiout +integer :: id_qnout, id_qniout integer :: id_vaporint, id_condensint, id_precipint, id_diffint integer :: id_vertmotion @@ -336,7 +357,7 @@ module moist_processes_mod integer :: id_wetdep_om, id_wetdep_SOA, id_wetdep_bc, & id_wetdep_so4, id_wetdep_so2, id_wetdep_DMS, & id_wetdep_NH4NO3, id_wetdep_salt, id_wetdep_dust -integer :: id_f_snow_berg +integer :: id_f_snow_berg, id_f_snow_berg_cond, id_f_snow_berg_wtd integer, dimension(:), allocatable :: id_tracerdt_conv, & id_tracerdt_conv_col, & @@ -387,6 +408,12 @@ module moist_processes_mod integer :: nqr, nqs, nqg ! additional tracer indices for Lin Micro-Physics integer :: ktop ! top layer index for Lin Micro-Physics logical :: do_cosp, donner_meso_is_largescale + real :: strat_precip_in_cosp = 0. + real :: donner_precip_in_cosp = 0. + real :: uw_precip_in_cosp = 0. +!-->cjg + integer :: do_clubb +!<--cjg !------------------ allocatable moist processes variables -------------- @@ -410,6 +437,7 @@ module moist_processes_mod liq_precflx, ice_precflx, & liq_cellh, mca_frzh, mca_liqh,& ice_precflxh, liq_precflxh + real, allocatable, dimension(:,:) :: sumneg real, allocatable, dimension(:,:,:) :: ttnd_conv, qtnd_conv real, allocatable, dimension(:,:,:) :: qsat, det0, det_cmt real, allocatable, dimension(:,:,:) :: mc_full, mc_donner, m_cdet_donner, massflux, mc_donner_up, & @@ -420,90 +448,114 @@ module moist_processes_mod qtr, q_tnd, donner_tracer real, allocatable, dimension(:,:) :: prec_intgl + +! ---> h1g, save cloud condensate tendency due to convection (20120817) + real, allocatable, dimension(:,:,:) :: qldt_conv, qidt_conv, qadt_conv, qndt_conv, qnidt_conv +! <--- h1g !----------------------------------------------------------------------- contains !####################################################################### ! used to allocate variables used throughout moist_processes -subroutine moist_alloc_init (ix, jx, kx, lx) - integer, intent(in) :: ix,jx,kx,lx +!--> cjg: code modification to allow diagnostic tracers in physics_up (20120508) +! lx is the number of prognostic tracers +! mx is the total number of tracers (prognostic+diagnostic) + +!subroutine moist_alloc_init (ix, jx, kx, lx) +! integer, intent(in) :: ix,jx,kx,lx + +subroutine moist_alloc_init (ix, jx, kx, lx, mx) + integer, intent(in) :: ix,jx,kx,lx,mx +!<--cjg if (moist_allocated) return - allocate( tin (ix,jx,kx)) - allocate( qin (ix,jx,kx)) - allocate( rin (ix,jx,kx)) - allocate( uin (ix,jx,kx)) - allocate( vin (ix,jx,kx)) - allocate( tin_orig (ix,jx,kx)) - allocate( qin_orig (ix,jx,kx)) - allocate( t_ref (ix,jx,kx)) - allocate( q_ref (ix,jx,kx)) - allocate( ttnd (ix,jx,kx)) - allocate( qtnd (ix,jx,kx)) - allocate( rtnd (ix,jx,kx)) - allocate( utnd (ix,jx,kx)) - allocate( vtnd (ix,jx,kx)) - allocate( ttnd_don (ix,jx,kx)) - allocate( qtnd_don (ix,jx,kx)) - allocate( ttnd_conv (ix,jx,kx)) - allocate( qtnd_conv (ix,jx,kx)) - allocate( qtnd_wet (ix,jx,kx)) - allocate( tdt_init (ix,jx,kx)) - allocate( qdt_init (ix,jx,kx)) - allocate( cf (ix,jx,kx)) - allocate( cmf (ix,jx,kx)) - allocate( delta_temp(ix,jx,kx)) - allocate( delta_q (ix,jx,kx)) - allocate( delta_vapor(ix,jx,kx)) - allocate( donner_humidity_area(ix,jx,kx)) - allocate( donner_humidity_factor(ix,jx,kx)) - allocate( cloud_wet (ix,jx,kx)) - allocate( cloud_frac (ix,jx,kx)) - allocate( liquid_precip(ix,jx,kx)) - allocate( frozen_precip(ix,jx,kx)) - allocate( ice_precflx (ix,jx,kx)) - allocate( liq_precflx (ix,jx,kx)) - allocate( frz_meso (ix,jx,kx)) - allocate( liq_meso (ix,jx,kx)) - allocate( frz_cell (ix,jx,kx)) - allocate( liq_cell (ix,jx,kx)) - allocate( mca_frz (ix,jx,kx)) - allocate( mca_liq (ix,jx,kx)) - allocate( frz_mesoh (ix,jx,kx+1)) - allocate( liq_mesoh (ix,jx,kx+1)) - allocate( frz_cellh (ix,jx,kx+1)) - allocate( liq_cellh (ix,jx,kx+1)) - allocate( mca_liqh (ix,jx,kx+1)) - allocate( mca_frzh (ix,jx,kx+1)) - allocate( ice_precflxh(ix,jx,kx+1)) - allocate( liq_precflxh(ix,jx,kx+1)) - allocate( qsat (ix,jx,kx)) - allocate( det0 (ix,jx,kx)) - allocate( det_cmt (ix,jx,kx)) - allocate( mc_full (ix,jx,kx)) - allocate( mc_donner (ix,jx,kx)) - allocate( mc_donner_up (ix,jx,kx)) - allocate( mc_half (ix,jx,kx+1)) - allocate( mc_donner_half (ix,jx,kx+1)) - allocate( m_cdet_donner(ix,jx,kx)) - allocate( massflux (ix,jx,kx)) - allocate( RH (ix,jx,kx)) + allocate( tin (ix,jx,kx)) !; tin = 0.0 + allocate( qin (ix,jx,kx)) !; qin = 0.0 + allocate( rin (ix,jx,kx)) !; rin = 0.0 + allocate( uin (ix,jx,kx)) !; uin = 0.0 + allocate( vin (ix,jx,kx)) !; vin = 0.0 + allocate( tin_orig (ix,jx,kx)) !; tin_orig = 0.0 + allocate( qin_orig (ix,jx,kx)) !; qin_orig = 0.0 + allocate( t_ref (ix,jx,kx)) ; t_ref = 0.0 + allocate( q_ref (ix,jx,kx)) ; q_ref = 0.0 + allocate( ttnd (ix,jx,kx)) ; ttnd = 0.0 + allocate( qtnd (ix,jx,kx)) ; qtnd = 0.0 + allocate( rtnd (ix,jx,kx)) ; rtnd = 0.0 + allocate( utnd (ix,jx,kx)) ; utnd = 0.0 + allocate( vtnd (ix,jx,kx)) ; vtnd = 0.0 + allocate( ttnd_don (ix,jx,kx)) ; ttnd_don = 0.0 + allocate( qtnd_don (ix,jx,kx)) ; qtnd_don = 0.0 + allocate( ttnd_conv (ix,jx,kx)) ; ttnd_conv = 0.0 + allocate( qtnd_conv (ix,jx,kx)) ; qtnd_conv = 0.0 + allocate( qtnd_wet (ix,jx,kx)) ; qtnd_wet = 0.0 + allocate( tdt_init (ix,jx,kx)) ; tdt_init = 0.0 + allocate( qdt_init (ix,jx,kx)) ; qdt_init = 0.0 + allocate( cf (ix,jx,kx)) ; cf = 0.0 + allocate( cmf (ix,jx,kx)) ; cmf = 0.0 + allocate( delta_temp(ix,jx,kx)) ; delta_temp = 0.0 + allocate( delta_q (ix,jx,kx)) ; delta_q = 0.0 + allocate( delta_vapor(ix,jx,kx)) ; delta_vapor = 0.0 + allocate( donner_humidity_area(ix,jx,kx)) ; donner_humidity_area = 0.0 + allocate( donner_humidity_factor(ix,jx,kx)) ; donner_humidity_factor = 0.0 + allocate( cloud_wet (ix,jx,kx)) ; cloud_wet = 0.0 + allocate( cloud_frac (ix,jx,kx)) ; cloud_frac = 0.0 + allocate( liquid_precip(ix,jx,kx)) ; liquid_precip = 0.0 + allocate( frozen_precip(ix,jx,kx)) ; frozen_precip = 0.0 + allocate( ice_precflx (ix,jx,kx)) ; ice_precflx = 0.0 + allocate( liq_precflx (ix,jx,kx)) ; liq_precflx = 0.0 + allocate( frz_meso (ix,jx,kx)) ; frz_meso = 0.0 + allocate( liq_meso (ix,jx,kx)) ; liq_meso = 0.0 + allocate( frz_cell (ix,jx,kx)) ; frz_cell = 0.0 + allocate( liq_cell (ix,jx,kx)) ; liq_cell = 0.0 + allocate( mca_frz (ix,jx,kx)) ; mca_frz = 0.0 + allocate( mca_liq (ix,jx,kx)) ; mca_liq = 0.0 + allocate( frz_mesoh (ix,jx,kx+1)) ; frz_mesoh = 0.0 + allocate( liq_mesoh (ix,jx,kx+1)) ; liq_mesoh = 0.0 + allocate( frz_cellh (ix,jx,kx+1)) ; frz_cellh = 0.0 + allocate( sumneg (ix,jx)) ; sumneg = 0.0 + allocate( liq_cellh (ix,jx,kx+1)) ; liq_cellh = 0.0 + allocate( mca_liqh (ix,jx,kx+1)) ; mca_liqh = 0.0 + allocate( mca_frzh (ix,jx,kx+1)) ; mca_frzh = 0.0 + allocate( ice_precflxh(ix,jx,kx+1)) ; ice_precflxh = 0.0 + allocate( liq_precflxh(ix,jx,kx+1)) ; liq_precflxh = 0.0 + allocate( qsat (ix,jx,kx)) ; qsat = 0.0 + allocate( det0 (ix,jx,kx)) ; det0 = 0.0 + allocate( det_cmt (ix,jx,kx)) ; det_cmt = 0.0 + allocate( mc_full (ix,jx,kx)) ; mc_full = 0.0 + allocate( mc_donner (ix,jx,kx)) ; mc_donner = 0.0 + allocate( mc_donner_up (ix,jx,kx)) ; mc_donner_up = 0.0 + allocate( mc_half (ix,jx,kx+1)) ; mc_half = 0.0 + allocate( mc_donner_half (ix,jx,kx+1)) ; mc_donner_half = 0.0 + allocate( m_cdet_donner(ix,jx,kx)) ; m_cdet_donner = 0.0 + allocate( massflux (ix,jx,kx)) ; massflux = 0.0 + allocate( RH (ix,jx,kx)) ; RH = 0.0 ! pmass defined in moist_processes_utils - allocate( pmass (ix,jx,kx)) - allocate( wetdeptnd (ix,jx,kx)) - allocate(tracer (ix,jx,kx,lx)) - allocate(tracer_orig(ix,jx,kx,lx)) - allocate(q_tnd (ix,jx,kx,lx)) - allocate(rdt_init (ix,jx,kx,lx)) - allocate(qtr (ix,jx,kx,num_donner_tracers)) - allocate(donner_tracer(ix,jx,kx,num_donner_tracers)) - allocate(delta_qn (ix,jx,kx)) - allocate(delta_qni (ix,jx,kx)) - allocate(nllin (ix,jx,kx)) - allocate(nilin (ix,jx,kx)) - + allocate( pmass (ix,jx,kx)) ; pmass = 0.0 + allocate( wetdeptnd (ix,jx,kx)) ; wetdeptnd = 0.0 +!--> cjg: code modification to allow diagnostic tracers in physics_up (20120508) +! allocate(tracer (ix,jx,kx,lx)) ; tracer = 0.0 +! allocate(tracer_orig(ix,jx,kx,lx)) ; tracer_orig = 0.0 + allocate(tracer (ix,jx,kx,mx)) ; tracer = 0.0 + allocate(tracer_orig(ix,jx,kx,mx)) ; tracer_orig = 0.0 +!<--cjg + allocate(q_tnd (ix,jx,kx,lx)) ; q_tnd = 0.0 + allocate(rdt_init (ix,jx,kx,lx)) ; rdt_init = 0.0 + allocate(qtr (ix,jx,kx,num_donner_tracers)) ; qtr = 0.0 + allocate(donner_tracer(ix,jx,kx,num_donner_tracers)) ; donner_tracer = 0.0 + allocate(delta_qn (ix,jx,kx)) ; delta_qn = 0.0 + allocate(delta_qni (ix,jx,kx)) ; delta_qni = 0.0 + allocate(nllin (ix,jx,kx)) ; nllin = 0.0 + allocate(nilin (ix,jx,kx)) ; nilin = 0.0 + +! ---> h1g, allocate cloud condensate tendency due to convection (20120817) + allocate( qldt_conv (ix,jx,kx)) + allocate( qidt_conv (ix,jx,kx)) + allocate( qadt_conv (ix,jx,kx)) + if( do_liq_num ) allocate( qndt_conv (ix,jx,kx)) + if( do_ice_num ) allocate( qnidt_conv (ix,jx,kx)) +! <--- h1g moist_allocated = .true. @@ -558,6 +610,7 @@ subroutine moist_alloc_end deallocate( frz_mesoh ) deallocate( liq_mesoh ) deallocate( frz_cellh ) + deallocate( sumneg ) deallocate( liq_cellh ) deallocate( mca_frzh ) deallocate( mca_liqh ) @@ -587,6 +640,13 @@ subroutine moist_alloc_end deallocate(nllin ) deallocate(nilin ) +! ---> h1g, deallocate cloud condensate tendency due to convection (20120817) + deallocate( qldt_conv ) + deallocate( qidt_conv ) + deallocate( qadt_conv ) + if( do_liq_num ) deallocate( qndt_conv ) + if( do_ice_num ) deallocate( qnidt_conv ) +! <--- h1g moist_allocated = .false. @@ -603,10 +663,18 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & convect, lprec, fprec, fl_lsrain, & fl_lssnow, fl_ccrain, fl_ccsnow, & fl_donmca_rain, fl_donmca_snow, gust_cv, & - area, lat, lsc_cloud_area, lsc_liquid, & + area, lon, lat, lsc_cloud_area, lsc_liquid, & lsc_ice, lsc_droplet_number, & lsc_ice_number, lsc_snow, lsc_rain, & lsc_snow_size, lsc_rain_size , & +! ---> h1g + dcond_ls_liquid, dcond_ls_ice, & + Ndrop_act_CLUBB, Icedrop_act_CLUBB, & + ndust, rbar_dust, & + diff_t_clubb, & + tdt_shf, & + qdt_lhf, & +! <--- h1g Aerosol, mask, kbot, & shallow_cloud_area, shallow_liquid, & shallow_ice, shallow_droplet_number, & @@ -676,6 +744,9 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! area grid box area (in m2) ! [real, dimension(nlon,nlat)] ! +! lon longitude in radians ! h1g +! [real, dimension(nlon,nlat)] ! h1g +! ! lat latitude in radians ! [real, dimension(nlon,nlat)] ! @@ -719,7 +790,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & real, intent(in) , dimension(:,:,:) :: phalf, pfull, zhalf, zfull, omega, & diff_t, t, q, u, v, tm, qm, um, vm real, dimension(:,:,:), intent(in) :: radturbten - real, intent(in) , dimension(:,:,:,:) :: r, rm + real, intent(inout), dimension(:,:,:,:) :: r, rm ! cjg: inout real, intent(inout),dimension(:,:,:) :: tdt, qdt, udt, vdt real, intent(inout),dimension(:,:,:,:):: rdt logical, intent(out), dimension(:,:) :: convect @@ -729,7 +800,17 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & fl_donmca_rain, fl_donmca_snow real, intent(out), dimension(:,:,:) :: diff_cu_mo real, intent(in) , dimension(:,:) :: area + real, intent(in) , dimension(:,:) :: lon real, intent(in) , dimension(:,:) :: lat + +! ---> h1g + real, intent(inout), dimension(:,:,:), optional :: dcond_ls_liquid, dcond_ls_ice + real, intent(inout), dimension(:,:,:), optional :: Ndrop_act_CLUBB, Icedrop_act_CLUBB + real, intent(inout), dimension(:,:,:), optional :: ndust, rbar_dust + real, intent(inout), dimension(:,:,:), optional :: diff_t_clubb + real, intent(inout), dimension(:,:), optional :: tdt_shf, qdt_lhf +! < --- h1g + real, intent(out) , dimension(:,:,:) :: & lsc_cloud_area, lsc_liquid, lsc_ice, & lsc_droplet_number, lsc_ice_number, lsc_snow, & @@ -756,7 +837,6 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & integer :: n, nn, i, j, k, ix, jx, kx, nt, tr integer :: m, mm logical :: used, avgbl - real :: sumneg real :: dtinv real, dimension(size(t,1),size(t,2)) :: cape, cin @@ -821,7 +901,21 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & real, dimension(size(t,1),size(t,2)) :: tca2 real, dimension(size(t,1),size(t,2),size(t,3)) :: total_cloud_area real, dimension(size(t,1),size(t,2),size(t,3)) :: temp_3d1, temp_3d2, temp_3d3 - + +! ---> h1g, 2010-08-23 + real :: current_total_sec + integer :: current_sec, current_days + +! consider the donner-deep mass flux impacts on clubb + real, dimension(size(omega,1),size(omega,2),size(omega,3)) :: conv_frac_clubb + real, dimension(size(omega,1),size(omega,2),size(omega,3)) :: convective_humidity_ratio_clubb + real :: qrf, env_fraction, env_qv +! <--- h1g, 2010-08-23 + + +! ---> h1g, 2012-10-05 + real, dimension(size(omega,1),size(omega,2),size(omega,3)) :: qcvar_clubb +! <--- h1g, 2012-10-05 !-------- input array size and position in global storage -------------- ix=size(t,1); jx=size(t,2); kx=size(t,3); nt=size(rdt,4) @@ -869,10 +963,10 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & rdt_init(is:ie,js:je,:,:) = rdt tdt_init(is:ie,js:je,:) = tdt qdt_init(is:ie,js:je,:) = qdt - ttnd_conv(is:ie,js:je,:) = 0. - qtnd_conv(is:ie,js:je,:) = 0. - qtnd(is:ie,js:je,:) = 0. - q_tnd(is:ie,js:je,:,:) = 0. +! ttnd_conv(is:ie,js:je,:) = 0. +! qtnd_conv(is:ie,js:je,:) = 0. +! qtnd(is:ie,js:je,:) = 0. +! q_tnd(is:ie,js:je,:,:) = 0. !--------------------------------------------------------------------- ! define input fields to be used, either the tau time level fields, @@ -1005,7 +1099,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! !@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - cmf(is:ie,js:je,:) = 0. +! cmf(is:ie,js:je,:) = 0. tracer_orig(is:ie,js:je,:,:) = tracer(is:ie,js:je,:,:) if (.not. do_donner_before_uw) then call mpp_clock_begin (shallowcu_clock) @@ -1103,7 +1197,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! check each active tracer to find those to be transported and fill ! the donner_tracers array with these fields. !--------------------------------------------------------------------- - donner_tracer(is:ie,js:je,:,:) = 0.0 +! donner_tracer(is:ie,js:je,:,:) = 0.0 nn = 1 do n=1,num_tracers if (tracers_in_donner(n)) then @@ -1446,6 +1540,12 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & endif endif ! (donner_conservation_checks) +! ---> h1g, dump donner-deep cell and meso cloud fraction, 2010-08-08 + used = send_data (id_cell_cld_frac, cell_cld_frac(is:ie,js:je,:), Time, is, js, 1, rmask=mask ) + used = send_data (id_meso_cld_frac, meso_cld_frac(is:ie,js:je,:), Time, is, js, 1, rmask=mask ) + used = send_data (id_donner_humidity_area, donner_humidity_area(is:ie,js:je,:), Time, is, js, 1, rmask=mask ) +! <--- h1g, dump donner-deep cell and meso cloud fraction, 2010-08-08 + call mpp_clock_end (donner_clock) if (do_donner_mca) then @@ -1580,13 +1680,13 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! appropriately. !--------------------------------------------------------------------- else ! (do_donner_deep) - mc_donner(is:ie,js:je,:) = 0.0 - mc_donner_up(is:ie,js:je,:) = 0.0 - mc_donner_half(is:ie,js:je, : ) = 0.0 - m_cdet_donner(is:ie,js:je,:) = 0.0 +! mc_donner(is:ie,js:je,:) = 0.0 +! mc_donner_up(is:ie,js:je,:) = 0.0 +! mc_donner_half(is:ie,js:je, : ) = 0.0 +! m_cdet_donner(is:ie,js:je,:) = 0.0 m_cellup = 0.0 - donner_humidity_area(is:ie,js:je,:) = 0. - donner_humidity_factor(is:ie,js:je,:) = 0. +! donner_humidity_area(is:ie,js:je,:) = 0. +! donner_humidity_factor(is:ie,js:je,:) = 0. endif ! (do_donner_deep) ! ADD TENDENCIES HERE, IN SAME AORDER AS ORIGINAL: if (do_donner_deep) then @@ -1621,8 +1721,13 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! radius for detrained droplets !------------------------------------------------------------------------- IF (do_liq_num .AND. detrain_liq_num) THEN - delta_qn(is:ie,js:je,:) = delta_ql(is:ie,js:je,:)/1000.* & - 3./(4.*3.14*10.e-15) + if ( remain_detrain_bug ) then + delta_qn(is:ie,js:je,:) = delta_ql(is:ie,js:je,:)/1000.* & + 3./(4.*3.14*10.e-15) + else + delta_qn(is:ie,js:je,:) = delta_ql(is:ie,js:je,:)/1000.* & + 3./(4.*3.14e-15) + endif !( remain_detrain_bug ) tracer(is:ie,js:je,:,nqn) = nllin (is:ie,js:je,:) + & delta_qn(is:ie,js:je,:) rdt(:,:,:,nqn) = rdt(:,:,:,nqn) + delta_qn(is:ie,js:je,:)*dtinv @@ -1812,7 +1917,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! if ras_mod is not activated, set the ras mass flux field to be 0.0. !--------------------------------------------------------------------- mc = 0.0 - det0(is:ie,js:je,:) = 0.0 +! det0(is:ie,js:je,:) = 0.0 rain_ras = 0.0 snow_ras = 0.0 endif ! (do_ras) @@ -1857,7 +1962,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! CURRENTLY no detrained mass flux provided from uw_conv; should only ! use with 'diffusive' cmt scheme, not the non-local. (attempt to ! use non-local will cause FATAL in _init routine.) - det_cmt(is:ie,js:je,:) = 0.0 +! det_cmt(is:ie,js:je,:) = 0.0 call moistproc_cmt ( Time, is, js, tin(is:ie,js:je,:), uin(is:ie,js:je,:), vin(is:ie,js:je,:), & tracer(is:ie,js:je,:,:), pfull, phalf, & zfull, zhalf, pmass(is:ie,js:je,:), tdt, udt, vdt, rdt, & @@ -1870,7 +1975,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! if using diffusive cmt, call cu_mo_trans once with combined mass ! fluxes from all desired convective schemes. mc_cmt = 0. - det_cmt(is:ie,js:je,:) = 0. +! det_cmt(is:ie,js:je,:) = 0. if (cmt_uses_ras) then mc_cmt = mc_cmt + mc endif @@ -1928,8 +2033,8 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & endif end do - mc_full(is:ie,js:je,:)=0.; - mc_half(is:ie,js:je,:)=0.; + mc_full(is:ie,js:je,1)=0.; + mc_half(is:ie,js:je,1)=0.; do k=2,kx mc_full(is:ie,js:je,k) = 0.5*(mc(:,:,k) + mc(:,:,k+1)) + & 0.5*(cmf(is:ie,js:je,k)+cmf(is:ie,js:je,k-1)) + & @@ -1992,24 +2097,24 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! lightning NOx parameterization !----------------------------------------------------------------------- if ( get_tracer_index(MODEL_ATMOS,'no') .ne. NO_TRACER ) then - cldbot = 0 - cldtop = 0 - do i = 1,ix - do j = 1,jx - do k = 1,kx - if (mc_full(i+is-1,j+js-1,k) /= 0 ) then - cldtop(i,j) = k - exit - endif - enddo - do k = size(r,3),1,-1 - if (mc_full(i+is-1,j+js-1,k) /= 0 ) then - cldbot(i,j) = k - exit - endif - enddo - enddo - enddo +! cldbot = 0 +! cldtop = 0 +! do i = 1,ix +! do j = 1,jx +! do k = 1,kx +! if (mc_full(i+is-1,j+js-1,k) /= 0 ) then +! cldtop(i,j) = k +! exit +! endif +! enddo +! do k = size(r,3),1,-1 +! if (mc_full(i+is-1,j+js-1,k) /= 0 ) then +! cldbot(i,j) = k +! exit +! endif +! enddo +! enddo +! enddo call moz_hook(cldtop, cldbot, land, zfull, zhalf, t, prod_no, area, lat, & Time, is, js) rdt(:,:,:,get_tracer_index(MODEL_ATMOS,'no')) = & @@ -2385,6 +2490,130 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & !----------------------------------------------------------------------- call mpp_clock_begin (largescale_clock) +! ---> h1g, if CLUBB is in moist-processes, CLUBB is called after donner-deep but before microphysics + if( do_clubb == 2) then +! ---> modify tendencies to consider donner-deep effects + call compute_qs (t, pfull, qsat) + + do k=1, kx + do j=js, je + do i=is, ie + qrf = MAX (q(i,j,k), 0.0) + + if (do_uw_conv .and. do_donner_deep) then + conv_frac_clubb(i,j,k) = donner_humidity_area(i,j,k) + & + shallow_cloud_area(i,j,k) + env_qv = qrf - qsat(i,j,k)*(cell_cld_frac(i,j,k) + & + donner_humidity_factor(i,j,k) + shallow_cloud_area(i,j,k)) + elseif (do_donner_deep) then + conv_frac_clubb(i,j,k) = donner_humidity_area(i,j,k) + env_qv = qrf - qsat(i,j,k)*(cell_cld_frac(i,j,k) + donner_humidity_factor(i,j,k)) + elseif (do_uw_conv) then + conv_frac_clubb(i,j,k) = shallow_cloud_area(i,j,k) + env_qv = qrf - shallow_cloud_area(i,j,k)*qsat(i,j,k) + else + conv_frac_clubb(i,j,k) = 0.0 + env_qv = qrf + endif + conv_frac_clubb(i,j,k) = min( conv_frac_clubb(i,j,k), conv_frac_max ) + env_fraction = 1.0 - conv_frac_clubb(i,j,k) +! <--- h1g, 2011-08-19 + +!--------------------------------------------------------------------- +! define the ratio of the grid-box relative humidity to the humidity +! in the environment of the convective clouds. +!---------------------------------------------------------------------- + +!---------------------------------------------------------------------- +! grid box has vapor and there is vapor outside of the convective a +! clouds available for condensation. +!---------------------------------------------------------------- + if (qrf /= 0.0 .and. env_qv > 0.0) then + +!-------------------------------------------------------------------- +! there is grid box area not filled with convective clouds +!-------------------------------------------------------------------- + if (env_fraction > 0.0) then + convective_humidity_ratio_clubb(i,j,k) = & + MAX (qrf*env_fraction/env_qv, 1.0) + +!--------------------------------------------------------------------- +! grid box is filled with convective clouds. +!---------------------------------------------------------------------- + else + convective_humidity_ratio_clubb(i,j,k) = -10.0 + endif + +!-------------------------------------------------------------------- +! either no vapor or all vapor taken up in convective clouds so +! none left for large-scale cd. +!--------------------------------------------------------------------- + else + convective_humidity_ratio_clubb(i,j,k) = 1.0 + endif + end do + end do + end do + + if ( .not. use_updated_profiles_for_clubb ) then + tdt = tdt - ttnd_conv + qdt = qdt - qtnd_conv + qldt_conv = rdt(:,:,:,nql) - rdt_init(:,:,:,nql) + qidt_conv = rdt(:,:,:,nqi) - rdt_init(:,:,:,nqi) + qadt_conv = rdt(:,:,:,nqa) - rdt_init(:,:,:,nqa) + IF (do_liq_num) qndt_conv = rdt(:,:,:,nqn) - rdt_init(:,:,:,nqn) + IF (do_ice_num) qnidt_conv= rdt(:,:,:,nqni)- rdt_init(:,:,:,nqni) + + rdt(:,:,:,nql) = rdt(:,:,:,nql) - qldt_conv + rdt(:,:,:,nqi) = rdt(:,:,:,nqi) - qidt_conv + rdt(:,:,:,nqa) = rdt(:,:,:,nqa) - qadt_conv + IF (do_liq_num) rdt(:,:,:,nqn) = rdt(:,:,:,nqn) - qndt_conv + IF (do_ice_num) rdt(:,:,:,nqni) = rdt(:,:,:,nqni) - qnidt_conv + endif + + call clubb( is, ie, js, je, lon, lat, & + Time, & + dt, & + phalf, pfull, zhalf, zfull, omega, & + t, q, r, u, v, & + ustar, bstar, qstar, & + tdt, qdt, rdt, udt, vdt, & + dcond_ls_liquid, dcond_ls_ice, & + Ndrop_act_CLUBB, Icedrop_act_CLUBB, & + ndust, rbar_dust, & + diff_t_clubb, & + qcvar_clubb=qcvar_clubb, & + tdt_shf = tdt_shf, & + qdt_lhf = qdt_lhf, & + Aerosol=Aerosol, mask=mask, & + mc_full=mc_full, & + conv_frac_clubb=conv_frac_clubb, & + convective_humidity_ratio_clubb=convective_humidity_ratio_clubb) + + if ( .not. use_updated_profiles_for_clubb ) then + tdt = tdt + ttnd_conv + qdt = qdt + qtnd_conv + rdt(:,:,:,nql) = rdt(:,:,:,nql) + qldt_conv + rdt(:,:,:,nqi) = rdt(:,:,:,nqi) + qidt_conv + rdt(:,:,:,nqa) = rdt(:,:,:,nqa) + qadt_conv + IF (do_liq_num) rdt(:,:,:,nqn) = rdt(:,:,:,nqn) + qndt_conv + IF (do_ice_num) rdt(:,:,:,nqni) = rdt(:,:,:,nqni) + qnidt_conv + endif + +! ---> updated profiles are used to call microphysics + tin(is:ie,js:je,:) = t + tdt*dt + qin(is:ie,js:je,:) = q + qdt*dt + uin(is:ie,js:je,:) = u + udt*dt + vin(is:ie,js:je,:) = v + vdt*dt + do tr=1,size(rdt,4) + tracer(is:ie,js:je,:,tr) = r(:,:,:,tr) + rdt(:,:,:,tr)*dt + end do + do tr=size(rdt,4) +1, size(r,4) + tracer(is:ie,js:je,:,tr) = r(:,:,:,tr) + end do + endif ! if do_clubb == 2 +! <--- h1g, if CLUBB is in moist-processes, CLUBB is called after donner-deep but before microphysics + !zero out arrays for large scale precipitation rain = 0. snow = 0. @@ -2410,7 +2639,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & else if (do_strat) then call mpp_clock_begin (stratcloud_clock) - call moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, tin(is:ie,js:je,:), qin(is:ie,js:je,:), & + call moistproc_strat_cloud(Time, is, ie, js, je, lon, lat, ktop, dt, tm, tin(is:ie,js:je,:), qin(is:ie,js:je,:), & tracer(is:ie,js:je,:,:), pfull, phalf, zhalf, omega, radturbten, mc_full(is:ie,js:je,:), & diff_t, land, area, tdt, qdt, rdt, q_tnd(is:ie,js:je,:,:), ttnd(is:ie,js:je,:), & qtnd(is:ie,js:je,:), lprec, fprec, & @@ -2421,16 +2650,20 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & donner_humidity_factor(is:ie,js:je,:), shallow_cloud_area, & cell_cld_frac, meso_cld_frac, & do_uw_conv, do_donner_deep, do_liq_num, & + do_clubb, & ! cjg do_lin_cld_microphys, id_qvout, id_qlout, & - id_qaout, id_qiout, limit_conv_cloud_frac, mask, & + id_qaout, id_qiout, id_qnout, id_qniout, & + limit_conv_cloud_frac, mask, & hydrostatic, phys_hydrostatic, & zfull, & do_ice_num , lsc_ice_number, & lsc_snow, lsc_rain, lsc_snow_size, & - lsc_rain_size, do_legacy_strat_cloud ) + lsc_rain_size, do_legacy_strat_cloud, & + dcond_ls_liquid, dcond_ls_ice, & ! h1g, cjg + Ndrop_act_CLUBB, Icedrop_act_CLUBB, & ! h1g, cjg + ndust, rbar_dust, qcvar_clubb=qcvar_clubb) ! h1g, cjg call mpp_clock_end (stratcloud_clock) endif ! (do_lsc) - !--------------------------------------------------------------------- ! calculate the wet deposition associated with the large scale ! condensation. @@ -2448,7 +2681,13 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & endif cloud_wet(is:ie,js:je,:) = cloud_wet(is:ie,js:je,:) + tracer(is:ie,js:je,:,nql) + tracer(is:ie,js:je,:,nqi) cloud_frac(is:ie,js:je,:) = max( min( tracer(is:ie,js:je,:,nqa), 1. ), 0. ) - used = send_data( id_f_snow_berg, f_snow_berg(:,:,:), Time,is_in=is,js_in=js ) + used = send_data( id_f_snow_berg, f_snow_berg(:,:,:), Time, & + is,js, 1) + used = send_data( id_f_snow_berg_cond, f_snow_berg(:,:,:), Time, & + is,js, 1, mask = f_snow_berg /= 0.0 ) + used = send_data( id_f_snow_berg_wtd, & + f_snow_berg(:,:,:)*(rain3d(:,:,2:)+snow3d(:,:,2:)), Time, & + is,js, 1, mask = f_snow_berg /= 0.0 ) else ! cloud_wet = qtnd_wet * dt cloud_wet(is:ie,js:je,:) = 0.5e-3 @@ -2596,6 +2835,12 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & !--------------------------------------------------------------------- used = send_data(id_lscale_snow3d, snow3d, Time, is, js, 1) +!--------------------------------------------------------------------- +!---- diagnostics for large scale precip ------------- +!--------------------------------------------------------------------- + used = send_data(id_lscale_precip3d, snow3d(:,:,2:)+rain3d(:,:,2:), & + Time, is, js, 1, mask = f_snow_berg /= 0.0 ) + endif ! (do_strat) !--------------------------------------------------------------------- @@ -2697,41 +2942,19 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & endif if (id_wetdep_salt > 0) then used = send_data (id_wetdep_salt , & - (58.44/WTMAIR)*(total_wetdep_donner(:,:,nsalt1 ) + & - total_wetdep_donner(:,:,nsalt2 ) + & - total_wetdep_donner(:,:,nsalt3 ) + & - total_wetdep_donner(:,:,nsalt4 ) + & - total_wetdep_donner(:,:,nsalt5 ) + & - total_wetdep_uw (:,:,nsalt1 ) + & - total_wetdep_uw (:,:,nsalt2 ) + & - total_wetdep_uw (:,:,nsalt3 ) + & - total_wetdep_uw (:,:,nsalt4 ) + & - total_wetdep_uw (:,:,nsalt5 )) + & - 0.05844*(ls_wetdep (:,:,nsalt1 ) + & - ls_wetdep (:,:,nsalt2 ) + & - ls_wetdep (:,:,nsalt3 ) + & - ls_wetdep (:,:,nsalt4 ) + & - ls_wetdep (:,:,nsalt5 )) , & - Time, is,js) + ( total_wetdep(:,:,nsalt1) + & + total_wetdep(:,:,nsalt2) + & + total_wetdep(:,:,nsalt3) + & + total_wetdep(:,:,nsalt4) + & + total_wetdep(:,:,nsalt5)), Time, is,js) endif if (id_wetdep_dust > 0) then used = send_data (id_wetdep_dust , & - (58.44/WTMAIR)*(total_wetdep_donner(:,:,ndust1 ) + & - total_wetdep_donner(:,:,ndust2 ) + & - total_wetdep_donner(:,:,ndust3 ) + & - total_wetdep_donner(:,:,ndust4 ) + & - total_wetdep_donner(:,:,ndust5 ) + & - total_wetdep_uw (:,:,ndust1 ) + & - total_wetdep_uw (:,:,ndust2 ) + & - total_wetdep_uw (:,:,ndust3 ) + & - total_wetdep_uw (:,:,ndust4 ) + & - total_wetdep_uw (:,:,ndust5 )) + & - 0.05844*(ls_wetdep (:,:,ndust1 ) + & - ls_wetdep (:,:,ndust2 ) + & - ls_wetdep (:,:,ndust3 ) + & - ls_wetdep (:,:,ndust4 ) + & - ls_wetdep (:,:,ndust5 )) , & - Time, is,js) + ( total_wetdep(:,:,ndust1) + & + total_wetdep(:,:,ndust2) + & + total_wetdep(:,:,ndust3) + & + total_wetdep(:,:,ndust4) + & + total_wetdep(:,:,ndust5)), Time, is,js) endif !--------------------------------------------------------------------- @@ -2769,7 +2992,7 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & temp_3d2 = rdt(:,:,:,nql) - rdt_init(is:ie,js:je,:,nql) temp_3d3 = rdt(:,:,:,nqi) - rdt_init(is:ie,js:je,:,nqi) temp_2d(:,:) = precip - call column_diag(id_enth_moist_col, is, js, Time, temp_3d1, 1.0, temp_3d2, 1.0, temp_3d3, 1.0, temp_2d) + call column_diag(id_wat_moist_col, is, js, Time, temp_3d1, 1.0, temp_3d2, 1.0, temp_3d3, 1.0, temp_2d) if (id_max_water_imbal > 0) then max_water_imbal = max( abs(temp_2d), max_water_imbal ) used = send_data(id_max_water_imbal, max_water_imbal, Time, is, js) @@ -3010,154 +3233,154 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & ! tendency, so at top of clouds a positive moisture tendency some- ! times results in a negative precipitation contribution. !-------------------------------------------------------------------- - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (liq_mesoh(i,j,k) > 0.0) then - if (liq_mesoh(i,j,k) > ABS(sumneg)) then - liq_mesoh(i,j,k) = liq_mesoh(i,j,k) + sumneg - sumneg = 0. + if (liq_mesoh(i,j,k) > ABS(sumneg(i,j))) then + liq_mesoh(i,j,k) = liq_mesoh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + liq_mesoh(i,j,k) + sumneg(i,j) = sumneg(i,j) + liq_mesoh(i,j,k) liq_mesoh(i,j,k) = 0. endif else - sumneg = sumneg + liq_mesoh(i,j,k) + sumneg(i,j) = sumneg(i,j) + liq_mesoh(i,j,k) liq_mesoh(i,j,k) = 0. endif end do end do end do - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (frz_mesoh(i,j,k) > 0.0) then - if (frz_mesoh(i,j,k) > ABS(sumneg)) then - frz_mesoh(i,j,k) = frz_mesoh(i,j,k) + sumneg - sumneg = 0. + if (frz_mesoh(i,j,k) > ABS(sumneg(i,j))) then + frz_mesoh(i,j,k) = frz_mesoh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + frz_mesoh(i,j,k) + sumneg(i,j) = sumneg(i,j) + frz_mesoh(i,j,k) frz_mesoh(i,j,k) = 0. endif else - sumneg = sumneg + frz_mesoh(i,j,k) + sumneg(i,j) = sumneg(i,j) + frz_mesoh(i,j,k) frz_mesoh(i,j,k) = 0. endif end do end do end do - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (liq_cellh(i,j,k) > 0.0) then - if (liq_cellh(i,j,k) > ABS(sumneg)) then - liq_cellh(i,j,k) = liq_cellh(i,j,k) + sumneg - sumneg = 0. + if (liq_cellh(i,j,k) > ABS(sumneg(i,j))) then + liq_cellh(i,j,k) = liq_cellh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + liq_cellh(i,j,k) + sumneg(i,j) = sumneg(i,j) + liq_cellh(i,j,k) liq_cellh(i,j,k) = 0. endif else - sumneg = sumneg + liq_cellh(i,j,k) + sumneg(i,j) = sumneg(i,j) + liq_cellh(i,j,k) liq_cellh(i,j,k) = 0. endif end do end do end do - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (frz_cellh(i,j,k) > 0.0) then - if (frz_cellh(i,j,k) > ABS(sumneg)) then - frz_cellh(i,j,k) = frz_cellh(i,j,k) + sumneg - sumneg = 0. + if (frz_cellh(i,j,k) > ABS(sumneg(i,j))) then + frz_cellh(i,j,k) = frz_cellh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + frz_cellh(i,j,k) + sumneg(i,j) = sumneg(i,j) + frz_cellh(i,j,k) frz_cellh(i,j,k) = 0. endif else - sumneg = sumneg + frz_cellh(i,j,k) + sumneg(i,j) = sumneg(i,j) + frz_cellh(i,j,k) frz_cellh(i,j,k) = 0. endif end do end do end do - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (ice_precflxh(i,j,k) > 0.0) then - if (ice_precflxh(i,j,k) > ABS(sumneg)) then - ice_precflxh(i,j,k) = ice_precflxh(i,j,k) + sumneg - sumneg = 0. + if (ice_precflxh(i,j,k) > ABS(sumneg(i,j))) then + ice_precflxh(i,j,k) = ice_precflxh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + ice_precflxh(i,j,k) + sumneg(i,j) = sumneg(i,j) + ice_precflxh(i,j,k) ice_precflxh(i,j,k) = 0. endif else - sumneg = sumneg + ice_precflxh(i,j,k) + sumneg(i,j) = sumneg(i,j) + ice_precflxh(i,j,k) ice_precflxh(i,j,k) = 0. endif end do end do end do - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (liq_precflxh(i,j,k) > 0.0) then - if (liq_precflxh(i,j,k) > ABS(sumneg)) then - liq_precflxh(i,j,k) = liq_precflxh(i,j,k) + sumneg - sumneg = 0. + if (liq_precflxh(i,j,k) > ABS(sumneg(i,j))) then + liq_precflxh(i,j,k) = liq_precflxh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + liq_precflxh(i,j,k) + sumneg(i,j) = sumneg(i,j) + liq_precflxh(i,j,k) liq_precflxh(i,j,k) = 0. endif else - sumneg = sumneg + liq_precflxh(i,j,k) + sumneg(i,j) = sumneg(i,j) + liq_precflxh(i,j,k) liq_precflxh(i,j,k) = 0. endif end do end do end do if (include_donmca_in_cosp) then - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (mca_liqh(i,j,k) > 0.0) then - if (mca_liqh(i,j,k) > ABS(sumneg)) then - mca_liqh(i,j,k) = mca_liqh(i,j,k) + sumneg - sumneg = 0. + if (mca_liqh(i,j,k) > ABS(sumneg(i,j))) then + mca_liqh(i,j,k) = mca_liqh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + mca_liqh(i,j,k) + sumneg(i,j) = sumneg(i,j) + mca_liqh(i,j,k) mca_liqh(i,j,k) = 0. endif else - sumneg = sumneg + mca_liqh(i,j,k) + sumneg(i,j) = sumneg(i,j) + mca_liqh(i,j,k) mca_liqh(i,j,k) = 0. endif end do end do end do - sumneg = 0. + sumneg(is:ie,js:je) = 0. do k=2, size(t,3)+1 do j=js,je do i=is,ie if (mca_frzh(i,j,k) > 0.0) then - if (mca_frzh(i,j,k) > ABS(sumneg)) then - mca_frzh(i,j,k) = mca_frzh(i,j,k) + sumneg - sumneg = 0. + if (mca_frzh(i,j,k) > ABS(sumneg(i,j))) then + mca_frzh(i,j,k) = mca_frzh(i,j,k) + sumneg(i,j) + sumneg(i,j) = 0. else - sumneg = sumneg + mca_frzh(i,j,k) + sumneg(i,j) = sumneg(i,j) + mca_frzh(i,j,k) mca_frzh(i,j,k) = 0. endif else - sumneg = sumneg + mca_frzh(i,j,k) + sumneg(i,j) = sumneg(i,j) + mca_frzh(i,j,k) mca_frzh(i,j,k) = 0. endif end do @@ -3173,49 +3396,64 @@ subroutine moist_processes (is, ie, js, je, Time, dt, land, & do j=1, size(t,2) do i=1, size(t,1) if (donner_meso_is_largescale) then - fl_lsrain(i,j,k) = & - 0.5*(rain3d(i,j,k) + rain3d(i,j,k+1) + & - liq_mesoh(i+is-1,j+js-1,k) + & - liq_mesoh(i+is-1,j+js-1,k+1)) - fl_lssnow(i,j,k) = & - 0.5*(snowclr3d(i,j,k) + snowclr3d(i,j,k+1) + & - frz_mesoh(i+is-1,j+js-1,k) + & - frz_mesoh(i+is-1,j+js-1,k+1)) - fl_ccrain(i,j,k) = & - 0.5*(liq_cellh(i+is-1,j+js-1,k) + & - liq_cellh(i+is-1,j+js-1,k+1) + & - liq_precflxh(i+is-1,j+js-1,k) + & - liq_precflxh(i+is-1,j+js-1,k+1)) - fl_ccsnow(i,j,k) = & - 0.5*(frz_cellh(i+is-1,j+js-1,k) + & - frz_cellh(i+is-1,j+js-1,k+1) + & - ice_precflxh(i+is-1,j+js-1,k) + & - ice_precflxh(i+is-1,j+js-1,k+1)) + fl_lsrain(i,j,k) = 0.5* & + ((strat_precip_in_cosp* & + (rain3d(i,j,k) + rain3d(i,j,k+1)) + & + donner_precip_in_cosp* & + (liq_mesoh(i+is-1,j+js-1,k) + & + liq_mesoh(i+is-1,j+js-1,k+1)))) + fl_lssnow(i,j,k) = 0.5* & + ((strat_precip_in_cosp* & + (snowclr3d(i,j,k) + snowclr3d(i,j,k+1)) + & + donner_precip_in_cosp* & + (frz_mesoh(i+is-1,j+js-1,k) + & + frz_mesoh(i+is-1,j+js-1,k+1)))) + fl_ccrain(i,j,k) = 0.5* & + ((donner_precip_in_cosp* & + (liq_cellh(i+is-1,j+js-1,k) + & + liq_cellh(i+is-1,j+js-1,k+1)) + & + uw_precip_in_cosp* & + (liq_precflxh(i+is-1,j+js-1,k) + & + liq_precflxh(i+is-1,j+js-1,k+1)))) + fl_ccsnow(i,j,k) = 0.5* & + ((donner_precip_in_cosp* & + (frz_cellh(i+is-1,j+js-1,k) + & + frz_cellh(i+is-1,j+js-1,k+1)) + & + uw_precip_in_cosp* & + (ice_precflxh(i+is-1,j+js-1,k) + & + ice_precflxh(i+is-1,j+js-1,k+1)))) else - fl_lsrain(i,j,k) = & - 0.5*(rain3d(i,j,k) + rain3d(i,j,k+1)) - fl_lssnow(i,j,k) = & - 0.5*(snowclr3d(i,j,k) + snowclr3d(i,j,k+1)) - fl_ccrain(i,j,k) = & - 0.5*(liq_mesoh(i+is-1,j+js-1,k) + & + fl_lsrain(i,j,k) = 0.5* & + strat_precip_in_cosp* & + (rain3d(i,j,k) + rain3d(i,j,k+1)) + fl_lssnow(i,j,k) = 0.5* & + strat_precip_in_cosp* & + (snowclr3d(i,j,k) + snowclr3d(i,j,k+1)) + fl_ccrain(i,j,k) = 0.5* & + ((donner_precip_in_cosp* & + (liq_mesoh(i+is-1,j+js-1,k) + & liq_mesoh(i+is-1,j+js-1,k+1) + & liq_cellh(i+is-1,j+js-1,k) + & - liq_cellh(i+is-1,j+js-1,k+1) + & - liq_precflxh(i+is-1,j+js-1,k) + & - liq_precflxh(i+is-1,j+js-1,k+1)) - fl_ccsnow(i,j,k) = & - 0.5*(frz_mesoh(i+is-1,j+js-1,k) + & + liq_cellh(i+is-1,j+js-1,k+1)) + & + uw_precip_in_cosp* & + (liq_precflxh(i+is-1,j+js-1,k) + & + liq_precflxh(i+is-1,j+js-1,k+1)))) + fl_ccsnow(i,j,k) = 0.5* & + ((donner_precip_in_cosp* & + (frz_mesoh(i+is-1,j+js-1,k) + & frz_mesoh(i+is-1,j+js-1,k+1) + & frz_cellh(i+is-1,j+js-1,k) + & - frz_cellh(i+is-1,j+js-1,k+1) + & - ice_precflxh(i+is-1,j+js-1,k) + & - ice_precflxh(i+is-1,j+js-1,k+1)) + frz_cellh(i+is-1,j+js-1,k+1)) + & + uw_precip_in_cosp* & + (ice_precflxh(i+is-1,j+js-1,k) + & + ice_precflxh(i+is-1,j+js-1,k+1)))) endif - if (include_donmca_in_cosp) then - fl_donmca_snow(i,j,k) = fl_donmca_snow(i,j,k) + 0.5* & + if (include_donmca_in_cosp .and. & + donner_precip_in_cosp .eq. 1.0) then + fl_donmca_snow(i,j,k) = 0.5* & (mca_frzh(i+is-1,j+js-1,k) + & mca_frzh(i+is-1,j+js-1,k+1)) - fl_donmca_rain(i,j,k) = fl_donmca_rain(i,j,k) + 0.5* & + fl_donmca_rain(i,j,k) = 0.5* & (mca_liqh(i+is-1,j+js-1,k) + & mca_liqh(i+is-1,j+js-1,k+1)) endif @@ -3239,6 +3477,9 @@ subroutine moist_processes_time_vary (dt) if (do_donner_deep) then call donner_deep_time_vary (dt) endif + if (do_strat .and. .not. do_legacy_strat_cloud) then + call strat_cloud_time_vary (dt, limit_conv_cloud_frac) + endif end subroutine moist_processes_time_vary @@ -3265,25 +3506,32 @@ end subroutine moist_processes_endts !################################################################### !####################################################################### - -subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & +!---> h1g +!subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & +subroutine moist_processes_init ( id, jd, kd, lonb, latb, lon, lat, phalf, pref, & axes, Time, doing_donner, & doing_uw_conv, num_uw_tracers_out,& - do_strat_out, do_cosp_in, & + do_strat_out, & + do_clubb_in, & ! cjg + do_cosp_in, & ! doing_uw_conv, & ! do_cosp_in, & donner_meso_is_largescale_in, & include_donmca_in_cosp_out) +!<--- h1g !----------------------------------------------------------------------- integer, intent(in) :: id, jd, kd, axes(4) real, dimension(:,:), intent(in) :: lonb, latb +real,dimension(:,:), intent(in) :: lon, lat ! h1g +real,dimension(:,:,:),intent(in) :: phalf ! h1g real, dimension(:), intent(in) :: pref type(time_type), intent(in) :: Time logical, intent(out) :: doing_donner, doing_uw_conv, & do_strat_out !logical, intent(out) :: doing_donner, doing_uw_conv integer, intent(out) :: num_uw_tracers_out +integer, intent(in), optional :: do_clubb_in ! cjg logical, intent(in), optional :: & do_cosp_in, & donner_meso_is_largescale_in @@ -3309,6 +3557,14 @@ subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & if ( module_is_initialized ) return +!-->cjg + if (present(do_clubb_in)) then + do_clubb = do_clubb_in + else + do_clubb = 0 + endif +!<--cjg + if (present(do_cosp_in)) then do_cosp = do_cosp_in else @@ -3354,12 +3610,6 @@ subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & &selected', FATAL) endif - if ( do_cosp .and. .not. (do_donner_deep .and. & - do_strat .and. do_uw_conv)) & - call error_mesg ('moist_processes_init', & - 'must activate do_donner_deep, do_strat and do_uw_conv & - &when do_cosp is true', FATAL) - if (include_donmca_in_cosp .and. (.not. do_donner_mca) ) & call error_mesg ('moist_processes_init', & 'want to include donmca in COSP when donmca is inactive', & @@ -3451,6 +3701,13 @@ subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & &do_donner_before_uw must be .true.', FATAL) endif + if (do_cosp .and. .not. do_donner_conservation_checks) then + do_donner_conservation_checks = .true. + call error_mesg ('moist_processes', & + 'setting do_donner_conservation_checks to true so that & + &needed fields for COSP are produced.', NOTE) + endif + !RSH endif !--------------------------------------------------------------------- @@ -3487,8 +3744,22 @@ subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & if (do_rh_clouds) call rh_clouds_init (id,jd,kd) if (do_diag_clouds) call diag_cloud_init (id,jd,kd,ierr) endif - if (do_strat) call strat_cloud_init (axes, Time, id, jd, kd, & + +! ---> h1g, cjg + if (do_strat) then + if (do_clubb > 0) then +! --->h1g, if CLUBB is in moist-processes, CLUBB is initialized here. + if( do_clubb == 2) then + call clubb_init( id, jd, kd, lon, lat, & + axes, Time, phalf ) + endif +! <---h1g, if CLUBB is in moist-processes, CLUBB is initialized here. + call MG_microp_3D_init(axes,Time,id,jd,kd) + end if + call strat_cloud_init (axes, Time, id, jd, kd, & do_legacy_strat_cloud = do_legacy_strat_cloud) + end if +! <--- h1g, cjg if (do_dryadj) call dry_adj_init () if (do_cmt) call cu_mo_trans_init (axes,Time, doing_diffusive) if (do_bm) call betts_miller_init () @@ -3879,15 +4150,34 @@ subroutine moist_processes_init ( id, jd, kd, lonb, latb, pref, & end subroutine moist_processes_init !####################################################################### - -subroutine moist_processes_end +!---> h1g +!subroutine moist_processes_end +subroutine moist_processes_end( clubb_term_clock ) +integer, intent (out), optional :: clubb_term_clock +!<--- h1g if( .not.module_is_initialized ) return !----------------close various schemes----------------- - if (do_strat) call strat_cloud_end +! ---> h1g, cjg + if (do_strat) then + if (do_clubb > 0) then +! ---> h1g, if CLUBB is in moist-process, CLUBB ends here + if( do_clubb == 2) then + call mpp_clock_begin ( clubb_term_clock ) + call clubb_end + call mpp_clock_end ( clubb_term_clock ) + endif +! <--- h1g, if CLUBB is in moist-process, CLUBB ends here + call MG_microp_3D_end + else + call strat_cloud_end + end if + end if +! <--- h1g, cjg + call detr_ice_num_end if (do_rh_clouds) call rh_clouds_end if (do_diag_clouds) call diag_cloud_end @@ -4167,6 +4457,10 @@ subroutine diag_field_init ( axes, Time, num_tracers, num_donner_tracers ) 'lscale_snow3d', axes(half), Time, & 'Snow fall rate from lscale -3D', 'kg(h2o)/m2/s' ) + id_lscale_precip3d= register_diag_field ( mod_name, & + 'lscale_precip3d', axes(1:3), Time, & + 'LS Precip falling out of gridbox', 'kg(h2o)/m2/s' , & + mask_variant = .true., missing_value = missing_value) id_max_enthalpy_imbal = register_diag_field & (mod_name, 'max_enth_imbal', axes(1:2), Time, & @@ -4627,6 +4921,24 @@ subroutine diag_field_init ( axes, Time, num_tracers, num_donner_tracers ) 'Upward Cell Mass Flux from donner', 'kg/m2/s', & missing_value=missing_value ) +! ---> h1g, cell and meso-scale cloud fraction from donner deep, 2011-08-08 + id_cell_cld_frac = register_diag_field ( mod_name, & + 'cell_cld_frac', axes(1:3), Time, & + 'cell cloud fraction from donner', '', & + missing_value=missing_value ) + + id_meso_cld_frac = register_diag_field ( mod_name, & + 'meso_cld_frac', axes(1:3), Time, & + 'meso-scale cloud fraction from donner', '', & + missing_value=missing_value ) + + id_donner_humidity_area = register_diag_field ( mod_name, & + 'donner_humidity_area', axes(1:3), Time, & + 'donner humidity area', '', & + missing_value=missing_value ) +! <--- h1g, cell and meso-scale cloud fraction from donner deep, 2011-08-08 + + endif @@ -4687,6 +4999,18 @@ subroutine diag_field_init ( axes, Time, num_tracers, num_donner_tracers ) 'qiout', axes(1:3), Time, 'qi after strat_cloud', 'kg/kg', & missing_value=missing_value ) + if (do_liq_num) then + id_qnout = register_diag_field ( mod_name, & + 'qnout', axes(1:3), Time, 'qn after strat_cloud', '#/kg', & + missing_value=missing_value ) + endif + + if (do_ice_num) then + id_qniout = register_diag_field ( mod_name, & + 'qniout', axes(1:3), Time, 'qni after strat_cloud', '#/kg', & + missing_value=missing_value ) + endif + !--------------------------------------------------------------------- ! register diagnostics for lightning NOx !--------------------------------------------------------------------- @@ -4792,10 +5116,28 @@ subroutine diag_field_init ( axes, Time, num_tracers, num_donner_tracers ) register_diag_field ( mod_name, & 'f_snow_berg', & axes(1:3), Time, & - 'fraction of liq to ice by bergeron process', & + 'fraction of snow/ice produced having IFN', & 'fraction', & missing_value=missing_value) + id_f_snow_berg_cond = & + register_diag_field ( mod_name, & + 'f_snow_berg_cond', & + axes(1:3), Time, & + 'conditional fraction of snow/ice produced & + &having IFN', 'fraction', & + mask_variant = .true., & + missing_value=missing_value) + + id_f_snow_berg_wtd = & + register_diag_field ( mod_name, & + 'f_snow_berg_wtd', & + axes(1:3), Time, & + 'product of snow/ice produced having IFN and & + &ls precip falling out of gridbox', & + 'kg(h2o)/m2/s', mask_variant = .true., & + missing_value=missing_value) + do n = 1,num_tracers call get_tracer_names (MODEL_ATMOS, n, name = tracer_name, & units = tracer_units) @@ -4906,6 +5248,44 @@ end function doing_strat !####################################################################### +subroutine set_cosp_precip_sources (cosp_precip_sources) + +character(len=16), intent(in) :: cosp_precip_sources + + if (trim(cosp_precip_sources) == 'stratdeepuw') then + strat_precip_in_cosp = 1. + donner_precip_in_cosp = 1. + uw_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'stratdeep') then + strat_precip_in_cosp = 1. + donner_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'stratuw') then + strat_precip_in_cosp = 1. + uw_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'deepuw') then + donner_precip_in_cosp = 1. + uw_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'strat') then + strat_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'deep') then + donner_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'uw') then + uw_precip_in_cosp = 1. + else if (trim(cosp_precip_sources) == 'noprecip') then +! COSP run without any precip input + else + call error_mesg ('moist_processes_mod:set_cosp_precip_sources', & + 'cosp_precip_sources does not match any currently allowed string',& + FATAL) + endif + +end subroutine set_cosp_precip_sources + + +!####################################################################### + + + end module moist_processes_mod diff --git a/src/atmos_param/moist_processes/moist_processes_utils.F90 b/src/atmos_param/moist_processes/moist_processes_utils.F90 index e2fabfa2bf..91e251b579 100644 --- a/src/atmos_param/moist_processes/moist_processes_utils.F90 +++ b/src/atmos_param/moist_processes/moist_processes_utils.F90 @@ -39,7 +39,7 @@ module moist_proc_utils_mod !--------------------- version number ---------------------------------- character(len=128) :: & version = '$Id: moist_processes_utils.F90,v 19.0 2012/01/06 20:10:44 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- diff --git a/src/atmos_param/moist_processes/moistproc_kernels.F90 b/src/atmos_param/moist_processes/moistproc_kernels.F90 index b2a56eca92..f87b8800f8 100644 --- a/src/atmos_param/moist_processes/moistproc_kernels.F90 +++ b/src/atmos_param/moist_processes/moistproc_kernels.F90 @@ -28,6 +28,11 @@ module moistproc_kernels_mod use moist_proc_utils_mod, only: rh_calc use detr_ice_num_mod , only: detr_ice_num +!--->h1g +use mpp_mod, only: mpp_chksum, mpp_pe, mpp_root_pe +use MG_microp_3D_mod, only: MG_microp_3D +! <--- h1g + implicit none private public moistproc_init, moistproc_end, moistproc_mca, moistproc_ras, & @@ -37,8 +42,8 @@ module moistproc_kernels_mod !--------------------- version number ---------------------------------- character(len=128) :: & -version = '$Id: moistproc_kernels.F90,v 19.0 2012/01/06 20:10:46 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +version = '$Id: moistproc_kernels.F90,v 20.0 2013/12/13 23:18:29 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- real, public, allocatable, dimension(:,:) :: rain_uw, snow_uw @@ -490,7 +495,7 @@ end subroutine moistproc_ras !####################################################################### -subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, tracer,& +subroutine moistproc_strat_cloud(Time, is, ie, js, je, lon, lat, ktop, dt, tm, t, q, tracer,& ! cjg pfull, phalf, zhalf, omega, radturbten, mc_full, & diff_t, land, area, tdt, qdt, rdt, q_tnd, ttnd, & qtnd, lprec, fprec, f_snow_berg, rain, & @@ -501,21 +506,30 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace donner_humidity_factor, shallow_cloud_area, & cell_cld_frac, meso_cld_frac, & do_uw_conv, do_donner_deep, do_liq_num, & + do_clubb, & ! cjg do_lin_cld_microphys, id_qvout, id_qlout, & - id_qaout, id_qiout, limit_conv_cloud_frac, mask, & + id_qaout, id_qiout, id_qnout, id_qniout, & + limit_conv_cloud_frac, mask, & hydrostatic, phys_hydrostatic, & zfull, do_ice_num, lsc_ice_number, & lsc_snow, lsc_rain, lsc_snow_size, & - lsc_rain_size, do_legacy_strat_cloud ) + lsc_rain_size, do_legacy_strat_cloud, & +! ---> h1g + dcond_ls_liquid, dcond_ls_ice, & + Ndrop_act_CLUBB, Icedrop_act_CLUBB, & + ndust, rbar_dust, qcvar_clubb ) +! <--- h1g type(time_type), intent(in) :: Time integer, intent(in) :: is, ie, js, je, ktop, id_qvout, id_qlout, & - id_qaout, id_qiout + id_qaout, id_qiout, id_qnout, id_qniout + real, intent(in), dimension(:,:) :: lon, lat real, intent(in) :: dt logical, intent(in) :: do_uw_conv, do_donner_deep, do_liq_num, & do_lin_cld_microphys, & limit_conv_cloud_frac, & do_ice_num, do_legacy_strat_cloud + integer, intent(in) :: do_clubb ! cjg real, intent(in), dimension(:,:) :: land, area real, intent(in), dimension(:,:,:) :: tm, pfull, phalf, zhalf, omega, & radturbten, mc_full, diff_t, & @@ -530,6 +544,12 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace rain3d, snow3d, snowclr3d, lsc_cloud_area, lsc_liquid, & lsc_ice, lsc_droplet_number, lsc_ice_number, lsc_snow, & lsc_rain, lsc_snow_size, lsc_rain_size +! ---> h1g + real, intent(in) , dimension(:,:,:), optional :: dcond_ls_liquid, dcond_ls_ice + real, intent(in) , dimension(:,:,:), optional :: Ndrop_act_CLUBB, Icedrop_act_CLUBB + real, intent(in) , dimension(:,:,:), optional :: ndust, rbar_dust + real, intent(in) , dimension(:,:,:), optional :: qcvar_clubb +! <--- h1g type(aerosol_type),intent(in), optional :: Aerosol logical, intent(in), optional :: hydrostatic, phys_hydrostatic @@ -626,9 +646,27 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace nqa = get_tracer_index ( MODEL_ATMOS, 'cld_amt' ) nqn = get_tracer_index ( MODEL_ATMOS, 'liq_drp' ) nqni = get_tracer_index ( MODEL_ATMOS, 'ice_num' ) - if (do_liq_num) then - if ( do_legacy_strat_cloud ) then - call strat_cloud (Time, is, ie, js, je, dt, pfull, phalf, & + if ( .not. do_lin_cld_microphys ) then + if (do_clubb > 0 .and. do_liq_num) then + call MG_microp_3D( Time, is, ie, js, je, lon, lat, dt, & + pfull, phalf, zhalf, land, & + t, q, tracer(:,:,:,nql), tracer(:,:,:,nqi), tracer(:,:,:,nqa), & + tracer(:,:,:,nqn), tracer(:,:,:,nqni), convective_humidity_area, & + dcond_ls_liquid, dcond_ls_ice, & + Ndrop_act_CLUBB, Icedrop_act_CLUBB, & + ndust, rbar_dust, & + ttnd, qtnd, q_tnd(:,:,:,nql), q_tnd(:,:,:,nqi), q_tnd(:,:,:,nqa), & + q_tnd(:,:,:,nqn), q_tnd(:,:,:,nqni), & + rain3d, snow3d, rain, snow, & + do_clubb=do_clubb, qcvar_clubb = qcvar_clubb, & + MASK3d=mask, & + lsc_snow = lsc_snow, & + lsc_rain = lsc_rain, & + lsc_snow_size = lsc_snow_size, & + lsc_rain_size = lsc_rain_size ) + elseif ( do_legacy_strat_cloud ) then + if (do_liq_num) then + call strat_cloud (Time, is, ie, js, je, dt, pfull, phalf, & radturbten, t, q, tracer(:,:,:,nql), & tracer(:,:,:,nqi), tracer(:,:,:,nqa), & omega, mc_full, diff_t, land, ttnd, qtnd, & @@ -640,7 +678,19 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace limit_conv_cloud_frac, mask=mask, & qn=tracer(:,:,:,nqn), Aerosol=Aerosol, & SN=q_tnd(:,:,:,nqn)) - else + else + call strat_cloud (Time, is, ie, js, je, dt, pfull, phalf, & + radturbten, t, q, tracer(:,:,:,nql), & + tracer(:,:,:,nqi), tracer(:,:,:,nqa), & + omega, mc_full, diff_t, land, ttnd, qtnd, & + q_tnd(:,:,:,nql), q_tnd(:,:,:,nqi), & + q_tnd(:,:,:,nqa), f_snow_berg, & + rain3d, snow3d, snowclr3d, & + rain, snow, convective_humidity_ratio, & + convective_humidity_area, & + limit_conv_cloud_frac, mask=mask) + endif ! do_liq_num + else ! do_legacy_strat_cloud if (do_ice_num) then call strat_cloud_new (Time, is, ie, js, je, dt, pfull, phalf, & zhalf, zfull, radturbten, t, q, & @@ -663,7 +713,8 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace lsc_snow_size = lsc_snow_size, & lsc_rain_size = lsc_rain_size ) else - call strat_cloud_new (Time, is, ie, js, je, dt, pfull, phalf, & + if (do_liq_num) then + call strat_cloud_new (Time, is, ie, js, je, dt, pfull, phalf, & zhalf, zfull, radturbten, t, q, & tracer(:,:,:,nql), tracer(:,:,:,nqi), & tracer(:,:,:,nqa), omega, mc_full, & @@ -681,8 +732,27 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace lsc_rain = lsc_rain, & lsc_snow_size = lsc_snow_size, & lsc_rain_size = lsc_rain_size ) - end if - end if + else + call strat_cloud_new (Time, is, ie, js, je, dt, pfull, phalf, & + zhalf, zfull, radturbten, t, q, & + tracer(:,:,:,nql), tracer(:,:,:,nqi), & + tracer(:,:,:,nqa), omega, mc_full, & + diff_t, land, ttnd, qtnd, & + q_tnd(:,:,:,nql), q_tnd(:,:,:,nqi), & + q_tnd(:,:,:,nqa), f_snow_berg, & + rain3d, snow3d, & + snowclr3d,rain, snow, & + convective_humidity_ratio, & + convective_humidity_area,& + limit_conv_cloud_frac, Aerosol, & + mask3d=mask, & + lsc_snow = lsc_snow, & + lsc_rain = lsc_rain, & + lsc_snow_size = lsc_snow_size, & + lsc_rain_size = lsc_rain_size ) + end if ! do_ice_num + end if ! do_liq_num + end if ! do_legacy_strat_cloud else if ( do_lin_cld_microphys ) then nqr = get_tracer_index (MODEL_ATMOS, 'rainwat') nqs = get_tracer_index (MODEL_ATMOS, 'snowwat') @@ -721,18 +791,7 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace tracer(:,:,:,nqr) = tracer(:,:,:,nqr) + q_tnd(:,:,:,nqr)*dt tracer(:,:,:,nqs) = tracer(:,:,:,nqs) + q_tnd(:,:,:,nqs)*dt tracer(:,:,:,nqg) = tracer(:,:,:,nqg) + q_tnd(:,:,:,nqg)*dt - else - call strat_cloud (Time, is, ie, js, je, dt, pfull, phalf, & - radturbten, t, q, tracer(:,:,:,nql), & - tracer(:,:,:,nqi), tracer(:,:,:,nqa), & - omega, mc_full, diff_t, land, ttnd, qtnd, & - q_tnd(:,:,:,nql), q_tnd(:,:,:,nqi), & - q_tnd(:,:,:,nqa), f_snow_berg, & - rain3d, snow3d, snowclr3d, & - rain, snow, convective_humidity_ratio, & - convective_humidity_area, & - limit_conv_cloud_frac, mask=mask) - endif + endif ! not do_lin_cld_microphys !---------------------------------------------------------------------- ! upon return from strat_cloud, update the cloud liquid, ice and area. @@ -760,6 +819,12 @@ subroutine moistproc_strat_cloud(Time, is, ie, js, je, ktop, dt, tm, t, q, trace used = send_data (id_qaout, tracer(:,:,:,nqa), Time, is, js, 1, rmask=mask) used = send_data (id_qlout, tracer(:,:,:,nql), Time, is, js, 1, rmask=mask) used = send_data (id_qiout, tracer(:,:,:,nqi), Time, is, js, 1, rmask=mask) + if (do_liq_num) then + used = send_data (id_qnout, tracer(:,:,:,nqn), Time, is, js, 1, rmask=mask) + endif + if (do_ice_num) then + used = send_data (id_qniout, tracer(:,:,:,nqni), Time, is, js, 1, rmask=mask) + endif !---------------------------------------------------------------------- ! call strat_cloud_sum to make the cloud variables available for diff --git a/src/atmos_param/monin_obukhov/monin_obukhov.F90 b/src/atmos_param/monin_obukhov/monin_obukhov.F90 index 87a26edecd..06f22fd496 100644 --- a/src/atmos_param/monin_obukhov/monin_obukhov.F90 +++ b/src/atmos_param/monin_obukhov/monin_obukhov.F90 @@ -59,7 +59,7 @@ module monin_obukhov_mod !--------------------- version number --------------------------------- character(len=128) :: version = '$Id: monin_obukhov.F90,v 19.0 2012/01/06 20:10:48 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !======================================================================= @@ -859,19 +859,14 @@ subroutine mo_diff_0d_1(z, u_star, b_star, k_m, k_h) integer :: ni, nj, nk, ier real, parameter :: ustar_min = 1.e-10 -real, dimension(1,1) :: u_star1, b_star1 -real, dimension(1,1,1) :: z1, k_m1, k_h1 if(.not.module_is_initialized) call monin_obukhov_init ni = 1; nj = 1; nk = 1 -z1 = z; u_star1 = u_star; b_star1 = b_star call monin_obukhov_diff(vonkarm, & & ustar_min, & & neutral, stable_option, rich_crit, zeta_trans, & - & ni, nj, nk, z1, u_star1, b_star1, k_m1, k_h1, ier) - -k_m = k_m1(1,1,1); k_h = k_h1(1,1,1) + & ni, nj, nk, z, u_star, b_star, k_m, k_h, ier) end subroutine mo_diff_0d_1 @@ -885,16 +880,14 @@ subroutine mo_diff_0d_n(z, u_star, b_star, k_m, k_h) integer :: ni, nj, nk, ier real, parameter :: ustar_min = 1.e-10 -real, dimension(1,1) :: u_star1, b_star1 if(.not.module_is_initialized) call monin_obukhov_init ni = 1; nj = 1; nk = size(z(:)) -u_star1 = u_star; b_star1 = b_star call monin_obukhov_diff(vonkarm, & & ustar_min, & & neutral, stable_option, rich_crit, zeta_trans, & - & ni, nj, nk, z, u_star1, b_star1, k_m, k_h, ier) + & ni, nj, nk, z, u_star, b_star, k_m, k_h, ier) end subroutine mo_diff_0d_n diff --git a/src/atmos_param/my25_turb/my25_turb.F90 b/src/atmos_param/my25_turb/my25_turb.F90 index cbe3de1e9b..de8a83137f 100644 --- a/src/atmos_param/my25_turb/my25_turb.F90 +++ b/src/atmos_param/my25_turb/my25_turb.F90 @@ -32,7 +32,7 @@ MODULE MY25_TURB_MOD !--------------------------------------------------------------------- character(len=128) :: version = '$Id: my25_turb.F90,v 19.0 2012/01/06 20:10:51 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. logical :: init_tke diff --git a/src/atmos_param/my25_turb/null/my25_turb.F90 b/src/atmos_param/my25_turb/null/my25_turb.F90 deleted file mode 100644 index 5245d9b1b7..0000000000 --- a/src/atmos_param/my25_turb/null/my25_turb.F90 +++ /dev/null @@ -1,159 +0,0 @@ - MODULE MY25_TURB_MOD - -!======================================================================= -! MELLOR-YAMADA LEVEL 2.5 TURBULENCE CLOSURE SCHEME - GFDL VERSION ! -!======================================================================= - - use Fms_Mod, ONLY: ERROR_MESG, FATAL, mpp_pe, mpp_root_pe, write_version_number - -!--------------------------------------------------------------------- - implicit none - private -!--------------------------------------------------------------------- - - public :: MY25_TURB, MY25_TURB_INIT, MY25_TURB_END, TKE_SURF, get_tke - public :: my25_turb_restart - -!--------------------------------------------------------------------- - - character(len=128) :: version = '$Id: my25_turb.F90,v 17.0 2009/07/21 02:55:45 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - contains - -!####################################################################### - - SUBROUTINE MY25_TURB( is, js, delt, fracland, phalf, pfull, theta, & - um, vm, zhalf, zfull, z0, & - el0, el, akm, akh, & - mask, kbot, ustar, bstar, h ) - -!======================================================================= -!--------------------------------------------------------------------- -! Arguments (Intent in) -! delt - Time step in seconds -! fracland - Fractional amount of land beneath a grid box -! phalf - Pressure at half levels -! pfull - Pressure at full levels -! theta - Potential temperature -! um, vm - Wind components -! zhalf - Height at half levels -! zfull - Height at full levels -! z0 - Roughness length -! mask - OPTIONAL; floating point mask (0. or 1.) designating -! where data is present -! kbot - OPTIONAL;lowest model level index (integer); -! at levels > kbot, mask = 0. -! ustar - OPTIONAL:friction velocity (m/sec) -! bstar - OPTIONAL:buoyancy scale (m/sec**2) -!--------------------------------------------------------------------- - integer, intent(in) :: is, js - real, intent(in) :: delt - real, intent(in), dimension(:,:) :: fracland, z0 - real, intent(in), dimension(:,:,:) :: phalf, pfull, zhalf, zfull - real, intent(in), dimension(:,:,:) :: um, vm, theta - - integer, intent(in), OPTIONAL, dimension(:,:) :: kbot - real, intent(in), OPTIONAL, dimension(:,:,:) :: mask - real, intent(in), OPTIONAL, dimension(:,:) :: ustar, bstar - -!--------------------------------------------------------------------- -! Arguments (Intent out) -! el0 - characteristic length scale -! el - master length scale -! akm - mixing coefficient for momentum -! akh - mixing coefficient for heat and moisture -! h - OPTIONAL, diagnosed depth of planetary boundary -! layer (m) -!--------------------------------------------------------------------- - real, intent(out), dimension(:,:) :: el0 - real, intent(out), dimension(:,:,:) :: akm, akh, el - real, intent(out), OPTIONAL, dimension(:,:) :: h - -call error_mesg('MY25_TURB', & - 'This module is not supported as part of the public release', FATAL) - -!==================================================================== - end SUBROUTINE MY25_TURB - -!####################################################################### -subroutine get_tke(is, ie, js, je, tke_out) -integer, intent(in) :: is, ie, js, je -real, intent(out), dimension(:,:,:) :: tke_out - -call error_mesg('get_tke', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine get_tke -!####################################################################### - - SUBROUTINE MY25_TURB_INIT( ix, jx, kx ) - -!======================================================================= -! ***** INITIALIZE MELLOR-YAMADA -!======================================================================= -!--------------------------------------------------------------------- -! Arguments (Intent in) -! ix, jx - Horizontal dimensions for global storage arrays -! kx - Number of vertical levels in model -!--------------------------------------------------------------------- - integer, intent(in) :: ix, jx, kx - - call error_mesg('MY25_TURB_INIT', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE MY25_TURB_INIT - -!####################################################################### - - SUBROUTINE MY25_TURB_END -!======================================================================= - - call error_mesg('MY25_TURB_END', & - 'This module is not supported as part of the public release', FATAL) - -!===================================================================== - - end SUBROUTINE MY25_TURB_END - -!####################################################################### - - SUBROUTINE TKE_SURF ( is, js, u_star, kbot ) - -!======================================================================= -!--------------------------------------------------------------------- -! Arguments (Intent in) -! u_star - surface friction velocity (m/s) -! kbot - OPTIONAL;lowest model level index (integer); -! at levels > Kbot, Mask = 0. -!--------------------------------------------------------------------- - integer, intent(in) :: is, js - real, intent(in), dimension(:,:) :: u_star - - integer, intent(in), OPTIONAL, dimension(:,:) :: kbot - - call error_mesg('TKE_SURF', & - 'This module is not supported as part of the public release', FATAL) - -!======================================================================= - end SUBROUTINE TKE_SURF - -!####################################################################### -! -! -! NAME="my25_turb_restart" - -!####################################################################### - end MODULE MY25_TURB_MOD diff --git a/src/atmos_param/physics_driver/physics_driver.F90 b/src/atmos_param/physics_driver/physics_driver.F90 index 243a4d5c30..d484f18a1a 100644 --- a/src/atmos_param/physics_driver/physics_driver.F90 +++ b/src/atmos_param/physics_driver/physics_driver.F90 @@ -90,9 +90,11 @@ module physics_driver_mod ! component modules: use cosp_driver_mod, only: cosp_driver_init, cosp_driver, & - cosp_driver_end + cosp_driver_end, cosp_driver_time_vary,& + cosp_driver_endts use moist_processes_mod, only: moist_processes, & moist_processes_init, & + set_cosp_precip_sources, & moist_processes_time_vary, & moist_processes_endts, & moist_processes_end, & @@ -152,6 +154,10 @@ module physics_driver_mod use grey_radiation_mod, only: grey_radiation_init, grey_radiation, & grey_radiation_end +!--> h1g, cjg +use clubb_driver_mod, only: clubb_init, clubb, clubb_end +!<-- h1g, cjg + #ifdef SCM ! Option to add SCM radiative tendencies from forcing to lw_tendency ! and radturbten @@ -175,8 +181,8 @@ module physics_driver_mod !--------------------------------------------------------------------- !----------- version number for this module ------------------- -character(len=128) :: version = '$Id: physics_driver.F90,v 19.0 2012/01/06 20:11:24 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: physics_driver.F90,v 20.0 2013/12/13 23:18:40 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -210,6 +216,7 @@ module physics_driver_mod ! call moist_processes routines real :: tau_diff = 3600. ! time scale for smoothing diffusion ! coefficients +integer :: do_clubb = 0 ! activate clubb parameterization ? logical :: do_cosp = .false. ! activate COSP simulator ? logical :: do_modis_yim = .true. ! activate simple modis simulator ? logical :: do_radiation = .true. @@ -252,6 +259,22 @@ module physics_driver_mod logical :: override_aerosols_cloud = .false. ! use offline aerosols for cloud calculation ! (via data_override in aerosol_driver)? +character(len=16) :: cosp_precip_sources = ' ' + ! sources of the precip fields to be sent to + ! COSP. Default = ' ' implies precip from + ! the radiatively-active clouds defined by + ! variable cloud_type_form in cloud_spec_nml + ! will be sent. Other available choices: + ! 'strat', 'deep', 'uw', 'stratdeep', + ! 'stratuw', deepuw', 'stratdeepuw', + ! 'noprecip'. + ! CURRENTLY NOT AVAILABLE: precip from ras, + ! lsc and mca. For completeness, these could + ! be made available, but since no cloud + ! fields are saved for these schemes to be + ! made available to COSP, they are also + ! currently not considered as precip + ! sources. !-! dummy interface -! Arguments: -! timestamp (optional, intent(in)) : A character string that represents the model time, -! used for writing restart. timestamp will append to -! the any restart file name as a prefix. -! -! -subroutine my25_turb_restart(timestamp) - character(len=*), intent(in), optional :: timestamp - -end subroutine my25_turb_restart -!! @@ -284,7 +307,14 @@ module physics_driver_mod ! ! ! + +! ---> h1g, 2012-08-28, add option of applying surface fluxes in host-model +! by default .true. (that is, applying surface fluxes in host-model) +logical :: l_host_applies_sfc_fluxes = .true. +! <--- h1g, 2012-08-28 + namelist / physics_driver_nml / do_radiation, & + do_clubb, & ! cjg, h1g do_cosp, & do_modis_yim, & donner_meso_is_largescale, & @@ -294,7 +324,9 @@ module physics_driver_mod use_cloud_tracers_in_radiation, & do_grey_radiation, R1, R2, R3, R4, & override_aerosols_radiation, & - override_aerosols_cloud + override_aerosols_cloud, & + cosp_precip_sources, & + l_host_applies_sfc_fluxes !--------------------------------------------------------------------- !------- public data ------ @@ -414,6 +446,13 @@ module physics_driver_mod real, dimension(:,:), allocatable :: daytime integer, dimension(:,:) , allocatable :: nsum_out real , dimension(:,:) , allocatable :: tsurf_save + +! --->h1g +real, dimension(:,:,:), allocatable :: dcond_ls_liquid, dcond_ls_ice +real, dimension(:,:,:), allocatable :: Ndrop_act_CLUBB, Icedrop_act_CLUBB +real, dimension(:,:,:), allocatable :: ndust, rbar_dust +real, dimension(:,:,:), allocatable :: diff_t_clubb +! <---h1g !--- for netcdf restart type(restart_file_type), pointer, save :: Phy_restart => NULL() @@ -469,13 +508,15 @@ module physics_driver_mod logical :: step_to_call_cosp = .false. logical :: include_donmca_in_cosp -integer :: id_tdt_phys, id_qdt_phys, & +!integer :: id_tdt_phys, id_qdt_phys, & ! cjg +integer :: id_tdt_phys, & id_tdt_phys_vdif_dn, & id_tdt_phys_vdif_up, & id_tdt_phys_turb, & id_tdt_phys_moist -integer, dimension(:), allocatable :: id_tracer_phys_vdif_dn, & +integer, dimension(:), allocatable :: id_tracer_phys, & ! cjg + id_tracer_phys_vdif_dn, & id_tracer_phys_vdif_up, & id_tracer_phys_turb, & id_tracer_phys_moist @@ -540,16 +581,19 @@ module physics_driver_mod ! !-! fil -! -!-! -! -!-! -! uw shallow convection cloud radiative properties module -! -! -!-! -! -! - -use time_manager_mod, only: time_type -use fms_mod, only: error_mesg, FATAL, & - mpp_pe, mpp_root_pe, & - write_version_number -use rad_utilities_mod, only: microphysics_type - -!-------------------------------------------------------------------- - -implicit none -private - -!-------------------------------------------------------------------- -! uw shallow convection cloud radiative properties module -! -!-------------------------------------------------------------------- - - - -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: uw_clouds_W.F90,v 19.0 2012/01/06 20:25:22 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - - -!--------------------------------------------------------------------- -!------- interfaces -------- - -public & - uw_clouds_W_init, & - uw_clouds_W_end , uw_clouds_amt - -!--------------------------------------------------------------------- -!-------- namelist --------- - -logical :: dummy = .true. - - -namelist /uw_clouds_W_nml / & - dummy - - -!---------------------------------------------------------------------- -!---- public data ------- - - -!---------------------------------------------------------------------- -!---- private data ------- - - logical :: module_is_initialized = .false. -!---------------------------------------------------------------------- -!---------------------------------------------------------------------- - - - - -contains - - - - - -!-! -! -subroutine uw_clouds_W_init (pref, lonb, latb, axes, Time) - -real, dimension(:,:), intent(in) :: pref -real, dimension(:,:), intent(in) :: lonb, latb -integer, dimension(4), intent(in) :: axes -type(time_type), intent(in) :: Time - - integer :: unit, ierr, io - - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - - call error_mesg('uw_clouds_W_init', & - 'This module is not supported as part of the public release', FATAL) - - -end subroutine uw_clouds_W_init - -!-! -! -!-! -! -! -! call uw_clouds_W_init (pref, lonb, latb, axes, Time) -! -! -!-! -! -!-! -! -!-! -! -!-! -! -!-! -! -!-! -! -subroutine uw_clouds_W_end - -!---------------------------------------------------------------------- -! uw_clouds_W_end is the destructor for uw_clouds_W_mod. -!---------------------------------------------------------------------- - -!--------------------------------------------------------------------- -! mark the module as not initialized. -!--------------------------------------------------------------------- - module_is_initialized = .false. - -!-------------------------------------------------------------------- - - call error_mesg('uw_clouds_W_end', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine uw_clouds_W_end - - -!################################################################# - - -!--------------------------------------------------------------------- - -!-! -! -!-! -! -! -! call uw_clouds_W_end -! -!-! -! - -subroutine uw_clouds_amt (is, ie, js, je, & - shallow_cloud_area, shallow_liquid, shallow_ice, & - shallow_droplet_number, shallow_ice_number, land, & - pfull, tkel, Shallow_microphys) - -!--------------------------------------------------------------------- -! uw_clouds_amt defines the distribution of cloud water and cloud ice -! amounts [ g / m**3 ] and liquid and ice particle sizes and total cloud -! fraction for the clouds associated with uw shallow convection. these -! values will later be combined with other cloud fields to produce the -! cloud radiative properties that will be seen by the radiation package. -!---------------------------------------------------------------------- - -integer, intent(in) :: is,ie,js,je -real, dimension(:,:,:), intent(in) :: shallow_cloud_area, & - shallow_liquid, shallow_ice, & - shallow_droplet_number, & - shallow_ice_number -real, dimension(:,:), intent(in) :: land -real, dimension(:,:,:), intent(in) :: pfull, tkel -type(microphysics_type), intent(inout) :: Shallow_microphys - - call error_mesg('uw_clouds_amt', & - 'This module is not supported as part of the public release', FATAL) - -end subroutine uw_clouds_amt - - - -!#################################################################### - - - end module uw_clouds_W_mod - diff --git a/src/atmos_param/sea_esf_rad/optical_path.F90 b/src/atmos_param/sea_esf_rad/optical_path.F90 index 75d17aeafa..d2af37507c 100644 --- a/src/atmos_param/sea_esf_rad/optical_path.F90 +++ b/src/atmos_param/sea_esf_rad/optical_path.F90 @@ -65,7 +65,7 @@ module optical_path_mod character(len=128) :: & version = '$Id: optical_path.F90,v 19.0 2012/01/06 20:20:47 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/original_fms_rad.F90 b/src/atmos_param/sea_esf_rad/original_fms_rad.F90 index 14dc14cb82..19fa1a13d4 100644 --- a/src/atmos_param/sea_esf_rad/original_fms_rad.F90 +++ b/src/atmos_param/sea_esf_rad/original_fms_rad.F90 @@ -59,7 +59,7 @@ module original_fms_rad_mod !----------------------------------------------------------------------- !------------ version number for this module --------------------------- character(len=128) :: version = '$Id: original_fms_rad.F90,v 19.0 2012/01/06 20:20:49 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' ! ---- list of restart versions readable by this module ---- ! (sorry, but restart version 1 will not be readable by this module) diff --git a/src/atmos_param/sea_esf_rad/ozone.F90 b/src/atmos_param/sea_esf_rad/ozone.F90 index 206e4bfc5f..a803d92d20 100644 --- a/src/atmos_param/sea_esf_rad/ozone.F90 +++ b/src/atmos_param/sea_esf_rad/ozone.F90 @@ -66,7 +66,7 @@ module ozone_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: ozone.F90,v 19.0 2012/01/06 20:21:21 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/rad_output_file.F90 b/src/atmos_param/sea_esf_rad/rad_output_file.F90 index 44c3435121..2c5ac8b762 100644 --- a/src/atmos_param/sea_esf_rad/rad_output_file.F90 +++ b/src/atmos_param/sea_esf_rad/rad_output_file.F90 @@ -59,7 +59,7 @@ module rad_output_file_mod character(len=128) :: version = & '$Id: rad_output_file.F90,v 19.0 2012/01/06 20:21:53 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/rad_utilities.F90 b/src/atmos_param/sea_esf_rad/rad_utilities.F90 index ff1e3c0a16..3db718b7fa 100644 --- a/src/atmos_param/sea_esf_rad/rad_utilities.F90 +++ b/src/atmos_param/sea_esf_rad/rad_utilities.F90 @@ -43,8 +43,8 @@ module rad_utilities_mod !--------------------------------------------------------------------- !----------- ****** VERSION NUMBER ******* --------------------------- -character(len=128) :: version = '$Id: rad_utilities.F90,v 19.0 2012/01/06 20:21:55 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: rad_utilities.F90,v 20.0 2013/12/13 23:20:23 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- @@ -3450,7 +3450,6 @@ subroutine sw_output_type_eq(sw_output_out,sw_output_in) sw_output_out%ufsw_vis_sfc_dir = sw_output_in%ufsw_vis_sfc_dir sw_output_out%dfsw_vis_sfc_dir = sw_output_in%dfsw_vis_sfc_dir sw_output_out%dfsw_vis_sfc_dif = sw_output_in%dfsw_vis_sfc_dif - sw_output_out%dfsw_vis_sfc_clr = sw_output_in%dfsw_vis_sfc_clr sw_output_out%ufsw_vis_sfc_dif = sw_output_in%ufsw_vis_sfc_dif sw_output_out%swdn_special = sw_output_in%swdn_special sw_output_out%swup_special = sw_output_in%swup_special @@ -3462,6 +3461,7 @@ subroutine sw_output_type_eq(sw_output_out,sw_output_in) sw_output_out%hswcf = sw_output_in%hswcf sw_output_out%dfsw_dir_sfc_clr = sw_output_in%dfsw_dir_sfc_clr sw_output_out%dfsw_dif_sfc_clr = sw_output_in%dfsw_dif_sfc_clr + sw_output_out%dfsw_vis_sfc_clr = sw_output_in%dfsw_vis_sfc_clr sw_output_out%swdn_special_clr = sw_output_in%swdn_special_clr sw_output_out%swup_special_clr = sw_output_in%swup_special_clr sw_output_out%bdy_flx_clr = sw_output_in%bdy_flx_clr diff --git a/src/atmos_param/sea_esf_rad/radiation_diag.F90 b/src/atmos_param/sea_esf_rad/radiation_diag.F90 index 7b66ca9630..84e6380f13 100644 --- a/src/atmos_param/sea_esf_rad/radiation_diag.F90 +++ b/src/atmos_param/sea_esf_rad/radiation_diag.F90 @@ -53,7 +53,7 @@ module radiation_diag_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: radiation_diag.F90,v 19.0 2012/01/06 20:22:27 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/radiative_gases.F90 b/src/atmos_param/sea_esf_rad/radiative_gases.F90 index e7c5492495..e75081c98d 100644 --- a/src/atmos_param/sea_esf_rad/radiative_gases.F90 +++ b/src/atmos_param/sea_esf_rad/radiative_gases.F90 @@ -70,8 +70,8 @@ module radiative_gases_mod !----------- version number for this module -------------------------- character(len=128) :: version = & -'$Id: radiative_gases.F90,v 19.0 2012/01/06 20:22:59 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +'$Id: radiative_gases.F90,v 20.0 2013/12/13 23:20:28 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- @@ -3439,6 +3439,7 @@ subroutine read_gas_timeseries (gas, gas_value, Gas_time_list, & integer :: index1, index2 real :: percent_of_period type(time_type) :: Gas_entry + character(len=256) :: err_msg !------------------------------------------------------------------- ! define the gas_name which is currently being processed. @@ -3545,7 +3546,10 @@ subroutine read_gas_timeseries (gas, gas_value, Gas_time_list, & gas_dataset_entry(5), & gas_dataset_entry(6)) call time_interp (Gas_entry, Gas_time_list, & - percent_of_period, index1, index2) + percent_of_period, index1, index2, err_msg=err_msg) + if(err_msg /= '') then + call error_mesg('radiative_gases_mod ',trim(err_msg)//' file='//trim(file_name), FATAL) + endif rgas = gas_value(index1) + percent_of_period* & (gas_value(index2) - gas_value(index1)) call error_mesg ( 'radiative_gases_mod', & @@ -3763,6 +3767,7 @@ subroutine define_gas_amount & integer :: days7, seconds7 type(time_type) :: Tf_displ, First_of_month, Gas_tf_next, & Time_left + character(len=256) :: err_msg !--------------------------------------------------------------------- ! local variables: ! @@ -3872,7 +3877,10 @@ & subroutine define_gas_amount are not present', FATAL) else if (trim(gas_specification_type) == 'time_series') then call time_interp (Rad_time, Gas_time_list, & ! call time_interp (Gas_time, Gas_time_list, & - percent_of_period, index1, index2) + percent_of_period, index1, index2, err_msg=err_msg) + if(err_msg /= '') then + call error_mesg('radiative_gases_mod 1',trim(err_msg), FATAL) + endif rrvgas = gas_value(index1) + percent_of_period* & (gas_value(index2) - gas_value(index1)) endif @@ -3970,7 +3978,10 @@ & subroutine define_gas_amount are not present', FATAL) mean_days*3600.), 0) call time_interp (Rad_time - Tf_calc_intrvl, Gas_time_list, & ! call time_interp (Gas_time - Tf_calc_intrvl, Gas_time_list, & - percent_of_period, index1, index2) + percent_of_period, index1, index2, err_msg=err_msg) + if(err_msg /= '') then + call error_mesg('radiative_gases_mod 2',trim(err_msg), FATAL) + endif gas_for_last_tf_calc = gas_value(index1) + & percent_of_period* & (gas_value(index2) - & @@ -4074,12 +4085,13 @@ & subroutine define_gas_amount are not present', FATAL) Tf_offset = Time_left if (gas_tf_offset > 0) then call time_interp (Rad_time + Tf_offset, Gas_time_list,& - - - percent_of_period, index1, index2) + percent_of_period, index1, index2, err_msg=err_msg) else call time_interp (Rad_time - Tf_offset, Gas_time_list,& - percent_of_period, index1, index2) + percent_of_period, index1, index2, err_msg=err_msg) + endif + if(err_msg /= '') then + call error_mesg('radiative_gases_mod 3',trim(err_msg), FATAL) endif else days3 = NINT(gas_tf_offset/24.0) @@ -4087,7 +4099,10 @@ & subroutine define_gas_amount are not present', FATAL) seconds3 = NINT(rseconds3) Tf_offset = set_time (seconds3, days3) call time_interp (Rad_time + Tf_offset, Gas_time_list, & - percent_of_period, index1, index2) + percent_of_period, index1, index2,err_msg=err_msg) + if(err_msg /= '') then + call error_mesg('radiative_gases_mod 4',trim(err_msg), FATAL) + endif endif gas_for_next_tf_calc = gas_value(index1) + & percent_of_period* & diff --git a/src/atmos_param/sea_esf_rad/rh_based_clouds.F90 b/src/atmos_param/sea_esf_rad/rh_based_clouds.F90 index c17703106c..fef7bee0cd 100644 --- a/src/atmos_param/sea_esf_rad/rh_based_clouds.F90 +++ b/src/atmos_param/sea_esf_rad/rh_based_clouds.F90 @@ -47,7 +47,7 @@ module rh_based_clouds_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: rh_based_clouds.F90,v 19.0 2012/01/06 20:23:01 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/sea_esf_rad.F90 b/src/atmos_param/sea_esf_rad/sea_esf_rad.F90 index ccb1593f6e..bc690aa8b7 100644 --- a/src/atmos_param/sea_esf_rad/sea_esf_rad.F90 +++ b/src/atmos_param/sea_esf_rad/sea_esf_rad.F90 @@ -74,7 +74,7 @@ module sea_esf_rad_mod !------------ version number for this module --------------------------- character(len=128) :: version = '$Id: sea_esf_rad.F90,v 19.0 2012/01/06 20:23:33 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !-------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/sealw99.F90 b/src/atmos_param/sea_esf_rad/sealw99.F90 index 3ffb8fc423..36fcf67cb0 100644 --- a/src/atmos_param/sea_esf_rad/sealw99.F90 +++ b/src/atmos_param/sea_esf_rad/sealw99.F90 @@ -94,7 +94,7 @@ module sealw99_mod !----------- version number for this module ------------------- character(len=128) :: version = '$Id: sealw99.F90,v 19.0 2012/01/06 20:23:35 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/shortwave_driver.F90 b/src/atmos_param/sea_esf_rad/shortwave_driver.F90 index 7f448850ff..5f4a9fa705 100644 --- a/src/atmos_param/sea_esf_rad/shortwave_driver.F90 +++ b/src/atmos_param/sea_esf_rad/shortwave_driver.F90 @@ -62,7 +62,7 @@ module shortwave_driver_mod !----------- version number for this module ------------------------- character(len=128) :: version = '$Id: shortwave_driver.F90,v 19.0 2012/01/06 20:24:07 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/specified_clouds_W.F90 b/src/atmos_param/sea_esf_rad/specified_clouds_W.F90 index 2e917e1394..01e631bdfa 100644 --- a/src/atmos_param/sea_esf_rad/specified_clouds_W.F90 +++ b/src/atmos_param/sea_esf_rad/specified_clouds_W.F90 @@ -46,7 +46,7 @@ module specified_clouds_W_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: specified_clouds_W.F90,v 19.0 2012/01/06 20:24:09 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/standalone_clouds.F90 b/src/atmos_param/sea_esf_rad/standalone_clouds.F90 index c930783ce0..1784b6a4ef 100644 --- a/src/atmos_param/sea_esf_rad/standalone_clouds.F90 +++ b/src/atmos_param/sea_esf_rad/standalone_clouds.F90 @@ -45,7 +45,7 @@ module standalone_clouds_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: standalone_clouds.F90,v 19.0 2012/01/06 20:24:41 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/strat_clouds_W.F90 b/src/atmos_param/sea_esf_rad/strat_clouds_W.F90 index 3b1fa334bc..1a613cdacd 100644 --- a/src/atmos_param/sea_esf_rad/strat_clouds_W.F90 +++ b/src/atmos_param/sea_esf_rad/strat_clouds_W.F90 @@ -62,7 +62,7 @@ module strat_clouds_W_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: strat_clouds_W.F90,v 19.0 2012/01/06 20:24:43 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/sea_esf_rad/uw_clouds_W.F90 b/src/atmos_param/sea_esf_rad/uw_clouds_W.F90 index 8f2b4391da..512e85c31a 100644 --- a/src/atmos_param/sea_esf_rad/uw_clouds_W.F90 +++ b/src/atmos_param/sea_esf_rad/uw_clouds_W.F90 @@ -47,7 +47,7 @@ module uw_clouds_W_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: uw_clouds_W.F90,v 19.0 2012/01/06 20:25:15 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' diff --git a/src/atmos_param/sea_esf_rad/zetac_clouds_W.F90 b/src/atmos_param/sea_esf_rad/zetac_clouds_W.F90 index c091356ac1..59f78dc73b 100644 --- a/src/atmos_param/sea_esf_rad/zetac_clouds_W.F90 +++ b/src/atmos_param/sea_esf_rad/zetac_clouds_W.F90 @@ -48,7 +48,7 @@ module zetac_clouds_W_mod !----------- version number for this module -------------------------- character(len=128) :: version = '$Id: zetac_clouds_W.F90,v 19.0 2012/01/06 20:25:17 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- diff --git a/src/atmos_param/shallow_conv/null/shallow_conv.F90 b/src/atmos_param/shallow_conv/null/shallow_conv.F90 deleted file mode 100644 index 1958579c82..0000000000 --- a/src/atmos_param/shallow_conv/null/shallow_conv.F90 +++ /dev/null @@ -1,140 +0,0 @@ - MODULE SHALLOW_CONV_MOD - -!======================================================================= -! --- SHALLOW CONVECTION MODULE - GFDL SPECTRAL MODEL VERSION -!======================================================================= - - use Sat_Vapor_Pres_Mod, ONLY: ESCOMP, DESCOMP - use Fms_Mod, ONLY: FILE_EXIST, ERROR_MESG, FATAL, & - CHECK_NML_ERROR, OPEN_NAMELIST_FILE, & - CLOSE_FILE, mpp_pe, mpp_root_pe, & - write_version_number, stdlog - - use constants_mod, only: Hlv, Cp_Air, RDgas, RVgas, Kappa, grav - -!--------------------------------------------------------------------- - implicit none - private -!--------------------------------------------------------------------- - - public :: SHALLOW_CONV, SHALLOW_CONV_INIT, SHALLOW_CONV_END - public :: MYLCL - -!--------------------------------------------------------------------- - - character(len=128) :: version = '$Id: shallow_conv.F90,v 10.0 2003/10/24 22:00:49 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - - logical :: module_is_initialized = .false. - -!--------------------------------------------------------------------- - - contains - -!####################################################################### -!####################################################################### - - SUBROUTINE SHALLOW_CONV_INIT( kx ) - -!======================================================================= -! ***** INITIALIZE SHALLOW CONVECTION -!======================================================================= -!--------------------------------------------------------------------- -! Arguments (Intent in) -! kx - Number of levels in vertical -!--------------------------------------------------------------------- - integer, intent(in) :: kx - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - -!------------------------------------------------------------------- - module_is_initialized = .true. -!--------------------------------------------------------------------- - - call error_mesg('SHALLOW_CONV_INIT', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE SHALLOW_CONV_INIT - -!####################################################################### - - SUBROUTINE SHALLOW_CONV_END -!------------------------------------------------------------------- - module_is_initialized = .false. -!--------------------------------------------------------------------- - - call error_mesg('SHALLOW_CONV_END', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE SHALLOW_CONV_END - -!####################################################################### - - SUBROUTINE SHALLOW_CONV( Temp, qmix0, pfull, phalf, akhsc, kbot ) - -!======================================================================= -! --- SHALLOW CONVECTION -!======================================================================= -!---------------------------------------------------------------------- -! Arguments (Intent in) -! Temp - Temperature -! qmix0 - Specific humidity -! pfull - Pressure at full levels -! phalf - Pressure at half levels -! kbot - OPTIONAL; lowest model level index (integer) -!---------------------------------------------------------------------- - real, intent(in), dimension(:,:,:) :: Temp, qmix0, pfull, phalf - - integer, intent(in), OPTIONAL, dimension(:,:) :: kbot - -!---------------------------------------------------------------------- -! Arguments (Intent out) -! akhsc - mixing coefficient for heat and moisture -! due to shallow convection -!---------------------------------------------------------------------- - real, intent(out), dimension(:,:,:) :: akhsc - -!--------------------------------------------------------------------- - - call error_mesg('SHALLOW_CONV', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE SHALLOW_CONV - -!####################################################################### - - SUBROUTINE MYLCL ( tlparc, qlparc, plparc, phalf, plcl, kbase ) - -!======================================================================= -! ***** COMPUTE LCL ( CLOUD BASE ) -!======================================================================= -!--------------------------------------------------------------------- -! Arguments (Intent in) -! tlparc Initial parcel temperature -! qlparc Initial parcel mixing ratio -! plparc Initial parcel pressure -! phalf Pressure at half levels -! Arguments (Intent out) -! plcl Pressure at LCL -! kbase Index of LCL in column -!--------------------------------------------------------------------- - real, intent(in), dimension(:,:) :: tlparc, qlparc, plparc - real, intent(in), dimension(:,:,:) :: phalf - real, intent(out), dimension(:,:) :: plcl - integer, intent(out), dimension(:,:) :: kbase - -!--------------------------------------------------------------------- - - call error_mesg('MYLCL', & - 'This module is not supported as part of the public release', FATAL) - - end SUBROUTINE MYLCL - -!####################################################################### -!####################################################################### - end MODULE SHALLOW_CONV_MOD - diff --git a/src/atmos_param/shallow_conv/shallow_conv.F90 b/src/atmos_param/shallow_conv/shallow_conv.F90 index 5d8e5d532d..5611243ec5 100644 --- a/src/atmos_param/shallow_conv/shallow_conv.F90 +++ b/src/atmos_param/shallow_conv/shallow_conv.F90 @@ -24,7 +24,7 @@ MODULE SHALLOW_CONV_MOD !--------------------------------------------------------------------- character(len=128) :: version = '$Id: shallow_conv.F90,v 19.0 2012/01/06 20:25:24 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_param/shallow_cu/conv_closures.F90 b/src/atmos_param/shallow_cu/conv_closures.F90 index 0cf445f967..e956fe5415 100644 --- a/src/atmos_param/shallow_cu/conv_closures.F90 +++ b/src/atmos_param/shallow_cu/conv_closures.F90 @@ -17,7 +17,7 @@ MODULE CONV_CLOSURES_MOD !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: conv_closures.F90,v 19.0 2012/01/06 20:25:26 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized=.false. ! module initialized ? !--------------------------------------------------------------------- diff --git a/src/atmos_param/shallow_cu/conv_plumes.F90 b/src/atmos_param/shallow_cu/conv_plumes.F90 index fc07b60c97..0625df5d2c 100644 --- a/src/atmos_param/shallow_cu/conv_plumes.F90 +++ b/src/atmos_param/shallow_cu/conv_plumes.F90 @@ -10,7 +10,7 @@ MODULE CONV_PLUMES_MOD !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: conv_plumes.F90,v 15.0 2007/08/14 03:56:03 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- diff --git a/src/atmos_param/shallow_cu/conv_plumes_k.F90 b/src/atmos_param/shallow_cu/conv_plumes_k.F90 index 9943d3771c..322e61952e 100644 --- a/src/atmos_param/shallow_cu/conv_plumes_k.F90 +++ b/src/atmos_param/shallow_cu/conv_plumes_k.F90 @@ -12,8 +12,8 @@ MODULE CONV_PLUMES_k_MOD !--------------------------------------------------------------------- !----------- ****** VERSION NUMBER ******* --------------------------- - character(len=128) :: version = '$Id: conv_plumes_k.F90,v 19.0 2012/01/06 20:25:58 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: conv_plumes_k.F90,v 20.0 2013/12/13 23:21:34 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- @@ -41,7 +41,7 @@ MODULE CONV_PLUMES_k_MOD real :: rle, rpen, rmaxfrac, wmin, rbuoy, rdrag, frac_drs, bigc real :: auto_th0, auto_rate, tcrit, cldhgt_max, atopevap, rad_crit, & wtwmin_ratio, deltaqc0, emfrac_max, wrel_min, & - Nl_land, Nl_ocean, r_thresh, qi_thresh, peff, rh0, cfrac,hcevap, weffect,t00 + Nl_land, Nl_ocean, r_thresh, qi_thresh, peff_l, peff_i, peff, rh0, cfrac,hcevap, weffect,t00 logical :: do_ice, do_ppen, do_forcedlifting, do_pevap, do_pdfpcp, isdeep, use_online_aerosol logical :: do_auto_aero, do_pmadjt, do_emmax, do_pnqv, do_weffect, do_qctflx_zero,do_detran_zero character(len=32), dimension(:), _ALLOCATABLE :: tracername _NULL @@ -184,7 +184,7 @@ subroutine cp_clear_k (cp) cp%ufrc =0.; cp%thvbot=0.; cp%thvtop=0.; cp%hlu =0.; cp%fdrsat=0.; cp%z =0.; cp%zs =0.; cp%hl =0.; cp%clu =0.; cp%ciu =0.; cp%buo =0.; cp%t =0.; - cp%crate =0.; cp%prate =0.; cp%peff =0.; + cp%crate =0.; cp%prate =0.; cp%peff =0.; !cp%maxcldfrac = 1.; !++++yim cp%pptn =0.; cp%tr =0.; cp%tru =0.; cp%tru_dwet = 0. end subroutine cp_clear_k @@ -511,23 +511,37 @@ subroutine cumulus_plume_k (cpn, sd, ac, cp, rkm, cbmf, wrel, scaleh,& cp%fer(k), cp%fdr(k), cp%fdrsat(k), rho0j, & rkm, Uw_p, cp%umf(km1), cp%dp(k), sd%delt) else if (cpn%mixing_assumption.eq.1) then - temp = sqrt(cp%ufrc(km1)) !scaleh for fixed length scale + temp = sqrt(cp%ufrc(km1)) !scaleh for fixed length scale for donner_plumes rho0j = sd%rho(k) cp%rei(k) = rkm/temp/Uw_p%grav/rho0j cp%fer(k) = cp%rei(k) cp%fdr(k) = 0. cp%fdrsat(k) = 0. else if (cpn%mixing_assumption.eq.2) then - gamma=0.0065 - scaleh1 = cpn%t00/gamma*(1.-(cp%p(k)/100000.)**(Uw_p%rdgas*gamma/Uw_p%grav)) - scaleh1 = max (1000., scaleh1-sd%zs(0)) + scaleh1 = max(1000., cp%z(k)) + call mixing_k (cpn, cp%z(k), cp%p(k), hl_env_k, cp%thc(k), & + qct_env_k, cp%hlu(km1), cp%thcu(km1), & + cp%qctu(km1), cp%wu(km1), scaleh1, cp%rei(k), & + cp%fer(k), cp%fdr(k), cp%fdrsat(k), rho0j, & + rkm, Uw_p, cp%umf(km1), cp%dp(k), sd%delt) + else if (cpn%mixing_assumption.eq.3) then + scaleh1 = cpn%t00*Uw_p%rdgas/Uw_p%grav*log(cp%p(1)/cp%p(k)) + scaleh1 = max (1000., scaleh1) + call mixing_k (cpn, cp%z(k), cp%p(k), hl_env_k, cp%thc(k), & + qct_env_k, cp%hlu(km1), cp%thcu(km1), & + cp%qctu(km1), cp%wu(km1), scaleh1, cp%rei(k), & + cp%fer(k), cp%fdr(k), cp%fdrsat(k), rho0j, & + rkm, Uw_p, cp%umf(km1), cp%dp(k), sd%delt) + else if (cpn%mixing_assumption.eq.4) then + scaleh1 = 2000. call mixing_k (cpn, cp%z(k), cp%p(k), hl_env_k, cp%thc(k), & qct_env_k, cp%hlu(km1), cp%thcu(km1), & cp%qctu(km1), cp%wu(km1), scaleh1, cp%rei(k), & cp%fer(k), cp%fdr(k), cp%fdrsat(k), rho0j, & rkm, Uw_p, cp%umf(km1), cp%dp(k), sd%delt) else - scaleh1 = max (1000., cp%z(k)-sd%zs(0)) + scaleh1 = cpn%t00*Uw_p%rdgas/Uw_p%grav*log(cp%p(1)/cp%p(k)) + scaleh1 = max (1000., scaleh1) call mixing_k (cpn, cp%z(k), cp%p(k), hl_env_k, cp%thc(k), & qct_env_k, cp%hlu(km1), cp%thcu(km1), & cp%qctu(km1), cp%wu(km1), scaleh1, cp%rei(k), & @@ -585,6 +599,18 @@ subroutine cumulus_plume_k (cpn, sd, ac, cp, rkm, cbmf, wrel, scaleh,& hlu_new, qctu_new, qlu_new, qiu_new, & clu_new, ciu_new, temp, cpn%do_ice, & delta_qn, Uw_p, kbelowlet) + else if (cpn%mp_choice.eq.4) then + call precip4_k (cp%zs(k), cp%ps(k), cp%hlu(k), & + cp%qctu(k), cp%qnu(k), cpn, qrj, qsj, & + hlu_new, qctu_new, qlu_new, qiu_new, & + clu_new, ciu_new, temp, cpn%do_ice, & + delta_qn, Uw_p, kbelowlet) + else if (cpn%mp_choice.eq.5) then + call precip5_k (cp%zs(k), cp%ps(k), cp%hlu(k), & + cp%qctu(k), cp%qnu(k), cpn, qrj, qsj, & + hlu_new, qctu_new, qlu_new, qiu_new, & + clu_new, ciu_new, temp, cpn%do_ice, & + delta_qn, Uw_p, kbelowlet, sd%dp(k)) end if cp%qctu(k)=qctu_new @@ -596,7 +622,7 @@ subroutine cumulus_plume_k (cpn, sd, ac, cp, rkm, cbmf, wrel, scaleh,& cp%peff(k)=(qrj+qsj)/max(qlu_new+qiu_new+qrj+qsj,1.e-28); cp%thvu(k)=temp/exn_k(cp%ps(k),Uw_p)*(1.+Uw_p%zvir*(cp%qctu(k)-cp%qlu(k)-cp%qiu(k))-cp%qlu(k)-cp%qiu(k)) - cp%buo (k)=cp%thvu(k)-cp%thvtop(k) + cp%buo (k)=(cp%thvu(k)-cp%thvtop(k))!/cp%thvtop(k)*Uw_p%grav cp%t (k)=temp nu = max(min((268. - temp)/20.,1.0),0.0) leff = (1-nu)*Uw_p%HLv + nu*Uw_p%HLs @@ -722,6 +748,10 @@ subroutine cumulus_plume_k (cpn, sd, ac, cp, rkm, cbmf, wrel, scaleh,& !convective scale height cp % cush=sd%z(ltop) - sd%zs(0) + if (cpn%mixing_assumption.eq.2) then + cp % cush = cpn%t00*Uw_p%rdgas/Uw_p%grav*log(cp%p(1)/cp%p(k)) + endif + if (cpn%do_ppen) then !Calculate penetrative entrainment call penetrative_mixing_k(cpn, sd, Uw_p, cp) else @@ -836,6 +866,127 @@ subroutine precipitation_k (zs, ps, hlu, qctu, qnu, cpn, qrj, qsj, & end subroutine precipitation_k + subroutine precip5_k (zs, ps, hlu, qctu, qnu, cpn, qrj, qsj, & + hlu_new, qctu_new, qlu_new, qiu_new, & + clu_new, ciu_new, temp, doice, delta_qn, & + Uw_p, kbelowlet, delp) + type(cpnlist), intent(in) :: cpn + type(uw_params), intent(inout) :: Uw_p + real, intent(in) :: zs, ps, hlu, qctu, delp + real, intent(inout) :: qnu, delta_qn + real, intent(inout) :: qrj, qsj, hlu_new, qctu_new, & + qlu_new, qiu_new, clu_new, & + ciu_new, temp + logical, intent(in) :: doice, kbelowlet + + real :: thj, qvj, qlj, qij, qse, thvj, nu, exnj, & + auto_th, leff, pcp, qctmp, deltaqc, auto_th2, peff + + !Precip at the flux level + call findt_k (zs,ps,hlu,qctu,thj,qvj,qlj,qij,qse,thvj,doice, & + Uw_p) + exnj=exn_k(ps,Uw_p) + temp=thj*exnj-273.15 + if (temp.ge.0.0) then + peff=cpn%peff_l*delp + else + peff=cpn%peff_i*delp + end if + peff=max(1.0-peff,0.0) + + if (.not.kbelowlet) peff=0.0 + + temp=temp+273.15 + + qctmp = qlj+qij; + pcp = max(qctmp*peff,0.) + qctmp = 1./max(qctmp,1.e-28) + qrj = pcp*qlj*qctmp + qsj = pcp*qij*qctmp + nu = max(min((268. - temp)/20.,1.0),0.0) + + if (qlj.le.0) then + delta_qn = -qnu + qnu = 0 + else + delta_qn = qnu * qrj * qctmp + qnu = qnu - delta_qn + end if + + leff = (1-nu)*Uw_p%HLv + nu*Uw_p%HLs + qctu_new = qctu - (qrj + qsj) + hlu_new = hlu + (qrj + qsj)*leff + qlu_new = qlj - qrj + qiu_new = qij - qsj + clu_new = qlu_new + ciu_new = qiu_new + + return + + end subroutine precip5_k + + + subroutine precip4_k (zs, ps, hlu, qctu, qnu, cpn, qrj, qsj, & + hlu_new, qctu_new, qlu_new, qiu_new, & + clu_new, ciu_new, temp, doice, delta_qn, & + Uw_p, kbelowlet) + type(cpnlist), intent(in) :: cpn + type(uw_params), intent(inout) :: Uw_p + real, intent(in) :: zs, ps, hlu, qctu + real, intent(inout) :: qnu, delta_qn + real, intent(inout) :: qrj, qsj, hlu_new, qctu_new, & + qlu_new, qiu_new, clu_new, & + ciu_new, temp + logical, intent(in) :: doice, kbelowlet + + real :: thj, qvj, qlj, qij, qse, thvj, nu, exnj, & + auto_th, leff, pcp, qctmp, deltaqc, auto_th2, peff + + !Precip at the flux level + call findt_k (zs,ps,hlu,qctu,thj,qvj,qlj,qij,qse,thvj,doice, & + Uw_p) + exnj=exn_k(ps,Uw_p) + temp=thj*exnj-273.15 + if (temp.ge.0.0) then + peff=cpn%peff_l + else +! peff=(1.0-cpn%peff)*min(temp/cpn%tcrit,1.0) + peff=cpn%peff_i + end if +! peff=max(1.0-peff,0.0) + + if (.not.kbelowlet) peff=0.0 + + temp=temp+273.15 + + qctmp = qlj+qij; + pcp = max(qctmp*peff,0.) + qctmp = 1./max(qctmp,1.e-28) + qrj = pcp*qlj*qctmp + qsj = pcp*qij*qctmp + nu = max(min((268. - temp)/20.,1.0),0.0) + + if (qlj.le.0) then + delta_qn = -qnu + qnu = 0 + else + delta_qn = qnu * qrj * qctmp + qnu = qnu - delta_qn + end if + + leff = (1-nu)*Uw_p%HLv + nu*Uw_p%HLs + qctu_new = qctu - (qrj + qsj) + hlu_new = hlu + (qrj + qsj)*leff + qlu_new = qlj - qrj + qiu_new = qij - qsj + clu_new = qlu_new + ciu_new = qiu_new + + return + + end subroutine precip4_k + + subroutine precip3_k (zs, ps, hlu, qctu, qnu, cpn, qrj, qsj, & hlu_new, qctu_new, qlu_new, qiu_new, & clu_new, ciu_new, temp, doice, delta_qn, & @@ -850,7 +1001,7 @@ subroutine precip3_k (zs, ps, hlu, qctu, qnu, cpn, qrj, qsj, & logical, intent(in) :: doice, kbelowlet real :: thj, qvj, qlj, qij, qse, thvj, nu, exnj, & - auto_th, leff, pcp, qctmp, deltaqc + auto_th, leff, pcp, qctmp, deltaqc, peff !Precip at the flux level call findt_k (zs,ps,hlu,qctu,thj,qvj,qlj,qij,qse,thvj,doice, & @@ -881,7 +1032,13 @@ subroutine precip3_k (zs, ps, hlu, qctu, qnu, cpn, qrj, qsj, & else pcp = max(qctmp-auto_th,0.) end if - pcp = qctmp*cpn%peff + + if (temp.ge.0.0) then + peff=cpn%peff_l + else + peff=cpn%peff_i + end if + pcp = qctmp*peff qctmp = 1./max(qctmp,1.e-28) qrj = pcp*qlj*qctmp @@ -1574,7 +1731,7 @@ SUBROUTINE precip_evap (sd, cp, cpn, ct, Uw_p, dpevap) mass = sd%dp/Uw_p%grav dpcu = 0.0 dpevap = 0.0 - do k = cp%ltop, 2, -1 + do k = cp%ltop, 1, -1 dpcu = dpcu + pptp(k) prec = MAX(dpcu - dpevap, 0.0 ) @@ -1591,6 +1748,7 @@ SUBROUTINE precip_evap (sd, cp, cpn, ct, Uw_p, dpevap) def=(hcevap*sd%qs(k) - sd%qv(k))/(1.+(HL*hcevap*dqs/Uw_p%Cp_Air )) def=evef*def def=MIN( def, prec/mass(k) ) + def=MAX( def, 0.0) else def=0.0 end if diff --git a/src/atmos_param/shallow_cu/conv_utilities.F90 b/src/atmos_param/shallow_cu/conv_utilities.F90 index 1c7a6190b8..f16b4b36ec 100644 --- a/src/atmos_param/shallow_cu/conv_utilities.F90 +++ b/src/atmos_param/shallow_cu/conv_utilities.F90 @@ -21,7 +21,7 @@ MODULE CONV_UTILITIES_MOD !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: conv_utilities.F90,v 17.0 2009/07/21 02:58:03 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- diff --git a/src/atmos_param/shallow_cu/conv_utilities_k.F90 b/src/atmos_param/shallow_cu/conv_utilities_k.F90 index c7e3fcaaca..cfb29e8fa4 100644 --- a/src/atmos_param/shallow_cu/conv_utilities_k.F90 +++ b/src/atmos_param/shallow_cu/conv_utilities_k.F90 @@ -11,8 +11,8 @@ MODULE CONV_UTILITIES_k_MOD !--------------------------------------------------------------------- !----------- ****** VERSION NUMBER ******* --------------------------- - character(len=128) :: version = '$Id: conv_utilities_k.F90,v 19.0 2012/01/06 20:26:00 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: conv_utilities_k.F90,v 20.0 2013/12/13 23:21:37 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- @@ -31,7 +31,7 @@ MODULE CONV_UTILITIES_k_MOD type sounding logical :: coldT integer :: kmax, kinv, ktoppbl, ktopconv - real :: psfc, pinv, zinv, thvinv, land, pblht, qint, delt, rhav, tke + real :: psfc, pinv, zinv, thvinv, land, pblht, qint, delt, crh, tke real, _ALLOCATABLE :: t (:)_NULL, qv (:)_NULL, u (:)_NULL real, _ALLOCATABLE :: v (:)_NULL, ql (:)_NULL, qi (:)_NULL real, _ALLOCATABLE :: qa (:)_NULL, thc (:)_NULL, qct (:)_NULL @@ -150,7 +150,7 @@ subroutine sd_init_k(kd, num_tracers, sd) sd%pblht = 0.0 sd%qint = 0.0 sd%delt = 0.0 - sd%rhav = 0.0 + sd%crh = 0.0 sd%tke = 0.0 allocate ( sd%t (1:kd)); sd%t =0.; allocate ( sd%qv (1:kd)); sd%qv =0.; @@ -363,7 +363,7 @@ subroutine extend_sd_k(sd, pblht, doice, Uw_p) integer :: k, kl, ktoppbl real :: sshl0a, sshl0b, ssthc0a, ssthc0b, ssqct0a, ssqct0b real :: hl0bot, thc0bot, qct0bot, hl0top, thc0top, qct0top - real :: thj, qvj, qlj, qij, qse, dpsum + real :: thj, qvj, qlj, qij, qse, qs_sum, qt_sum, dpsum real, dimension(size(sd%tr,2)) :: sstr0a, sstr0b sd % exners(0) = exn_k(sd%ps(0),Uw_p); @@ -377,7 +377,7 @@ subroutine extend_sd_k(sd, pblht, doice, Uw_p) sd % hl (:) = Uw_p%cp_air*sd%t(:)+Uw_p%grav*sd%z(:)- & sd%leff(:)*(sd%ql(:)+sd%qi(:)) sd % qint = 0. - sd % rhav = 0.; dpsum=0. + sd % crh = 0.; qs_sum=0.; qt_sum=0.; !dpsum=0.; do k=1, sd%ktopconv !sd%kmax sd % dp (k) = sd%ps(k-1)-sd%ps(k) sd % dz (k) = sd%zs(k) -sd%zs(k-1) @@ -391,13 +391,12 @@ subroutine extend_sd_k(sd, pblht, doice, Uw_p) sd % rho (k) = sd % p(k)/ & (Uw_p%rdgas * sd % thv(k) * sd % exner(k)) sd % qint =sd % qint + sd%qct(k)*sd%dp(k) - if (sd%p(k) .gt. 40000) then - sd % rhav = sd % rhav+ sd%rh (k)*sd%dp(k) - dpsum = dpsum + sd%dp(k) - end if + qs_sum = qs_sum + sd % qs(k) * sd%dp(k) + qt_sum = qt_sum + sd % qct(k) * sd%dp(k) + !dpsum = dpsum + sd%dp(k) end do sd % qint = sd % qint / Uw_p%grav - sd % rhav = sd % rhav / dpsum + sd % crh = qt_sum / qs_sum sd % hm (:) = Uw_p%cp_air*sd%t(:)+Uw_p%grav*sd%z(:)+sd%leff(:)*sd%qv(:) sd % hms (:) = Uw_p%cp_air*sd%t(:)+Uw_p%grav*sd%z(:)+sd%leff(:)*sd%qs(:) diff --git a/src/atmos_param/shallow_cu/deep_conv.F90 b/src/atmos_param/shallow_cu/deep_conv.F90 index 8afddb1c48..a76168da52 100644 --- a/src/atmos_param/shallow_cu/deep_conv.F90 +++ b/src/atmos_param/shallow_cu/deep_conv.F90 @@ -21,18 +21,17 @@ MODULE DEEP_CONV_MOD cclosure_relaxwfn, & cclosure_implicit, cclosure - !--------------------------------------------------------------------- implicit none private !----------- ****** VERSION NUMBER ******* --------------------------- - character(len=128) :: version = '$Id: deep_conv.F90,v 19.0 2012/01/06 20:26:02 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: deep_conv.F90,v 20.0 2013/12/13 23:21:39 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !------- interfaces -------- - public :: dpconv0, dpconv1, dpconv2, dpconv3, DEEP_CONV_INIT, DEEP_CONV_END + public :: cpn_copy, dpconv0, dpconv1, dpconv2 logical :: module_is_initialized = .false. @@ -40,22 +39,26 @@ MODULE DEEP_CONV_MOD public deepc type deepc - real, dimension(7) :: rkm_dp - real, dimension(7) :: rat_dp - real, dimension(50) :: rkm - real, dimension(50) :: rat - real, dimension(50) :: hgt - real :: omeg_th + real :: rkm_dp1 + real :: rkm_dp2 + real :: cbmf_dp_frac1 + real :: cbmf_dp_frac2 + real :: crh_th_land + real :: crh_th_ocean real :: cape_th - real :: tau_dp - real :: cbmf_d - real :: cwfn_d - real :: deepdepth - integer :: ideep_closure - integer :: mixing_assumption - logical :: do_generation - logical :: do_ppen - logical :: do_pevap + real :: tau_dp + real :: rpen_d + integer :: mixing_assumption_d + logical :: do_ppen_d + logical :: do_pevap_d + real :: cfrac_d + real :: hcevap_d + real :: dcapedm_th + real :: frac_limit_d + real :: lofactor_d + real :: tcrit_d + real :: auto_th0_d + logical :: do_forcedlifting_d end type deepc contains @@ -67,65 +70,90 @@ subroutine cpn_copy(cpn, dpn) type(cpnlist), intent(in) :: cpn type(cpnlist), intent(inout) :: dpn - dpn % rle = cpn % rle - dpn % rpen = cpn % rpen - dpn % rmaxfrac = cpn % rmaxfrac - dpn % wmin = cpn % wmin - dpn % rbuoy = cpn % rbuoy - dpn % rdrag = cpn % rdrag - dpn % frac_drs = cpn % frac_drs - dpn % bigc = cpn % bigc - dpn % auto_th0 = cpn % auto_th0 - dpn % auto_rate = cpn % auto_rate - dpn % tcrit = cpn % tcrit - dpn % cldhgt_max = cpn % cldhgt_max - dpn % do_ice = cpn % do_ice - dpn % do_ppen = cpn % do_ppen - dpn % do_pevap = cpn % do_pevap - dpn % mixing_assumption= cpn % mixing_assumption - dpn % mp_choice = cpn % mp_choice - dpn % do_forcedlifting = cpn % do_forcedlifting - dpn % atopevap = cpn % atopevap - dpn % wtwmin_ratio = cpn % wtwmin_ratio + dpn % do_qctflx_zero = cpn % do_qctflx_zero + dpn % do_detran_zero = cpn % do_detran_zero + dpn % rle = cpn % rle + dpn % rpen = cpn % rpen + dpn % rmaxfrac = cpn % rmaxfrac + dpn % wmin = cpn % wmin + dpn % rbuoy = cpn % rbuoy + dpn % rdrag = cpn % rdrag + dpn % frac_drs = cpn % frac_drs + dpn % bigc = cpn % bigc + dpn % auto_th0 = cpn % auto_th0 + dpn % deltaqc0 = cpn % deltaqc0 + dpn % do_pdfpcp = cpn % do_pdfpcp + dpn % do_pmadjt = cpn % do_pmadjt + dpn % do_emmax = cpn % do_emmax + dpn % do_pnqv = cpn % do_pnqv + dpn % emfrac_max = cpn % emfrac_max + dpn % auto_rate = cpn % auto_rate + dpn % tcrit = cpn % tcrit + dpn % cldhgt_max = cpn % cldhgt_max + dpn % do_ice = cpn % do_ice + dpn % do_ppen = cpn % do_ppen + dpn % do_pevap = cpn % do_pevap + dpn % hcevap = cpn % hcevap + dpn % cfrac = cpn % cfrac + dpn % mixing_assumption = cpn % mixing_assumption + dpn % mp_choice = cpn % mp_choice + dpn % Nl_land = cpn % Nl_land + dpn % Nl_ocean = cpn % Nl_ocean + dpn % qi_thresh = cpn % qi_thresh + dpn % r_thresh = cpn % r_thresh + dpn % peff_l = cpn % peff_l + dpn % peff_i = cpn % peff_i + dpn % peff = cpn % peff + dpn % t00 = cpn % t00 + dpn % rh0 = cpn % rh0 + dpn % do_forcedlifting = cpn % do_forcedlifting + dpn % atopevap = cpn % atopevap + dpn % wtwmin_ratio = cpn % wtwmin_ratio + dpn % do_auto_aero = cpn % do_auto_aero + dpn % rad_crit = cpn % rad_crit + dpn % wrel_min = cpn % wrel_min + dpn % do_weffect = cpn % do_weffect + dpn % weffect = cpn % weffect + dpn % use_online_aerosol = cpn % use_online_aerosol + dpn % isdeep = cpn % isdeep end subroutine cpn_copy !##################################################################### !##################################################################### - subroutine dpconv0(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & - omeg_avg, rkm_sh, cp1, ct1, cbmf_deep, ocode, ier, ermesg) + subroutine dpconv0(dpc, dpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & + rkm_dp, cbmf_deep, cp1, ct1, ocode, ier, ermesg) implicit none type(deepc), intent(inout) :: dpc - type(cpnlist), intent(in) :: cpn + type(cpnlist), intent(inout) :: dpn type(uw_params), intent(inout) :: Uw_p type(sounding), intent(in) :: sd type(adicloud), intent(in) :: ac type(cclosure), intent(in) :: cc logical, intent(in) :: do_coldT logical, intent(in) :: do_ice - type(cplume), intent(inout) :: cp, cp1 - type(ctend), intent(inout) :: ct, ct1 - real, intent(inout) :: cbmf_deep, ocode, rkm_sh, omeg_avg - integer, intent(out) :: ier - character(len=256), intent(out) :: ermesg - + type(cplume), intent(inout) :: cp + type(ctend), intent(inout) :: ct + real, intent(inout) :: rkm_dp, cbmf_deep + type(cplume), intent(inout) :: cp1 + type(ctend), intent(inout) :: ct1 + real, intent(inout) :: ocode + integer, intent(out) :: ier + character(len=256), intent(out) :: ermesg - type(cpnlist) :: dpn - real :: rkm_dp, zcldtop + real :: zcldtop, dcrh, cbmf_dp_frac - if ( (ocode.ne.0) .or. (omeg_avg .gt.dpc%omeg_th)) then - ocode=6; return + ier = 0 + ermesg = ' ' + if ( (ocode.ne.0 .and. ocode.ne.4) .or. (cbmf_deep.eq.0) ) then + ocode=6; + return end if - call cpn_copy(cpn, dpn) - dpn % do_ppen = dpc % do_ppen - dpn % do_pevap = dpc % do_pevap - rkm_dp = dpc%rkm_dp(1) * rkm_sh zcldtop = sd%z(cp%ltop) - - call cp_clear_k(cp1); + call cp_clear_k(cp1); cp1%maxcldfrac=1.; call ct_clear_k(ct1); call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, cbmf_deep, cc%wrel, zcldtop, Uw_p, ier, ermesg) if(cp1%ltop.lt.cp1%krel+2 .or. cp1%let.le.cp1%krel+1) then @@ -140,111 +168,58 @@ end subroutine dpconv0 !##################################################################### !##################################################################### - subroutine dpconv1(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, sd1, ac1, & - cc1, cp1, ct1, ocode, ier, ermesg) + subroutine dpconv1(dpc, dpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & + rkm_dp, cbmf_deep, sd1, ac1, cp1, ct1, ocode, dcapedm, ier, ermesg) implicit none type(deepc), intent(inout) :: dpc - type(cpnlist), intent(in) :: cpn + type(cpnlist), intent(inout) :: dpn type(uw_params), intent(inout) :: Uw_p type(sounding), intent(in) :: sd - type(adicloud), intent(inout) :: ac + type(adicloud), intent(in) :: ac + type(cclosure), intent(in) :: cc logical, intent(in) :: do_coldT logical, intent(in) :: do_ice + type(cplume), intent(inout) :: cp + type(ctend), intent(inout) :: ct + real, intent(inout) :: rkm_dp, cbmf_deep type(sounding), intent(inout) :: sd1 type(adicloud), intent(inout) :: ac1 - type(cclosure), intent(inout) :: cc,cc1 - type(cplume), intent(inout) :: cp,cp1 - type(ctend), intent(inout) :: ct,ct1 - real, intent(inout) :: ocode - integer, intent(out) :: ier - character(len=256), intent(out) :: ermesg - - integer :: i, ksrc - real :: cbmf0, cbmfs, cbmf_max, dcape, scaleh, wrel, tmp, cbmf, rkm - real :: zsrc, psrc, thcsrc, hlsrc, qctsrc, pdeet1, pdeet2 - - type(cpnlist) :: dpn - - call cpn_copy(cpn, dpn) - - dpn % do_ppen = .false. - dpn % rmaxfrac = 1000000. - dpn % rbuoy = 0.66666 - dpn % rdrag = 3.0 - dpn % auto_th0 = 0.5e-3 - dpn % auto_rate = 1.0e-3 - dpn % mixing_assumption= 1 - dpn % mp_choice = 1 - dpn % do_forcedlifting = .true. - -!!$ zsrc =sd%zs (1); -!!$ psrc =sd%ps (1); thcsrc=sd%thc(1) -!!$ hlsrc =cc%xhlsrc -!!$ qctsrc=cc%xqtsrc -!!$ call adi_cloud(zsrc, psrc, hlsrc, thcsrc, qctsrc, sd, .false., do_ice, ac1) -!!$ cc % dcape=(ac1%cape-cc%xcape)/sd%delt - - pdeet1=ac%plfc - ac%plnb - pdeet2=ac%plfc - ac%plcl - - if ((ac%cape <= dpc%cape_th ) .or. & -! (cc%dcape <= 0. .and. dpc%do_dcape_closure ) .or. & - (pdeet1 <= 500.e02 ) .or. & - (ac%cin >= 100.)) then - dpc%cbmf_d=0.; - ocode=6; + type(cplume), intent(inout) :: cp1 + type(ctend), intent(inout) :: ct1 + real, intent(inout) :: ocode, dcapedm + integer, intent(out) :: ier + character(len=256), intent(out) :: ermesg + + real :: zcldtop, wrel, cbmf0, cbmf_max, tmp + integer :: ksrc + + ier = 0 + ermesg = ' ' + zcldtop = 2000 !sd%z(cp%ltop) + wrel = max(cc%wrel, 0.1) + +! if ( (ocode.ne.0 .and. ocode.ne.4) .or. (cbmf_deep.eq.0) ) then + if ( cbmf_deep.eq.0 ) then + ocode=6; return end if - - ksrc=2 - zsrc =sd%zs (ksrc); - psrc =sd%ps (ksrc); thcsrc=sd%thc(ksrc) - qctsrc=sd%qct(ksrc) - hlsrc =sd%hl (ksrc) - call adi_cloud_k(zsrc, psrc, hlsrc, thcsrc, qctsrc, sd, Uw_p, .false., do_ice, ac) - - cbmf0=0.0001; dpc%cbmf_d=0.; wrel=0.5; scaleh=1000. - - cbmf=1000000.*wrel; - do i=1, size(dpc%rkm_dp(:)) - call ct_clear_k(ct) - call cp_clear_k(cp) - rkm = dpc%rkm_dp(i) - call cumulus_plume_k(dpn, sd, ac, cp, rkm, cbmf, wrel, scaleh, Uw_p, ier, ermesg) - if(cp%ltop.lt.cp%krel+2 .or. cp%let.le.cp%krel+1) then - dpc%cbmf_d=0.; ocode=6; return - end if - call cumulus_tend_k(dpn, sd, Uw_p, cp, ct, do_coldT) - ct1%tten = ct1%tten + ct%tten * dpc%rat_dp(i) - ct1%qvten = ct1%qvten + ct%qvten * dpc%rat_dp(i) - ct1%qlten = ct1%qlten + ct%qlten * dpc%rat_dp(i) - ct1%qiten = ct1%qiten + ct%qiten * dpc%rat_dp(i) - ct1%qaten = ct1%qaten + ct%qaten * dpc%rat_dp(i) - ct1%qnten = ct1%qnten + ct%qnten * dpc%rat_dp(i) - ct1%uten = ct1%uten + ct%uten * dpc%rat_dp(i) - ct1%vten = ct1%vten + ct%vten * dpc%rat_dp(i) - ct1%pflx = ct1%pflx + ct%pflx * dpc%rat_dp(i) - ct1%hlflx = ct1%hlflx + ct%hlflx * dpc%rat_dp(i) - ct1%qctflx= ct1%qctflx+ ct%qctflx* dpc%rat_dp(i) -! ct1%tevap = ct1%tevap + ct%tevap * dpc%rat_dp(i) -! ct1%qevap = ct1%qevap + ct%qevap * dpc%rat_dp(i) - ct1%rain = ct1%rain + ct%rain * dpc%rat_dp(i) - ct1%snow = ct1%snow + ct%snow * dpc%rat_dp(i) - ct1%denth = ct1%denth + ct%denth * dpc%rat_dp(i) - - cp1%ufrc = cp1%ufrc + cp%ufrc * dpc%rat_dp(i) - cp1%qlu = cp1%qlu + cp%qlu * dpc%rat_dp(i) - cp1%qiu = cp1%qiu + cp%qiu * dpc%rat_dp(i) - cp1%qnu = cp1%qnu + cp%qnu * dpc%rat_dp(i) - cp1%umf = cp1%umf + cp%umf * dpc%rat_dp(i) - cp1%wu = cp1%wu + cp%wu * dpc%rat_dp(i) - cp1%fdrsat= cp1%fdrsat+ cp%fdrsat* dpc%rat_dp(i) - cp1%fdr = cp1%fdr + cp%fdr * dpc%rat_dp(i) - end do + if (ac%cape .lt. dpc%cape_th) then + ocode=7; return + end if + + cbmf0 = 0.0001 + call cp_clear_k(cp1); cp1%maxcldfrac=1.; + call ct_clear_k(ct1); + call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, cbmf0, wrel, zcldtop, Uw_p, ier, ermesg) + if(cp1%ltop.lt.cp1%krel+2 .or. cp1%let.le.cp1%krel+1) then + ocode=8; return + else + call cumulus_tend_k(dpn, sd, Uw_p, cp1, ct1, do_coldT) + end if call sd_copy_k(sd, sd1) - tmp = cbmf0 / cbmf + tmp = 1. sd1 % t = sd1 % t + ct1%tten * sd%delt * tmp sd1 % qv = sd1 % qv + ct1%qvten * sd%delt * tmp sd1 % ql = sd1 % ql + ct1%qlten * sd%delt * tmp @@ -255,320 +230,84 @@ subroutine dpconv1(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, sd1, ac sd1 % v = sd1 % v + ct1%vten * sd%delt * tmp call extend_sd_k(sd1,sd%pblht, do_ice, Uw_p) - + + call ac_clear_k(ac1); + ksrc=1 call adi_cloud_k(sd1%zs(ksrc), sd1%ps(ksrc), sd1%hl(ksrc), sd1%thc(ksrc), sd1%qct(ksrc), & sd1, Uw_p, .false., do_ice, ac1) - dcape=(ac%cape-ac1%cape)/cbmf0 - if (dcape <= 0.) then - dpc%cbmf_d=0.; ocode=6; return - end if - if (dpc%ideep_closure.eq.1) then - cbmfs = (ac%cape - dpc%cape_th) / dcape / (dpc%tau_dp/sd%delt) - else if (dpc%ideep_closure.eq.2) then - cbmfs = cc%dcape / dcape - else - cbmfs = 0.0 - end if -!!$ call cumulus_plume_k(dpn, sd1, ac1, cp1, rkm_dp, cbmf0, cc%wrel, cc%scaleh) -!!$ cc%dwfn=0.; cc%wfn=0.; delp=0.; -!!$ do k=cp1%krel, cp1%let -!!$ cc % wfn = cc % wfn + 0.5*(cp %wu(k)*cp %wu(k)) * cp%dp(k) -!!$ cc % dwfn = cc % dwfn + 0.5*(cp1%wu(k)*cp1%wu(k) - cp%wu(k)*cp%wu(k)) * cp%dp(k) -!!$ delp = delp + cp%dp(k) -!!$ end do -!!$ cc % wfn = cc % wfn / delp -!!$ cc % dwfn = cc % dwfn / delp / cbmf0 -!!$ if (do_cape_closure) then -!!$ cbmfs = - ac%cape / cc % dcape / (dpc%tau_dp/sd%delt) -!!$ elseif (do_relaxwfn) then -!!$ cbmfs = - cc%wfn / cc % dwfn / (dpc%tau_dp/sd%delt) -!!$ else -!!$ cbmfs = - cc%wfn / cc % dwfn -!!$ tmp = sd%delt/dpc%tau_dp -!!$ cbmfs = (cbmf_old+tmp*cbmfs)/(1.+tmp) -!!$ end if - - cbmf_max=(sd%ps(0) - sd%ps(cp%krel))*(0.25/sd%delt)/Grav - dpc%cbmf_d = max(min(cbmfs, cbmf_max), 0.) - - if(dpc%cbmf_d.lt.1.e-10) then - dpc%cbmf_d=0.; ocode=6; return - end if - - tmp = dpc%cbmf_d/ cbmf - ct1%tten = ct1%tten * tmp - ct1%qvten = ct1%qvten * tmp - ct1%qlten = ct1%qlten * tmp - ct1%qiten = ct1%qiten * tmp - ct1%qaten = ct1%qaten * tmp - ct1%qnten = ct1%qnten * tmp - ct1%uten = ct1%uten * tmp - ct1%vten = ct1%vten * tmp - ct1%pflx = ct1%pflx * tmp - ct1%hlflx = ct1%hlflx * tmp - ct1%qctflx= ct1%qctflx* tmp -! ct1%tevap = ct1%tevap * tmp -! ct1%qevap = ct1%qevap * tmp - ct1%rain = ct1%rain * tmp - ct1%snow = ct1%snow * tmp - ct1%denth = ct1%denth * tmp - -! call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, dpc%cbmf_d, cc%wrel, 10000.) -! call cumulus_tend_k(dpn, sd, cp1, ct1, do_coldT) - - end subroutine dpconv1 - - -!##################################################################### -!##################################################################### - - - subroutine dpconv2(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, sd1, ac1, & - cc1, cp1, ct1, cbmf_deep, ocode, ier, ermesg) - implicit none + dcapedm=(ac%cape-ac1%cape)/cbmf0 - type(deepc), intent(inout) :: dpc - type(cpnlist), intent(in) :: cpn - type(uw_params), intent(inout) :: Uw_p - type(sounding), intent(in) :: sd - type(adicloud), intent(inout) :: ac - logical, intent(in) :: do_coldT - logical, intent(in) :: do_ice - type(sounding), intent(inout) :: sd1 - type(adicloud), intent(inout) :: ac1 - type(cclosure), intent(inout) :: cc,cc1 - type(cplume), intent(inout) :: cp,cp1 - type(ctend), intent(inout) :: ct,ct1 - real, intent(inout) :: ocode, cbmf_deep - integer, intent(out) :: ier - character(len=256), intent(out) :: ermesg - - integer :: k, ksrc, n - real :: cbmf0, cbmfs, cbmf_max, dcape, scaleh, wrel, tmp, rkm - real :: cwfn_d, dcwfn, rat, ratsum, zcldtop - type(cpnlist) :: dpn - - call cpn_copy(cpn, dpn) - dpn % do_ppen = dpc % do_ppen - dpn % do_pevap = dpc % do_pevap - dpn % mixing_assumption = dpc % mixing_assumption - - if (ocode.ne.0) then + if (dcapedm .lt. dpc%dcapedm_th) then + cbmf_deep=0.; ocode=9; + call ct_clear_k(ct1); return + else + cbmf_deep= (ac%cape - dpc%cape_th) / dcapedm / (dpc%tau_dp/sd%delt) end if - call sd_copy_k(sd, sd1) - call extend_sd_k(sd1,sd%pblht, do_ice, Uw_p) - - dpc%cbmf_d = 0.; - dpc%cwfn_d = 0.; - dpc%rat = 0.; - dpc%rkm = 0.; - dpc%hgt = 0.; - scaleh = 0.; - ratsum = 0.; - cbmf0 = 0.0001; - wrel = cc%wrel; - rkm = dpc%rkm_dp(1); - zcldtop = sd%z(cp%ltop); - - do n=1, sd%kmax - scaleh = zcldtop - dpc%hgt(n) = scaleh - dpc%rkm(n) = rkm/scaleh - rat = dpc%rkm(n) - dpc%rat(n) = rat - - if (dpc%do_generation) then - do k=1,cp%ltop - sd1 % qv(k) = sd1 % qs(k) - end do - call extend_sd_k(sd1,sd%pblht, do_ice, Uw_p) - sd1 % thvtop(:) = sd % thvtop(:) - sd1 % thvbot(:) = sd % thvbot(:) - end if - - call cumulus_plume_k(dpn, sd1, ac, cp, rkm, cbmf0, wrel, scaleh, Uw_p, ier, ermesg) - if(cp%ltop.lt.cp%krel+2 .or. cp%let.le.cp%krel+1) then - dpc%cbmf_d=0.; ocode=6; return - end if - - zcldtop = sd%z(cp%ltop) - if (zcldtop.le.scaleh) then - exit - end if - - call cumulus_tend_k(dpn, sd, Uw_p, cp, ct, do_coldT) - - ct1%tten = ct1%tten + ct%tten * rat - ct1%qvten = ct1%qvten + ct%qvten * rat - ct1%qlten = ct1%qlten + ct%qlten * rat - ct1%qiten = ct1%qiten + ct%qiten * rat - ct1%qaten = ct1%qaten + ct%qaten * rat - ct1%qnten = ct1%qnten + ct%qnten * rat - ct1%uten = ct1%uten + ct%uten * rat - ct1%vten = ct1%vten + ct%vten * rat - ct1%tevap = ct1%tevap + ct%tevap * rat - ct1%qevap = ct1%qevap + ct%qevap * rat - ct1%pflx = ct1%pflx + ct%pflx * rat - ct1%hlflx = ct1%hlflx + ct%hlflx * rat - ct1%qctflx= ct1%qctflx+ ct%qctflx* rat - ct1%rain = ct1%rain + ct%rain * rat - ct1%snow = ct1%snow + ct%snow * rat - ct1%denth = ct1%denth + ct%denth * rat - - cp1%ufrc = cp1%ufrc + cp%ufrc * rat - cp1%qlu = cp1%qlu + cp%qlu * rat - cp1%qiu = cp1%qiu + cp%qiu * rat - cp1%qnu = cp1%qnu + cp%qnu * rat - cp1%umf = cp1%umf + cp%umf * rat - cp1%wu = cp1%wu + cp%wu * rat - cp1%fdrsat= cp1%fdrsat+ cp%fdrsat* rat - cp1%fdr = cp1%fdr + cp%fdr * rat - - tmp = maxval(cp%wu(:)) - dpc%cwfn_d= max(dpc%cwfn_d, tmp*tmp) - - ratsum = ratsum + rat - end do - - if (n > 1) then - rat = 1./ratsum - dpc%rat = dpc%rat*rat - ct1%tten = ct1%tten * rat - ct1%qvten = ct1%qvten * rat - ct1%qlten = ct1%qlten * rat - ct1%qiten = ct1%qiten * rat - ct1%qaten = ct1%qaten * rat - ct1%qnten = ct1%qnten * rat - ct1%uten = ct1%uten * rat - ct1%vten = ct1%vten * rat - ct1%tevap = ct1%tevap * rat - ct1%qevap = ct1%qevap * rat - ct1%pflx = ct1%pflx * rat - ct1%hlflx = ct1%hlflx * rat - ct1%qctflx= ct1%qctflx* rat - ct1%rain = ct1%rain * rat - ct1%snow = ct1%snow * rat - ct1%denth = ct1%denth * rat - - cp1%ufrc = cp1%ufrc * rat - cp1%qlu = cp1%qlu * rat - cp1%qiu = cp1%qiu * rat - cp1%qnu = cp1%qnu * rat - cp1%umf = cp1%umf * rat - cp1%wu = cp1%wu * rat - cp1%fdrsat= cp1%fdrsat* rat - cp1%fdr = cp1%fdr * rat - end if - - - if (dpc%ideep_closure.eq.0) then - cbmfs = cbmf_deep - else - call sd_copy_k(sd, sd1) - sd1 % t = sd1 % t + ct1%tten * sd%delt - sd1 % qv = sd1 % qv + ct1%qvten * sd%delt - sd1 % ql = sd1 % ql + ct1%qlten * sd%delt - sd1 % qi = sd1 % qi + ct1%qiten * sd%delt - sd1 % qa = sd1 % qa + ct1%qaten * sd%delt - sd1 % qn = sd1 % qn + ct1%qnten * sd%delt - sd1 % u = sd1 % u + ct1%uten * sd%delt - sd1 % v = sd1 % v + ct1%vten * sd%delt - call extend_sd_k(sd1,sd%pblht, do_ice, Uw_p) - ksrc=1 - call adi_cloud_k(sd1%zs(ksrc), sd1%ps(ksrc), sd1%hl(ksrc), sd1%thc(ksrc), sd1%qct(ksrc), & - sd1, Uw_p, .false., do_ice, ac1) - if (dpc%ideep_closure.eq.1) then - dcape = (ac%cape - ac1%cape)/cbmf0 - if (dcape <= 0.) then - dpc%cbmf_d=0.; ocode=6; return - end if - cbmfs = (ac%cape - dpc%cape_th) / dcape / (dpc%tau_dp/sd%delt) - else if (dpc%ideep_closure.eq.2) then - call cumulus_plume_k(dpn, sd1, ac1, cp, rkm, cbmf0, wrel, scaleh, Uw_p, ier, ermesg) - tmp = maxval(cp%wu(:)) - cwfn_d = tmp*tmp - dcwfn=(dpc%cwfn_d - cwfn_d) /cbmf0 - cbmfs = (dpc%cwfn_d - 0.) / dcwfn / (dpc%tau_dp/sd%delt) - end if - end if - - cbmf_max=(sd%ps(0) - sd%ps(cp%krel))*(0.25/sd%delt)/Grav - dpc%cbmf_d = max(min(cbmfs, cbmf_max), 0.) + cbmf_max = (sd%ps(0) - sd%ps(cp1%krel))*(dpc%frac_limit_d/sd%delt)/Grav + cbmf_deep = max(min(cbmf_deep, cbmf_max), 0.) - if(dpc%cbmf_d.lt.1.e-10) then - dpc%cbmf_d=0.; ocode=6; return + if(cbmf_deep.lt.1.e-10) then + cbmf_deep=0.; ocode=10; + call ct_clear_k(ct1); + return end if - tmp = dpc%cbmf_d/ cbmf0 - ct1%tten = ct1%tten * tmp - ct1%qvten = ct1%qvten * tmp - ct1%qlten = ct1%qlten * tmp - ct1%qiten = ct1%qiten * tmp - ct1%qaten = ct1%qaten * tmp - ct1%qnten = ct1%qnten * tmp - ct1%uten = ct1%uten * tmp - ct1%vten = ct1%vten * tmp - ct1%tevap = ct1%tevap * tmp - ct1%qevap = ct1%qevap * tmp - ct1%pflx = ct1%pflx * tmp - ct1%hlflx = ct1%hlflx * tmp - ct1%qctflx= ct1%qctflx* tmp - ct1%rain = ct1%rain * tmp - ct1%snow = ct1%snow * tmp - ct1%denth = ct1%denth * tmp - - cp1%ufrc = cp1%ufrc * tmp - cp1%umf = cp1%umf * tmp - - end subroutine dpconv2 + call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, cbmf_deep, wrel, zcldtop, Uw_p, ier, ermesg) + if(cp1%ltop.lt.cp1%krel+2 .or. cp1%let.le.cp1%krel+1) then + ocode=11; return + else + call cumulus_tend_k(dpn, sd, Uw_p, cp1, ct1, do_coldT) + end if + + end subroutine dpconv1 !##################################################################### !##################################################################### - subroutine dpconv3(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & - omeg_avg, rkm_sh, sd1, ac1, cp1, ct1, cbmf_deep, ocode, ier, ermesg) + subroutine dpconv2(dpc, dpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & + rkm_dp, cbmf_deep, sd1, ac1, cp1, ct1, ocode, ier, ermesg) implicit none type(deepc), intent(inout) :: dpc - type(cpnlist), intent(in) :: cpn + type(cpnlist), intent(inout) :: dpn type(uw_params), intent(inout) :: Uw_p type(sounding), intent(in) :: sd type(adicloud), intent(in) :: ac type(cclosure), intent(in) :: cc logical, intent(in) :: do_coldT logical, intent(in) :: do_ice - real, intent(in) :: rkm_sh, omeg_avg + type(cplume), intent(inout) :: cp + type(ctend), intent(inout) :: ct + real, intent(inout) :: rkm_dp, cbmf_deep type(sounding), intent(inout) :: sd1 type(adicloud), intent(inout) :: ac1 - type(cplume), intent(inout) :: cp, cp1 - type(ctend), intent(inout) :: ct, ct1 - real, intent(inout) :: cbmf_deep, ocode - integer, intent(out) :: ier - character(len=256), intent(out) :: ermesg - - type(cpnlist) :: dpn - real :: rkm_dp, zcldtop, cbmf0, dcapedm, cbmf_max, tmp - integer :: ksrc + type(cplume), intent(inout) :: cp1 + type(ctend), intent(inout) :: ct1 + real, intent(inout) :: ocode + integer, intent(out) :: ier + character(len=256), intent(out) :: ermesg + + real :: zcldtop, cbmf0, dcwfn, cwfn0, cwfn1, dpsum, cbmf_max, tmp + integer :: ksrc, k + ier = 0 + ermesg = ' ' zcldtop = sd%z(cp%ltop) - if ( (ocode.ne.0) .or. (ac%cape <= dpc%cape_th) .or. zcldtop < dpc%deepdepth) then - ocode=6; return - end if - call cpn_copy(cpn, dpn) - dpn % do_ppen = dpc % do_ppen - dpn % do_pevap = dpc % do_pevap - rkm_dp = dpc%rkm_dp(1) * rkm_sh + if ( (ocode.ne.0 .and. ocode.ne.4) .or. (cbmf_deep.eq.0) ) then + ocode=6; + return + end if cbmf0 = 0.0001 - call cp_clear_k(cp1); + call cp_clear_k(cp1); cp1%maxcldfrac=1.; call ct_clear_k(ct1); call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, cbmf0, cc%wrel, zcldtop, Uw_p, ier, ermesg) if(cp1%ltop.lt.cp1%krel+2 .or. cp1%let.le.cp1%krel+1) then - ocode=6; return + ocode=8; return else call cumulus_tend_k(dpn, sd, Uw_p, cp1, ct1, do_coldT) end if @@ -586,60 +325,51 @@ subroutine dpconv3(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & call extend_sd_k(sd1,sd%pblht, do_ice, Uw_p) + call ac_clear_k(ac1); ksrc=1 call adi_cloud_k(sd1%zs(ksrc), sd1%ps(ksrc), sd1%hl(ksrc), sd1%thc(ksrc), sd1%qct(ksrc), & sd1, Uw_p, .false., do_ice, ac1) - dcapedm=(ac%cape-ac1%cape)/cbmf0 + call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, cbmf_deep, cc%wrel, zcldtop, Uw_p, ier, ermesg) - if (dcapedm <= 0.) then - cbmf_deep=0.; ocode=6; return + cwfn0=0.; dpsum=0. + do k = cp%let,cp%ltop + cwfn0 = cwfn0 + cp%buo(k)*sd%dp(k) + dpsum = dpsum + sd%dp(k) + end do + cwfn0 = cwfn0 /dpsum + + cwfn1=0.; dpsum=0. + do k = cp1%let,cp1%ltop + cwfn1 = cwfn1 + cp%buo(k)*sd%dp(k) + dpsum = dpsum + sd%dp(k) + end do + cwfn1 = cwfn1 /dpsum + + dcwfn =(cwfn0 - cwfn1)/cbmf0 + + if (dcwfn <= 0.) then + cbmf_deep=0.; ocode=9; return else - cbmf_deep= (ac%cape - dpc%cape_th) / dcapedm / (dpc%tau_dp/sd%delt) + cbmf_deep= (cwfn0-0) / dcwfn / (dpc%tau_dp/sd%delt) end if - cbmf_max=(sd%ps(0) - sd%ps(cp%krel))*(0.25/sd%delt)/Grav + cbmf_max = (sd%ps(0) - sd%ps(cp%krel))*(dpc%frac_limit_d/sd%delt)/Grav cbmf_deep = max(min(cbmf_deep, cbmf_max), 0.) if(cbmf_deep.lt.1.e-10) then - cbmf_deep=0.; ocode=6; return + cbmf_deep=0.; ocode=10; + call ct_clear_k(ct1); + return end if call cumulus_plume_k(dpn, sd, ac, cp1, rkm_dp, cbmf_deep, cc%wrel, zcldtop, Uw_p, ier, ermesg) if(cp1%ltop.lt.cp1%krel+2 .or. cp1%let.le.cp1%krel+1) then - ocode=6; return + ocode=11; return else call cumulus_tend_k(dpn, sd, Uw_p, cp1, ct1, do_coldT) end if - end subroutine dpconv3 - - -!##################################################################### -!##################################################################### - -subroutine DEEP_CONV_INIT - -!--------------------------------------------------------------------- -! write version number and namelist to logfile. -!--------------------------------------------------------------------- - call write_version_number (version, tagname) -!--------------------------------------------------------------------- -! mark the module as initialized. -!--------------------------------------------------------------------- - module_is_initialized = .true. - - - -end subroutine DEEP_CONV_INIT -!##################################################################### -!##################################################################### -subroutine DEEP_CONV_END - - module_is_initialized = .false. - - -end subroutine DEEP_CONV_END - + end subroutine dpconv2 !##################################################################### !##################################################################### diff --git a/src/atmos_param/shallow_cu/null/uw_conv.F90 b/src/atmos_param/shallow_cu/null/uw_conv.F90 deleted file mode 100644 index 71c702a38e..0000000000 --- a/src/atmos_param/shallow_cu/null/uw_conv.F90 +++ /dev/null @@ -1,181 +0,0 @@ - -MODULE UW_CONV_MOD - - use Time_Manager_Mod, ONLY: time_type - use fms_mod, only : write_version_number, ERROR_MESG, FATAL - - use rad_utilities_mod, only : aerosol_type - - -!--------------------------------------------------------------------- - implicit none - private -!--------------------------------------------------------------------- -!----------- ****** VERSION NUMBER ******* --------------------------- - - character(len=128) :: version = '$Id: uw_conv.F90,v 18.0 2010/03/02 23:33:14 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - -!--------------------------------------------------------------------- -!------- interfaces -------- - - public :: uw_conv, uw_conv_init, uw_conv_end, calculate_uw_closure - - logical :: module_is_initialized = .false. - - character(len=7) :: mod_name = 'uw_conv' - -contains - -!##################################################################### -!##################################################################### - - SUBROUTINE UW_CONV_INIT( do_strat, axes, Time, kd, tracers_in_uw ) - logical, intent(in) :: do_strat - integer, intent(in) :: axes(4), kd - type(time_type), intent(in) :: Time - logical, intent(in) :: tracers_in_uw(:) - - call write_version_number (version, tagname) - module_is_initialized = .true. - call error_mesg('UW_CONV_INIT', & - 'This module is not supported as part of the public release', FATAL) - end SUBROUTINE UW_CONV_INIT - -!##################################################################### -!##################################################################### - - subroutine uw_conv_end - module_is_initialized = .FALSE. - call error_mesg('uw_conv_end', & - 'This module is not supported as part of the public release', FATAL) - end subroutine uw_conv_end - -!##################################################################### -!##################################################################### - - SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input - zint, q, omega, delt, pblht, ustar, bstar, qstar, land, coldT,& !input - asol, & !input - cush, do_strat, skip_calculation, max_available_cf, & !input - tten, qvten, qlten, qiten, qaten, qnten, & !output - uten, vten, rain, snow, & !output - cmf, hlflx, qtflx, pflx, liq_pflx, ice_pflx, cldql, cldqi, cldqa,cldqn, cbmfo, & !output - tracers, trtend, uw_wetdep) - -!CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -! -! SHALLOW CONVECTION SCHEME -! Described in Bretherton et. al (MWR, April 2004) -! For info contact Ming Zhao: ming.zhao@noaa.gov -! -! Inputs: see below -! -! Outputs: see below -! -!CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC - implicit none - - type(time_type), intent(in) :: Time - integer, intent(in) :: is, js - real, intent(in) :: delt - - real, intent(in), dimension(:,:,:) :: ub,vb !wind profile (m/s) - real, intent(in), dimension(:,:,:) :: zint !height@model interfaces(m) - real, intent(in), dimension(:,:,:) :: pint !pressure@model interfaces(pa) - real, intent(in), dimension(:,:,:) :: tb !temperature profile (K) - real, intent(in), dimension(:,:,:) :: qv !specific humidity profile (kg/kg) - real, intent(in), dimension(:,:,:,:) :: q !specific humidity profile (kg/kg) - real, intent(in), dimension(:,:,:) :: pmid !pressure@model mid-levels (pa) - real, intent(in), dimension(:,:,:) :: zmid !height@model mid-levels (m) - real, intent(in), dimension(:,:,:) :: omega !omega (Pa/s) - real, intent(in), dimension(:,:) :: land !land fraction - real, intent(in), dimension(:,:,:) :: max_available_cf ! largest - ! realizable value for uw cld frac - ! after accounting for deep cld frac - logical,intent(in), dimension(:,:) :: skip_calculation ! do not - ! calculate where .true. - logical,intent(in) :: do_strat !logical flag - logical,intent(in), dimension(:,:) :: coldT !logical flag - - real, intent(in), dimension(:,:) :: pblht, ustar, bstar, qstar !pbl height... - real, intent(inout), dimension(:,:) :: cush ! convective scale height (m) - - type(aerosol_type), intent (in) :: asol - - real, intent(out), dimension(:,:,:) :: tten,qvten ! T,qv tendencies - real, intent(out), dimension(:,:,:) :: qlten,qiten,qaten,qnten ! q tendencies - real, intent(out), dimension(:,:,:) :: uten,vten ! u,v tendencies - - real, intent(out), dimension(:,:,:) :: cldql,cldqi,cldqa, cldqn!in-updraft q - real, intent(out), dimension(:,:,:) :: cmf ! mass flux at level above layer (kg/m2/s) - real, intent(out), dimension(:,:,:) :: pflx ! precipitation flux removed from a layer - real, intent(out), dimension(:,:,:) :: liq_pflx ! liq precipitation flux removed from a layer - real, intent(out), dimension(:,:,:) :: ice_pflx ! solid precipitation flux removed from a layer - real, intent(out), dimension(:,:,:) :: hlflx ! theta_l flux - real, intent(out), dimension(:,:,:) :: qtflx ! qt flux - real, intent(out), dimension(:,:) :: rain, snow - real, intent(inout), dimension(:,:) :: cbmfo ! cloud-base mass flux - real, intent(in), dimension(:,:,:,:) :: tracers ! env. tracers - real, intent(out), dimension(:,:,:,:) :: trtend ! calculated tracer tendencies - real, intent(out), dimension(:,:,:) :: uw_wetdep ! calculated wet depostion for tracers - - call error_mesg('UW_CONV', & - 'This module is not supported as part of the public release', FATAL) - - END SUBROUTINE UW_CONV - -!##################################################################### -!##################################################################### - - - SUBROUTINE calculate_uw_closure(is, js, Time, tb, qv, ub, vb, pmid, & !input - pint, zmid, zint, q, omega, delt, pblht, ustar, bstar, qstar, & !input - land, coldT, asol, cush, & !input - cbmfo, & !output - tracers ) - -!CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC -! -! SHALLOW CONVECTION SCHEME -! Described in Bretherton et. al (MWR, April 2004) -! For info contact Ming Zhao: ming.zhao@noaa.gov -! -! Inputs: see below -! -! Outputs: see below -! -!CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC - implicit none - - type(time_type), intent(in) :: Time - integer, intent(in) :: is, js - real, intent(in) :: delt - - real, intent(in), dimension(:,:,:) :: ub,vb !wind profile (m/s) - real, intent(in), dimension(:,:,:) :: zint !height@model interfaces(m) - real, intent(in), dimension(:,:,:) :: pint !pressure@model interfaces(pa) - real, intent(in), dimension(:,:,:) :: tb !temperature profile (K) - real, intent(in), dimension(:,:,:) :: qv !specific humidity profile (kg/kg) - real, intent(in), dimension(:,:,:,:) :: q !specific humidity profile (kg/kg) - real, intent(in), dimension(:,:,:) :: pmid !pressure@model mid-levels (pa) - real, intent(in), dimension(:,:,:) :: zmid !height@model mid-levels (m) - real, intent(in), dimension(:,:,:) :: omega !omega (Pa/s) - real, intent(in), dimension(:,:) :: land !land fraction - logical,intent(in), dimension(:,:) :: coldT !logical flag - - real, intent(in), dimension(:,:) :: pblht, ustar, bstar, qstar !pbl height... - type(aerosol_type), intent (in) :: asol - real, intent(in ), dimension(:,:) :: cush ! convective scale height (m) - - - - real, intent(inout), dimension(:,:) :: cbmfo ! cloud-base mass flux - real, intent(in), dimension(:,:,:,:) :: tracers ! env. tracers - - call error_mesg('calculate_uw_closure', & - 'This module is not supported as part of the public release', FATAL) - END SUBROUTINE calculate_uw_closure - - -end MODULE UW_CONV_MOD diff --git a/src/atmos_param/shallow_cu/uw_conv.F90 b/src/atmos_param/shallow_cu/uw_conv.F90 index 2b75d05a07..f39c02edfa 100644 --- a/src/atmos_param/shallow_cu/uw_conv.F90 +++ b/src/atmos_param/shallow_cu/uw_conv.F90 @@ -39,7 +39,7 @@ MODULE UW_CONV_MOD cclosure_relaxwfn, & cclosure_implicit, cclosure - use deep_conv_mod,only : deepc, dpconv0, dpconv1, dpconv2, dpconv3 + use deep_conv_mod,only : deepc, cpn_copy, dpconv0, dpconv1, dpconv2 !--------------------------------------------------------------------- implicit none @@ -47,8 +47,8 @@ MODULE UW_CONV_MOD !--------------------------------------------------------------------- !----------- ****** VERSION NUMBER ******* --------------------------- - character(len=128) :: version = '$Id: uw_conv.F90,v 19.0 2012/01/06 20:26:04 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: uw_conv.F90,v 20.0 2013/12/13 23:21:41 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- !------- interfaces -------- @@ -66,7 +66,6 @@ MODULE UW_CONV_MOD ! 1: Emanuel-Rayment: quasiequilibrium PBL real :: rkm_sh = 16.0 ! fractional lateral mixing rate for shallow real :: cldhgt_max = 4.e3 - real :: cbmf_dp_frac = 0.0 real :: landfact_m = 0.0 integer :: idpchoice = 0 logical :: do_deep = .false. @@ -91,11 +90,22 @@ MODULE UW_CONV_MOD logical :: do_auto_aero = .false. logical :: do_rescale = .false. logical :: do_debug = .false. +!miz + logical :: do_imposing_cooling_drying = .false. + real :: tdt_rate = 0.0 + real :: qvdt_rate = 0.0 + real :: pres_min = 0.0 + real :: pres_max = 0.0 + logical :: do_imposing_rad_cooling = .false. + logical :: do_no_uw_conv = .false. + real :: cooling_rate = -1.5 !K/day + real :: t_thresh = 207.5 !K + real :: t_strato = 200.0 !K + real :: tau_rad = 5.0 !day +!miz integer :: cush_choice = 0 real :: pcp_min = 3e-5 real :: pcp_max = 1.5e-3 - real :: rhav_ocean = 0.8 - real :: rhav_land = 0.8 real :: rh0 = 0.8 real :: cush_ref = 0. real :: pblht0 = 500. @@ -107,15 +117,21 @@ MODULE UW_CONV_MOD real :: sea_salt_scale = 0.1 logical :: do_qctflx_zero = .false. logical :: do_detran_zero = .false. + logical :: do_gust_cv = .false. + real :: gustmax = 3.! maximum gustiness wind (m/s) + real :: gustconst = 10./86400. ! constant in kg/m2/sec, default = + ! 1 cm/day = 10 mm/day - NAMELIST / uw_conv_nml / iclosure, rkm_sh, cldhgt_max, cbmf_dp_frac, & + NAMELIST / uw_conv_nml / iclosure, rkm_sh, cldhgt_max, & do_deep, idpchoice, do_relaxcape, do_relaxwfn, do_coldT, do_lands, do_uwcmt, & do_fast, do_ice, do_ppen, do_forcedlifting, & atopevap, apply_tendency, prevent_unreasonable, aerol, gama, tkemin, & wmin_ratio, use_online_aerosol, use_sub_seasalt, landfact_m, pblht0, tke0, lofactor0, lochoice, & do_auto_aero, do_rescale, wrel_min, om_to_oc, sea_salt_scale, & do_debug, cush_choice, pcp_min, pcp_max, cush_ref, & - rhav_ocean, rhav_land, rh0, do_qctflx_zero, do_detran_zero + rh0, do_qctflx_zero, do_detran_zero, do_gust_cv, gustmax, gustconst, & + do_imposing_cooling_drying, tdt_rate, qvdt_rate, pres_min, pres_max, & + do_imposing_rad_cooling, do_no_uw_conv, cooling_rate, t_thresh, t_strato, tau_rad !namelist parameters for UW convective plume real :: rle = 0.10 ! for critical stopping distance for entrainment @@ -147,13 +163,14 @@ MODULE UW_CONV_MOD real :: hcevap = 0.8 logical :: do_weffect = .false. real :: weffect = 0.5 - real :: peff = 1.0 + real :: peff_l = 1.0 + real :: peff_i = 1.0 real :: t00 = 295 NAMELIST / uw_plume_nml / rle, rpen, rmaxfrac, wmin, rbuoy, rdrag, frac_drs, bigc, & auto_th0, auto_rate, tcrit, deltaqc0, do_pdfpcp, do_pmadjt, do_emmax, do_pnqv, rad_crit, emfrac_max, & mixing_assumption, mp_choice, Nl_land, Nl_ocean, qi_thresh, r_thresh, do_pevap, cfrac, hcevap, & - do_weffect, weffect, peff, t00 + do_weffect, weffect, peff_l, peff_i, t00 !namelist parameters for UW convective closure integer :: igauss = 1 ! options for cloudbase massflux closure ! 1: cin/gaussian closure, using TKE to compute CIN. @@ -167,23 +184,36 @@ MODULE UW_CONV_MOD !========Option for deep convection======================================= - real, dimension(7) :: rkm_dp - data rkm_dp / 0.302, 0.232, 0.168, 0.121, 0.092, 0.067, 0.030 / - real, dimension(7) :: rat_dp - data rat_dp / 0.292, 0.076, 0.102, 0.093, 0.088, 0.157, 0.192 / - integer :: ideep_closure = 0 + real :: rkm_dp1 = 10. + real :: rkm_dp2 = 1. + real :: cbmf_dp_frac1 = 0. + real :: cbmf_dp_frac2 = 1. + real :: crh_th_ocean = 100. + real :: crh_th_land = 100. + real :: cape_th = 0. + real :: tau_dp = 7200. + real :: rpen_d = 5.0 integer :: mixing_assumption_d = 0 - logical :: do_generation = .false. + integer :: norder = 1 logical :: do_ppen_d = .true. - logical :: do_pevap_d = .false. - real :: cape_th = 0. - real :: omeg_th = 0. - real :: tau_dp = 7200. - real :: rpen_d = 5.0 - - NAMELIST / deep_conv_nml / rkm_dp, rat_dp, ideep_closure, & - do_generation, cape_th, omeg_th, tau_dp, mixing_assumption_d, & - do_ppen_d, rpen_d, do_pevap_d + logical :: do_pevap_d = .true. + real :: cfrac_d = 0.05 + real :: hcevap_d = 0.8 + real :: dcapedm_th = 0 + real :: frac_limit_d = 0.25 + real :: lofactor_d = 1.0 + real :: auto_th0_d = 1.0e-3 + real :: tcrit_d = -120 + logical :: do_forcedlifting_d = .false. + logical :: do_lod_rkm = .false. + logical :: do_lod_cfrac = .false. + logical :: do_lod_tcrit = .false. + + NAMELIST / deep_conv_nml / rkm_dp1, rkm_dp2, cbmf_dp_frac1, cbmf_dp_frac2, & + crh_th_ocean, crh_th_land, do_forcedlifting_d, frac_limit_d, & + cape_th, tau_dp, rpen_d, mixing_assumption_d, norder, & + do_ppen_d, do_pevap_d, cfrac_d, hcevap_d, lofactor_d, dcapedm_th, & + auto_th0_d, tcrit_d, do_lod_rkm, do_lod_cfrac, do_lod_tcrit !========Option for deep convection======================================= !------------------------------------------------------------------------ @@ -197,11 +227,12 @@ MODULE UW_CONV_MOD id_qldt_uwc, id_qidt_uwc, id_qadt_uwc, id_qndt_uwc, id_cmf_uwc, id_wu_uwc, & id_fer_uwc, id_fdr_uwc, id_fdrs_uwc, id_cqa_uwc, id_cql_uwc, & id_cqi_uwc, id_cqn_uwc, id_hlflx_uwc, id_qtflx_uwc, & - id_cape_uwc, id_dcin_uwc, id_dcape_uwc, id_dwfn_uwc, id_rhav_uwc,& + id_cape_uwc, id_dcin_uwc, id_dcape_uwc, id_dwfn_uwc, id_crh_uwc,& id_ocode_uwc, id_plnb_uwc, id_wrel_uwc, id_ufrc_uwc, id_qtmp_uwc,& id_tdt_pevap_uwc, id_qdt_pevap_uwc, id_xhlsrc_uwc, id_xqtsrc_uwc,& id_qldet_uwc, id_qidet_uwc, id_qadet_uwc, id_qtdt_uwc, id_dting_uwc, & - id_cfq_uwc, id_fdp_uwc, id_hmo_uwc, id_hms_uwc, id_abu_uwc, id_peo_uwc + id_cfq_uwc, id_fdp_uwc, id_hmo_uwc, id_hms_uwc, id_abu_uwc, id_peo_uwc, & + id_tdt_rad_uwc integer, allocatable :: id_tracerdt_uwc(:), id_tracerdt_uwc_col(:), & @@ -213,8 +244,8 @@ MODULE UW_CONV_MOD id_qndt_uwd, id_qadt_uwd, id_cmf_uwd, id_wu_uwd, id_fer_uwd, & id_fdr_uwd, id_fdrs_uwd, id_cqa_uwd, id_cql_uwd, id_cqi_uwd, & id_cqn_uwd, id_hlflx_uwd, id_qtflx_uwd, id_dcin_uwd, & - id_dcape_uwd, id_dwfn_uwd, id_ocode_uwd, & - id_tdt_pevap_uwd, id_qdt_pevap_uwd + id_dcapedm_uwd, id_dwfn_uwd, id_ocode_uwd, & + id_tdt_pevap_uwd, id_qdt_pevap_uwd, id_rkm_uwd, id_cbu_uwd !========Option for deep convection======================================= type(cwetdep_type), dimension(:), allocatable :: wetdep @@ -406,8 +437,8 @@ SUBROUTINE UW_CONV_INIT(do_strat, axes, Time, kd, tracers_in_uw) 'CIN from uw_conv', 'm2/s2' ) id_cape_uwc= register_diag_field ( mod_name,'cape_uwc', axes(1:2), Time, & 'CAPE from uw_conv', 'm2/s2' ) - id_rhav_uwc= register_diag_field ( mod_name,'rhav_uwc', axes(1:2), Time, & - 'Vertically averaged RH from uw_conv', '%' ) + id_crh_uwc= register_diag_field ( mod_name,'crh_uwc', axes(1:2), Time, & + 'Column RH from uw_conv', '%' ) id_cbmf_uwc = register_diag_field (mod_name,'cbmf_uwc', axes(1:2), Time, & 'Cloud-base mass flux from uw_conv', 'kg/m2/s' ) id_wrel_uwc = register_diag_field (mod_name,'wrel_uwc', axes(1:2), Time, & @@ -465,6 +496,11 @@ SUBROUTINE UW_CONV_INIT(do_strat, axes, Time, kd, tracers_in_uw) 'Total water tendency from uw_conv', 'kg/kg/s', missing_value=mv) end if + if (do_imposing_rad_cooling) then + id_tdt_rad_uwc = register_diag_field ( mod_name, 'tdt_rad_uwc', axes(1:3), Time, & + 'Idealized radiative temperature tendency from uw_conv', 'K/s', missing_value=mv ) + end if + !========Option for deep convection======================================= if (do_deep) then id_tdt_pevap_uwd = register_diag_field ( mod_name, 'tdt_pevap_uwd', axes(1:3), Time, & @@ -482,6 +518,8 @@ SUBROUTINE UW_CONV_INIT(do_strat, axes, Time, kd, tracers_in_uw) 'Cloud vert. mass flux from deep_conv', 'kg/m2/s', missing_value=mv) id_wu_uwd = register_diag_field ( mod_name, 'wu_uwd', axes(1:3), Time, & 'Updraft vert. velocity from deep_conv', 'm/s', missing_value=mv) + id_cbu_uwd= register_diag_field ( mod_name, 'cbu_uwd', axes(1:3), Time, & + 'deep plume buoyancy', 'K', missing_value=mv) id_fer_uwd = register_diag_field ( mod_name, 'fer_uwd', axes(1:3), Time, & 'Fractional entrainment rate from deep_conv', '1/Pa', missing_value=mv) id_fdr_uwd = register_diag_field ( mod_name, 'fdr_uwd', axes(1:3), Time, & @@ -506,7 +544,7 @@ SUBROUTINE UW_CONV_INIT(do_strat, axes, Time, kd, tracers_in_uw) 'Frozen precip. rate from deep_conv', 'kg/m2/sec' ) id_cbmf_uwd = register_diag_field (mod_name,'cbmf_uwd', axes(1:2), Time, & 'Cloud-base mass flux from deep_conv', 'kg/m2/s' ) - id_dcape_uwd= register_diag_field (mod_name, 'dcape_uwd', axes(1:2), Time, & + id_dcapedm_uwd= register_diag_field (mod_name, 'dcapedm_uwd', axes(1:2), Time, & 'dCAPE/cbmf from deep_conv', 'm2/s2/(kg/m2/s)' ) id_dwfn_uwd = register_diag_field (mod_name, 'dwfn_uwd', axes(1:2), Time, & 'dwfn/cbmf from deep_conv', '(m2/s2)/(kg/m2/s)' ) @@ -514,6 +552,8 @@ SUBROUTINE UW_CONV_INIT(do_strat, axes, Time, kd, tracers_in_uw) 'Column-integrated enthalpy tendency from deep_conv', 'K/s' ) id_ocode_uwd = register_diag_field (mod_name,'ocode_uwd', axes(1:2), Time, & 'Out code from deep_conv', 'none' ) + id_rkm_uwd = register_diag_field (mod_name,'rkm_uwd', axes(1:2), Time, & + 'rkm for deep_conv', 'none' ) if ( do_strat ) then id_qldt_uwd= register_diag_field (mod_name,'qldt_uwd',axes(1:3),Time, & 'Liquid water tendency from deep_conv', 'kg/kg/s', missing_value=mv) @@ -639,8 +679,8 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input integer i, j, k, kl, klm, nk, naer, na, n real rhos0j - real hlsrc, thcsrc, qctsrc, tmp, lofactor - real zsrc, psrc, cbmf_shallow, cbmf_old, cbmf_deep, rkm_sh1, omeg_avg, dpsum + real hlsrc, thcsrc, qctsrc, tmp, lofactor, crh_th + real zsrc, psrc, cbmf_shallow, cbmf_old, cbmf_deep, rkm_sh1, rkm_dp, cbmf_dp_frac, dcrh, dcrh0, dpsum real, dimension(size(tb,1),size(tb,2)) :: & plcl, & ! pressure of lifting condensation level (Pa) plfc, & ! pressure of level of free convection (Pa) @@ -660,7 +700,8 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input ocode, & xhlsrc, & xqtsrc, & - rhavo, & + crho, & + rkm_d, & fdp real, dimension(size(tb,1),size(tb,2),size(tb,3)) :: wuo,fero,fdro,fdrso, tten_pevap, qvten_pevap @@ -671,9 +712,9 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input !========Option for deep convection======================================= real, dimension(size(tb,1),size(tb,2),size(tb,3)) :: uten_d, vten_d, tten_d, & - qvten_d, qlten_d, qiten_d, qaten_d, qnten_d, cmf_d, pflx_d, hlflx_d, qtflx_d, qtten_d, & + qvten_d, qlten_d, qiten_d, qaten_d, qnten_d, cmf_d, cbu_d, pflx_d, hlflx_d, qtflx_d, qtten_d, & wuo_d, fero_d, fdro_d, fdrso_d, cldql_d, cldqi_d, cldqa_d, cldqn_d, tten_pevap_d, qvten_pevap_d - real, dimension(size(tb,1),size(tb,2)) :: rain_d, snow_d, dcape_d, dwfn_d, denth_d, cbmf_d + real, dimension(size(tb,1),size(tb,2)) :: rain_d, snow_d, dcapedm_d, dwfn_d, denth_d, dting_d, dqtmp_d, cbmf_d !========Option for deep convection======================================= real, dimension(size(tb,3)) :: am1, am2, am3, am4, am5, qntmp @@ -685,6 +726,10 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input integer imax, jmax, kmax integer kd, ntracers + integer ktop_tmp, kbot_tmp + real :: tten_intg, qvten_intg + real, dimension(size(tb,3)) :: tten_tmp, qvten_tmp + real, dimension(size(tb,1),size(tb,2),size(tb,3)) :: tten_rad logical used type(sounding) :: sd, sd1 @@ -692,7 +737,7 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input type(cclosure) :: cc, cc1 type(cplume) :: cp, cp1 type(ctend) :: ct, ct1 - type(cpnlist) :: cpn + type(cpnlist) :: cpn,dpn type(deepc) :: dpc integer :: ier character(len=256) :: ermesg @@ -739,7 +784,8 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input cpn % Nl_ocean = Nl_ocean cpn % qi_thresh = qi_thresh cpn % r_thresh = r_thresh - cpn % peff = peff + cpn % peff_l = peff_l + cpn % peff_i = peff_i cpn % t00 = t00 cpn % rh0 = rh0 cpn % do_forcedlifting= do_forcedlifting @@ -767,7 +813,24 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input cpn%wetdep(:)%Lgas = wetdep(:)%Lgas cpn%wetdep(:)%Laerosol = wetdep(:)%Laerosol cpn%wetdep(:)%Lice = wetdep(:)%Lice + allocate ( dpn%tracername (ntracers) ) + allocate ( dpn%tracer_units (ntracers) ) + allocate ( dpn%wetdep (ntracers) ) + dpn%tracername(:) = tracername(:) + dpn%tracer_units(:) = tracer_units(:) + dpn%wetdep(:)%scheme = wetdep(:)%scheme + dpn%wetdep(:)%Henry_constant = wetdep(:)%Henry_constant + dpn%wetdep(:)%Henry_variable = wetdep(:)%Henry_variable + dpn%wetdep(:)%frac_in_cloud = wetdep(:)%frac_in_cloud + dpn%wetdep(:)%alpha_r = wetdep(:)%alpha_r + dpn%wetdep(:)%alpha_s = wetdep(:)%alpha_s + dpn%wetdep(:)%Lwetdep = wetdep(:)%Lwetdep + dpn%wetdep(:)%Lgas = wetdep(:)%Lgas + dpn%wetdep(:)%Laerosol = wetdep(:)%Laerosol + dpn%wetdep(:)%Lice = wetdep(:)%Lice endif + call cpn_copy(cpn, dpn) + cc % igauss = igauss cc % rkfre = rkfre cc % rmaxfrac = rmaxfrac @@ -775,16 +838,26 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input cc % rbuoy = rbuoy cc % tau_sh = tau_sh !========Option for deep convection======================================= - dpc % rkm_dp = rkm_dp - dpc % rat_dp = rat_dp - dpc % cape_th = cape_th - dpc % omeg_th = omeg_th - dpc % tau_dp = tau_dp - dpc % ideep_closure = ideep_closure - dpc % do_generation = do_generation - dpc % mixing_assumption = mixing_assumption_d - dpc % do_ppen = do_ppen_d - dpc % do_pevap = do_pevap_d + dpc % rkm_dp1 = rkm_dp1 + dpc % rkm_dp2 = rkm_dp2 + dpc % cbmf_dp_frac1 = cbmf_dp_frac1 + dpc % cbmf_dp_frac2 = cbmf_dp_frac2 + dpc % crh_th_ocean = crh_th_ocean + dpc % crh_th_land = crh_th_land + dpc % cape_th = cape_th + dpc % tau_dp = tau_dp + dpc % mixing_assumption_d = mixing_assumption_d + dpc % do_ppen_d = do_ppen_d + dpc % rpen_d = rpen_d + dpc % do_pevap_d = do_pevap_d + dpc % cfrac_d = cfrac_d + dpc % hcevap_d = hcevap_d + dpc % frac_limit_d = frac_limit_d + dpc % dcapedm_th = dcapedm_th + dpc % do_forcedlifting_d = do_forcedlifting_d + dpc % lofactor_d = lofactor_d + dpc % auto_th0_d = auto_th0_d + dpc % tcrit_d = tcrit_d !========Option for deep convection======================================= imax = size( tb, 1 ) jmax = size( tb, 2 ) @@ -806,7 +879,7 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input cino=0.; capeo=0.; tkeo=0.; wrelo=0.; ufrco=0.; zinvo=0.; wuo=0.; peo=0.; fero=0.; fdro=0.; fdrso=0.; cmf=0.; denth=0.; dqtmp=0.; ocode=0; dcapeo=0.; dcino=0.; dwfno=0.; xhlsrc=0.; xqtsrc=0.; fdp=0.; - trtend=0.; qldet=0.; qidet=0.; qadet=0.; rhavo=0.; hmo=0.; hms=0.; abu=0.; + trtend=0.; qldet=0.; qidet=0.; qadet=0.; crho=0.; hmo=0.; hms=0.; abu=0.; trwet = 0. dting = 0. @@ -817,11 +890,11 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input tten_d=0.; qvten_d=0.; qlten_d=0.; qiten_d=0.; qaten_d=0.; qnten_d=0.; uten_d=0.; vten_d =0.; rain_d =0.; snow_d =0.; qtten_d=0.; cldqa_d=0.; cldql_d=0.; cldqi_d=0.; cldqn_d=0.; - hlflx_d=0.; qtflx_d=0.; pflx_d=0.; + hlflx_d=0.; qtflx_d=0.; pflx_d=0.; wuo_d=0.; fero_d=0.; fdro_d=0.; fdrso_d=0.; - cmf_d=0.; - denth_d=0.; cbmf_d=0.; dcape_d=0.; dcino=0.; dwfn_d=0.; - tten_pevap_d=0.; qvten_pevap_d=0.; + cmf_d=0.; cbu_d=0.; + denth_d=0.; dting_d=0.; dqtmp_d=0.; cbmf_d=0.; dcapedm_d=0.; dcino=0.; dwfn_d=0.; + tten_pevap_d=0.; qvten_pevap_d=0.; rkm_d=0.; end if !========Option for deep convection======================================= @@ -848,6 +921,12 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input if (temp_1 .gt. 0.) temp_1 = 0.5*temp_1**(2./3.) tkeo(i,j) = MAX (tkemin, temp_1) + if (do_gust_cv) then + if (cbmfo(i,j)>0) then + tkeo(i,j) = tkeo(i,j)+(gustmax*sqrt(cbmfo(i,j)/(gustconst + cbmfo(i,j))))**2. + endif + endif + if (skip_calculation(i,j)) then ocode(i,j) = 6 go to 100 @@ -936,34 +1015,6 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input rkm_sh1 = rkm_sh * lofactor end if - if (cush_choice.eq.1) then - if (sd%land.gt.0.3) then - tmp=0; - do k=1,sd % ktoppbl - tmp=max(tmp, sd%hm(k)) - end do - do k=1,sd % ktoppbl - if (tmp.eq.sd%hm(k)) then - zsrc =sd%zs (k) - psrc =sd%ps (k) - thcsrc=sd%thc(k) - tmp = min(sd%qct(k)+gama*sd%qs(k), sd%qs(k)) - qctsrc=max(qctsrc, tmp) - hlsrc =sd%hl (k) - exit - end if - end do - sd%tke = max(sd%tke, tke0) - tkeo(i,j)=sd%tke - end if - else if (cush_choice.eq.2) then - lofactor = 1. - sd%land * (1. - lofactor0) - rkm_sh1=rkm_sh1*lofactor - else if (cush_choice.eq.6) then - lofactor = 1. - sd%land * (1. - lofactor0) - rkm_sh1=rkm_sh1*lofactor - end if - call adi_cloud_k(zsrc, psrc, hlsrc, thcsrc, qctsrc, sd, Uw_p, do_fast, do_ice, ac) ac % usrc = sd%u(sd%ktoppbl) ac % vsrc = sd%v(sd%ktoppbl) @@ -976,7 +1027,7 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input capeo(i,j) = ac%cape xhlsrc(i,j)= ac%hlsrc; xqtsrc(i,j)= ac%qctsrc; - rhavo(i,j) = sd%rhav; + crho(i,j) = sd%crh; do k = 1,kmax nk = kmax+1-k hmo (i,j,nk) = sd%hm(k); @@ -1018,7 +1069,6 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input wrelo(i,j) = cc%wrel ufrco(i,j) = cc%ufrc - if (.not.do_fast) then if (ac%klcl.eq.0 .or. ac%plcl.eq.sd%ps(1) .or. ac%plcl.lt.20000.) then ! if (ac%klcl.eq.0 .or. ac%plcl.lt.20000.) then @@ -1037,9 +1087,8 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input cpn%isdeep=.false. - cbmf_deep = min(cbmf_dp_frac * cc%cbmf * cc%cbmf / cc%wrel, cc%cbmf*0.9) - cbmf_shallow = cc%cbmf - cbmf_deep + cbmf_shallow = cc%cbmf ! - cbmf_deep cpn%do_ppen=do_ppen cpn%rpen =rpen call cumulus_plume_k(cpn, sd, ac, cp, rkm_sh1, cbmf_shallow, cc%wrel, cc%scaleh, Uw_p, ier, ermesg) @@ -1053,56 +1102,6 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input ocode(i,j)=5; goto 100 !cycle; end if - if (cush_choice.eq.6) then - do k=1,sd % kmax - tmp=cp%cush+sd%zs(0) - if ((tmp+1.-sd%zs(k))*(tmp+1.-sd%zs(k+1)).lt.0.) then - tmp = sd%p(k+1); exit - end if - end do - if (ac%plfc.gt.0.and.ac%plnb.gt.0.and.(ac%plfc-ac%plnb).gt.0.and.ac%plnb.lt.sd%ps(0)*0.5 & - .and.tmp.lt.ac%plfc.and.tmp.gt.ac%plnb.and.tmp.lt.sd%ps(0)) then - cpn%isdeep=.true. - cpn%do_ppen=do_ppen_d - cpn%rpen =rpen_d - rkm_sh1=max(rkm_dp(1)*(1.-(ac%plfc-tmp)/(ac%plfc-ac%plnb)),0.001) - - lofactor = 1. - sd%land * (1. - lofactor0) - rkm_sh1=rkm_sh1*lofactor - call cumulus_plume_k(cpn, sd, ac, cp, rkm_sh1, cbmf_shallow, cc%wrel, cc%scaleh, Uw_p, ier, ermesg) - if (ier /= 0) then - call error_mesg ('subroutine uw_conv cush_choice=6', ermesg, FATAL) - endif - - if(cp%ltop.lt.cp%krel+2 .or. cp%let.le.cp%krel+1) then - ocode(i,j)=4; goto 100 !cycle; - end if - if(cp%cldhgt.ge.cldhgt_max) then - ocode(i,j)=5; goto 100 !cycle; - end if - end if - elseif (cush_choice.eq.2) then - if ((ac%plfc-ac%plnb).gt.sd%ps(0) .and. (sd%rhav.gt.rh0)) then - cpn%isdeep=.true. - cpn%do_ppen=do_ppen_d - cpn%rpen =rpen_d - rkm_sh1 =rkm_dp(1) - lofactor = 1. - sd%land * (1. - lofactor0) - rkm_sh1=rkm_sh1*lofactor - call cumulus_plume_k(cpn, sd, ac, cp, rkm_sh1, cbmf_shallow, cc%wrel, cc%scaleh, Uw_p, ier, ermesg) - if (ier /= 0) then - call error_mesg ('subroutine uw_conv cush_choice=2', ermesg, FATAL) - endif - - if(cp%ltop.lt.cp%krel+2 .or. cp%let.le.cp%krel+1) then - ocode(i,j)=4; goto 100 !cycle; - end if - if(cp%cldhgt.ge.cldhgt_max) then - ocode(i,j)=5; goto 100 !cycle; - end if - end if - end if - if (cpn%isdeep .EQV. .true.) then fdp(i,j) = 1 else @@ -1116,14 +1115,6 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input call cumulus_tend_k(cpn, sd, Uw_p, cp, ct, do_coldT) -!test -! cpn%rpen = 0; -! cpn%do_ppen=do_ppen -! call cumulus_plume_k(cpn, sd, ac, cp1, rkm_sh1, cbmf_shallow, cc%wrel, cc%scaleh, Uw_p) -! call cumulus_tend_k(cpn, sd, Uw_p, cp1, ct1, do_coldT) -!test - - !========Unpack convective tendencies======================================== do k = 1,cp%ltop nk = kmax+1-k @@ -1179,31 +1170,51 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input !========Option for deep convection======================================= 100 if (do_deep) then + cbmf_deep = 0. + rkm_dp = 0. + tmp = max(min (sd%crh, 1.0), 0.0) + crh_th = sd%land*dpc%crh_th_land+(1.-sd%land)*dpc%crh_th_ocean + dcrh = tmp - crh_th + dcrh0 = 1.0001-crh_th + if (dcrh .gt. 0) then + dcrh = dcrh/dcrh0; + dcrh = dcrh**norder + rkm_dp = dpc%rkm_dp1 + dcrh * (dpc%rkm_dp2 -dpc%rkm_dp1) + cbmf_dp_frac = dpc%cbmf_dp_frac1+ dcrh * (dpc%cbmf_dp_frac2-dpc%cbmf_dp_frac1) + cbmf_deep = 1. !%cbmf_dp_frac * cc%cbmf + lofactor = 1. - sd%land * (1. - dpc%lofactor_d) + if (do_lod_rkm) then + rkm_dp = rkm_dp * lofactor + elseif (do_lod_cfrac) then + dpc % cfrac_d= dpc % cfrac_d * lofactor + elseif (do_lod_tcrit) then + dpc % tcrit_d= dpc % tcrit_d * lofactor + end if + end if + rkm_d(i,j) = rkm_dp; + + dpn % do_ppen = dpc % do_ppen_d + dpn % do_pevap = dpc % do_pevap_d + dpn % cfrac = dpc % cfrac_d + dpn % hcevap = dpc % hcevap_d + dpn % tcrit = dpc % tcrit_d + dpn % auto_th0 = dpc % auto_th0_d + dpn % mixing_assumption = dpc % mixing_assumption_d + dpn % do_forcedlifting = dpc % do_forcedlifting_d if (idpchoice.eq.0) then - omeg_avg=0.; dpsum=0. - do k = 1,sd%kmax - if (sd%p(k) .gt. 50000.) then - omeg_avg = omeg_avg + omega(i,j,k)*sd%dp(k) - dpsum = dpsum + sd%dp(k) - end if - end do - omeg_avg = omeg_avg/dpsum * 864. - call dpconv0(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, & - do_ice, omeg_avg, rkm_sh1, cp1, ct1, cbmf_deep, ocode(i,j), ier, ermesg) + call dpconv0(dpc, dpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & + rkm_dp, cbmf_deep, cp1, ct1, ocode(i,j), ier, ermesg) else if (idpchoice.eq.1) then - call dpconv1(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, & - do_ice, sd1, ac1, cc1, cp1, ct1, ocode(i,j), ier, ermesg) + call dpconv1(dpc, dpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & + rkm_dp, cbmf_deep, sd1, ac1, cp1, ct1, ocode(i,j), dcapedm_d(i,j), ier, ermesg) else if (idpchoice.eq.2) then - call dpconv2(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, & - do_ice, sd1, ac1, cc1, cp1, ct1, cbmf_deep, ocode(i,j), ier, ermesg) - else if (idpchoice.eq.3) then - call dpconv3(dpc, cpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, & - do_ice, omeg_avg, rkm_sh1, sd1, ac1, cp1, ct1, cbmf_deep, ocode(i,j), ier, ermesg) + call dpconv2(dpc, dpn, Uw_p, sd, ac, cc, cp, ct, do_coldT, do_ice, & + rkm_dp, cbmf_deep, sd1, ac1, cp1, ct1, ocode(i,j), ier, ermesg) end if if (ier /= 0) then - call error_mesg ('uw_conv calling dpconv', ermesg, FATAL) + call error_mesg ('uw_conv calling dpconv', ermesg, FATAL) endif - if(ocode(i,j).eq.6) cycle; + if(ocode(i,j).ge.6) cycle; do k = 1,kmax !cp1%ltop nk = kmax+1-k uten_d (i,j,nk) = ct1%uten (k) @@ -1222,7 +1233,8 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input cldql_d (i,j,nk) = cp1%qlu(k) cldqi_d (i,j,nk) = cp1%qiu(k) cldqn_d (i,j,nk) = cp1%qnu(k) - cmf_d (i,j,nk) = cp1%umf(k) + cmf_d (i,j,nk) = cp1%umf(k) + cp1%emf(k) + cbu_d (i,j,nk) = cp1%buo(k) tten_pevap_d (i,j,nk) = ct1%tevap (k) qvten_pevap_d(i,j,nk) = ct1%qevap (k) wuo_d (i,j,nk) = cp1%wu (k) @@ -1233,8 +1245,9 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input snow_d (i,j) = ct1%snow rain_d (i,j) = ct1%rain cbmf_d (i,j) = cbmf_deep - !denth_d (i,j) = ct1%denth - !dcape_d (i,j) = cc%dcape + denth_d (i,j) = ct1%denth + dting_d (i,j) = ct1%dting + dqtmp_d (i,j) = ct1%dqtmp !dwfn_d (i,j) = cc%dwfn !========Option for deep convection======================================= @@ -1251,6 +1264,8 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input hlflx (i,j,:) = hlflx (i,j,:) + hlflx_d (i,j,:) qtflx (i,j,:) = qtflx (i,j,:) + qtflx_d (i,j,:) cmf (i,j,:) = cmf (i,j,:) + cmf_d (i,j,:) + tten_pevap (i,j,:)=tten_pevap (i,j,:) + tten_pevap_d (i,j,:) + qvten_pevap(i,j,:)=qvten_pevap(i,j,:) + qvten_pevap_d(i,j,:) !wuo (i,j,:) = wuo (i,j,:) !fero (i,j,:) = fero (i,j,:) !fdro (i,j,:) = fdro (i,j,:) @@ -1260,12 +1275,67 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input !enddo snow (i,j) = snow (i,j) + snow_d (i,j) rain (i,j) = rain (i,j) + rain_d (i,j) - !denth (i,j) = denth (i,j) + denth (i,j) = denth (i,j) + denth_d (i,j) + dting (i,j) = dting (i,j) + dting_d (i,j) + dqtmp (i,j) = dqtmp (i,j) + dqtmp_d (i,j) !cbmfo (i,j) = cc%cbmf - !dcapeo(i,j) = cc%dcape !dwfno (i,j) = cc%dwfn end if !========Option for deep convection======================================= + if (do_no_uw_conv) then + uten (i,j,:)=0.; vten (i,j,:)=0.; + tten (i,j,:)=0.; qvten(i,j,:)=0.; + cmf (i,j,:)=0.; qlten(i,j,:)=0.; + qiten(i,j,:)=0.; qaten(i,j,:)=0.; + qnten(i,j,:)=0.; rain (i,j) =0.; snow(i,j)=0.; + endif + if (do_imposing_rad_cooling) then + tten_rad (i,j,:)=0; + do k = 1,sd%kmax + nk = kmax+1-k + if (sd%t(k)>t_thresh) then + tten_rad (i,j,nk) = cooling_rate/86400. + else + tten_rad (i,j,nk) = (t_strato-sd%t(k))/(tau_rad*86400.) + end if + enddo + end if + if (do_imposing_cooling_drying) then + kbot_tmp=1; + ktop_tmp=sd%kmax; + do k=1,sd%kmax + if (sd%p(k)>=7500) then + ktop_tmp=k + end if + if (sd%p(k)>=85000) then + kbot_tmp=k + end if + enddo + tten_tmp (:)=0; + qvten_tmp(:)=0; + do k = kbot_tmp,ktop_tmp + if (sd%p(k)>pres_min .and. sd%p(k)<=pres_max) then + tten_tmp (k)=tdt_rate/86400. + qvten_tmp(k)=qvdt_rate/86400. + end if + enddo +! tten_intg=0. +! qvten_intg=0. +! dpsum =0. +! do k = kbot_tmp,ktop_tmp +! tten_intg = tten_intg + tten_tmp (k)*sd%dp(k) +! qvten_intg = qvten_intg + qvten_tmp(k)*sd%dp(k) +! dpsum = dpsum + sd%dp(k) +! end do +! do k = kbot_tmp,ktop_tmp +! tten_tmp(k) = tten_tmp(k) - tten_intg / dpsum +! qvten_tmp(k)= qvten_tmp(k) - qvten_intg /dpsum +! end do + do k = 1,kmax + nk = kmax+1-k + tten_rad (i,j,nk) = tten_rad (i,j,nk) + tten_tmp (k) + end do + end if enddo enddo @@ -1281,6 +1351,9 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input if (_ALLOCATED ( cpn%tracername )) deallocate ( cpn%tracername ) if (_ALLOCATED ( cpn%tracer_units )) deallocate ( cpn%tracer_units ) if (_ALLOCATED ( cpn%wetdep )) deallocate ( cpn%wetdep ) + if (_ALLOCATED ( dpn%tracername )) deallocate ( dpn%tracername ) + if (_ALLOCATED ( dpn%tracer_units )) deallocate ( dpn%tracer_units ) + if (_ALLOCATED ( dpn%wetdep )) deallocate ( dpn%wetdep ) if (.not.do_uwcmt) then uten=0.; vten=0.; @@ -1395,12 +1468,13 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input used = send_data( id_hmo_uwc, hmo, Time, is, js, 1) used = send_data( id_hms_uwc, hms, Time, is, js, 1) used = send_data( id_abu_uwc, abu, Time, is, js, 1) - + used = send_data( id_tdt_rad_uwc,tten_rad*aday,Time, is, js, 1)!miz + used = send_data( id_prec_uwc, (rain+snow)*aday, Time, is, js ) used = send_data( id_snow_uwc, (snow)*aday, Time, is, js ) used = send_data( id_cin_uwc, (cino), Time, is, js ) used = send_data( id_cape_uwc, (capeo), Time, is, js ) - used = send_data( id_rhav_uwc, (rhavo), Time, is, js ) + used = send_data( id_crh_uwc, (crho), Time, is, js ) used = send_data( id_tke_uwc, (tkeo), Time, is, js ) used = send_data( id_cbmf_uwc, (cbmfo), Time, is, js ) used = send_data( id_wrel_uwc, (wrelo), Time, is, js ) @@ -1473,6 +1547,7 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input used=send_data( id_qdt_uwd, qvten_d*aday, Time, is, js, 1) used=send_data( id_qtdt_uwd, qtten_d*aday, Time, is, js, 1) used=send_data( id_cmf_uwd, cmf_d, Time, is, js, 1) + used=send_data( id_cbu_uwd, cbu_d, Time, is, js, 1) used=send_data( id_wu_uwd, wuo_d, Time, is, js, 1) used=send_data( id_fer_uwd, fero_d, Time, is, js, 1) used=send_data( id_fdr_uwd, fdro_d, Time, is, js, 1) @@ -1487,9 +1562,10 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input used=send_data( id_prec_uwd, (rain_d+snow_d)*aday,Time, is, js ) used=send_data( id_snow_uwd, (snow_d)*aday, Time, is, js ) used=send_data( id_cbmf_uwd, (cbmf_d), Time, is, js ) - used=send_data( id_dcape_uwd,(dcape_d), Time, is, js ) + used=send_data( id_dcapedm_uwd,(dcapedm_d), Time, is, js ) used=send_data( id_dwfn_uwd, (dwfn_d), Time, is, js ) used=send_data( id_enth_uwd, (denth_d), Time, is, js ) + used=send_data( id_rkm_uwd, (rkm_d), Time, is, js ) if ( do_strat ) then used=send_data( id_qldt_uwd, qlten_d*aday, Time, is, js, 1) @@ -1504,6 +1580,22 @@ SUBROUTINE uw_conv(is, js, Time, tb, qv, ub, vb, pmid, pint,zmid, & !input uten=0.; vten=0.; tten=0.; qvten=0.; cmf=0.; rain=0.; snow=0.; qlten=0.; qiten=0.; qaten=0.; qnten=0.; end if +!miz + if (do_imposing_rad_cooling) then + do j = 1, jmax + do i=1, imax + tten (i,j,:) = tten (i,j,:) + tten_rad (i,j,:) + end do + end do + end if +!miz + if (do_gust_cv) then + do j = 1, jmax + do i=1, imax + cbmfo(i,j) = rain(i,j) + snow(i,j) + end do + end do + end if END SUBROUTINE UW_CONV @@ -1522,9 +1614,9 @@ subroutine clearit(ac, cc, cp, ct, cp1, ct1) cc%wrel=0.; cc%ufrc=0.; cc%scaleh=0.; - call cp_clear_k(cp) + call cp_clear_k(cp); cp%maxcldfrac =1.; call ct_clear_k(ct); - call cp_clear_k(cp1); + call cp_clear_k(cp1); cp1%maxcldfrac=1.; call ct_clear_k(ct1); end subroutine clearit diff --git a/src/atmos_param/shallow_physics/shallow_physics.F90 b/src/atmos_param/shallow_physics/shallow_physics.F90 deleted file mode 100644 index 6d6c8bb23a..0000000000 --- a/src/atmos_param/shallow_physics/shallow_physics.F90 +++ /dev/null @@ -1,228 +0,0 @@ -module shallow_physics_mod -use mpp_mod, only: input_nml_file - -use fms_mod, only: open_namelist_file, file_exist, & - close_file, check_nml_error, & - error_mesg, FATAL, WARNING, & - write_version_number, stdlog, & - mpp_pe, mpp_root_pe - -use time_manager_mod, only: time_type - -implicit none -private - -!======================================================================== - -public :: shallow_physics_init, & - shallow_physics, & - shallow_physics_end - -interface shallow_physics_init - module procedure shallow_physics_init_1d, shallow_physics_init_2d -end interface -!======================================================================== -! version information -character(len=128) :: version = '$Id: shallow_physics.F90,v 19.0 2012/01/06 20:26:06 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' -!======================================================================== - -real, allocatable, dimension(:,:) :: h_eq - -real :: kappa_m, kappa_t - -logical :: module_is_initialized = .false. - -!======================================================================== -! namelist - -real :: fric_damp_time = -20.0 -real :: therm_damp_time = -10.0 -real :: h_0 = 3.e04 -real :: h_monsoon = 2.e04 -real :: lon_monsoon = 90.0 -real :: lat_monsoon = 25.0 -real :: width_monsoon = 15.0 -real :: h_itcz = 1.e05 -real :: width_itcz = 4.0 -logical :: no_forcing = .false. - -namelist /shallow_physics_nml/ fric_damp_time, therm_damp_time, & - h_0, h_monsoon, width_monsoon, & - lon_monsoon, lat_monsoon, & - width_itcz, h_itcz, no_forcing - -contains - -!======================================================================== - -subroutine shallow_physics_init_2d (axes, Time, lon, lat) -integer, intent(in) :: axes(4) -type(time_type), intent(in) :: Time -real, intent(in) :: lon(:,:), lat(:,:) ! longitude and latitude in radians - -integer :: i, j, unit, ierr, io, logunit -real :: xm, ym, dm, di -real :: lon_m, lat_m, width_m, width_i, deg2rad - -! cannot initialize the module more than once - if (module_is_initialized) then - call error_mesg ('shallow_physics_init', & - 'module has already been initialized ', FATAL) - endif - -! read the namelist -#ifdef INTERNAL_FILE_NML - read (input_nml_file, nml=shallow_physics_nml, iostat=io) - ierr = check_nml_error(io,"shallow_physics_nml") -#else - if (file_exist('input.nml')) then - unit = open_namelist_file () - ierr=1 - do while (ierr /= 0) - read (unit, nml=shallow_physics_nml, iostat=io, end=10) - ierr = check_nml_error (io, 'shallow_physics_nml') - enddo - 10 call close_file (unit) - endif -#endif - -! write version info and namelist to logfile - - call write_version_number (version, tagname) - logunit = stdlog() - write(logunit,nml=shallow_physics_nml) - -! damping times < 0 are in days (convert to seconds) - - if (fric_damp_time < 0.0) fric_damp_time = - fric_damp_time*86400 - if (therm_damp_time < 0.0) therm_damp_time = - therm_damp_time*86400 - -! compute damping coefficients - - kappa_m = 0.0 - kappa_t = 0.0 - if ( fric_damp_time .ne. 0.0) kappa_m = 1./fric_damp_time - if (therm_damp_time .ne. 0.0) kappa_t = 1./therm_damp_time - -! global storage - - allocate ( h_eq(size(lon,1),size(lon,2)) ) - -! convert namelist variables in degrees to radians - - deg2rad = acos(0.0)/90. - lon_m = lon_monsoon * deg2rad - lat_m = lat_monsoon * deg2rad - width_m = width_monsoon * deg2rad - width_i = width_itcz * deg2rad - -! compute constants - - do j = 1, size(lon,2) - do i = 1, size(lon,1) - xm = (lon(i,j) - lon_m)/(width_m*2.) - ym = (lat(i,j) - lat_m)/width_m - dm = xm*xm + ym*ym - di = (lat(i,j)/width_i)**2 - h_eq(i,j) = h_0 + h_monsoon*max(1.e-10, exp(-dm)) + h_itcz*exp(-di) - enddo - enddo - - module_is_initialized = .true. - -end subroutine shallow_physics_init_2d - -!======================================================================= - -subroutine shallow_physics_init_1d (axes, Time, lon, lat) -integer, intent(in) :: axes(4) -type(time_type), intent(in) :: Time -real, intent(in) :: lon(:), lat(:) ! longitude and latitude in radians - -real, dimension(size(lon),size(lat)) :: lon2, lat2 - - lon2 = spread(lon,2,size(lat)) - lat2 = spread(lat,1,size(lon)) - call shallow_physics_init_2d (axes, Time, lon2, lat2) - -end subroutine shallow_physics_init_1d - -!======================================================================= - -subroutine shallow_physics ( is, ie, js, je, timelev, dt, Time, & - um, vm, hm, u, v, h, u_dt, v_dt, h_dt ) - -integer, intent(in) :: is, ie, js, je, timelev -real, intent(in) :: dt -type(time_type), intent(in) :: Time -real, intent(in) , dimension(is:ie,js:je) :: um, vm, hm, u, v, h -real, intent(inout), dimension(is:ie,js:je) :: u_dt, v_dt, h_dt - -integer :: i, j - - if (.not.module_is_initialized) then - call error_mesg ('shallow_physics', & - 'module has not been initialized ', FATAL) - endif - - if (no_forcing) return - -! choose which time level is used to compute forcing - - select case (timelev) - case(-1) - ! previous time level (tau-1) - do j = js, je - do i = is, ie - u_dt(i,j) = u_dt(i,j) - kappa_m * um(i,j) - v_dt(i,j) = v_dt(i,j) - kappa_m * vm(i,j) - h_dt(i,j) = h_dt(i,j) - kappa_t * (hm(i,j) - h_eq(i,j)) - enddo - enddo - case(0) - ! current time level (tau) - do j = js, je - do i = is, ie - u_dt(i,j) = u_dt(i,j) - kappa_m * u(i,j) - v_dt(i,j) = v_dt(i,j) - kappa_m * v(i,j) - h_dt(i,j) = h_dt(i,j) - kappa_t * (h(i,j) - h_eq(i,j)) - enddo - enddo - case(+1) - ! next time level (tau+1) - do j = js, je - do i = is, ie - u_dt(i,j) = u_dt(i,j)*(1.-kappa_m*dt) - kappa_m * um(i,j) - v_dt(i,j) = v_dt(i,j)*(1.-kappa_m*dt) - kappa_m * vm(i,j) - h_dt(i,j) = h_dt(i,j)*(1.-kappa_t*dt) - kappa_t * (hm(i,j)-h_eq(i,j)) - enddo - enddo - case default - call error_mesg ('shallow_physics', & - 'invalid value for timelev argument', FATAL) - end select - -end subroutine shallow_physics - -!====================================================================== - -subroutine shallow_physics_end - - if (.not.module_is_initialized) then - call error_mesg ('shallow_physics_end', & - 'module has not been initialized ', WARNING) - return - endif - -! release global storage - - deallocate ( h_eq ) - - module_is_initialized = .false. - -end subroutine shallow_physics_end - -!====================================================================== - -end module shallow_physics_mod diff --git a/src/atmos_param/stable_bl_turb/stable_bl_turb.F90 b/src/atmos_param/stable_bl_turb/stable_bl_turb.F90 index f4f8770958..c1caebf199 100644 --- a/src/atmos_param/stable_bl_turb/stable_bl_turb.F90 +++ b/src/atmos_param/stable_bl_turb/stable_bl_turb.F90 @@ -21,7 +21,7 @@ MODULE STABLE_BL_TURB_MOD !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% character(len=128) :: version = '$Id: stable_bl_turb.F90,v 19.0 2012/01/06 20:26:08 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/atmos_param/strat_cloud/aerosol_cloud.F90 b/src/atmos_param/strat_cloud/aerosol_cloud.F90 index 8abb39ea40..569bbec333 100644 --- a/src/atmos_param/strat_cloud/aerosol_cloud.F90 +++ b/src/atmos_param/strat_cloud/aerosol_cloud.F90 @@ -5,7 +5,7 @@ MODULE aerosol_cloud_mod check_nml_error, close_file, & write_version_number, file_exist, & stdlog -use constants_mod, ONLY : grav, cp_air, rdgas, rvgas +use constants_mod, ONLY : grav, cp_air, rdgas, rvgas, tfreeze use rad_utilities_mod, ONLY : aerosol_type use mpp_mod, only : mpp_clock_id, mpp_clock_begin, & mpp_clock_end, CLOCK_LOOP, & @@ -37,8 +37,8 @@ MODULE aerosol_cloud_mod !-------------------------------------------------------------------------- !---version number--------------------------------------------------------- -Character(len=128) :: Version = '$Id: aerosol_cloud.F90,v 19.0 2012/01/06 20:26:09 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: aerosol_cloud.F90,v 20.0 2013/12/13 23:21:48 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !-------------------------------------------------------------------------- !---namelist--------------------------------------------------------------- @@ -85,6 +85,7 @@ MODULE aerosol_cloud_mod aero_loop2, aero_loop3 logical :: module_is_initialized = .false. +real :: missing_value = -1.e30 CONTAINS @@ -138,7 +139,9 @@ subroutine aerosol_cloud_init (Constants) !------------------------------------------------------------------------- ! define offset into aerosol activation tables. !------------------------------------------------------------------------- - IF (.NOT. Constants%do_mg_microphys .AND. reproduce_rk) THEN + IF (.NOT. (Constants%do_mg_microphys .OR. & + Constants%do_mg_ncar_microphys) & + .AND. reproduce_rk) THEN wpdf_offs =0 ELSE wpdf_offs = 1 @@ -290,6 +293,7 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & do i = 1,idim if ( (Nml%do_pdf_clouds) .or. & (Constants%do_mg_microphys) .or. & + (Constants%do_mg_ncar_microphys) .or. & (up_strat(i,j,k) >= 0.0) ) then thickness(i,j,k) = Atmos_state%deltpg(i,j,k)/ & Atmos_state%airdens(i,j,k) @@ -298,10 +302,8 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & Atmos_state%diff_t(i,j,min(k+1,KDIM)))/& thickness(i,j,k) )**2 wp2(i,j,k) = MAX (wp2t(i,j,k), Nml%var_limit**2) - if(diag_id%debug2_3d > 0) & - diag_4d(i,j,k,diag_pt%debug2_3d) = wp2(i,j,k)**0.5 - if(diag_id%debug3_3d > 0) & - diag_4d(i,j,k,diag_pt%debug3_3d) = 1. + if(diag_id%subgrid_w_variance > 0) & + diag_4d(i,j,k,diag_pt%subgrid_w_variance) = wp2(i,j,k)**0.5 call aer_ccn_act_wpdf_m & (Atmos_state%T_in(i,j,k), Atmos_state%pfull(i,j,k), & @@ -329,7 +331,7 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & !------------------------------------------------------------------------ ! ice nuclei activation may only occur at temps below -5 C. !------------------------------------------------------------------------ - if (Atmos_state%T_in(i,j,k) .LT. 268.15) then + if (Atmos_state%T_in(i,j,k) .LT. tfreeze - 5.) then !----------------------------------------------------------------------- ! place a lower limit on the velocity pdf variance, if desired. @@ -371,6 +373,10 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & qvt(i,j,k) = Atmos_state%qv_in(i,j,k) ENDIF END IF + + if (qvt(i,j,k) .LE. 0.0) then + qvt(i,j,k) = MAX(Atmos_state%qv_in(i,j,k), Nml%qmin) + endif u_i(i,j,k) = qvt(i,j,k)/qvsi(i,j,k) u_l(i,j,k) = qvt(i,j,k)/qvsl(i,j,k) @@ -383,10 +389,12 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & u_i(i,j,k) .gt. 200. ) then write(otun,*) " +++++++++++++++++++++++ " write(otun,*) " i,j,k ,u_i ", i,j,k,u_i(i,j,k) - write(otun,*) " qs, qvsi , qv ", & + write(otun,*) " qs, qvsi , qvt, qv ", & Atmos_state%qs(i,j,k), qvsi(i,j,k), & - Atmos_state%qv_in(i,j,k) - write(otun,*) " cf ", cf(i,j,k) + qvt(i,j,k), Atmos_state%qv_in(i,j,k) + write(otun,*) " cf, ahuco,qa_upd,qrat ", cf(i,j,k), & + Atmos_state%ahuco(i,j,k), & + qa_upd(i,j,k), Atmos_state%qrat(i,j,k) write(otun,*) " qv(i,k) - cf * qs(i,k), (1-cf) " , & Atmos_state%qv_in(i,j,k) - & cf(i,j,k)*Atmos_state%qs(i,j,k), & @@ -411,6 +419,9 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & ni_sulf(i,j,k) = 0. ni_dust(i,j,k) = 0. ni_bc (i,j,k) = 0. + cf(i,j,k) = missing_value + u_i(i,j,k) = missing_value + u_l(i,j,k) = missing_value endif !------------------------------------------------------------------------- @@ -450,20 +461,19 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & !------------------------------------------------------------------------- ! define various desired diagnostics. !------------------------------------------------------------------------- - if(diag_id%debug3_3d > 0) & - diag_4d(:,:,:,diag_pt%debug3_3d) = Particles%drop1 if ( diag_id%imass7 > 0 ) & diag_4d(:,:,:,diag_pt%imass7) = imass1(:,:,:,7) - if(diag_id%debug4_3d > 0) & - diag_4d(:,:,:,diag_pt%debug4_3d) = Particles%crystal1 + if(diag_id%potential_crystals > 0) & + diag_4d(:,:,:,diag_pt%potential_crystals) = & + Particles%crystal1 if ( diag_id%rhcrit > 0 ) & - diag_4d(:,:,:,diag_pt%rhcrit) = ATmos_state%rh_crit + diag_4d(:,:,:,diag_pt%rhcrit) = 100.*Atmos_state%rh_crit if ( diag_id%rhcrit_min > 0 ) & - diag_4d(:,:,:,diag_pt%rhcrit_min) = Atmos_state%rh_crit_min + diag_4d(:,:,:,diag_pt%rhcrit_min) = 100.*Atmos_state%rh_crit_min if ( diag_id%ndust1 > 0 ) & diag_4d(:,:,:,diag_pt%ndust1) = Nfact_du1 * imass1(:,:,:,8) @@ -497,6 +507,11 @@ subroutine aerosol_cloud (idim, jdim, kdim, n_diag_4d, Nml, Constants, & if ( diag_id%rhlin > 0 ) diag_4d(:,:,:,diag_pt%rhlin) = u_l END IF ! do_ice_nucl_wpdf + + if(diag_id%potential_droplets > 0) & + diag_4d(:,:,:,diag_pt%potential_droplets) = & + Particles%drop1 + call mpp_clock_end (aero_loop3) end if ! (do_liq_num) @@ -797,16 +812,19 @@ subroutine aerosol_effects (idim,jdim,kdim,n_diag_4d, phalf, airdens, T, & totalmass1(i,j,k,3) end if if (diag_id%sulfate > 0) then - diag_4d(i,j,k, diag_pt%sulfate) = 0.7273*totalmass1(i,j,k,1)/ & + diag_4d(i,j,k, diag_pt%sulfate) = & + 0.7273*totalmass1(i,j,k,1)/ & pthickness(i,j,k)*1.0e9 endif if (diag_id%seasalt_sub > 0) then - diag_4d(i,j,k,diag_pt%seasalt_sub) = concen_ss_sub(i,j,k)/ & + diag_4d(i,j,k,diag_pt%seasalt_sub) = & + concen_ss_sub(i,j,k)/ & pthickness(i,j,k)*1.0e9 endif if (diag_id%seasalt_sup > 0) then - diag_4d(i,j,k, diag_pt%seasalt_sup) = concen_ss_sup(i,j,k)/ & + diag_4d(i,j,k, diag_pt%seasalt_sup) = & + concen_ss_sup(i,j,k)/ & pthickness(i,j,k)*1.0e9 endif end do @@ -898,6 +916,8 @@ subroutine aerosol_effects (idim,jdim,kdim,n_diag_4d, phalf, airdens, T, & do k=1,kdim do j=1,jdim do i=1,idim +!RSH the 1.0e12 factor here is to counter the 1.0e-12 factor applied +! above to totalmass1. The 1.0e9 factor (kg -> ug) is already in totalmass1. diag_4d(i,j,k,diag_pt%om) = totalmass1(i,j,k,2)*1.0e12 end do end do diff --git a/src/atmos_param/strat_cloud/check_nan.F90 b/src/atmos_param/strat_cloud/check_nan.F90 index 888adfc7b3..d0daf4d03e 100644 --- a/src/atmos_param/strat_cloud/check_nan.F90 +++ b/src/atmos_param/strat_cloud/check_nan.F90 @@ -12,8 +12,8 @@ MODULE check_nan_mod public check_nan, check_nan_init !---------------version number--------------------------- -Character(len=128) :: Version = '$Id: check_nan.F90,v 19.0 2012/01/06 20:26:10 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: check_nan.F90,v 20.0 2013/12/13 23:21:50 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------- @@ -136,6 +136,7 @@ subroutine check_nan_0d (inv, name) character(len=*), intent(in) :: name integer :: outunit + !------------------------------------------------------------------------ outunit = stdout() if (inv .ne. inv) then diff --git a/src/atmos_param/strat_cloud/cldwat2m_micro.F90 b/src/atmos_param/strat_cloud/cldwat2m_micro.F90 new file mode 100644 index 0000000000..a0eb70d98b --- /dev/null +++ b/src/atmos_param/strat_cloud/cldwat2m_micro.F90 @@ -0,0 +1,6063 @@ +#ifdef CAM_COMPATIBLE_MICROP +#undef GFDL_COMPATIBLE_MICROP +#else +#define GFDL_COMPATIBLE_MICROP +#endif +#ifdef GFDL_COMPATIBLE_MICROP +module cldwat2m_micro_mod +#else +module cldwat2m_micro +#endif + +!------------------------------------------------------------------------- +! Purpose: +! CAM Interface for microphysics +! +! Author: Andrew Gettelman, Hugh Morrison. +! Contributions from: Xiaohong Liu and Steve Ghan +! December 2005-May 2010 +! Description in: Morrison and Gettelman, 2008. J. Climate (MG2008) +! Gettelman et al., 2010 J. Geophys. Res. - Atmospheres +! (G2010) +! for questions contact Hugh Morrison, Andrew Gettelman +! e-mail: morrison@ucar.edu, andrew@ucar.edu +!------------------------------------------------------------------------- +! modification for sub-columns, HM, (orig 8/11/10) +! This is done using the logical 'sub_column' set to .true. = subcolumns +!------------------------------------------------------------------------- +#ifdef GFDL_COMPATIBLE_MICROP +! Interfaces, diagnostics, used modules, constants modified for use in GFDL +!based models +! Huan Guo and Rick Hemler, 2010 - 2012 +!-------------------------------------------------------------------------- +#endif + +#ifdef GFDL_COMPATIBLE_MICROP + use constants_mod, only: grav, rdgas, rvgas, cp_air, hlv, & + hlf, hls, tfreeze + use strat_cloud_utilities_mod, only: diag_id_type, diag_pt_type, & + strat_nml_type + use mpp_mod, only: input_nml_file + use fms_mod, only: mpp_pe, file_exist, error_mesg, & + open_namelist_file, FATAL, & + stdlog, write_version_number, & + check_nml_error, close_file, & + mpp_root_pe + use simple_pdf_mod, only: simple_pdf +#else + use shr_kind_mod, only: r8=>shr_kind_r8 + use spmd_utils, only: masterproc + use ppgrid, only: pcols, pver, pverp + use physconst, only: gravit, rair, tmelt, cpair, rh2o, rhoh2o + use physconst, only: latvap, latice + use wv_saturation, only: cp, polysvp, epsqs, vqsatd_water + use cam_history, only: addfld, add_default, phys_decomp, outfld, & + fillvalue + use cam_logfile, only: iulog + use phys_control, only: phys_getopts + use cldwat2m_macro, only: rhmini +#endif + + implicit none + private + public :: ini_micro, mmicro_pcond, gamma, mmicro_end + save + +#ifdef GFDL_COMPATIBLE_MICROP +!------------------------------------------------------------------------ +!--version number-------------------------------------------------------- + +character(len=128) :: Version = '$Id: cldwat2m_micro.F90,v 20.0 2013/12/13 23:21:51 fms Exp $' +character(len=128) :: Tagname = '$Name: tikal $' + + +INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6,30) +INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(14,300) +INTEGER, PARAMETER :: r8 = dp +#endif +!#else + +! logical, public :: liu_in = .true. ! True = Liu et al 2007 Ice nucleation +! ! False = cooper fixed ice nucleation (MG2008) + + +!#ifdef GFDL_COMPATIBLE_MICROP +!INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6,30) +!INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(14,300) +!INTEGER, PARAMETER :: r8 = dp +!#endif + +!constants remapped +real(r8), private:: g !gravity +real(r8), private:: r !Dry air Gas constant +real(r8), private:: rv !water vapor gas contstant +real(r8), private:: cpp !specific heat of dry air +real(r8), private:: rhow !density of liquid water +real(r8), private:: xxlv ! latent heat of vaporization +real(r8), private:: xlf !latent heat of freezing +real(r8), private:: xxls !latent heat of sublimation + +#ifndef GFDL_COMPATIBLE_MICROP +real(r8), private:: rhosn ! bulk density snow +#endif +real(r8), private:: rhoi ! bulk density ice + +real(r8), private:: ac,bc,as,bs,ai,bi,ar,br !fall speed parameters +real(r8), private:: ci,di !ice mass-diameter relation parameters +real(r8), private:: cs,ds !snow mass-diameter relation parameters +real(r8), private:: cr,dr !drop mass-diameter relation parameters +real(r8), private:: f1s,f2s !ventilation param for snow +real(r8), private:: Eii !collection efficiency aggregation of ice +real(r8), private:: Ecc !collection efficiency +real(r8), private:: Ecr !collection efficiency cloud droplets/rain +real(r8), private:: f1r,f2r !ventilation param for rain +#ifndef GFDL_COMPATIBLE_MICROP +real(r8), private:: DCS !autoconversion size threshold +#endif +real(r8), private:: qsmall !min mixing ratio +real(r8), private:: bimm,aimm !immersion freezing +real(r8), private:: rhosu !typical 850mn air density +real(r8), private:: mi0 ! new crystal mass +real(r8), private:: rin ! radius of contact nuclei +real(r8), private:: qcvar ! 1/relative variance of sub-grid qc +real(r8), private:: pi ! pi + +! Additional constants to help speed up code + +real(r8), private:: cons1 +real(r8), private:: cons2 +real(r8), private:: cons3 +real(r8), private:: cons4 +real(r8), private:: cons5 +real(r8), private:: cons6 +real(r8), private:: cons7 +real(r8), private:: cons8 +real(r8), private:: cons9 +real(r8), private:: cons10 +real(r8), private:: cons11 +real(r8), private:: cons12 +real(r8), private:: cons13 +real(r8), private:: cons14 +real(r8), private:: cons15 +real(r8), private:: cons16 +real(r8), private:: cons17 +real(r8), private:: cons18 +real(r8), private:: cons19 +real(r8), private:: cons20 +real(r8), private:: cons21 +real(r8), private:: cons22 +real(r8), private:: cons23 +real(r8), private:: cons24 +real(r8), private:: cons25 +real(r8), private:: cons27 +real(r8), private:: cons28 + +real(r8), private:: lammini +real(r8), private:: lammaxi +real(r8), private:: lamminr +real(r8), private:: lammaxr +real(r8), private:: lammins +real(r8), private:: lammaxs + +real(r8), private:: tmax_fsnow ! max temperature for transition to + ! convective snow +real(r8), private:: tmin_fsnow ! min temperature for transition to + ! convective snow + +real(r8), private:: tt0 ! Freezing temperature + +real(r8), private:: csmin,csmax,minrefl,mindbz + +!real(r8), private:: Berg_factor = 1._r8 + + +#ifdef GFDL_COMPATIBLE_MICROP + +real :: dcs = 400.e-6_r8 !autoconversion size threshold +real :: min_diam_ice = 10.e-6_r8 +logical :: allow_all_cldtop_collection = .false. +logical :: rho_factor_in_max_vt = .true. +real :: max_rho_factor_in_vt = 1.0 +real :: lowest_temp_for_sublimation = 180._r8 +real :: rhosn = 100._r8 +!--> cjg: modifications incorporated from Huan's code +logical :: allow_rain_num_evap = .false. +real :: accretion_scale = 1.0_r8 +!<--cjg + +!-->cjg: imposed cloud or ice number +logical, private:: nccons = .false. ! nccons = true to specify constant cloud droplet number +logical, private:: nicons = .false. ! nicons = true to specify constant cloud ice number +real(r8), private:: ncnst = 100.e6 ! specified value (m-3) droplet num concentration (in-cloud not grid-mean) +real(r8), private:: ninst = 0.1e6 ! specified value (m-3) ice num concentration (in-cloud not grid-mean) +!<--cjg + +logical :: use_qcvar_in_accretion = .false. +real(r8), private :: qcvar_min4accr = 0.1 +real(r8), private :: qcvar_max4accr = 0.5 +real(r8), private :: accretion_scale_max = 2.0 +real(r8), private :: accr_scale + +! <---h1g, 2012-06-12 +logical :: liu_in = .false. ! True = Liu et al 2007 Ice nucleation + ! False = cooper fixed ice nucleation + ! (MG2008) +namelist / cldwat2m_micro_nml / & + dcs, min_diam_ice, & + allow_all_cldtop_collection, & + max_rho_factor_in_vt, & + rho_factor_in_max_vt, lowest_temp_for_sublimation, & +! lowest_temp_for_sublimation, & +!--> cjg: modifications incorporated from Huan's code + allow_rain_num_evap, accretion_scale, & +!<--cjg + rhosn, & ! h1g + nccons, ncnst, & ! cjg + nicons, ninst, & ! cjg + liu_in, & ! h1g + use_qcvar_in_accretion, & ! h1g + qcvar_min4accr, & ! h1g + qcvar_max4accr, & ! h1g + accretion_scale_max ! h1g + + +real(r8), private, parameter :: tmelt = tfreeze +real(r8), private:: rhmini = 0.80_r8 ! Minimum rh for ice + ! cloud fraction +real(r8), private, parameter :: epsqs = rdgas/rvgas +!real(r8),parameter :: d378 = 1. - epsqs +real(r8), private, parameter :: d378 = 1. - epsqs +#else +logical, public :: liu_in = .true. ! True = Liu et al 2007 Ice nucleation + ! False = cooper fixed ice nucleation + ! (MG2008) +#endif + +contains + +!========================================================================= + +#ifdef GFDL_COMPATIBLE_MICROP +subroutine ini_micro (qcvar_in) + +real, intent(in) :: qcvar_in + +#else +subroutine ini_micro +#endif + +!----------------------------------------------------------------------- +! +! Purpose: +! initialize constants for the morrison microphysics +! called from stratiform.F90 +! +! Author: Andrew Gettelman Dec 2005 +! +!----------------------------------------------------------------------- + + +#ifdef GFDL_COMPATIBLE_MICROP + INTEGER :: unit, io, ierr, logunit +#endif + +#ifndef GFDL_COMPATIBLE_MICROP + integer k + + integer l,m, iaer + real(r8) surften ! surface tension of water w/respect to air (N/m) + real(r8) arg + + character(len=16) :: eddy_scheme = ' ' + logical :: history_microphysics ! output variables for + ! microphysics diagnostics + ! package + + ! Query the PBL eddy scheme + call phys_getopts(eddy_scheme_out = eddy_scheme, & + history_microphysics_out = history_microphysics ) + + ! diagnostic precip + call addfld ('QRAIN ','kg/kg ',pver, 'A', & + 'Diagnostic grid-mean rain mixing ratio', phys_decomp) + call addfld ('QSNOW ','kg/kg ',pver, 'A', & + 'Diagnostic grid-mean snow mixing ratio', phys_decomp) + call addfld ('NRAIN ','m-3 ',pver, 'A', & + 'Diagnostic grid-mean rain number conc' ,phys_decomp) + call addfld ('NSNOW ','m-3 ',pver, 'A', & + 'Diagnostic grid-mean snow number conc' ,phys_decomp) + + ! size of precip + call addfld ('RERCLD ','m ',pver, 'A', & + 'Diagnostic effective radius of Liquid Cloud and Rain' , & + phys_decomp) + + call addfld ('DSNOW ','m ',pver, 'A', & + 'Diagnostic grid-mean snow diameter',phys_decomp) + + ! diagnostic radar reflectivity, cloud-averaged + call addfld ('REFL ','DBz ',pver, 'A','94 GHz radar reflectivity', & + phys_decomp) + call addfld ('AREFL ','DBz ',pver, 'A', & + 'Average 94 GHz radar reflectivity',phys_decomp) + call addfld ('FREFL ','fraction ',pver, 'A', & + 'Fractional occurance of radar reflectivity' ,phys_decomp) + + call addfld ('CSRFL ','DBz ',pver, 'A', & + '94 GHz radar reflectivity (CloudSat thresholds)' , & + phys_decomp) + call addfld ('ACSRFL ','DBz ',pver, 'A', & + 'Average 94 GHz radar reflectivity (CloudSat thresholds)',& + phys_decomp) + call addfld ('FCSRFL ','fraction ',pver, 'A', & + 'Fractional occurance of radar reflectivity & + &(CloudSat thresholds)' ,phys_decomp) + + call addfld ('AREFLZ ','mm^6/m^3 ',pver, 'A', & + 'Average 94 GHz radar reflectivity',phys_decomp) + + ! Aerosol information + call addfld ('NCAL ','#/m3 ',pver, 'A', & + 'Number Concentation Activated for Liquid',phys_decomp) + call addfld ('NCAI ','#/m3 ',pver, 'A', & + 'Number Concentation Activated for Ice',phys_decomp) + + + ! Average rain and snow mixing ratio (Q), number (N) and diameter (D), with frequency + call addfld ('AQRAIN ','kg/kg ',pver, 'A', & + 'Average rain mixing ratio' ,phys_decomp) + call addfld ('AQSNOW ','kg/kg ',pver, 'A', & + 'Average snow mixing ratio' ,phys_decomp) + call addfld ('ANRAIN ','m-3 ',pver, 'A', & + 'Average rain number conc' ,phys_decomp) + call addfld ('ANSNOW ','m-3 ',pver, 'A', & + 'Average snow number conc' ,phys_decomp) + call addfld ('ADRAIN ','Micron ',pver, 'A', & + 'Average rain effective Diameter',phys_decomp) + call addfld ('ADSNOW ','Micron ',pver, 'A', & + 'Average snow effective Diameter' ,phys_decomp) + call addfld ('FREQR ','fraction ',pver, 'A', & + 'Fractional occurance of rain' ,phys_decomp) + call addfld ('FREQS ','fraction ',pver, 'A', & + 'Fractional occurance of snow' ,phys_decomp) + + if ( history_microphysics) then + call add_default ('AQSNOW ', 1, ' ') + call add_default ('FREQR ', 1, ' ') + call add_default ('FREQS ', 1, ' ') + call add_default ('AQRAIN ', 1, ' ') + call add_default ('AQSNOW ', 1, ' ') + call add_default ('ANRAIN ', 1, ' ') + call add_default ('ANSNOW ', 1, ' ') + end if + +#endif + +!declarations for morrison codes (transforms variable names): + +#ifdef GFDL_COMPATIBLE_MICROP + + qcvar = qcvar_in + +!obtain constants from constants_mod when in FMS + g = grav !gravity + r = rdgas !Dry air Gas constant: + ! note units(phys_constants are in J/K/kmol) + rv= rvgas !water vapor gas contstant + cpp=cp_air !specific heat of dry air + rhow = 1000.0_r8 !density of liquid water + +! latent heats + xxlv = hlv !latent heat vaporization + xlf = hlf !latent heat freezing + xxls = hls !latent heat of sublimation + +!--------------------------------------------------------------- +! process namelist +!--------------------------------------------------------------- +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=cldwat2m_micro_nml, iostat=io) + ierr = check_nml_error(io,'cldwat2m_micro_nml') +#else + if ( file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1; do while (ierr /= 0) + read (unit, nml=cldwat2m_micro_nml, iostat=io, end=10) + ierr = check_nml_error(io,'cldwat2m__micro_nml') + enddo +10 call close_file (unit) + endif +#endif + +!----------------------------------------------------------------------- +! write version and namelist to stdlog. +!----------------------------------------------------------------------- + call write_version_number (version, tagname) + logunit = stdlog() + if (mpp_pe() == mpp_root_pe()) & + write (logunit, nml=cldwat2m_micro_nml) +#else + g= gravit !gravity + r= rair !Dry air Gas constant: + ! note units(phys_constants are in J/K/kmol) + rv= rh2o !water vapor gas contstant + cpp = cpair !specific heat of dry air + rhow = rhoh2o !density of liquid water + rhosn = 250._r8 !bulk density snow (++ ceh) + +! latent heats + + xxlv = latvap ! latent heat vaporization + xlf = latice ! latent heat freezing + xxls = xxlv + xlf ! latent heat of sublimation +#endif + + +! parameters for snow/rain fraction for convective clouds + + tmax_fsnow = tmelt + tmin_fsnow = tmelt - 5._r8 + +! parameters below from Reisner et al. (1998) +! density parameters (kg/m3) + + rhoi = 500._r8 ! bulk density ice + rhow = 1000._r8 ! bulk density liquid + + +! fall speed parameters, V = aD^b +! V is in m/s + +! droplets + ac = 3.e7_r8 + bc = 2._r8 + +! snow + as = 11.72_r8 + bs = 0.41_r8 + +! cloud ice + ai = 700._r8 + bi = 1._r8 + +! rain + ar = 841.99667_r8 + br = 0.8_r8 + +! particle mass-diameter relationship +! currently we assume spherical particles for cloud ice/snow +! m = cD^d + + pi= 3.1415927_r8 + +! cloud ice mass-diameter relationship + + ci = rhoi*pi/6._r8 + di = 3._r8 + +! snow mass-diameter relationship + + cs = rhosn*pi/6._r8 + ds = 3._r8 + +! drop mass-diameter relationship + + cr = rhow*pi/6._r8 + dr = 3._r8 + +! ventilation parameters for snow +! hall and prupacher + + f1s = 0.86_r8 + f2s = 0.28_r8 + +! collection efficiency, aggregation of cloud ice and snow + + Eii = 0.1_r8 + +! collection efficiency, accretion of cloud water by rain + + Ecr = 1.0_r8 + +! ventilation constants for rain + + f1r = 0.78_r8 + f2r = 0.32_r8 + +! autoconversion size threshold for cloud ice to snow (m) + +#ifndef GFDL_COMPATIBLE_MICROP + Dcs = 400.e-6_r8 +#endif + +! smallest mixing ratio considered in microphysics + + qsmall = 1.e-14_r8 + +! immersion freezing parameters, bigg 1953 + + bimm = 100._r8 + aimm = 0.66_r8 + +! typical air density at 850 mb + rhosu = 85000._r8/(r * tmelt) +!#ifdef GFDL_COMPATIBLE_MICROP +! rhosu = 85000._r8/(rdgas * tmelt) +!#else +! rhosu = 85000._r8/(rair * tmelt) +!#endif + +! mass of new crystal due to aerosol freezing and growth (kg) + +#ifndef GFDL_COMPATIBLE_MICROP + mi0 = 4._r8/3._r8*pi*rhoi*(10.e-6_r8)*(10.e-6_r8)*(10.e-6_r8) +#else + mi0 = 4._r8/3._r8*pi*rhoi*(min_diam_ice)*(min_diam_ice)*(min_diam_ice) +#endif + +! radius of contact nuclei aerosol (m) + + rin = 0.1e-6_r8 + +! 1 / relative variance of sub-grid cloud water distribution +! see morrison and gettelman, 2007, J. Climate for details + +#ifndef GFDL_COMPATIBLE_MICROP + qcvar = 2._r8 +#endif + +! freezing temperature + tt0=tmelt + +#ifndef GFDL_COMPATIBLE_MICROP + pi=4._r8*atan(1.0_r8) +#endif + +!Range of cloudsat reflectivities (dBz) for analytic simulator + csmin= -30._r8 + csmax= 26._r8 + mindbz = -99._r8 +! minrefl = 10._r8**(mindbz/10._r8) + minrefl = 1.26e-10_r8 + +! Define constants to help speed up code (limit calls to gamma function) + + cons1=gamma(1._r8+di) + cons2=gamma(qcvar+2.47_r8) + cons3=gamma(qcvar) + cons4=gamma(1._r8+br) + cons5=gamma(4._r8+br) + cons6=gamma(1._r8+ds) + cons7=gamma(1._r8+bs) + cons8=gamma(4._r8+bs) + cons9=gamma(qcvar+2._r8) + cons10=gamma(qcvar+1._r8) + cons11=gamma(3._r8+bs) + cons12=gamma(qcvar+1.15_r8) + cons13=gamma(5._r8/2._r8+br/2._r8) + cons14=gamma(5._r8/2._r8+bs/2._r8) + cons15=gamma(qcvar+bc/3._r8) + cons16=gamma(1._r8+bi) + cons17=gamma(4._r8+bi) + cons18=qcvar**2.47_r8 + cons19=qcvar**2 + cons20=qcvar**1.15_r8 + cons21=qcvar**(bc/3._r8) + cons22=(4._r8/3._r8*pi*rhow*(25.e-6_r8)**3) + cons23=dcs**3 + cons24=dcs**2 + cons25=dcs**bs + cons27=xxlv**2 + cons28=xxls**2 + +#ifdef GFDL_COMPATIBLE_MICROP + lammaxi = 1._r8/min_diam_ice + lammaxs = 1._r8/min_diam_ice +#else + lammaxi = 1._r8/10.e-6_r8 + lammaxs = 1._r8/10.e-6_r8 +#endif + lammini = 1._r8/(2._r8*dcs) + lammaxr = 1._r8/20.e-6_r8 + lamminr = 1._r8/500.e-6_r8 + lammins = 1._r8/2000.e-6_r8 + + return + +end subroutine ini_micro + +!========================================================================= +!microphysics routine for each timestep goes here... + + +#ifdef GFDL_COMPATIBLE_MICROP +subroutine mmicro_pcond (dqa_activation, total_activation, & + tiedtke_macrophysics, sub_column,& + j, jdim, pver, pcols, ncol, deltatin, tn, & + qn, qc_in, qi_in, nc_in, ni_in, p, pdel, cldn, & + liqcldf, icecldf, delta_cf, & + D_eros_l4, nerosc4, D_eros_i4, nerosi4, dqcdt, & + dqidt, naai, npccnin, rndst, nacon, & + tlat, qvlat, qctend, qitend, nctend, nitend,& + prect, preci, rflx, sflx, & + qrout,qsout, lsc_rain_size, lsc_snow_size, & + f_snow_berg, Nml, qa0, gamma_mg, SA_0, SA, & + ssat_disposal, n_diag_4d, diag_4d, diag_id, & + diag_pt, do_clubb, qcvar_clubb) + +logical, intent(in) :: dqa_activation +logical, intent(in) :: total_activation +logical, intent(in) :: tiedtke_macrophysics +logical, intent(in) :: sub_column ! True = configure for sub-columns + ! False = use w/o sub-columns (standard) +integer, intent(in) :: j, jdim +integer, intent(in) :: pver, pcols +integer, intent(in) :: ncol +real(r8), intent(in) :: deltatin ! time step (s) +real(r8), intent(in) :: tn(pcols,pver) ! input temperature (K) +real(r8), intent(in) :: qn(pcols,pver) ! input h20 vapor mixing ratio + ! (kg/kg) +! note: all input cloud variables are grid-averaged +real(r8), intent(in) :: qc_in(pcols,pver) ! cloud water mixing ratio + ! (kg/kg) +real(r8), intent(in) :: qi_in(pcols,pver) ! cloud ice mixing ratio (kg/kg) +real(r8), intent(in) :: nc_in(pcols,pver) ! grid-average cloud water number + ! conc (#/kg) +real(r8), intent(in) :: ni_in(pcols,pver) ! grid-average cloud ice number + ! conc (#/kg) +real(r8), intent(in) :: p(pcols,pver) ! air pressure (pa) +real(r8), intent(in) :: pdel(pcols,pver) ! pressure difference across + ! level (pa) +real(r8), intent(inout) :: cldn(pcols,pver) + ! cloud fraction +real(r8), intent(in) :: liqcldf(pcols,pver) ! liquid cloud fraction +real(r8), intent(in) :: icecldf(pcols,pver) ! ice cloud fraction +real(r8), intent(in) :: delta_cf(pcols,pver) ! +real(r8), intent(inout) :: D_eros_l4(pcols,pver) ! +real(r8), intent(in) :: nerosc4 (pcols,pver) ! +real(r8), intent(inout) :: D_eros_i4(pcols,pver) ! +real(r8), intent(in) :: nerosi4 (pcols,pver) ! +real(r8), intent(in) :: dqcdt (pcols,pver) ! +real(r8), intent(in) :: dqidt (pcols,pver) ! +real(r8), intent(in) :: naai(pcols,pver) ! ice nulceation number +real(r8), intent(in) :: npccnin(pcols,pver) ! ccn activated number +real(r8), intent(in) :: rndst(pcols,pver,4) ! radius of 4 dust bins for + ! contact freezing +real(r8), intent(in) :: nacon(pcols,pver,4) ! number in 4 dust bins for + ! contact freezing +real(r8), intent(out) :: tlat(pcols,pver) ! latent heating rate (W/kg) +real(r8), intent(out) :: qvlat(pcols,pver) ! microphysical tendency qv + ! (1/s) +real(r8), intent(out) :: qctend(pcols,pver) ! microphysical tendency qc + ! (1/s) +real(r8), intent(out) :: qitend(pcols,pver) ! microphysical tendency qi + ! (1/s) +real(r8), intent(out) :: nctend(pcols,pver) ! microphysical tendency nc + ! (1/s) +real(r8), intent(out) :: nitend(pcols,pver) ! microphysical tendency ni + ! (1/s) +real(r8), intent(out) :: prect(pcols) ! surface precip rate (m/s) +real(r8), intent(out) :: preci(pcols) ! cloud ice/snow precip rate + ! (m/s) +real(r8), intent(out) :: rflx(pcols,pver+1) ! grid-box average rain flux + ! (kg m^-2 s^-1) +real(r8), intent(out) :: sflx(pcols,pver+1) ! grid-box average snow flux + ! (kg m^-2 s^-1) +real(r8), intent(out) :: qrout(pcols,pver) ! grid-box average rain + ! mixing ratio (kg/kg) +real(r8), intent(out) :: qsout(pcols,pver) ! snow mixing ratio (kg/kg) +real(r8), intent(out) :: lsc_rain_size(pcols,pver) ! raindrop effective + ! size (diameter) + ! (micron) +real(r8), intent(out) :: lsc_snow_size(pcols,pver) ! snow flake effective + ! size (diameter) + ! (micron) +real(r8), intent(out) :: f_snow_berg (pcols,pver) ! ratio of bergeron + ! production of qi to + ! sum of bergeron, + ! riming and freezing +type(strat_nml_type), intent(in) :: Nml +real(r8), intent(in) :: qa0(pcols,pver) ! +real(r8), intent(in) :: gamma_mg(pcols,pver) ! +real(r8), intent(in) :: SA_0 (pcols,pver) ! +real(r8), intent(inout) :: SA (pcols,pver) ! +real(r8), intent(out) :: ssat_disposal(pcols,pver) + ! disposition of supersaturation at end + ! of step; 0.= no ssat, 1.= liq, 2.=ice) +INTEGER,INTENT(IN) :: n_diag_4d +REAL, dimension( ncol, jdim, pver, 0:n_diag_4d ), INTENT(INOUT) :: diag_4d +TYPE(diag_id_type),INTENT(IN) :: diag_id +TYPE(diag_pt_type),INTENT(INout) :: diag_pt + +! --> h1g, 2012-10-05 + integer, intent(in), optional :: do_clubb + real(r8), intent(in), optional :: qcvar_clubb(pcols,pver) +! <-- h1g, 2012-10-05 + +#else + +subroutine mmicro_pcond ( sub_column, & + lchnk, ncol, deltatin, tn, & + qn, qc, qi, & + nc, ni, p, pdel, cldn, & + liqcldf, icecldf, & + cldo, & + rate1ord_cw2pr_st, & + naai, npccnin, rndst,nacon, & + tlat, qvlat, & + qctend, qitend, nctend, nitend, effc, & + effc_fn, effi, prect, preci, & + nevapr, evapsnow, & + prain, prodsnow, cmeout, deffi, pgamrad, & + lamcrad,qsout,dsout, & + rflx,sflx, qrout,reff_rain,reff_snow, & + qcsevap,qisevap,qvres,cmeiout, & + vtrmc,vtrmi,qcsedten,qisedten, & + prao,prco,mnuccco,mnuccto,msacwio,psacwso,& + bergso,bergo,melto,homoo,qcreso,prcio,praio,qireso,& + mnuccro,pracso,meltsdt,frzrdt,mnuccdo) + + logical, intent(in) :: sub_column ! True = configure for sub-columns + ! False = use w/o sub-columns + ! (standard) + integer, intent(in) :: lchnk + integer, intent(in) :: ncol + real(r8), intent(in) :: deltatin ! time step (s) + real(r8), intent(in) :: tn(pcols,pver) ! input temperature (K) + real(r8), intent(in) :: qn(pcols,pver) ! input h20 vapor mixing ratio + ! (kg/kg) + real(r8), intent(inout) :: qc(pcols,pver) ! cloud water mixing ratio + ! (kg/kg) + real(r8), intent(inout) :: qi(pcols,pver) ! cloud ice mixing ratio + ! (kg/kg) + real(r8), intent(inout) :: nc(pcols,pver) ! cloud water number conc + ! (1/kg) + real(r8), intent(inout) :: ni(pcols,pver) ! cloud ice number conc + ! (1/kg) + real(r8), intent(in) :: p(pcols,pver) ! air pressure (pa) + real(r8), intent(in) :: pdel(pcols,pver) ! pressure difference across + ! level (pa) + real(r8), intent(in) :: cldn(pcols,pver) ! cloud fraction + real(r8), intent(in) :: icecldf(pcols,pver) ! ice cloud fraction + real(r8), intent(in) :: liqcldf(pcols,pver) ! liquid cloud fraction + real(r8), intent(inout) :: cldo(pcols,pver) ! old cloud fraction + real(r8), intent(out) :: rate1ord_cw2pr_st(pcols,pver) + ! 1st order rate for direct cw to + ! precip conversion + real(r8), intent(in) :: naai(pcols,pver) ! ice nulceation number + ! (from microp_aero_ts) + real(r8), intent(in) :: npccnin(pcols,pver) ! ccn activated number + ! (from microp_aero_ts) + real(r8), intent(in) :: rndst(pcols,pver,4) ! radius of 4 dust bins for + ! contact freezing (from + ! microp_aero_ts) + real(r8), intent(in) :: nacon(pcols,pver,4) ! number in 4 dust bins for + ! contact freezing (from + ! microp_aero_ts) + real(r8), intent(out) :: tlat(pcols,pver) ! latent heating rate + ! (W/kg) + real(r8), intent(out) :: qvlat(pcols,pver) ! microphysical tendency qv + ! (1/s) + real(r8), intent(out) :: qctend(pcols,pver) ! microphysical tendency qc + ! (1/s) + real(r8), intent(out) :: qitend(pcols,pver) ! microphysical tendency qi + ! (1/s) + real(r8), intent(out) :: nctend(pcols,pver) ! microphysical tendency nc + ! (1/(kg*s)) + real(r8), intent(out) :: nitend(pcols,pver) ! microphysical tendency ni + ! (1/(kg*s)) + real(r8), intent(out) :: effc(pcols,pver) ! droplet effective radius + ! (micron) + real(r8), intent(out) :: effc_fn(pcols,pver)! droplet effective radius, + ! assuming nc = 1.e8 kg-1 + real(r8), intent(out) :: effi(pcols,pver) ! cloud ice effective radius + ! (micron) + real(r8), intent(out) :: prect(pcols) ! surface precip rate (m/s) + real(r8), intent(out) :: preci(pcols) ! cloud ice/snow precip rate + ! (m/s) + real(r8), intent(out) :: nevapr(pcols,pver) ! evaporation rate of rain + ! + snow + real(r8), intent(out) :: evapsnow(pcols,pver)! sublimation rate of snow + real(r8), intent(out) :: prain(pcols,pver) ! production of rain + snow + real(r8), intent(out) :: prodsnow(pcols,pver)! production of snow + real(r8), intent(out) :: cmeout(pcols,pver) ! evap/sub of cloud + real(r8), intent(out) :: deffi(pcols,pver) ! ice effective diameter + ! for optics (radiation) + real(r8), intent(out) :: pgamrad(pcols,pver) ! ice gamma parameter for + ! optics (radiation) + real(r8), intent(out) :: lamcrad(pcols,pver) ! slope of droplet + ! distribution for optics + ! (radiation) + real(r8), intent(out) :: qsout(pcols,pver) ! snow mixing ratio (kg/kg) + real(r8), intent(out) :: dsout(pcols,pver) ! snow diameter (m) + real(r8), intent(out) :: rflx(pcols,pver+1) ! grid-box average rain + ! flux (kg m^-2 s^-1) + real(r8), intent(out) :: sflx(pcols,pver+1) ! grid-box average snow + ! flux (kg m^-2 s^-1) + real(r8), intent(out) :: qrout(pcols,pver) ! grid-box average rain + ! mixing ratio (kg/kg) + real(r8), intent(out) :: reff_rain(pcols,pver) ! rain effective radius + ! (micron) + real(r8), intent(out) :: reff_snow(pcols,pver) ! snow effective radius + ! (micron) + real(r8), intent(out) :: qcsevap(pcols,pver) ! cloud water evaporation + ! due to sedimentation + real(r8), intent(out) :: qisevap(pcols,pver) ! cloud ice sublimation due + ! to sublimation + real(r8), intent(out) :: qvres(pcols,pver) ! residual condensation + ! term to ensure RH < 100% + real(r8), intent(out) :: cmeiout(pcols,pver) ! grid-mean cloud ice + ! sub/dep + real(r8), intent(out) :: vtrmc(pcols,pver) ! mass-weighted cloud water + ! fallspeed + real(r8), intent(out) :: vtrmi(pcols,pver) ! mass-weighted cloud ice + ! fallspeed + real(r8), intent(out) :: qcsedten(pcols,pver)! qc sedimentation tendency + real(r8), intent(out) :: qisedten(pcols,pver)! qi sedimentation tendency + +! microphysical process rates for output (mixing ratio tendencies) + real(r8), intent(out) :: prao(pcols,pver) ! accretion of cloud by rain + real(r8), intent(out) :: prco(pcols,pver) ! autoconversion of cloud to + ! rain + real(r8), intent(out) :: mnuccco(pcols,pver) ! mixing rat tend due to + ! immersion freezing + real(r8), intent(out) :: mnuccto(pcols,pver) ! mixing ratio tend due to + ! contact freezing + real(r8), intent(out) :: msacwio(pcols,pver) ! mixing ratio tend due to + ! H-M splintering + real(r8), intent(out) :: psacwso(pcols,pver) ! collection of cloud water + ! by snow + real(r8), intent(out) :: bergso(pcols,pver) ! bergeron process on snow + real(r8), intent(out) :: bergo(pcols,pver) ! bergeron process on + ! cloud ice + real(r8), intent(out) :: melto(pcols,pver) ! melting of cloud ice + real(r8), intent(out) :: homoo(pcols,pver) ! homogeneos freezing + ! cloud water + real(r8), intent(out) :: qcreso(pcols,pver) ! residual cloud conden- + ! sation due to removal of + ! excess supersat + real(r8), intent(out) :: prcio(pcols,pver) ! autoconversion of cloud + ! ice to snow + real(r8), intent(out) :: praio(pcols,pver) ! accretion of cloud ice by + ! snow + real(r8), intent(out) :: qireso(pcols,pver) ! residual ice deposition + ! due to removal of excess + ! supersat + real(r8), intent(out) :: mnuccro(pcols,pver) ! mixing ratio tendency due + ! to heterogeneous freezing + ! of rain to snow (1/s) + real(r8), intent(out) :: pracso (pcols,pver) ! mixing ratio tendency due + ! to accretion of rain by + ! snow (1/s) + real(r8), intent(out) :: meltsdt(pcols,pver) ! latent heating rate due + ! to melting of snow (W/kg) + real(r8), intent(out) :: frzrdt (pcols,pver) ! latent heating rate due + ! to homogeneous freezing + ! of rain (W/kg) + real(r8), intent(out) :: mnuccdo(pcols,pver) ! mass tendency from ice + ! nucleation +#endif + +!Author: Hugh Morrison, Andrew Gettelman, NCAR +! e-mail: morrison@ucar.edu, andrew@ucar.edu + +#ifdef GFDL_COMPATIBLE_MICROP +! these variables are output by NCAR, but not GFDL, so need to be +! declared as local for GFDL implementation + + real(r8) :: qc(pcols,pver) ! cloud water mixing ratio (kg/kg) + real(r8) :: qi(pcols,pver) ! cloud ice mixing ratio (kg/kg) + real(r8) :: nc(pcols,pver) ! cloud water number conc (1/kg) + real(r8) :: ni(pcols,pver) ! cloud ice number conc (1/kg) + real(r8) :: rate1ord_cw2pr_st(pcols,pver) + ! 1st order rate for direct cw to + ! precip conversion used for scavenging + real(r8) :: effc(pcols,pver) ! droplet effective radius (micron) + real(r8) :: effc_fn(pcols,pver) ! droplet effective radius, + ! assuming nc = 1.e8 kg-1 + real(r8) :: effi(pcols,pver) ! cloud ice effective radius (micron) + real(r8) :: nevapr(pcols,pver) ! evaporation rate of rain + snow + real(r8) :: evapsnow(pcols,pver)! sublimation rate of snow + real(r8) :: prain(pcols,pver) ! production of rain + snow + real(r8) :: prodsnow(pcols,pver)! production of snow + real(r8) :: cmeout(pcols,pver) ! evap/sub of cloud + real(r8) :: deffi(pcols,pver) ! ice effective diameter for optics + ! (radiation) + real(r8) :: pgamrad(pcols,pver) ! ice gamma parameter for optics + ! (radiation) + real(r8) :: lamcrad(pcols,pver) ! slope of droplet distribution for + ! optics (radiation) + real(r8) :: dsout(pcols,pver) ! snow diameter (m) + real(r8) :: qcsevap(pcols,pver) ! cloud water evaporation due to + ! sedimentation + real(r8) :: qisevap(pcols,pver) ! cloud ice sublimation due to + ! sublimation + real(r8) :: qvres(pcols,pver) ! residual condensation term to ensure + ! RH < 100% + real(r8) :: cmeiout(pcols,pver) ! grid-mean cloud ice sub/dep + real(r8) :: vtrmc(pcols,pver) ! mass-weighted cloud water fallspeed + real(r8) :: vtrmi(pcols,pver) ! mass-weighted cloud ice fallspeed + real(r8) :: qcsedten(pcols,pver)! qc sedimentation tendency + real(r8) :: qisedten(pcols,pver)! qi sedimentation tendency + real(r8) :: prao(pcols,pver) ! accretion of cloud by rain + real(r8) :: prco(pcols,pver) ! autoconversion of cloud to rain + real(r8) :: mnuccco(pcols,pver) ! mixing rat tend due to immersion + ! freezing + real(r8) :: mnuccto(pcols,pver) ! mixing ratio tend due to contact + ! freezing + real(r8) :: msacwio(pcols,pver) ! mixing ratio tend due to H-M + ! splintering + real(r8) :: psacwso(pcols,pver) ! collection of cloud water by snow + real(r8) :: bergso(pcols,pver) ! bergeron process on snow + real(r8) :: bergo(pcols,pver) ! bergeron process on cloud ice + real(r8) :: melto(pcols,pver) ! melting of cloud ice + real(r8) :: homoo(pcols,pver) ! homogeneos freezign cloud water + real(r8) :: qcreso(pcols,pver) ! residual cloud condensation due to + ! removal of excess supersat + real(r8) :: prcio(pcols,pver) ! autoconversion of cloud ice to snow + real(r8) :: praio(pcols,pver) ! accretion of cloud ice by snow + real(r8) :: qireso(pcols,pver) ! residual ice deposition due to removal + ! of excess supersat + real(r8) :: mnuccro(pcols,pver) ! mixing ratio tendency due to + ! heterogeneous freezing of rain to + ! snow (1/s) + real(r8) :: pracso (pcols,pver) ! mixing ratio tendency due to accretion + ! of rain by snow (1/s) + real(r8) :: meltsdt(pcols,pver) ! latent heating rate due to melting of + ! snow (W/kg) + real(r8) :: frzrdt (pcols,pver) ! latent heating rate due to homogeneous + ! freezing of rain (W/kg) + real(r8) :: mnuccdo(pcols,pver) ! mass tendency from ice nucleation + +! these variables are only used in the GFDL implementation + + real(r8) :: cmelo(pcols,pver) ! liquid condensation + real(r8) :: eroslo(pcols,pver) ! liquid erosion + real(r8) :: erosio(pcols,pver) ! ice erosion + real(r8) :: preo(pcols,pver) ! rain evaporation + real(r8) :: prdso(pcols,pver) ! snow sublimation + logical :: do_berg1 + logical :: limit_berg = .false. + real(r8) :: berg_lim = 1.0e-6_r8 + real(r8) :: dum3 ! temporary dummy variable + +! droplet number + real(r8) :: nucclim(pver) + real(r8) :: nucclimo(pcols,pver) + real(r8) :: npccno(pcols,pver) + real(r8) :: nnuccco(pcols,pver) + real(r8) :: nnuccto(pcols,pver) + real(r8) :: npsacwso(pcols,pver) + real(r8) :: nsubco(pcols,pver) + real(r8) :: nerosco(pcols,pver) + real(r8) :: nprao(pcols,pver) + real(r8) :: nprc1o(pcols,pver) + real(r8) :: nerosc(pcols,pver) + real(r8) :: D_eros_l(pcols,pver) + +! cloud ice number + real(r8) :: nucclim1i(pver) + real(r8) :: nucclim1io(pcols,pver) + real(r8) :: nnuccdo(pcols,pver) + real(r8) :: nsacwio(pcols,pver) + real(r8) :: nsubio(pcols,pver) + real(r8) :: nerosio(pcols,pver) + real(r8) :: nprcio(pcols,pver) + real(r8) :: npraio(pcols,pver) + real(r8) :: nerosi(pcols,pver) + real(r8) :: D_eros_i(pcols,pver) + + + real(r8) :: cmel (pcols,pver) + real(r8) :: cmel_orig(pcols,pver) + real(r8) :: cmei_orig(pcols,pver) + real(r8) :: berg_orig(pcols,pver) + + real(r8) :: sum_freeze(pcols,pver) + real(r8) :: sum_freeze2(pcols,pver) + real(r8) :: sum_rime (pcols,pver) + real(r8) :: sum_berg (pcols,pver) + real(r8) :: sum_ice_adj(pcols,pver) + real(r8) :: sum_bergs (pcols,pver) + real(r8) :: sum_cond (pcols,pver) + real(r8) :: sum_splinter(pcols,pver) + real(r8) :: qldt_sum + real(r8) :: eslt, esit, rhi, qs_d, tc + real(r8) :: qs2d(pcols,pver) + real(r8) :: qtot(pcols,pver) + + logical :: lflag = .false. + +#endif + +#ifndef GFDL_COMPATIBLE_MICROP +! these variables are not used in the GFDL implementation + + real(r8) :: qcld ! total cloud water + real(r8) :: lcldn(pcols,pver) ! fractional coverage of new liquid cloud + real(r8) :: lcldo(pcols,pver) ! fractional coverage of old liquid cloud + real(r8) :: nctend_mixnuc(pcols,pver) + real(r8) :: arg ! argument of erfc + real(r8) :: drout(pcols,pver) ! rain diameter (m) +#endif + +! local workspace +! all units mks unless otherwise stated + +! temporary variables for sub-stepping + real(r8) :: t1(pcols,pver) + real(r8) :: q1(pcols,pver) + real(r8) :: qc1(pcols,pver) + real(r8) :: qi1(pcols,pver) + real(r8) :: nc1(pcols,pver) + real(r8) :: ni1(pcols,pver) + real(r8) :: tlat1(pcols,pver) + real(r8) :: qvlat1(pcols,pver) + real(r8) :: qctend1(pcols,pver) + real(r8) :: qitend1(pcols,pver) + real(r8) :: nctend1(pcols,pver) + real(r8) :: nitend1(pcols,pver) + real(r8) :: prect1(pcols) + real(r8) :: preci1(pcols) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + real(r8) :: deltat ! sub-time step (s) + real(r8) :: omsm ! number near unity for round-off issues + real(r8) :: dto2 ! dt/2 (s) + real(r8) :: mincld ! minimum allowed cloud fraction + real(r8) :: q(pcols,pver) ! water vapor mixing ratio (kg/kg) + real(r8) :: t(pcols,pver) ! temperature (K) + real(r8) :: rho(pcols,pver) ! air density (kg m-3) + real(r8) :: dv(pcols,pver) ! diffusivity of water vapor in air + real(r8) :: mu(pcols,pver) ! viscocity of air + real(r8) :: sc(pcols,pver) ! schmidt number + real(r8) :: kap(pcols,pver) ! thermal conductivity of air + real(r8) :: rhof(pcols,pver) ! air density correction factor for + ! fallspeed + real(r8) :: cldmax(pcols,pver) ! precip fraction assuming maximum + ! overlap + real(r8) :: cldm(pcols,pver) ! cloud fraction + real(r8) :: icldm(pcols,pver) ! ice cloud fraction + real(r8) :: lcldm(pcols,pver) ! liq cloud fraction + real(r8) :: icwc(pcols) ! in cloud water content (liquid+ice) + real(r8) :: calpha(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cbeta(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cbetah(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cgamma(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cgamah(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: rcgama(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cmec1(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cmec2(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cmec3(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: cmec4(pcols) ! parameter for cond/evap + ! (Zhang et al. 2003) + real(r8) :: qtmp ! dummy qv + real(r8) :: dum ! temporary dummy variable + +! real(r8) :: cme(pcols,pver) ! total (liquid+ice) cond/evap rate + ! of cloud + real(r8) :: cmei(pcols,pver) ! dep/sublimation rate of cloud ice + real(r8) :: cwml(pcols,pver) ! cloud water mixing ratio + real(r8) :: cwmi(pcols,pver) ! cloud ice mixing ratio + real(r8) :: nnuccd(pver) ! ice nucleation rate from + ! deposition/cond.-freezing + real(r8) :: mnuccd(pver) ! mass tendency from ice nucleation + +! for calculation of rate1ord_cw2pr_st: + real(r8) :: qcsinksum_rate1ord(pver) ! sum over iterations of cw + ! to precip sink + real(r8) :: qcsum_rate1ord(pver) ! sum over iterations of + ! cloud water + real(r8) :: alpha + + real(r8) :: dum1,dum2 !general dummy variables + + real(r8) :: npccn(pver) ! droplet activation rate + real(r8) :: qcic(pcols,pver) ! in-cloud cloud liquid mixing ratio + real(r8) :: qiic(pcols,pver) ! in-cloud cloud ice mixing ratio + real(r8) :: qniic(pcols,pver)! in-precip snow mixing ratio + real(r8) :: qric(pcols,pver) ! in-precip rain mixing ratio + real(r8) :: ncic(pcols,pver) ! in-cloud droplet number conc + real(r8) :: niic(pcols,pver) ! in-cloud cloud ice number conc + real(r8) :: nsic(pcols,pver) ! in-precip snow number conc + real(r8) :: nric(pcols,pver) ! in-precip rain number conc + real(r8) :: lami(pver) ! slope of cloud ice size distr + real(r8) :: n0i(pver) ! intercept of cloud ice size distr + real(r8) :: lamc(pver) ! slope of cloud liquid size distr + real(r8) :: n0c(pver) ! intercept of cloud liquid size distr + real(r8) :: lams(pver) ! slope of snow size distr + real(r8) :: n0s(pver) ! intercept of snow size distr + real(r8) :: lamr(pver) ! slope of rain size distr + real(r8) :: n0r(pver) ! intercept of rain size distr + real(r8) :: cdist1(pver) ! size distr parameter to calculate + ! droplet freezing + real(r8) :: rercld(pcols,pver) ! effective radius calculation for + ! rain + cloud (combined size of + ! precip & cloud drops) + real(r8) :: arcld(pcols,pver) ! averaging control flag + real(r8) :: Actmp ! area cross section of drops + real(r8) :: Artmp ! area cross section of rain + + real(r8) :: pgam(pver) ! spectral width parameter of + ! droplet size distr + real(r8) :: lammax ! maximum allowed slope of size + ! distr + real(r8) :: lammin ! minimum allowed slope of size + ! distr + real(r8) :: nacnt ! number conc of contact ice nuclei + real(r8) :: mnuccc(pver) ! mixing ratio tendency due to + ! freezing of cloud water + real(r8) :: nnuccc(pver) ! number conc tendency due to + ! freezing of cloud water + + real(r8) :: mnucct(pver) ! mixing ratio tendency due to + ! contact freezing of cloud water + real(r8) :: nnucct(pver) ! number conc tendency due to + ! contact freezing of cloud water + real(r8) :: msacwi(pver) ! mixing ratio tendency due to HM + ! ice multiplication + real(r8) :: nsacwi(pver) ! number conc tendency due to HM + ! ice multiplication + + real(r8) :: prc(pver) ! qc tendency due to autoconversion + ! of cloud droplets + real(r8) :: nprc(pver) ! number conc tendency due to + ! autoconversion of cloud droplets + real(r8) :: nprc1(pver) ! qr tendency due to autoconversion + ! of cloud droplets + real(r8) :: nsagg(pver) ! ns tendency due to + ! self-aggregation of snow + real(r8) :: dc0 ! mean size droplet size distr + real(r8) :: ds0 ! mean size snow size distr + ! (area weighted) + real(r8) :: eci ! collection efficiency for riming + ! of snow by droplets + real(r8) :: psacws(pver) ! mixing rat tendency due to + ! collection of droplets by snow + real(r8) :: npsacws(pver) ! number conc tendency due to + ! collection of droplets by snow + real(r8) :: uni ! number-weighted cloud ice + ! fallspeed + real(r8) :: umi ! mass-weighted cloud ice fallspeed + real(r8) :: uns(pver) ! number-weighted snow fallspeed + real(r8) :: ums(pver) ! mass-weighted snow fallspeed + real(r8) :: unr(pver) ! number-weighted rain fallspeed + real(r8) :: umr(pver) ! mass-weighted rain fallspeed + real(r8) :: unc ! number-weighted cloud droplet + ! fallspeed + real(r8) :: umc ! mass-weighted cloud droplet + ! fallspeed + real(r8) :: pracs(pver) ! mixing rat tendency due to + ! collection of rain by snow + real(r8) :: npracs(pver) ! number conc tendency due to + ! collection of rain by snow + real(r8) :: mnuccr(pver) ! mixing rat tendency due to + ! freezing of rain + real(r8) :: nnuccr(pver) ! number conc tendency due to + ! freezing of rain + real(r8) :: pra(pver) ! mixing rat tendnency due to + ! accretion of droplets by rain + real(r8) :: npra(pver) ! nc tendnency due to accretion of + ! droplets by rain + real(r8) :: nragg(pver) ! nr tendency due to + ! self-collection of rain + real(r8) :: prci(pver) ! mixing rat tendency due to auto- + ! conversion of cloud ice to snow + real(r8) :: nprci(pver) ! number conc tendency due to auto- + ! conversion of cloud ice to snow + real(r8) :: prai(pver) ! mixing rat tendency due to + ! accretion of cloud ice by snow + real(r8) :: nprai(pver) ! number conc tendency due to + ! accretion of cloud ice by snow + real(r8) :: qvs ! liquid saturation vapor mixing + ! ratio + real(r8) :: qvi ! ice saturation vapor mixing ratio + real(r8) :: dqsdt ! change of sat vapor mixing ratio + ! with temperature + real(r8) :: dqsidt ! change of ice sat vapor mixing + ! ratio with temperature + real(r8) :: ab ! correction factor for rain evap + ! to account for latent heat + real(r8) :: qclr ! water vapor mixing ratio in clear + ! air + real(r8) :: abi ! correction factor for snow + ! sublimation to account for + ! latent heat + real(r8) :: epss ! 1/ sat relaxation timescale for + ! snow + real(r8) :: epsr ! 1/ sat relaxation timescale for + ! rain + real(r8) :: pre(pver) ! rain mixing rat tendency due to + ! evaporation + real(r8) :: prds(pver) ! snow mixing rat tendency due to + ! sublimation + real(r8) :: qce ! dummy qc for conservation check + real(r8) :: qie ! dummy qi for conservation check + real(r8) :: nce ! dummy nc for conservation check + real(r8) :: nie ! dummy ni for conservation check + real(r8) :: ratio ! parameter for conservation check + real(r8) :: dumc(pcols,pver) ! dummy in-cloud qc + real(r8) :: dumnc(pcols,pver) ! dummy in-cloud nc + real(r8) :: dumi(pcols,pver) ! dummy in-cloud qi + real(r8) :: dumni(pcols,pver) ! dummy in-cloud ni + real(r8) :: dums(pcols,pver) ! dummy in-cloud snow mixing rat + real(r8) :: dumns(pcols,pver) ! dummy in-cloud snow number conc + real(r8) :: dumr(pcols,pver) ! dummy in-cloud rain mixing rat + real(r8) :: dumnr(pcols,pver) ! dummy in-cloud rain number conc + +! these are parameters for cloud water and cloud ice sedimentation +! calculations: + real(r8) :: fr(pver) + real(r8) :: fnr(pver) + real(r8) :: fc(pver) + real(r8) :: fnc(pver) + real(r8) :: fi(pver) + real(r8) :: fni(pver) + real(r8) :: fs(pver) + real(r8) :: fns(pver) + real(r8) :: faloutr(pver) + real(r8) :: faloutnr(pver) + real(r8) :: faloutc(pver) + real(r8) :: faloutnc(pver) + real(r8) :: falouti(pver) + real(r8) :: faloutni(pver) + real(r8) :: falouts(pver) + real(r8) :: faloutns(pver) + real(r8) :: faltndr + real(r8) :: faltndnr + real(r8) :: faltndc + real(r8) :: faltndnc + real(r8) :: faltndi + real(r8) :: faltndni + real(r8) :: faltnds + real(r8) :: faltndns + real(r8) :: faltndqie + real(r8) :: faltndqce + + + + real(r8) :: relhum(pcols,pver) ! relative humidity + real(r8) :: csigma(pcols) ! parameter for cond/evap of + ! cloud water/ice + real(r8) :: rgvm ! max fallspeed for all species + real(r8) :: arn(pcols,pver) ! air density corrected rain + ! fallspeed parameter + real(r8) :: asn(pcols,pver) ! air density corrected snow + ! fallspeed parameter + real(r8) :: acn(pcols,pver) ! air density corrected cloud + ! droplet fallspeed parameter + real(r8) :: ain(pcols,pver) ! air density corrected cloud ice + ! fallspeed parameter + real(r8) :: nsubi(pver) ! evaporation of cloud ice number + real(r8) :: nsubc(pver) ! evaporation of droplet number + real(r8) :: nsubs(pver) ! evaporation of snow number + real(r8) :: nsubr(pver) ! evaporation of rain number + real(r8) :: mtime ! factor to account for droplet + ! activation timescale + real(r8) :: dz(pcols,pver) ! height difference across model + ! vertical level + + real(r8) :: nfice(pcols,pver) ! fice variable + +! precip flux variables for sub-stepping: + real(r8) :: rflx1(pcols,pver+1) + real(r8) :: sflx1(pcols,pver+1) + +! returns from function/subroutine calls: + real(r8) :: tsp(pcols,pver) ! saturation temp (K) + real(r8) :: qsp(pcols,pver) ! saturation mixing ratio (kg/kg) + real(r8) :: qsphy(pcols,pver) ! saturation mixing ratio (kg/kg): + ! hybrid rh + real(r8) :: qs(pcols) ! liquid-ice weighted sat mixing + ! rat (kg/kg) + real(r8) :: es(pcols) ! liquid-ice weighted sat vapor + ! press (pa) + real(r8) :: esl(pcols,pver) ! liquid sat vapor pressure (pa) + real(r8) :: esi(pcols,pver) ! ice sat vapor pressure (pa) + real(r8) :: gammas(pcols) ! parameter for cond/evap of cloud + ! water + +! sum of source/sink terms for diagnostic precip: + real(r8) :: qnitend(pcols,pver)! snow mixing ratio source/sink term + real(r8) :: nstend(pcols,pver) ! snow number concentration + ! source/sink term + real(r8) :: qrtend(pcols,pver) ! rain mixing ratio source/sink term + real(r8) :: nrtend(pcols,pver) ! rain number concentration + ! source/sink term + real(r8) :: qrtot ! vertically-integrated rain mixing + ! rat source/sink term + real(r8) :: nrtot ! vertically-integrated rain number + ! conc source/sink term + real(r8) :: qstot ! vertically-integrated snow mixing + ! rat source/sink term + real(r8) :: nstot ! vertically-integrated snow number + ! conc source/sink term + +! new terms for Bergeron process + real(r8) :: dumnnuc ! provisional ice nucleation rate + ! (for calculating bergeron) + real(r8) :: ninew ! provisional cloud ice number conc + ! (for calculating bergeron) + real(r8) :: qinew ! provisional cloud ice mixing ratio + ! (for calculating bergeron) + real(r8) :: qvl ! liquid sat mixing ratio + real(r8) :: epsi ! 1/ sat relaxation timecale for + ! cloud ice + real(r8) :: prd ! provisional deposition rate of + ! cloud ice at water sat + real(r8) :: berg(pcols,pver) ! mixing rat tendency due to + ! bergeron process for cloud ice + real(r8) :: bergs(pver) ! mixing rat tendency due to + ! bergeron process for snow + +!bergeron terms + real(r8) :: bergtsf ! bergeron timescale to remove all + ! liquid + real(r8) :: rhin !modified RH for vapor deposition + +! diagnostic rain/snow for output to history +! values are in-precip (local) !!!! + real(r8) :: nrout(pcols,pver) ! rain number concentration (1/m3) + real(r8) :: nsout(pcols,pver) ! snow number concentration (1/m3) + +!averaged rain/snow for history + real(r8) :: qrout2(pcols,pver) + real(r8) :: qsout2(pcols,pver) + real(r8) :: nrout2(pcols,pver) + real(r8) :: nsout2(pcols,pver) + real(r8) :: freqs(pcols,pver) + real(r8) :: freqr(pcols,pver) + real(r8) :: dumfice + real(r8) :: drout2(pcols,pver) ! mean rain particle diameter (m) + real(r8) :: dsout2(pcols,pver) ! mean snow particle diameter (m) + +!ice nucleation, droplet activation + real(r8) :: dum2i(pcols,pver) ! number conc of ice nuclei + ! available (1/kg) + real(r8) :: dum2l(pcols,pver) ! number conc of CCN (1/kg) + real(r8) :: ncmax + real(r8) :: nimax + +!output fields for number conc + real(r8) :: ncai(pcols,pver) ! output number conc of ice nuclei + ! available (1/m3) + real(r8) :: ncal(pcols,pver) ! output number conc of CCN (1/m3) + +! loop array variables + integer i, k, nstep, n, l + integer ii, kk, m + +! loop variables for sub-step solution + integer iter, it, ltrue(pcols) + +! used in contact freezing via dust particles + real(r8) tcnt, viscosity, mfp + real(r8) slip1, slip2, slip3, slip4 + real(r8) ndfaer1, ndfaer2, ndfaer3, ndfaer4 + real(r8) nslip1, nslip2, nslip3, nslip4 + +! used in ice effective radius + real(r8) bbi, cci, ak, iciwc, rvi + +! used in Bergeron processe and water vapor deposition + real(r8) Tk, deles, Aprpr, Bprpr, Cice, qi0, Crate, qidep + +! mean cloud fraction over the time step + real(r8) cldmw(pcols,pver) + +! used in secondary ice production + real(r8) ni_secp + +! variables to check for RH after rain evap + real(r8) :: esn + real(r8) :: qsn + real(r8) :: ttmp + + + real(r8) :: refl(pcols,pver) ! analytic radar reflectivity + real(r8) :: rainrt(pcols,pver) ! rain rate for reflectivity + ! calculation + real(r8) :: rainrt1(pcols,pver) + real(r8) :: csrfl(pcols,pver) ! cloudsat reflectivity + real(r8) :: arefl(pcols,pver) ! average reflectivity will zero + ! points outside valid range + real(r8) :: acsrfl(pcols,pver) ! cloudsat average + real(r8) :: frefl(pcols,pver) + real(r8) :: fcsrfl(pcols,pver) + real(r8) :: areflz(pcols,pver) !average reflectivity in z. + real(r8) :: tmp + + real(r8) dmc,ssmc,dstrn ! variables for modal scheme. + + real(r8), parameter :: cdnl = 0.e6_r8 ! cloud droplet number limiter + + +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + +! initialize output fields for number conc qand ice nucleation + ncai(1:ncol,1:pver)=0._r8 + ncal(1:ncol,1:pver)=0._r8 + +!Initialize rain size + rercld(1:ncol,1:pver)=0._r8 + arcld(1:ncol,1:pver)=0._r8 + +!initialize radiation output variables + pgamrad(1:ncol,1:pver)=0._r8 ! liquid gamma parameter for optics + lamcrad(1:ncol,1:pver)=0._r8 ! slope of droplet distribution for optics + deffi (1:ncol,1:pver)=0._r8 ! slope of droplet distribution for optics + +!initialize water vapor tendency term output + qcsevap(1:ncol,1:pver)=0._r8 + qisevap(1:ncol,1:pver)=0._r8 + qvres (1:ncol,1:pver)=0._r8 + cmeiout (1:ncol,1:pver)=0._r8 + vtrmc (1:ncol,1:pver)=0._r8 + vtrmi (1:ncol,1:pver)=0._r8 + qcsedten (1:ncol,1:pver)=0._r8 + qisedten (1:ncol,1:pver)=0._r8 + +!initialize arrays which accumulate tendencies across sub-steps + prao(1:ncol,1:pver)=0._r8 + prco(1:ncol,1:pver)=0._r8 + mnuccco(1:ncol,1:pver)=0._r8 + mnuccto(1:ncol,1:pver)=0._r8 + msacwio(1:ncol,1:pver)=0._r8 + psacwso(1:ncol,1:pver)=0._r8 + bergso(1:ncol,1:pver)=0._r8 + bergo(1:ncol,1:pver)=0._r8 + melto(1:ncol,1:pver)=0._r8 + homoo(1:ncol,1:pver)=0._r8 + qcreso(1:ncol,1:pver)=0._r8 + prcio(1:ncol,1:pver)=0._r8 + praio(1:ncol,1:pver)=0._r8 + qireso(1:ncol,1:pver)=0._r8 + mnuccro(1:ncol,1:pver)=0._r8 + pracso (1:ncol,1:pver)=0._r8 + meltsdt(1:ncol,1:pver)=0._r8 + frzrdt (1:ncol,1:pver)=0._r8 + mnuccdo(1:ncol,1:pver)=0._r8 +#ifdef GFDL_COMPATIBLE_MICROP + preo(1:ncol,1:pver) =0._r8 + prdso(1:ncol,1:pver)=0._r8 + cmelo(1:ncol,1:pver) =0._r8 + eroslo(1:ncol,1:pver) =0._r8 + erosio(1:ncol,1:pver) =0._r8 +!droplet number + nucclimo(1:ncol,1:pver) = 0._r8 + npccno(1:ncol,1:pver) = 0._r8 + nnuccco(1:ncol,1:pver) = 0._r8 + nnuccto(1:ncol,1:pver) = 0._r8 + npsacwso(1:ncol,1:pver) = 0._r8 + nsubco(1:ncol,1:pver) = 0._r8 + nerosco(1:ncol,1:pver) = 0._r8 + nprao(1:ncol,1:pver) = 0._r8 + nprc1o(1:ncol,1:pver) = 0._r8 +!ice number + nucclim1io(1:ncol,1:pver) = 0._r8 + nnuccdo(1:ncol,1:pver) = 0._r8 + nsacwio(1:ncol,1:pver) = 0._r8 + nsubio(1:ncol,1:pver) = 0._r8 + nerosio(1:ncol,1:pver) = 0._r8 + nprcio(1:ncol,1:pver) = 0._r8 + npraio(1:ncol,1:pver) = 0._r8 +#endif + + + +! assign variable deltat for sub-stepping... + deltat=deltatin + +! parameters for scheme + + omsm=0.99999_r8 + dto2=0.5_r8*deltat + mincld=0.0001_r8 + +! initialize multi-level fields + q(1:ncol,1:pver)=qn(1:ncol,1:pver) + t(1:ncol,1:pver)=tn(1:ncol,1:pver) + +#ifdef GFDL_COMPATIBLE_MICROP + qc(1:ncol,1:pver) = qc_in(1:ncol,1:pver) + qi(1:ncol,1:pver) = qi_in(1:ncol,1:pver) + nc(1:ncol,1:pver) = nc_in(1:ncol,1:pver) + ni(1:ncol,1:pver) = ni_in(1:ncol,1:pver) + if (PRESENT(do_clubb)) lflag=(do_clubb>0) +#endif + +! initialize time-varying parameters + + do k=1,pver + do i=1,ncol + rho(i,k) = p(i,k)/(r*t(i,k)) + dv(i,k) = 8.794E-5_r8*t(i,k)**1.81_r8/p(i,k) + mu(i,k) = 1.496E-6_r8*t(i,k)**1.5_r8/(t(i,k) + 120._r8) + sc(i,k) = mu(i,k)/(rho(i,k)*dv(i,k)) + kap(i,k) = 1.414e3_r8*1.496e-6_r8*t(i,k)**1.5_r8/ & + (t(i,k) + 120._r8) + +! air density adjustment for fallspeed parameters +! includes air density correction factor to the +! power of 0.54 following Heymsfield and Bansemer 2007 + + rhof(i,k) = (rhosu/rho(i,k))**0.54_r8 +#ifdef GFDL_COMPATIBLE_MICROP + rhof(i,k) = MIN (rhof(i,k), max_rho_factor_in_vt) +#endif + arn(i,k) = ar*rhof(i,k) + asn(i,k) = as*rhof(i,k) + acn(i,k) = ac*rhof(i,k) + ain(i,k) = ai*rhof(i,k) + +!#ifdef GFDL_COMPATIBLE_MICROP +! if (.not. rho_factor_in_max_vt) rhof(i,k) = 1.0 +! rhof(i,k) = MIn(rhof(i,k), 1.6) +!#endif + +! get dz from dp and hydrostatic approx +! keep dz positive (define as layer k-1 - layer k) + + dz(i,k) = pdel(i,k)/(rho(i,k)*g) + end do + end do + +! initialization -- these variables retain the input fields during +! sub-stepping + t1(1:ncol,1:pver) = t(1:ncol,1:pver) + q1(1:ncol,1:pver) = q(1:ncol,1:pver) + qc1(1:ncol,1:pver) = qc(1:ncol,1:pver) + qi1(1:ncol,1:pver) = qi(1:ncol,1:pver) + nc1(1:ncol,1:pver) = nc(1:ncol,1:pver) + ni1(1:ncol,1:pver) = ni(1:ncol,1:pver) + +! initialize tendencies to zero + tlat1(1:ncol,1:pver)=0._r8 + qvlat1(1:ncol,1:pver)=0._r8 + qctend1(1:ncol,1:pver)=0._r8 + qitend1(1:ncol,1:pver)=0._r8 + nctend1(1:ncol,1:pver)=0._r8 + nitend1(1:ncol,1:pver)=0._r8 + +! initialize precip output + qrout(1:ncol,1:pver)=0._r8 + qsout(1:ncol,1:pver)=0._r8 + nrout(1:ncol,1:pver)=0._r8 + nsout(1:ncol,1:pver)=0._r8 + dsout(1:ncol,1:pver)=0._r8 + +#ifdef GFDL_COMPATIBLE_MICROP +! initialize bergeron fraction arrays + sum_freeze(1:ncol,1:pver) = 0._r8 + sum_freeze2(1:ncol,1:pver) = 0._r8 + sum_rime(1:ncol,1:pver) = 0._r8 + sum_berg(1:ncol,1:pver) = 0._r8 + sum_ice_adj(1:ncol,1:pver) = 0._r8 + sum_bergs(1:ncol,1:pver) = 0._r8 + sum_cond (1:ncol,1:pver) = 0._r8 + sum_splinter(1:ncol,1:pver) = 0._r8 +#endif + +#ifndef GFDL_COMPATIBLE_MICROP + drout(1:ncol,1:pver)=0._r8 +!! initialize as fillvalue to avoid Floating Exceptions + reff_rain(1:ncol,1:pver)=fillvalue + reff_snow(1:ncol,1:pver)=fillvalue +#endif + +! initialize variables for trop_mozart + nevapr(1:ncol,1:pver) = 0._r8 + evapsnow(1:ncol,1:pver) = 0._r8 + prain(1:ncol,1:pver) = 0._r8 + prodsnow(1:ncol,1:pver) = 0._r8 + cmeout(1:ncol,1:pver) = 0._r8 + +! for refl calc + rainrt1(1:ncol,1:pver) = 0._r8 + +! initialize precip fraction and output tendencies + cldmax(1:ncol,1:pver) = mincld + +!initialize aerosol number + dum2l(1:ncol,1:pver)=0._r8 + dum2i(1:ncol,1:pver)=0._r8 + +! initialize avg precip rate + prect1(1:ncol)=0._r8 + preci1(1:ncol)=0._r8 + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +!Get humidity and saturation vapor pressures + + do k=1,pver + +! find wet bulk temperature and saturation value for provisional t and q +! without condensation + + call vqsatd_water (t(1,k),p(1,k),es,qs,gammas,ncol) ! use rhw + + do i=1,ncol + + esl(i,k) = polysvp(t(i,k),0) + esi(i,k) = polysvp(t(i,k),1) + +! hm fix, make sure when above freezing that esi=esl, not active yet + if (t(i,k).gt.tmelt) esi(i,k) = esl(i,k) + + relhum(i,k) = q(i,k)/qs(i) + +! get cloud fraction, check for minimum + cldm(i,k)=max(cldn(i,k),mincld) + cldmw(i,k)=max(cldn(i,k),mincld) + + icldm(i,k)=max(icecldf(i,k),mincld) + lcldm(i,k)=max(liqcldf(i,k),mincld) + +! subcolumns, set cloud fraction variables to one +! if cloud water or ice is present, if not present +! set to mincld (mincld used instead of zero, to prevent +! possible division by zero errors + + if (sub_column) then + cldm(i,k)=mincld + cldmw(i,k)=mincld + icldm(i,k)=mincld + lcldm(i,k)=mincld + if (qc(i,k).ge.qsmall) then + lcldm(i,k)=1. + cldm(i,k)=1. + cldmw(i,k)=1. + end if + if (qi(i,k).ge.qsmall) then + cldm(i,k)=1. + icldm(i,k)=1. + end if + end if ! sub-column + +! calculate nfice based on liquid and ice mmr (no rain and snow mmr +! available yet) + + nfice(i,k)=0._r8 + dumfice=qc(i,k)+qi(i,k) + if (dumfice.gt.qsmall .and. qi(i,k).gt.qsmall) then + nfice(i,k)=qi(i,k)/dumfice + endif + +! determine number of activated ice nuclei on this step + +#ifdef GFDL_COMPATIBLE_MICROP + + if (t(i,k).lt.tmelt - 5._r8) then + +! if aerosols interact with ice set number of activated ice nuclei + if ( liu_in ) then + dum2=naai(i,k) + dumnnuc = (dum2 - ni(i,k)/icldm(i,k))/deltat*icldm(i,k) + elseif ( Nml%do_ice_nucl_wpdf ) THEN + if (total_activation) then + dum2 = naai(i,k) + if (Nml%activate_all_ice_always) then + dumnnuc = (dum2 - ni(i,k)/icldm(i,k))/deltat*icldm(i,k) + else + if (delta_cf(i,k) .gt. 0._r8) then + dumnnuc = (dum2 - ni(i,k)/icldm(i,k))/deltat*icldm(i,k) + else + dumnnuc = 0._r8 + endif + endif + else if (dqa_activation) then + dum2 = naai(i,k) + dumnnuc = max(delta_cf(i,k), 0._r8)*dum2/deltat + endif + else +! default when aerosol field not used for nuclei source +! cooper curve (factor of 1000 is to convert from L-1 to m-3) + dum2=0.005_r8*exp(0.304_r8*(tmelt -t(i,k)))*1000._r8 +! put limit on number of nucleated crystals, set to number at T=-30 C +! cooper (limit to value at -35 C) + dum2=min(dum2,208.9e3_r8)/rho(i,k) ! convert from m-3 to kg-1 + dumnnuc = (dum2 - ni(i,k)/icldm(i,k))/deltat*icldm(i,k) + endif + + dumnnuc = max(dumnnuc, 0._r8) + +! get provisional ni and qi after nucleation in order to calculate +! Bergeron process below + ninew = ni(i,k) + dumnnuc*deltat +!What is proper if test here -- dqa or tiedtke or ???? +! or is this incorrect and qi SHOULD increase here (and so also below where +! mnuccd is defined) + if ( tiedtke_macrophysics .or. dqa_activation) then + qinew = qi(i,k) + else + qinew = qi(i,k) + dumnnuc*deltat*mi0 + endif + else ! T>268 + ninew=ni(i,k) + qinew=qi(i,k) + end if ! T>268 +#else + if (t(i,k).lt.tmelt - 5._r8) then + +! if aerosols interact with ice set number of activated ice nuclei + if (liu_in) then + dum2=naai(i,k) + + else +! cooper curve (factor of 1000 is to convert from L-1 to m-3) + dum2=0.005_r8*exp(0.304_r8*(273.15_r8-t(i,k)))*1000._r8 +! put limit on number of nucleated crystals, set to number at T=-30 C +! cooper (limit to value at -35 C) + dum2=min(dum2,208.9e3_r8)/rho(i,k) ! convert from m-3 to kg-1 + endif + + dumnnuc = (dum2 - ni(i,k)/icldm(i,k))/deltat*icldm(i,k) + dumnnuc = max(dumnnuc, 0._r8) + +! get provisional ni and qi after nucleation in order to calculate +! Bergeron process below + ninew = ni(i,k) + dumnnuc*deltat + qinew = qi(i,k) + dumnnuc*deltat*mi0 + else ! T>268 + ninew = ni(i,k) + qinew = qi(i,k) + end if ! T>268 +#endif + +! get in-cloud qi and ni after nucleation + if (icldm(i,k) .gt. 0._r8) then + qiic(i,k) = qinew/icldm(i,k) + niic(i,k) = ninew/icldm(i,k) + else + qiic(i,k) = 0._r8 + niic(i,k) = 0._r8 + endif + +!-->cjg +! hm add 6/2/11 switch for specification of cloud ice number + if (nicons) then + niic(i,k)=ninst/rho(i,k) + end if +!<--cjg + +!------------------------------------------------------------------- +!Bergeron process + +! initialize bergeron process terms to zero + cmei(i,k)= 0._r8 + berg(i,k) = 0._r8 + prd = 0._r8 + +#ifdef GFDL_COMPATIBLE_MICROP +! define the large-scale cloud water and ice condensation/evaporation from +! values passed into routine, and their sum. + cmel(i,k) = dqcdt(i,k) + cmei(i,k) = dqidt(i,k) + dum2 = cmel(i,k) + cmei(i,k) + +! if bergeron process to be active for any non-zero condensate, set flag +! so indicating. +! current setting is limit_berg = .false. (controlled by nml) + IF ( .NOT. limit_berg ) THEN + if (dum2 .ge. 0._r8) then + do_berg1 = .true. + else + do_berg1 = .false. + end if + ELSE +! GFDL has option to not allow bergeron process when cloud ice is less than +! berg_lim, even if have positive condensate. set flag appropriately. + if (dum2 .ge. 0._r8 .and. qinew .gt. berg_lim ) then + do_berg1 = .true. + else + do_berg1 = .false. + end if + END If + + if (do_berg1 .or. lflag ) THEN +#endif + +! calculate bergeron term. +! temp must be cold enough + if (t(i,k).lt.tmelt) then +! ice must exist + if (qi(i,k).gt.qsmall) then + bergtsf = 0._r8 ! bergeron time scale (fraction of + ! timestep) + qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8 - epsqs)*esi(i,k)) + qvl = epsqs*esl(i,k)/(p(i,k) - (1._r8 - epsqs)*esl(i,k)) + +!LIMITS RSH 8/14/12: probably not needed here since liquid not likely to +! be present at these pressures, but not guaranteed. + if( .not. lflag ) then + qvi = MAX(0._r8, MIN (qvi,1.0_r8)) + qvl = MAX(0._r8, MIN (qvl,1.0_r8)) + endif + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi = 1._r8 + dqsidt*xxls/cpp + +! get ice size distribution parameters + if (qiic(i,k).ge.qsmall) then + lami(k) = (cons1*ci* & + niic(i,k)/qiic(i,k))**(1._r8/di) + n0i(k) = niic(i,k)*lami(k) + +! check for slope +! adjust vars + if (lami(k).lt.lammini) then + lami(k) = lammini + n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1) + else if (lami(k).gt.lammaxi) then + lami(k) = lammaxi + n0i(k) = lami(k)**(di + 1._r8)*qiic(i,k)/(ci*cons1) + end if + epsi = 2._r8*pi*n0i(k)*rho(i,k)*Dv(i,k)/(lami(k)*lami(k)) + +! liquid must exist +#ifdef GFDL_COMPATIBLE_MICROP + if (qc(i,k) + dqcdt(i,k)*deltat .gt. qsmall) then +#else + if (qc(i,k) .gt. qsmall) then +#endif + +! calculate Bergeron process + prd = epsi*(qvl - qvi)/abi + else + prd = 0._r8 + end if + +! multiply by cloud fraction + prd = prd*min(icldm(i,k), lcldm(i,k)) + +! transfer of existing cloud liquid to ice + berg(i,k) = max(0._r8, prd) + end if !end qiic exists bergeron + + if (berg(i,k).gt.0._r8) then +#ifdef GFDL_COMPATIBLE_MICROP + if( lflag ) then + bergtsf = max(0._r8, (qc(i,k)/berg(i,k))/deltat) + if (bergtsf.lt.1._r8) berg(i,k) = max(0._r8, & + qc(i,k)/deltat) + else + bergtsf = max(0._r8, & + ((dqcdt(i,k) + qc(i,k)/deltat)/berg(i,k))) + + if (bergtsf.lt.1._r8) berg(i,k) = & + max(0._r8, dqcdt(i,k) + qc(i,k)/deltat) + endif +#else + bergtsf = max(0._r8, (qc(i,k)/berg(i,k))/deltat) + if (bergtsf.lt.1._r8) berg(i,k) = max(0._r8, & + qc(i,k)/deltat) +#endif + endif +#ifdef GFDL_COMPATIBLE_MICROP +! Marc includes a restriction on berg at T < -40C + if (t(i,k) < tmelt - 40._r8 .and. & + ( .not. lflag ) ) then + berg(i,k) = 0._r8 + endif +#endif + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +#ifdef GFDL_COMPATIBLE_MICROP +! As per Marc, the following is inconsistent with the Tiedtke asumption +! of in-cloud RH = 1., so it is excluded in the Tiedtke case. + if ( .not. tiedtke_macrophysics) then +#endif + if (bergtsf.lt.1._r8.or.icldm(i,k).gt.lcldm(i,k)) then + if (qiic(i,k).ge.qsmall) then + +! first case is for case when liquid water is present, but is completely depleted in time step, i.e., bergrsf > 0 but < 1 + if (qc(i,k).ge.qsmall) then + rhin = (1.0_r8 + relhum(i,k)) / 2._r8 + if ((rhin*esl(i,k)/esi(i,k)) > 1._r8) then + prd = epsi*(rhin*qvl-qvi)/abi + +! multiply by cloud fraction assuming liquid/ice maximum overlap + prd = prd*min(icldm(i,k),lcldm(i,k)) + +! add to cmei + cmei(i,k) = cmei(i,k) + (prd * (1._r8- bergtsf)) + + end if ! rhin + end if ! qc > qsmall + +! second case is for pure ice cloud, either no liquid, or icldm > lcldm + + if (qc(i,k).lt.qsmall.or.icldm(i,k).gt.lcldm(i,k)) & + then + +! note: for case of no liquid, need to set liquid cloud fraction to zero +! store liquid cloud fraction in 'dum' + if (qc(i,k).lt.qsmall) then + dum=0._r8 + else + dum=lcldm(i,k) + end if + +! set RH to grid-mean value for pure ice cloud + rhin = relhum(i,k) + if ((rhin*esl(i,k)/esi(i,k)) > 1._r8) then + prd = epsi*(rhin*qvl-qvi)/abi + +! multiply by relevant cloud fraction for pure ice cloud +! assuming maximum overlap of liquid/ice + prd = prd*max((icldm(i,k)-dum),0._r8) + cmei(i,k) = cmei(i,k) + prd + end if ! rhin + end if ! qc or icldm > lcldm + end if ! qiic .ge.qsmall + end if ! bergtsf or icldm > lcldm + +! if deposition, it should not reduce grid mean rhi below 1.0 + if (cmei(i,k) > 0.0_r8 .and. & + (relhum(i,k)*esl(i,k)/esi(i,k)) > 1._r8 ) & + cmei(i,k) = min(cmei(i,k), & + (q(i,k)-qs(i)*esi(i,k)/esl(i,k))/abi/deltat) + +#ifdef GFDL_COMPATIBLE_MICROP + endif ! (tiedtke_macrophysics) +#endif + end if !end ice exists loop qi(i,k).gt.qsmall + end if ! t(i,k).lt.tmelt + +#ifdef GFDL_COMPATIBLE_MICROP + endif ! (do_berg1 .or. do_clubb>0) +#endif + +!!!!! END OF BERGERON CALCULATION + +#ifdef GFDL_COMPATIBLE_MICROP +! evaporation should not exceed available water + if( lflag ) then + if ((-berg(i,k)).lt.-qc(i,k)/deltat) & + berg(i,k) = max(qc(i,k)/deltat, 0._r8) + endif +#else + if ((-berg(i,k)).lt.-qc(i,k)/deltat) & + berg(i,k) = max(qc(i,k)/deltat, 0._r8) +#endif + +#ifdef GFDL_COMPATIBLE_MICROP +! if Tiedtke scheme, this already supplied in input args -- calculated +! in nc_cond.F90 for Tiedtke scheme + + if (.not. tiedtke_macrophysics) then +#endif + +! sublimation process... + + if ((relhum(i,k)*esl(i,k)/esi(i,k)).lt.1._r8 .and. & + qiic(i,k).ge.qsmall ) then + qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8-epsqs)*esi(i,k)) + qvl = epsqs*esl(i,k)/(p(i,k) - (1._r8-epsqs)*esl(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi = 1._r8 + dqsidt*xxls/cpp + +! get ice size distribution parameters + lami(k) = (cons1*ci*niic(i,k)/qiic(i,k))**(1._r8/di) + n0i(k) = niic(i,k)*lami(k) + +! check for slope +! adjust vars + if (lami(k).lt.lammini) then + lami(k) = lammini + n0i(k) = lami(k)**(di + 1._r8)*qiic(i,k)/(ci*cons1) + else if (lami(k).gt.lammaxi) then + lami(k) = lammaxi + n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1) + end if + + epsi = 2._r8*pi*n0i(k)*rho(i,k)*Dv(i,k)/(lami(k)*lami(k)) + +! modify for ice fraction below + prd = epsi*(relhum(i,k)*qvl-qvi)/abi*icldm(i,k) + cmei(i,k) = min(prd, 0._r8) + endif + +! sublimation should not exceed available ice + if (cmei(i,k).lt.-qi(i,k)/deltat) cmei(i,k) = -qi(i,k)/deltat + +! sublimation should not increase grid mean rhi above 1.0 + if (cmei(i,k) < 0.0_r8 .and. & + (relhum(i,k)*esl(i,k)/esi(i,k)) < 1._r8 ) & + cmei(i,k) = min(0._r8, max(cmei(i,k), & + (q(i,k) - qs(i)*esi(i,k)/esl(i,k))/abi/deltat)) + +#ifdef GFDL_COMPATIBLE_MICROP + endif ! tiedtke_macrophysics +#endif + + cmei(i,k) = cmei(i,k)*omsm + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) & + cmel(i,k) = cmel(i,k)*omsm +#endif + +! calculate ice nucleation dum2i + +#ifdef GFDL_COMPATIBLE_MICROP + if (t(i,k).lt.(tmelt - 5._r8)) then + if ( liu_in) then + dum2i(i,k) = naai(i,k) + elseif ( Nml%do_ice_nucl_wpdf ) THEN +! using Liu et al. (2007) ice nucleation with hooks into simulated aerosol +! ice nucleation rate (dum2) has already been calculated and read in (naai) + +! if aerosols interact with ice set number of activated ice nuclei + if (total_activation) then + dum2i(i,k) = naai(i,k) + else if (dqa_activation) then + dum2i(i,k) = naai(i,k) + endif + else +! cooper curve (factor of 1000 is to convert from L-1 to m-3) + dum2i(i,k)=0.005_r8*exp(0.304_r8*(tmelt -t(i,k)))*1000._r8 +! put limit on number of nucleated crystals, set to number at T=-30 C +! cooper (limit to value at -35 C) + dum2i(i,k)=min(dum2i(i,k),208.9e3_r8)/rho(i,k) ! convert from + ! m-3 to kg-1 + endif + else + dum2i(i,k)=0._r8 + end if ! t(i,k).lt.(tmelt - 5._r8) +#else + if (t(i,k) .lt. (tmelt - 5._r8)) then + if (liu_in) then +! using Liu et al. (2007) ice nucleation with hooks into simulated aerosol +! ice nucleation rate (dum2) has already been calculated and read in (naai) + +! if aerosols interact with ice set number of activated ice nuclei + dum2i(i,k) = naai(i,k) + else +! cooper curve (factor of 1000 is to convert from L-1 to m-3) + dum2i(i,k)=0.005_r8*exp(0.304_r8*(273.15_r8-t(i,k)))*1000._r8 +! put limit on number of nucleated crystals, set to number at T=-30 C +! cooper (limit to value at -35 C) + dum2i(i,k)=min(dum2i(i,k),208.9e3_r8)/rho(i,k) ! convert from + ! m-3 to kg-1 + endif + else + dum2i(i,k)=0._r8 + end if ! t(i,k).lt.(tmelt - 5._r8) +#endif + + end do ! i loop + end do ! k loop + +#ifndef GFDL_COMPATIBLE_MICROP + cldo(:ncol,:)=cldn(:ncol,:) +#endif + + +#ifdef GFDL_COMPATIBLE_MICROP +! code for pdf cloud option -- THIS HAS NOT BEEN TESTED AT ALL !! + +! re-calculate cloud fraction + IF (Nml%do_pdf_clouds .AND. & + (Nml%super_ice_opt .EQ. 1 .OR. Nml%super_ice_opt .EQ. 2)) THEN + IF (Nml%super_ice_opt .EQ. 1 ) THEN + + DO k=1,pver + DO i= 1,ncol + ttmp = t(i,k) + IF (ttmp .LT. tmelt - 40._r8 .OR. (ttmp .LE. tmelt .AND. & + qc(i,k) + (cmel(i,k) - berg(i,k))/deltat .LT. & + 3._r8*Nml%qmin)) THEN + eslt = polysvp(ttmp,1) + ELSE + eslt = polysvp(ttmp,0) + END IF + qs_d = p(i,k) - d378*eslt + qs_d = max(qs_d,eslt) + qs2d(i,k) = epsqs*eslt/qs_d + END DO + END DO + END IF + + IF ( Nml%super_ice_opt .EQ. 2 ) THEN + DO k=1,pver + DO i= 1,ncol + ttmp = t(i,k) + IF (ttmp .LT. tmelt - 40._r8 .OR. (ttmp .LE. tmelt .AND. & + qc(i,k) + ( cmel(i,k) - berg(i,k))/deltat .LT. & + 3._r8*Nml%qmin) ) THEN + eslt = polysvp(ttmp,1) + tc=ttmp-tmelt +!!! rhi=MIN( max_super_ice , 0.000195*tc**2+0.00266*tc+1.005) + rhi = 0.000195_r8*tc**2+0.00266_r8*tc+1.005_r8 + ELSE + eslt = polysvp(ttmp,0) + rhi = 1._r8 + END IF + qs_d = p(i,k) - d378*eslt + qs_d = max(qs_d,eslt) + qs2d(i,k)= rhi * epsqs*eslt/qs_d + END DO + END DO + END IF + qtot = qn+qc_in+qi_in + + IF ( Nml%pdf_org ) call error_mesg ( 'cldwat2m_micro', & + 'ERROR 1 simple_pdf ', FATAL) + CALL simple_pdf(j, ncol, jdim, pver, Nml%qmin, qa0, qtot, & + qs2d, gamma_mg, Nml%qthalfwidth, Nml%betaP, & + 1._r8/deltat, SA_0, n_diag_4d, diag_4d, & + diag_id, diag_pt, SA, cldn) + + do k=1,pver + do i=1,ncol + cldm(i,k)=max(cldn (i,k),mincld) + lcldm(i,k)=cldm(i,k) + icldm(i,k)=cldm(i,k) + end do + end do + END IF +#endif + +!! initialize sub-step precip flux variables +!! flux is zero at top interface. +! do i=1,ncol +! rflx1(i,1)=0._r8 +! sflx1(i,1)=0._r8 +! end do + do k=1,pver+1 + do i=1,ncol + rflx1(i,k)=0._r8 + sflx1(i,k)=0._r8 + end do + end do + +!! initialize final precip flux variables. +!! flux is zero at top interface, so these should stay as 0. +! do i=1,ncol +! rflx(i,1)=0._r8 +! sflx(i,1)=0._r8 + do k=1,pver+1 + do i=1,ncol + rflx(i,k)=0._r8 + sflx(i,k)=0._r8 + end do + end do + +! skip microphysical calculations if no cloud water + do i=1,ncol + ltrue(i)=0 + do k=1,pver + +#ifndef GFDL_COMPATIBLE_MICROP + if (qc(i,k).ge.qsmall .or. qi(i,k).ge.qsmall.or. & + cmei(i,k).ge.qsmall ) ltrue(i) = 1 +#endif +#ifdef GFDL_COMPATIBLE_MICROP + if( lflag ) then + if (qc(i,k).ge.qsmall.or.qi(i,k).ge.qsmall.or.cmei(i,k).ge.qsmall) ltrue(i)=1 + else + if (qc(i,k).ge.qsmall .or. qi(i,k).ge.qsmall .or. & + cmei(i,k).ge.qsmall .or. cmel(i,k).ge.qsmall) ltrue(i) = 1 +!cms also skip if total water amount is negative anywhere within the column + if ( qc(i,k) + qi(i,k) + qn(i,k) .lt. -1.e-9_r8 .OR. & + qn(i,k) .lt. -1.e-9_r8 ) then + ltrue(i)=0 + end if ! (qc(i,k) + qi(i,k) + qn(i,k) .lt. -1.e-9_r8 .OR. ... ) + end if ! ( lflag ) +#endif + end do + end do + +! assign number of sub-steps to iter +! use 2 sub-steps, following tests described in MG2008 + + iter = 2 + +! get sub-step time step + deltat = deltat/real(iter) + +! since activation/nucleation processes are fast, need to take into account +! factor mtime = mixing timescale in cloud / model time step +! mixing time can be interpreted as cloud depth divided by sub-grid +! vertical velocity +! for now mixing timescale is assumed to be 1 timestep for modal aerosols, +! 20 min bulk +! note: mtime for bulk aerosols was set to: mtime=deltat/1200._r8 + + mtime=1._r8 + rate1ord_cw2pr_st(:,:)=0._r8 ! rce 2010/05/01 + +!!!! skip calculations if no cloud water +! define output fields if doing so. + do i=1,ncol + if (ltrue(i).eq.0) then + tlat(i,1:pver)=0._r8 + qvlat(i,1:pver)=0._r8 + qctend(i,1:pver)=0._r8 + qitend(i,1:pver)=0._r8 + qnitend(i,1:pver)=0._r8 + qrtend(i,1:pver)=0._r8 + nctend(i,1:pver)=0._r8 + nitend(i,1:pver)=0._r8 + nrtend(i,1:pver)=0._r8 + nstend(i,1:pver)=0._r8 + prect(i)=0._r8 + preci(i)=0._r8 + qniic(i,1:pver)=0._r8 + qric(i,1:pver)=0._r8 + nsic(i,1:pver)=0._r8 + nric(i,1:pver)=0._r8 + rainrt(i,1:pver)=0._r8 +!6/6/12 +#ifdef GFDL_COMPATIBLE_MICROP + ssat_disposal(i,1:pver) =0._r8 +#endif + goto 300 + end if + + qcsinksum_rate1ord(1:pver) = 0._r8 + qcsum_rate1ord(1:pver) = 0._r8 + +#ifdef GFDL_COMPATIBLE_MICROP + cmel_orig(i,1:pver) = cmel(i,1:pver) + cmei_orig(i,1:pver) = cmei(i,1:pver) + + + berg_orig(i,1:pver) = berg(i,1:pver) +#endif + + +!!!!!!!!! BEGIN SUB-STEP LOOP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!....................................................................... + do it=1,iter + +! initialize sub-step microphysical tendencies + tlat(i,1:pver)=0._r8 + qvlat(i,1:pver)=0._r8 + qctend(i,1:pver)=0._r8 + qitend(i,1:pver)=0._r8 + qnitend(i,1:pver)=0._r8 + qrtend(i,1:pver)=0._r8 + nctend(i,1:pver)=0._r8 + nitend(i,1:pver)=0._r8 + nrtend(i,1:pver)=0._r8 + nstend(i,1:pver)=0._r8 + +! initialize diagnostic precipitation to zero + + qniic(i,1:pver)=0._r8 + qric(i,1:pver)=0._r8 + nsic(i,1:pver)=0._r8 + nric(i,1:pver)=0._r8 + + rainrt(i,1:pver)=0._r8 + + +! initialize vertically-integrated rain and snow tendencies + + qrtot = 0._r8 + nrtot = 0._r8 + qstot = 0._r8 + nstot = 0._r8 + +! initialize precip at surface + + prect(i)=0._r8 + preci(i)=0._r8 + +! begin new i,k loop. + do k=1,pver + +! set cwml and cwmi to current qc and qi + cwml(i,k) = qc(i,k) + cwmi(i,k) = qi(i,k) + +! initialize precip fallspeeds to zero + ums(k)=0._r8 + uns(k)=0._r8 + umr(k)=0._r8 + unr(k)=0._r8 + +#ifdef GFDL_COMPATIBLE_MICROP +! set erosion, bergeron and condensation fields to input values + if( .not. lflag ) then + nerosi(i,k) = nerosi4(i,k) + nerosc(i,k) = nerosc4(i,k) + D_eros_l(i,k) = D_eros_l4(i,k) + D_eros_i(i,k) = D_eros_i4(i,k) + cmel(i,k) = cmel_orig(i,k) + cmei(i,k) = cmei_orig(i,k) + berg(i,k) = berg_orig(i,k) + endif +#endif + +! calculate new cldmax after adjustment to cldm above +! calculate precip fraction based on maximum overlap assumption + +! for sub-columns cldm has already been set to 1 if cloud +! water or ice is present, so cldmax will be correctly set below +! and nothing extra needs to be done here + + if (k.eq.1) then + cldmax(i,k)=cldm(i,k) + else +! if rain or snow mix ratio is smaller than +! threshold, then set cldmax to cloud fraction at current level + if (qric(i,k-1).ge.qsmall.or.qniic(i,k-1).ge.qsmall) then + cldmax(i,k)=max(cldmax(i,k-1),cldm(i,k)) + else + cldmax(i,k)=cldm(i,k) + end if + end if + +#ifdef GFDL_COMPATIBLE_MICROP +! nsubc(k) = 0._r8 +! nsubi(k) = 0._r8 + if ( .not. tiedtke_macrophysics) then +! decrease in number concentration due to sublimation/evap +! divide by cloud fraction to get in-cloud decrease +! don't reduce Nc due to bergeron process + + if (cmei(i,k) < 0._r8 .and. qi(i,k) > qsmall .and. & + cldm(i,k) > mincld) then + nsubi(k)=cmei(i,k)/qi(i,k)*ni(i,k)/cldm(i,k) + else + nsubi(k) = 0._r8 + end if + +!!SHOULD NSUBC be nonzero ?? NCAR says no, MG includes code but it is +!! not activated with Tiedtke. Should it be activated in general for +!! non-Tiedtke case ?? + if( lflag ) then + nsubc(k) = 0._r8 ! (do_clubb >0) + else + if (cmel(i,k) < 0._r8 .AND. qc(i,k) .ge. qsmall & + .and. cldm(i,k) > mincld ) then + nsubc(k) = cmel(i,k)/qc(i,k)*nc(i,k)/cldm(i,k) + else + nsubc(k) = 0._r8 + end if ! (cmel(i,k) < 0._r8 .AND. qc(i,k) .ge. qsmall + endif ! (do_clubb <=0) + else ! tiedtke_macrophysics + nsubc(k) = 0._r8 + nsubi(k) = 0._r8 + endif ! tiedtke_macrophysics +#else +! decrease in ice number concentration due to sublimation/evap +! divide by cloud fraction to get in-cloud decrease +! don't reduce Nc due to bergeron process + + if (cmei(i,k) < 0._r8 .and. qi(i,k) > qsmall .and. & + cldm(i,k) > mincld) then + nsubi(k) = cmei(i,k)/qi(i,k)*ni(i,k)/cldm(i,k) + else + nsubi(k) = 0._r8 + end if + nsubc(k) = 0._r8 +#endif + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! calculate ice nucleation +! ice nucleation if activated nuclei exist at t<-5C AND rhmini + 5% +! note: this is gridbox averaged + +#ifndef GFDL_COMPATIBLE_MICROP + + if (dum2i(i,k).gt.0._r8.and.t(i,k).lt.(tmelt - 5._r8).and. & + relhum(i,k)*esl(i,k)/esi(i,k).gt. rhmini + 0.05_r8) then + +!if NCAI > 0. then set numice = ncai (as before) + nnuccd(k) = (dum2i(i,k) - ni(i,k)/icldm(i,k))/deltat* & + icldm(i,k) + nnuccd(k) = max(nnuccd(k), 0._r8) + nimax = dum2i(i,k)*icldm(i,k) + +!Calc mass of new particles using new crystal mass... +!also this will be multiplied by mtime as nnuccd is... + mnuccd(k) = nnuccd(k)*mi0 + +! add mnuccd to cmei.... + cmei(i,k) = cmei(i,k) + mnuccd(k)*mtime + +! limit cmei + qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8-epsqs)*esi(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi = 1._r8 + dqsidt*xxls/cpp + cmei(i,k) =min(cmei(i,k), (q(i,k) - qvi)/abi/deltat) + +! limit for roundoff error + cmei(i,k) = cmei(i,k)*omsm + + else + nnuccd(k) =0._r8 + nimax = 0._r8 + mnuccd(k) = 0._r8 + end if +#endif + +#ifdef GFDL_COMPATIBLE_MICROP +! Note that ice nucleation calculated later on in code for +! Tiedtke macrophysics case. + if (.not. tiedtke_macrophysics) then + if (dum2i(i,k).gt.0._r8.and.t(i,k).lt.(tmelt - 5._r8).and. & + relhum(i,k)*esl(i,k)/esi(i,k).gt. rhmini+0.05_r8) then + if( liu_in ) then + nnuccd(k) = (dum2i(i,k) - ni(i,k)/icldm(i,k))/deltat* & + icldm(i,k) + nnuccd(k) = max(nnuccd(k), 0._r8) + elseif (total_activation) then + nnuccd(k) = (dum2i(i,k) - ni(i,k)/icldm(i,k))/deltat* & + icldm(i,k) + nnuccd(k) = max(nnuccd(k), 0._r8) + else if (dqa_activation) then + nnuccd(k) = max(delta_cf(i,k),0._r8) *dum2i(i,k)/deltatin + endif + nimax = dum2i(i,k)*icldm(i,k) + + if (.not. dqa_activation) then + +!Calc mass of new particles using new crystal mass... +!also this will be multiplied by mtime as nnuccd is... + mnuccd(k) = nnuccd(k) * mi0 + +! add mnuccd to cmei.... + cmei(i,k)= cmei(i,k) + mnuccd(k) * mtime + +! limit cmei + qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8-epsqs)*esi(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi = 1._r8 + dqsidt*xxls/cpp + cmei(i,k) = min(cmei(i,k),(q(i,k) - qvi)/abi/deltat) + +! limit for roundoff error + cmei(i,k)=cmei(i,k)*omsm + else + mnuccd(k) = 0. + endif ! (dqa_activation) + else + nnuccd(k)=0._r8 + nimax = 0._r8 + mnuccd(k) = 0._r8 + end if + endif ! (tiedtke_macrophyics) +#endif + +!c........................................................................ +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! obtain in-cloud values of cloud water/ice mixing ratios and number +! concentrations for microphysical process calculations +! units are kg/kg for mixing ratio, 1/kg for number conc + +! limit in-cloud values to 0.005 kg/kg + + qcic(i,k) = min(cwml(i,k)/lcldm(i,k), 5.e-3_r8) + qiic(i,k) = min(cwmi(i,k)/icldm(i,k), 5.e-3_r8) + ncic(i,k) = max(nc(i,k)/lcldm(i,k),0._r8) + niic(i,k) = max(ni(i,k)/icldm(i,k),0._r8) + +!-->cjg +! hm add 6/2/11 specify droplet concentration + if (nccons) then + ncic(i,k)=ncnst/rho(i,k) + end if + +! hm add 6/2/11 switch for specification of cloud ice number + if (nicons) then + niic(i,k)=ninst/rho(i,k) + end if +!<--cjg + +! adjust previously calculated tendencies to avoid creating negative +! water species + +#ifdef GFDL_COMPATIBLE_MICROP + if( lflag ) then + if (qc(i,k) - berg(i,k)*deltat.lt.qsmall) then + qcic(i,k)=0._r8 + ncic(i,k)=0._r8 + if (qc(i,k)-berg(i,k)*deltat.lt.0._r8) then + berg(i,k)=qc(i,k)/deltat*omsm + end if + end if + + if (qi(i,k) + (cmei(i,k) + berg(i,k))*deltat.lt.qsmall) then + qiic(i,k)=0._r8 + niic(i,k)=0._r8 + if (qi(i,k) + (cmei(i,k) + berg(i,k))*deltat.lt.0._r8) then + cmei(i,k) = (-qi(i,k)/deltat - berg(i,k))*omsm + end if + end if + + else + if (qc(i,k) + (cmel(i,k) + D_eros_l(i,k) - & + berg(i,k))*deltat.lt.qsmall) then + qcic(i,k)=0._r8 + ncic(i,k)=0._r8 + if (qc(i,k) + (cmel(i,k) + D_eros_l(i,k) - & + berg(i,k))*deltat.lt.0._r8) then + if (cmel(i,k).lt.0._r8) then + !++ first only scale cmel, d_eros + dum = -cmel(i,k) - D_eros_l(i,k) + if (dum .gt. 1.e-30_r8) then + dum3 = qc(i,k)/deltat/dum*omsm + else + dum3 = 0._r8 + end if + cmel(i,k) = dum3*cmel(i,k) + D_eros_l(i,k) = dum3*D_eros_l(i,k) + dum = -cmel(i,k) - D_eros_l(i,k) + berg(i,k) + if (dum .gt. 1.e-30_r8) then + dum3 = qc(i,k)/deltat/dum*omsm + else + dum3 = 0._r8 + end if + cmel(i,k) = dum3*cmel(i,k) + D_eros_l(i,k) = dum3*D_eros_l(i,k) + berg(i,k) = dum3*berg(i,k) + else + dum = -D_eros_l(i,k) + berg(i,k) + if (dum .gt. 1.e-30_r8) then + dum3 = ( qc(i,k)/deltat + cmel(i,k) ) / dum * omsm + else + dum3 = 0._r8 + end if + D_eros_l(i,k) = D_eros_l(i,k)*dum3 + berg(i,k) = berg(i,k)*dum3 + endif + endif + end if + + if (qi(i,k) + (cmei(i,k) + D_eros_i(i,k) + berg(i,k))* & + deltat.lt.qsmall) then + qiic(i,k)=0._r8 + niic(i,k)=0._r8 + if (qi(i,k) + (cmei(i,k) + D_eros_i(i,k) + berg(i,k))* & + deltat.lt.0._r8) then + if (cmei(i,k).lt.0._r8) then + dum = - cmei(i,k) - D_eros_i(i,k) + if (dum .gt. 1.e-30_r8) then + dum3 = (qi(i,k)/deltat + berg(i,k))/dum*omsm + else + dum3 = 0._r8 + end if + cmei(i,k) = dum3 * cmei(i,k) + D_eros_i(i,k) = dum3 * D_eros_i(i,k) + else + dum = - D_eros_i(i,k) + if (dum .gt. 1.e-30_r8) then + dum3 = (qi(i,k)/deltat + cmei(i,k) + berg(i,k))/ & + dum*omsm + else + dum3 = 0._r8 + end if + D_eros_i(i,k) = dum3*D_eros_i(i,k) + end if + end if + end if + + endif +#else + if (qc(i,k) - berg(i,k)*deltat.lt.qsmall) then + qcic(i,k) = 0._r8 + ncic(i,k) = 0._r8 + if (qc(i,k) - berg(i,k)*deltat.lt.0._r8) then + berg(i,k) = qc(i,k)/deltat*omsm + end if + end if + + if (qi(i,k) + (cmei(i,k) + berg(i,k))*deltat.lt.qsmall) then + qiic(i,k)=0._r8 + niic(i,k)=0._r8 + if (qi(i,k) + (cmei(i,k) + berg(i,k))*deltat.lt.0._r8) then + cmei(i,k) = (-qi(i,k)/deltat - berg(i,k))*omsm + end if + end if +#endif + +! add to cme output + cmeout(i,k) = cmeout(i,k) + cmei(i,k) + +#ifdef GFDL_COMPATIBLE_MICROP +! calculate ice nuclei activation for tiedtke macrophysics +! note: this is gridbox averaged + if ( tiedtke_macrophysics) then + if (qiic(i,k).ge.qsmall .and. t(i,k).lt.tmelt - 5._r8) then + if (total_activation) then + nnuccd(k) = (dum2i(i,k) - ni(i,k)/icldm(i,k))/deltat* & + icldm(i,k) + nnuccd(k) = max(nnuccd(k), 0._r8) + else if (dqa_activation) then + nnuccd(k) = max(delta_cf(i,k),0._r8)*dum2i(i,k)/deltatin + endif + nimax = dum2i(i,k)*icldm(i,k) +! if (.not. dqa_activation) then + +!Calc mass of new particles using new crystal mass... +!also this will be multiplied by mtime as nnuccd is... +! mnuccd(k) = nnuccd(k) * mi0 + +! add mnuccd to cmei.... +! cmei(i,k) = cmei(i,k) + mnuccd(k)*mtime + +! limit cmei +! qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8-epsqs)*esi(i,k)) +! dqsidt = xxls*qvi/(rv*t(i,k)**2) +! abi = 1._r8 + dqsidt*xxls/cpp +! cmei(i,k) = min(cmei(i,k), (q(i,k)-qvi)/abi/deltat) + +! limit for roundoff error +! cmei(i,k) = cmei(i,k)*omsm +! else +! mnuccd(k) = 0. +! endif !(dqa_activation) + mnuccd(k) = 0._r8 + else + nnuccd(k)=0._r8 + nimax = 0._r8 + mnuccd(k) = 0._r8 + end if + endif ! (tiedtke_macrophysics) +#endif + + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! droplet activation +! calculate potential for droplet activation if cloud water is present +! formulation from Abdul-Razzak and Ghan (2000) and Abdul-Razzak et al. (1998), AR98 +! number (npccnin) is read in from companion routine + +! assume aerosols already activated are equal to number of existing droplets for simplicity +! multiply by cloud fraction to obtain grid-average tendency + +#ifdef GFDL_COMPATIBLE_MICROP + if (qcic(i,k).ge.qsmall) then + if( lflag ) then + npccn(k) = max(0._r8, npccnin(i,k)) + dum2l(i,k) = (nc(i,k) + npccn(k)*deltat)/cldm(i,k) + dum2l(i,k) = max(dum2l(i,k), cdnl/rho(i,k)) ! sghan minimum + ! in #/cm3 + ncmax = dum2l(i,k)*cldm(i,k) + + else + IF ( total_activation) THEN + dum2l(i,k) = max(0._r8, npccnin(i,k)) + npccn(k) = ((dum2l(i,k) - nc(i,k)/cldm(i,k))/deltat)* & + cldm(i,k) + npccn(k) = max(0._r8,npccn(k)) + dum2l(i,k) = (nc(i,k) + npccn(k)*deltat)/cldm(i,k) + dum2l(i,k) = max(dum2l(i,k), cdnl/rho(i,k)) ! sghan minimum + ! in #/cm3 + ELSE IF ( dqa_activation ) THEN +!delta_cf: A_dt * (1.-qabar) where A_dt = A*dt , A source rate +! Eq. 7 of Yi's 2007 paper +!dum2l has already been multiplied by 1.e6/airdens(i,k) + npccn(k) = max (delta_cf(i,k), 0._r8)*npccnin(i,k)/deltatin + dum2l(i,k) = (nc(i,k) + npccn(k)*deltat)/cldm(i,k) + END IF + ncmax = npccnin(i,k)*cldm(i,k) + endif + else + npccn(k)=0._r8 + ncmax = 0._r8 + dum2l(i,k) = 0._r8 + end if +#else + if (qcic(i,k).ge.qsmall) then + npccn(k) = max(0._r8, npccnin(i,k)) + dum2l(i,k) = (nc(i,k) + npccn(k)*deltat)/cldm(i,k) + dum2l(i,k) = max(dum2l(i,k),cdnl/rho(i,k)) ! sghan minimum + ! in #/cm3 + ncmax = dum2l(i,k)*cldm(i,k) + else + npccn(k)=0._r8 + dum2l(i,k)=0._r8 + ncmax = 0._r8 + end if +#endif + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! get size distribution parameters based on in-cloud cloud water/ice +! the calculations also ensure consistency between number and mixing ratio +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + +!...................................................................... +! cloud ice + + if (qiic(i,k).ge.qsmall) then + +! impose upper limit on in-cloud number concentration to prevent numerical +! error + niic(i,k) = min(niic(i,k), qiic(i,k)*1.e20_r8) + lami(k) = (cons1*ci*niic(i,k)/qiic(i,k))**(1._r8/di) + n0i(k) = niic(i,k)*lami(k) +! check for slope +! adjust vars + if (lami(k).lt.lammini) then + lami(k) = lammini + n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1) + niic(i,k) = n0i(k)/lami(k) + else if (lami(k).gt.lammaxi) then + lami(k) = lammaxi + n0i(k) = lami(k)**(di+1._r8)*qiic(i,k)/(ci*cons1) + niic(i,k) = n0i(k)/lami(k) + end if + else + lami(k) = 0._r8 + n0i(k) = 0._r8 + end if !qiic(i,k).ge.qsmall + + if (qcic(i,k).ge.qsmall) then + +! add upper limit to in-cloud number concentration to prevent numerical +! error + ncic(i,k) = min(ncic(i,k), qcic(i,k)*1.e20_r8) + ncic(i,k) = max(ncic(i,k), cdnl/rho(i,k)) ! sghan minimum + ! in #/cm + +! get pgam from fit to observations of martin et al. 1994 + pgam(k) = 0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k)) + & + 0.2714_r8 + pgam(k) = 1._r8/(pgam(k)**2) - 1._r8 + pgam(k) = max(pgam(k), 2._r8) + pgam(k) = min(pgam(k), 15._r8) + +! calculate lamc + lamc(k) = (pi/6._r8*rhow*ncic(i,k)*gamma(pgam(k) + 4._r8)/ & + (qcic(i,k)*gamma(pgam(k) + 1._r8)))**(1._r8/3._r8) + +! lammin, 50 micron diameter max mean size + lammin = (pgam(k) + 1._r8)/50.e-6_r8 + lammax = (pgam(k) + 1._r8)/2.e-6_r8 + + if (lamc(k).lt.lammin) then + lamc(k) = lammin + ncic(i,k) = 6._r8*lamc(k)**3*qcic(i,k)* & + gamma(pgam(k)+1._r8)/ & + (pi*rhow*gamma(pgam(k) + 4._r8)) + else if (lamc(k).gt.lammax) then + lamc(k) = lammax + ncic(i,k) = 6._r8*lamc(k)**3*qcic(i,k)* & + gamma(pgam(k)+1._r8)/ & + (pi*rhow*gamma(pgam(k) + 4._r8)) + end if + +! parameter to calculate droplet freezing + cdist1(k) = ncic(i,k)/gamma(pgam(k) + 1._r8) + else + lamc(k) = 0._r8 + cdist1(k) = 0._r8 + end if + +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! begin micropysical process calculations +!................................................................. +! autoconversion of cloud liquid water to rain +! formula from Khrouditnov and Kogan (2000), modified for sub-grid distribution of qc +! minimum qc of 1 x 10^-8 prevents floating point error + + if (qcic(i,k).ge.1.e-8_r8) then + +! nprc is increase in rain number conc due to autoconversion +! nprc1 is decrease in cloud droplet conc due to autoconversion +! assume exponential sub-grid distribution of qc, resulting in additional +! factor related to qcvar below + + ! hm switch for sub-columns, don't include sub-grid qc + if (sub_column) then + prc(k) = 1350._r8*qcic(i,k)**2.47_r8* & + (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8) + nprc(k) = prc(k)/(4._r8/3._r8*pi*rhow*(25.e-6_r8)**3) + nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k)) + else +#ifdef GFDL_COMPATIBLE_MICROP + if( present(qcvar_clubb) ) then + prc(k) = gamma(qcvar_clubb(i,k)+2.47_r8)/(gamma(qcvar_clubb(i,k))*qcvar_clubb(i,k)**2.47_r8)*1350._r8*qcic(i,k)**2.47_r8* & + (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8) + else + prc(k) = cons2/(cons3*cons18)*1350._r8*qcic(i,k)**2.47_r8* & + (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8) + endif +#else + prc(k) = cons2/(cons3*cons18)*1350._r8*qcic(i,k)**2.47_r8*& + (ncic(i,k)/1.e6_r8*rho(i,k))**(-1.79_r8) +#endif + nprc(k) = prc(k)/cons22 + nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k)) + end if ! sub-column switch + else + prc(k)=0._r8 + nprc(k)=0._r8 + nprc1(k)=0._r8 + end if + +! add autoconversion to precip from above to get provisional rain mixing +! ratio and number concentration (qric and nric) +! 0.45 m/s is fallspeed of new rain drop (80 micron diameter) + dum = 0.45_r8 + dum1 = 0.45_r8 + + if (k.eq.1) then + qric(i,k) = prc(k)*lcldm(i,k)*dz(i,k)/cldmax(i,k)/dum + nric(i,k) = nprc(k)*lcldm(i,k)*dz(i,k)/cldmax(i,k)/dum + else + if (qric(i,k-1).ge.qsmall) then + dum = umr(k-1) + dum1 = unr(k-1) + end if + +#ifdef GFDL_COMPATIBLE_MICROP + if (allow_all_cldtop_collection) then +! NCAR allows no autoconversion of rain number if rain/snow falling from +! above. this assumes that new drizzle drops formed by autoconversion are +! rapidly collected by the existing rain/snow particles falling from above. +! Marc's code allowed autoconversion to change rain number, so variable +! allow_all_cldtop_collection introduced, which when .true. would turn off +! this effect. By default, it is .false. for GFDL (as in MG), in contrast +! to what NCAR does (ifndef GFDL_COMPATIBLE_MICROP). + if (qric(i,k-1).ge.1.e-9_r8 .or. & + qniic(i,k-1).ge.1.e-9_r8) then + nprc(k)=0._r8 + end if + endif ! allow_all_cldtop_collection +#else +! no autoconversion of rain number if rain/snow falling from above +! this assumes that new drizzle drops formed by autoconversion are rapidly +! collected by the existing rain/snow particles from above + if (qric(i,k-1).ge.1.e-9_r8 .or. & + qniic(i,k-1).ge.1.e-9_r8) then + nprc(k)=0._r8 + end if +#endif + + qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ & + (rho(i,k)*dz(i,k)*((pra(k-1) + prc(k))* & + lcldm(i,k) + (pre(k-1) - pracs(k-1) - & + mnuccr(k-1))*cldmax(i,k))))/ & + (dum*rho(i,k)*cldmax(i,k)) + nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ & + (rho(i,k)*dz(i,k)*(nprc(k)*lcldm(i,k) + & + (nsubr(k-1) - npracs(k-1) - nnuccr(k-1) & + + nragg(k-1))*cldmax(i,k)))) & + /(dum1*rho(i,k)*cldmax(i,k)) + end if ! k > 1 + +!....................................................................... +! Autoconversion of cloud ice to snow +! similar to Ferrier (1994) +! note: assumes autoconversion timescale of 180 sec + + if (t(i,k).le.tmelt .and.qiic(i,k).ge.qsmall) then + nprci(k) = n0i(k)/(lami(k)*180._r8)*exp(-lami(k)*dcs) + prci(k) = pi*rhoi*n0i(k)/(6._r8*180._r8)* & + (cons23/lami(k) + 3._r8*cons24/lami(k)**2 + & + 6._r8*dcs/lami(k)**3 + & + 6._r8/lami(k)**4)*exp(-lami(k)*dcs) + else + prci(k)=0._r8 + nprci(k)=0._r8 + end if + +! add autoconversion to flux from level above to get provisional +! snow mixing ratio and number concentration (qniic and nsic) + dum = (asn(i,k)*cons25) + dum1 = (asn(i,k)*cons25) + if (k.eq.1) then + qniic(i,k) = prci(k)*icldm(i,k)*dz(i,k)/cldmax(i,k)/dum + nsic(i,k) = nprci(k)*icldm(i,k)*dz(i,k)/cldmax(i,k)/dum + else + if (qniic(i,k-1).ge.qsmall) then + dum = ums(k-1) + dum1 = uns(k-1) + end if + qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*((prci(k) + prai(k-1) + & + psacws(k-1) + bergs(k-1))*icldm(i,k) + & + (prds(k-1) + pracs(k-1) + mnuccr(k-1)) & + *cldmax(i,k))))& + /(dum*rho(i,k)*cldmax(i,k)) + nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ & + (rho(i,k)*dz(i,k)*(nprci(k)*icldm(i,k) + & + (nsubs(k-1) + nsagg(k-1) + nnuccr(k-1))* & + cldmax(i,k))))/(dum1*rho(i,k)*cldmax(i,k)) + end if ! k > 1 + +! if precip mix ratio is zero so should number concentration + if (qniic(i,k).lt.qsmall) then + qniic(i,k)=0._r8 + nsic(i,k)=0._r8 + end if + + if (qric(i,k).lt.qsmall) then + qric(i,k)=0._r8 + nric(i,k)=0._r8 + end if + +! make sure number concentration is a positive number to avoid +! taking root of negative later + + nric(i,k) = max(nric(i,k), 0._r8) + nsic(i,k) = max(nsic(i,k), 0._r8) + +!....................................................................... +! get size distribution parameters for precip +!...................................................................... +! rain + if (qric(i,k).ge.qsmall) then + lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._r8/3._r8) + n0r(k) = nric(i,k)*lamr(k) + +! check for slope +! adjust vars + if (lamr(k).lt.lamminr) then + lamr(k) = lamminr + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + else if (lamr(k).gt.lammaxr) then + lamr(k) = lammaxr + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + end if + +! provisional rain number and mass weighted mean fallspeed (m/s) + unr(k) = min(arn(i,k)*cons4/lamr(k)**br,9.1_r8*rhof(i,k)) + umr(k) = min(arn(i,k)*cons5/(6._r8*lamr(k)**br), & + 9.1_r8*rhof(i,k)) + else + lamr(k) = 0._r8 + n0r(k) = 0._r8 + umr(k) = 0._r8 + unr(k) = 0._r8 + end if ! qric(i,k).ge.qsmall + +!...................................................................... +! snow + + if (qniic(i,k).ge.qsmall) then + lams(k) = (cons6*cs*nsic(i,k)/ & + qniic(i,k))**(1._r8/ds) + n0s(k) = nsic(i,k)*lams(k) + +! check for slope +! adjust vars + if (lams(k).lt.lammins) then + lams(k) = lammins + n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6) + nsic(i,k) = n0s(k)/lams(k) + else if (lams(k).gt.lammaxs) then + lams(k) = lammaxs + n0s(k) = lams(k)**(ds+1._r8)*qniic(i,k)/(cs*cons6) + nsic(i,k) = n0s(k)/lams(k) + end if + +! provisional snow number and mass weighted mean fallspeed (m/s) + + ums(k) = min(asn(i,k)*cons8/(6._r8*lams(k)**bs), & + 1.2_r8*rhof(i,k)) + uns(k) = min(asn(i,k)*cons7/lams(k)**bs,1.2_r8*rhof(i,k)) + else + lams(k) = 0._r8 + n0s(k) = 0._r8 + ums(k) = 0._r8 + uns(k) = 0._r8 + end if ! qniic(i,k).ge.qsmall + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! heterogeneous freezing of cloud water + if (qcic(i,k).ge.qsmall .and. t(i,k).lt.tmelt - 4._r8 ) then + +! immersion freezing (Bigg, 1953) +! subcolumns + if (sub_column) then + mnuccc(k) = pi*pi/36._r8*rhow* & + cdist1(k)*gamma(7._r8+pgam(k))* & + bimm*(exp(aimm*(273.15_r8 - t(i,k))) - 1._r8)/ & + lamc(k)**3/lamc(k)**3 + nnuccc(k) = & + pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8)*bimm* & + (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamc(k)**3 + else +! ---> h1g, this is the MG 2011-02 version + if( present(qcvar_clubb) ) then + mnuccc(k) = gamma(qcvar_clubb(i,k)+2._r8)/(gamma(qcvar_clubb(i,k))*qcvar_clubb(i,k)**2)* & + pi*pi/36._r8*rhow* & + cdist1(k)*gamma(7._r8+pgam(k))* & + bimm*(exp(aimm*(273.15_r8-t(i,k)))-1._r8)/ & + lamc(k)**3/lamc(k)**3 + nnuccc(k) = gamma(qcvar_clubb(i,k)+1._r8)/(gamma(qcvar_clubb(i,k))*qcvar_clubb(i,k))* & + pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8) & + *bimm* & + (exp(aimm*(273.15_r8-t(i,k)))-1._r8)/lamc(k)**3 + else + mnuccc(k) = cons9/(cons3*cons19)* & + pi*pi/36._r8*rhow*cdist1(k)*gamma(7._r8+pgam(k))* & + bimm*(exp(aimm*(tmelt - t(i,k)))-1._r8)/ & + lamc(k)**3/lamc(k)**3 + nnuccc(k) = cons10/(cons3*qcvar)* & + pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8)*bimm* & + (exp(aimm*(tmelt - t(i,k))) - 1._r8)/lamc(k)**3 + endif +! <--- h1g, the MG 2011-02 version +! ---> h1g, this is the MG 2010-09 version + ! mnuccc(k) = cons9/(cons3*cons19)* & + ! pi*pi/36._r8*rhow* & + ! cdist1(k)*gamma(7._r8+pgam(k))* & + ! bimm*exp(aimm*(273.15_r8-t(i,k)))/ & + ! lamc(k)**3/lamc(k)**3 + ! + ! nnuccc(k) = cons10/(cons3*qcvar)* & + ! pi/6._r8*cdist1(k)*gamma(pgam(k)+4._r8) & + ! *bimm* & + ! exp(aimm*(273.15_r8-t(i,k)))/lamc(k)**3 +! <--- h1g, the MG 2010-09 version + end if ! sub-columns + +#ifdef GFDL_COMPATIBLE_MICROP +! contact freezing not currently availablein GFDL. Need to get proper +! dust input fields. + if( .not. lflag ) then + mnucct(k) = 0._r8 + nnucct(k) = 0._r8 + else +! contact freezing (-40-! uw_clouds_amt defines the distribution of cloud water and cloud ice -! amounts [ g / m**3 ] and liquid and ice particle sizes and total cloud -! fraction for the clouds associated with uw shallow convection. these -! values will later be combined with other cloud fields to produce the -! cloud radiative properties that will be seen by the radiation package. -! -! -!-! uw_clouds_amt defines the distribution of cloud water and cloud ice -! amounts [ g / m**3 ] and liquid and ice particle sizes and total cloud -! fraction for the clouds associated with uw shallow convection. these -! values will later be combined with other cloud fields to produce the -! cloud radiative properties that will be seen by the radiation package. -! -! -! -! call uw_clouds_amt (is, ie, js, je, Shallow_microphys) -! -! -!-! -! -!-! -! -!-! -! -!-! -! -!-! -! -!h1g, this is the MG 2011-02 version + if( present(qcvar_clubb) ) then + mnucct(k) = gamma(qcvar_clubb(i,k)+4._r8/3._r8)/(gamma(qcvar_clubb(i,k))*qcvar_clubb(i,k)**(4._r8/3._r8))* & + (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* & + cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4 + nnucct(k) = gamma(qcvar_clubb(i,k)+1._r8/3._r8)/(gamma(qcvar_clubb(i,k))*qcvar_clubb(i,k)**(1._r8/3._r8))* & + (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi* & + cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k) + else + mnucct(k) = gamma(qcvar+4._r8/3._r8)/(cons3*qcvar**(4._r8/3._r8))* & + (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* & + cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4 + nnucct(k) = gamma(qcvar+1._r8/3._r8)/(cons3*qcvar**(1._r8/3._r8))* & + (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi* & + cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k) + endif +! <--- h1g, the MG 2011-02 version + + +! ---> h1g, this is the MG 2010-09 version + ! mnucct(k) = cons10/(cons3*qcvar)* & + ! (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow*& + ! cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4 + ! nnucct(k) = (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi*& + ! cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k) +! <--- h1g, the MG 2010-09 version + + end if ! sub-column switch + endif +#endif +#ifndef GFDL_COMPATIBLE_MICROP + +! contact freezing (-40 h1g, this is the MG 2011-02 version + mnucct(k) = gamma(qcvar+4._r8/3._r8)/ & + (cons3*qcvar**(4._r8/3._r8))* & + (ndfaer1*(nacon(i,k,1)*tcnt)+ & + ndfaer2*(nacon(i,k,2)*tcnt)+ & + ndfaer3*(nacon(i,k,3)*tcnt)+ & + ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow* & + cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4 + nnucct(k) = gamma(qcvar+1._r8/3._r8)/ & + (cons3*qcvar**(1._r8/3._r8))* & + (ndfaer1*(nacon(i,k,1)*tcnt)+ & + ndfaer2*(nacon(i,k,2)*tcnt)+ & + ndfaer3*(nacon(i,k,3)*tcnt)+ & + ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi* & + cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k) +! <--- h1g, the MG 2011-02 version + + +! ---> h1g, this is the MG 2010-09 version + ! mnucct(k) = cons10/(cons3*qcvar)* & + ! (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*pi*pi/3._r8*rhow*& + ! cdist1(k)*gamma(pgam(k)+5._r8)/lamc(k)**4 + ! nnucct(k) = (ndfaer1*(nacon(i,k,1)*tcnt)+ndfaer2*(nacon(i,k,2)*tcnt)+ndfaer3*(nacon(i,k,3)*tcnt)+ndfaer4*(nacon(i,k,4)*tcnt))*2._r8*pi*& + ! cdist1(k)*gamma(pgam(k)+2._r8)/lamc(k) +! <--- h1g, the MG 2010-09 version + + end if ! sub-column switch +#endif + +! make sure number of droplets frozen does not exceed available ice nuclei +! concentration +! this prevents 'runaway' droplet freezing + + if (nnuccc(k)*lcldm(i,k).gt.nnuccd(k)) then + dum = (nnuccd(k)/(nnuccc(k)*lcldm(i,k))) + +! scale mixing ratio of droplet freezing with limit + mnuccc(k)=mnuccc(k)*dum + nnuccc(k)=nnuccd(k)/lcldm(i,k) + end if + else + mnuccc(k) = 0._r8 + nnuccc(k) = 0._r8 + mnucct(k) = 0._r8 + nnucct(k) = 0._r8 + end if ! qcic(i,k).ge.qsmall .and. t(i,k).lt.269.15_r8 + +!....................................................................... +! snow self-aggregation from passarelli, 1978, used by reisner, 1998 +! this is hard-wired for bs = 0.4 for now +! ignore self-collection of cloud ice + + if (qniic(i,k).ge.qsmall .and. t(i,k).le.tmelt) then + nsagg(k) = & + -1108._r8*asn(i,k)*Eii*pi**((1._r8-bs)/3._r8)* & + rhosn**((-2._r8-bs)/3._r8)*rho(i,k)**((2._r8+bs)/3._r8)*& + qniic(i,k)**((2._r8+bs)/3._r8)* & + (nsic(i,k)*rho(i,k))**((4._r8-bs)/3._r8)/ & + (4._r8*720._r8*rho(i,k)) + else + nsagg(k) = 0._r8 + end if + +!....................................................................... +! accretion of cloud droplets onto snow/graupel +! here use continuous collection equation with +! simple gravitational collection kernel +! ignore collisions between droplets/cloud ice +! since minimum size ice particle for accretion is 50 - 150 micron + +! ignore collision of snow with droplets above freezing + + if (qniic(i,k).ge.qsmall .and. t(i,k).le.tmelt .and. & + qcic(i,k).ge.qsmall) then + +! put in size dependent collection efficiency +! mean diameter of snow is area-weighted, since +! accretion is function of crystal geometric area +! collection efficiency is approximation based on stoke's law (Thompson et al. 2004) + + dc0 = (pgam(k)+1._r8)/lamc(k) + ds0 = 1._r8/lams(k) + dum = dc0*dc0*uns(k)*rhow/(9._r8*mu(i,k)*ds0) + eci = dum*dum/((dum+0.4_r8)*(dum+0.4_r8)) + + eci = max(eci,0._r8) + eci = min(eci,1._r8) + + +! no impact of sub-grid distribution of qc since psacws +! is linear in qc + + psacws(k) = pi/4._r8*asn(i,k)*qcic(i,k)*rho(i,k)* & + n0s(k)*Eci*cons11/ lams(k)**(bs+3._r8) + npsacws(k) = pi/4._r8*asn(i,k)*ncic(i,k)*rho(i,k)* & + n0s(k)*Eci*cons11/lams(k)**(bs+3._r8) + else + psacws(k) = 0._r8 + npsacws(k) = 0._r8 + end if + +#ifdef GFDL_COMPATIBLE_MICROP + if (Nml%do_hallet_mossop .or. lflag ) then +#endif +! add secondary ice production due to accretion of droplets by snow +! (Hallet-Mossop process) (from Cotton et al., 1986) + if ((t(i,k).lt.tmelt - 3._r8) .and. & + (t(i,k).ge.tmelt - 5._r8)) then + ni_secp = 3.5e8_r8*(tmelt - 3._r8-t(i,k))/2.0_r8*psacws(k) + nsacwi(k) = ni_secp + msacwi(k) = min(ni_secp*mi0, psacws(k)) + else if((t(i,k).lt.tmelt -5._r8) .and. & + (t(i,k).ge.tmelt - 8._r8)) then + ni_secp = 3.5e8_r8*(t(i,k) - (tmelt -8._r8))/ & + 3.0_r8*psacws(k) + nsacwi(k) = ni_secp + msacwi(k) = min(ni_secp*mi0, psacws(k)) + else + ni_secp = 0.0_r8 + nsacwi(k) = 0.0_r8 + msacwi(k) = 0.0_r8 + endif + psacws(k) = max(0.0_r8, psacws(k) - ni_secp*mi0) +#ifdef GFDL_COMPATIBLE_MICROP + else + msacwi(k) = 0.0_r8 + nsacwi(k) = 0.0_r8 + endif ! (do_hallet_mossop or do_clubb>0) +#endif + +!....................................................................... +! accretion of rain water by snow +! formula from ikawa and saito, 1991, used by reisner et al., 1998 + + if (qric(i,k).ge.1.e-8_r8 .and. & + qniic(i,k).ge.1.e-8_r8 .and. & + t(i,k).le.tmelt) then + + pracs(k) = pi*pi*ecr*(((1.2_r8*umr(k) - & + 0.95_r8*ums(k))**2 + & + 0.08_r8*ums(k)*umr(k))**0.5_r8*rhow*rho(i,k)* & + n0r(k)*n0s(k)* & + (5._r8/(lamr(k)**6*lams(k)) + & + 2._r8/(lamr(k)**5*lams(k)**2) + & + 0.5_r8/(lamr(k)**4*lams(k)**3))) + + npracs(k) = pi/2._r8*rho(i,k)*ecr*(1.7_r8* & + (unr(k) - uns(k))**2 + & + 0.3_r8*unr(k)*uns(k))**0.5_r8*n0r(k)*n0s(k)* & + (1._r8/(lamr(k)**3*lams(k)) + & + 1._r8/(lamr(k)**2*lams(k)**2) + & + 1._r8/(lamr(k)*lams(k)**3)) + + else + pracs(k) = 0._r8 + npracs(k) = 0._r8 + end if + +!....................................................................... +! heterogeneous freezing of rain drops +! follows from Bigg (1953) + + if (t(i,k).lt.tmelt -4._r8 .and. qric(i,k).ge.qsmall) then + +! ---> h1g, this is the MG 2011-02 version + mnuccr(k) = 20._r8*pi*pi*rhow*nric(i,k)*bimm* & + (exp(aimm*(tmelt - t(i,k))) - 1._r8)/lamr(k)**3 & + /lamr(k)**3 + nnuccr(k) = pi*nric(i,k)*bimm* & + (exp(aimm*(tmelt - t(i,k)))-1._r8)/lamr(k)**3 +! ---> h1g, the MG 2011-02 version + +! ---> h1g, this is the MG 2010-09 version + ! mnuccr(k) = 20._r8*pi*pi*rhow*nric(i,k)*bimm* & + ! exp(aimm*(273.15_r8-t(i,k)))/lamr(k)**3 & + ! /lamr(k)**3 + ! nnuccr(k) = pi*nric(i,k)*bimm* & + ! exp(aimm*(273.15_r8-t(i,k)))/lamr(k)**3 +! ---> h1g, the MG 2010-09 version + + else + mnuccr(k) = 0._r8 + nnuccr(k) = 0._r8 + end if + +!....................................................................... +! accretion of cloud liquid water by rain +! formula from Khrouditnov and Kogan (2000) +! gravitational collection kernel, droplet fall speed neglected + + if (qric(i,k).ge.qsmall .and. qcic(i,k).ge.qsmall) then + +! include sub-grid distribution of cloud water + +! add sub-column switch + + if (sub_column) then + pra(k) = & + 67._r8*(qcic(i,k)*qric(i,k))**1.15_r8 + npra(k) = pra(k)/(qcic(i,k)/ncic(i,k)) + else +!--> cjg: modifications incorporated from Huan's code +#ifdef GFDL_COMPATIBLE_MICROP + if( present( qcvar_clubb)) then + if( use_qcvar_in_accretion ) then + if ( qcvar_clubb(i,k) > qcvar_max4accr ) then + accr_scale = 1.0 + elseif( qcvar_clubb(i,k) < qcvar_min4accr ) then + accr_scale = accretion_scale_max + else + accr_scale = (accretion_scale_max-1.0)/(1.0/qcvar_min4accr - 1.0/qcvar_max4accr) & + * (1.0/qcvar_clubb(i,k) - 1.0/qcvar_max4accr) + 1.0 + endif + else + accr_scale = accretion_scale + endif + pra(k) = accr_scale* gamma(qcvar_clubb(i,k)+1.15_r8)/(gamma(qcvar_clubb(i,k))*qcvar_clubb(i,k)**1.15_r8)* & + 67._r8*(qcic(i,k)*qric(i,k))**1.15_r8 + else + pra(k) = accretion_scale*cons12/(cons3*cons20)* & + 67._r8*(qcic(i,k)*qric(i,k))**1.15_r8 + endif +#else + pra(k) = cons12/(cons3*cons20)* & + 67._r8*(qcic(i,k)*qric(i,k))**1.15_r8 +#endif +!<--cjg + npra(k) = pra(k)/(qcic(i,k)/ncic(i,k)) + end if ! sub-column switch + else + pra(k) = 0._r8 + npra(k) = 0._r8 + end if + +!....................................................................... +! Self-collection of rain drops +! from Beheng(1994) + + if (qric(i,k).ge.qsmall) then + nragg(k) = -8._r8*nric(i,k)*qric(i,k)*rho(i,k) + else + nragg(k) = 0._r8 + end if + +!....................................................................... +! Accretion of cloud ice by snow +! For this calculation, it is assumed that the Vs >> Vi +! and Ds >> Di for continuous collection + + if (qniic(i,k).ge.qsmall .and. qiic(i,k).ge.qsmall .and. & + t(i,k).le.tmelt) then + prai(k) = pi/4._r8*asn(i,k)*qiic(i,k)*rho(i,k)* & + n0s(k)*Eii*cons11/lams(k)**(bs+3._r8) + nprai(k) = pi/4._r8*asn(i,k)*niic(i,k)* & + rho(i,k)*n0s(k)*Eii*cons11/lams(k)**(bs+3._r8) + else + prai(k) = 0._r8 + nprai(k) = 0._r8 + end if + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! calculate evaporation/sublimation of rain and snow +! note: evaporation/sublimation occurs only in cloud-free portion of grid cell +! in-cloud condensation/deposition of rain and snow is neglected +! except for transfer of cloud water to snow through bergeron process + +! initialize evap/sub tendncies + pre(k)=0._r8 + prds(k)=0._r8 + +! evaporation of rain +! only calculate if there is some precip fraction > cloud fraction +!!!NOTE NOTE NOTE +!RSH 7/31/12: The use of 1.e-6 as the limit here results in snow sublim- +! ation at high levels (p=1.3 hPa) and a resultant heating +! term which becomes excessive and causes model blowup +! (likely associated with assumed cloud fraction). +! I have therefore changed the if test to be < qsmall, as is done +! in all other tests against qcic, qiic, etc in this routine. +! Marc's code used this qsmall test until 11/27/08 when he changed it -- +! I will also check there to see if it solves problem. +! 8/7: In MG code, switching to use qsmall also eliminates model +! blowups previously encountered. +!END NOTE + + if (qcic(i,k) + qiic(i,k) .lt. qsmall .or. & + cldmax(i,k) .gt. lcldm(i,k)) then + +! set temporary cloud fraction to zero if cloud water + ice is very small +! this will ensure that evaporation/sublimation of precip occurs over +! entire grid cell, since min cloud fraction is specified otherwise + if (qcic(i,k) + qiic(i,k) .lt. qsmall) then + dum = 0._r8 + else + dum = lcldm(i,k) + end if + +! saturation vapor pressure + esn = polysvp(t(i,k),0) + qsn = min(epsqs*esn/(p(i,k) - (1._r8 - epsqs)*esn), 1._r8) +!RSH 8/1/12: Need to prevent negative values which may occur at low p +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) & + qsn = max(qsn, 0._r8) +#endif +! recalculate saturation vapor pressure for liquid and ice + esl(i,k) = esn + esi(i,k) = polysvp(t(i,k),1) +! hm fix, make sure when above freezing that esi=esl, not active yet + if (t(i,k) .gt. tmelt) esi(i,k) = esl(i,k) + +! calculate q for out-of-cloud region + qclr = (q(i,k) - dum*qsn)/(1._r8 - dum) + + if (qric(i,k).ge.qsmall) then + qvs = epsqs*esl(i,k)/(p(i,k) - (1._r8 - epsqs)*esl(i,k)) + dqsdt = xxlv*qvs/(rv*t(i,k)**2) + ab = 1._r8 + dqsdt*xxlv/cpp + epsr = 2._r8*pi*n0r(k)*rho(i,k)*Dv(i,k)* & + (f1r/(lamr(k)*lamr(k)) + & + f2r*(arn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* & + sc(i,k)**(1._r8/3._r8)*cons13/ & + (lamr(k)**(5._r8/2._r8 + br/2._r8))) + pre(k) = epsr*(qclr - qvs)/ab + +! only evaporate in out-of-cloud region +! and distribute across cldmax + pre(k) = min(pre(k)*(cldmax(i,k)-dum), 0._r8) + pre(k) = pre(k)/cldmax(i,k) + end if + +! sublimation of snow + if (qniic(i,k).ge.qsmall) then + qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8 - epsqs)*esi(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi = 1._r8 + dqsidt*xxls/cpp + epss = 2._r8*pi*n0s(k)*rho(i,k)*Dv(i,k)* & + (f1s/(lams(k)*lams(k)) + & + f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* & + sc(i,k)**(1._r8/3._r8)*cons14/ & + (lams(k)**(5._r8/2._r8 + bs/2._r8))) + prds(k) = epss*(qclr - qvi)/abi + +! only sublimate in out-of-cloud region and distribute over cldmax + prds(k) = min(prds(k)*(cldmax(i,k)-dum), 0._r8) + prds(k) = prds(k)/cldmax(i,k) + end if + +! make sure RH not pushed above 100% due to rain evaporation/snow sublimation +! get updated RH at end of time step based on cloud water/ice condensation/evap + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + qtmp = q(i,k) - & + (D_eros_l(i,k) + D_eros_i(i,k) + cmel(i,k) + & + cmei(i,k) + (pre(k) + prds(k))*cldmax(i,k))*deltat + ttmp = t(i,k) +( & + (D_eros_l(i,k) + cmel(i,k) + pre(k)*cldmax(i,k))* & + xxlv + & + (D_eros_i(i,k) + cmei(i,k) + prds(k)*cldmax(i,k))* & + xxls)*deltat/cpp + else + qtmp = q(i,k) - & + (cmei(i,k) + (pre(k) + prds(k))*cldmax(i,k))*deltat + ttmp = t(i,k) + & + ((pre(k)*cldmax(i,k))*xxlv + & + (cmei(i,k) + prds(k)*cldmax(i,k))*xxls)*deltat/cpp + endif +#else + qtmp = q(i,k) - & + (cmei(i,k) + (pre(k) + prds(k))*cldmax(i,k))*deltat + ttmp = t(i,k) + & + ((pre(k)*cldmax(i,k))*xxlv + & + (cmei(i,k) + prds(k)*cldmax(i,k))*xxls)*deltat/cpp +#endif + +!limit range of temperatures! +#ifdef GFDL_COMPATIBLE_MICROP + ttmp = max(lowest_temp_for_sublimation, min(ttmp, 323._r8)) +#else + ttmp = max(180._r8, min(ttmp, 323._r8)) +#endif + esn = polysvp(ttmp,0) ! use rhw to allow ice supersaturation + qsn = min(epsqs*esn/(p(i,k) - (1._r8 - epsqs)*esn), 1._r8) +#ifdef GFDL_COMPATIBLE_MICROP +!RSH 8/1/12: Need to prevent negative values which may occur at low p + if( .not. lflag ) & + qsn = max(qsn, 0._r8) +#endif + +! modify precip evaporation rate if q > qsat + if (qtmp .gt. qsn) then + if (pre(k) + prds(k) .lt. -1.e-20_r8) then + dum1 = pre(k)/(pre(k) + prds(k)) +! recalculate q and t after cloud water cond but without precip evap +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + qtmp = q(i,k) - & + (D_eros_l(i,k) + D_eros_i(i,k) + & + cmel(i,k) + cmei(i,k))*deltat + ttmp = t(i,k)+ & + ((D_eros_l(i,k) + cmel(i,k))*xxlv + & + (D_eros_i(i,k) + cmei(i,k))*xxls)*deltat/cpp + else + qtmp = q(i,k) - (cmei(i,k))*deltat + ttmp = t(i,k) + (cmei(i,k)*xxls)*deltat/cpp + endif +#else + qtmp = q(i,k) - (cmei(i,k))*deltat + ttmp = t(i,k) + (cmei(i,k)*xxls)*deltat/cpp +#endif + esn = polysvp(ttmp,0) ! use rhw to allow ice + ! supersaturation + qsn = min(epsqs*esn/(p(i,k) - (1._r8 - epsqs)*esn), & + 1._r8) +!RSH 8/1/12: Need to prevent negative values which may occur at low p +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) & + qsn = max(qsn, 0._r8) +#endif + + dum = (qtmp - qsn)/(1._r8 + cons27*qsn/(cpp*rv*ttmp**2)) + dum = min(dum, 0._r8) + +! modify rates if needed, divide by cldmax to get local (in-precip) value + pre(k) = dum*dum1/deltat/cldmax(i,k) + +! do separately using RHI for prds.... + esn = polysvp(ttmp,1) ! use rhi to allow ice + ! supersaturation + qsn = min(epsqs*esn/(p(i,k) - (1._r8 - epsqs)*esn), & + 1._r8) + dum = (qtmp - qsn)/(1._r8 + cons28*qsn/(cpp*rv*ttmp**2)) + dum = min(dum, 0._r8) + +! modify rates if needed, divide by cldmax to get local (in-precip) value + prds(k) = dum*(1._r8 - dum1)/deltat/cldmax(i,k) + end if ! pre(k)+prds(k).lt.-1.e-20_r8 + end if !qtmp.gt.qsn + end if ! qcic(i,k)+qiic(i,k).lt.qsmall .or.cldmax(i,k)... + +! bergeron process - evaporation of droplets and deposition onto snow + + if (qniic(i,k) .ge. qsmall .and. & + qcic(i,k) .ge. qsmall .and. & + t(i,k) .lt. tmelt) then + qvi = epsqs*esi(i,k)/(p(i,k) - (1._r8 - epsqs)*esi(i,k)) + qvs = epsqs*esl(i,k)/(p(i,k) - (1._r8 - epsqs)*esl(i,k)) + +#ifdef GFDL_COMPATIBLE_MICROP +!8/1/12 RSH: Need to prevent negative values which may occur at low p + if( .not. lflag ) then + qvi = MAX(0._r8, MIN (qvi,1.0_r8)) + qvs = MAX(0._r8, MIN (qvs,1.0_r8)) + endif +#endif + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi = 1._r8 + dqsidt*xxls/cpp + epss = 2._r8*pi*n0s(k)*rho(i,k)*Dv(i,k)* & + (f1s/(lams(k)*lams(k)) + & + f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_r8* & + sc(i,k)**(1._r8/3._r8)*cons14/ & + (lams(k)**(5._r8/2._r8 + bs/2._r8))) + bergs(k) = epss*(qvs - qvi)/abi + else + bergs(k) = 0._r8 + end if + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! conservation to ensure no negative values of cloud water/precipitation +! in case microphysical process rates are large + +! make sure and use end-of-time step values for cloud water, ice, due +! condensation/deposition + +! note: for check on conservation, processes are multiplied by omsm +! to prevent problems due to round off error + +! include mixing timescale (mtime) + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + qce = (qc(i,k) + & + (D_eros_l(i,k) + cmel(i,k) - berg(i,k))*deltat) + else + qce = (qc(i,k) - berg(i,k)*deltat) + endif +#else + qce = (qc(i,k) - berg(i,k)*deltat) +#endif + nce = (nc(i,k) + npccn(k)*deltat*mtime) +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + qie = (qi(i,k) + & + (D_eros_i(i,k) + cmei(i,k) + berg(i,k))*deltat) + else + qie = (qi(i,k) + (cmei(i,k) + berg(i,k))*deltat) + endif +#else + qie = (qi(i,k) + (cmei(i,k) + berg(i,k))*deltat) +#endif + nie = (ni(i,k) + nnuccd(k)*deltat*mtime) + +! conservation of qc + + dum = (prc(k) + pra(k) + mnuccc(k) + mnucct(k) + msacwi(k) + & + psacws(k) + bergs(k))*lcldm(i,k)*deltat + if (dum .gt. qce) then + ratio = qce/deltat/lcldm(i,k)/ & + (prc(k) + pra(k) + mnuccc(k) + mnucct(k) + & + msacwi(k) + psacws(k) + bergs(k))*omsm + prc(k) = prc(k)*ratio + pra(k) = pra(k)*ratio + mnuccc(k) = mnuccc(k)*ratio + mnucct(k) = mnucct(k)*ratio + msacwi(k) = msacwi(k)*ratio + psacws(k) = psacws(k)*ratio + bergs(k) = bergs(k)*ratio + end if + +! conservation of nc + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + dum = (nprc1(k) + npra(k) + nnuccc(k) + nnucct(k) + & + npsacws(k) - nsubc(k) - nerosc(i,k))*lcldm(i,k)*deltat + else + dum = (nprc1(k) + npra(k) + nnuccc(k) + nnucct(k) + & + npsacws(k) - nsubc(k))*lcldm(i,k)*deltat + endif +#else + dum = (nprc1(k) + npra(k) + nnuccc(k) + nnucct(k) + & + npsacws(k) - nsubc(k))*lcldm(i,k)*deltat +#endif + + if (dum .gt. nce) then +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + ratio = nce/deltat/ & + ((nprc1(k) + npra(k) + nnuccc(k) + nnucct(k) + & + npsacws(k) - nsubc(k) - nerosc(i,k))*lcldm(i,k))*omsm + else + ratio = nce/deltat/ & + ((nprc1(k) + npra(k) + nnuccc(k) + nnucct(k) + & + npsacws(k) - nsubc(k))*lcldm(i,k))*omsm + endif +#else + ratio = nce/deltat/ & + ((nprc1(k) + npra(k) + nnuccc(k) + nnucct(k) + & + npsacws(k) - nsubc(k))*lcldm(i,k))*omsm +#endif + nprc1(k) = nprc1(k)*ratio + npra(k) = npra(k)*ratio + nnuccc(k) = nnuccc(k)*ratio + nnucct(k) = nnucct(k)*ratio + npsacws(k) = npsacws(k)*ratio + nsubc(k)=nsubc(k)*ratio +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) & + nerosc(i,k)=nerosc(i,k)*ratio +#endif + end if + +! conservation of qi + + dum = ((-mnuccc(k) - mnucct(k) - msacwi(k))*lcldm(i,k) + & + (prci(k) + prai(k))*icldm(i,k))*deltat + if (dum .gt. qie) then + ratio = (qie/deltat + & + (mnuccc(k) + mnucct(k) + msacwi(k))*lcldm(i,k))/ & + ((prci(k) + prai(k))*icldm(i,k))*omsm + prci(k) = prci(k)*ratio + prai(k) = prai(k)*ratio + end if + +! conservation of ni + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + dum = ((-nnucct(k) - nsacwi(k))*lcldm(i,k) + (nprci(k) + & + nprai(k) - nsubi(k) - nerosi(i,k))*icldm(i,k))*deltat + else + dum = ((-nnucct(k) - nsacwi(k))*lcldm(i,k) + (nprci(k) + & + nprai(k) - nsubi(k))*icldm(i,k))*deltat + endif +#else + dum = ((-nnucct(k) - nsacwi(k))*lcldm(i,k) + (nprci(k) + & + nprai(k) - nsubi(k))*icldm(i,k))*deltat +#endif + if (dum .gt. nie) then + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + ratio = (nie/deltat + (nnucct(k) + nsacwi(k))*lcldm(i,k))/ & + ((nprci(k) + nprai(k) - nsubi(k) - nerosi(i,k))* & + icldm(i,k))*omsm + else + ratio = (nie/deltat + (nnucct(k) + nsacwi(k))*lcldm(i,k))/ & + ((nprci(k) + nprai(k) - nsubi(k))*icldm(i,k))*omsm + endif +#else + ratio = (nie/deltat + (nnucct(k) + nsacwi(k))*lcldm(i,k))/ & + ((nprci(k) + nprai(k) - nsubi(k))*icldm(i,k))*omsm +#endif + nprci(k) = nprci(k)*ratio + nprai(k) = nprai(k)*ratio + nsubi(k) = nsubi(k)*ratio +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) & + nerosi(i,k) = nerosi(i,k)*ratio +#endif + end if + +! for preciptiation conservation, use logic that vertical integral +! of tendency from current level to top of model (i.e., qrtot) cannot be negative + +! conservation of rain mixing rat + + if (((prc(k) + pra(k))*lcldm(i,k) + & + (-mnuccr(k) + pre(k) - pracs(k))*cldmax(i,k))* & + dz(i,k)*rho(i,k) + qrtot .lt. 0._r8) then + if (-pre(k) + pracs(k) + mnuccr(k) .ge. qsmall) then + ratio = (qrtot/(dz(i,k)*rho(i,k)) + & + (prc(k) + pra(k))*lcldm(i,k))/& + ((-pre(k) + pracs(k) + mnuccr(k))*cldmax(i,k))*omsm + pre(k) = pre(k)*ratio + pracs(k) = pracs(k)*ratio + mnuccr(k) = mnuccr(k)*ratio + end if ! -pre(k)+pracs(k)+mnuccr(k).ge.qsmall + end if + +! conservation of nr +! for now neglect evaporation of nr + nsubr(k)=0._r8 +!--> cjg: modifications incorporated from Huan's code + if (allow_rain_num_evap) then + if (qric(i,k) .ge. qsmall) nsubr(k)= max(pre(k)/qric(i,k)*nric(i,k), -nric(i,k)/deltat) + endif +!<--cjg + + if ((nprc(k)*lcldm(i,k) + (-nnuccr(k) + nsubr(k) - & + npracs(k) + nragg(k))*cldmax(i,k))*dz(i,k)*rho(i,k) + & + nrtot .lt. 0._r8) then + if (-nsubr(k) - nragg(k) + npracs(k) + & + nnuccr(k) .ge.qsmall) then + ratio = (nrtot/(dz(i,k)*rho(i,k)) + nprc(k)*lcldm(i,k))/& + ((-nsubr(k) - nragg(k) + npracs(k) + & + nnuccr(k))*cldmax(i,k))*omsm + nsubr(k) = nsubr(k)*ratio + npracs(k) = npracs(k)*ratio + nnuccr(k) = nnuccr(k)*ratio + nragg(k) = nragg(k)*ratio + end if + end if + +! conservation of snow mix ratio + + if (((bergs(k) + psacws(k))*lcldm(i,k) + & + (prai(k) + prci(k))*icldm(i,k) + (pracs(k) + & + mnuccr(k) + prds(k))*cldmax(i,k))*dz(i,k)* & + rho(i,k) + qstot .lt. 0._r8) then + if (-prds(k) .ge. qsmall) then + ratio = (qstot/(dz(i,k)*rho(i,k)) + & + (bergs(k) + psacws(k))*lcldm(i,k) + & + (prai(k) + prci(k))*icldm(i,k) + & + (pracs(k) + mnuccr(k))*cldmax(i,k))/ & + (-prds(k)*cldmax(i,k))*omsm + prds(k) = prds(k)*ratio + end if ! -prds(k).ge.qsmall + end if + +! conservation of ns + +! calculate loss of number due to sublimation +! for now neglect sublimation of ns + nsubs(k)=0._r8 + if ((nprci(k)*icldm(i,k) + (nnuccr(k) + nsubs(k) + & + nsagg(k))*cldmax(i,k))*& + dz(i,k)*rho(i,k) + nstot .lt. 0._r8) then + if (-nsubs(k) - nsagg(k) .ge. qsmall) then + ratio = (nstot/(dz(i,k)*rho(i,k)) + nprci(k)* & + icldm(i,k) + nnuccr(k)*cldmax(i,k))/ & + ((-nsubs(k) - nsagg(k))*cldmax(i,k))*omsm + nsubs(k) = nsubs(k)*ratio + nsagg(k) = nsagg(k)*ratio + end if + end if + +! get tendencies due to microphysical conversion processes +! note: tendencies are multiplied by appropaiate cloud/precip +! fraction to get grid-scale values +! note: cmei is already grid-average values + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + qvlat(i,k) = qvlat(i,k) - & + (pre(k) + prds(k))*cldmax(i,k) - cmel(i,k) - & + cmei(i,k) - D_eros_l(i,k) - D_eros_i(i,k) + tlat(i,k) = tlat(i,k) + ((pre(k)*cldmax(i,k) + cmel(i,k) + & + D_eros_l(i,k))*xxlv + (prds(k)*cldmax(i,k) + & + cmei(i,k) + D_eros_i(i,k))*xxls + & + ((bergs(k) + psacws(k) + mnuccc(k) + & + mnucct(k) + msacwi(k))*lcldm(i,k) + & + (mnuccr(k) + pracs(k))*cldmax(i,k) + & + berg(i,k))*xlf) + qctend(i,k) = qctend(i,k) + & + (-pra(k) - prc(k) - mnuccc(k) - mnucct(k) - & + msacwi(k) - psacws(k) - bergs(k))* & + lcldm(i,k) + & + cmel(i,k) - berg(i,k) + D_eros_l(i,k) + qitend(i,k) = qitend(i,k) + & + (mnuccc(k) + mnucct(k) + msacwi(k))* & + lcldm(i,k) + & + (-prci(k) - prai(k))*icldm(i,k) + & + cmei(i,k) + berg(i,k) + D_eros_i(i,k) + else + qvlat(i,k) = qvlat(i,k) - & + (pre(k) + prds(k))*cldmax(i,k) - cmei(i,k) + tlat(i,k) = tlat(i,k) + ((pre(k)*cldmax(i,k))*xxlv + & + (prds(k)*cldmax(i,k) + cmei(i,k))*xxls + & + ((bergs(k) + psacws(k) + mnuccc(k) + & + mnucct(k) + msacwi(k))*lcldm(i,k) + & + (mnuccr(k) + pracs(k))*cldmax(i,k) + & + berg(i,k))*xlf) + qctend(i,k) = qctend(i,k) + & + (-pra(k) - prc(k) - mnuccc(k) - mnucct(k) - & + msacwi(k) - psacws(k) - bergs(k))* & + lcldm(i,k) - berg(i,k) + qitend(i,k) = qitend(i,k) + & + (mnuccc(k) + mnucct(k) + msacwi(k))* & + lcldm(i,k) + & + (-prci(k) - prai(k))*icldm(i,k) & + + cmei(i,k) + berg(i,k) + + endif +#else + qvlat(i,k) = qvlat(i,k) - & + (pre(k) + prds(k))*cldmax(i,k) - cmei(i,k) + tlat(i,k) = tlat(i,k) + ((pre(k)*cldmax(i,k))*xxlv + & + (prds(k)*cldmax(i,k) + cmei(i,k))*xxls + & + ((bergs(k) + psacws(k) + mnuccc(k) + & + mnucct(k) + msacwi(k))*lcldm(i,k) + & + (mnuccr(k) + pracs(k))*cldmax(i,k) + & + berg(i,k))*xlf) + qctend(i,k) = qctend(i,k) + & + (-pra(k) - prc(k) - mnuccc(k) - mnucct(k) - & + msacwi(k) - psacws(k) - bergs(k))* & + lcldm(i,k) - berg(i,k) + qitend(i,k) = qitend(i,k) + & + (mnuccc(k) + mnucct(k) + msacwi(k))* & + lcldm(i,k) + & + (-prci(k) - prai(k))*icldm(i,k) & + + cmei(i,k) + berg(i,k) +#endif + qrtend(i,k) = qrtend(i,k) + & + (pra(k) + prc(k))*lcldm(i,k) + (pre(k) - & + pracs(k) - mnuccr(k))*cldmax(i,k) + qnitend(i,k) = qnitend(i,k) + & + (prai(k) + prci(k))*icldm(i,k) + & + (psacws(k) + bergs(k))*lcldm(i,k) + & + (prds(k) + pracs(k) + mnuccr(k))*cldmax(i,k) +! add output for cmei (accumulate) + cmeiout(i,k) = cmeiout(i,k) + cmei(i,k) + +! assign variables for trop_mozart, these are grid-average +! evaporation/sublimation is stored here as positive term + + evapsnow(i,k) = evapsnow(i,k) - prds(k)*cldmax(i,k) + nevapr(i,k) = nevapr(i,k) - pre(k)*cldmax(i,k) + +! change to make sure prain is positive: do not remove snow from +! prain used for wet deposition + prain(i,k) = prain(i,k) + (pra(k) + prc(k))*lcldm(i,k) + & + (-pracs(k) - mnuccr(k))*cldmax(i,k) + prodsnow(i,k) = prodsnow(i,k) + (prai(k) + & + prci(k))*icldm(i,k) + & + (psacws(k) + bergs(k))*lcldm(i,k) + & + (pracs(k) + mnuccr(k))*cldmax(i,k) + +! following are used to calculate 1st order conversion rate of cloud water +! to rain and snow (1/s), for later use in aerosol wet removal routine +! previously, wetdepa used (prain/qc) for this, and the qc in wetdepa may +! be smaller than the qc used to calculate pra, prc, ... in this routine +! qcsinksum_rate1ord = sum over iterations{ rate of direct transfer of +! cloud water to rain & snow } +! (no cloud ice or bergeron terms) +! qcsum_rate1ord = sum over iterations{ qc used in calculation of the +! transfer terms } + + qcsinksum_rate1ord(k) = qcsinksum_rate1ord(k) + & + (pra(k) + prc(k) + psacws(k))* & + lcldm(i,k) + qcsum_rate1ord(k) = qcsum_rate1ord(k) + qc(i,k) + +! microphysics output, note this is grid-averaged +#ifdef GFDL_COMPATIBLE_MICROP + preo(i,k) = preo(i,k) + pre(k)*cldmax(i,k) + prdso(i,k) = prdso(i,k) + prds(k)*cldmax(i,k) + if( .not. lflag ) then + cmelo(i,k) = cmelo(i,k) + cmel(i,k) + eroslo(i,k) = eroslo(i,k) + D_eros_l(i,k) + erosio(i,k) = erosio(i,k) + D_eros_i(i,k) + endif +#endif + prao(i,k) = prao(i,k) + pra(k)*lcldm(i,k) + prco(i,k) = prco(i,k) + prc(k)*lcldm(i,k) + mnuccco(i,k) = mnuccco(i,k) + mnuccc(k)*lcldm(i,k) + mnuccto(i,k) = mnuccto(i,k) + mnucct(k)*lcldm(i,k) + mnuccdo(i,k) = mnuccdo(i,k) + mnuccd(k)*lcldm(i,k) + msacwio(i,k) = msacwio(i,k) + msacwi(k)*lcldm(i,k) + psacwso(i,k) = psacwso(i,k) + psacws(k)*lcldm(i,k) + bergso(i,k) = bergso(i,k) + bergs(k)*lcldm(i,k) + bergo(i,k) = bergo(i,k) + berg(i,k) + prcio(i,k) = prcio(i,k) + prci(k)*icldm(i,k) + praio(i,k) = praio(i,k) + prai(k)*icldm(i,k) + mnuccro(i,k) = mnuccro(i,k) + mnuccr(k)*cldmax(i,k) + pracso (i,k) = pracso (i,k) + pracs (k)*cldmax(i,k) + +! multiply activation/nucleation by mtime to account for fast timescale + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + nctend(i,k) = nctend(i,k) + npccn(k)*mtime + & + (-nnuccc(k) - nnucct(k) - npsacws(k) + & + nsubc(k) + nerosc(i,k) - npra(k) - nprc1(k))* & + lcldm(i,k) + nitend(i,k) = nitend(i,k) + nnuccd(k)*mtime + & + (nnucct(k) + nsacwi(k))*lcldm(i,k) + & + (nsubi(k) + nerosi(i,k) - nprci(k) - & + nprai(k))*icldm(i,k) + else + nctend(i,k) = nctend(i,k)+ npccn(k)*mtime+& + (-nnuccc(k)-nnucct(k)-npsacws(k)+nsubc(k) & + -npra(k)-nprc1(k))*lcldm(i,k) + + nitend(i,k) = nitend(i,k)+ nnuccd(k)*mtime+ & + (nnucct(k)+nsacwi(k))*lcldm(i,k)+(nsubi(k)-nprci(k)- & + nprai(k))*icldm(i,k) + + endif +#else +!#endif +!#ifndef GFDL_COMPATIBLE_MICROP + nctend(i,k) = nctend(i,k) + npccn(k)*mtime + & + (-nnuccc(k) - nnucct(k) - npsacws(k) + & + nsubc(k) - npra(k) - nprc1(k))*lcldm(i,k) + nitend(i,k) = nitend(i,k) + nnuccd(k)*mtime + & + (nnucct(k) + nsacwi(k))*lcldm(i,k) + & + (nsubi(k) - nprci(k) - nprai(k))*icldm(i,k) +#endif + + nstend(i,k) = nstend(i,k) + (nsubs(k) + & + nsagg(k) + nnuccr(k))*cldmax(i,k) + & + nprci(k)*icldm(i,k) + nrtend(i,k) = nrtend(i,k) + & + nprc(k)*lcldm(i,k) + (nsubr(k) - npracs(k) - & + nnuccr(k) + nragg(k))*cldmax(i,k) + +#ifdef GFDL_COMPATIBLE_MICROP +! save current tendencies so that upcoming adjustment may be captured + IF (diag_id%qndt_nucclim + & + diag_id%qn_nucclim_col > 0) THEN + nucclim(k) = nctend(i,k) + END IF + + IF (diag_id%qnidt_nucclim1 + & + diag_id%qni_nucclim1_col > 0) THEN + nucclim1i(k) = nitend(i,k) + END IF +#endif +! make sure that nc and ni at advanced time step do not exceed +! maximum (existing N + source terms*dt), which is possible due to +! fast nucleation timescale + + if (nctend(i,k) .gt. 0._r8 .and. & + nc(i,k) + nctend(i,k)*deltat .gt. ncmax) then + nctend(i,k) = max(0._r8, (ncmax - nc(i,k))/deltat) + end if + if (nitend(i,k) .gt. 0._r8 .and. & + ni(i,k) + nitend(i,k)*deltat .gt. nimax) then + nitend(i,k) = max(0._r8, (nimax - ni(i,k))/deltat) + end if + +#ifdef GFDL_COMPATIBLE_MICROP +! complete diagnostic calculation + IF (diag_id%qndt_nucclim + & + diag_id%qn_nucclim_col > 0) THEN + nucclim(k) = nctend(i,k) - nucclim(k) + END IF + IF (diag_id%qnidt_nucclim1 + & + diag_id%qni_nucclim1_col > 0) THEN + nucclim1i(k) = nitend(i,k) - nucclim1i(k) + END IF +#endif + +! get final values for precipitation q and N, based on +! flux of precip from above, source/sink term, and terminal fallspeed +! see eq. 15-16 in MG2008 + +! rain + + if (qric(i,k) .ge. qsmall) then + if (k .eq. 1) then + qric(i,k) = qrtend(i,k)*dz(i,k)/cldmax(i,k)/umr(k) + nric(i,k) = nrtend(i,k)*dz(i,k)/cldmax(i,k)/unr(k) + else + qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*qrtend(i,k)))/ & + (umr(k)*rho(i,k)*cldmax(i,k)) + nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*nrtend(i,k)))/ & + (unr(k)*rho(i,k)*cldmax(i,k)) + end if + else + qric(i,k)=0._r8 + nric(i,k)=0._r8 + end if + +! snow + if (qniic(i,k) .ge. qsmall) then + if (k .eq. 1) then + qniic(i,k) = qnitend(i,k)*dz(i,k)/cldmax(i,k)/ums(k) + nsic(i,k) = nstend(i,k)*dz(i,k)/cldmax(i,k)/uns(k) + else + qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*qnitend(i,k)))/ & + (ums(k)*rho(i,k)*cldmax(i,k)) + nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*nstend(i,k)))/ & + (uns(k)*rho(i,k)*cldmax(i,k)) + end if + else + qniic(i,k)=0._r8 + nsic(i,k)=0._r8 + end if + +! calculate precipitation flux at surface +! divide by density of water to get units of m/s + + prect(i) = prect(i) + (qrtend(i,k)*dz(i,k)*rho(i,k) + & + qnitend(i,k)*dz(i,k)*rho(i,k))/rhow + preci(i) = preci(i) + qnitend(i,k)*dz(i,k)*rho(i,k)/rhow +!RSH 4/3/12 +! prect(i) = max(prect(i), 0._r8) +! preci(i) = max(preci(i), 0._r8) + +! convert rain rate from m/s to mm/hr + rainrt(i,k) = qric(i,k)*rho(i,k)*umr(k)/rhow*3600._r8*1000._r8 + +! vertically-integrated precip source/sink terms (note: grid-averaged) +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then +!RSH 4/3/12 +! qrtot = max(qrtot+qrtend(i,k)*dz(i,k)*rho(i,k),0._r8) +! qstot = max(qstot+qnitend(i,k)*dz(i,k)*rho(i,k),0._r8) +! nrtot = max(nrtot+nrtend(i,k)*dz(i,k)*rho(i,k),0._r8) +! nstot = max(nstot+nstend(i,k)*dz(i,k)*rho(i,k),0._r8) + qrtot = (qrtot + qrtend(i,k)*dz(i,k)*rho(i,k)) + qstot = (qstot + qnitend(i,k)*dz(i,k)*rho(i,k)) + nrtot = (nrtot + nrtend(i,k)*dz(i,k)*rho(i,k)) + nstot = (nstot + nstend(i,k)*dz(i,k)*rho(i,k)) + else + qrtot = max(qrtot + qrtend(i,k)*dz(i,k)*rho(i,k),0._r8) + qstot = max(qstot + qnitend(i,k)*dz(i,k)*rho(i,k),0._r8) + nrtot = max(nrtot + nrtend(i,k)*dz(i,k)*rho(i,k),0._r8) + nstot = max(nstot + nstend(i,k)*dz(i,k)*rho(i,k),0._r8) + endif +#else + qrtot = max(qrtot+qrtend(i,k)*dz(i,k)*rho(i,k),0._r8) + qstot = max(qstot+qnitend(i,k)*dz(i,k)*rho(i,k),0._r8) + nrtot = max(nrtot+nrtend(i,k)*dz(i,k)*rho(i,k),0._r8) + nstot = max(nstot+nstend(i,k)*dz(i,k)*rho(i,k),0._r8) +#endif +! calculate melting and freezing of precip +! melt snow at +2 C + + if (t(i,k) + tlat(i,k)/cpp*deltat > tmelt + 2._r8) then + if (qstot > 0._r8) then + +! make sure melting snow doesn't reduce temperature below threshold + dum = -xlf/cpp*qstot/(dz(i,k)*rho(i,k)) + if (t(i,k) + tlat(i,k)/cpp*deltat & + + dum .lt. tmelt + 2._r8) then + dum = (t(i,k) + tlat(i,k)/cpp*deltat - & + (tmelt + 2._r8))*cpp/xlf + dum = dum/(xlf/cpp*qstot/(dz(i,k)*rho(i,k))) + dum = max(0._r8, dum) + dum = min(1._r8, dum) + else + dum = 1._r8 + end if + qric(i,k) = qric(i,k) + dum*qniic(i,k) + nric(i,k) = nric(i,k) + dum*nsic(i,k) + qniic(i,k) = (1._r8 - dum)*qniic(i,k) + nsic(i,k) = (1._r8 - dum)*nsic(i,k) +! heating tendency + tmp = -xlf*dum*qstot/(dz(i,k)*rho(i,k)) + meltsdt(i,k) = meltsdt(i,k) + tmp + tlat(i,k) = tlat(i,k) + tmp + +#ifdef GFDL_COMPATIBLE_MICROP + if (diag_id%snow_melt + diag_id%snow_melt_col > 0) & + diag_4d(i,j,k, diag_pt%snow_melt) = & + diag_4d(i,j,k, diag_pt%snow_melt) + & + dum*preci(i)*rhow/(rho(i,k)*dz(i,k)) +#endif + qrtot = qrtot + dum*qstot + nrtot = nrtot + dum*nstot + qstot = (1._r8 - dum)*qstot + nstot = (1._r8 - dum)*nstot + preci(i) = (1._r8 - dum)*preci(i) + end if + end if + +! freeze all rain at -5C for Arctic + + if (t(i,k) + tlat(i,k)/cpp*deltat < (tmelt - 5._r8)) then + if (qrtot > 0._r8) then + +! make sure freezing rain doesn't increase temperature above threshold + dum = xlf/cpp*qrtot/(dz(i,k)*rho(i,k)) + if (t(i,k) + tlat(i,k)/cpp*deltat + & + dum .gt. (tmelt - 5._r8)) then + dum = -(t(i,k) + tlat(i,k)/cpp*deltat - & + (tmelt - 5._r8))*cpp/xlf + dum = dum/(xlf/cpp*qrtot/(dz(i,k)*rho(i,k))) + dum = max(0._r8, dum) + dum = min(1._r8, dum) + else + dum = 1._r8 + end if + + qniic(i,k) = qniic(i,k) + dum*qric(i,k) + nsic(i,k) = nsic(i,k) + dum*nric(i,k) + qric(i,k) = (1._r8 - dum)*qric(i,k) + nric(i,k) = (1._r8 - dum)*nric(i,k) +! heating tendency + tmp = xlf*dum*qrtot/(dz(i,k)*rho(i,k)) + frzrdt(i,k) = frzrdt(i,k) + tmp + + tlat(i,k) = tlat(i,k) + tmp +#ifdef GFDL_COMPATIBLE_MICROP + diag_4d(i,j,k, diag_pt%rain_freeze) = & + diag_4d(i,j,k, diag_pt%rain_freeze) + & + dum*(prect(i) - preci(i))* & + rhow /(rho(i,k)*dz(i,k)) +#endif + qstot = qstot + dum*qrtot + qrtot = (1._r8 - dum)*qrtot + nstot = nstot + dum*nrtot + nrtot = (1._r8 - dum)*nrtot + preci(i) = preci(i) + dum*(prect(i) - preci(i)) + end if !qrtot > 0._r8 + end if ! t(i,k)+tlat(i,k)/cp*deltat < (tmelt - 5._r8) + +! if rain/snow mix ratio is zero so should number concentration + + if (qniic(i,k) .lt. qsmall) then + qniic(i,k) = 0._r8 + nsic(i,k) = 0._r8 + end if + + if (qric(i,k) .lt. qsmall) then + qric(i,k) = 0._r8 + nric(i,k) = 0._r8 + end if + +! make sure number concentration is a positive number to avoid +! taking root of negative + + nric(i,k) = max(nric(i,k), 0._r8) + nsic(i,k) = max(nsic(i,k), 0._r8) + +!....................................................................... +! get size distribution parameters for fallspeed calculations +!...................................................................... +! rain + + if (qric(i,k) .ge. qsmall) then + lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._r8/3._r8) + n0r(k) = nric(i,k)*lamr(k) + +! check for slope +! change lammax and lammin for rain and snow +! adjust vars + + if (lamr(k) .lt. lamminr) then + lamr(k) = lamminr + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + else if (lamr(k) .gt. lammaxr) then + lamr(k) = lammaxr + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + end if + +! 'final' values of number and mass weighted mean fallspeed for rain (m/s) + + unr(k) = min(arn(i,k)*cons4/lamr(k)**br, 9.1_r8*rhof(i,k)) + umr(k) = min(arn(i,k)*cons5/(6._r8*lamr(k)**br), & + 9.1_r8*rhof(i,k)) + else + lamr(k) = 0._r8 + n0r(k) = 0._r8 + umr(k)=0._r8 + unr(k)=0._r8 + end if + +!calculate mean size of combined rain and snow + + if (lamr(k) .gt. 0._r8) then + Artmp = n0r(k)*pi/(2*lamr(k)**3._r8) + else + Artmp = 0._r8 + endif + + if (lamc(k) .gt. 0._r8) then + Actmp = cdist1(k)*pi*gamma(pgam(k) + 3._r8)/ & + (4._r8*lamc(k)**2._r8) + else + Actmp = 0._r8 + endif + +!8/15 if (Actmp.gt.0_r8.or.Artmp.gt.0) then + if (Actmp .gt. 0._r8 .or. Artmp .gt. 0._r8) then + rercld(i,k) = rercld(i,k) + 3._r8*(qric(i,k) + qcic(i,k))/ & + (4._r8*rhow*(Actmp + Artmp)) + arcld(i,k) = arcld(i,k) + 1._r8 + endif + +!...................................................................... +! snow + + if (qniic(i,k) .ge. qsmall) then + lams(k) = (cons6*cs*nsic(i,k)/qniic(i,k))**(1._r8/ds) + n0s(k) = nsic(i,k)*lams(k) + +! check for slope +! adjust vars + + if (lams(k) .lt. lammins) then + lams(k) = lammins + n0s(k) = lams(k)**(ds + 1._r8)*qniic(i,k)/(cs*cons6) + nsic(i,k) = n0s(k)/lams(k) + else if (lams(k) .gt. lammaxs) then + lams(k) = lammaxs + n0s(k) = lams(k)**(ds + 1._r8)*qniic(i,k)/(cs*cons6) + nsic(i,k) = n0s(k)/lams(k) + end if + +! 'final' values of number and mass weighted mean fallspeed for snow (m/s) + + ums(k) = min(asn(i,k)*cons8/(6._r8*lams(k)**bs), & + 1.2_r8*rhof(i,k)) + uns(k) = min(asn(i,k)*cons7/lams(k)**bs, 1.2_r8*rhof(i,k)) + else + lams(k) = 0._r8 + n0s(k) = 0._r8 + ums(k) = 0._r8 + uns(k) = 0._r8 + end if + +!c........................................................................ +! sum over sub-step for average process rates + +! convert rain/snow q and N for output to history, note, +! output is for gridbox average + + qrout(i,k) = qrout(i,k) + qric(i,k)*cldmax(i,k) + qsout(i,k) = qsout(i,k) + qniic(i,k)*cldmax(i,k) + nrout(i,k) = nrout(i,k) + nric(i,k)*rho(i,k)*cldmax(i,k) + nsout(i,k) = nsout(i,k) + nsic(i,k)*rho(i,k)*cldmax(i,k) + + tlat1(i,k) = tlat1(i,k) + tlat(i,k) + qvlat1(i,k) = qvlat1(i,k) + qvlat(i,k) + qctend1(i,k) = qctend1(i,k) + qctend(i,k) + qitend1(i,k) = qitend1(i,k) + qitend(i,k) + nctend1(i,k) = nctend1(i,k) + nctend(i,k) + nitend1(i,k) = nitend1(i,k) + nitend(i,k) + + t(i,k) = t(i,k) + tlat(i,k)*deltat/cpp + q(i,k) = q(i,k) + qvlat(i,k)*deltat + qc(i,k) = qc(i,k) + qctend(i,k)*deltat + qi(i,k) = qi(i,k) + qitend(i,k)*deltat + nc(i,k) = nc(i,k) + nctend(i,k)*deltat + ni(i,k) = ni(i,k) + nitend(i,k)*deltat + + rainrt1(i,k) = rainrt1(i,k) + rainrt(i,k) + +! divide rain radius over substeps for average + if (arcld(i,k) .gt. 0._r8) then + rercld(i,k) = rercld(i,k)/arcld(i,k) + end if + +! calculate precip fluxes and adding them to summing sub-stepping variables +! flux is zero at top interface + rflx(i,1) = 0.0_r8 + sflx(i,1) = 0.0_r8 + +! calculating the precip flux (kg/m2/s) as mixingratio(kg/kg)* +! airdensity(kg/m3)*massweightedfallspeed(m/s) +!!RSH 11/28/11 FIX OF BUG ?? + rflx(i,k+1)=qrout(i,k)*rho(i,k)*umr(k) + sflx(i,k+1)=qsout(i,k)*rho(i,k)*ums(k) + +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then + rflx(i,k+1) = qric(i,k)*cldmax(i,k)*rho(i,k)*umr(k) + sflx(i,k+1) = qniic(i,k)*cldmax(i,k)*rho(i,k)*ums(k) + endif +#endif + +! add to summing sub-stepping variable + rflx1(i,k+1) = rflx1(i,k+1) + rflx(i,k+1) + sflx1(i,k+1) = sflx1(i,k+1) + sflx(i,k+1) + +!c........................................................................ + +#ifdef GFDL_COMPATIBLE_MICROP +!droplet number + npccno(i,k) = npccno(i,k) + npccn(k)*mtime + nnuccco(i,k) = nnuccco(i,k) - nnuccc(k)*lcldm(i,k) + nnuccto(i,k) = nnuccto(i,k) - nnucct(k)*lcldm(i,k) + npsacwso(i,k) = npsacwso(i,k) - npsacws(k)*lcldm(i,k) + nsubco(i,k) = nsubco(i,k) + nsubc(k)*lcldm(i,k) + if( .not. lflag ) & + nerosco(i,k) = nerosco(i,k) + nerosc(i,k)*lcldm(i,k) + nprao(i,k) = nprao(i,k) - npra(k)*lcldm(i,k) + nprc1o(i,k) = nprc1o(i,k) - nprc1(k)*lcldm(i,k) + nucclimo(i,k) = nucclimo(i,k) + nucclim(k) + +!ice number + nnuccdo(i,k) = nnuccdo(i,k) + nnuccd(k)*mtime + nsacwio(i,k) = nsacwio(i,k) + nsacwi(k)*lcldm(i,k) + nsubio(i,k) = nsubio(i,k) + nsubi(k)*icldm(i,k) + if( .not. lflag ) & + nerosio(i,k) = nerosio(i,k) + nerosi(i,k)*icldm(i,k) + nprcio(i,k) = nprcio(i,k) - nprci(k)*icldm(i,k) + npraio(i,k) = npraio(i,k) - nprai(k)*icldm(i,k) + nucclim1io(i,k) = nucclim1io(i,k) + nucclim1i(k) +#endif + + end do ! k loop +!c........................................................................ + prect1(i) = prect1(i) + prect(i) + preci1(i) = preci1(i) + preci(i) +!!!!!!!!!!! +! END OF ITER LOOP +!!!!!!!!!!! + end do ! it loop, sub-step + +!---------------------------------------------------------------------- + + do k = 1, pver + rate1ord_cw2pr_st(i,k) = qcsinksum_rate1ord(k)/ & + max(qcsum_rate1ord(k), 1.0e-30_r8) + end do + + 300 continue ! continue if no cloud water ! GO TO 300 + +!!!!!!!!!!! +! END OF I LOOP +!!!!!!!!!!! + end do ! i loop + +! convert dt from sub-step back to full time step + deltat = deltat*real(iter) + +!c........................................................................ + + do i=1,ncol + +! skip all calculations if no cloud water + if (ltrue(i) .eq. 0) then + + do k=1,pver +! assign default values for effective radius + effc(i,k) = 10._r8 + effi(i,k) = 25._r8 + effc_fn(i,k) = 10._r8 + lamcrad(i,k) = 0._r8 + pgamrad(i,k) = 0._r8 + deffi(i,k) = 0._r8 + end do +#ifdef GFDL_COMPATIBLE_MICROP + if (diag_id%vfall > 0) diag_4d(i,j,:,diag_pt%vfall) = 0.0_r8 +#endif + goto 500 ! EXIT FROM LOOP + end if + +! initialize nstep for sedimentation sub-steps + nstep = 1 + +! divide precip rate by number of sub-steps to get average over time step + + prect(i) = prect1(i)/real(iter) + preci(i) = preci1(i)/real(iter) + +#ifdef GFDL_COMPATIBLE_MICROP +! convert unit from m/s to kg/m2/s by multiply water density 1000 kg/m3 + diag_4d(i,j,:, diag_pt%snow_melt) = & + diag_4d(i,j,:, diag_pt%snow_melt)/real(iter) + diag_4d(i,j,:, diag_pt%rain_freeze) = & + diag_4d(i,j,:, diag_pt%rain_freeze)/real(iter) +! <--- h1g, 2010-11-15 +#endif + + do k=1,pver + +! assign variables back to start-of-timestep values before updating +! after sub-steps + + t(i,k) = t1(i,k) + q(i,k) = q1(i,k) + qc(i,k)= qc1(i,k) + qi(i,k) = qi1(i,k) + nc(i,k) = nc1(i,k) + ni(i,k) = ni1(i,k) + +! divide microphysical tendencies by number of sub-steps to get average +! over time step + + tlat(i,k) = tlat1(i,k)/real(iter) + qvlat(i,k) = qvlat1(i,k)/real(iter) + qctend(i,k) = qctend1(i,k)/real(iter) + qitend(i,k) = qitend1(i,k)/real(iter) + nctend(i,k) = nctend1(i,k)/real(iter) + nitend(i,k) = nitend1(i,k)/real(iter) + + rainrt(i,k) = rainrt1(i,k)/real(iter) + +! divide by number of sub-steps to find final values + rflx(i,k+1) = rflx1(i,k+1)/real(iter) + sflx(i,k+1) = sflx1(i,k+1)/real(iter) + +! divide output precip q and N by number of sub-steps to get average over +! time step + + qrout(i,k) = qrout(i,k)/real(iter) + qsout(i,k) = qsout(i,k)/real(iter) + nrout(i,k) = nrout(i,k)/real(iter) + nsout(i,k) = nsout(i,k)/real(iter) + +! divide trop_mozart variables by number of sub-steps to get average over +! time step + + nevapr(i,k) = nevapr(i,k)/real(iter) + evapsnow(i,k) = evapsnow(i,k)/real(iter) + prain(i,k) = prain(i,k)/real(iter) + prodsnow(i,k) = prodsnow(i,k)/real(iter) + cmeout(i,k) = cmeout(i,k)/real(iter) + + cmeiout(i,k) = cmeiout(i,k)/real(iter) + meltsdt(i,k) = meltsdt(i,k)/real(iter) + frzrdt (i,k) = frzrdt (i,k)/real(iter) + +! microphysics output +#ifdef GFDL_COMPATIBLE_MICROP +! vapor + preo(i,k) = preo(i,k)/real(iter) + prdso(i,k) = prdso(i,k)/real(iter) + if( .not. lflag ) then + cmelo(i,k) = cmelo(i,k)/real(iter) + eroslo(i,k) = eroslo(i,k)/real(iter) + erosio(i,k) = erosio(i,k)/real(iter) + endif +#endif +! liquid + prao(i,k) = prao(i,k)/real(iter) + prco(i,k) = prco(i,k)/real(iter) + mnuccco(i,k) = mnuccco(i,k)/real(iter) + mnuccto(i,k) = mnuccto(i,k)/real(iter) + msacwio(i,k) = msacwio(i,k)/real(iter) + psacwso(i,k) = psacwso(i,k)/real(iter) + bergso(i,k) = bergso(i,k)/real(iter) + bergo(i,k) = bergo(i,k)/real(iter) + prcio(i,k) = prcio(i,k)/real(iter) + praio(i,k) = praio(i,k)/real(iter) + + mnuccro(i,k) = mnuccro(i,k)/real(iter) + pracso (i,k) = pracso (i,k)/real(iter) + + mnuccdo(i,k) = mnuccdo(i,k)/real(iter) + +! modify to include snow. in prain & evap (diagnostic here: for wet dep) + nevapr(i,k) = nevapr(i,k) + evapsnow(i,k) + prain(i,k) = prain(i,k) + prodsnow(i,k) + +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! calculate sedimentation for cloud water and ice +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + +! update in-cloud cloud mixing ratio and number concentration +! with microphysical tendencies to calculate sedimentation, assign to dummy +! vars +! note: these are in-cloud values***, hence we divide by cloud fraction + + dumc(i,k) = (qc(i,k) + qctend(i,k)*deltat)/lcldm(i,k) + dumi(i,k) = (qi(i,k) + qitend(i,k)*deltat)/icldm(i,k) + dumnc(i,k) = max((nc(i,k) + nctend(i,k)*deltat)/lcldm(i,k),0._r8) + dumni(i,k) = max((ni(i,k) + nitend(i,k)*deltat)/icldm(i,k),0._r8) + +!-->cjg +! hm add 6/2/11 switch for specification of droplet and crystal number + if (nccons) then + dumnc(i,k)=ncnst/rho(i,k) + end if + +! hm add 6/2/11 switch for specification of cloud ice number + if (nicons) then + dumni(i,k)=ninst/rho(i,k) + end if +!<--cjg + +! obtain new slope parameter to avoid possible singularity + + if (dumi(i,k) .ge. qsmall) then +! add upper limit to in-cloud number concentration to prevent +! numerical error + dumni(i,k) = min(dumni(i,k), dumi(i,k)*1.e20_r8) + + lami(k) = (cons1*ci*dumni(i,k)/dumi(i,k))**(1._r8/di) + lami(k) = max(lami(k),lammini) + lami(k) = min(lami(k),lammaxi) + else + lami(k)=0._r8 + end if + + if (dumc(i,k) .ge. qsmall) then +! add upper limit to in-cloud number concentration to prevent +! numerical error + dumnc(i,k) = min(dumnc(i,k), dumc(i,k)*1.e20_r8) +! add lower limit to in-cloud number concentration + dumnc(i,k) = max(dumnc(i,k), cdnl/rho(i,k)) ! sghan minimum + ! in #/cm3 +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then +!RSH76 pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + pgam(k) = 0.0005714_r8*(dumnc(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + else + pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + endif +#else + pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 +#endif + pgam(k) = 1._r8/(pgam(k)**2) - 1._r8 + pgam(k) = max(pgam(k), 2._r8) + pgam(k) = min(pgam(k), 15._r8) + + lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k) + 4._r8)/ & + (dumc(i,k)*gamma(pgam(k) + 1._r8)))**(1._r8/3._r8) + lammin = (pgam(k) + 1._r8)/50.e-6_r8 + lammax = (pgam(k) + 1._r8)/2.e-6_r8 + lamc(k) = max(lamc(k), lammin) + lamc(k) = min(lamc(k), lammax) + else + lamc(k) = 0._r8 + end if + +! calculate number and mass weighted fall velocity for droplets +! include effects of sub-grid distribution of cloud water + + + if (dumc(i,k).ge.qsmall) then + unc = & + acn(i,k)*gamma(1._r8 + bc+pgam(k))/ & + (lamc(k)**bc*gamma(pgam(k) + 1._r8)) + umc = & + acn(i,k)*gamma(4._r8 + bc+pgam(k))/ & + (lamc(k)**bc*gamma(pgam(k) + 4._r8)) +! fallspeed for output + vtrmc(i,k)=umc + else + umc = 0._r8 + unc = 0._r8 + end if + +! calculate number and mass weighted fall velocity for cloud ice + + if (dumi(i,k).ge.qsmall) then + uni = ain(i,k)*cons16/lami(k)**bi + umi = ain(i,k)*cons17/(6._r8*lami(k)**bi) + uni = min(uni, 1.2_r8*rhof(i,k)) + umi = min(umi, 1.2_r8*rhof(i,k)) + +! fallspeed + vtrmi(i,k) = umi + else + umi = 0._r8 + uni = 0._r8 + end if + +#ifdef GFDL_COMPATIBLE_MICROP + if (diag_id%vfall > 0) diag_4d(i,j,k,diag_pt%vfall) = umi +#endif + + fi(k) = g*rho(i,k)*umi + fni(k) = g*rho(i,k)*uni + fc(k) = g*rho(i,k)*umc + fnc(k) = g*rho(i,k)*unc + +! calculate number of split time steps to ensure courant stability criteria +! for sedimentation calculations + + rgvm = max(fi(k), fc(k), fni(k), fnc(k)) + nstep = max(int(rgvm*deltat/pdel(i,k) + 1._r8),nstep) + +! redefine dummy variables - sedimentation is calculated over grid-scale +! quantities to ensure conservation + + dumc(i,k) = (qc(i,k) + qctend(i,k)*deltat) + dumi(i,k) = (qi(i,k) + qitend(i,k)*deltat) + dumnc(i,k) = max((nc(i,k) + nctend(i,k)*deltat), 0._r8) + dumni(i,k) = max((ni(i,k) + nitend(i,k)*deltat), 0._r8) + + if (dumc(i,k) .lt. qsmall) dumnc(i,k) = 0._r8 + if (dumi(i,k) .lt. qsmall) dumni(i,k) = 0._r8 + + end do !!! vertical loop + + do n = 1,nstep !! loop over sub-time step to ensure stability + do k = 1,pver + falouti(k) = fi(k)*dumi(i,k) + faloutni(k) = fni(k)*dumni(i,k) + faloutc(k) = fc(k)*dumc(i,k) + faloutnc(k) = fnc(k)*dumnc(i,k) + end do + +! top of model + + k = 1 + faltndi = falouti(k)/pdel(i,k) + faltndni = faloutni(k)/pdel(i,k) + faltndc = faloutc(k)/pdel(i,k) + faltndnc = faloutnc(k)/pdel(i,k) + +! add fallout terms to microphysical tendencies + + qitend(i,k) = qitend(i,k) - faltndi/nstep + nitend(i,k) = nitend(i,k) - faltndni/nstep + qctend(i,k) = qctend(i,k) - faltndc/nstep + nctend(i,k) = nctend(i,k) - faltndnc/nstep + +! sedimentation tendencies for output + qcsedten(i,k) = qcsedten(i,k) - faltndc/nstep + qisedten(i,k) = qisedten(i,k) - faltndi/nstep + +#ifdef GFDL_COMPATIBLE_MICROP + IF ( diag_id%qndt_sedi + diag_id%qn_sedi_col > 0 ) & + diag_4d(i,j,k,diag_pt%qndt_sedi) = & + diag_4d(i,j,k,diag_pt%qndt_sedi) - faltndnc/nstep + + IF ( diag_id%qnidt_sedi + diag_id%qni_sedi_col > 0 ) & + diag_4d(i,j,k,diag_pt%qnidt_sedi) = & + diag_4d(i,j,k,diag_pt%qnidt_sedi) - faltndni/nstep +#endif + + dumi(i,k) = dumi(i,k) - faltndi*deltat/nstep + dumni(i,k) = dumni(i,k) - faltndni*deltat/nstep + dumc(i,k) = dumc(i,k) - faltndc*deltat/nstep + dumnc(i,k) = dumnc(i,k) - faltndnc*deltat/nstep + + do k = 2,pver + +! for cloud liquid and ice, if cloud fraction increases with height +! then add flux from above to both vapor and cloud water of current level +! this means that flux entering clear portion of cell from above evaporates +! instantly + + dum = lcldm(i,k)/lcldm(i,k-1) + dum = min(dum, 1._r8) + dum1 = icldm(i,k)/icldm(i,k-1) + dum1 = min(dum1, 1._r8) + + faltndqie = (falouti(k) - falouti(k-1))/pdel(i,k) + faltndi = (falouti(k) - dum1*falouti(k-1))/pdel(i,k) + faltndni = (faloutni(k) - dum1*faloutni(k-1))/pdel(i,k) + faltndqce = (faloutc(k) - faloutc(k-1))/pdel(i,k) + faltndc = (faloutc(k) - dum*faloutc(k-1))/pdel(i,k) + faltndnc = (faloutnc(k) - dum*faloutnc(k-1))/pdel(i,k) + +! add fallout terms to eulerian tendencies + + qitend(i,k) = qitend(i,k) - faltndi/nstep + nitend(i,k) = nitend(i,k) - faltndni/nstep + qctend(i,k) = qctend(i,k) - faltndc/nstep + nctend(i,k) = nctend(i,k) - faltndnc/nstep + +! sedimentation tendencies for output + qcsedten(i,k) = qcsedten(i,k) - faltndc/nstep + qisedten(i,k) = qisedten(i,k) - faltndi/nstep + +! add terms to to evap/sub of cloud water + +#ifdef GFDL_COMPATIBLE_MICROP + IF ( diag_id%qndt_sedi + diag_id%qn_sedi_col > 0 ) & + diag_4d(i,j,k,diag_pt%qndt_sedi) = & + diag_4d(i,j,k,diag_pt%qndt_sedi) - faltndnc/nstep + + IF ( diag_id%qnidt_sedi + diag_id%qni_sedi_col > 0 ) & + diag_4d(i,j,k,diag_pt%qnidt_sedi) = & + diag_4d(i,j,k,diag_pt%qnidt_sedi) - faltndni/nstep +#endif + + qvlat(i,k) = qvlat(i,k) - (faltndqie-faltndi)/nstep +! for output + qisevap(i,k) = qisevap(i,k) - (faltndqie - faltndi)/nstep + qvlat(i,k) = qvlat(i,k) - (faltndqce - faltndc)/nstep +! for output + qcsevap(i,k) = qcsevap(i,k) - (faltndqce - faltndc)/nstep + + tlat(i,k) = tlat(i,k) + (faltndqie - faltndi)*xxls/nstep + tlat(i,k) = tlat(i,k) + (faltndqce - faltndc)*xxlv/nstep + + dumi(i,k) = dumi(i,k) - faltndi*deltat/nstep + dumni(i,k) = dumni(i,k) - faltndni*deltat/nstep + dumc(i,k) = dumc(i,k) - faltndc*deltat/nstep + dumnc(i,k) = dumnc(i,k) - faltndnc*deltat/nstep + + Fni(K) = MAX(Fni(K)/pdel(i,K), Fni(K-1)/pdel(i,K-1))*pdel(i,K) + FI(K) = MAX(FI(K)/pdel(i,K), FI(K-1)/pdel(i,K-1))*pdel(i,K) + fnc(k) = max(fnc(k)/pdel(i,k), fnc(k-1)/pdel(i,k-1))*pdel(i,k) + Fc(K) = MAX(Fc(K)/pdel(i,K), Fc(K-1)/pdel(i,K-1))*pdel(i,K) + end do !! k loop + +! units below are m/s +! cloud water/ice sedimentation flux at surface +! is added to precip flux at surface to get total precip +! (cloud + precip water) rate + + prect(i) = prect(i) + (faloutc(pver) + falouti(pver))/ & + g/nstep/1000._r8 + preci(i) = preci(i) + (falouti(pver)) & + /g/nstep/1000._r8 + +#ifdef GFDL_COMPATIBLE_MICROP +! for the diagnostic of surface precip + k = 1 + IF ( diag_id%sedi_sfc > 0 ) & + diag_4d(i,j,1,diag_pt%sedi_sfc) = & + diag_4d(i,j,1,diag_pt%sedi_sfc) + & + faloutc(pver)/g/nstep/rhow + IF ( diag_id%sedi_ice > 0 ) & + diag_4d(i,j,1,diag_pt%sedi_ice) = & + diag_4d(i,j,1,diag_pt%sedi_ice) + & + falouti(pver)/g/nstep/rhoi +#endif + end do !! nstep loop + +! end sedimentation +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + +! get new update for variables that includes sedimentation tendency +! note : here dum variables are grid-average, NOT in-cloud + + do k=1,pver + + dumc(i,k) = max(qc(i,k) + qctend(i,k)*deltat, 0._r8) + dumi(i,k) = max(qi(i,k) + qitend(i,k)*deltat, 0._r8) + dumnc(i,k) = max(nc(i,k) + nctend(i,k)*deltat, 0._r8) + dumni(i,k) = max(ni(i,k) + nitend(i,k)*deltat, 0._r8) + +!-->cjg +! hm add 6/2/11 switch for specification of droplet and crystal number + if (nccons) then + dumnc(i,k)=ncnst/rho(i,k)*lcldm(i,k) + end if + +! hm add 6/2/11 switch for specification of cloud ice number + if (nicons) then + dumni(i,k)=ninst/rho(i,k)*icldm(i,k) + end if +!<--cjg + + if (dumc(i,k) .lt. qsmall) dumnc(i,k) = 0._r8 + if (dumi(i,k) .lt. qsmall) dumni(i,k) = 0._r8 + +! calculate instantaneous processes (melting, homogeneous freezing) + + if (t(i,k) + tlat(i,k)/cpp*deltat > tmelt) then + if (dumi(i,k) > 0._r8) then + +! limit so that melting does not push temperature below freezing + dum = -dumi(i,k)*xlf/cpp + if (t(i,k) + tlat(i,k)/cpp*deltat + dum .lt. tmelt) then + dum = (t(i,k) + tlat(i,k)/cpp*deltat - tmelt)*cpp/xlf + dum = dum/dumi(i,k)*xlf/cpp + dum = max(0._r8, dum) + dum = min(1._r8, dum) + else + dum = 1._r8 + end if + + qctend(i,k) = qctend(i,k) + dum*dumi(i,k)/deltat + +! for output + melto(i,k) = dum*dumi(i,k)/deltat + +! assume melting ice produces droplet +! mean volume radius of 8 micron + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qndt_melt + diag_id%qn_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_melt) = nctend(i,k) + IF (diag_id%qidt_melt2 + diag_id%qi_melt2_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_melt2) = qitend(i,k) + IF (diag_id%qnidt_melt + diag_id%qni_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_melt) = nitend(i,k) +#endif + + nctend(i,k) = nctend(i,k) + 3._r8*dum*dumi(i,k)/deltat/ & + (4._r8*pi*5.12e-16_r8*rhow) + + qitend(i,k) = ((1._r8 - dum)*dumi(i,k) - qi(i,k))/deltat + nitend(i,k) = ((1._r8 - dum)*dumni(i,k) - ni(i,k))/deltat + tlat(i,k) = tlat(i,k) - xlf*dum*dumi(i,k)/deltat + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qndt_melt + diag_id%qn_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_melt) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_melt) + IF (diag_id%qidt_melt2 + diag_id%qi_melt2_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_melt2) = & + qitend(i,k) - diag_4d(i,j,k,diag_pt%qidt_melt2) + IF (diag_id%qnidt_melt + diag_id%qni_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_melt) = & + nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_melt) +#endif + end if + end if + +! homogeneously freeze droplets at -40 C + + if (t(i,k) + tlat(i,k)/cpp*deltat < tmelt -40._r8) then + if (dumc(i,k) > 0._r8) then + +! limit so that freezing does not push temperature above threshold + dum = dumc(i,k)*xlf/cpp + if (t(i,k) + tlat(i,k)/cpp*deltat + & + dum .gt. tmelt - 40._r8) then + dum = -(t(i,k) + tlat(i,k)/cpp*deltat - (tmelt -40._r8))* & + cpp/xlf + dum = dum/dumc(i,k)*xlf/cpp + dum = max(0._r8, dum) + dum = min(1._r8, dum) + else + dum = 1._r8 + end if + + qitend(i,k) = qitend(i,k) + dum*dumc(i,k)/deltat +! for output + homoo(i,k) = dum*dumc(i,k)/deltat + +! assume 25 micron mean volume radius of homogeneously frozen droplets +! consistent with size of detrained ice in stratiform.F90 + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qldt_freez + diag_id%ql_freez_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_freez) = qctend(i,k) + sum_freeze(i,k) = qctend(i,k) + IF ( diag_id%qndt_ihom + diag_id%qn_ihom_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_ihom) = nctend(i,k) +#endif + + +! 4/24/12: replace the 1.563 with x**3, here and in nCAR routine. + nitend(i,k) = nitend(i,k) + dum*3._r8*dumc(i,k)/ & + (4._r8*3.14_r8*1.563e-14_r8*500._r8)/deltat + qctend(i,k) = ((1._r8 - dum)*dumc(i,k) - qc(i,k))/deltat + nctend(i,k) = ((1._r8 - dum)*dumnc(i,k) - nc(i,k))/deltat + tlat(i,k) = tlat(i,k) + xlf*dum*dumc(i,k)/deltat + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qldt_freez + diag_id%ql_freez_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_freez) = & + qctend(i,k) - diag_4d(i,j,k,diag_pt%qldt_freez) + sum_freeze(i,k) = -(qctend(i,k) - sum_freeze(i,k)) + IF (diag_id%qndt_ihom + diag_id%qn_ihom_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_ihom) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_ihom) +! 4/24/12: replace the 1.563 with x**3, here and in nCAR routine. + IF ( diag_id%qnidt_ihom + diag_id%qni_ihom_col > 0 ) & + diag_4d(i,j,k,diag_pt%qnidt_ihom) = & + dum*3._r8*dumc(i,k)/ & + (4._r8*3.14_r8*1.563e-14_r8*500._r8)/deltat +#endif + end if + end if + +! remove any excess over-saturation, which is possible due to non-linearity +! when adding together all microphysical processes +! follow code similar to old CAM scheme + + qtmp = q(i,k) + qvlat(i,k)*deltat + ttmp = t(i,k) + tlat(i,k)/cpp*deltat + + esn = polysvp(ttmp,0) ! use rhw to allow ice supersaturation + qsn = min(epsqs*esn/(p(i,k) - (1._r8 - epsqs)*esn), 1._r8) + +#ifdef GFDL_COMPATIBLE_MICROP + if (qtmp > qsn .and. qsn > 0._r8) then + +! expression below is approximate since there may be ice deposition + dum = (qtmp - qsn)/(1._r8 + cons27*qsn/(cpp*rv*ttmp**2))/deltat + +! add to output cme + cmeout(i,k) = cmeout(i,k) + dum + +! now add to tendencies, partition between liquid and ice based on +! temperature + + if( .not. lflag ) then + if (tiedtke_macrophysics) then + if (ttmp > tmelt - 5._r8) then + dum1 = 0.0_r8 + ssat_disposal(i,k) = 1._r8 + else if (ttmp < tmelt - 40._r8) then + dum1 = 1.0_r8 + ssat_disposal(i,k) = 2._r8 + else + dum1 = 0.0_r8 + ssat_disposal(i,k) = 1._r8 + end if + else ! (tiedtke_macrophysics) + +! for non-tiedtke, need to define how supersaturation removal affects +! particle number, if at all ?? +! for now, assume supersaturation removal does not lead to change in +! particle numbers +! use ice / liq partitioning as in original NCAR + ssat_disposal(i,k) = 0._r8 + if (ttmp > tmelt - 5._r8) then + dum1 = 0.0_r8 + else if (ttmp < tmelt - 35._r8) then + dum1 = 1.0_r8 + else + dum1 = (tmelt - 5._r8 - ttmp)/30._r8 + end if + endif !(tiedtke_macrophysics) + +!???????? +!RSH 10/05 0553 +! dum = (qtmp-qsn)/(1._r8+(xxls*dum1+xxlv*(1._r8-dum1))**2 & + dum = (qtmp - qsn)/(1._r8 + & + (xxlv*dum1 + xxlv*(1._r8 - dum1))**2* & + qsn/(cpp*rv*ttmp**2))/deltat + + else + if (ttmp > 268.15_r8) then + dum1=0.0_r8 +! now add to tendencies, partition between liquid and ice based on te + else if (ttmp < 238.15_r8) then + dum1=1.0_r8 + else + dum1=(268.15_r8-ttmp)/30._r8 + end if + dum = (qtmp-qsn)/(1._r8+(xxls*dum1+xxlv*(1._r8-dum1))**2 & + *qsn/(cpp*rv*ttmp**2))/deltat + endif + qctend(i,k) = qctend(i,k) + dum*(1._r8 - dum1) +! for output + qcreso(i,k) = dum*(1._r8 - dum1) + qitend(i,k) = qitend(i,k) + dum*dum1 + qireso(i,k) = dum*dum1 + qvlat(i,k) = qvlat(i,k) - dum +! for output + qvres(i,k) = -dum + tlat(i,k) = tlat(i,k) + dum*(1._r8 - dum1)*xxlv + dum*dum1*xxls + else + if( .not. lflag ) & + ssat_disposal(i,k) = 0._r8 + end if +#else + if (qtmp > qsn .and. qsn > 0._r8) then + +! expression below is approximate since there may be ice deposition + dum = (qtmp - qsn)/(1._r8 + cons27*qsn/(cpp*rv*ttmp**2))/deltat + +! add to output cme + cmeout(i,k) = cmeout(i,k) + dum + +! now add to tendencies, partition between liquid and ice based on +! temperature + if (ttmp > tmelt - 5._r8) then + dum1 = 0.0_r8 + else if (ttmp < tmelt - 35._r8) then + dum1 = 1.0_r8 + else + dum1 = (tmelt - 5._r8 - ttmp)/30._r8 + end if + + dum = (qtmp - qsn)/(1._r8 + & + (xxls*dum1 + xxlv*(1._r8 - dum1))**2 * & + qsn/(cpp*rv*ttmp**2))/deltat + qctend(i,k) = qctend(i,k) + dum*(1._r8 - dum1) +! for output + qcreso(i,k) = dum*(1._r8 - dum1) + qitend(i,k) = qitend(i,k) + dum*dum1 + qireso(i,k) = dum*dum1 + qvlat(i,k) = qvlat(i,k) - dum +! for output + qvres(i,k) = -dum + tlat(i,k) = tlat(i,k) + dum*(1._r8 - dum1)*xxlv+dum*dum1*xxls + endif +#endif +!......................................................................... +! calculate effective radius for pass to radiation code +! if no cloud water, default value is 10 micron for droplets, +! 25 micron for cloud ice + +! update cloud variables after instantaneous processes to get effective +! radius +! variables are in-cloud to calculate size dist parameters + + dumc(i,k) = max(qc(i,k) + qctend(i,k)*deltat, 0._r8)/lcldm(i,k) + dumi(i,k) = max(qi(i,k) + qitend(i,k)*deltat, 0._r8)/icldm(i,k) + dumnc(i,k) = max(nc(i,k) + nctend(i,k)*deltat, 0._r8)/lcldm(i,k) + dumni(i,k) = max(ni(i,k) + nitend(i,k)*deltat, 0._r8)/icldm(i,k) + +!-->cjg +! hm add 6/2/11 switch for specification of droplet and crystal number + if (nccons) then + dumnc(i,k)=ncnst/rho(i,k) + end if + +! hm add 6/2/11 switch for specification of cloud ice number + if (nicons) then + dumni(i,k)=ninst/rho(i,k) + end if +!<--cjg + +! limit in-cloud mixing ratio to reasonable value of 5 g kg-1 + + dumc(i,k) = min(dumc(i,k), 5.e-3_r8) + dumi(i,k) = min(dumi(i,k), 5.e-3_r8) + +!................... +! cloud ice effective radius + + if (dumi(i,k) .ge. qsmall) then +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qnidt_size_adj + diag_id%qni_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_size_adj ) = nitend(i,k) +#endif + +! add upper limit to in-cloud number concentration to prevent numerical +! error + dumni(i,k) = min(dumni(i,k), dumi(i,k)*1.e20_r8) + lami(k) = (cons1*ci*dumni(i,k)/dumi(i,k))**(1._r8/di) + + if (lami(k) .lt. lammini) then + lami(k) = lammini + n0i(k) = lami(k)**(di + 1._r8)*dumi(i,k)/(ci*cons1) + niic(i,k) = n0i(k)/lami(k) + +! adjust number conc if needed to keep mean size in reasonable range + nitend(i,k) = (niic(i,k)*icldm(i,k) - ni(i,k))/deltat + else if (lami(k) .gt. lammaxi) then + lami(k) = lammaxi + n0i(k) = lami(k)**(di + 1._r8)*dumi(i,k)/(ci*cons1) + niic(i,k) = n0i(k)/lami(k) + +! adjust number conc if needed to keep mean size in reasonable range + nitend(i,k) = (niic(i,k)*icldm(i,k) - ni(i,k))/deltat + end if + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qnidt_size_adj + diag_id%qni_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_size_adj ) = & + nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_size_adj ) +#endif + + effi(i,k) = 1.5_r8/lami(k)*1.e6_r8 + else + effi(i,k) = 25._r8 + end if + + +! cloud droplet effective radius + + if (dumc(i,k) .ge. qsmall) then +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qndt_size_adj + diag_id%qn_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_size_adj ) = nctend(i,k) +#endif + +! add upper limit to in-cloud number concentration to prevent numerical +! error + dumnc(i,k) = min(dumnc(i,k), dumc(i,k)*1.e20_r8) + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! set tendency to ensure minimum droplet concentration after update by +! microphysics, except when lambda exceeds bounds on +! mean drop size or if there is no cloud water + if (dumnc(i,k) .lt. cdnl/rho(i,k)) then + nctend(i,k) = (cdnl/rho(i,k)*cldm(i,k) - nc(i,k))/deltat + end if + dumnc(i,k) = max(dumnc(i,k), cdnl/rho(i,k)) ! sghan minimum + ! in #/cm3 +!-->cjg +! hm add 6/2/11 switch for specification of droplet and crystal number + if (nccons) then +! make sure nc is consistence with the constant N by adjusting tendency, need +! to multiply by cloud fraction +! note that nctend may be further adjusted below if mean droplet size is +! out of bounds + + nctend(i,k)=(ncnst/rho(i,k)*lcldm(i,k)-nc(i,k))/deltat + end if +!<--cjg + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then +!RSH76 pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + pgam(k) = 0.0005714_r8*(dumnc(i,k)/1.e6_r8*rho(i,k)) + & + 0.2714_r8 + else + pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + endif +#else + pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 +#endif + pgam(k) = 1._r8/(pgam(k)**2) - 1._r8 + pgam(k) = max(pgam(k), 2._r8) + pgam(k) = min(pgam(k), 15._r8) + + lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k) + 4._r8)/ & + (dumc(i,k)*gamma(pgam(k) + 1._r8)))**(1._r8/3._r8) + lammin = (pgam(k) + 1._r8)/50.e-6_r8 + lammax = (pgam(k) + 1._r8)/2.e-6_r8 + if (lamc(k) .lt. lammin) then + lamc(k) = lammin + ncic(i,k) = 6._r8*lamc(k)**3*dumc(i,k)* & + gamma(pgam(k) + 1._r8)/& + (pi*rhow*gamma(pgam(k) + 4._r8)) + +! adjust number conc if needed to keep mean size in reasonable range + nctend(i,k) = (ncic(i,k)*lcldm(i,k) - nc(i,k))/deltat + + else if (lamc(k) .gt. lammax) then + lamc(k) = lammax + ncic(i,k) = 6._r8*lamc(k)**3*dumc(i,k)* & + gamma(pgam(k) + 1._r8)/ & + (pi*rhow*gamma(pgam(k) + 4._r8)) + +! adjust number conc if needed to keep mean size in reasonable range + nctend(i,k) = (ncic(i,k)*lcldm(i,k) - nc(i,k))/deltat + end if + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qndt_size_adj + diag_id%qn_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_size_adj ) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_size_adj ) +#endif + + effc(i,k) = gamma(pgam(k) + 4._r8)/ & + gamma(pgam(k) + 3._r8)/lamc(k)/2._r8*1.e6_r8 + +!assign output fields for shape here + lamcrad(i,k) = lamc(k) + pgamrad(i,k) = pgam(k) + else + effc(i,k) = 10._r8 + lamcrad(i,k)=0._r8 + pgamrad(i,k)=0._r8 + end if + +! ice effective diameter for david mitchell's optics + deffi(i,k) = effi(i,k)*rhoi/917._r8*2._r8 + + +! recalculate effective radius for constant number, in order to separate +! first and second indirect effects +! assume constant number of 10^8 kg-1 + + dumnc(i,k) = 1.e8_r8 + + if (dumc(i,k) .ge. qsmall) then +#ifdef GFDL_COMPATIBLE_MICROP + if( .not. lflag ) then +!RSH76 pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + pgam(k) = 0.0005714_r8*(dumnc(i,k)/1.e6_r8*rho(i,k)) + & + 0.2714_r8 + else + pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 + endif +#else + pgam(k)=0.0005714_r8*(ncic(i,k)/1.e6_r8*rho(i,k))+0.2714_r8 +#endif + pgam(k) = 1._r8/(pgam(k)**2) - 1._r8 + pgam(k) = max(pgam(k), 2._r8) + pgam(k) = min(pgam(k), 15._r8) + + lamc(k) = (pi/6._r8*rhow*dumnc(i,k)*gamma(pgam(k) + 4._r8)/ & + (dumc(i,k)*gamma(pgam(k) + 1._r8)))**(1._r8/3._r8) + lammin = (pgam(k) + 1._r8)/50.e-6_r8 + lammax = (pgam(k) + 1._r8)/2.e-6_r8 + if (lamc(k) .lt. lammin) then + lamc(k) = lammin + else if (lamc(k) .gt. lammax) then + lamc(k) = lammax + end if + effc_fn(i,k) = gamma(pgam(k) + 4._r8)/ & + gamma(pgam(k) + 3._r8)/lamc(k)/2._r8*1.e6_r8 + else + effc_fn(i,k) = 10._r8 + end if + + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1! + + end do ! vertical k loop + + 500 continue + + do k=1,pver +! if updated q (after microphysics) is zero, then ensure updated n is +! also zero + +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qndt_fill2 + diag_id%qn_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_fill2 ) = nctend(i,k) + IF (diag_id%qnidt_fill2 + diag_id%qni_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_fill2 ) = nitend(i,k) +#endif + if (qc(i,k) + qctend(i,k)*deltat .lt. qsmall) nctend(i,k) = & + -nc(i,k)/deltat + if (qi(i,k) + qitend(i,k)*deltat .lt. qsmall) nitend(i,k)= & + -ni(i,k)/deltat +#ifdef GFDL_COMPATIBLE_MICROP + IF (diag_id%qndt_fill2 + diag_id%qn_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_fill2 ) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_fill2 ) + IF (diag_id%qnidt_fill2 + diag_id%qni_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_fill2 ) = & + nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_fill2 ) +#endif + end do ! k loop + + end do ! i loop + +! hm add rain/snow mixing ratio and number concentration as diagnostic + +#ifndef GFDL_COMPATIBLE_MICROP + call outfld('QRAIN',qrout, pcols, lchnk) + call outfld('QSNOW',qsout, pcols, lchnk) + call outfld('NRAIN',nrout, pcols, lchnk) + call outfld('NSNOW',nsout, pcols, lchnk) +#endif + +! add snow output + do i = 1,ncol + do k=1,pver + if (qsout(i,k) .gt. 1.e-7_r8 .and. nsout(i,k) .gt. 0._r8) then + dsout(i,k) = 3._r8*rhosn/917._r8* & + (pi*rhosn*nsout(i,k)/qsout(i,k))**(-1._r8/3._r8) + endif + end do + end do + +#ifndef GFDL_COMPATIBLE_MICROP + call outfld('DSNOW',dsout, pcols, lchnk) + +! calculate effective radius of rain and snow in microns for COSP using +! Eq. 9 of COSP v1.3 manual + do i = 1,ncol + do k=1,pver +!! RAIN + if (qrout(i,k) .gt. 1.e-7_r8 .and. nrout(i,k) .gt. 0._r8) then + reff_rain(i,k) = 1.5_r8* & + (pi*rhow*nrout(i,k)/qrout(i,k))**(-1._r8/3._r8)*1.e6_r8 + endif +!! SNOW + if (qsout(i,k) .gt. 1.e-7_r8 .and. nsout(i,k) .gt. 0._r8) then + reff_snow(i,k) = 1.5_r8* & + (pi*rhosn*nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)*1.e6_r8 + endif + end do + end do + +#else +! calculate effective radius of rain and snow in microns for COSP using +! Eq. 9 of COSP v1.3 manual +! convert to diameter to pass out for use in radiation package +! snow_size is not currently used -- as per mns + do i = 1,ncol + do k=1,pver +!! RAIN + if (qrout(i,k) .gt. 1.e-7_r8 .and. nrout(i,k) .gt. 0._r8) then + lsc_rain_size(i,k) = 3.0_r8* & + (pi*rhow*nrout(i,k)/qrout(i,k))**(-1._r8/3._r8)*1.e6_r8 + +! ---> h1g, hard-write rain effective radius range 30--750 um, 2012-04-25 + if( lflag ) then + lsc_rain_size(i,k) = max( 60.0_r8, lsc_rain_size(i,k) ) + lsc_rain_size(i,k) = min(1500.0_r8, lsc_rain_size(i,k) ) + endif + else + lsc_rain_size(i,k) = 100._r8 + endif +!! SNOW + if (qsout(i,k).gt.1.e-7_r8.and.nsout(i,k).gt.0._r8) then + if( lflag ) & + lsc_snow_size(i,k) = 3.0_r8* & + (pi*rhosn*nsout(i,k)/qsout(i,k))**(-1._r8/3._r8)*1.e6_r8 + endif + end do + end do +#endif + +! analytic radar reflectivity +! formulas from Matthew Shupe, NOAA/CERES +! *****note: radar reflectivity is local (in-precip average) +! units of mm^6/m^3 + + do i = 1,ncol + do k=1,pver + if (qc(i,k) + qctend(i,k)*deltat .ge. qsmall) then + dum = ((qc(i,k) + qctend(i,k)*deltat)/lcldm(i,k) & + *rho(i,k)*1000._r8)**2 / & + (0.109_r8*(nc(i,k) + nctend(i,k)*deltat)/lcldm(i,k)* & + rho(i,k)/1.e6_r8)*lcldm(i,k)/cldmax(i,k) + else + dum=0._r8 + end if + if (qi(i,k) + qitend(i,k)*deltat .ge. qsmall) then + dum1 = ((qi(i,k) + qitend(i,k)*deltat)*rho(i,k)/ & + icldm(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8)* & + icldm(i,k)/cldmax(i,k) + else + dum1 = 0._r8 + end if + + if (qsout(i,k) .ge. qsmall) then + dum1 = dum1 + & + (qsout(i,k)*rho(i,k)*1000._r8/0.1_r8)**(1._r8/0.63_r8) + end if + + refl(i,k) = dum + dum1 + +! add rain rate, but for 37 GHz formulation instead of 94 GHz +! formula approximated from data of Matrasov (2007) +! rainrt is the rain rate in mm/hr +! reflectivity (dum) is in DBz +! don't include rain rate in R calculation for values less than 0.001 mm/hr + + if (rainrt(i,k) .ge. 0.001_r8) then + dum = log10(rainrt(i,k)**6._r8) + 16._r8 + +! convert from DBz to mm^6/m^3 + dum = 10._r8**(dum/10._r8) + else + dum=0._r8 + end if + +! add to refl + + refl(i,k) = refl(i,k) + dum + +! output reflectivity in Z. + areflz(i,k) = refl(i,k) + +! convert back to DBz + + if (refl(i,k) .gt. minrefl) then + refl(i,k) = 10._r8*log10(refl(i,k)) + else + refl(i,k) = -9999._r8 + end if + +! set averaging flag + if (refl(i,k).gt.mindbz) then + arefl(i,k) = refl(i,k) + frefl(i,k) = 1.0_r8 + else + arefl(i,k) = 0._r8 + areflz(i,k) = 0._r8 + frefl(i,k) = 0._r8 + end if + +! bound cloudsat reflectivity + + csrfl(i,k) = min(csmax, refl(i,k)) + +! set averaging flag + if (csrfl(i,k) .gt. csmin) then + acsrfl(i,k) = refl(i,k) + fcsrfl(i,k) = 1.0_r8 + else + acsrfl(i,k) = 0._r8 + fcsrfl(i,k) = 0._r8 + end if + + end do + end do + +#ifndef GFDL_COMPATIBLE_MICROP + call outfld('REFL',refl, pcols, lchnk) + call outfld('AREFL',arefl, pcols, lchnk) + call outfld('AREFLZ',areflz, pcols, lchnk) + call outfld('FREFL',frefl, pcols, lchnk) + call outfld('CSRFL',csrfl, pcols, lchnk) + call outfld('ACSRFL',acsrfl, pcols, lchnk) + call outfld('FCSRFL',fcsrfl, pcols, lchnk) + + call outfld('RERCLD',rercld, pcols, lchnk) +#endif + +! averaging for snow and rain number and diameter + + qrout2(:,:) = 0._r8 + qsout2(:,:) = 0._r8 + nrout2(:,:) = 0._r8 + nsout2(:,:) = 0._r8 + drout2(:,:) = 0._r8 + dsout2(:,:) = 0._r8 + freqs(:,:) = 0._r8 + freqr(:,:) = 0._r8 + do i = 1,ncol + do k=1,pver + if (qrout(i,k) .gt. 1.e-7_r8 .and. nrout(i,k) .gt. 0._r8) then + qrout2(i,k) = qrout(i,k) + nrout2(i,k) = nrout(i,k) + drout2(i,k) = (pi*rhow*nrout(i,k)/qrout(i,k))**(-1._r8/3._r8) + freqr(i,k) = 1._r8 + endif + if (qsout(i,k) .gt. 1.e-7_r8 .and. nsout(i,k) .gt. 0._r8) then + qsout2(i,k) = qsout(i,k) + nsout2(i,k) = nsout(i,k) + dsout2(i,k) = (pi*rhosn*nsout(i,k)/qsout(i,k))**(-1._r8/3._r8) + freqs(i,k) = 1._r8 + endif + end do + end do + +! output activated liquid and ice (convert from #/kg -> #/m3) + do i = 1,ncol + do k=1,pver + ncai(i,k) = dum2i(i,k)*rho(i,k) + ncal(i,k) = dum2l(i,k)*rho(i,k) + end do + end do + +#ifndef GFDL_COMPATIBLE_MICROP + call outfld('NCAL',ncal, pcols,lchnk) + call outfld('NCAI',ncai, pcols,lchnk) + +!add averaged output fields. + call outfld('AQRAIN',qrout2, pcols,lchnk) + call outfld('AQSNOW',qsout2, pcols,lchnk) + call outfld('ANRAIN',nrout2, pcols,lchnk) + call outfld('ANSNOW',nsout2, pcols,lchnk) + call outfld('ADRAIN',drout2, pcols,lchnk) + call outfld('ADSNOW',dsout2, pcols,lchnk) + call outfld('FREQR',freqr, pcols,lchnk) + call outfld('FREQS',freqs, pcols,lchnk) +#endif + +!redefine fice here.... + nfice(:,:) = 0._r8 + do k=1,pver + do i=1,ncol + dumc(i,k) = (qc(i,k) + qctend(i,k)*deltat) + dumi(i,k) = (qi(i,k) + qitend(i,k)*deltat) + dumfice=qsout(i,k) + qrout(i,k) + dumc(i,k) + dumi(i,k) + if (dumfice .gt. qsmall .and. & + (qsout(i,k) + dumi(i,k) .gt. qsmall)) then + nfice(i,k) = (qsout(i,k) + dumi(i,k))/dumfice + endif + + if (nfice(i,k) .gt. 1._r8) then + nfice(i,k) = 1._r8 + endif + + enddo ! i loop + enddo ! k loop + +#ifndef GFDL_COMPATIBLE_MICROP + call outfld('FICE',nfice, pcols, lchnk) +#endif + +#ifdef GFDL_COMPATIBLE_MICROP +! diagnostics for water tendencies +! water vapor specific humicity + if (diag_id%rain_evap + diag_id%rain_evap_col > 0) & + diag_4d(:,j,:,diag_pt%rain_evap) = -preo( : , : ) + if (diag_id%qdt_rain_evap > 0) & + diag_4d(:,j,:,diag_pt%qdt_rain_evap) = -preo( : , : ) + if (diag_id%qdt_cond > 0) & + diag_4d(:,j,:,diag_pt%qdt_cond) = -cmelo(:,:) + if (diag_id%qdt_snow_sublim > 0 .or. & + diag_id%q_snow_sublim_col > 0 ) & + diag_4d(:,j,:,diag_pt%qdt_snow_sublim ) = - prdso( : , : ) + if (diag_id%qdt_deposition > 0) & + diag_4d(:,j,:,diag_pt%qdt_deposition ) = -cmeiout( : , : ) + if (diag_id%qdt_sedi_ice2vapor> 0) & + diag_4d(:,j,:,diag_pt%qdt_sedi_ice2vapor) = qisevap( : , : ) + if (diag_id%qdt_sedi_liquid2vapor> 0) & + diag_4d(:,j,:,diag_pt%qdt_sedi_liquid2vapor) = qcsevap( : , : ) + if (diag_id%qdt_super_sat_rm > 0) & + diag_4d(:,j,:,diag_pt%qdt_super_sat_rm) = qvres( : , : ) + +! cloud liquid water + if (diag_id%qldt_accr + diag_id%ql_accr_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_accr) = - prao(:,:) + if (diag_id%qldt_auto + diag_id%ql_auto_col > 0)& + diag_4d(:,j,:,diag_pt%qldt_auto) = -prco(:,:) + if (diag_id%qldt_freez2 + diag_id%ql_freez2_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_freez2) = & + -(mnuccco(:,:) + mnuccto(:,:) ) + sum_freeze2(:,:) = mnuccco(:,:) + mnuccto(:,:) + if (diag_id%qldt_accrs + diag_id%ql_accrs_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_accrs) = -psacwso(:,:) + sum_rime(:,:) = psacwso(:,:) + if (diag_id%qldt_HM_splinter + diag_id%ql_HM_splinter_col > 0)& + diag_4d(:,j,:,diag_pt%qldt_HM_splinter) = -msacwio(:,:) + sum_splinter(:,:) = msacwio(:,:) + if (diag_id%qldt_bergs + diag_id%ql_bergs_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_bergs) = -bergso(:,:) + sum_bergs(:,:) = bergso (:,:) + if (diag_id%qidt_dep + diag_id%qi_dep_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_dep) = max(cmeiout(:,:),0._r8) + sum_cond(:,:) = max(cmeiout(:,:),0._r8) + if (diag_id%qidt_subl + diag_id%qi_subl_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_subl) = & + -max(-1._r8*cmeiout(:,:),0._r8) + if (diag_id%qldt_cond + diag_id%ql_cond_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_cond) = max(cmelo(:,:), 0._r8) + if (diag_id%qldt_evap + diag_id%ql_evap_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_evap) = & + - max(-1._r8*cmelo(:,:),0._r8) + if (diag_id%qldt_eros + diag_id%ql_eros_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_eros) = eroslo (:,:) + if (diag_id%qdt_eros_l > 0) & + diag_4d(:,j,:,diag_pt%qdt_eros_l) = -eroslo (:,:) + if (diag_id%qidt_eros + diag_id%qi_eros_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_eros) = erosio (:,:) + if (diag_id%qdt_eros_i > 0) & + diag_4d(:,j,:,diag_pt%qdt_eros_i) = -erosio (:,:) + if (diag_id%qldt_berg + diag_id%ql_berg_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_berg) = -bergo(:,:) + sum_berg(:,:) = bergo(:,:) + IF ( diag_id%qldt_sedi + diag_id%ql_sedi_col > 0 ) & + diag_4d(:,j,1:pver,diag_pt%qldt_sedi) = qcsedten(:,1:pver) + IF ( diag_id%liq_adj + diag_id%liq_adj_col > 0 ) & + diag_4d(:,j,:,diag_pt%liq_adj) = qcreso(:,:) + +! cloud ice water + if (diag_id%qidt_auto + diag_id%qi_auto_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_auto) = -prcio(:,:) + if (diag_id%qidt_accr + diag_id%qi_accr_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_accr) = -praio(:,:) + IF ( diag_id%qidt_fall + diag_id%qi_fall_col > 0 ) & + diag_4d(:,j,1:pver,diag_pt%qidt_fall) = qisedten(:,1:pver) + IF ( diag_id%ice_adj + diag_id%ice_adj_col > 0 ) & + diag_4d(:,j,:,diag_pt%ice_adj) = qireso(:,:) + sum_ice_adj(:,:) = qireso(:,:) + +! ---> rain water mixing ratio + if (diag_id%srfrain_accrs + diag_id%srfrain_accrs_col > 0) & + diag_4d(:,j,:,diag_pt%srfrain_accrs) = -pracso(:,:) + if (diag_id%srfrain_freez + diag_id%srfrain_freez_col > 0) & + diag_4d(:,j,:,diag_pt%srfrain_freez) = -mnuccro(:,:) + +! ---> snow mixing ratio + +! --->liquid droplet number + if (diag_id%qndt_cond + diag_id%qn_cond_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_cond) = npccno(:,:) /real(iter) + if (diag_id%qndt_freez + diag_id%qn_freez_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_freez) = nnuccco(:,:) /real(iter) + if (diag_id%qndt_contact_frz > 0) & + diag_4d(:,j,:,diag_pt%qndt_contact_frz) = & + nnuccto(:,:) /real(iter) + if (diag_id%qndt_sacws + diag_id%qn_sacws_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_sacws) = npsacwso(:,:) /real(iter) + if (diag_id%qndt_evap + diag_id%qn_evap_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_evap) = nsubco(:,:) /real(iter) + if (diag_id%qndt_eros + diag_id%qn_eros_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_eros) = nerosco(:,:) /real(iter) + if (diag_id%qndt_pra + diag_id%qn_pra_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_pra) = nprao(:,:) /real(iter) + if (diag_id%qndt_auto + diag_id%qn_auto_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_auto) = nprc1o(:,:) /real(iter) + if ( diag_id%qndt_nucclim + diag_id%qn_nucclim_col > 0 ) & + diag_4d(:,j,:,diag_pt%qndt_nucclim) = & + nucclimo(:,:) /real(iter) + +! ---> ice number + if (diag_id%qnidt_nnuccd + diag_id%qni_nnuccd_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nnuccd) = & + nnuccdo(:,:) /real(iter) + if (diag_id%qnidt_nsacwi> 0) & + diag_4d(:,j,:,diag_pt%qnidt_nsacwi) = & + nsacwio(:,:) /real(iter) + if (diag_id%qnidt_nsubi + diag_id%qni_nsubi_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nsubi) = nsubio(:,:) /real(iter) + if (diag_id%qnidt_nerosi + diag_id%qni_nerosi_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nerosi) = nerosio(:,:) /real(iter) + if (diag_id%qnidt_nprci + diag_id%qni_nprci_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nprci) = nprcio(:,:) /real(iter) + if (diag_id%qnidt_nprai + diag_id%qni_nprai_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nprai) = npraio(:,:) /real(iter) + if (diag_id%qnidt_nucclim1 + diag_id%qni_nucclim1_col > 0 ) & + diag_4d(:,j,:,diag_pt%qnidt_nucclim1) = & + nucclim1io(:,:) /real(iter) +!RSH: +! calculate fraction of total ice / snow creation that requires +! ice-forming nuclei + do k=1,pver + do i=1,ncol + qldt_sum = sum_cond(i,k) + sum_rime(i,k) + sum_berg(i,k) + & + sum_ice_adj(i,k) + MAX(sum_bergs(i,k), 0.0) + & + sum_freeze(i,k) + sum_freeze2(i,k) + sum_splinter(i,k) + if (ABS(qldt_sum) > 0.0 ) then + f_snow_berg(i,k) = (sum_berg(i,k) + sum_cond(i,k) + & + sum_ice_adj(i,k) + & + MAX( sum_bergs(i,k), 0.0) + & + sum_freeze (i,k))/qldt_sum + else + f_snow_berg(i,k) = 0._r8 + endif + end do + end do + +#endif + + return + +end subroutine mmicro_pcond + +!######################################################################## + +subroutine mmicro_end + +return + + +end subroutine mmicro_end +! +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + + FUNCTION GAMMA(X) + +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + +!D DOUBLE PRECISION FUNCTION DGAMMA(X) +!---------------------------------------------------------------------- +! +! THIS ROUTINE CALCULATES THE GAMMA FUNCTION FOR A REAL ARGUMENT X. +! COMPUTATION IS BASED ON AN ALGORITHM OUTLINED IN REFERENCE 1. +! THE PROGRAM USES RATIONAL FUNCTIONS THAT APPROXIMATE THE GAMMA +! FUNCTION TO AT LEAST 20 SIGNIFICANT DECIMAL DIGITS. COEFFICIENTS +! FOR THE APPROXIMATION OVER THE INTERVAL (1,2) ARE UNPUBLISHED. +! THOSE FOR THE APPROXIMATION FOR X .GE. 12 ARE FROM REFERENCE 2. +! THE ACCURACY ACHIEVED DEPENDS ON THE ARITHMETIC SYSTEM, THE +! COMPILER, THE INTRINSIC FUNCTIONS, AND PROPER SELECTION OF THE +! MACHINE-DEPENDENT CONSTANTS. +! +! +!******************************************************************* +!******************************************************************* +! +! EXPLANATION OF MACHINE-DEPENDENT CONSTANTS +! +! BETA - RADIX FOR THE FLOATING-POINT REPRESENTATION +! MAXEXP - THE SMALLEST POSITIVE POWER OF BETA THAT OVERFLOWS +! XBIG - THE LARGEST ARGUMENT FOR WHICH GAMMA(X) IS REPRESENTABLE +! IN THE MACHINE, I.E., THE SOLUTION TO THE EQUATION +! GAMMA(XBIG) = BETA**MAXEXP +! XINF - THE LARGEST MACHINE REPRESENTABLE FLOATING-POINT NUMBER; +! APPROXIMATELY BETA**MAXEXP +! EPS - THE SMALLEST POSITIVE FLOATING-POINT NUMBER SUCH THAT +! 1.0+EPS .GT. 1.0 +! XMININ - THE SMALLEST POSITIVE FLOATING-POINT NUMBER SUCH THAT +! 1/XMININ IS MACHINE REPRESENTABLE +! +! APPROXIMATE VALUES FOR SOME IMPORTANT MACHINES ARE: +! +! BETA MAXEXP XBIG +! +! CRAY-1 (S.P.) 2 8191 966.961 +! CYBER 180/855 +! UNDER NOS (S.P.) 2 1070 177.803 +! IEEE (IBM/XT, +! SUN, ETC.) (S.P.) 2 128 35.040 +! IEEE (IBM/XT, +! SUN, ETC.) (D.P.) 2 1024 171.624 +! IBM 3033 (D.P.) 16 63 57.574 +! VAX D-FORMAT (D.P.) 2 127 34.844 +! VAX G-FORMAT (D.P.) 2 1023 171.489 +! +! XINF EPS XMININ +! +! CRAY-1 (S.P.) 5.45E+2465 7.11E-15 1.84E-2466 +! CYBER 180/855 +! UNDER NOS (S.P.) 1.26E+322 3.55E-15 3.14E-294 +! IEEE (IBM/XT, +! SUN, ETC.) (S.P.) 3.40E+38 1.19E-7 1.18E-38 +! IEEE (IBM/XT, +! SUN, ETC.) (D.P.) 1.79D+308 2.22D-16 2.23D-308 +! IBM 3033 (D.P.) 7.23D+75 2.22D-16 1.39D-76 +! VAX D-FORMAT (D.P.) 1.70D+38 1.39D-17 5.88D-39 +! VAX G-FORMAT (D.P.) 8.98D+307 1.11D-16 1.12D-308 +! +!******************************************************************* +!******************************************************************* +! +! ERROR RETURNS +! +! THE PROGRAM RETURNS THE VALUE XINF FOR SINGULARITIES OR +! WHEN OVERFLOW WOULD OCCUR. THE COMPUTATION IS BELIEVED +! TO BE FREE OF UNDERFLOW AND OVERFLOW. +! +! +! INTRINSIC FUNCTIONS REQUIRED ARE: +! +! INT, DBLE, EXP, LOG, REAL, SIN +! +! +! REFERENCES: AN OVERVIEW OF SOFTWARE DEVELOPMENT FOR SPECIAL +! FUNCTIONS W. J. CODY, LECTURE NOTES IN MATHEMATICS, +! 506, NUMERICAL ANALYSIS DUNDEE, 1975, G. A. WATSON +! (ED.), SPRINGER VERLAG, BERLIN, 1976. +! +! COMPUTER APPROXIMATIONS, HART, ET. AL., WILEY AND +! SONS, NEW YORK, 1968. +! +! LATEST MODIFICATION: OCTOBER 12, 1989 +! +! AUTHORS: W. J. CODY AND L. STOLTZ +! APPLIED MATHEMATICS DIVISION +! ARGONNE NATIONAL LABORATORY +! ARGONNE, IL 60439 +! +!---------------------------------------------------------------------- + INTEGER I,N + LOGICAL PARITY + + real(r8) gamma + REAL(r8) & +!D DOUBLE PRECISION + C,CONV,EPS,FACT,HALF,ONE,P,PI,Q,RES,SQRTPI,SUM,TWELVE, & + TWO,X,XBIG,XDEN,XINF,XMININ,XNUM,Y,Y1,YSQ,Z,ZERO + DIMENSION C(7),P(8),Q(8) +!---------------------------------------------------------------------- +! MATHEMATICAL CONSTANTS +!---------------------------------------------------------------------- + DATA ONE,HALF,TWELVE,TWO,ZERO/1.0E0_r8,0.5E0_r8,12.0E0_r8,2.0E0_r8,0.0E0_r8/, & + SQRTPI/0.9189385332046727417803297E0_r8/, & + PI/3.1415926535897932384626434E0_r8/ +!D DATA ONE,HALF,TWELVE,TWO,ZERO/1.0D0,0.5D0,12.0D0,2.0D0,0.0D0/, +!D 1 SQRTPI/0.9189385332046727417803297D0/, +!D 2 PI/3.1415926535897932384626434D0/ +!---------------------------------------------------------------------- +! MACHINE DEPENDENT PARAMETERS +!---------------------------------------------------------------------- + DATA XBIG,XMININ,EPS/35.040E0_r8,1.18E-38_r8,1.19E-7_r8/, & + XINF/3.4E38_r8/ +!D DATA XBIG,XMININ,EPS/171.624D0,2.23D-308,2.22D-16/, +!D 1 XINF/1.79D308/ +!---------------------------------------------------------------------- +! NUMERATOR AND DENOMINATOR COEFFICIENTS FOR RATIONAL MINIMAX +! APPROXIMATION OVER (1,2). +!---------------------------------------------------------------------- + DATA P/-1.71618513886549492533811E+0_r8,2.47656508055759199108314E+1_r8,& + -3.79804256470945635097577E+2_r8,6.29331155312818442661052E+2_r8,& + 8.66966202790413211295064E+2_r8,-3.14512729688483675254357E+4_r8,& + -3.61444134186911729807069E+4_r8,6.64561438202405440627855E+4_r8/ + DATA Q/-3.08402300119738975254353E+1_r8,3.15350626979604161529144E+2_r8,& + -1.01515636749021914166146E+3_r8,-3.10777167157231109440444E+3_r8,& + 2.25381184209801510330112E+4_r8,4.75584627752788110767815E+3_r8,& + -1.34659959864969306392456E+5_r8,-1.15132259675553483497211E+5_r8/ +!D DATA P/-1.71618513886549492533811D+0,2.47656508055759199108314D+1, +!D 1 -3.79804256470945635097577D+2,6.29331155312818442661052D+2, +!D 2 8.66966202790413211295064D+2,-3.14512729688483675254357D+4, +!D 3 -3.61444134186911729807069D+4,6.64561438202405440627855D+4/ +!D DATA Q/-3.08402300119738975254353D+1,3.15350626979604161529144D+2, +!D 1 -1.01515636749021914166146D+3,-3.10777167157231109440444D+3, +!D 2 2.25381184209801510330112D+4,4.75584627752788110767815D+3, +!D 3 -1.34659959864969306392456D+5,-1.15132259675553483497211D+5/ +!---------------------------------------------------------------------- +! COEFFICIENTS FOR MINIMAX APPROXIMATION OVER (12, INF). +!---------------------------------------------------------------------- + DATA C/-1.910444077728E-03_r8,8.4171387781295E-04_r8, & + -5.952379913043012E-04_r8,7.93650793500350248E-04_r8,& + -2.777777777777681622553E-03_r8,8.333333333333333331554247E-02_r8,& + 5.7083835261E-03_r8/ +!D DATA C/-1.910444077728D-03,8.4171387781295D-04, +!D 1 -5.952379913043012D-04,7.93650793500350248D-04, +!D 2 -2.777777777777681622553D-03,8.333333333333333331554247D-02, +!D 3 5.7083835261D-03/ +!---------------------------------------------------------------------- +! STATEMENT FUNCTIONS FOR CONVERSION BETWEEN INTEGER AND FLOAT +!---------------------------------------------------------------------- + CONV(I) = REAL(I,r8) +!D CONV(I) = DBLE(I) + PARITY=.FALSE. + FACT=ONE + N=0 + Y=X + IF(Y.LE.ZERO)THEN +!---------------------------------------------------------------------- +! ARGUMENT IS NEGATIVE +!---------------------------------------------------------------------- + Y=-X + Y1=AINT(Y) + RES=Y-Y1 + IF(RES.NE.ZERO)THEN + IF(Y1.NE.AINT(Y1*HALF)*TWO)PARITY=.TRUE. + FACT=-PI/SIN(PI*RES) + Y=Y+ONE + ELSE + RES=XINF + GOTO 900 + ENDIF + ENDIF +!---------------------------------------------------------------------- +! ARGUMENT IS POSITIVE +!---------------------------------------------------------------------- + IF(Y.LT.EPS)THEN +!---------------------------------------------------------------------- +! ARGUMENT .LT. EPS +!---------------------------------------------------------------------- + IF(Y.GE.XMININ)THEN + RES=ONE/Y + ELSE + RES=XINF + GOTO 900 + ENDIF + ELSEIF(Y.LT.TWELVE)THEN + Y1=Y + IF(Y.LT.ONE)THEN +!---------------------------------------------------------------------- +! 0.0 .LT. ARGUMENT .LT. 1.0 +!---------------------------------------------------------------------- + Z=Y + Y=Y+ONE + ELSE +!---------------------------------------------------------------------- +! 1.0 .LT. ARGUMENT .LT. 12.0, REDUCE ARGUMENT IF NECESSARY +!---------------------------------------------------------------------- + N=INT(Y)-1 + Y=Y-CONV(N) + Z=Y-ONE + ENDIF +!---------------------------------------------------------------------- +! EVALUATE APPROXIMATION FOR 1.0 .LT. ARGUMENT .LT. 2.0 +!---------------------------------------------------------------------- + XNUM=ZERO + XDEN=ONE + DO 260 I=1,8 + XNUM=(XNUM+P(I))*Z + XDEN=XDEN*Z+Q(I) + 260 CONTINUE + RES=XNUM/XDEN+ONE + IF(Y1.LT.Y)THEN +!---------------------------------------------------------------------- +! ADJUST RESULT FOR CASE 0.0 .LT. ARGUMENT .LT. 1.0 +!---------------------------------------------------------------------- + RES=RES/Y1 + ELSEIF(Y1.GT.Y)THEN +!---------------------------------------------------------------------- +! ADJUST RESULT FOR CASE 2.0 .LT. ARGUMENT .LT. 12.0 +!---------------------------------------------------------------------- + DO 290 I=1,N + RES=RES*Y + Y=Y+ONE + 290 CONTINUE + ENDIF + ELSE +!---------------------------------------------------------------------- +! EVALUATE FOR ARGUMENT .GE. 12.0, +!---------------------------------------------------------------------- + IF(Y.LE.XBIG)THEN + YSQ=Y*Y + SUM=C(7) + DO 350 I=1,6 + SUM=SUM/YSQ+C(I) + 350 CONTINUE + SUM=SUM/Y-Y+SQRTPI + SUM=SUM+(Y-HALF)*LOG(Y) + RES=EXP(SUM) + ELSE + RES=XINF + GOTO 900 + ENDIF + ENDIF +!---------------------------------------------------------------------- +! FINAL ADJUSTMENTS AND RETURN +!---------------------------------------------------------------------- + IF(PARITY)RES=-RES + IF(FACT.NE.ONE)RES=FACT/RES + 900 GAMMA=RES +!D900 DGAMMA = RES + RETURN +! ---------- LAST LINE OF GAMMA ---------- + END function gamma + + + +#ifdef GFDL_COMPATIBLE_MICROP +!######################################################################## + function polysvp (T,type) +! Compute saturation vapor pressure by using +! function from Goff and Gatch (1946) + +! Polysvp returned in units of pa. +! T is input in units of K. +! type refers to saturation with respect to liquid (0) or ice (1) + + real(r8) dum + + real(r8) T,polysvp + + integer type + +! ice + + if (type.eq.1) then + +! Goff Gatch equation (good down to -100 C) + + polysvp = 10._r8**(-9.09718_r8*(273.16_r8/t-1._r8)-3.56654_r8* & + log10(273.16_r8/t)+0.876793_r8*(1._r8-t/273.16_r8)+ & + log10(6.1071_r8))*100._r8 + + end if + +! Goff Gatch equation, uncertain below -70 C + + if (type.eq.0) then + polysvp = 10._r8**(-7.90298_r8*(373.16_r8/t-1._r8)+ & + 5.02808_r8*log10(373.16_r8/t)- & + 1.3816e-7_r8*(10._r8**(11.344_r8*(1._r8-t/373.16_r8))-1._r8)+ & + 8.1328e-3_r8*(10._r8**(-3.49149_r8*(373.16_r8/t-1._r8))-1._r8)+ & + log10(1013.246_r8))*100._r8 + end if + + + end function polysvp +!######################################################################### + + +!######################################################################### +subroutine vqsatd_water(t ,p ,es ,qs ,gam , & + len ) + +!------------------------------Arguments-------------------------------- +! +! Input arguments +! + integer, intent(in) :: len ! vector length + real(r8), intent(in) :: t(len) ! temperature + real(r8), intent(in) :: p(len) ! pressure + +! +! Output arguments +! + real(r8), intent(out) :: es(len) ! saturation vapor pressure + real(r8), intent(out) :: qs(len) ! saturation specific humidity + real(r8), intent(out) :: gam(len) ! (l/cp)*(d(qs)/dt) +! +!--------------------------Local Variables------------------------------ +! + integer i ! index for vector calculations +! + real(r8) omeps ! 1. - 0.622 + real(r8) hltalt ! appropriately modified hlat for T derivatives +! + real(r8) hlatsb ! hlat weighted in transition region + real(r8) hlatvp ! hlat modified for t changes above freezing + real(r8) desdt ! d(es)/dT +! +!----------------------------------------------------------------------- +! + omeps = 1.0_r8 - epsqs + do i=1,len + es(i) = polysvp(t(i),0) +! +! Saturation specific humidity +! + qs(i) = epsqs*es(i)/(p(i) - omeps*es(i)) +! +! The following check is to avoid the generation of negative +! values that can occur in the upper stratosphere and mesosphere +! + qs(i) = min(1.0_r8,qs(i)) +! + if (qs(i) < 0.0_r8) then + qs(i) = 1.0_r8 + es(i) = p(i) + end if + end do +! +! No icephs or water to ice transition +! + do i=1,len +! +! Account for change of hlatv with t above freezing where +! constant slope is given by -2369 j/(kg c) = cpv - cw +! + hlatvp = hlv - 2369.0_r8*(t(i)-tmelt) + hlatsb = hlv + if (t(i) < tmelt) then + hltalt = hlatsb + else + hltalt = hlatvp + end if + desdt = hltalt*es(i)/(rvgas*t(i)*t(i)) + gam(i) = hltalt*qs(i)*p(i)*desdt/(cpp*es(i)*(p(i) - omeps*es(i))) + if (qs(i) == 1.0_r8) gam(i) = 0.0_r8 + end do +! + return +end subroutine vqsatd_water + +!######################################################################### +end module cldwat2m_micro_mod + +#else + +end module cldwat2m_micro + +#endif diff --git a/src/atmos_param/strat_cloud/gamma_mg.F90 b/src/atmos_param/strat_cloud/gamma_mg.F90 index 4c0fffa049..f011c1f866 100644 --- a/src/atmos_param/strat_cloud/gamma_mg.F90 +++ b/src/atmos_param/strat_cloud/gamma_mg.F90 @@ -12,8 +12,8 @@ MODULE gamma_mg_mod !----------------------------------------------------------------------- !-------version number------------------------------------------------- -Character(len=128) :: Version = '$Id: gamma_mg.F90,v 19.0 2012/01/06 20:26:11 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: gamma_mg.F90,v 20.0 2013/12/13 23:21:53 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_param/strat_cloud/mg_const.F90 b/src/atmos_param/strat_cloud/mg_const.F90 index 9e8ca614cb..d6395efc06 100644 --- a/src/atmos_param/strat_cloud/mg_const.F90 +++ b/src/atmos_param/strat_cloud/mg_const.F90 @@ -14,8 +14,8 @@ MODULE mg_const_mod !------------------------------------------------------------------------ ! DECLARE VERSION NUMBER !------------------------------------------------------------------------ -Character(len=128) :: Version = '$Id: mg_const.F90,v 19.0 2012/01/06 20:26:12 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: mg_const.F90,v 20.0 2013/12/13 23:21:55 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------- !---module variables------------------------------------------------------ @@ -42,9 +42,6 @@ MODULE mg_const_mod -! 1 / relative variance of sub-grid cloud water distribution -! see morrison and gettelman, 2007, J. Climate for details -REAL(kind=mg_pr), PUBLIC, PARAMETER :: qcvar = 1._mg_pr logical :: module_is_initialized = .false. diff --git a/src/atmos_param/strat_cloud/microphysics.F90 b/src/atmos_param/strat_cloud/microphysics.F90 index cdb69208db..cf023aab59 100644 --- a/src/atmos_param/strat_cloud/microphysics.F90 +++ b/src/atmos_param/strat_cloud/microphysics.F90 @@ -1,7 +1,10 @@ module microphysics_mod use fms_mod, only : FATAL, error_mesg, & - write_version_number + write_version_number, & + mpp_pe +use constants_mod, only : cp_air, hlv, hls, tfreeze, & + rdgas, grav, rvgas use rotstayn_klein_mp_mod, only : rotstayn_klein_microp, & rotstayn_klein_microp_init, & rotstayn_klein_microp_end @@ -15,6 +18,8 @@ module microphysics_mod strat_constants_type, & cloud_processes_type, & precip_state_type +use cldwat2m_micro_mod, only : ini_micro, mmicro_pcond, & + mmicro_end implicit none private @@ -29,15 +34,13 @@ module microphysics_mod !------------------------------------------------------------------------ !---version number------------------------------------------------------- -character(len=128) :: version = '$Id: microphysics.F90,v 19.0 2012/01/06 20:26:13 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: microphysics.F90,v 20.0 2013/12/13 23:21:57 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. - - CONTAINS @@ -61,7 +64,8 @@ subroutine microphysics_init (Nml) !------------------------------------------------------------------------- call strat_cloud_utilities_init call rotstayn_klein_microp_init - call morrison_gettelman_microp_init (Nml%do_pdf_clouds) + call morrison_gettelman_microp_init (Nml%do_pdf_clouds, Nml%qcvar) + call ini_micro (Nml%qcvar) module_is_initialized = .true. @@ -97,7 +101,7 @@ subroutine microphysics & qa_upd_0, SA_0 real, dimension(idim,jdim,kdim,0:n_diag_4d), & intent(inout) :: diag_4d -real, dimension(idim,jdim,kdim+1,0:n_diag_4d), & +real, dimension(idim,jdim,kdim+1,0:n_diag_4d_kp1), & intent(inout) :: diag_4d_kp1 type(diag_id_type), intent(in) :: diag_id type(diag_pt_type), intent(inout) :: diag_pt @@ -105,7 +109,19 @@ subroutine microphysics & !------------------------------------------------------------------------ !---local variables------------------------------------------------------ - integer :: i,j,k + real, dimension(idim,jdim,kdim,4) :: rbar_dust_4bin, ndust_4bin + real, dimension(idim,jdim,kdim) :: ST_micro, SQ_micro, SL_micro, & + SI_micro, SN_micro, SNI_micro + real, dimension(idim,jdim,kdim) :: D_eros_l, D_eros_i, & + nerosc, nerosi, & + dqcdt, dqidt, & + qa_new, & + ssat_disposal, & + ql_new, qi_new, & + nctend, nitend, qn_new, qni_new + real, dimension(idim,jdim,kdim) :: rho, liqcldf, icecldf, tmp2s + real, dimension(idim,jdim) :: m1, m2, scalef + integer :: i,j,k !------------------------------------------------------------------------ @@ -131,7 +147,7 @@ subroutine microphysics & Cloud_processes%D_eros, Cloud_processes%dcond_ls, & Cloud_processes% dcond_ls_ice, & Cloud_processes%qvg, Atmos_state%gamma, & - Cloud_processes%tmp5, Particles%drop1, & + Cloud_processes%delta_cf, Particles%drop1, & Particles%concen_dust_sub, Cloud_state%ql_upd, & Cloud_state%qi_upd, Cloud_state%qn_upd, & Cloud_state%qi_mean, Cloud_state%qa_upd, & @@ -144,11 +160,11 @@ subroutine microphysics & Precip_state%snow3d, Precip_state%snowclr3d, & Precip_state%surfrain, Precip_state%surfsnow, & Cloud_processes%f_snow_berg, otun) - else if (Constants%do_mg_microphys) then + else !if (Constants%do_rk_microphys ) !-------------------------------------------------------------------------- -! for morrison-gettelman, some additional fields are needed. for droplet -! activation Yi's drop1 is used. +! for morrison-gettelman and NCAR, some additional fields are needed. +! for droplet activation Yi's drop1 is used. !-------------------------------------------------------------------------- do k=1,kdim do j=1,jdim @@ -162,53 +178,113 @@ subroutine microphysics & ST_out(i,j,k) Atmos_state%qvn(i,j,k) = Atmos_state%qv_in(i,j,k) + & SQ_out(i,j,k) + if (Constants%tiedtke_macrophysics) then + D_eros_i(i,j,k) = -Cloud_state%qi_upd(i,j,k)* & + Cloud_processes%D_eros(i,j,k)/ & + Constants%dtcloud + D_eros_l(i,j,k) = -Cloud_state%ql_upd(i,j,k)* & + Cloud_processes%D_eros(i,j,k)/ & + Constants%dtcloud + if (Cloud_state%ql_upd(i,j,k) >= Nml%qmin) then + nerosc(i,j,k) = D_eros_l(i,j,k)/ & + Cloud_state%ql_upd(i,j,k)* & + Cloud_state%qn_upd(i,j,k)/MAX(0.0001, & + Cloud_state%qa_upd(i,j,k)) + else + nerosc(i,j,k) = 0. + endif + if (Cloud_state%qi_upd(i,j,k) >= Nml%qmin) then + nerosi(i,j,k) = D_eros_i(i,j,k)/ & + Cloud_state%qi_upd(i,j,k)* & + Cloud_state%qni_upd(i,j,k)/MAX(0.0001, & + Cloud_state%qa_upd(i,j,k)) + else + nerosi(i,j,k) = 0. + endif + if (Cloud_processes%dcond_ls_tot(i,j,k) > 0.) then + if (Atmos_state%tn(i,j,k) <= (tfreeze - 40.) ) then + dqcdt (i,j,k) = 0. + dqidt(i,j,k) = Cloud_processes%dcond_ls_tot(i,j,k)* & + Constants%inv_dtcloud + else + dqidt (i,j,k) = 0. + dqcdt(i,j,k) = Cloud_processes%dcond_ls_tot(i,j,k)* & + Constants%inv_dtcloud + endif + else + if (Atmos_state%tn(i,j,k) <= tfreeze) then + dqcdt(i,j,k) = MAX(Cloud_processes%dcond_ls_tot(i,j,k),& + -Cloud_state%ql_upd(i,j,k)) + dqidt(i,j,k) = MAX(Cloud_processes%dcond_ls_tot(i,j,k) & + - dqcdt(i,j,k), -Cloud_state%qi_upd(i,j,k)) + dqcdt(i,j,k) = dqcdt(i,j,k)* Constants%inv_dtcloud + dqidt(i,j,k) = dqidt(i,j,k)* Constants%inv_dtcloud + else + dqidt(i,j,k) = 0. + dqcdt(i,j,k) = MAX(Cloud_processes%dcond_ls_tot(i,j,k),& + -Cloud_state%ql_upd(i,j,k))* & + Constants%inv_dtcloud + endif + endif + else + dqidt(i,j,k) = 0. + dqcdt(i,j,k) = 0. + nerosi(i,j,k) = 0. + nerosc(i,j,k) = 0. + D_eros_l(i,j,k) = 0. + D_eros_i(i,j,k) = 0. + endif end do end do end do - do j=1,jdim + if (Constants%do_mg_microphys) then + + do j=1,jdim !------------------------------------------------------------------------ ! if debugging is activated, output the temp tendency prior to ! microphysics. !------------------------------------------------------------------------ - if (debugo) then - if ( j .eq. jsamp) then - write(otun, *) " ST samp bef mg ", ST_out(isamp,jsamp,ksamp) - end if - endif - + if (debugo) then + if ( j .eq. jsamp) then + write(otun, *) " ST samp bef mg ", ST_out(isamp,jsamp,ksamp) + end if + endif !------------------------------------------------------------------------- ! call morrison-gettelman microphysics package. !------------------------------------------------------------------------- - call morrison_gettelman_microp( & + call morrison_gettelman_microp( & + Constants%tiedtke_macrophysics, & + Constants%total_activation, Constants%dqa_activation, & ncall, j ,idim, jdim, kdim, Nml, & Constants%dtcloud, Atmos_state%pfull(:,j,:), & - Atmos_state%delp(:,j,:), Atmos_state%zhalf(:,j,:),& + Atmos_state%delp(:,j,:), & Atmos_state%tn(:,j,:), Atmos_state%T_in(:,j,:), & Atmos_state%qvn(:,j,:), Atmos_state%qv_in(:,j,:), & Cloud_state%ql_upd(:,j,:), Cloud_state%qi_upd(:,j,:), & Cloud_state%qn_upd(:,j,:), Cloud_state%qni_upd(:,j,:), & - Cloud_state%qa_upd(:,j,:), Atmos_state%ahuco(:,j,:), & - Constants%limit_conv_cloud_frac, & - Cloud_processes%dcond_ls_tot(:,j,:), & + Cloud_state%qa_upd(:,j,:), & + dqcdt(:,j,:), dqidt(:,j,:), & Particles%drop2(:,j,:), Particles%crystal1(:,j,:), & Particles%rbar_dust(:,j,:), Particles%ndust(:,j,:), & - Cloud_processes%tmp5(:,j,:), Cloud_state%qa_upd(:,j,:), & - qa_upd_0(:,j,:), SA_0(:,j,:), & - Cloud_processes%D_eros(:,j,:), Atmos_state%gamma(:,j,:), & - Constants%inv_dtcloud, Cloud_state%ql_in(:,j,:), & - Cloud_state%qi_in(:,j,:), Cloud_state%qa_in(:,j,:), & - Cloud_state%qn_in(:,j,:), Cloud_state%qni_in(:,j,:),& - Atmos_state%rh_crit(:,j,:), ST_out(:,j,:), SQ_out(:,j,:),& - Cloud_state%SL_out(:,j,:), Cloud_state%SI_out(:,j,:), & - Cloud_state%SN_out(:,j,:), Cloud_state%SNI_out(:,j,:),& - Cloud_state%SA_out(:,j,:), Precip_state%rain3d, & - Precip_state%snow3d, Precip_state%surfrain, & - Precip_state%surfsnow, Precip_state%qrout3d_mg(:,j,:), & - Precip_state%qsout3d_mg(:,j,:), Precip_state%lsc_snow, & - Precip_state%lsc_rain, Precip_state%lsc_snow_size, & - Precip_state%lsc_rain_size, & + Cloud_processes%delta_cf(:,j,:), & + Cloud_state%qa_upd(:,j,:), & + qa_upd_0(:,j,:), SA_0(:,j,:), D_eros_l(:,j,:), & + nerosc(:,j,:), D_eros_i(:,j,:), nerosi(:,j,:), & + Atmos_state%gamma(:,j,:), & + Constants%inv_dtcloud, Cloud_state%qa_in(:,j,:), & + ST_out(:,j,:), SQ_out(:,j,:), ssat_disposal(:,j,:), & + ST_micro(:,j,:), SQ_micro(:,j,:),& + SL_micro(:,j,:), SI_micro(:,j,:), & + SN_micro(:,j,:), SNI_micro(:,j,:),& + Cloud_state%SA_out(:,j,:), & + Precip_state%rain3d, Precip_state%snow3d, & + Precip_state%surfrain(:,j), Precip_state%surfsnow(:,j), & + Precip_state%lsc_rain(:,j,:), & + Precip_state%lsc_snow(:,j,:), & + Precip_state%lsc_rain_size(:,j,:), & + Precip_state%lsc_snow_size(:,j,:), & Cloud_processes%f_snow_berg(:,j,:), & n_diag_4d, diag_4d, diag_id, & diag_pt, nrefuse, debugo0, debugo1, otun) @@ -216,21 +292,378 @@ subroutine microphysics & !------------------------------------------------------------------------ ! if debugging is activated, output the temp tendency after microphysics. !------------------------------------------------------------------------ - IF (debugo) THEN - if ( j .eq. jsamp) then - write(otun, *) " ST samp aft mg ", ST_out(isamp,jsamp,ksamp) - end if - END IF - end do + IF (debugo) THEN + if ( j .eq. jsamp) then + write(otun, *) " ST samp aft mg ", ST_out(isamp,jsamp,ksamp) + end if + END IF + end do ! j loop + + else if (Constants%do_mg_ncar_microphys) then !(do_mg_microphys) +!------------------------------------------------------------------------- +! use ncar maintained version of microphysics +!------------------------------------------------------------------------- +! are these the actual bin centers, or arbitrary values ?? + rbar_dust_4bin(:,:,:,1) = 5.0e-6 + rbar_dust_4bin(:,:,:,2) = 10.0e-6 + rbar_dust_4bin(:,:,:,3) = 15.0e-6 + rbar_dust_4bin(:,:,:,4) = 20.0e-6 + ndust_4bin = 0.0 +! ndust_4bin(:,j,:,1) = 0.25*Particles%ndust(:,j,:) +! ndust_4bin(:,j,:,2) = 0.25*Particles%ndust(:,j,:) +! ndust_4bin(:,j,:,3) = 0.25*Particles%ndust(:,j,:) +! ndust_4bin(:,j,:,4) = 0.25*Particles%ndust(:,j,:) + + + +!------------------------------------------------------------------------- +! call microphysics package as maintained at NCAR. +!------------------------------------------------------------------------- + do k=1,kdim + do j=1,jdim + do i=1,idim + rho(i,j,k) = Atmos_state%pfull(i,j,k)/ & + (rdgas*Atmos_state%tn(i,j,k)) + liqcldf(i,j,k) = Cloud_state%qa_upd(i,j,k) + icecldf(i,j,k) = Cloud_state%qa_upd(i,j,k) + end do + end do + end do + + do j=1,jdim + call mmicro_pcond( & + Constants%dqa_activation, & + Constants%total_activation, & + Constants%tiedtke_macrophysics, & + .false., j ,jdim, kdim, idim, idim, & + Constants%dtcloud, & + Atmos_state%tn(:,j,:), & + Atmos_state%qvn(:,j,:), & + Cloud_state%ql_upd(:,j,:), Cloud_state%qi_upd(:,j,:), & + Cloud_state%qn_upd(:,j,:), Cloud_state%qni_upd(:,j,:), & + Atmos_state%pfull(:,j,:), & + Atmos_state%delp(:,j,:), & + Cloud_state%qa_upd(:,j,:), & + liqcldf(:,j,:) , icecldf(:,j,:), & + Cloud_processes%delta_cf(:,j,:), & + D_eros_l(:,j,:), nerosc(:,j,:), & + D_eros_i(:,j,:), nerosi(:,j,:), & + dqcdt(:,j,:), dqidt(:,j,:), & + Particles%crystal1(:,j,:)/rho(:,j,:), & + Particles%drop2(:,j,:), & + rbar_dust_4bin(:,j,:,:), ndust_4bin(:,j,:,:), & + ST_micro(:,j,:), SQ_micro(:,j,:), SL_micro(:,j,:), & + SI_micro(:,j,:), SN_micro(:,j,:), SNI_micro(:,j,:), & + Precip_state%surfrain(:,j), & + Precip_state%surfsnow(:,j), & + Precip_state%rain3d(:,j,:), & + Precip_state%snow3d(:,j,:), & + Precip_state%lsc_rain(:,j,:), & + Precip_state%lsc_snow(:,j,:), & + Precip_state%lsc_rain_size(:,j,:), & + Precip_state%lsc_snow_size(:,j,:), & + Cloud_processes%f_snow_berg(:,j,:), & + + Nml, Cloud_state%qa_in(:,j,:), Atmos_state%gamma(:,j,:),& + SA_0(:,j,:), Cloud_state%SA_out(:,j,:), & + + ssat_disposal (:,j,:), & + n_diag_4d, diag_4d, diag_id, & + diag_pt) + end do + !------------------------------------------------------------------------- ! exit with error if no valid microphysics scheme was specified. !------------------------------------------------------------------------- - else - call error_mesg ('strat_cloud/microphysics', & - 'invalid strat_cloud_nml microphys_scheme option', FATAL) - endif + else + call error_mesg ('strat_cloud/microphysics', & + 'invalid strat_cloud_nml microphys_scheme option', FATAL) + endif + +!------ POST MICROPHYSICS ROUTINE CALL + + + if (Nml%mass_cons) then + do j=1,jdim + do i=1,idim + m1(i,j) = 0. + do k=1,kdim + + m1(i,j) = m1(i,j) + & + (SQ_micro(i,j,k) + SL_micro(i,j,k) + SI_micro(i,j,k))* & + Constants%dtcloud*Atmos_state%delp(i,j,k)/grav + end do + m2(i,j) = 1.e3*Precip_state%surfrain(i,j)*Constants%dtcloud + if (m2(i,j) .NE. 0.0) THEN + scalef(i,j) = -m1(i,j)/m2(i,j) + + IF ( diag_id%rain_mass_conv > 0 ) & + diag_4d(i,j,1,diag_pt%rain_mass_conv) = & + (scalef(i,j)*Precip_state%surfrain(i,j) - & + Precip_state%surfrain(i,j))/Constants%dtcloud + IF ( diag_id%snow_mass_conv > 0 ) & + diag_4d(i,j,1,diag_pt%snow_mass_conv) = & + (scalef(i,j)*Precip_state%surfsnow(i,j) - & + Precip_state%surfsnow(i,j))/Constants%dtcloud + + Precip_state%surfrain(i,j) = & + scalef(i,j)*Precip_state%surfrain(i,j) + Precip_state%surfsnow(i,j) = & + scalef(i,j)*Precip_state%surfsnow(i,j) + end if + end do + end do + end if + + if (diag_id%neg_rain > 0) & + diag_4d(:,:,1,diag_pt%neg_rain) = 1.0e3* & + (Precip_state%surfrain(:,:) - Precip_state%surfsnow(:,:))* & + Constants%dtcloud + if (diag_id%neg_snow > 0) & + diag_4d(:,:,1,diag_pt%neg_snow) = 1.0e3* & + (Precip_state%surfsnow(:,:))*Constants%dtcloud + + Precip_state%surfrain = max( & + 1.e3*(Precip_state%surfrain - Precip_state%surfsnow)* & + Constants%dtcloud , 0.0) + Precip_state%surfsnow = max( & + 1.e3*Precip_state%surfsnow*Constants%dtcloud, 0.0) + + if (diag_id%neg_rain > 0) & + diag_4d(:,:,1,diag_pt%neg_rain) = & + -1.0*( (Precip_state%surfrain(:,:)) - & + diag_4d(:,:,1,diag_pt%neg_rain))/ & + (Constants%dtcloud) + if (diag_id%neg_snow > 0) & + diag_4d(:,:,1,diag_pt%neg_snow) = & + -1.0*( (Precip_state%surfsnow(:,:)) - & + diag_4d(:,:,1,diag_pt%neg_snow))/ & + (Constants%dtcloud) + + ST_out = ST_out + ST_micro/cp_air*Constants%dtcloud + SQ_out = SQ_out + SQ_micro*Constants%dtcloud + Cloud_state%SL_out = Cloud_state%SL_out + & + SL_micro*Constants%dtcloud + Cloud_state%SI_out = Cloud_state%SI_out + & + SI_micro*Constants%dtcloud + Cloud_state%SN_out = Cloud_state%SN_out + & + SN_micro*Constants%dtcloud + Cloud_state%SNI_out = Cloud_state%SNI_out + & + SNI_micro*Constants%dtcloud + +!next time: Get rid of nctend nitend. simply update SN_out within the +! loops below where nitend is updated. + nctend = 0. + nitend = 0. + + +! tiedtke macrophysics --> cloud area adjustment required due to removing supersaturation + if (Constants%tiedtke_macrophysics .and. & + .not. Nml%do_pdf_clouds) then + do k=1,kdim + do j=1,jdim + do i=1,idim + rho(i,j,k) = Atmos_state%pfull(i,j,k)/ & + (rdgas*Atmos_state%tn(i,j,k)) + if (Constants%limit_conv_cloud_frac) then + tmp2s(i,j,k) = Atmos_state%ahuco(i,j,k) + else + tmp2s(i,j,k) = 0. + endif + if (ssat_disposal(i,j,k) == 2.) then +! ming_activation --> additional aerosol activation proportional to change +! in cloud area due to supersaturation removal + nitend(i,j,k) = Particles%crystal1(i,j,k)/rho(i,j,k)* & + (1. - Cloud_state%qa_upd(i,j,k) - & + tmp2s(i,j,k))/Constants%dtcloud + if (diag_id%qnidt_super + diag_id%qni_super_col > 0 ) & + diag_4d(i,j,k,diag_pt%qnidt_super ) = & + Particles%crystal1(i,j,k)/rho(i,j,k)* & + (1. - Cloud_state%qa_upd(i,j,k) - tmp2s(i,j,k))/ & + Constants%dtcloud + else if (ssat_disposal(i,j,k) == 1.) then + nctend(i,j,k) = Particles%drop2(i,j,k)* & + (1. - Cloud_state%qa_upd(i,j,k) - & + tmp2s(i,j,k))/Constants%dtcloud + if (diag_id%qndt_super + diag_id%qn_super_col > 0 ) & + diag_4d(i,j,k,diag_pt%qndt_super ) = & + Particles%drop2(i,j,k)* & + (1. - Cloud_state%qa_upd(i,j,k) - tmp2s(i,j,k))/ & + Constants%dtcloud + endif + if (ssat_disposal(i,j,k) > 0.0) then + if (max(diag_id%qadt_super,diag_id%qa_super_col) > 0) then + diag_4d(i,j,k,diag_pt%qadt_super ) = & + (1. - Cloud_state%qa_upd(i,j,k) - tmp2s(i,j,k))* & + Constants%inv_dtcloud + end if + Cloud_state%SA_out(i,j,k) = Cloud_state%SA_out(i,j,k) + & + (1. - Cloud_state%qa_upd(i,j,k) - tmp2s(i,j,k)) + Cloud_state%qa_upd(i,j,k) = 1. - tmp2s(i,j,k) + endif + end do + end do + end do + end if + + Cloud_state%SN_out = Cloud_state%SN_out + nctend*Constants%dtcloud + Cloud_state%SNI_out = Cloud_state%SNI_out + nitend*Constants%dtcloud + +!----------------------------------------------------------------------- +! Cloud Destruction +!----------------------------------------------------------------------- + ql_new = Cloud_state%ql_in + Cloud_state%SL_out + qi_new = Cloud_state%qi_in + Cloud_state%SI_out + qn_new = Cloud_state%qn_in + Cloud_state%SN_out + qni_new = Cloud_state%qni_in + Cloud_state%SNi_out + do k=1,kdim + do j=1,jdim + do i=1,idim + if ((ql_new(i,j,k) <= NMl%qmin .and. & + qi_new(i,j,k) <= Nml%qmin) .or. & + (Cloud_state%qa_upd(i,j,k) <= Nml%qmin)) then + Cloud_state%SL_out(i,j,k) = Cloud_state%SL_out(i,j,k) - & + ql_new(i,j,k) + Cloud_state%SI_out(i,j,k) = Cloud_state%SI_out(i,j,k) - & + qi_new(i,j,k) + Cloud_state%SA_out(i,j,k) = Cloud_state%SA_out(i,j,k) - & + Cloud_state%qa_upd(i,j,k) + ST_out(i,j,k) = ST_out(i,j,k) - & + (hlv*ql_new(i,j,k) + hls*qi_new(i,j,k))/cp_air + SQ_out(i,j,k) = SQ_out(i,j,k) + & + (ql_new(i,j,k) + qi_new(i,j,k)) + Cloud_state%SN_out(i,j,k) = Cloud_state%SN_out(i,j,k) - & + qn_new(i,j,k) + Cloud_state%SNi_out(i,j,k) = Cloud_state%SNi_out(i,j,k) - & + qni_new(i,j,k) + if (diag_id%qldt_destr > 0 .or. diag_id%ql_destr_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_destr) = & + - ql_new(i,j,k)/Constants%dtcloud + if (diag_id%qidt_destr > 0 .or. diag_id%qi_destr_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_destr) = & + - qi_new(i,j,k)/Constants%dtcloud + if (diag_id%qadt_destr > 0 .or. diag_id%qa_destr_col > 0) & + diag_4d(i,j,k,diag_pt%qadt_destr) = & + - Cloud_state%qa_upd(i,j,k)/Constants%dtcloud + if (diag_id%qndt_destr > 0 .or. diag_id%qn_destr_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_destr) = & + - qn_new(i,j,k)/Constants%dtcloud + if (diag_id%qnidt_destr + diag_id%qni_destr_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_destr) = & + - qni_new(i,j,k)/Constants%dtcloud + if (diag_id%qdt_destr + diag_id%q_destr_col > 0) & + diag_4d(i,j,k,diag_pt%qdt_destr) = & + (ql_new(i,j,k) + qi_new(i,j,k))/Constants%dtcloud + endif + end do + end do + end do + + ql_new = Cloud_state%ql_in + Cloud_state%SL_out + qi_new = Cloud_state%qi_in + Cloud_state%SI_out + qn_new = Cloud_state%qn_in + Cloud_state%SN_out + qni_new = Cloud_state%qni_in + Cloud_state%SNI_out + do k=1,kdim + do j=1,jdim + do i=1,idim + if (abs(ql_new(i,j,k)) .le. Nml%qmin .and. & + Atmos_state%qv_in(i,j,k) + SQ_out(i,j,k) + & + ql_new(i,j,k) > 0.0) then + Cloud_state%SL_out(i,j,k) = - Cloud_state%ql_in(i,j,k) + SQ_out(i,j,k) = SQ_out(i,j,k) + ql_new(i,j,k) + ST_out(i,j,k) = ST_out(i,j,k) - (hlv*ql_new(i,j,k))/cp_air + if (diag_id%qdt_cleanup_liquid + & + diag_id%q_cleanup_liquid_col > 0) & + diag_4d(i,j,k,diag_pt%qdt_cleanup_liquid) = & + ql_new(i,j,k)/Constants%dtcloud + Cloud_state%SN_out(i,j,k) = Cloud_state%SN_out(i,j,k) - & + qn_new(i,j,k) + if (diag_id%qndt_cleanup + diag_id%qn_cleanup_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_cleanup) = - qn_new(i,j,k)/ & + Constants%dtcloud + endif + end do + end do + end do + + do k=1,kdim + do j=1,jdim + do i=1,idim + if (abs(qi_new(i,j,k)) .le. Nml%qmin .and. & + Atmos_state%qv_in(i,j,k) + SQ_out(i,j,k) + & + qi_new(i,j,k) > 0.0) then + Cloud_state%SI_out(i,j,k) = - Cloud_state%qi_in(i,j,k) + SQ_out(i,j,k) = SQ_out(i,j,k) + qi_new(i,j,k) + ST_out(i,j,k) = ST_out(i,j,k) - (hls*qi_new(i,j,k))/cp_air + if (diag_id%qdt_cleanup_ice + & + diag_id%q_cleanup_ice_col > 0) & + diag_4d(i,j,k,diag_pt%qdt_cleanup_ice) = & + qi_new(i,j,k)/Constants%dtcloud + Cloud_state%SNI_out(i,j,k) = Cloud_state%SNI_out(i,j,k) - & + qni_new(i,j,k) + if (diag_id%qnidt_cleanup + diag_id%qni_cleanup_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_cleanup) = & + - qni_new(i,j,k)/Constants%dtcloud + endif + end do + end do + end do + + do k=1,kdim + do j=1,jdim + do i=1,idim + if (diag_id%qnidt_cleanup2 + diag_id%qni_cleanup2_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_cleanup2) = & + Cloud_state%SNi_out(i,j,k) + Cloud_state%SNi_out(i,j,k) = MAX(Cloud_state%SNi_out(i,j,k), & + - Cloud_state%qni_in(i,j,k)) + if (diag_id%qnidt_cleanup2 + diag_id%qni_cleanup2_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_cleanup2) = & + (diag_4d(i,j,k,diag_pt%qnidt_cleanup2) - & + Cloud_state%SNi_out(i,j,k))*Constants%inv_dtcloud + end do + end do + end do + + do k=1,kdim + do j=1,jdim + do i=1,idim + if (diag_id%qndt_cleanup2 + diag_id%qn_cleanup2_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_cleanup2) = & + Cloud_state%SN_out(i,j,k) + Cloud_state%SN_out(i,j,k) = MAX(Cloud_state%SN_out(i,j,k), & + - Cloud_state%qn_in(i,j,k)) + if (diag_id%qndt_cleanup2 + diag_id%qn_cleanup2_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_cleanup2) = & + (diag_4d(i,j,k,diag_pt%qndt_cleanup2) - & + Cloud_state%SN_out(i,j,k))*Constants%inv_dtcloud + end do + end do + end do + + if (diag_id%qadt_destr + diag_id%qa_destr_col > 0) & + diag_4d(:,:,:,diag_pt%qadt_destr) = & + diag_4d(:,:,:,diag_pt%qadt_destr) + & + Cloud_state%SA_out*Constants%inv_dtcloud + + qa_new = Cloud_state%qa_in + Cloud_state%SA_out + where ( abs(qa_new) .le. Nml%qmin ) + Cloud_state%SA_out = -Cloud_state%qa_in + endwhere + + if (diag_id%qadt_destr + diag_id%qa_destr_col > 0) & + diag_4d(:,:,:,diag_pt%qadt_destr) = & + diag_4d(:,:,:,diag_pt%qadt_destr) - & + Cloud_state%SA_out*Constants%inv_dtcloud + + if (diag_id%qadt_limits + diag_id%qa_limits_col > 0) & + diag_4d(:,:,:,diag_pt%qadt_limits) = Cloud_state%SA_out(:,:,:) + Cloud_state%SA_out = MAX(Cloud_state%SA_out,-Cloud_state%qa_in) + Cloud_state%SA_out = MIN(Cloud_state%SA_out, & + 1. - Atmos_state%ahuco - Cloud_state%qa_in) + endif ! rotstayn !------------------------------------------------------------------------ diff --git a/src/atmos_param/strat_cloud/morrison_gettelman_microp.F90 b/src/atmos_param/strat_cloud/morrison_gettelman_microp.F90 index 318f8e4d9e..15d622e26f 100644 --- a/src/atmos_param/strat_cloud/morrison_gettelman_microp.F90 +++ b/src/atmos_param/strat_cloud/morrison_gettelman_microp.F90 @@ -16,7 +16,7 @@ MODULE morrison_gettelman_microp_mod diag_id_type, diag_pt_type, & strat_nml_type use gamma_mg_mod, only : gamma_mg, gamma_mg_init, gamma_mg_end -use mg_const_mod, only : mg_const_init, rhow, rhoi, qcvar, & +use mg_const_mod, only : mg_const_init, rhow, rhoi, & mg_pr, di_mg, ci_mg use simple_pdf_mod, only : simple_pdf, simple_pdf_init, & simple_pdf_end @@ -33,8 +33,8 @@ MODULE morrison_gettelman_microp_mod !------------------------------------------------------------------------ !--version number-------------------------------------------------------- -Character(len=128) :: Version = '$Id: morrison_gettelman_microp.F90,v 19.0 2012/01/06 20:26:14 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: morrison_gettelman_microp.F90,v 20.0 2013/12/13 23:21:59 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------ !--namelist-------------------------------------------------------------- @@ -42,7 +42,7 @@ MODULE morrison_gettelman_microp_mod logical :: do_morrison_gettelman_eros = .true. integer :: auto_conv_ice_choice = 1 real :: auto_conv_time_scale = 180._mg_pr -real :: auto_conv_m_thresh = 1.e-4 +real :: auto_conv_m_thresh = 1.e-4_mg_pr integer :: act_choice = 1 ! M+G super_act logical :: super_act = .false. ! super_act is more consistent ! with Yi's formula. @@ -58,27 +58,27 @@ MODULE morrison_gettelman_microp_mod real :: bs = 0.41_mg_pr ! b in the fallspeed relationship ! V=a*D^b for cloud ice ! (mg two moment scheme) -real :: in_cloud_limit = 5.e-3 +real :: in_cloud_limit = 5.e-3_mg_pr logical :: orig_app_test = .false. logical :: sub_cld_var = .true. logical :: do_berg_snow = .false. logical :: do_excess1 = .false. logical :: hd_sedi_sens = .false. -real :: vfact = 1.0 -real :: vfact_n = 1.0 -real :: vfact_m = 1.0 -real :: max_vt_ice = 1.2 -real :: max_vt_snow = 1.2 -real :: nucl_thresh = 208.9e3 +real :: vfact = 1.0_mg_pr +real :: vfact_n = 1.0_mg_pr +real :: vfact_m = 1.0_mg_pr +real :: max_vt_ice = 1.2_mg_pr +real :: max_vt_snow = 1.2_mg_pr +real :: nucl_thresh = 208.9e3_mg_pr integer :: no_rh_adj_opt = 0 -real :: min_diam_ice = 10.e-6 -real :: min_diam_drop = 2.e-6 -real :: max_diam_drop = 50.e-6 +real :: min_diam_ice = 10.e-6_mg_pr +real :: min_diam_drop = 2.e-6_mg_pr +real :: max_diam_drop = 50.e-6_mg_pr -real :: max_diam_ii = 2400.e-6 -real :: min_diam_ii = 1.e-6 +real :: max_diam_ii = 2400.e-6_mg_pr +real :: min_diam_ii = 1.e-6_mg_pr logical :: rain_evap_opt = .false. logical :: subl_snow = .false. logical :: mass_cons = .false. @@ -87,31 +87,35 @@ MODULE morrison_gettelman_microp_mod logical :: do_contact_frz = .false. integer :: n_contact_opt = 2 logical :: do_bigg_frz = .true. -real :: limit_bigg_t = 0. +real :: limit_bigg_t = 0._mg_pr logical :: limit_volri = .true. logical :: one_ice = .false. logical :: scav_by_cloud_ice = .false. -real :: tmin_fice = 233.15 ! min temperature for ice - ! deposition/bergeron process -real :: Dcs = 200.e-6 -real :: qsmall = 1.e-14 ! smallest mixing ratio considered - ! in microphysics +real :: tmin_fice = tfreeze - 40._mg_pr ! min temperature for + ! ice deposition/bergeron process +real :: Dcs = 200.e-6_mg_pr +real :: qsmall = 1.e-14_mg_pr ! smallest mixing ratio + ! considered in microphysics logical :: tiedtke_qa_test = .false. logical :: qv_on_qi = .false. integer :: sat_adj_opt = 1 -real :: autoconv_ice_thr = 100.e-6 +real :: autoconv_ice_thr = 100.e-6_mg_pr real :: Eii = 0.1_mg_pr -real :: size_hom = 25.e-6 +real :: size_hom = 25.e-6_mg_pr logical :: limit_berg = .false. logical :: do_nevap = .true. integer :: limit_droplet_freeze_opt = 1 -real :: berg_lim = 1.e-6 -real :: rhosn = 100. ! bulk density snow (from - ! Reisner et al. (1998)) +real :: berg_lim = 1.e-6_mg_pr +real :: rhosn = 100._mg_pr ! bulk density snow (from + ! Reisner et al. (1998)) logical :: mg_repartition_first = .true. logical :: meyers_test = .false. +logical :: allow_all_cldtop_collection = .false. +logical :: rho_factor_in_max_vt = .true. +real :: max_rho_factor_in_vt = 1.0 +real :: lowest_temp_for_sublimation = 180._mg_pr namelist / morrison_gettelman_microp_nml / & do_morrison_gettelman_eros, auto_conv_ice_choice, & @@ -127,13 +131,15 @@ MODULE morrison_gettelman_microp_mod eii, size_hom, limit_berg, do_nevap, berg_lim, rhosn, & do_contact_frz, n_contact_opt, do_bigg_frz, limit_bigg_t,& limit_volri, limit_droplet_freeze_opt, & - mg_repartition_first, meyers_test + mg_repartition_first, meyers_test, & + allow_all_cldtop_collection, rho_factor_in_max_vt,& +! allow_all_cldtop_collection, & + max_rho_factor_in_vt, & + lowest_temp_for_sublimation !----------------------------------------------------------------------- !-----internal parameters and constants--------------------------------- - - !----------------------------------------------------------------------- ! radius of contact nuclei aerosol (m) : REAL(kind=mg_pr), PARAMETER :: rin = 0.1e-6_mg_pr @@ -171,6 +177,10 @@ MODULE morrison_gettelman_microp_mod ! collection efficiency, accretion of cloud water by rain REAL(kind=mg_pr), PARAMETER :: Ecr = 1.0_mg_pr +!----------------------------------------------------------------------- +! radius for homogeneously frozen droplets +!REAL(kind=mg_pr), PARAMETER :: homog_frz_radius = 25.e-6 + !----------------------------------------------------------------------- ! ventilation constants for rain REAL(kind=mg_pr), PARAMETER :: f1r = 0.78_mg_pr @@ -184,7 +194,7 @@ MODULE morrison_gettelman_microp_mod !------------------------------------------------------------------------ ! ratio of h2o to dry air molecular weight -REAL(kind=mg_pr), PARAMETER :: epsqs = 0.62197 +REAL(kind=mg_pr), PARAMETER :: epsqs = 0.62197_mg_pr !----------------------------------------------------------------------- !NOTE: @@ -213,7 +223,11 @@ MODULE morrison_gettelman_microp_mod !------------------------------------------------------------------------ -logical :: module_is_initialized = .false. +logical :: module_is_initialized = .false. + +! 1 / relative variance of sub-grid cloud water distribution +! see morrison and gettelman, 2007, J. Climate for details +real :: qcvar CONTAINS @@ -222,10 +236,11 @@ MODULE morrison_gettelman_microp_mod !######################################################################### -SUBROUTINE morrison_gettelman_microp_init (do_pdf_clouds) +SUBROUTINE morrison_gettelman_microp_init (do_pdf_clouds, qcvar_in) !----------------------------------------------------------------------- LOGICAL, INTENT(IN ) :: do_pdf_clouds +Real, INTENT(IN ) :: qcvar_in !----------------------------------------------------------------------- !--local variables------------------------------------------------------ @@ -235,6 +250,8 @@ SUBROUTINE morrison_gettelman_microp_init (do_pdf_clouds) !----------------------------------------------------------------------- if (module_is_initialized) return + qcvar = qcvar_in + !----------------------------------------------------------------------- ! process namelist. !----------------------------------------------------------------------- @@ -308,103 +325,128 @@ END SUBROUTINE morrison_gettelman_microp_init !######################################################################## -SUBROUTINE morrison_gettelman_microp & - (ncall, j, idim, jdim, kdim, Nml, deltatin, pfull, & - pdel, zhalf, t_in, t0, qv_in, qv0, qc_in, qi_in, & - nc_in, ni_in, cldn_in, ahuco, limit_conv_cloud_frac, & - dcond_ls_tot, drop2, crystal1, rbar_dust, ndust, & - tmp5, qa_upd, qa_upd_0, SA_0, D_eros, gamma, & - inv_dtcloud, ql0, qi0, qa0, nc0, ni0, rh_crit, & - ST, SQ, SL, SI, SN, SNi, SA, rain3d, snow3d, & - surfrain, surfsnow, qrout, qsout, lsc_snow, & - lsc_rain, lsc_snow_size, lsc_rain_size, f_snow_berg, & - n_diag_4d, & - diag_4d, diag_id, diag_pt, nrefuse, debugo0, & - debugo1, otun) +SUBROUTINE morrison_gettelman_microp ( & + tiedtke_macrophysics, total_activation, dqa_activation, & + ncall, j, idim, jdim, kdim, Nml, deltatin, pfull, & + pdel, t_in, t0, qv_in, qv0, qc_in, qi_in, nc_in, ni_in, & + cldn_in, dqcdt, dqidt, drop2, crystal1, rbar_dust, & + ndust, delta_cf, qa_upd, qa_upd_0, SA_0, D_eros_l4, & + nerosc4, D_eros_i4, nerosi4, gamma, inv_dtcloud, qa0, & + ST, SQ, ssat_disposal, tlat, qvlat, qctend, qitend, & + nctend, nitend, SA, rain3d, snow3d, prect, preci, & + qrout, qsout, lsc_rain_size, lsc_snow_size, & + f_snow_berg, n_diag_4d, diag_4d, diag_id, diag_pt, & + nrefuse, debugo0, debugo1, otun) !------------------------------------------------------------------------ -type(strat_nml_type), intent(in) :: & - Nml -INTEGER, INTENT(IN ) :: & - ncall, j, idim, jdim, kdim -INTEGER, INTENT(INOUT) :: & - nrefuse -LOGICAL, INTENT(IN) :: & - limit_conv_cloud_frac -REAL(kind=mg_pr), INTENT(IN ) :: & - deltatin ! time step (s) -REAL(kind=mg_pr), INTENT(IN ) :: & - inv_dtcloud -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - t_in ! input temperature (K) -REAL(kind=mg_pr), DIMENSION(idim,kdim+1), INTENT(IN) :: & - zhalf -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - pfull ! air pressure (pa) -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - pdel ! pressure difference across - ! level (pa) - -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - qv_in ! input h20 vapor mixing - ! ratio (kg/kg) -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - qc_in ! cloud water mixing - ! ratio (kg/kg) -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - qi_in ! cloud ice mixing - ! ratio (kg/kg) -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - nc_in ! cloud droplet number conc - ! (1/kg) at the beginning of - ! the timestep prior to - ! activation calc. -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - qv0, T0 -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - ni_in ! cloud ice number conc (1/kg) -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - cldn_in ! cloud fraction -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - ahuco ! cumulus/anvil cloud fraction -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - D_eros -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - dcond_ls_tot -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) :: & - drop2, crystal1 -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - rbar_dust, ndust -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) :: & - tmp5 -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - ql0, qi0, qa0, nc0, ni0 -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT ) :: & - qa_upd_0, SA_0 -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) :: & - gamma, rh_crit -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) :: & - ST, SQ, SL, SI, SA, SN, SNi -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) :: & - qa_upd -real, dimension(idim, jdim, kdim+1), INTENT(INOUT) :: & - rain3d, snow3d -real, dimension(idim,jdim), INTENT(INOUT) :: & - surfrain,surfsnow -! snow and rain mass mixing ratio (kg/kg) and diameter (micrometer): -! (snow_size currently not used) -REAL, dimension(idim, jdim, kdim), INTENT(INOUT) :: & - lsc_snow, lsc_rain, lsc_snow_size, & - lsc_rain_size -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT) :: f_snow_berg -REAL(kind=mg_pr), DIMENSION(idim,kdim) :: & - dcond_ls_tem +logical, intent(in) :: tiedtke_macrophysics, & + total_activation, & + dqa_activation +INTEGER, INTENT(IN ) :: ncall, j, idim, jdim, kdim +type(strat_nml_type), intent(in) :: Nml +REAL(kind=mg_pr), INTENT(IN ) :: deltatin ! time step (s) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: pfull ! air pressure (pa) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: pdel ! pressure difference + ! across level (pa) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: t_in ! input temperature (K) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: qv_in ! input h20 vapor mixing + ! ratio (kg/kg) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: T0, qv0 +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: qc_in ! cloud water mixing + ! ratio (kg/kg) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: qi_in ! cloud ice mixing + ! ratio (kg/kg) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: nc_in ! cloud droplet number + ! conc (1/kg) at the + ! beginning of the + ! timestep prior to + ! activation calc. +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: ni_in ! cloud ice number conc + ! (1/kg) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: cldn_in + ! cloud fraction +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: dqcdt, dqidt +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) & + :: drop2, crystal1 +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: rbar_dust, ndust +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) & + :: delta_cf +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) & + :: qa_upd +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT ) & + :: qa_upd_0, SA_0 +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: D_eros_l4, D_eros_i4 +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: nerosc4, nerosi4 +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: gamma +REAL(kind=mg_pr), INTENT(IN ) & + :: inv_dtcloud +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: qa0 +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(IN) & + :: ST, SQ +REAL(kind=mg_pr), DIMENSION(idim,kdim),intent(out) & + :: ssat_disposal +REAL(kind=mg_pr), DIMENSION(idim,kdim),intent(out) & + :: tlat ! latent heating rate + ! (K/s) +REAL(kind=mg_pr), DIMENSION(idim,kdim),intent(out) & + :: qvlat ! microphysical tendency + ! qv (1/s) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT) & + :: qctend, qitend, nctend, nitend +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(INOUT) & + :: SA +! snow and rain mass mixing ratio (kg/kg) +real, dimension(idim, jdim, kdim+1), INTENT(INOUT) & + :: rain3d, snow3d +REAL(kind=mg_pr), DIMENSION(idim), intent(out) & + :: prect ! surface precip rate + ! (m/s) +REAL(kind=mg_pr), DIMENSION(idim), intent(out) & + :: preci ! cloud ice/snow precip + ! rate (m/s) ! diagnostic rain/snow for output to history ! values are in-precip (local) !!!! -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT ) :: & - qrout ! rain mixing ratio (kg/kg) -REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT ) :: & - qsout ! snow mixing ratio (kg/kg) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT ) & + :: qrout ! rain mixing ratio (kg/kg) +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT ) & + :: qsout ! snow mixing ratio (kg/kg) +! snow and rain diameter (micrometer): +! (snow_size currently not used) +REAL, dimension(idim, kdim), INTENT(INOUT) & + :: lsc_snow_size, lsc_rain_size +REAL(kind=mg_pr), DIMENSION(idim,kdim), INTENT(OUT) & + :: f_snow_berg +INTEGER, intent(in) & + :: n_diag_4d +REAL, dimension( idim, jdim, kdim, 0:n_diag_4d ), INTENT(INOUT ) & + :: diag_4d +TYPE(diag_id_type), intent(in) & + :: diag_id +TYPE(diag_pt_type), intent(inout) & + :: diag_pt +INTEGER, INTENT(INOUT) & + :: nrefuse +LOGICAL, INTENT(IN ) & + :: debugo0, debugo1 +INTEGER, INTENT(IN ) & + :: otun + !------------------------------------------------------------------------- !------------------------------------------------------------------------- @@ -417,61 +459,54 @@ SUBROUTINE morrison_gettelman_microp & !across model vertical level - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qv, qtot + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qv, qtot - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qc, qi + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qc, qi - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nc, ni + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nc, ni - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: tlat ! latent heating rate (K/s) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvlat ! microphysical tendency qv (1/s) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qctend ! microphysical tendency qc (1/s) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qitend ! microphysical tendency qi (1/s) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nctend ! microphysical tendency nc (1/(kg*s)) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nitend ! microphysical tendency ni (1/(kg*s)) ! sum of source/sink terms for diagnostic prec - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qnitend ! snow mixing ratio source/sink term - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nstend ! snow number concentration source/sink term - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qrtend ! rain mixing ratio source/sink term - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nrtend ! rain number concentration source/sink term + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qnitend ! snow mixing ratio source/sink term + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nstend ! snow number concentration source/sink term + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qrtend ! rain mixing ratio source/sink term + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nrtend ! rain number concentration source/sink term ! new terms for Bergeron process REAL(kind=mg_pr) :: dumnnuc ! provisional ice nucleation rate (for calculating bergeron) - REAL(kind=mg_pr) :: ninew ! provisional cloud ice number conc (for calculating bergeron) + REAL(kind=mg_pr) :: ninew ! provisional cloud ice number conc (for calculating bergeron) REAL(kind=mg_pr) :: qinew ! provisional cloud ice mixing ratio (for calculating bergeron) REAL(kind=mg_pr), DIMENSION(idim,kdim) :: berg ! mixing rat tendency due to bergeron process for cloud ice !cms++ - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvdep_qi ! mixing rat tendency due to vapor deposition on ice + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvdep_qi ! mixing rat tendency due to vapor deposition on ice !cms-- - REAL(kind=mg_pr), DIMENSION(idim) :: prect ! surface precip rate (m/s) - REAL(kind=mg_pr), DIMENSION(idim) :: preci ! cloud ice/snow precip rate (m/s) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: esl ! liquid sat vapor pressure (pa) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: esi ! ice sat vapor pressure (pa) + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: esl ! liquid sat vapor pressure (pa) + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: esi ! ice sat vapor pressure (pa) - REAL(kind=mg_pr), DIMENSION(kdim) :: nsubi ! evaporation of cloud ice number - REAL(kind=mg_pr), DIMENSION(kdim) :: nsubc ! evaporation of droplet number + REAL(kind=mg_pr), DIMENSION(kdim) :: nsubi ! evaporation of cloud ice number + REAL(kind=mg_pr), DIMENSION(kdim) :: nsubc ! evaporation of droplet number - REAL(kind=mg_pr), DIMENSION(kdim) :: nerosi! "erosion" of cloud ice number - REAL(kind=mg_pr), DIMENSION(kdim) :: nerosc ! "erosion" of droplet number - REAL(kind=mg_pr), DIMENSION(kdim) :: nsubs ! evaporation of snow number - REAL(kind=mg_pr), DIMENSION(kdim) :: nsubr ! evaporation of rain number + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nerosi! "erosion" of cloud ice number + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nerosc! "erosion" of cloud ice number + REAL(kind=mg_pr), DIMENSION(kdim) :: nsubs ! evaporation of snow number + REAL(kind=mg_pr), DIMENSION(kdim) :: nsubr ! evaporation of rain number - REAL(kind=mg_pr), DIMENSION(kdim) :: nnuccd ! ice nucleation rate from various freezing processes - REAL(kind=mg_pr), DIMENSION(kdim) :: npccn ! droplet activation rate + REAL(kind=mg_pr), DIMENSION(kdim) :: nnuccd ! ice nucleation rate from various freezing processes + REAL(kind=mg_pr), DIMENSION(kdim) :: mnuccd ! ice nucleation rate from various freezing processes + REAL(kind=mg_pr), DIMENSION(kdim) :: npccn ! droplet activation rate @@ -480,179 +515,183 @@ SUBROUTINE morrison_gettelman_microp & REAL(kind=mg_pr) :: qstot ! vertically-integrated snow mixing rat source/sink term REAL(kind=mg_pr) :: nstot ! vertically-integrated snow number conc source/sink term - REAL(kind=mg_pr) :: deltat ! sub-time step (s) + REAL(kind=mg_pr) :: deltat ! sub-time step (s) - REAL(kind=mg_pr) :: omsm ! number near unity for round-off issues - REAL(kind=mg_pr) :: mincld ! minimum allowed cloud fraction + REAL(kind=mg_pr) :: omsm ! number near unity for round-off issues + REAL(kind=mg_pr) :: mincld ! minimum allowed cloud fraction - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: q ! water vapor mixing ratio (kg/kg) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: t ! temperature (K) - REAL(kind=mg_pr) , DIMENSION(idim,kdim):: rho ! air density (kg m-3) + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: q ! water vapor mixing ratio (kg/kg) + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: t ! temperature (K) + REAL(kind=mg_pr) , DIMENSION(idim,kdim):: rho ! air density (kg m-3) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dv ! diffusivity of water vapor in air - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: mu ! viscocity of air - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: sc ! schmidt number - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: kap ! thermal conductivity of air - REAL(kind=mg_pr) :: dap ! effecvtive diffusivity of contact ice nuclei - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: arn ! air density corrected rain fallspeed parameter - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: asn ! air density corrected snow fallspeed parameter - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: acn ! air density corrected cloud droplet fallspeed parameter - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: ain ! air density corrected cloud ice fallspeed parameter + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dv ! diffusivity of water vapor in air + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: mu ! viscocity of air + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: sc ! schmidt number + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: kap ! thermal conductivity of air + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: rhof! air density correction factor for fallspeed + REAL(kind=mg_pr) :: dap ! effecvtive diffusivity of contact ice nuclei + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: arn ! air density corrected rain fallspeed parameter + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: asn ! air density corrected snow fallspeed parameter + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: acn ! air density corrected cloud droplet fallspeed parameter + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: ain ! air density corrected cloud ice fallspeed parameter - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qcic ! in-cloud cloud liquid mixing ratio - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qiic ! in-cloud cloud ice mixing ratio - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qniic ! in-precip snow mixing ratio - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qric ! in-precip rain mixing ratio - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: ncic ! in-cloud droplet number conc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: niic ! in-cloud cloud ice number conc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsic ! in-precip snow number conc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nric ! in-precip rain number conc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qcic ! in-cloud cloud liquid mixing ratio + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qiic ! in-cloud cloud ice mixing ratio + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qniic ! in-precip snow mixing ratio + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qric ! in-precip rain mixing ratio + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: ncic ! in-cloud droplet number conc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: niic ! in-cloud cloud ice number conc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsic ! in-precip snow number conc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nric ! in-precip rain number conc ! hm, add9/5/07, rain rate for reflectivity calculation - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: rainrt - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: rainrt1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: rainrt + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: rainrt1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: atotrt - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: atotrt1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: atotrt + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: atotrt1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: asnowrt - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: asnowrt1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: asnowrt + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: asnowrt1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cwml ! cloud water mixing ratio - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cwmi ! cloud ice mixing ratio + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cwml ! cloud water mixing ratio + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cwmi ! cloud ice mixing ratio + REAL(kind=mg_pr), DIMENSION(kdim) :: snow2vapor - REAL(kind=mg_pr) :: uni ! number-weighted cloud ice fallspeed - REAL(kind=mg_pr), DIMENSION(kdim) :: umi ! mass-weighted cloud ice fallspeed - REAL(kind=mg_pr), DIMENSION(kdim) :: uns ! number-weighted snow fallspeed - REAL(kind=mg_pr), DIMENSION(kdim) :: ums ! mass-weighted snow fallspeed - REAL(kind=mg_pr), DIMENSION(kdim) :: unr ! number-weighted rain fallspeed - REAL(kind=mg_pr), DIMENSION(kdim) :: umr ! mass-weighted rain fallspeed - REAL(kind=mg_pr) :: unc ! number-weighted cloud droplet fallspeed - REAL(kind=mg_pr) :: umc ! mass-weighted cloud droplet fallspeed + REAL(kind=mg_pr) :: uni ! number-weighted cloud ice fallspeed + REAL(kind=mg_pr), DIMENSION(kdim) :: umi ! mass-weighted cloud ice fallspeed + REAL(kind=mg_pr), DIMENSION(kdim) :: uns ! number-weighted snow fallspeed + REAL(kind=mg_pr), DIMENSION(kdim) :: ums ! mass-weighted snow fallspeed + REAL(kind=mg_pr), DIMENSION(kdim) :: unr ! number-weighted rain fallspeed + REAL(kind=mg_pr), DIMENSION(kdim) :: umr ! mass-weighted rain fallspeed + REAL(kind=mg_pr) :: unc ! number-weighted cloud droplet fallspeed + REAL(kind=mg_pr) :: umc ! mass-weighted cloud droplet fallspeed - REAL(kind=mg_pr), DIMENSION(kdim) :: pracs ! mixing rat tendency due to collection of rain by snow - REAL(kind=mg_pr), DIMENSION(kdim) :: npracs ! number conc tendency due to collection of rain by snow ! number conc tendency due to collection of rain by snow - REAL(kind=mg_pr), DIMENSION(kdim) :: mnuccr ! mixing rat tendency due to freezing of rain - REAL(kind=mg_pr), DIMENSION(kdim) :: nnuccr ! number conc tendency due to freezing of rain - REAL(kind=mg_pr), DIMENSION(kdim) :: pra ! mixing rat tendnency due to accretion of droplets by rain - REAL(kind=mg_pr), DIMENSION(kdim) :: npra ! nc tendnency due to accretion of droplets by rain - REAL(kind=mg_pr), DIMENSION(kdim) :: nragg ! nr tendency due to self-collection of rain - REAL(kind=mg_pr), DIMENSION(kdim) :: prci ! mixing rat tendency due to autoconversion of cloud ice to snow - REAL(kind=mg_pr), DIMENSION(kdim) :: nprci ! number conc tendency due to autoconversion of cloud ice to snow - REAL(kind=mg_pr), DIMENSION(kdim) :: prai ! mixing rat tendency due to accretion of cloud ice by snow - REAL(kind=mg_pr), DIMENSION(kdim) :: nprai ! number conc tendency due to accretion of cloud ice by snow - REAL(kind=mg_pr), DIMENSION(kdim) :: mnuccc ! mixing ratio tendency due to freezing of cloud water - REAL(kind=mg_pr), DIMENSION(kdim) :: nnuccc ! number conc tendency due to freezing of cloud water - REAL(kind=mg_pr), DIMENSION(kdim) :: nsagg ! ns tendency due to self-aggregation of snow + REAL(kind=mg_pr), DIMENSION(kdim) :: pracs ! mixing rat tendency due to collection of rain by snow + REAL(kind=mg_pr), DIMENSION(kdim) :: npracs ! number conc tendency due to collection of rain by snow ! number conc tendency due to collection of rain by snow + REAL(kind=mg_pr), DIMENSION(kdim) :: mnuccr ! mixing rat tendency due to freezing of rain + REAL(kind=mg_pr), DIMENSION(kdim) :: nnuccr ! number conc tendency due to freezing of rain + REAL(kind=mg_pr), DIMENSION(kdim) :: pra ! mixing rat tendnency due to accretion of droplets by rain + REAL(kind=mg_pr), DIMENSION(kdim) :: npra ! nc tendnency due to accretion of droplets by rain + REAL(kind=mg_pr), DIMENSION(kdim) :: nragg ! nr tendency due to self-collection of rain + REAL(kind=mg_pr), DIMENSION(kdim) :: prci ! mixing rat tendency due to autoconversion of cloud ice to snow + REAL(kind=mg_pr), DIMENSION(kdim) :: nprci ! number conc tendency due to autoconversion of cloud ice to snow + REAL(kind=mg_pr), DIMENSION(kdim) :: prai ! mixing rat tendency due to accretion of cloud ice by snow + REAL(kind=mg_pr), DIMENSION(kdim) :: nprai ! number conc tendency due to accretion of cloud ice by snow + REAL(kind=mg_pr), DIMENSION(kdim) :: mnuccc ! mixing ratio tendency due to freezing of cloud water + REAL(kind=mg_pr), DIMENSION(kdim) :: nnuccc ! number conc tendency due to freezing of cloud water + REAL(kind=mg_pr), DIMENSION(kdim) :: nsagg ! ns tendency due to self-aggregation of snow - REAL(kind=mg_pr), DIMENSION(kdim) :: pre ! rain mixing rat tendency due to evaporation - REAL(kind=mg_pr), DIMENSION(kdim) :: prds ! snow mixing rat tendency due to sublimation + REAL(kind=mg_pr), DIMENSION(kdim) :: pre ! rain mixing rat tendency due to evaporation + REAL(kind=mg_pr), DIMENSION(kdim) :: prds ! snow mixing rat tendency due to sublimation - REAL(kind=mg_pr), DIMENSION(kdim) ::psacws ! mixing rat tendency due to collection of droplets by snow - REAL(kind=mg_pr), DIMENSION(kdim) ::npsacws ! number conc tendency due to collection of droplets by snow + REAL(kind=mg_pr), DIMENSION(kdim) ::psacws ! mixing rat tendency due to collection of droplets by snow + REAL(kind=mg_pr), DIMENSION(kdim) ::npsacws ! number conc tendency due to collection of droplets by snow - !for the one ice class scheme: - REAL(kind=mg_pr), DIMENSION(kdim) ::psacws_o ! mixing rat tendency due to collection of droplets by snow - REAL(kind=mg_pr), DIMENSION(kdim) ::npsacws_o ! number conc tendency due to collection of droplets by snow +! for the one ice class scheme: + REAL(kind=mg_pr), DIMENSION(kdim) ::psacws_o ! mixing rat tendency due to collection of droplets by snow + REAL(kind=mg_pr), DIMENSION(kdim) ::npsacws_o ! number conc tendency due to collection of droplets by snow - REAL(kind=mg_pr), DIMENSION(kdim) :: prc ! qc tendency due to autoconversion of cloud droplets - REAL(kind=mg_pr), DIMENSION(kdim) :: nprc ! number conc tendency due to autoconversion of cloud droplets - REAL(kind=mg_pr), DIMENSION(kdim) :: nprc1 ! qr tendency due to autoconversion of cloud droplets + REAL(kind=mg_pr), DIMENSION(kdim) :: prc ! qc tendency due to autoconversion of cloud droplets + REAL(kind=mg_pr), DIMENSION(kdim) :: nprc ! number conc tendency due to autoconversion of cloud droplets + REAL(kind=mg_pr), DIMENSION(kdim) :: nprc1 ! qr tendency due to autoconversion of cloud droplets - REAL(kind=mg_pr), DIMENSION(kdim) :: bergs ! mixing rat tendency due to bergeron process for snow + REAL(kind=mg_pr), DIMENSION(kdim) :: bergs ! mixing rat tendency due to bergeron process for snow - REAL(kind=mg_pr), DIMENSION(kdim) :: lami ! slope of cloud ice size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: n0i ! intercept of cloud ice size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: lami ! slope of cloud ice size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: n0i ! intercept of cloud ice size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: lamr ! slope of rain size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: n0r ! intercept of rain size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: lamr ! slope of rain size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: n0r ! intercept of rain size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: lams ! slope of snow size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: n0s ! intercept of snow size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: lams ! slope of snow size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: n0s ! intercept of snow size distr - REAL(kind=mg_pr) :: lammax ! maximum allowed slope of size distr - REAL(kind=mg_pr) :: lammin ! minimum allowed slope of size distr + REAL(kind=mg_pr) :: lammax ! maximum allowed slope of size distr + REAL(kind=mg_pr) :: lammin ! minimum allowed slope of size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: pgam ! spectral width parameter of droplet size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: pgam ! spectral width parameter of droplet size distr - REAL(kind=mg_pr), DIMENSION(kdim) :: cdist1 ! size distr parameter to calculate droplet freezing + REAL(kind=mg_pr), DIMENSION(kdim) :: cdist1 ! size distr parameter to calculate droplet freezing - REAL(kind=mg_pr), DIMENSION(kdim) :: lamc ! slope of cloud liquid size distr + REAL(kind=mg_pr), DIMENSION(kdim) :: lamc ! slope of cloud liquid size distr - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cldmax ! precip fraction assuming maximum overlap - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cldm ! cloud fraction + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cldmax ! precip fraction assuming maximum overlap + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cldm ! cloud fraction - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: t1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: q1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qi1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: ni1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: tlat1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvlat1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qctend1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qitend1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nctend1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nitend1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: t1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: q1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qi1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: ni1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: tlat1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvlat1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qctend1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qitend1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nctend1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nitend1 - REAL(kind=mg_pr), DIMENSION(idim) :: prect1 - REAL(kind=mg_pr), DIMENSION(idim) :: preci1 + REAL(kind=mg_pr), DIMENSION(idim) :: prect1 + REAL(kind=mg_pr), DIMENSION(idim) :: preci1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cme ! total (liquid+ice) cond/evap rate of cloud - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmei ! dep/sublimation rate of cloud ice - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmel ! cond/evap rate of cloud liquid + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmei ! dep/sublimation rate of cloud ice + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmel ! cond/evap rate of cloud liquid + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmel_orig, cmei_orig, & + berg_orig - REAL(kind=mg_pr) :: qvi ! ice saturation vapor mixing ratio + REAL(kind=mg_pr) :: qvi ! ice saturation vapor mixing ratio - REAL(kind=mg_pr) :: qvqvsi ! ICE SATURAION RATIO + REAL(kind=mg_pr) :: qvqvsi ! ICE SATURAION RATIO - REAL(kind=mg_pr) :: qvl ! liquid sat mixing ratio - REAL(kind=mg_pr) :: qvs ! liquid saturation vapor mixing ratio + REAL(kind=mg_pr) :: qvl ! liquid sat mixing ratio + REAL(kind=mg_pr) :: qvs ! liquid saturation vapor mixing ratio - REAL(kind=mg_pr) :: dqsdt ! change of sat vapor mixing ratio with temperature - REAL(kind=mg_pr) :: dqsidt ! change of ice sat vapor mixing ratio with temperature + REAL(kind=mg_pr) :: dqsdt ! change of sat vapor mixing ratio with temperature + REAL(kind=mg_pr) :: dqsidt ! change of ice sat vapor mixing ratio with temperature - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: abi ! correction factor for snow sublimation to account for latent heat - REAL(kind=mg_pr) :: qclr ! water vapor mixing ratio in clear air + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: abi ! correction factor for snow sublimation to account for latent heat + REAL(kind=mg_pr) :: qclr ! water vapor mixing ratio in clear air - REAL(kind=mg_pr) :: ab ! correction factor for rain evap to account for latent heat + REAL(kind=mg_pr) :: ab ! correction factor for rain evap to account for latent heat - REAL(kind=mg_pr) :: epsi ! 1/ sat relaxation timecale for cloud ice - REAL(kind=mg_pr) :: prd ! provisional deposition rate of cloud ice at water sat - REAL(kind=mg_pr) :: epsr ! 1/ sat relaxation timescale for rain - REAL(kind=mg_pr) :: epss ! 1/ sat relaxation timescale for snow - + REAL(kind=mg_pr) :: epsi ! 1/ sat relaxation timecale for cloud ice + REAL(kind=mg_pr) :: prd ! provisional deposition rate of cloud ice at water sat + REAL(kind=mg_pr) :: epsr ! 1/ sat relaxation timescale for rain + REAL(kind=mg_pr) :: epss ! 1/ sat relaxation timescale for snow + + real(kind=mg_pr) :: bergtsf !bergeron timescale to remove all liquid - REAL(kind=mg_pr) :: esat0, gamma1, qvmax + REAL(kind=mg_pr) :: esat0, gamma1, qvmax ! hm add 3/19/07, ice nucleation, droplet activation - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dum2i ! number conc of ice nuclei available (1/kg) - REAL(kind=mg_pr) , DIMENSION(idim,kdim):: dum2l ! number conc of CCN (1/kg) - REAL(kind=mg_pr) :: ncmax - REAL(kind=mg_pr) :: nimax + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dum2i ! number conc of ice nuclei available (1/kg) + REAL(kind=mg_pr) , DIMENSION(idim,kdim):: dum2l ! number conc of CCN (1/kg) + REAL(kind=mg_pr) :: ncmax + REAL(kind=mg_pr) :: nimax @@ -660,93 +699,93 @@ SUBROUTINE morrison_gettelman_microp & ! diagnostic rain/snow for output to history ! values are in-precip (local) !!!! - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nrout ! rain number concentration (1/m3) - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsout ! snow number concentration (1/m3) + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nrout ! rain number concentration (1/m3) + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsout ! snow number concentration (1/m3) - REAL(kind=mg_pr) :: dc0 ! mean size droplet size distr - REAL(kind=mg_pr) :: ds0 ! mean size snow size distr (area weighted) - REAL(kind=mg_pr) :: eci ! collection efficiency for riming of snow by droplets + REAL(kind=mg_pr) :: dc0 ! mean size droplet size distr + REAL(kind=mg_pr) :: ds0 ! mean size snow size distr (area weighted) + REAL(kind=mg_pr) :: eci ! collection efficiency for riming of snow by droplets REAL(kind=mg_pr) :: mtime ! factor to account for droplet activation timescale ! variabels to check for RH after rain evap - REAL(kind=mg_pr) :: esn - REAL(kind=mg_pr) :: qsn - REAL(kind=mg_pr) :: qtmp - REAL(kind=mg_pr) :: ttmp, tc, rhi + REAL(kind=mg_pr) :: esn + REAL(kind=mg_pr) :: qsn + REAL(kind=mg_pr) :: qtmp + REAL(kind=mg_pr) :: ttmp, tc, rhi - REAL(kind=mg_pr) :: dum, dum1, dum2, dumd + REAL(kind=mg_pr) :: dum, dum1, dum2, dumd - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumc ! dummy in-cloud qc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumnc ! dummy in-cloud nc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumi ! dummy in-cloud qi - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumni ! dummy in-cloud ni - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dums ! dummy in-cloud snow mixing rat - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumns ! dummy in-cloud snow number conc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumr ! dummy in-cloud rain mixing rat - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumnr ! dummy in-cloud rain number conc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumc ! dummy in-cloud qc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumnc ! dummy in-cloud nc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumi ! dummy in-cloud qi + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumni ! dummy in-cloud ni + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dums ! dummy in-cloud snow mixing rat + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumns ! dummy in-cloud snow number conc + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumr ! dummy in-cloud rain mixing rat + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: dumnr ! dummy in-cloud rain number conc - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cldn ! cloud fraction + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cldn ! cloud fraction - REAL(kind=mg_pr) :: qce ! dummy qc for conservation check - REAL(kind=mg_pr) :: qie ! dummy qi for conservation check - REAL(kind=mg_pr) :: nce ! dummy nc for conservation check - REAL(kind=mg_pr) :: nie ! dummy ni for conservation check + REAL(kind=mg_pr) :: qce ! dummy qc for conservation check + REAL(kind=mg_pr) :: qie ! dummy qi for conservation check + REAL(kind=mg_pr) :: nce ! dummy nc for conservation check + REAL(kind=mg_pr) :: nie ! dummy ni for conservation check - REAL(kind=mg_pr) :: ratio ! parameter for conservation check + REAL(kind=mg_pr) :: ratio ! parameter for conservation check ! below are parameters for cloud water and cloud ice sedimentation calculations - REAL(kind=mg_pr), DIMENSION(kdim) :: fr - REAL(kind=mg_pr), DIMENSION(kdim) :: fnr - REAL(kind=mg_pr), DIMENSION(kdim) :: fc - REAL(kind=mg_pr), DIMENSION(kdim) :: fnc - REAL(kind=mg_pr), DIMENSION(kdim) :: fi - REAL(kind=mg_pr), DIMENSION(kdim) :: fni - REAL(kind=mg_pr), DIMENSION(kdim) :: fs - REAL(kind=mg_pr), DIMENSION(kdim) :: fns - REAL(kind=mg_pr), DIMENSION(kdim) :: faloutr - REAL(kind=mg_pr), DIMENSION(kdim) :: faloutnr - REAL(kind=mg_pr), DIMENSION(kdim) :: faloutc - REAL(kind=mg_pr), DIMENSION(kdim) :: faloutnc - REAL(kind=mg_pr), DIMENSION(kdim) :: falouti - REAL(kind=mg_pr), DIMENSION(kdim) :: faloutni - REAL(kind=mg_pr), DIMENSION(kdim) :: falouts - REAL(kind=mg_pr), DIMENSION(kdim) :: faloutns - REAL(kind=mg_pr) :: faltndr - REAL(kind=mg_pr) :: faltndnr - REAL(kind=mg_pr) :: faltndc - REAL(kind=mg_pr) :: faltndnc - REAL(kind=mg_pr) :: faltndi - REAL(kind=mg_pr) :: faltndni - REAL(kind=mg_pr) :: faltnds - REAL(kind=mg_pr) :: faltndns - REAL(kind=mg_pr) :: faltndqie - REAL(kind=mg_pr) :: faltndqce + REAL(kind=mg_pr), DIMENSION(kdim) :: fr + REAL(kind=mg_pr), DIMENSION(kdim) :: fnr + REAL(kind=mg_pr), DIMENSION(kdim) :: fc + REAL(kind=mg_pr), DIMENSION(kdim) :: fnc + REAL(kind=mg_pr), DIMENSION(kdim) :: fi + REAL(kind=mg_pr), DIMENSION(kdim) :: fni + REAL(kind=mg_pr), DIMENSION(kdim) :: fs + REAL(kind=mg_pr), DIMENSION(kdim) :: fns + REAL(kind=mg_pr), DIMENSION(kdim) :: faloutr + REAL(kind=mg_pr), DIMENSION(kdim) :: faloutnr + REAL(kind=mg_pr), DIMENSION(kdim) :: faloutc + REAL(kind=mg_pr), DIMENSION(kdim) :: faloutnc + REAL(kind=mg_pr), DIMENSION(kdim) :: falouti + REAL(kind=mg_pr), DIMENSION(kdim) :: faloutni + REAL(kind=mg_pr), DIMENSION(kdim) :: falouts + REAL(kind=mg_pr), DIMENSION(kdim) :: faloutns + REAL(kind=mg_pr) :: faltndr + REAL(kind=mg_pr) :: faltndnr + REAL(kind=mg_pr) :: faltndc + REAL(kind=mg_pr) :: faltndnc + REAL(kind=mg_pr) :: faltndi + REAL(kind=mg_pr) :: faltndni + REAL(kind=mg_pr) :: faltnds + REAL(kind=mg_pr) :: faltndns + REAL(kind=mg_pr) :: faltndqie + REAL(kind=mg_pr) :: faltndqce - REAL(kind=mg_pr) :: rgvm ! max fallspeed for all species + REAL(kind=mg_pr) :: rgvm ! max fallspeed for all species - REAL(kind=mg_pr) :: dumt1, dumt2 + REAL(kind=mg_pr) :: dumt1, dumt2 - REAL(kind=mg_pr) :: ql_new, qi_new, qn_new, qni_new, qa_new + REAL(kind=mg_pr) :: ql_new, qi_new, qn_new, qni_new, qa_new - ! hm add 3/19/07, new loop variables for sub-step solution - integer iter, it, ltrue(idim) +! hm add 3/19/07, new loop variables for sub-step solution + integer iter, it, ltrue(idim) - REAL(kind=mg_pr) :: dum3 + REAL(kind=mg_pr) :: dum3 - REAL(kind=mg_pr) :: qii_new, nii_new, nii_min, nii_max + REAL(kind=mg_pr) :: qii_new, nii_new, nii_min, nii_max - logical :: do_berg_ex, do_berg1 + logical :: do_berg_ex, do_berg1 ! v1.4 @@ -757,10 +796,10 @@ SUBROUTINE morrison_gettelman_microp & - REAL(kind=mg_pr) :: scalef, m1, m2, m3, m4, m5 + REAL(kind=mg_pr) :: scalef, m1, m2, m3, m4, m5 - INTEGER :: i, k, n ,nstep, kk + INTEGER :: i, k, n ,nstep, kk @@ -768,4666 +807,3461 @@ SUBROUTINE morrison_gettelman_microp & !cms++ 6/6/08 temp? - real(kind=mg_pr), parameter :: d622 = rdgas / rvgas - real(kind=mg_pr), parameter :: d378 = 1._mg_pr - d622 + real(kind=mg_pr), parameter :: d622 = rdgas / rvgas + real(kind=mg_pr), parameter :: d378 = 1._mg_pr - d622 !cms-- - REAL (kind=mg_pr) :: tmp1, tmp2, tmp3, tmp7, coffi - - REAL (kind=mg_pr) :: qs_t, qs_d , eslt, esit, dqsi + REAL (kind=mg_pr) :: tmp1, tmp2, tmp3, tmp7, coffi + REAL (kind=mg_pr) :: qs_t, qs_d , eslt, esit, dqsi - REAL (kind=mg_pr) :: q_e - - - -!diag + REAL (kind=mg_pr) :: q_e -! REAL, dimension( idim, kdim ), INTENT(INOUT ) :: debug4 - - INTEGER :: n_diag_4d - REAL, dimension( idim, jdim, kdim, 0:n_diag_4d ), INTENT(INOUT ) :: diag_4d - TYPE(diag_id_type) :: diag_id - TYPE(diag_pt_type) :: diag_pt !------------------------------------ !cloud droplets - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmel1 ! cond/evap rate of cloud liquid - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: D_eros_l1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: berg1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvdep_qi1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: pre1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prds1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: snow2vapor1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: sedi_ice2vapor1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: sedi_liquid2vapor1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: super_saturation_rm1 + + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmel1 ! cond/evap rate of cloud liquid + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: D_eros_l1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: berg1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qvdep_qi1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: pra1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: mnuccc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: pra1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: mnuccc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: psacws1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: bergs1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: psacws1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: bergs1 !cloud ice - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: psacws_o1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: psacws_o1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmei1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: D_eros_i1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: cmei1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: D_eros_i1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prci1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prai1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prci1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: prai1 !cloud droplet number - REAL(kind=mg_pr), DIMENSION(kdim) :: nucclim - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nucclim1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npccn1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nnuccc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npsacws1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npsacws_o1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsubc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nerosc1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npra1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nprc11 + REAL(kind=mg_pr), DIMENSION(kdim) :: nucclim + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nucclim1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npccn1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nnuccc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npsacws1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npsacws_o1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsubc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nerosc1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: npra1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nprc11 !cloud ice number - REAL(kind=mg_pr), DIMENSION(kdim) :: nucclim1i - REAL(kind=mg_pr), DIMENSION(kdim) :: nucclim2 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nnuccd1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsubi1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nerosi1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nprci1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nprai1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nucclim1_1 - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nucclim2_1 + REAL(kind=mg_pr), DIMENSION(kdim) :: nucclim1i + REAL(kind=mg_pr), DIMENSION(kdim) :: nucclim2 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nnuccd1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nsubi1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nerosi1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nprci1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nprai1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nucclim1_1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: nucclim2_1 + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: pracs1 + real(kind=mg_pr), DIMENSION(idim,kdim) :: mnuccr1 + real(kind=mg_pr), DIMENSION(idim,kdim) :: relhum - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qs - - - REAL :: tmp2s, qa_t - - REAL :: NACNT - - -!diag-- -!debug - + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: qs -! LOGICAL, INTENT(IN ):: debugo, debugo0, debugo1 - LOGICAL, INTENT(IN ):: debugo0, debugo1 - INTEGER, INTENT(IN ) :: otun -! INTEGER, INTENT(IN ) :: isamp,jsamp, ksamp - integer, dimension(2) :: maxl, minl - LOGICAL :: debugom - - -integer :: debugn - - integer, save :: errcoun = 1 - real :: tsum + REAL :: tmp2s, qa_t + REAL :: NACNT - REAL(kind=mg_pr), DIMENSION(idim,kdim) :: sum_freeze, sum_rime, & - sum_berg - real :: qldt_sum + REAL(kind=mg_pr), DIMENSION(idim,kdim) :: sum_freeze, sum_rime, & + sum_bergs, sum_ice_adj, & + sum_berg, sum_cond, & + sum_freeze2 + real :: qldt_sum - debugom=.TRUE. - - !--------------------- !some sanity checking (more needed!!) -IF ( .NOT. Nml%do_pdf_clouds ) THEN -IF ( auto_conv_ice_choice .EQ. 2 ) THEN -call error_mesg ( 'morrison_gettelman_microp', & - 'ERROR auto_conv_ice_choice =2 not compatible w. Tiedtke param. assumption of in-cloud RH=1 ', FATAL) -END IF -IF ( qv_on_qi ) THEN -call error_mesg ( 'morrison_gettelman_microp', & - 'ERROR qv_on_qi = .true. not compatible w. Tiedtke param. assumption of in-cloud RH=1 ', FATAL) -END IF -END IF - - - - - - DO k=1,kdim - DO i= 1,idim - - - qv(i,k) = qv_in(i,k) - - qc(i,k) = qc_in(i,k) - qi(i,k) = qi_in(i,k) - - nc(i,k) = nc_in(i,k) - ni(i,k) = ni_in(i,k) - - tn(i,k) = t_in(i,k) - - cldn(i,k) = cldn_in(i,k) + IF ( .NOT. Nml%do_pdf_clouds ) THEN + IF (auto_conv_ice_choice .EQ. 2 ) THEN + call error_mesg ( 'morrison_gettelman_microp', & + 'ERROR auto_conv_ice_choice =2 not compatible w. Tiedtke& + & param. assumption of in-cloud RH=1 ', FATAL) + END IF + IF ( qv_on_qi ) THEN + call error_mesg ( 'morrison_gettelman_microp', & + 'ERROR qv_on_qi = .true. not compatible w. Tiedtke & + ¶m. assumption of in-cloud RH=1 ', FATAL) + END IF + END IF +!--------------------------------------------------------------------- + DO k=1,kdim + DO i= 1,idim + qv(i,k) = qv_in(i,k) + qc(i,k) = qc_in(i,k) + qi(i,k) = qi_in(i,k) + nc(i,k) = nc_in(i,k) + ni(i,k) = ni_in(i,k) + tn(i,k) = t_in(i,k) + cldn(i,k) = cldn_in(i,k) + END DO END DO - END DO - - - !---------------------------------------------------- - - - - IF ( do_morrison_gettelman_eros ) THEN - DO k=1,kdim - DO i= 1,idim - D_eros_l(i,k) = - qc(i,k) * D_eros(i,k) / deltatin - D_eros_i(i,k) = - qi(i,k) * D_eros(i,k) / deltatin - - END DO - END DO - ELSE - DO k=1,kdim - DO i= 1,idim - D_eros_l(i,k) = 0._mg_pr - D_eros_i(i,k) = 0._mg_pr - END DO - END DO - END IF - - - - - DO i= 1,idim - surfrain(i,j)=0._mg_pr - surfsnow(i,j)=0._mg_pr - END DO - - - DO k=1,kdim - DO i= 1,idim - - cme(i,k) = dcond_ls_tot(i,k)/deltatin - - END DO - END DO - - - - -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc !++ag assign variable deltat for sub-stepping... - deltat=deltatin + deltat = deltatin ! parameters for scheme -!! omsm=0.99999_mg_pr !orig. value - omsm=0.99999_mg_pr - mincld=0.0001_mg_pr + omsm = 0.99999_mg_pr + mincld = 0.0001_mg_pr ! initialize multi-level fields -!RSH#1 do i=1,idim - do k=1,kdim - do i=1,idim - q(i,k)=qv(i,k) - t(i,k)=tn(i,k) - end do + do k=1,kdim + do i=1,idim + q(i,k) = qv(i,k) + t(i,k) = tn(i,k) end do - + end do + ! initialize time-varying parameters - do k=1,kdim + do k=1,kdim do i=1,idim - rho(i,k)=pfull(i,k)/(rdgas*t(i,k)) - dv(i,k) = 8.794E-5_mg_pr*t(i,k)**1.81_mg_pr/pfull(i,k) - mu(i,k) = 1.496E-6_mg_pr*t(i,k)**1.5_mg_pr/ & - (t(i,k)+120._mg_pr) - sc(i,k) = mu(i,k)/(rho(i,k)*dv(i,k)) - kap(i,k) = 1.414e3_mg_pr*1.496e-6_mg_pr*t(i,k)** & - 1.5_mg_pr/(t(i,k)+120._mg_pr) + rho(i,k) = pfull(i,k)/(rdgas*t(i,k)) + dv(i,k) = 8.794E-5_mg_pr*t(i,k)**1.81_mg_pr/pfull(i,k) + mu(i,k) = 1.496E-6_mg_pr*t(i,k)**1.5_mg_pr/ & + (t(i,k) + 120._mg_pr) + sc(i,k) = mu(i,k)/(rho(i,k)*dv(i,k)) + kap(i,k) = 1.414e3_mg_pr*1.496e-6_mg_pr*t(i,k)**1.5_mg_pr/ & + (t(i,k) + 120._mg_pr) ! air density adjustment for fallspeed parameters ! hm added 11/18/06, add air density correction factor to the ! power of 0.54 following Heymsfield and Bansemer 2006 - arn(i,k)=ar*(rhosu/rho(i,k))**0.54 - asn(i,k)=as*(rhosu/rho(i,k))**0.54 - acn(i,k)=ac*(rhosu/rho(i,k))**0.54 - ain(i,k)=ai*(rhosu/rho(i,k))**0.54 +! if (rho_factor_in_max_vt) then + rhof(i,k)=(rhosu/rho(i,k))**0.54_mg_pr +! else +! rhof(i,k) = 1.0 +! endif + rhof(i,k) = MIN (rhof(i,k), max_rho_factor_in_vt) + +! arn(i,k)=ar*(rhosu/rho(i,k))**0.54_mg_pr +! asn(i,k)=as*(rhosu/rho(i,k))**0.54_mg_pr +! acn(i,k)=ac*(rhosu/rho(i,k))**0.54_mg_pr +! ain(i,k)=ai*(rhosu/rho(i,k))**0.54_mg_pr + arn(i,k)=ar*rhof(i,k) + asn(i,k)=as*rhof(i,k) + acn(i,k)=ac*rhof(i,k) + ain(i,k)=ai*rhof(i,k) - - ! keep dz positive (define as layer k-1 - layer k) - dz(i,k) = zhalf(i,k) - zhalf(i,k+1) - - end do - end do + dz(i,k)= pdel(i,k)/(rho(i,k)*grav) + end do + end do !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ! calculate condensation based on cloud fraction, t,q tendencies ! -!RSH#2 do i=1,idim - do k=1,kdim - do i=1,idim + do k=1,kdim + do i=1,idim ! store original variables for sub-stepping - t1(i,k) = t(i,k) - q1(i,k) = q(i,k) - qc1(i,k) = qc(i,k) - qi1(i,k) = qi(i,k) - nc1(i,k) = nc(i,k) - ni1(i,k) = ni(i,k) + t1(i,k) = t(i,k) + q1(i,k) = q(i,k) + qc1(i,k) = qc(i,k) + qi1(i,k) = qi(i,k) + nc1(i,k) = nc(i,k) + ni1(i,k) = ni(i,k) !cms++ ! initialize tendencies to zero - tlat1(i,k)=0._mg_pr - qvlat1(i,k)=0._mg_pr - qctend1(i,k)=0._mg_pr - qitend1(i,k)=0._mg_pr - nctend1(i,k)=0._mg_pr - nitend1(i,k)=0._mg_pr - - - tlat(i,k)=0._mg_pr - qvlat(i,k)=0._mg_pr - qctend(i,k)=0._mg_pr - qitend(i,k)=0._mg_pr - qnitend(i,k)=0._mg_pr - qrtend(i,k)=0._mg_pr - nctend(i,k)=0._mg_pr - nitend(i,k)=0._mg_pr - nrtend(i,k)=0._mg_pr - nstend(i,k)=0._mg_pr - prect(i)=0._mg_pr - preci(i)=0._mg_pr - qniic(i,k)=0._mg_pr - qric(i,k)=0._mg_pr - nsic(i,k)=0._mg_pr - nric(i,k)=0._mg_pr - - ! hm add 9/5/07 - rainrt(i,k)=0._mg_pr - !cms for calc. rain3d, snow3d -! arainrt(i,k)=0._mg_pr - asnowrt(i,k)=0._mg_pr - atotrt(i,k)=0._mg_pr + tlat1(i,k) = 0._mg_pr + qvlat1(i,k) = 0._mg_pr + qctend1(i,k) = 0._mg_pr + qitend1(i,k) = 0._mg_pr + nctend1(i,k) = 0._mg_pr + nitend1(i,k) = 0._mg_pr + + tlat(i,k) = 0._mg_pr + qvlat(i,k) = 0._mg_pr + qctend(i,k) = 0._mg_pr + qitend(i,k) = 0._mg_pr + qnitend(i,k) = 0._mg_pr + qrtend(i,k) = 0._mg_pr + nctend(i,k) = 0._mg_pr + nitend(i,k) = 0._mg_pr + nrtend(i,k) = 0._mg_pr + nstend(i,k) = 0._mg_pr + prect(i) = 0._mg_pr + preci(i) = 0._mg_pr + qniic(i,k) = 0._mg_pr + qric(i,k) = 0._mg_pr + nsic(i,k) = 0._mg_pr + nric(i,k) = 0._mg_pr + +! hm add 9/5/07 + rainrt(i,k) = 0._mg_pr +!cms for calc. rain3d, snow3d !cms-- ! initialize precip output - qrout(i,k)=0._mg_pr - qsout(i,k)=0._mg_pr - nrout(i,k)=0._mg_pr - nsout(i,k)=0._mg_pr + qrout(i,k) = 0._mg_pr + qsout(i,k) = 0._mg_pr + nrout(i,k) = 0._mg_pr + nsout(i,k) = 0._mg_pr ! initialize bergeron fraction arrays - sum_freeze(i,k) = 0. - sum_rime (i,k) = 0. - sum_berg (i,k) = 0. - - - -!!$! hm add, initialize variables for trop_mozart -!!$ -!!$ nevapr(i,k) = 0._mg_pr -!!$ evapsnow(i,k) = 0._mg_pr -!!$ prain(i,k) = 0._mg_pr -!!$ prodsnow(i,k) = 0._mg_pr -!!$ cmeout(i,k) = 0._mg_pr + sum_freeze(i,k) = 0._mg_pr + sum_freeze2(i,k) = 0._mg_pr + sum_rime (i,k) = 0._mg_pr + sum_berg (i,k) = 0._mg_pr + sum_ice_adj(i,k) = 0._mg_pr + sum_bergs (i,k) = 0._mg_pr + sum_cond (i,k) = 0._mg_pr -!!$ ! hm, add for refl calc 9/5/07 -!!$ - rainrt1(i,k) = 0._mg_pr - - atotrt1(i,k) = 0._mg_pr - asnowrt1(i,k) = 0._mg_pr + rainrt1(i,k) = 0._mg_pr !diag++ !droplets - - cmel1(i,k) = 0._mg_pr - D_eros_l1(i,k) = 0._mg_pr - berg1(i,k) = 0._mg_pr - qvdep_qi1(i,k) = 0._mg_pr - - prc1(i,k) = 0._mg_pr - - pra1(i,k) = 0._mg_pr - mnuccc1(i,k) = 0._mg_pr - - psacws1(i,k) = 0._mg_pr - - bergs1(i,k) = 0._mg_pr - + pre1(i,k) = 0._mg_pr + prds1(i,k) = 0._mg_pr + snow2vapor1(i,k) = 0._mg_pr + snow2vapor(k) = 0._mg_pr + sedi_ice2vapor1(i,k) = 0._mg_pr + sedi_liquid2vapor1(i,k) = 0._mg_pr + super_saturation_rm1(i,k) = 0._mg_pr + + cmel1(i,k) = 0._mg_pr + D_eros_l1(i,k) = 0._mg_pr + berg1(i,k) = 0._mg_pr + qvdep_qi1(i,k) = 0._mg_pr + prc1(i,k) = 0._mg_pr + pra1(i,k) = 0._mg_pr + mnuccc1(i,k) = 0._mg_pr + psacws1(i,k) = 0._mg_pr + bergs1(i,k) = 0._mg_pr !ice - - psacws_o1(i,k) = 0._mg_pr - cmei1(i,k) = 0._mg_pr - D_eros_i1(i,k) = 0._mg_pr - - prci1(i,k) = 0._mg_pr - prai1(i,k) = 0._mg_pr - + psacws_o1(i,k) = 0._mg_pr + cmei1(i,k) = 0._mg_pr + D_eros_i1(i,k) = 0._mg_pr + prci1(i,k) = 0._mg_pr + prai1(i,k) = 0._mg_pr !droplet number - nucclim1(i,k) = 0._mg_pr - npccn1(i,k) = 0._mg_pr - nnuccc1(i,k) = 0._mg_pr - npsacws1(i,k) = 0._mg_pr - npsacws_o1(i,k) = 0._mg_pr - nsubc1(i,k) = 0._mg_pr - nerosc1(i,k) = 0._mg_pr - npra1(i,k) = 0._mg_pr - nprc11(i,k) = 0._mg_pr - - + nucclim1(i,k) = 0._mg_pr + npccn1(i,k) = 0._mg_pr + nnuccc1(i,k) = 0._mg_pr + npsacws1(i,k) = 0._mg_pr + npsacws_o1(i,k) = 0._mg_pr + nsubc1(i,k) = 0._mg_pr + nerosc1(i,k) = 0._mg_pr + npra1(i,k) = 0._mg_pr + nprc11(i,k) = 0._mg_pr !ice number + nnuccd1(i,k) = 0._mg_pr + nsubi1(i,k) = 0._mg_pr + nerosi1(i,k) = 0._mg_pr + nprci1(i,k) = 0._mg_pr + nprai1(i,k) = 0._mg_pr + nucclim1_1(i,k) = 0._mg_pr + nucclim2_1(i,k) = 0._mg_pr + pracs1(i,k) = 0._mg_pr + mnuccr1(i,k) = 0._mg_pr + end do + end do - nnuccd1(i,k) = 0._mg_pr - nsubi1(i,k) = 0._mg_pr - nerosi1(i,k) = 0._mg_pr - nprci1(i,k) = 0._mg_pr - nprai1(i,k) = 0._mg_pr - nucclim1_1(i,k) = 0._mg_pr - nucclim2_1(i,k) = 0._mg_pr - - -!diag-- +! get cloud fraction, check for minimum + do k=1,kdim + do i=1,idim + cldmax(i,k) = mincld + cldm(i,k) = max(cldn(i,k), mincld) + end do + end do +! initialize avg precip rate + do i=1,idim + prect1(i)=0._mg_pr + preci1(i)=0._mg_pr + end do - end do - end do + do k=1,kdim + do i=1,idim + esl(i,k) = polysvp_l(t(i,k)) + esi(i,k) = polysvp_i(t(i,k)) +! MAKE SURE ICE SATURATION DOESN'T EXCEED WATER SAT. NEAR FREEZING + IF (esi(i,k) .GT. esl(i,k)) esi(i,k) = esl(i,k) + end do + end do -! initialize precip fraction and output tendencies -debugn = 0 + IF ( meyers_test ) THEN +! over-write crystal1 +! this is Steve Klein's version, Hugh's WRF version is different ... + do k=1,kdim + do i=1,idim + crystal1(i,k) = 1000._mg_pr*exp((12.96_mg_pr* & + 0.0125_mg_pr*(tfreeze - T(i,k))) - & + 0.639_mg_pr) + end do + end do + END IF - do k=1,kdim - do i=1,idim - cldmax(i,k)=mincld + do k=1,kdim + do i=1,idim + prd = 0._mg_pr + if (t(i,k) .lt. tfreeze - 5._mg_pr) then + IF (Nml%do_ice_nucl_wpdf) THEN -!++ag initialize aerosol number -!!$ naer2(i,k,:)=0._mg_pr +!use number calculated outside this code + IF (total_activation) THEN + dum = crystal1(i,k)*cldm(i,k)/rho(i,k) + ELSE IF (dqa_activation) THEN + dum = crystal1(i,k)/rho(i,k) + END IF + ELSE +! cooper + dum = min(0.005_mg_pr*exp(0.304_mg_pr* & + (tfreeze - t(i,k)))*1000._mg_pr, 208.9e3_mg_pr) + dum = dum/rho(i,k) + END IF + + IF (total_activation) THEN + if (delta_cf(i,k) .gt. 0._mg_pr ) then + dumnnuc = (dum - ni(i,k)/cldm(i,k))/deltat*cldm(i,k) + else + dumnnuc = 0._mg_pr + end if + ELSE IF (dqa_activation) THEN + dumnnuc = max(delta_cf(i,k), 0.)*dum/deltat + END IF + dumnnuc=max(dumnnuc,0._mg_pr) -! get cloud fraction, check for minimum + ! get provisional ni and qi after nucleation in order to calculate + ! Bergeron process below + ninew = ni(i,k) + dumnnuc*deltat + if (tiedtke_macrophysics .or. dqa_activation) then + qinew = qi(i,k) + else + qinew =qi(i,k) + dumnnuc*deltat*mi0 + endif + else + ninew = ni(i,k) + qinew = qi(i,k) + end if - cldm(i,k)=max(cldn(i,k),mincld) - end do - end do +! NOTE: this approach has been replaced by NCAR's, so the following +! comments are no longer valid +! for condensation +! for T < tmin_fice, assume all new condensate is ice +! for T > tmin_fice, put all new condensate into liquid temporarily, +! then calculate transfer to ice through Bergeron process +! note: this approach assumes that ice/liquid is mixed throughout the +! cloudy portion of the grid cell +! END NOTE +! make sure to initialize bergeron process to zero + berg(i,k) = 0._mg_pr + qvdep_qi(i,k) = 0._mg_pr -! initialize avg precip rate - do i=1,idim - prect1(i)=0._mg_pr - preci1(i)=0._mg_pr - end do +! cmel and cmei are liquid and ice condensate as clacuklated in nc_cond.F90 +! and input here + cmel(i,k) = dqcdt(i,k) + cmei(i,k) = dqidt(i,k) + dum2 = dqcdt(i,k) + dqidt(i,k) +! get in-cloud qi and ni after nucleation +!RSH: Note loop may be unnecessary since icldm >= mincld, which is > 0. + if (cldm(i,k) .gt. 0._mg_pr) then + qiic(i,k)=qinew/cldm(i,k) + niic(i,k)=ninew/cldm(i,k) + else + qiic(i,k)=0._mg_pr + niic(i,k)=0._mg_pr + endif + + IF (.NOT. limit_berg) THEN + if (dum2 .ge. 0._mg_pr .and. & + (qc(i,k) + dqcdt(i,k)*deltat > qsmall) ) then + do_berg1 = .true. + else + do_berg1 = .false. + end if + ELSE + if (dum2 .ge. 0._mg_pr .and. qinew .gt. berg_lim ) then + do_berg1 = .true. + else + do_berg1 = .false. + end if + END If + if (do_berg1) then + if (t(i,k) .lt. tfreeze ) then + if (qi(i,k) > qsmall) then +! calculate Bergeron process - do k=1,kdim - do i=1,idim + bergtsf = 0._mg_pr ! bergeron time scale + ! (fraction of timestep) + qvi = 0.622_mg_pr*esi(i,k)/(pfull(i,k) - d378*esi(i,k)) + qvl = 0.622_mg_pr*esl(i,k)/(pfull(i,k) - d378*esl(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi(i,k) = 1._mg_pr + dqsidt*xxls/cpp +! get ice size distribution parameters +!adding this 10/1 0421AM + if (qiic(i,k).ge.qsmall) then + lami(k) = (gamma_mg(1._mg_pr + di_mg)*ci_mg* & + niic(i,k)/qiic(i,k))**(1._mg_pr/di_mg) + n0i(k) = niic(i,k)*lami(k) - esl(i,k)=polysvp_l(t(i,k)) - esi(i,k)=polysvp_i(t(i,k)) +! check for slope + lammax = 1._mg_pr/min_diam_ice + lammin = 1._mg_pr/(2._mg_pr*dcs) -! MAKE SURE ICE SATURATION DOESN'T EXCEED WATER SAT. NEAR FREEZING - IF (esi(i,k).GT.esl(i,k)) esi(i,k) = esl(i,k) +! adjust vars + if (lami(k) .lt. lammin) then + lami(k) = lammin + n0i(k) = lami(k)**(di_mg + 1._mg_pr)*qiic(i,k)/ & + (ci_mg*gamma_mg(1._mg_pr + di_mg)) + else if (lami(k) .gt. lammax) then + lami(k) = lammax + n0i(k) = lami(k)**(di_mg + 1._mg_pr)*qiic(i,k)/ & + (ci_mg*gamma_mg(1._mg_pr + di_mg)) + end if + + epsi = 2._mg_pr*pi*n0i(k)*rho(i,k)*Dv(i,k)/ & + (lami(k)*lami(k)) + if (qc(i,k) + dqcdt(i,k)*deltat .gt. qsmall) then + prd = epsi*(qvl - qvi)/abi(i,k) + else + prd = 0._mg_pr + end if - end do - end do +! multiply by cloud fraction + prd = prd*cldm(i,k) + berg(i,k) = max(0._mg_pr, prd) + end if + if (berg(i,k) .gt. 0._mg_pr) then + bergtsf = max(0._mg_pr, & + ((dqcdt(i,k) + qc(i,k)/deltat)/berg(i,k))) + if(bergtsf .lt. 1._mg_pr) berg(i,k) = & + max(0._mg_pr, dqcdt(i,k) + qc(i,k)/deltat) + endif +!TEST IF NEEDED: 9/27 0133Z + if (t(i,k) < tfreeze - 40._mg_pr) then + berg(i,k) = 0._mg_pr + endif +!cms++ +! vapor deposition onto cloud ice + if (qv_on_qi) then + dqsi = MAX(qv(i,k) - qvi, 0._mg_pr) + qvdep_qi(i,k) = max(min(prd - cmei(i,k) - berg(i,k), & + dqsi/deltat*omsm), 0._mg_pr) + end if +!cms-- + endif + end if ! t < 273.15 + endif ! (do_berg1) +! limit cmel,cmei due for roundoff error + cmel(i,k) = cmel(i,k)*omsm + cmei(i,k) = cmei(i,k)*omsm - IF ( meyers_test ) THEN -!over-write crystal1 -!this is Steve Klein's version, Hugh's WRF version is different ... - do k=1,kdim - do i=1,idim - crystal1(i,k) = 1000._mg_pr * exp((12.96_mg_pr*0.0125_mg_pr*(273.15_mg_pr-T(i,k)))-0.639_mg_pr) - end do - end do - END IF +! define activated ice nuclei + if (t(i,k) < tfreeze - 5.0_mg_pr) then +! use number calculated outside this code + IF (Nml%do_ice_nucl_wpdf) THEN + IF (total_activation) THEN + if (delta_cf(i,k) .gt. 0._mg_pr) then + dum2i(i,k) = crystal1(i,k)*cldm(i,k)/rho(i,k) + else + dum2i(i,k) = 0._mg_pr + end if + ELSEIF (dqa_activation) THEN + dum2i(i,k) = crystal1(i,k)/rho(i,k) + END IF + ELSE +! cooper + dum2i(i,k) = min(0.005_mg_pr*exp(0.304_mg_pr* & + (tfreeze - t(i,k)))*1000._mg_pr, 208.9e3_mg_pr) + END IF + else + dum2i(i,k) = 0.0_mg_pr + endif + end do + end do - do k=1,kdim - do i=1,idim - prd = 0._mg_pr +!pdf clouds option -- validity ?? +!re-calculate cloud fraction + IF (Nml%do_pdf_clouds .AND. & + (Nml%super_ice_opt .EQ. 1 .OR. Nml%super_ice_opt .EQ. 2)) THEN + IF (Nml%super_ice_opt .EQ. 1) THEN + DO k=1,kdim + DO i=1,idim + ttmp = t(i,k) + IF (ttmp .LT. tfreeze - 40._mg_pr .OR. & + (ttmp .LE. tfreeze .AND. qc(i,k) + & + (cmel(i,k) - berg(i,k) )/deltat & + .LT. 3._mg_pr*Nml%qmin)) THEN + eslt = polysvp_i(ttmp) + ELSE + eslt = polysvp_l(ttmp) + END IF + qs_d = pfull(i,k) - d378*eslt + qs_d = max(qs_d, eslt) + qs(i,k) = d622*eslt/qs_d + END DO + END DO + END IF + IF (Nml%super_ice_opt .EQ. 2) THEN + DO k=1,kdim + DO i=1,idim + ttmp = t(i,k) + IF (ttmp .LT. tfreeze - 40._mg_pr .OR. & + (ttmp .LE. tfreeze .AND. qc(i,k) + & + (cmel(i,k) - berg(i,k) )/deltat & + .LT. 3._mg_pr*Nml%qmin) ) THEN + eslt = polysvp_i(ttmp) + tc = ttmp - tfreeze +!!! rhi=MIN( max_super_ice, 0.000195*tc**2+0.00266*tc+1.005) + rhi = 0.000195_mg_pr*tc**2 + 0.00266_mg_pr*tc + & + 1.005_mg_pr + ELSE + eslt = polysvp_l(ttmp) + rhi = 1._mg_pr + END IF + qs_d = pfull(i,k) - d378*eslt + qs_d = max(qs_d, eslt) + qs(i,k)= rhi*d622*eslt/qs_d + END DO + END DO + END IF - t_if1: if (t(i,k).lt.268.15_mg_pr) then + qtot = qv_in + qc_in + qi_in + IF ( Nml%pdf_org ) & + call error_mesg ( 'morrison_gettelman_microp', & + 'ERROR 1 simple_pdf ', FATAL) - crystal_if: IF ( Nml%do_ice_nucl_wpdf ) THEN + CALL simple_pdf (j, idim, jdim, kdim, Nml%qmin, qa0, & + qtot, qs, gamma, Nml%qthalfwidth, & + Nml%betaP, inv_dtcloud, & +!inout + SA_0, & +!diag + n_diag_4d, diag_4d, diag_id, diag_pt, & + SA, qa_upd) -!use number calculated outside this code - IF ( act_choice .EQ. 1 ) THEN - - dum = crystal1(i,k)*cldm(i,k)/rho(i,k) - ELSE IF ( act_choice .EQ. 2 ) THEN + do k=1,kdim + do i=1,idim + cldm(i,k) = max(qa_upd(i,k), mincld) + end do + end do + END IF - dum = crystal1(i,k)/rho(i,k) +!! initialize sub-step precip flux variables + do i=1,idim +!! flux is zero at top interface, so these should stay as 0. + do k=1,kdim + +! initialize normal and sub-step precip flux variables + atotrt1(i,k)=0._mg_pr + asnowrt1(i,k)=0._mg_pr + end do + end do + +!! initialize final precip flux variables. + do i=1,idim +!! flux is zero at top interface, so these should stay as 0. + do k=1,kdim +! initialize normal and sub-step precip flux variables + atotrt(i,k)=0._mg_pr + asnowrt(i,k)=0._mg_pr + end do + end do + + do i=1,idim + ltrue(i) = 0 + do k=1,kdim +! hm add 3/19/07 skip microphysical calculations if no cloud water - END IF - ELSE ! crystal_if + if (qc(i,k).ge.qsmall .or. qi(i,k).ge.qsmall .or. & + cmel(i,k).ge.qsmall .or. cmei(i,k).ge.qsmall .or. & + qvdep_qi(i,k).ge.qsmall) ltrue(i)=1 +!cms also skip if total water amount is negative anywhere within the column + if (qc(i,k) + qi(i,k) + qv(i,k) .lt. -1.e-9_mg_pr .OR. & + qv(i,k) .lt. -1.e-9_mg_pr) then + ltrue(i) = 0 + nrefuse = nrefuse + 1 + end if + end do + end do - dum = min(0.005_mg_pr*exp(0.304_mg_pr*(273.15_mg_pr-t(i,k)))*1000._mg_pr,208.9e3_mg_pr) !cooper - - END IF crystal_if +! assign number of sub-steps to iter +! use 2 sub-steps, following tests described in +! Morrison and Gettelman, 2007, J. Clim. + iter = 2 - IF ( act_choice .EQ. 1 ) THEN +! get sub-step time step + deltat = deltat/real(iter) - if (tmp5(i,k) .gt. 0._mg_pr ) then +!!!! skip calculations if no cloud water - dumnnuc=(dum-ni(i,k)/cldm(i,k))/deltat*cldm(i,k) - else + do i=1,idim - dumnnuc = 0._mg_pr + if (ltrue(i) .eq. 0) then + do k=1,kdim + tlat(i,k)=0._mg_pr + qvlat(i,k)=0._mg_pr + qctend(i,k)=0._mg_pr + qitend(i,k)=0._mg_pr + qnitend(i,k)=0._mg_pr + qrtend(i,k)=0._mg_pr + nctend(i,k)=0._mg_pr + nitend(i,k)=0._mg_pr + nrtend(i,k)=0._mg_pr + nstend(i,k)=0._mg_pr + prect(i)=0._mg_pr + preci(i)=0._mg_pr + qniic(i,k)=0._mg_pr + qric(i,k)=0._mg_pr + nsic(i,k)=0._mg_pr + nric(i,k)=0._mg_pr + +! hm add 9/5/07 + rainrt(i,k)=0._mg_pr + end do + goto 300 + end if - end if + cmel_orig(i,:) = cmel(i,:) + cmei_orig(i,:) = cmei(i,:) + berg_orig(i,:) = berg(i,:) - ELSE IF ( act_choice .EQ. 2 ) THEN +!!!!!!!!! begin sub-step!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!......................................................................... - dumnnuc=max(tmp5(i,k),0.) * dum /deltat + do it=1,iter + do k=1,kdim - END IF +! initialize sub-step microphysical tendencies + tlat(i,k)=0._mg_pr + qvlat(i,k)=0._mg_pr + qctend(i,k)=0._mg_pr + qitend(i,k)=0._mg_pr + qnitend(i,k)=0._mg_pr + qrtend(i,k)=0._mg_pr + nctend(i,k)=0._mg_pr + nitend(i,k)=0._mg_pr + nrtend(i,k)=0._mg_pr + nstend(i,k)=0._mg_pr +! initialize diagnostic precipitation to zero - dumnnuc=max(dumnnuc,0._mg_pr) - ! get provisional ni and qi after nucleation in order to calculate - ! Bergeron process below - ninew=ni(i,k)+dumnnuc*deltat - qinew=qi(i,k)+dumnnuc*deltat*mi0 -else !t_if1 - ninew=ni(i,k) - qinew=qi(i,k) -end if t_if1 + qniic(i,k)=0._mg_pr + qric(i,k)=0._mg_pr + nsic(i,k)=0._mg_pr + nric(i,k)=0._mg_pr + nerosc(i,k) = nerosc4(i,k) + nerosi(i,k) = nerosi4(i,k) + D_eros_l(i,k) = D_eros_l4(i,k) + D_eros_i(i,k) = D_eros_i4(i,k) + cmel(i,k) = cmel_orig(i,k) + cmei(i,k) = cmei_orig(i,k) + berg(i,k) = berg_orig(i,k) -! for condensation -! for T < tmin_fice, assume all new condensate is ice -! for T > tmin_fice, put all new condensate into liquid temporarily, -! then calculate transfer to ice through Bergeron process -! note: this approach assumes that ice/liquid is mixed throughout the cloudy -! portion of the grid cell +! hm, add 9/5/07 + + rainrt(i,k)=0._mg_pr -! make sure to initialize bergeron process to zero - berg(i,k)=0._mg_pr + end do - qvdep_qi(i,k)=0._mg_pr +! initialize vertically-integrated rain and snow tendencies + qrtot = 0._mg_pr + nrtot = 0._mg_pr + qstot = 0._mg_pr + nstot = 0._mg_pr - IF ( .NOT. limit_berg ) THEN - if (cme(i,k).ge.0._mg_pr) then - do_berg1 = .true. - else - do_berg1 = .false. - end if - ELSE - if (cme(i,k).ge.0._mg_pr .and. qinew .gt. berg_lim ) then - do_berg1 = .true. - else - do_berg1 = .false. - end if -END If - if (do_berg1 ) then -!cms if (cme(i,k).ge.0._mg_pr) then +! initialize precip at surface -!!$ if (t(i,k).ge.tmin_fice) then + prect(i)=0._mg_pr + preci(i)=0._mg_pr - if (t(i,k).lt.273.15) then + do k=1,kdim -! calculate Bergeron process +! set cwml and cwmi to current qc and qi + cwml(i,k) = qc(i,k) + cwmi(i,k) = qi(i,k) - qvi=0.622_mg_pr*esi(i,k)/(pfull(i,k)-d378*esi(i,k)) - qvl=0.622_mg_pr*esl(i,k)/(pfull(i,k)-d378*esl(i,k)) -!! qvi=0.622_mg_pr*esi(i,k)/(pfull(i,k)-esi(i,k)) -!! qvl=0.622_mg_pr*esl(i,k)/(pfull(i,k)-esl(i,k)) +! initialize precip fallspeeds to zero - dqsidt = xxls*qvi/(rv*t(i,k)**2) - abi(i,k) = 1._mg_pr+dqsidt*xxls/cpp + ums(k) = 0._mg_pr + uns(k) = 0._mg_pr + umr(k) = 0._mg_pr + unr(k)= 0._mg_pr +! calculate precip fraction based on maximum overlap assumption -! get ice size distribution parameters + if (k .eq. 1) then + cldmax(i,k) = cldm(i,k) + else -! get in-cloud qi and ni after nucleation - qiic(i,k)=qinew/cldm(i,k) - niic(i,k)=ninew/cldm(i,k) +! hm add sep 6, 2006, if rain or snow mix ratio is smaller than +! threshold, then set cldmax to cloud fraction at current level + if (qric(i,k-1) .ge. qsmall .or. & + qniic(i,k-1) .ge. qsmall) then + cldmax(i,k) = max(cldmax(i,k-1), cldm(i,k)) + else + cldmax(i,k) = cldm(i,k) + end if + end if +! should this be behind the next block (scaling)? +! decrease in number concentration due to sublimation/evap +! divide by cloud fraction to get in-cloud decrease +! don't reduce Nc due to bergeron process ????? + + nsubi(k) = 0._mg_pr + nsubc(k) = 0._mg_pr + + if (.not. tiedtke_macrophysics) then + if (cmei(i,k) < 0._mg_pr .and. & + qi(i,k) > qsmall .and. & + cldm(i,k) > mincld) then + nsubi(k) = cmei(i,k)/qi(i,k)*ni(i,k)/cldm(i,k) + else + nsubi(k) = 0._mg_pr + end if + if (cmel(i,k) < 0._mg_pr .AND. & + qc(i,k) .ge. qsmall .and. & + cldm(i,k) > mincld) then + nsubc(k) = cmel(i,k)/qc(i,k)*nc(i,k)/cldm(i,k) + else + nsubc(k) = 0._mg_pr + end if + end if + +!c....................................................................... +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! obtain in-cloud values of cloud water/ice mixing ratios and number +! concentrations for microphysical process calculations +! units are kg/kg for mixing ratio, 1/kg for number conc +! limit in-cloud values to 0.005 kg/kg - if (qiic(i,k).ge.qsmall) then - lami(k) = (gamma_mg(1._mg_pr+di_mg)*ci_mg* & - niic(i,k)/qiic(i,k))**(1._mg_pr/di_mg) - n0i(k) = niic(i,k)*lami(k) -! check for slope + qcic(i,k) = min(cwml(i,k)/cldm(i,k), in_cloud_limit) + qiic(i,k) = min(cwmi(i,k)/cldm(i,k), in_cloud_limit) + ncic(i,k) = max(nc(i,k)/cldm(i,k), 0._mg_pr) + niic(i,k) = max(ni(i,k)/cldm(i,k), 0._mg_pr) - lammax = 1._mg_pr/min_diam_ice - - lammin = 1._mg_pr/(2._mg_pr*dcs) + if (qc(i,k) + & + (cmel(i,k) + D_eros_l(i,k) - berg(i,k))*deltat & + .lt. qsmall) then + qcic(i,k) = 0._mg_pr + ncic(i,k) = 0._mg_pr -! adjust vars + if (qc(i,k) + & + (cmel(i,k) + D_eros_l(i,k) - berg(i,k))*deltat & + .lt. 0._mg_pr) then + if (cmel(i,k) .lt. 0._mg_pr) then - if (lami(k).lt.lammin) then +!++ first only scale cmel, d_eros + dum = -cmel(i,k) - D_eros_l(i,k) + if (dum .gt. 1.e-30_mg_pr) then + dum3 = qc(i,k)/deltat/dum*omsm + else + dum3 = 0._mg_pr + end if + cmel(i,k) = dum3*cmel(i,k) + D_eros_l(i,k) = dum3*D_eros_l(i,k) - lami(k) = lammin - n0i(k) = lami(k)**(di_mg+1._mg_pr)*qiic(i,k)/(ci_mg*gamma_mg(1._mg_pr+di_mg)) - else if (lami(k).gt.lammax) then - lami(k) = lammax - n0i(k) = lami(k)**(di_mg+1._mg_pr)*qiic(i,k)/(ci_mg*gamma_mg(1._mg_pr+di_mg)) - end if +!-- + dum = -cmel(i,k) - D_eros_l(i,k) + berg(i,k) + if (dum .gt. 1.e-30_mg_pr) then + dum3 = qc(i,k)/deltat/dum*omsm + else + dum3 = 0._mg_pr + end if + cmel(i,k) = dum3*cmel(i,k) + D_eros_l(i,k) = dum3*D_eros_l(i,k) + berg(i,k) = dum3*berg(i,k) + else + dum = -D_eros_l(i,k) + berg(i,k) +! berg(i,k)=qc(i,k)/deltat*omsm + if (dum .gt. 1.e-30_mg_pr) then + dum3 = (qc(i,k)/deltat + cmel(i,k))/dum*omsm + else + dum3 = 0._mg_pr + end if + D_eros_l(i,k) = D_eros_l(i,k)*dum3 + berg(i,k) = berg(i,k)*dum3 + end if + end if + end if + + if (qi(i,k) + (cmei(i,k) + D_eros_i(i,k) + berg(i,k) + & + qvdep_qi(i,k))*deltat .lt. qsmall) then + qiic(i,k) = 0._mg_pr + niic(i,k) = 0._mg_pr + if (qi(i,k) + (cmei(i,k) + berg(i,k) + D_eros_i(i,k) + & + qvdep_qi(i,k))*deltat .lt. 0._mg_pr) then + if (cmei(i,k) .lt. 0._mg_pr) then + dum = - cmei(i,k) - D_eros_i(i,k) + if (dum .gt. 1.e-30_mg_pr) then + dum3 = (qi(i,k)/deltat + berg(i,k) + & + qvdep_qi(i,k))/dum*omsm + else + dum3 = 0._mg_pr + end if + cmei(i,k) = dum3*cmei(i,k) + D_eros_i(i,k) = dum3*D_eros_i(i,k) + else + dum = - D_eros_i(i,k) + if (dum .gt. 1.e-30_mg_pr) then + dum3 = (qi(i,k)/deltat + cmei(i,k) + berg(i,k) + & + qvdep_qi(i,k))/dum*omsm + else + dum3 = 0._mg_pr + end if + D_eros_i(i,k) = dum3*D_eros_i(i,k) + end if + end if + end if +! add to cme output - epsi = 2._mg_pr*pi*n0i(k)*rho(i,k)*Dv(i,k) & - /(lami(k)*lami(k)) - prd = epsi*(qvl-qvi)/abi(i,k) +!cms cmeout1(i,k) = cmeout1(i,k)+cmel(i,k)+cmei(i,k) - else - prd = 0._mg_pr - end if + + if (qiic(i,k) .ge. qsmall .and. & + t(i,k) .lt. tfreeze - 5._mg_pr) then -! multiply by cloud fraction - prd = prd*cldm(i,k) +! if NCAI > 0. then set numice = ncai (as before) +! note: this is gridbox averaged + + if (total_activation) then + nnuccd(k) = (dum2i(i,k) - ni(i,k)/cldm(i,k))/deltat* & + cldm(i,k) + nnuccd(k) = max(nnuccd(k), 0._mg_pr) + else if (dqa_activation ) then + nnuccd(k) = max(delta_cf(i,k), 0.)*dum2i(i,k)/deltatin + endif + nimax = dum2i(i,k)*cldm(i,k) + else + nnuccd(k) = 0._mg_pr + nimax = 0._mg_pr + mnuccd(k) = 0._mg_pr + end if +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! droplet activation +! calculate potential for droplet activation if cloud water is present -! get fraction of new condensate converted to ice + if (qcic(i,k) .ge. qsmall) then + IF (total_activation) THEN + if (delta_cf(i,k) .gt. 0._mg_pr) then + dum2l(i,k) = drop2(i,k)*cldm(i,k) + else + dum2l(i,k) = 0._mg_pr + end if - if (t(i,k).ge.tmin_fice) then !cms moved to here +! assume aerosols already activated are equal to number of existing +! droplets for simplicity +! multiply by cloud fraction to obtain grid-average tendency + npccn(k) = (dum2l(i,k) - nc(i,k)/cldm(i,k))/deltat* & + cldm(i,k) - dum=0._mg_pr - if (cme(i,k).ne.0._mg_pr) then - dum=prd/cme(i,k) - endif - dum=max(dum,0._mg_pr) - dum=min(dum,1._mg_pr) +! make sure number activated > 0 + npccn(k) = max(0._mg_pr, npccn(k)) + ELSE IF (dqa_activation) THEN +! delta_cf: A_dt * (1.-qabar) where A_dt = A*dt , A source rate +! Eq. 7 of Yi's 2007 paper +! dum2l has already been multiplied by 1.e6/airdens(i,k) + dum2l(i,k) = drop2(i,k) + npccn(k) = max(delta_cf(i,k), 0.)*dum2l(i,k) /deltatin + END IF + ncmax = dum2l(i,k)*cldm(i,k) + else + npccn(k) = 0._mg_pr + ncmax = 0._mg_pr + end if - cmei(i,k)=dum*cme(i,k) - cmel(i,k)=(1._mg_pr-dum)*cme(i,k) +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! get size distribution parameters based on in-cloud cloud water/ice +! these calculations also ensure consistency between number and +! mixing ratio +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! transfer of existing cloud liquid to ice - IF ( .NOT. limit_berg ) THEN - if (prd.gt.cme(i,k)) then - do_berg_ex = .true. - else - do_berg_ex = .false. - end if - ELSE +!...................................................................... +! cloud ice -! korolev '07 -! qv at beginning of time step !grid-box average! this is somewhat arbitrary .... -! cme > 0 => e > e_i in cloud - if (prd.gt.cme(i,k) .and. qv(i,k) .LT. qvl .and. qinew .gt. berg_lim ) then - do_berg_ex = .true. - else - do_berg_ex = .false. - end if + if (qiic(i,k).ge.qsmall) then - END IF +! add upper limit to in-cloud number concentration to prevent +! numerical error + niic(i,k) = min(niic(i,k), qiic(i,k)*1.e20_mg_pr) + lami(k) = (gamma_mg(1._mg_pr + di_mg)*ci_mg* & + niic(i,k)/qiic(i,k))**(1._mg_pr/di_mg) + n0i(k) = niic(i,k)*lami(k) +! check for slope + lammax = 1._mg_pr/min_diam_ice + lammin = 1._mg_pr/(2._mg_pr*dcs) +! adjust vars + if (lami(k) .lt. lammin) then + lami(k) = lammin + n0i(k) = lami(k)**(di_mg + 1._mg_pr)*qiic(i,k)/ & + (ci_mg*gamma_mg(1._mg_pr + di_mg)) + niic(i,k) = n0i(k)/lami(k) + else if (lami(k) .gt. lammax) then + lami(k) = lammax + n0i(k) = lami(k)**(di_mg + 1._mg_pr)*qiic(i,k)/ & + (ci_mg*gamma_mg(1._mg_pr + di_mg)) + niic(i,k) = n0i(k)/lami(k) + end if + else + lami(k) = 0._mg_pr + n0i(k) = 0._mg_pr + end if + if (qcic(i,k).ge.qsmall) then -!cms if (prd.gt.cme(i,k)) then - if ( do_berg_ex ) then +! add upper limit to in-cloud number concentration to prevent +! numerical error + ncic(i,k) = min(ncic(i,k), qcic(i,k)*1.e20_mg_pr) +! get pgam from fit to observations of martin et al. 1994 - !! debugn = debugn + 1 - berg(i,k)=min(prd-cme(i,k),qc(i,k)/deltat*omsm) - end if +!RSH BUGFIX email of 6/8/10 +! pgam(k) = 0.0005714_mg_pr*(ncic(i,k)/1.e6_mg_pr/ & +! rho(i,k)) + 0.2714_mg_pr + pgam(k) = 0.0005714_mg_pr*(ncic(i,k)/1.e6_mg_pr* & + rho(i,k)) + 0.2714_mg_pr + pgam(k) = 1._mg_pr/(pgam(k)**2) - 1._mg_pr + pgam(k) = max(pgam(k), 2._mg_pr) + pgam(k) = min(pgam(k), 15._mg_pr) +! calculate lamc + lamc(k) = (pi/6._mg_pr*rhow*ncic(i,k)* & + gamma_mg(pgam(k) + 4._mg_pr)/(qcic(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)))**(1._mg_pr/3._mg_pr) - else ! t(i,k) l. tmin_fice - cmel(i,k)=0._mg_pr - cmei(i,k)=cme(i,k) - end if +! lammin, 40 micron diameter max mean size + lammin = (pgam(k) + 1._mg_pr)/max_diam_drop + lammax = (pgam(k) + 1._mg_pr)/min_diam_drop + + if (lamc(k) .lt. lammin) then + lamc(k) = lammin + ncic(i,k) = 6._mg_pr*lamc(k)**3*qcic(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)/ & + (pi*rhow*gamma_mg(pgam(k) + 4._mg_pr)) + else if (lamc(k) .gt. lammax) then + lamc(k) = lammax + ncic(i,k) = 6._mg_pr*lamc(k)**3*qcic(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)/ & + (pi*rhow*gamma_mg(pgam(k) + 4._mg_pr)) + end if +! parameter to calculate droplet freezing + cdist1(k) = ncic(i,k)/gamma_mg(pgam(k) + 1._mg_pr) + else + lamc(k) = 0._mg_pr + cdist1(k) = 0._mg_pr + end if -!cms++ -! vapor deposition onto cloud ice - if( qv_on_qi ) then - dqsi = MAX(qv(i,k) - qvi, 0._mg_pr) - qvdep_qi(i,k) = max(min(prd-cme(i,k)-berg(i,k), dqsi/deltat*omsm),0._mg_pr) - end if -!cms-- +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! begin micropysical process calculations +!................................................................. +! autoconversion of cloud liquid water to rain +! formula from Khrouditnov and Kogan (2000) +! minimum qc of 1 x 10^-8 prevents floating point error + if (qcic(i,k) .ge. 1.e-8_mg_pr) then +! nprc is increase in rain number conc due to autoconversion +! nprc1 is decrease in cloud droplet conc due to autoconversion - else ! t(i,k) .ge. 273.15 - cmel(i,k)=cme(i,k) - cmei(i,k)=0._mg_pr - end if +! assume exponential sub-grid distribution of qc, resulting in additional +! factor related to qcvar below -!!$ else ! t(i,k) l. tmin_fice -!!$ cmel(i,k)=0._mg_pr -!!$ cmei(i,k)=cme(i,k) -!!$ end if +! prc(k) = gamma_mg(qcvar+2.47_mg_pr)/(gamma_mg(qcvar)*qcvar**2.47_mg_pr)*1350._mg_pr*qcic(i,k)**2.47_mg_pr* & + prc(k) = sfac1*1350._mg_pr*qcic(i,k)**2.47_mg_pr* & + (ncic(i,k)/1.e6_mg_pr*rho(i,k))**(-1.79_mg_pr) + nprc(k) = prc(k)/(4._mg_pr/3._mg_pr*pi*rhow* & + (25.e-6_mg_pr)**3) + nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k)) + else + prc(k)=0._mg_pr + nprc(k)=0._mg_pr + nprc1(k)=0._mg_pr + end if -!.............................................................. +! add autoconversion to precip from above to get provisional rain mixing +! ratio and number concentration (qric and nric) +! 0.45 m/s is fallspeed of new rain drop (80 micron diameter) -! for evaporation, evaporate liquid first, then cloud ice if -! ice is present + dum = 0.45_mg_pr + dum1 = 0.45_mg_pr - else ! cme(i,k) .lt. 0.) - - if (t(i,k) > 273.15_mg_pr) then - cmei(i,k)=0.0_mg_pr - cmel(i,k)=cme(i,k) - else - cmel(i,k)=max(cme(i,k),-qc(i,k)/deltat) - cmei(i,k)=min(cme(i,k)-cmel(i,k),0._mg_pr) - end if - - end if - -! evaporation should not exceed available water - if (cmel(i,k).lt.-qc(i,k)/deltat) & - cmel(i,k)=-qc(i,k)/deltat -! sublimation should not exceed available ice - if (cmei(i,k).lt.-qi(i,k)/deltat) & - cmei(i,k)=-qi(i,k)/deltat - -! limit cmel,cmei due for roundoff error - - cmel(i,k)=cmel(i,k)*omsm - cmei(i,k)=cmei(i,k)*omsm - - - if (qi(i,k).ge.qsmall.or.cmei(i,k)+berg(i,k).ge.qsmall) then - -!use number calculated outside this code -IF ( Nml%do_ice_nucl_wpdf ) THEN - - IF (act_choice .EQ. 1 ) THEN - if ( tmp5(i,k) .gt. 0._mg_pr ) then - dum2i(i,k) = crystal1(i,k)*cldm(i,k)/rho(i,k) - else - dum2i(i,k) = 0._mg_pr - end if - - ELSEIF (act_choice .EQ. 2 ) THEN - - dum2i(i,k) = crystal1(i,k)/rho(i,k) - END IF - -ELSE - dum2i(i,k) = min(0.005_mg_pr*exp(0.304_mg_pr*(273.15_mg_pr-t(i,k)))*1000._mg_pr,208.9e3_mg_pr) !cooper - -END IF - - else - dum2i(i,k)=0._mg_pr - end if - - - -!liquid activation done ouside - - IF (act_choice .EQ. 1 ) THEN - if ( tmp5(i,k) .gt. 0._mg_pr ) then - dum2l(i,k) = drop2(i,k) * cldm(i,k) - else - dum2l(i,k) = 0._mg_pr - end if - ELSEIF (act_choice .EQ. 2 ) THEN - dum2l(i,k) = drop2(i,k) - END IF - - - end do - end do - - - -!re-calculate cloud fraction -IF ( Nml%do_pdf_clouds .AND. ( Nml%super_ice_opt .EQ. 1 .OR. Nml%super_ice_opt .EQ. 2 ) ) THEN - - IF ( Nml%super_ice_opt .EQ. 1 ) THEN - - DO k=1,kdim - DO i= 1,idim - - ttmp = t(i,k) - - IF ( ttmp .LT. 233.15 .OR. ( ttmp .LE. 273.15 .AND. qc(i,k) + ( cmel(i,k) - berg(i,k) )/deltat .LT. 3.*Nml%qmin) ) THEN - eslt = polysvp_i(ttmp) - ELSE - eslt = polysvp_l(ttmp) - END IF - - qs_d = pfull(i,k) - d378*eslt - qs_d = max(qs_d,eslt) - - qs(i,k)=d622*eslt/qs_d - END DO - END DO - - - END IF - -IF ( Nml%super_ice_opt .EQ. 2 ) THEN - - DO k=1,kdim - DO i= 1,idim - - ttmp = t(i,k) - - - - IF ( ttmp .LT. 233.15 .OR. ( ttmp .LE. 273.15 .AND. qc(i,k) + ( cmel(i,k) - berg(i,k) )/deltat .LT. 3.*Nml%qmin) ) THEN - eslt = polysvp_i(ttmp) - tc=ttmp-tfreeze -!!! rhi=MIN( max_super_ice , 0.000195*tc**2+0.00266*tc+1.005) - rhi = 0.000195*tc**2+0.00266*tc+1.005 - ELSE - eslt = polysvp_l(ttmp) - - rhi = 1. - END IF - - qs_d = pfull(i,k) - d378*eslt - qs_d = max(qs_d,eslt) - - qs(i,k)= rhi * d622*eslt/qs_d - END DO - END DO - - - END IF - - -qtot = qv_in+qc_in+qi_in - -IF ( Nml%pdf_org ) call error_mesg ( 'morrison_gettelman_microp', & - 'ERROR 1 simple_pdf ', FATAL) - -CALL simple_pdf( j, idim, jdim, kdim, Nml%qmin, & - qa0, & -!RSH qtot, qv_in, & - qtot, & - qs, gamma, & - Nml%qthalfwidth, Nml%betaP, & - inv_dtcloud, & -!inout - SA_0, & -! SA, qa_upd, & -!RSH tmp5, & -!RSH dcond_ls_tem, & -!diag - n_diag_4d, & - diag_4d, & !diag arr !! - diag_id, & - diag_pt, & - SA, qa_upd ) -!RSH diag_pt, & -!debug -!RSH Nml%debugo, otun, & -!RSH Nml%isamp,Nml%jsamp, Nml%ksamp ) - - - - - - - do k=1,kdim - do i=1,idim - cldm(i,k)=max(qa_upd(i,k),mincld) - end do - end do - - - -END IF - - - - - - - do i=1,idim - ltrue(i)=0 - do k=1,kdim -! hm add 3/19/07 skip microphysical calculations if no cloud water - - if (qc(i,k).ge.qsmall.or.qi(i,k).ge.qsmall.or.cmel(i,k).ge.qsmall.or.cmei(i,k).ge.qsmall.or.qvdep_qi(i,k).ge.qsmall) ltrue(i)=1 -!cms also skip if total water amount is negative anywhere within the column - if ( qc(i,k) + qi(i,k) + qv(i,k) .lt. -1.e-9 .OR. qv(i,k) .lt. -1.e-9 ) then - ltrue(i)=0 - nrefuse = nrefuse + 1 - end if - - - end do - end do - - -! assign number of sub-steps to iter -! use 2 sub-steps, following tests described in Morrison and Gettelman, 2007, J. Clim. - iter = 2 - -! get sub-step time step - deltat=deltat/real(iter) - - - - -!!!! skip calculations if no cloud water - - i_loop_1: do i=1,idim - - if (ltrue(i).eq.0) then - do k=1,kdim - tlat(i,k)=0._mg_pr - qvlat(i,k)=0._mg_pr - qctend(i,k)=0._mg_pr - qitend(i,k)=0._mg_pr - qnitend(i,k)=0._mg_pr - qrtend(i,k)=0._mg_pr - nctend(i,k)=0._mg_pr - nitend(i,k)=0._mg_pr - nrtend(i,k)=0._mg_pr - nstend(i,k)=0._mg_pr - prect(i)=0._mg_pr - preci(i)=0._mg_pr - qniic(i,k)=0._mg_pr - qric(i,k)=0._mg_pr - nsic(i,k)=0._mg_pr - nric(i,k)=0._mg_pr - - ! hm add 9/5/07 - rainrt(i,k)=0._mg_pr - !cms for calc. rain3d, snow3d - atotrt(i,k)=0._mg_pr - asnowrt(i,k)=0._mg_pr - end do - goto 300 - end if - - - - - -!!!!!!!!! begin sub-step!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!..................................................................................................... - iter_loop: do it=1,iter - - do k=1,kdim - -! initialize sub-step microphysical tendencies - - tlat(i,k)=0._mg_pr - qvlat(i,k)=0._mg_pr - qctend(i,k)=0._mg_pr - qitend(i,k)=0._mg_pr - qnitend(i,k)=0._mg_pr - qrtend(i,k)=0._mg_pr - nctend(i,k)=0._mg_pr - nitend(i,k)=0._mg_pr - nrtend(i,k)=0._mg_pr - nstend(i,k)=0._mg_pr - -! initialize diagnostic precipitation to zero - - qniic(i,k)=0._mg_pr - qric(i,k)=0._mg_pr - nsic(i,k)=0._mg_pr - nric(i,k)=0._mg_pr - - - - -!!$! hm add, initialize variables for trop_mozart -!!$ -!!$ nevapr1(i,k) = 0._mg_pr -!!$ evapsnow1(i,k) = 0._mg_pr -!!$ prain1(i,k) = 0._mg_pr -!!$ prodsnow1(i,k) = 0._mg_pr -!!$ cmeout1(i,k) = 0._mg_pr - - ! hm, add 9/5/07 - - rainrt(i,k)=0._mg_pr - atotrt(i,k)=0._mg_pr - asnowrt(i,k)=0._mg_pr - - end do - -! begin new i,k loop, calculate new cldmax after adjustment to cldm above - -! initialize vertically-integrated rain and snow tendencies - - qrtot = 0._mg_pr - nrtot = 0._mg_pr - qstot = 0._mg_pr - nstot = 0._mg_pr - -! initialize precip at surface - - prect(i)=0._mg_pr - preci(i)=0._mg_pr - - large_k_loop_in_iter: do k=1,kdim - - -! set cwml and cwmi to current qc and qi - - cwml(i,k)=qc(i,k) - cwmi(i,k)=qi(i,k) - -! initialize precip fallspeeds to zero - - ums(k)=0._mg_pr - uns(k)=0._mg_pr - umr(k)=0._mg_pr - unr(k)=0._mg_pr - - -! initialize tendencies due to Tiedtke "erosion" - nerosi(k) = 0._mg_pr - nerosc(k) = 0._mg_pr - - -! calculate precip fraction based on maximum overlap assumption - - if (k.eq.1) then - cldmax(i,k)=cldm(i,k) - else -! hm add sep 6, 2006, if rain or snow mix ratio is smaller than -! threshold, then set cldmax to cloud fraction at current level - if (qric(i,k-1).ge.qsmall.or.qniic(i,k-1).ge.qsmall) then - cldmax(i,k)=max(cldmax(i,k-1),cldm(i,k)) - else - cldmax(i,k)=cldm(i,k) - end if - end if - - -!should this be behind the next block (scaling)? -! decrease in number concentration due to sublimation/evap -! divide by cloud fraction to get in-cloud decrease -! don't reduce Nc due to bergeron process ????? - - nsubi(k)= 0._mg_pr - nsubc(k)=0._mg_pr - - if ( do_nevap ) then - if (cmei(i,k) < 0._mg_pr ) then !!!.AND. qi(i,k) .ge. qsmall ) then !cms added and - !nsubi(k)=cmei(i,k)/qi(i,k)*ni(i,k)/cldm(i,k) - nsubi(k)=cmei(i,k)/max(qi(i,k),qsmall)*ni(i,k)/cldm(i,k) - else - nsubi(k)=0._mg_pr - end if - if (cmel(i,k) < 0._mg_pr ) then !!! .AND. qc(i,k) .ge. qsmall ) then - ! nsubc(k)=cmel(i,k)/qc(i,k)*nc(i,k)/cldm(i,k) - nsubc(k)=cmel(i,k)/max(qc(i,k),qsmall)*nc(i,k)/cldm(i,k) - else - nsubc(k)=0._mg_pr - end if - end if - -!decrease in number conc. due to Tiedtke "erosion" - - - nerosi(k) = 0._mg_pr - nerosc(k) = 0._mg_pr - - if ( do_morrison_gettelman_eros ) then - IF ( qi(i,k) .ge. qsmall ) THEN - nerosi(k) = D_eros_i(i,k)/qi(i,k)*ni(i,k)/cldm(i,k) - END IF - IF ( qc(i,k) .ge. qsmall ) THEN - nerosc(k) = D_eros_l(i,k)/qc(i,k)*nc(i,k)/cldm(i,k) - END IF - end if - - -!c............................................................................ -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! obtain in-cloud values of cloud water/ice mixing ratios and number concentrations -! for microphysical process calculations -! units are kg/kg for mixing ratio, 1/kg for number conc - -! limit in-cloud values to 0.005 kg/kg - - - qcic(i,k)=min(cwml(i,k)/cldm(i,k), in_cloud_limit) - qiic(i,k)=min(cwmi(i,k)/cldm(i,k), in_cloud_limit) - ncic(i,k)=max(nc(i,k)/cldm(i,k),0._mg_pr) - niic(i,k)=max(ni(i,k)/cldm(i,k),0._mg_pr) - - - - - if (qc(i,k)+(cmel(i,k)+D_eros_l(i,k)-berg(i,k))*deltat.lt.qsmall) then - qcic(i,k)=0._mg_pr - ncic(i,k)=0._mg_pr - - if (qc(i,k)+(cmel(i,k)+D_eros_l(i,k)-berg(i,k))*deltat.lt.0._mg_pr) then - - if (cmel(i,k).lt.0._mg_pr) then - -!++ first only scale cmel, d_eros - - dum=-cmel(i,k)-D_eros_l(i,k) - - if (dum .gt. 1.e-30) then - dum3 = qc(i,k)/deltat/dum*omsm - else - dum3 = 0._mg_pr - end if - - - cmel(i,k)= dum3 * cmel(i,k) - D_eros_l(i,k)= dum3 * D_eros_l(i,k) - -!-- - - dum=-cmel(i,k)-D_eros_l(i,k)+berg(i,k) - if (dum .gt. 1.e-30) then - dum3 = qc(i,k)/deltat/dum*omsm - else - dum3 = 0._mg_pr - end if - - - cmel(i,k)= dum3 * cmel(i,k) - D_eros_l(i,k)= dum3 * D_eros_l(i,k) - berg(i,k)= dum3 * berg(i,k) - else - - dum=-D_eros_l(i,k)+berg(i,k) - ! berg(i,k)=qc(i,k)/deltat*omsm - - - if (dum .gt. 1.e-30) then - dum3 = ( qc(i,k)/deltat + cmel(i,k) ) / dum * omsm - else - dum3 = 0._mg_pr - end if - - - D_eros_l(i,k)=D_eros_l(i,k)* dum3 - berg(i,k)=berg(i,k) * dum3 - - - end if - - - - - end if - end if - - if (qi(i,k)+(cmei(i,k)+D_eros_i(i,k)+berg(i,k)+qvdep_qi(i,k))*deltat.lt.qsmall) then - qiic(i,k)=0._mg_pr - niic(i,k)=0._mg_pr - if (qi(i,k)+(cmei(i,k)+berg(i,k)+D_eros_i(i,k)+qvdep_qi(i,k))*deltat.lt.0._mg_pr) then - - if (cmei(i,k).lt.0._mg_pr) then - - dum = - cmei(i,k) - D_eros_i(i,k) - - - if (dum .gt. 1.e-30) then - dum3 = ( qi(i,k)/deltat + berg(i,k) + qvdep_qi(i,k) ) / dum * omsm - else - dum3 = 0._mg_pr - end if - - - - cmei(i,k) = dum3 * cmei(i,k) - D_eros_i(i,k) = dum3 * D_eros_i(i,k) - - - else - dum = - D_eros_i(i,k) - - if (dum .gt. 1.e-30) then - dum3 = ( qi(i,k)/deltat + cmei(i,k) + berg(i,k) + qvdep_qi(i,k) ) / dum * omsm - else - dum3 = 0. - end if - - - - - D_eros_i(i,k) = dum3 * D_eros_i(i,k) - - end if - - end if - end if - -! add to cme output - -!cms cmeout1(i,k) = cmeout1(i,k)+cmel(i,k)+cmei(i,k) - - - - - - - -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - -! ice nucleation -! calculate ice nucleation if cloud ice is present and T < -5 C - - if (qiic(i,k).ge.qsmall.and.t(i,k).lt.268.15_mg_pr) then - - IF ( act_choice .EQ. 1 ) THEN - nnuccd(k)=(dum2i(i,k)-ni(i,k)/cldm(i,k))/deltat*cldm(i,k) - nnuccd(k)=max(nnuccd(k),0._mg_pr) -ELSE IF ( act_choice .EQ. 2 ) THEN - - nnuccd(k) = max(tmp5(i,k),0.) * dum2i(i,k) /deltat - -END IF - nimax = dum2i(i,k)*cldm(i,k) - else - nnuccd(k)=0._mg_pr - nimax = 0._mg_pr - end if - -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! droplet activation -! calculate potential for droplet activation if cloud water is present - - - if (qcic(i,k).ge.qsmall) then - - - IF ( act_choice .EQ. 1 ) THEN -! assume aerosols already activated are equal number of existing droplets for simplicity -! multiply by cloud fraction to obtain grid-average tendency - npccn(k) = (dum2l(i,k)-nc(i,k)/cldm(i,k))/deltat*cldm(i,k) - - - - -! make sure number activated > 0 - npccn(k) = max(0._mg_pr,npccn(k)) - - - ELSE IF ( act_choice .EQ. 2 ) THEN -!tmp5: A_dt * (1.-qabar) where A_dt = A*dt , A source rate -! Eq. 7 of Yi's 2007 paper -!dum2l has already been multiplied by 1.e6/airdens(i,k) - - npccn(k) = max(tmp5(i,k),0.) * dum2l(i,k) /deltat - - END IF - - ncmax = dum2l(i,k)*cldm(i,k) - else - npccn(k)=0._mg_pr - ncmax = 0._mg_pr - end if - -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! get size distribution parameters based on in-cloud cloud water/ice -! these calculations also ensure consistency between number and mixing ratio -!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - - -!...................................................................... -! cloud ice - - if (qiic(i,k).ge.qsmall) then - -! add upper limit to in-cloud number concentration to prevent numerical error - niic(i,k)=min(niic(i,k),qiic(i,k)*1.e20_mg_pr) - - lami(k) = (gamma_mg(1._mg_pr+di_mg)*ci_mg* & - niic(i,k)/qiic(i,k))**(1._mg_pr/di_mg) - n0i(k) = niic(i,k)*lami(k) - -! check for slope - - lammax = 1._mg_pr/min_diam_ice - - lammin = 1._mg_pr/(2._mg_pr*dcs) - -! adjust vars - - if (lami(k).lt.lammin) then - - lami(k) = lammin - n0i(k) = lami(k)**(di_mg+1._mg_pr)*qiic(i,k)/(ci_mg*gamma_mg(1._mg_pr+di_mg)) - niic(i,k) = n0i(k)/lami(k) - else if (lami(k).gt.lammax) then - lami(k) = lammax - n0i(k) = lami(k)**(di_mg+1._mg_pr)*qiic(i,k)/(ci_mg*gamma_mg(1._mg_pr+di_mg)) - niic(i,k) = n0i(k)/lami(k) - end if - - else - lami(k) = 0._mg_pr - n0i(k) = 0._mg_pr - end if - - if (qcic(i,k).ge.qsmall) then - -! add upper limit to in-cloud number concentration to prevent numerical error - ncic(i,k)=min(ncic(i,k),qcic(i,k)*1.e20_mg_pr) - -! get pgam from fit to observations of martin et al. 1994 - -!RSH BUGFIX email of 6/8/10 -! pgam(k)=0.0005714_mg_pr*(ncic(i,k)/1.e6_mg_pr/rho(i,k))+0.2714_mg_pr - pgam(k)=0.0005714_mg_pr*(ncic(i,k)/1.e6_mg_pr*rho(i,k))+0.2714_mg_pr - pgam(k)=1._mg_pr/(pgam(k)**2)-1._mg_pr - pgam(k)=max(pgam(k),2._mg_pr) - pgam(k)=min(pgam(k),15._mg_pr) - -! calculate lamc - - lamc(k) = (pi/6._mg_pr*rhow*ncic(i,k)*gamma_mg(pgam(k)+4._mg_pr)/ & - (qcic(i,k)*gamma_mg(pgam(k)+1._mg_pr)))**(1._mg_pr/3._mg_pr) - -! lammin, 40 micron diameter max mean size - - lammin = (pgam(k)+1._mg_pr)/max_diam_drop - lammax = (pgam(k)+1._mg_pr)/min_diam_drop - - - - if (lamc(k).lt.lammin) then - lamc(k) = lammin - ncic(i,k) = 6._mg_pr*lamc(k)**3*qcic(i,k)* & - gamma_mg(pgam(k)+1._mg_pr)/ & - (pi*rhow*gamma_mg(pgam(k)+4._mg_pr)) - else if (lamc(k).gt.lammax) then - lamc(k) = lammax - ncic(i,k) = 6._mg_pr*lamc(k)**3*qcic(i,k)* & - gamma_mg(pgam(k)+1._mg_pr)/ & - (pi*rhow*gamma_mg(pgam(k)+4._mg_pr)) - end if - -! parameter to calculate droplet freezing - - cdist1(k) = ncic(i,k)/gamma_mg(pgam(k)+1._mg_pr) - - else - lamc(k) = 0._mg_pr - cdist1(k) = 0._mg_pr - end if - -!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! begin micropysical process calculations -!................................................................. -! autoconversion of cloud liquid water to rain -! formula from Khrouditnov and Kogan (2000) -! minimum qc of 1 x 10^-8 prevents floating point error - - - if (qcic(i,k).ge.1.e-8_mg_pr) then - - - -! nprc is increase in rain number conc due to autoconversion -! nprc1 is decrease in cloud droplet conc due to autoconversion - -! assume exponential sub-grid distribution of qc, resulting in additional -! factor related to qcvar below - -! prc(k) = gamma_mg(qcvar+2.47_mg_pr)/(gamma_mg(qcvar)*qcvar**2.47_mg_pr)*1350._mg_pr*qcic(i,k)**2.47_mg_pr* & - prc(k) = sfac1 *1350._mg_pr*qcic(i,k)**2.47_mg_pr* & - (ncic(i,k)/1.e6_mg_pr*rho(i,k))**(-1.79_mg_pr) - nprc(k) = prc(k)/(4._mg_pr/3._mg_pr*pi*rhow*(25.e-6_mg_pr)**3) - nprc1(k) = prc(k)/(qcic(i,k)/ncic(i,k)) - - - - - - else - prc(k)=0._mg_pr - nprc(k)=0._mg_pr - nprc1(k)=0._mg_pr - end if - - - - -! add autoconversion to precip from above to get provisional rain mixing ratio -! and number concentration (qric and nric) - -! 0.45 m/s is fallspeed of new rain drop (80 micron diameter) - - dum=0.45_mg_pr - dum1=0.45_mg_pr - -! hm modify 6/12 - if (k.eq.1) then - qric(i,k)=prc(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum - nric(i,k)=nprc(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum - else - if (qric(i,k-1).ge.qsmall) then - dum=umr(k-1) - dum1=unr(k-1) - end if - -! hm add 4/17/06, no autoconversion of rain number if rain/snow falling from above -! this assumes that new drizzle drops formed by autoconversion are rapidly collected -! by the existing rain/snow particles from above - - if (qric(i,k-1).ge.1.e-9_mg_pr.or.qniic(i,k-1).ge.1.e-9_mg_pr) then - nprc(k)=0._mg_pr - end if - - qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*((pra(k-1)+prc(k))*cldm(i,k)+(pre(k-1)-pracs(k-1)-mnuccr(k-1))*cldmax(i,k))))& - /(dum*rho(i,k)*cldmax(i,k)) - nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*(nprc(k)*cldm(i,k)+(nsubr(k-1)-npracs(k-1)-nnuccr(k-1)+nragg(k-1))*cldmax(i,k))))& - /(dum1*rho(i,k)*cldmax(i,k)) - - - end if - - -IF ( .NOT. one_ice ) THEN - -!!do_auto_conv_ice_if: if (t(i,k).le.273.15_mg_pr.and.qiic(i,k).ge.1.e-8_mg_pr ) then - do_auto_conv_ice_if: if (t(i,k).le.273.15_mg_pr.and.qiic(i,k).ge.qsmall) then - - IF ( auto_conv_ice_choice .EQ. 1 ) THEN -!....................................................................... -! Autoconversion of cloud ice to snow -! si8milar to Ferrier (1994) - -! note: assumes autoconversion timescale of 180 sec - - nprci(k) = n0i(k)/(lami(k)*auto_conv_time_scale)*exp(-lami(k)*dcs) - - prci(k) = pi*rhoi*n0i(k)/(6._mg_pr*auto_conv_time_scale)* & - (dcs**3/lami(k)+3._mg_pr*dcs**2/lami(k)**2+ & - 6._mg_pr*dcs/lami(k)**3+6._mg_pr/lami(k)**4)*exp(-lami(k)*dcs) - - - ELSE IF ( auto_conv_ice_choice .EQ. 2 ) THEN -!....................................................................... -! AUTOCONVERSION OF CLOUD ICE TO SNOW -! FOLLOWING HARRINGTON ET AL. (1995) WITH MODIFICATION -! HERE IT IS ASSUMED THAT AUTOCONVERSION CAN ONLY OCCUR WHEN THE -! ICE IS GROWING, I.E. IN CONDITIONS OF ICE SUPERSATURATION - -!!$ call error_mesg ( 'morrison_gettelman', & -!!$ 'auto_conv_ice_choice ', FATAL) - prci(k)=0._mg_pr - nprci(k)=0._mg_pr - - ! IF (QI3D(K).GE.1.E-8 .AND.QVQVSI(K).GE.1.) THEN - - esi(i,k)=polysvp_i(t(i,k)) - qvi=0.622_mg_pr*esi(i,k)/(pfull(i,k)-d378*esi(i,k)) - - dqsidt = xxls*qvi/(rv*t(i,k)**2) - abi(i,k) = 1._mg_pr+dqsidt*xxls/cpp - - - IF ( Q(i,k)-QVI .GT. qsmall) THEN - -! COFFI = 2./LAMI(K) -! IF (COFFI.GE.DCS) THEN - - NPRCI(K) = 4./(DCS*RHOI)*(Q(i,k)-QVI)*rho(i,k) & - *n0i(K)*EXP(-lami(K)*dcs)*dv(i,k)/abi(i,k) - NPRCI(K) = MIN(NPRCI(K),niic(i,K)/deltat) - PRCI(K) = MIN(PI*RHOI*DCS**3/6.*NPRCI(K), qiic(i,k)/deltat) - - -! END IF - END IF - - ELSE IF ( auto_conv_ice_choice .EQ. 3 ) THEN -!....................................................................... -! Autoconversion of cloud ice to snow -! si8milar to Ferrier (1994) - -! note: assumes autoconversion timescale of 180 sec - - IF ( lami(k) .LT. 1._mg_pr/autoconv_ice_thr ) THEN - - nprci(k) = n0i(k)/(lami(k)*auto_conv_time_scale)*exp(-lami(k)*dcs) - - prci(k) = pi*rhoi*n0i(k)/(6._mg_pr*auto_conv_time_scale)* & - (dcs**3/lami(k)+3._mg_pr*dcs**2/lami(k)**2+ & - 6._mg_pr*dcs/lami(k)**3+6._mg_pr/lami(k)**4)*exp(-lami(k)*dcs) - - END IF - - - ELSE IF ( auto_conv_ice_choice .EQ. 4 ) THEN -!ferrier, 1994, 4.54 - - dum = 1._mg_pr/autoconv_ice_thr - - IF ( lami(k) .LT. dum ) THEN - nprci(k) = niic(i,K)/deltat * ( 1._mg_pr - ( lami(k) / dum )**3 ) - prci(k) = qiic(i,k) /deltat * ( 1._mg_pr - ( lami(k) / dum )**3 )/ ( 1._mg_pr + ( lami(k) / dum )**3 ) - - - END IF - - - ELSE IF ( auto_conv_ice_choice .EQ. 5 ) THEN -!....................................................................... -! Autoconversion of cloud ice to snow -! si8milar to Ferrier (1994) - -! note: assumes autoconversion timescale of 180 sec - - IF ( qiic(i,k) .GE. auto_conv_m_thresh ) THEN - - nprci(k) = n0i(k)/(lami(k)*auto_conv_time_scale)*exp(-lami(k)*dcs) - - prci(k) = pi*rhoi*n0i(k)/(6._mg_pr*auto_conv_time_scale)* & - (dcs**3/lami(k)+3._mg_pr*dcs**2/lami(k)**2+ & - 6._mg_pr*dcs/lami(k)**3+6._mg_pr/lami(k)**4)*exp(-lami(k)*dcs) - - END IF - - END IF - - -else ! do_auto_conv_ice_if - - prci(k)=0._mg_pr - nprci(k)=0._mg_pr - -end if do_auto_conv_ice_if - -ELSE ! one_ice - prci(k)=0._mg_pr - nprci(k)=0._mg_pr - -END IF - - - -! add autoconversion to flux from level above to get provisional snow mixing ratio -! and number concentration (qniic and nsic) - - dum=(asn(i,k)*dcs**bs) - dum1=(asn(i,k)*dcs**bs) - - if (k.eq.1) then - qniic(i,k)=prci(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum - nsic(i,k)=nprci(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum - else - - if (qniic(i,k-1).ge.qsmall) then - dum=ums(k-1) - dum1=uns(k-1) - end if - -!++ag fixed snow bug (from Morrison nov.27.2007) -! qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ & -! (rho(i,k)*dz(i,k)*(prci(k)*cldm(i,k)+(prai(k-1)+psacws(k-1)+prci(k-1)+bergs(k-1))*cldmax(i,k))))& -! /(dum*rho(i,k)*cldmax(i,k)) - - qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*((prci(k)+prai(k-1)+psacws(k-1)+bergs(k-1))*cldm(i,k)+(prds(k-1)+ & - pracs(k-1)+mnuccr(k-1))*cldmax(i,k))))& - /(dum*rho(i,k)*cldmax(i,k)) -!--ag - - - - - - nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*(nprci(k)*cldm(i,k)+(nsubs(k-1)+nsagg(k-1)+nnuccr(k-1))*cldmax(i,k))))& - /(dum1*rho(i,k)*cldmax(i,k)) - - - - - end if - -! if precip mix ratio is zero so should number concentration - - if (qniic(i,k).lt.qsmall) then - qniic(i,k)=0._mg_pr - nsic(i,k)=0._mg_pr - end if - - if (qric(i,k).lt.qsmall) then - qric(i,k)=0._mg_pr - nric(i,k)=0._mg_pr - end if - -! make sure number concentration is a positive number to avoid -! taking root of negative later - - nric(i,k)=max(nric(i,k),0._mg_pr) - nsic(i,k)=max(nsic(i,k),0._mg_pr) - -!....................................................................... -! get size distribution parameters for precip -!...................................................................... -! rain - - if (qric(i,k).ge.qsmall) then - lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._mg_pr/3._mg_pr) - n0r(k) = nric(i,k)*lamr(k) - -! check for slope - - lammax = 1._mg_pr/20.e-6_mg_pr - - lammin = 1._mg_pr/500.e-6_mg_pr - -! adjust vars - - if (lamr(k).lt.lammin) then - - lamr(k) = lammin - - n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) - nric(i,k) = n0r(k)/lamr(k) - else if (lamr(k).gt.lammax) then - lamr(k) = lammax - n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) - nric(i,k) = n0r(k)/lamr(k) - end if - -! provisional rain number and mass weighted mean fallspeed (m/s) - unr(k) = min(arn(i,k)*gamma_mg(1._mg_pr+br)/lamr(k)**br,9.1_mg_pr) - umr(k) = min(arn(i,k)*gamma_mg(4._mg_pr+br)/(6._mg_pr*lamr(k)**br),9.1_mg_pr) - - else - lamr(k) = 0._mg_pr - n0r(k) = 0._mg_pr - umr(k) = 0._mg_pr - unr(k) = 0._mg_pr - end if - -!...................................................................... -! snow - - if (qniic(i,k).ge.qsmall) then - lams(k) = (gamma_mg(1._mg_pr+ds)*cs*nsic(i,k)/ & - qniic(i,k))**(1._mg_pr/ds) - n0s(k) = nsic(i,k)*lams(k) - - - - -! check for slope - - - lammax = 1._mg_pr/min_diam_ice - - lammin = 1._mg_pr/2000.e-6_mg_pr - -! adjust vars - - if (lams(k).lt.lammin) then - lams(k) = lammin - n0s(k) = lams(k)**(ds+1._mg_pr)*qniic(i,k)/(cs*gamma_mg(1._mg_pr+ds)) - nsic(i,k) = n0s(k)/lams(k) - - else if (lams(k).gt.lammax) then - lams(k) = lammax - n0s(k) = lams(k)**(ds+1._mg_pr)*qniic(i,k)/(cs*gamma_mg(1._mg_pr+ds)) - nsic(i,k) = n0s(k)/lams(k) - end if - -! provisional snow number and mass weighted mean fallspeed (m/s) - ums(k) = min(asn(i,k)*gamma_mg(4._mg_pr+bs)/(6._mg_pr*lams(k)**bs),max_vt_snow) - uns(k) = min(asn(i,k)*gamma_mg(1._mg_pr+bs)/lams(k)**bs,max_vt_snow) - - else - lams(k) = 0._mg_pr - n0s(k) = 0._mg_pr - ums(k) = 0._mg_pr - uns(k) = 0._mg_pr - end if - - - -!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - -! heterogeneous freezing of cloud water - - if (qcic(i,k).ge.qsmall ) then - - mnuccc(k) = 0._mg_pr - nnuccc(k) = 0._mg_pr -!contact freezing - IF ( do_contact_frz ) THEN - tc=ttmp-tfreeze - - IF (tc .LE. -3 .AND. tc .GE. -40. ) THEN - IF ( rbar_dust(i,k) .GT. 0._mg_pr ) THEN - -! mean free path - - dum = 7.37_mg_pr*t(i,k)/(288._mg_pr*10._mg_pr*pfull(i,k))/100._mg_pr - -! effective diffusivity based on Brownian collection - - dap = 4._mg_pr*pi*1.38e-23_mg_pr*t(i,k)*(1._mg_pr+dum/rbar_dust(i,k))/ & - (6._mg_pr*pi*rbar_dust(i,k)*mu(i,k)) - - - -! number of contact nucleii similar Young as in Liu et al. - -IF(n_contact_opt .eq. 1 ) THEN - NACNT = ndust(i,k)/rho(i,k) * (270.16_mg_pr -T(i,k)) ** 1.3 -ELSE IF (n_contact_opt .eq. 2 ) THEN -!similar Meyers et al., 1992, Eq. 2.6 - NACNT = ndust(i,k)/rho(i,k) * EXP(-2.8_mg_pr + 0.262_mg_pr * ( 273.15_mg_pr - T(i,k))) -END IF - - MNUCCC(K) = sfac3 * PI*PI/3.*RHOW*DAP*NACNT*EXP(LOG(CDIST1(K))+ & - LOG(GAMMA_mg(PGAM(K)+5.))-4.*LOG(LAMC(K))) - - NNUCCC(K) = 2.*PI*DAP*NACNT *CDIST1(K)* & - GAMMA_mg(PGAM(K)+2.)/ & - LAMC(K) - - - - - END IF - END IF - - END IF - - IF ( do_bigg_frz ) THEN -! immersion freezing (Bigg, 1953) - if ( t(i,k).lt.269.15_mg_pr .and. t(i,k).gt.limit_bigg_t ) then - - -! mnuccc(k) = gamma_mg(qcvar+2._mg_pr)/(gamma_mg(qcvar)*qcvar**2)* & - mnuccc(k) = mnuccc(k) + sfac2 * & - pi*pi/36._mg_pr*rhow* & - cdist1(k)*gamma_mg(7._mg_pr+pgam(k))* & -!RSH BUGFIX email 8/9/10 -! bimm*exp(aimm*(273.15_mg_pr-t(i,k)))/ & - bimm*(exp(aimm*(273.15_mg_pr-t(i,k))) -1._mg_pr)/ & - lamc(k)**3/lamc(k)**3 - - - -! nnuccc(k) = gamma_mg(qcvar+1._mg_pr)/(gamma_mg(qcvar)*qcvar)* & - nnuccc(k) = nnuccc(k) + sfac3 * & - pi/6._mg_pr*cdist1(k)*gamma_mg(pgam(k)+4._mg_pr) & - *bimm* & -!RSH BUGFIX email 8/9/10 -! exp(aimm*(273.15_mg_pr-t(i,k)))/lamc(k)**3 - (exp(aimm*(273.15_mg_pr-t(i,k)))-1._mg_pr)/lamc(k)**3 - - end if -END IF - -IF ( limit_droplet_freeze_opt .EQ. 1 ) THEN -! hm add 11/17/06 -! make sure number of droplets frozen does not exceed available ice nuclei concentration -! this prevents 'runaway' droplet freezing - - if (nnuccc(k).gt.nnuccd(k)/cldm(i,k)) then - dum=(nnuccd(k)/cldm(i,k))/nnuccc(k) -! scale mixing ratio of droplet freezing with limit - mnuccc(k)=mnuccc(k)*dum - nnuccc(k)=nnuccd(k)/cldm(i,k) - end if - -ELSE IF ( limit_droplet_freeze_opt .EQ. 2 ) THEN - - dum1 = nnuccc(k)*deltat - dum2 = ndust(i,k)/rho(i,k)/cldm(i,k) - - if (dum1.gt.dum2) then - dum=dum2/dum1 -! scale mixing ratio of droplet freezing with limit - mnuccc(k)=mnuccc(k)*dum - nnuccc(k)= nnuccc(k)*dum - !!!nnuccc(k)=nnuccd(k)/cldm(i,k) - end if - -END IF - else - mnuccc(k)=0._mg_pr - nnuccc(k)=0._mg_pr - end if - -!....................................................................... -! snow self-aggregation from passarelli, 1978, used by reisner, 1998 -! this is hard-wired for bs = 0.4 for now -! ignore self-collection of cloud ice - - if (qniic(i,k).ge.qsmall .and. t(i,k).le.273.15_mg_pr) then - nsagg(k) = -1108._mg_pr*asn(i,k)*Eii* & - pi**((1._mg_pr-bs)/3._mg_pr)*rhosn**((-2._mg_pr-bs)/3._mg_pr)*rho(i,k)** & - ((2._mg_pr+bs)/3._mg_pr)*qniic(i,k)**((2._mg_pr+bs)/3._mg_pr)* & - (nsic(i,k)*rho(i,k))**((4._mg_pr-bs)/3._mg_pr)/ & - (4._mg_pr*720._mg_pr*rho(i,k)) - else - nsagg(k)=0._mg_pr - end if - - - IF ( .NOT. one_ice ) THEN - -!....................................................................... -! accretion of cloud droplets onto snow/graupel -! here use continuous collection equation with -! simple gravitational collection kernel -! ignore collisions between droplets/cloud ice -! since minimum size ice particle for accretion is 50 - 150 micron - -! ignore collision of snow with droplets above freezing - - if (qniic(i,k).ge.qsmall .and. t(i,k).le.273.15_mg_pr .and. & - qcic(i,k).ge.qsmall) then - -! put in size dependent collection efficiency -! mean diameter of snow is area-weighted, since -! accretion is function of crystal geometric area -! collection efficiency is from stoke's law (Thompson et al. 2004) - - dc0 = (pgam(k)+1._mg_pr)/lamc(k) - ds0 = 1._mg_pr/lams(k) - dum = dc0*dc0*uns(k)*rhow/(9._mg_pr*mu(i,k)*ds0) - eci = dum*dum/((dum+0.4_mg_pr)*(dum+0.4_mg_pr)) - - eci = max(eci,0._mg_pr) - eci = min(eci,1._mg_pr) - - - -! no impact of sub-grid distribution of qc since psacws -! is linear in qc - - psacws(k) = pi/4._mg_pr*asn(i,k)*qcic(i,k)*rho(i,k)* & - n0s(k)*Eci*gamma_mg(bs+3._mg_pr)/ & - lams(k)**(bs+3._mg_pr) - npsacws(k) = pi/4._mg_pr*asn(i,k)*ncic(i,k)*rho(i,k)* & - n0s(k)*Eci*gamma_mg(bs+3._mg_pr)/ & - lams(k)**(bs+3._mg_pr) - else - psacws(k)=0._mg_pr - npsacws(k)=0._mg_pr - end if - - - psacws_o(k)=0._mg_pr - npsacws_o(k)=0._mg_pr - -ELSE !one_ice - - psacws_o(k)=0._mg_pr - npsacws_o(k)=0._mg_pr - - - IF ( lami(k) .gt. 1._mg_pr/50.e-6_mg_pr ) THEN !size - -! provisional snow number and mass weighted mean fallspeed (m/s) - ums(k) = min(asn(i,k)*gamma_mg(4._mg_pr+bs)/(6._mg_pr*lami(k)**bs),max_vt_snow) - uns(k) = min(asn(i,k)*gamma_mg(1._mg_pr+bs)/lami(k)**bs,max_vt_snow) - - qiic(i,k) = (rho(i,k-1)*ums(k-1)*qiic(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*((psacws_o(k-1))*cldm(i,k))))& - /(dum*rho(i,k)*cldmax(i,k)) - - if (qiic(i,k).ge.qsmall .and. t(i,k).le.273.15_mg_pr .and. & - qcic(i,k).ge.qsmall) then - -! put in size dependent collection efficiency -! mean diameter of snow is area-weighted, since -! accretion is function of crystal geometric area -! collection efficiency is from stoke's law (Thompson et al. 2004) - - dc0 = (pgam(k)+1._mg_pr)/lamc(k) - ds0 = 1._mg_pr/lami(k) - dum = dc0*dc0*uns(k)*rhow/(9._mg_pr*mu(i,k)*ds0) - eci = dum*dum/((dum+0.4_mg_pr)*(dum+0.4_mg_pr)) - - eci = max(eci,0._mg_pr) - eci = min(eci,1._mg_pr) - - - -! no impact of sub-grid distribution of qc since psacws -! is linear in qc - - psacws_o(k) = pi/4._mg_pr*asn(i,k)*qcic(i,k)*rho(i,k)* & - n0i(k)*Eci*gamma_mg(bs+3._mg_pr)/ & - lami(k)**(bs+3._mg_pr) - npsacws_o(k) = pi/4._mg_pr*asn(i,k)*ncic(i,k)*rho(i,k)* & - n0i(k)*Eci*gamma_mg(bs+3._mg_pr)/ & - lami(k)**(bs+3._mg_pr) - else - psacws_o(k)=0._mg_pr - npsacws_o(k)=0._mg_pr - end if - - - psacws(k)=0._mg_pr - npsacws(k)=0._mg_pr - - -END IF !size - -END IF !one_ice - - - - - -IF ( .NOT. one_ice ) THEN -!....................................................................... -! accretion of rain water by snow -! formula from ikawa and saito, 1991, used by reisner et al., 1998 - - if (qric(i,k).ge.1.e-8_mg_pr .and. qniic(i,k).ge.1.e-8_mg_pr .and. & - t(i,k).le.273.15_mg_pr) then - - pracs(k) = pi*pi*ecr*(((1.2_mg_pr*umr(k)-0.95_mg_pr*ums(k))**2+ & - 0.08_mg_pr*ums(k)*umr(k))**0.5_mg_pr*rhow*rho(i,k)* & - n0r(k)*n0s(k)* & - (5._mg_pr/(lamr(k)**6*lams(k))+ & - 2._mg_pr/(lamr(k)**5*lams(k)**2)+ & - 0.5_mg_pr/(lamr(k)**4*lams(k)**3))) - - npracs(k) = pi/2._mg_pr*rho(i,k)*ecr*(1.7_mg_pr*(unr(k)-uns(k))**2+ & - 0.3_mg_pr*unr(k)*uns(k))**0.5_mg_pr*n0r(k)*n0s(k)* & - (1._mg_pr/(lamr(k)**3*lams(k))+ & - 1._mg_pr/(lamr(k)**2*lams(k)**2)+ & - 1._mg_pr/(lamr(k)*lams(k)**3)) - - else - pracs(k)=0._mg_pr - npracs(k)=0._mg_pr - end if - -ELSE - - pracs(k)=0._mg_pr - npracs(k)=0._mg_pr - -END IF - - -IF ( .NOT. one_ice ) THEN -!....................................................................... -! heterogeneous freezing of rain drops -! follows from Bigg (1953) - - if (t(i,k).lt.269.15_mg_pr .and. qric(i,k).ge.qsmall) then - - mnuccr(k) = 20._mg_pr*pi*pi*rhow*nric(i,k)*bimm* & -!RSH BUGFIX email 8/9/10 -! exp(aimm*(273.15_mg_pr-t(i,k)))/lamr(k)**3 & - (exp(aimm*(273.15_mg_pr-t(i,k)))-1._mg_pr)/lamr(k)**3 & - /lamr(k)**3 - - nnuccr(k) = pi*nric(i,k)*bimm* & -!RSH BUGFIX email 8/9/10 -! exp(aimm*(273.15_mg_pr-t(i,k)))/lamr(k)**3 - (exp(aimm*(273.15_mg_pr-t(i,k)))-1._mg_pr)/lamr(k)**3 - else - mnuccr(k)=0._mg_pr - nnuccr(k)=0._mg_pr - end if - -ELSE - mnuccr(k)=0._mg_pr - nnuccr(k)=0._mg_pr - -END IF - -!....................................................................... -! accretion of cloud liquid water by rain -! formula from Khrouditnov and Kogan (2000) -! gravitational collection kernel, droplet fall speed neglected - - if (qric(i,k).ge.qsmall .and. qcic(i,k).ge.qsmall) then - -! include sub-grid distribution of cloud water - - - - ! pra(k) = gamma_mg(qcvar+1.15_mg_pr)/(gamma_mg(qcvar)*qcvar**1.15_mg_pr) * & - pra(k) = sfac4 * & - 67._mg_pr*(qcic(i,k)*qric(i,k))**1.15_mg_pr - npra(k) = pra(k)/(qcic(i,k)/ncic(i,k)) - - else - pra(k)=0._mg_pr - npra(k)=0._mg_pr - end if - -!....................................................................... -! Self-collection of rain drops -! from Beheng(1994) - - if (qric(i,k).ge.qsmall) then - nragg(k) = -8._mg_pr*nric(i,k)*qric(i,k)*rho(i,k) - else - nragg(k)=0._mg_pr - end if - -!....................................................................... -! Accretion of cloud ice by snow -! For this calculation, it is assumed that the Vs >> Vi -! and Ds >> Di for continuous collection - - IF ( .NOT. one_ice ) THEN - - if (qniic(i,k).ge.qsmall.and.qiic(i,k).ge.qsmall & - .and.t(i,k).le.273.15_mg_pr) then - prai(k) = pi/4._mg_pr*asn(i,k)*qiic(i,k)*rho(i,k)* & - n0s(k)*Eii*gamma_mg(bs+3._mg_pr)/ & - lams(k)**(bs+3._mg_pr) - nprai(k) = pi/4._mg_pr*asn(i,k)*niic(i,k)* & - rho(i,k)*n0s(k)*Eii*gamma_mg(bs+3._mg_pr)/ & - lams(k)**(bs+3._mg_pr) - else - prai(k)=0._mg_pr - nprai(k)=0._mg_pr - end if - -ELSE - - prai(k)=0._mg_pr - nprai(k)=0._mg_pr - -END IF - -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! calculate evaporation/sublimation of rain and snow -! note: evaporation/sublimation occurs only in cloud-free portion of grid cell -! in-cloud condensation/deposition of rain and snow is neglected -! except for transfer of cloud water to snow through bergeron process - -! initialize evap/sub tendncies - pre(k)=0._mg_pr - prds(k)=0._mg_pr - -! evaporation of rain -! only calculate if there is some precip fraction > cloud fraction - - if (qcic(i,k)+qiic(i,k).lt.1.e-6_mg_pr.or.cldmax(i,k).gt.cldm(i,k)) then -!cms2008-11-27 if (qcic(i,k)+qiic(i,k).lt.qsmall.or.cldmax(i,k).gt.cldm(i,k)) then - - -! set temporary cloud fraction to zero if cloud water + ice is very small -! this will ensure that evaporation/sublimation of precip occurs over -! entire grid cell, since min cloud fraction is specified otherwise - - - !cms2008-11-27 if (qcic(i,k)+qiic(i,k).lt.qsmall) then - - if (qcic(i,k)+qiic(i,k).lt.1.e-6_mg_pr) then - dum=0._mg_pr - else - dum=cldm(i,k) - end if - - - - -! esn=estblf(t(i,k)) - - - ttmp=t(i,k) - - -!! CALL lookup_es(ttmp,esn) - - - - - -! recalculate saturation vapor pressure for liquid and ice - esl(i,k)=polysvp_l(t(i,k)) - esi(i,k)=polysvp_i(t(i,k)) - - - esn=min(esi(i,k), esl(i,k)) - - qsn=min(epsqs*esn/(pfull(i,k)-(1._mg_pr-epsqs)*esn),1._mg_pr) - - qsn=max(qsn,0._mg_pr) - - -! MAKE SURE ICE SATURATION DOESN'T EXCEED WATER SAT. NEAR FREEZING - - IF (esi(i,k).GT.esl(i,k)) esi(i,k) = esl(i,k) - - -! calculate q for out-of-cloud region - qclr=(q(i,k)-dum*qsn)/(1._mg_pr-dum) - - if (qric(i,k).ge.qsmall) then - qvs=0.622_mg_pr*esl(i,k)/(pfull(i,k)- d378* esl(i,k)) - dqsdt = xxlv*qvs/(rv*t(i,k)**2) - ab = 1._mg_pr+dqsdt*xxlv/cpp - epsr = 2._mg_pr*pi*n0r(k)*rho(i,k)*Dv(i,k)* & - (f1r/(lamr(k)*lamr(k))+ & - f2r*(arn(i,k)*rho(i,k)/mu(i,k))**0.5_mg_pr* & - sc(i,k)**(1._mg_pr/3._mg_pr)*gamma_mg(5._mg_pr/2._mg_pr+br/2._mg_pr)/ & - (lamr(k)**(5._mg_pr/2._mg_pr+br/2._mg_pr))) - - pre(k) = epsr*(qclr-qvs)/ab - -! only evaporate in out-of-cloud region -! and distribute across cldmax - pre(k)=min(pre(k)*(cldmax(i,k)-dum),0._mg_pr) - pre(k)=pre(k)/cldmax(i,k) - end if - -IF ( .NOT. one_ice ) THEN -! sublimation of snow - if (qniic(i,k).ge.qsmall) then - qvi=0.622_mg_pr*esi(i,k)/(pfull(i,k)-d378*esi(i,k)) - dqsidt = xxls*qvi/(rv*t(i,k)**2) - abi(i,k) = 1._mg_pr+dqsidt*xxls/cpp - - -!++ - dumt1 = 2._mg_pr*pi*n0s(k)*rho(i,k)*Dv(i,k) - dumt2 = sc(i,k)**(1._mg_pr/3._mg_pr)*gamma_mg(5._mg_pr/2._mg_pr+bs/2._mg_pr)/ & - (lams(k)**(5._mg_pr/2._mg_pr+bs/2._mg_pr)) - - - -!-- - epss = 2._mg_pr*pi*n0s(k)*rho(i,k)*Dv(i,k)* & - (f1s/(lams(k)*lams(k))+ & - f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_mg_pr* & - sc(i,k)**(1._mg_pr/3._mg_pr)*gamma_mg(5._mg_pr/2._mg_pr+bs/2._mg_pr)/ & - (lams(k)**(5._mg_pr/2._mg_pr+bs/2._mg_pr))) - - - - prds(k) = epss*(qclr-qvi)/abi(i,k) - - -! only sublimate in out-of-cloud region and distribute over cldmax - prds(k)=min(prds(k)*(cldmax(i,k)-dum),0._mg_pr) - prds(k)=prds(k)/cldmax(i,k) - end if - -ELSE - prds(k)=0._mg_pr - - -END IF - - -! hm add 2/2/07, make sure RH not pushed above 100% -! get updated RH at end of time step based on cloud water/ice condensation/evap - - qtmp=q(i,k)-(D_eros_l(i,k)+D_eros_i(i,k)+cmel(i,k)+cmei(i,k)+ qvdep_qi(i,k)+(pre(k)+prds(k))*cldmax(i,k))*deltat - -!bug? 2/12/09 -!!$ ttmp=t(i,k)+((D_eros_l(i,k)+cmel(i,k)+pre(k)*cldmax(i,k))*xxlv+ & -!!$ (D_eros_i(i,k)+cmei(i,k)+prds(k))*cldmax(i,k)*xxls)*deltat/cpp - - ttmp=t(i,k)+((D_eros_l(i,k)+cmel(i,k)+pre(k)*cldmax(i,k))*xxlv+ & - (D_eros_i(i,k)+cmei(i,k)+ qvdep_qi(i,k) +prds(k)*cldmax(i,k))*xxls)*deltat/cpp - - - ttmp= MAX(ttmp,194._mg_pr) - - eslt=polysvp_l(ttmp) - esit=polysvp_i(ttmp) - esn=min(esit, eslt) - - - qsn=min(epsqs*esn/(pfull(i,k)-(1._mg_pr-epsqs)*esn),1._mg_pr) - qsn = max(qsn, 0._mg_pr) - -! modify precip evaporation rate if q > qsat - if (qtmp.gt.qsn ) then - if (pre(k)+prds(k).lt.-1.e-20) then - dum1=pre(k)/(pre(k)+prds(k)) -! recalculate q and t after cloud water cond but without precip evap - qtmp=q(i,k)-(D_eros_l(i,k)+D_eros_i(i,k)+cmel(i,k)+cmei(i,k)+ qvdep_qi(i,k))*deltat - -!bug 2/12/09 -!!$ ttmp=t(i,k)+(D_eros_l(i,k)+cmel(i,k)*xxlv+ & -!!$ D_eros_i(i,k)+cmei(i,k)*xxls)*deltat/cpp - - ttmp=t(i,k)+((D_eros_l(i,k)+cmel(i,k))*xxlv+ & - (D_eros_i(i,k)+cmei(i,k)+ qvdep_qi(i,k))*xxls)*deltat/cpp - - - eslt=polysvp_l(ttmp) - esit=polysvp_i(ttmp) - esn=min(esit, eslt) - - qsn=min(epsqs*esn/(pfull(i,k)-(1._mg_pr-epsqs)*esn),1._mg_pr) - qsn=max(qsn,0._mg_pr) - - - dum=(qtmp-qsn)/(1._mg_pr+(xxlv*dum1+xxls*(1._mg_pr-dum1))**2*qsn/(cpp*rv*ttmp**2)) - dum=min(dum,0._mg_pr) - - -! modify rates if needed, divide by cldmax to get local (in-precip) value - pre(k)=dum*dum1/deltat/cldmax(i,k) - prds(k)=dum*(1._mg_pr-dum1)/deltat/cldmax(i,k) - end if - end if - - end if - - -IF ( .NOT. one_ice ) THEN - -! bergeron process - evaporation of droplets and deposition onto snow -! bergeron process for snow is neglected for now............. - if (do_berg_snow ) then - - if (qniic(i,k).ge.qsmall.and.qcic(i,k).ge.qsmall.and.t(i,k).lt.273.15_mg_pr) then - qvs=0.622_mg_pr*esl(i,k)/(pfull(i,k)-d378* esl(i,k)) - qvi=0.622_mg_pr*esi(i,k)/(pfull(i,k)-d378* esi(i,k)) -!! qvs=0.622_mg_pr*esl(i,k)/(pfull(i,k)- esl(i,k)) -!! qvi=0.622_mg_pr*esi(i,k)/(pfull(i,k)- esi(i,k)) - dqsidt = xxls*qvi/(rv*t(i,k)**2) - abi(i,k) = 1._mg_pr+dqsidt*xxls/cpp - epss = 2._mg_pr*pi*n0s(k)*rho(i,k)*Dv(i,k)* & - (f1s/(lams(k)*lams(k))+ & - f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_mg_pr* & - sc(i,k)**(1._mg_pr/3._mg_pr)*gamma_mg(5._mg_pr/2._mg_pr+bs/2._mg_pr)/ & - (lams(k)**(5._mg_pr/2._mg_pr+bs/2._mg_pr))) -!cms 2009/3/2 bergs(k)=epss*(qvs-qvi)/abi(i,k) - bergs(k)=MAX(epss*(qvs-qvi)/abi(i,k), 0._mg_pr) - else - bergs(k)=0._mg_pr - end if -!++ag -else - bergs(k)=0._mg_pr -endif -!--ag -ELSE - bergs(k)=0._mg_pr - -END IF - - - - -! sensitivity - no rain/snow evaporation - -! pre(k)=0._mg_pr -! prds(k)=0._mg_pr - -!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! conservation to ensure no negative values of cloud water/precipitation -! in case microphysical process rates are large - -! make sure and use end-of-time step values for cloud water, ice, due -! condensation/deposition - -! note: for check on conservation, processes are multiplied by omsm -! to prevent problems due to round off error - -! since activation/nucleation processes are fast, need to take into account -! factor mtime = mixing timescale in cloud / model time step -! mixing time can be interpreted as cloud depth divided by sub-grid vertical velocity -! for now mixing timescale is assumed to be 20 min -! could possibly be estimated better from model variables - - IF (act_choice .EQ. 1 )THEN ! since act. is assumed to take place at cloud base - !cms mtime=deltat/1200._mg_pr - - mtime= 1._mg_pr - ELSE IF (act_choice .EQ. 2 )THEN !since Yi's formulation assumes activation at lateral cloud boundaries - mtime=1._mg_pr - ENDIF - - qce=(qc(i,k)+(D_eros_l(i,k)+cmel(i,k)-berg(i,k))*deltat) - nce=(nc(i,k)+npccn(k)*deltat*mtime)/cldm(i,k) - qie=(qi(i,k)+(D_eros_i(i,k)+cmei(i,k)+berg(i,k)+qvdep_qi(i,k))*deltat) - nie=(ni(i,k)+nnuccd(k)*deltat*mtime)/cldm(i,k) - - - -! conservation of qc - - dum = (prc(k)+pra(k)+mnuccc(k)+ & - psacws(k)+bergs(k) + psacws_o(k))*cldm(i,k)*deltat - - if (dum.gt.qce) then - if ( dum .gt. 1.e-30 ) then - ratio = qce/deltat/cldm(i,k)/(prc(k)+pra(k)+mnuccc(k)+psacws(k)+ psacws_o(k)+bergs(k))*omsm - else - ratio = 0. - endif - - - prc(k) = prc(k)*ratio - pra(k) = pra(k)*ratio - mnuccc(k) = mnuccc(k)*ratio - psacws(k) = psacws(k)*ratio - psacws_o(k) = psacws_o(k)*ratio - bergs(k) = bergs(k)*ratio - end if - -! conservation of nc - - dum = (nprc1(k)+npra(k)+nnuccc(k)+ & - npsacws(k)+ npsacws_o(k)-nsubc(k)-nerosc(k))*deltat - - if (dum.gt.nce) then - if ( dum .gt. 1.e-30 ) then - ratio = nce/deltat/(nprc1(k)+npra(k)+nnuccc(k)+& - npsacws(k)+ npsacws_o(k)-nsubc(k)-nerosc(k))*omsm - else - ratio = 0._mg_pr - end if - - nprc1(k) = nprc1(k)*ratio - npra(k) = npra(k)*ratio - nnuccc(k) = nnuccc(k)*ratio - npsacws(k) = npsacws(k)*ratio - npsacws_o(k) = npsacws_o(k)*ratio - nsubc(k)=nsubc(k)*ratio - nerosc(k) = nerosc(k)*ratio - end if - -! conservation of qi - - dum = (-mnuccc(k)+prci(k)+ & - prai(k) - psacws_o(k) )*cldm(i,k)*deltat - - - - if (dum.gt.qie) then - if ( dum .gt. 1.e-30 ) then - ratio = (qie/deltat/cldm(i,k)+mnuccc(k)+ psacws_o(k))/(prci(k)+prai(k))*omsm - else - ratio = 0._mg_pr - end if - prci(k) = prci(k)*ratio - prai(k) = prai(k)*ratio - psacws_o(k) = psacws_o(k)*ratio - end if - -! conservation of ni - - dum = (nprci(k)+ & - nprai(k)-nsubi(k)-nerosi(k))*deltat - - if (dum.gt.nie) then - if ( dum .gt. 1.e-30 ) then - ratio = (nie/deltat)/ & - (nprci(k)+nprai(k)-nsubi(k)-nerosi(k))*omsm - else - ratio = 0._mg_pr - end if - nprci(k) = nprci(k)*ratio - nprai(k) = nprai(k)*ratio - nsubi(k) = nsubi(k)*ratio - nerosi(k) = nerosi(k)*ratio - end if - -! for preciptiation conservation, use logic that vertical integral -! of tendency from current level to top of model (i.e., qrtot) cannot be negative - -! conservation of rain mixing rat - - if (((prc(k)+pra(k))*cldm(i,k)+(-mnuccr(k)+pre(k)-pracs(k))*& - cldmax(i,k))*pdel(i,k)/grav + qrtot.lt.0._mg_pr) then - - - - if (-pre(k)+pracs(k)+mnuccr(k).ge.qsmall) then - - - ratio = (qrtot/(pdel(i,k)/grav)+(prc(k)+pra(k))*cldm(i,k))/& - ((-pre(k)+pracs(k)+mnuccr(k))*cldmax(i,k))*omsm - - else - ratio = 0._mg_pr - - end if - - - pre(k) = pre(k)*ratio - pracs(k) = pracs(k)*ratio - mnuccr(k) = mnuccr(k)*ratio - - end if - -! conservation of nr -! for now neglect evaporation of nr - -IF (rain_evap_opt) THEN - -! calculate evaporation of nr - if (pre(k).lt.0._mg_pr.and.qric(i,k).ge.qsmall) then - nsubr(k)=pre(k)/qric(i,k)*nric(i,k) - else - nsubr(k)=0._mg_pr - end if - -ELSE - -nsubr(k)=0._mg_pr - -END IF - - if ((nprc(k)*cldm(i,k)+(-nnuccr(k)+nsubr(k)-npracs(k)& - +nragg(k))*cldmax(i,k))*pdel(i,k)/grav+nrtot.lt.0._mg_pr) then - - if (-nsubr(k)-nragg(k)+npracs(k)+nnuccr(k).ge.qsmall) then - - - ratio = (nrtot/(pdel(i,k)/grav)+nprc(k)*cldm(i,k))/& - ((-nsubr(k)-nragg(k)+npracs(k)+nnuccr(k))*cldmax(i,k))*omsm - - - else - ratio =0._mg_pr - end if - - nsubr(k) = nsubr(k)*ratio - npracs(k) = npracs(k)*ratio - nnuccr(k) = nnuccr(k)*ratio - nragg(k) = nragg(k)*ratio - end if - -! conservation of snow mix ratio - - if (((bergs(k)+psacws(k)+prai(k)+prci(k))*cldm(i,k)+(pracs(k)+& - mnuccr(k)+prds(k))*cldmax(i,k))*pdel(i,k)/grav+qstot.lt.0._mg_pr) then - - - if (-prds(k).ge.qsmall) then - - ratio = (qstot/(pdel(i,k)/grav)+(bergs(k)+psacws(k)+prai(k)+prci(k))*cldm(i,k)+& - (pracs(k)+mnuccr(k))*cldmax(i,k))/(-prds(k)*cldmax(i,k))*omsm - - else - ratio =0._mg_pr - end if - - - prds(k) = prds(k)*ratio - - end if - -! conservation of ns - - -! calculate loss of number due to sublimation - IF ( subl_snow ) THEN - - if (prds(k).lt.0._mg_pr.and.qniic(i,k).ge.qsmall) then - nsubs(k)=prds(k)/qniic(i,k)*nsic(i,k) - else - nsubs(k)=0._mg_pr - end if - ELSE -! neglect sublimation of ns - nsubs(k)=0._mg_pr - - END IF - - if ((nprci(k)*cldm(i,k)+(nnuccr(k)+nsubs(k)+nsagg(k))*cldmax(i,k))*& - pdel(i,k)/grav+nstot.lt.0._mg_pr) then - - if (-nsubs(k)-nsagg(k).ge.qsmall) then - - ratio = (nstot/(pdel(i,k)/grav)+nprci(k)*cldm(i,k)+& - nnuccr(k)*cldmax(i,k))/((-nsubs(k)-nsagg(k))*cldmax(i,k))*omsm - - else - ratio =0._mg_pr - end if - - - nsubs(k) = nsubs(k)*ratio - nsagg(k) = nsagg(k)*ratio - end if - -! get tendencies due to microphysical conversion processes -! note: tendencies are multiplied by appropaiate cloud/precip -! fraction to get grid-scale values -! note: cmei,cmel are already grid-average values - - qvlat(i,k) = qvlat(i,k)- & - (pre(k)+prds(k))*cldmax(i,k)-cmel(i,k)-cmei(i,k)-D_eros_l(i,k)-D_eros_i(i,k) - qvdep_qi(i,k) - - tlat(i,k) = tlat(i,k)+((pre(k)*cldmax(i,k)+cmel(i,k)+D_eros_l(i,k)) & - *xxlv+(prds(k)*cldmax(i,k)+cmei(i,k)+D_eros_i(i,k)+ qvdep_qi(i,k))*xxls+ & - ((bergs(k)+psacws(k)+psacws_o(k)+mnuccc(k))*cldm(i,k)+(mnuccr(k)+ & - pracs(k))*cldmax(i,k)+berg(i,k))*xlf) - - - - qctend(i,k) = qctend(i,k)+ & - (-pra(k)-prc(k)-mnuccc(k)- & - psacws(k)-psacws_o(k)-bergs(k))*cldm(i,k)+cmel(i,k)-berg(i,k) + D_eros_l(i,k) - - - - qitend(i,k) = qitend(i,k)+ & - (mnuccc(k)-prci(k)- & - prai(k)+psacws_o(k))*cldm(i,k)+cmei(i,k)+berg(i,k) + D_eros_i(i,k) + qvdep_qi(i,k) - - - - - qrtend(i,k) = qrtend(i,k)+ & - (pra(k)+prc(k))*cldm(i,k)+(pre(k)-pracs(k)- & - mnuccr(k))*cldmax(i,k) - - - - qnitend(i,k) = qnitend(i,k)+ & - (prai(k)+psacws(k)+prci(k)+bergs(k))*cldm(i,k)+(prds(k)+ & - pracs(k)+mnuccr(k))*cldmax(i,k) - - -! multiply activation/nucleation by mtime to account for fast timescale - - dumd = nctend(i,k) - nctend(i,k) = nctend(i,k)+ npccn(k)*mtime+& - (-nnuccc(k)-npsacws(k)-npsacws_o(k)+nsubc(k) + nerosc(k) & - -npra(k)-nprc1(k))*cldm(i,k) - - - - -!-- - - nitend(i,k) = nitend(i,k)+ nnuccd(k)*mtime+& - (nsubi(k) + nerosi(k) -nprci(k)- & - nprai(k))*cldm(i,k) - - - - nstend(i,k) = nstend(i,k)+(nsubs(k)+ & - nsagg(k)+nnuccr(k))*cldmax(i,k)+nprci(k)*cldm(i,k) - - - - - nrtend(i,k) = nrtend(i,k)+ & - nprc(k)*cldm(i,k)+(nsubr(k)-npracs(k)-nnuccr(k) & - +nragg(k))*cldmax(i,k) - - - -! make sure that nc and ni at advanced time step do not exceed -! maximum (existing N + source terms*dt), which is possible due to -! fast nucleation timescale - - !diag++ - - IF ( diag_id%qndt_nucclim + diag_id%qn_nucclim_col > 0 ) THEN - nucclim(k) = nctend(i,k) - END IF - - - IF ( diag_id%qnidt_nucclim1 > 0 ) THEN - nucclim1i(k) = nitend(i,k) - END IF - - - - !diag-- - - - - if (nctend(i,k).gt.0._mg_pr.and.nc(i,k)+nctend(i,k)*deltat.gt.ncmax) then - nctend(i,k)=max(0._mg_pr,(ncmax-nc(i,k))/deltat) - end if - if (nitend(i,k).gt.0._mg_pr.and.ni(i,k)+nitend(i,k)*deltat.gt.nimax) then - nitend(i,k)=max(0._mg_pr,(nimax-ni(i,k))/deltat) - end if - - - ! diag ++ - - IF ( diag_id%qndt_nucclim + diag_id%qn_nucclim_col > 0 ) THEN - nucclim(k) = nctend(i,k) - nucclim(k) - END IF - - - IF ( diag_id%qnidt_nucclim1 > 0 ) THEN - nucclim1i(k) = nitend(i,k) - nucclim1i(k) - END IF - - - !-------------- - -IF (limit_volri ) THEN - - IF ( diag_id%qnidt_nucclim2 > 0 ) THEN - nucclim2(k) = nitend(i,k) - END IF - - !-- - - !diag -- - - - -!cms 2009-2-26 also limit volume mean ice radius - - - qii_new = ( qi(i,k)+qitend(i,k)*deltat ) /cldm(i,k) - nii_new = ( ni(i,k)+nitend(i,k)*deltat ) /cldm(i,k) - -!max XXX micron - nii_min = qii_new/rhoi * 3./(4.*3.14*max_diam_ii**3) - -!min XXX micron - nii_max = qii_new/rhoi * 3./(4.*3.14*min_diam_ii**3) - - - if ( nii_new .gt. nii_max ) then - - nitend(i,k)= (nii_max - ni(i,k)/cldm(i,k))/deltat*cldm(i,k) - - else if ( nii_new .lt. nii_min ) then - - nitend(i,k)= (nii_min - ni(i,k)/cldm(i,k))/deltat*cldm(i,k) - - end if - - - !-- diag ++ - IF ( diag_id%qnidt_nucclim2 > 0 ) THEN - nucclim2(k) = nitend(i,k) - nucclim2(k) - END IF - - !-- diag -- - -END IF - -!--- - - - -! get final values for precipitation q and N, based on -! flux of precip from above, source/sink term, and terminal fallspeed -! see eq. 15-16 in Morrison and Gettelman, 2007, J. Climate - -! rain - - if (qric(i,k).ge.qsmall) then - if (k.eq.1) then - qric(i,k)=qrtend(i,k)*dz(i,k)/cldmax(i,k)/umr(k) - nric(i,k)=nrtend(i,k)*dz(i,k)/cldmax(i,k)/unr(k) - else - qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*qrtend(i,k)))/(umr(k)*rho(i,k)*cldmax(i,k)) - nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*nrtend(i,k)))/(unr(k)*rho(i,k)*cldmax(i,k)) - - end if - else - qric(i,k)=0._mg_pr - nric(i,k)=0._mg_pr - end if - -! snow - - if (qniic(i,k).ge.qsmall) then - if (k.eq.1) then - qniic(i,k)=qnitend(i,k)*dz(i,k)/cldmax(i,k)/ums(k) - nsic(i,k)=nstend(i,k)*dz(i,k)/cldmax(i,k)/uns(k) - else - qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*qnitend(i,k)))/(ums(k)*rho(i,k)*cldmax(i,k)) - nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)*cldmax(i,k-1)+ & - (rho(i,k)*dz(i,k)*nstend(i,k)))/(uns(k)*rho(i,k)*cldmax(i,k)) - end if - else - qniic(i,k)=0._mg_pr - nsic(i,k)=0._mg_pr - end if - - - -! calculate precipitation flux at surface -! divide by density of water to get units of m/s - - - - prect(i) = prect(i)+(qrtend(i,k) * pdel(i,k)/grav +& - qnitend(i,k) * pdel(i,k)/grav )/rhow - preci(i) = preci(i)+qnitend(i,k) * pdel(i,k)/grav /rhow - - - - ! hm, add 9/5/07 - ! convert rain rate from m/s to mm/hr - - rainrt(i,k)=qric(i,k)*rho(i,k)*umr(k)/rhow*3600._mg_pr*1000._mg_pr - - !mm/s - -if ( k > 1 ) then -!! arainrt(i,k)= `cldmax(i,k-1)*qric(i,k-1)*rho(i,k-1)*umr(k-1)/rhow*1000._mg_pr -!! asnowrt(i,k)= cldmax(i,k-1)*qniic(i,k-1)*rho(i,k-1)*ums(k-1)/rhosn*1000._mg_pr -IF ( .NOT. one_ice ) THEN - asnowrt(i,k)= cldmax(i,k-1)*qniic(i,k-1)*rho(i,k-1)*ums(k-1)/rhosn -ELSE - asnowrt(i,k)= cldmax(i,k-1)*qiic(i,k-1)*rho(i,k-1)*ums(k-1)/rhosn -END IF - atotrt(i,k) = asnowrt(i,k) + cldmax(i,k-1)*qric(i,k-1)*rho(i,k-1)*umr(k-1)/rhow - - -!! atotrt(i,k)= atotrt(i,k) + (qrtend(i,k) + qnitend(i,k) ) *dz(i,k)*rho(i,k)/rhow -!! asnowrt(i,k)= asnowrt(i,k) + qnitend(i,k)*dz(i,k)*rho(i,k)/rhow -end if - - -! vertically-integrated precip source/sink terms (note: grid-averaged) - - - qrtot = max(qrtot+qrtend(i,k)*pdel(i,k)/grav,0._mg_pr) - qstot = max(qstot+qnitend(i,k)*pdel(i,k)/grav,0._mg_pr) - nrtot = max(nrtot+nrtend(i,k)*pdel(i,k)/grav,0._mg_pr) - nstot = max(nstot+nstend(i,k)*pdel(i,k)/grav,0._mg_pr) - - - -! calculate melting and freezing of precip - -! melt snow at +2 C -! - if (t(i,k)+tlat(i,k)/cpp*deltat > 275.15_mg_pr) then - - if (qstot > 0._mg_pr) then - -! make sure melting snow doesn't reduce temperature below threshold - - dum = -xlf/cpp*qstot/(pdel(i,k)/grav) - if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.275.15_mg_pr) then - dum = (t(i,k)+tlat(i,k)/cpp*deltat-275.15_mg_pr)*cpp/xlf - dum = dum/(xlf/cpp*qstot/(pdel(i,k)/grav)) - dum = max(0._mg_pr,dum) - dum = min(1._mg_pr,dum) - else - dum = 1._mg_pr - end if - - - - qric(i,k)=qric(i,k)+dum*qniic(i,k) - nric(i,k)=nric(i,k)+dum*nsic(i,k) - qniic(i,k)=(1._mg_pr-dum)*qniic(i,k) - nsic(i,k)=(1._mg_pr-dum)*nsic(i,k) - tlat(i,k)=tlat(i,k)-xlf*dum*qstot/(pdel(i,k)/grav) - qrtot=qrtot+dum*qstot - qstot=(1._mg_pr-dum)*qstot - nrtot=nrtot+dum*nstot - nstot=(1._mg_pr-dum)*nstot - preci(i)=(1._mg_pr-dum)*preci(i) - - - -!cms++ -! assume that droplets which would condense due to cooling associated with melting of snow are -! rapidly collected by (newly formed) rain drops - - collect_frzreg2: IF ( collect_frzreg ) THEN - IF ( tlat(i,k) .LT. 0._mg_pr ) THEN !ony if there is net cooling - - ttmp=t(i,k)+tlat(i,k)/cpp*deltat - qtmp=q(i,k)+qvlat(i,k)*deltat - - esn = polysvp_l(ttmp) - -! eslt=polysvp_l(ttmp) -! esit=polysvp_i(ttmp) -! esn=min(esit, eslt) - - qvs=0.622_mg_pr*esn/(pfull(i,k)- d378* esn) - - dqsdt = xxlv*qvs/(rv*ttmp**2) - ab = 1._mg_pr+dqsdt*xxlv/cpp - - tmp2 = pfull(i,k) - d378*esn - tmp2 = max(tmp2,esn) - tmp2 = d622*esn/tmp2 - tmp1 = max(0._mg_pr, (qtmp -tmp2)/ab) - - - !change vapor content and T - - - qvlat(i,k) = qvlat(i,k)-tmp1/deltat - tlat(i,k) = tlat(i,k) + hlv*tmp1/deltat - - - - !and rain mixing ratio - - qric(i,k)=qric(i,k)+ tmp1/cldmax(i,k) - - - qrtot=qrtot+tmp1/deltat * pdel(i,k)/grav - prect(i) = prect(i) + tmp1/deltat * pdel(i,k)/grav /rhow -!cms-- - - END IF - END IF collect_frzreg2 -!cms-- - - -!! asnowrt(i,k)=(1._mg_pr-dum)* asnowrt(i,k) - end if - end if - - - -! freeze rain homogeneously at -40 C - - if (t(i,k)+tlat(i,k)/cpp*deltat < tmin_fice ) then - if (qrtot > 0._mg_pr) then - -! make sure freezing rain doesn't increase temperature above threshold - dum = xlf/cpp*qrtot/(pdel(i,k)/grav) - if (t(i,k)+tlat(i,k)/cpp*deltat+dum.gt. tmin_fice) then - dum = -(t(i,k)+tlat(i,k)/cpp*deltat- tmin_fice)*cpp/xlf - dum = dum/(xlf/cpp*qrtot/(pdel(i,k)/grav)) - dum = max(0._mg_pr,dum) - dum = min(1._mg_pr,dum) - else - dum = 1._mg_pr - end if - - qniic(i,k)=qniic(i,k)+dum*qric(i,k) - nsic(i,k)=nsic(i,k)+dum*nric(i,k) - qric(i,k)=(1._mg_pr-dum)*qric(i,k) - nric(i,k)=(1._mg_pr-dum)*nric(i,k) - tlat(i,k)=tlat(i,k)+xlf*dum*qrtot/(pdel(i,k)/grav) - qstot=qstot+dum*qrtot - qrtot=(1._mg_pr-dum)*qrtot - nstot=nstot+dum*nrtot - nrtot=(1._mg_pr-dum)*nrtot - preci(i)=preci(i)+dum* (prect(i)-preci(i)) - - - - !! asnowrt(i,k)= asnowrt(i,k) +dum*(atotrt(i,k)- asnowrt(i,k)) - end if - end if - - -! if rain/snow mix ratio is zero so should number concentration - - if (qniic(i,k).lt.qsmall) then - qniic(i,k)=0._mg_pr - nsic(i,k)=0._mg_pr - end if - - if (qric(i,k).lt.qsmall) then - qric(i,k)=0._mg_pr - nric(i,k)=0._mg_pr - end if - -! make sure number concentration is a positive number to avoid -! taking root of negative - - nric(i,k)=max(nric(i,k),0._mg_pr) - nsic(i,k)=max(nsic(i,k),0._mg_pr) - -!....................................................................... -! get size distribution parameters for fallspeed calculations -!...................................................................... -! rain - - if (qric(i,k).ge.qsmall) then - lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))**(1._mg_pr/3._mg_pr) - n0r(k) = nric(i,k)*lamr(k) - -! check for slope -! hm 4/5/07, change lammax and lammin for rain and snow - - lammax = 1._mg_pr/20.e-6_mg_pr - - lammin = 1._mg_pr/500.e-6_mg_pr - -! adjust vars - - if (lamr(k).lt.lammin) then - - lamr(k) = lammin - - n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) - nric(i,k) = n0r(k)/lamr(k) - else if (lamr(k).gt.lammax) then - lamr(k) = lammax - n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) - nric(i,k) = n0r(k)/lamr(k) - end if - -! 'final' values of number and mass weighted mean fallspeed for rain (m/s) - unr(k) = min(arn(i,k)*gamma_mg(1._mg_pr+br)/lamr(k)**br,9.1_mg_pr) - umr(k) = min(arn(i,k)*gamma_mg(4._mg_pr+br)/(6._mg_pr*lamr(k)**br),9.1_mg_pr) - - else - lamr(k) = 0._mg_pr - n0r(k) = 0._mg_pr - umr(k)=0._mg_pr - unr(k)=0._mg_pr - end if - - - -!...................................................................... -! snow - - if (qniic(i,k).ge.qsmall) then - lams(k) = (gamma_mg(1._mg_pr+ds)*cs*nsic(i,k)/ & - qniic(i,k))**(1._mg_pr/ds) - n0s(k) = nsic(i,k)*lams(k) - -! check for slope - - lammax = 1._mg_pr/min_diam_ice - lammin = 1._mg_pr/2000.e-6_mg_pr - -! adjust vars - - if (lams(k).lt.lammin) then - lams(k) = lammin - n0s(k) = lams(k)**(ds+1._mg_pr)*qniic(i,k)/(cs*gamma_mg(1._mg_pr+ds)) - nsic(i,k) = n0s(k)/lams(k) - - else if (lams(k).gt.lammax) then - lams(k) = lammax - n0s(k) = lams(k)**(ds+1._mg_pr)*qniic(i,k)/(cs*gamma_mg(1._mg_pr+ds)) - nsic(i,k) = n0s(k)/lams(k) - end if - -! 'final' values of number and mass weighted mean fallspeed for snow (m/s) - ums(k) = min(asn(i,k)*gamma_mg(4._mg_pr+bs)/(6._mg_pr*lams(k)**bs),max_vt_snow) - uns(k) = min(asn(i,k)*gamma_mg(1._mg_pr+bs)/lams(k)**bs,max_vt_snow) - - - else - lams(k) = 0._mg_pr - n0s(k) = 0._mg_pr - ums(k) = 0._mg_pr - uns(k) = 0._mg_pr - end if - - - - -!c........................................................................ -! sum over sub-step for average process rates - -! convert rain/snow q and N for output to history, note, -! output is for gridbox average - - qrout(i,k)=qrout(i,k)+qric(i,k)*cldmax(i,k) - qsout(i,k)=qsout(i,k)+qniic(i,k)*cldmax(i,k) - nrout(i,k)=nrout(i,k)+nric(i,k)*rho(i,k)*cldmax(i,k) - nsout(i,k)=nsout(i,k)+nsic(i,k)*rho(i,k)*cldmax(i,k) - - tlat1(i,k)=tlat1(i,k)+tlat(i,k) - qvlat1(i,k)=qvlat1(i,k)+qvlat(i,k) - qctend1(i,k)=qctend1(i,k)+qctend(i,k) - qitend1(i,k)=qitend1(i,k)+qitend(i,k) - nctend1(i,k)=nctend1(i,k)+nctend(i,k) - nitend1(i,k)=nitend1(i,k)+nitend(i,k) - - t(i,k)=t(i,k)+tlat(i,k)*deltat/cpp - q(i,k)=q(i,k)+qvlat(i,k)*deltat - qc(i,k)=qc(i,k)+qctend(i,k)*deltat - qi(i,k)=qi(i,k)+qitend(i,k)*deltat - nc(i,k)=nc(i,k)+nctend(i,k)*deltat - ni(i,k)=ni(i,k)+nitend(i,k)*deltat - - ! hm add 9/5/07 - - rainrt1(i,k)=rainrt1(i,k)+rainrt(i,k) - - atotrt1(i,k)=atotrt1(i,k)+atotrt(i,k) - asnowrt1(i,k)=asnowrt1(i,k)+asnowrt(i,k) - - -!diag-- -!cloud droplets - cmel1(i,k) = cmel1(i,k) + cmel(i,k) - D_eros_l1(i,k) = D_eros_l1(i,k) + D_eros_l(i,k) - berg1(i,k) = berg1(i,k) + berg(i,k) - qvdep_qi1(i,k) = qvdep_qi1(i,k) + qvdep_qi(i,k) - prc1(i,k) = prc1(i,k) - prc(k) * cldm(i,k) - - pra1(i,k) = pra1(i,k) - pra(k) * cldm(i,k) - mnuccc1(i,k) = mnuccc1(i,k) -mnuccc(k) * cldm(i,k) - - psacws1(i,k) = psacws1(i,k) - ( psacws(k) + psacws_o(k)) *cldm(i,k) - - psacws_o1(i,k) = psacws_o1(i,k) - psacws_o(k) *cldm(i,k) - - bergs1(i,k) = bergs1(i,k) -bergs(k) * cldm(i,k) - - -!cloud ice - cmei1(i,k) = cmei1(i,k) + cmei(i,k) - - D_eros_i1(i,k) = D_eros_i1(i,k) + D_eros_i(i,k) - - prci1(i,k) = prci1(i,k) - prci(k) * cldm(i,k) - prai1(i,k) = prai1(i,k) - prai(k) * cldm(i,k) - - - -!droplet number - - npccn1(i,k) = npccn1(i,k) + npccn(k)*mtime - nnuccc1(i,k) = nnuccc1(i,k) - nnuccc(k) *cldm(i,k) - npsacws1(i,k) = npsacws1(i,k) - npsacws(k) *cldm(i,k) - npsacws_o1(i,k) = npsacws_o1(i,k) - npsacws_o(k) *cldm(i,k) - nsubc1(i,k) = nsubc1(i,k) + nsubc(k) *cldm(i,k) - nerosc1(i,k) = nerosc1(i,k) + nerosc(k) *cldm(i,k) - npra1(i,k) = npra1(i,k) - npra(k) *cldm(i,k) - nprc11(i,k) = nprc11(i,k) - nprc1(k) *cldm(i,k) - nucclim1(i,k) = nucclim1(i,k) + nucclim(k) - - -!ice number - - nnuccd1(i,k) = nnuccd1(i,k) + nnuccd(k)*mtime - nsubi1(i,k) = nsubi1(i,k) + nsubi(k)*cldm(i,k) - nerosi1(i,k) = nerosi1(i,k) + nerosi(k) *cldm(i,k) - nprci1(i,k) = nprci1(i,k) - nprci(k) *cldm(i,k) - nprai1(i,k) = nprai1(i,k) - nprai(k) *cldm(i,k) - nucclim1_1(i,k) = nucclim1_1(i,k) + nucclim1i(k) - nucclim2_1(i,k) = nucclim2_1(i,k) + nucclim2(k) - -!diag-- - -!c........................................................................ - - - - end do large_k_loop_in_iter - - - prect1(i)=prect1(i)+prect(i) - preci1(i)=preci1(i)+preci(i) - - - - - - end do iter_loop ! it loop, sub-step - - 300 continue ! continue if no cloud water - end do i_loop_1 ! i loop - - -! convert dt from sub-step back to full time step - deltat=deltat*real(iter) - - - -!c............................................................................. - - - i_loop_3: do i=1,idim - -! skip all calculations if no cloud water - if (ltrue(i).eq.0) then - - - goto 500 - endif - - - - -! initialize nstep for sedimentation sub-steps - nstep = 1 - -! divide precip rate by number of sub-steps to get average over time step - - prect(i)=prect1(i)/real(iter) - preci(i)=preci1(i)/real(iter) - - - do k=1,kdim - umi(k)=0._mg_pr - end do - - do k=1,kdim - -! assign variables back to start-of-timestep values before updating after sub-steps - - t(i,k)=t1(i,k) - q(i,k)=q1(i,k) - qc(i,k)=qc1(i,k) - qi(i,k)=qi1(i,k) - nc(i,k)=nc1(i,k) - ni(i,k)=ni1(i,k) - -! divide microphysical tendencies by number of sub-steps to get average over time step - - tlat(i,k)=tlat1(i,k)/real(iter) - qvlat(i,k)=qvlat1(i,k)/real(iter) - qctend(i,k)=qctend1(i,k)/real(iter) - qitend(i,k)=qitend1(i,k)/real(iter) - nctend(i,k)=nctend1(i,k)/real(iter) - nitend(i,k)=nitend1(i,k)/real(iter) - - - ! hm, add 9/5/07 - rainrt(i,k)=rainrt1(i,k)/real(iter) - - atotrt(i,k)=atotrt1(i,k)/real(iter) - asnowrt(i,k)=asnowrt1(i,k)/real(iter) - - -! divide output precip q and N by number of sub-steps to get average over time step - - qrout(i,k)=qrout(i,k)/real(iter) - qsout(i,k)=qsout(i,k)/real(iter) - nrout(i,k)=nrout(i,k)/real(iter) - nsout(i,k)=nsout(i,k)/real(iter) - - - -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -! calculate sedimentation for cloud water and ice -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - - - -! update in-cloud cloud mixing ratio and number concentration -! with microphsical tendencies to calculate sedimentation, assign to dummy vars -! note: these are in-cloud values***, hence we divide by cloud fraction - - dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat)/cldm(i,k) - dumi(i,k) = (qi(i,k)+qitend(i,k)*deltat)/cldm(i,k) - dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat)/cldm(i,k),0._mg_pr) - dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat)/cldm(i,k),0._mg_pr) - -! obtain new slope parameter to avoid possible singularity - - if (dumi(i,k).ge.qsmall) then -! add upper limit to in-cloud number concentration to prevent numerical error - dumni(i,k)=min(dumni(i,k),dumi(i,k)*1.e20_mg_pr) - - lami(k) = (gamma_mg(1._mg_pr+di_mg)*ci_mg* & - dumni(i,k)/dumi(i,k))**(1._mg_pr/di_mg) - lammax = 1._mg_pr/min_diam_ice - lammin = 1._mg_pr/(2._mg_pr*dcs) - lami(k)=max(lami(k),lammin) - lami(k)=min(lami(k),lammax) - else - lami(k)=0._mg_pr - end if - - if (dumc(i,k).ge.qsmall) then -! add upper limit to in-cloud number concentration to prevent numerical error - dumnc(i,k)=min(dumnc(i,k),dumc(i,k)*1.e20_mg_pr) - -!RSH BUGFIX email of 6/8/10 -! pgam(k)=0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr/rho(i,k))+0.2714_mg_pr - pgam(k)=0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr*rho(i,k))+0.2714_mg_pr - pgam(k)=1._mg_pr/(pgam(k)**2)-1._mg_pr - pgam(k)=max(pgam(k),2._mg_pr) - pgam(k)=min(pgam(k),15._mg_pr) - - lamc(k) = (pi/6._mg_pr*rhow*dumnc(i,k)*gamma_mg(pgam(k)+4._mg_pr)/ & - (dumc(i,k)*gamma_mg(pgam(k)+1._mg_pr)))**(1._mg_pr/3._mg_pr) - lammin = (pgam(k)+1._mg_pr)/max_diam_drop - lammax = (pgam(k)+1._mg_pr)/min_diam_drop - lamc(k)=max(lamc(k),lammin) - lamc(k)=min(lamc(k),lammax) - else - lamc(k)=0._mg_pr - end if - -! calculate number and mass weighted fall velocity for droplets -! include effects of sub-grid distribution of cloud water - - - if (dumc(i,k).ge.qsmall) then -!RSH bugfix email 6/8/10 - unc= & -! unc= sfac5 * & - acn(i,k)*gamma_mg(1._mg_pr+bc+pgam(k))/ & - (lamc(k)**bc*gamma_mg(pgam(k)+1._mg_pr)) -!RSH bugfix email 6/8/10 -! umc = sfac5 * & - umc = & - acn(i,k)*gamma_mg(4._mg_pr+bc+pgam(k))/ & - (lamc(k)**bc*gamma_mg(pgam(k)+4._mg_pr)) - else - umc = 0._mg_pr - unc = 0._mg_pr - end if - -! calculate number and mass weighted fall velocity for cloud ice - - if (dumi(i,k).ge.qsmall) then - - - IF ( .NOT. one_ice ) THEN - uni = ain(i,k)*gamma_mg(1._mg_pr+bi)/lami(k)**bi - umi(k) = ain(i,k)*gamma_mg(4._mg_pr+bi)/(6._mg_pr*lami(k)**bi) - - ELSE - umi(k) = min(asn(i,k)*gamma_mg(4._mg_pr+bs)/(6._mg_pr*lami(k)**bs),max_vt_ice) - uni = min(asn(i,k)*gamma_mg(1._mg_pr+bs)/lami(k)**bs,max_vt_ice) - END IF - - - uni=vfact_n*uni - umi(k) =vfact_m*umi(k) - - - - uni=min(uni,max_vt_ice) - umi(k)=min(umi(k),max_vt_ice) - -IF (hd_sedi_sens) THEN - umi(k) = vfact *3.29*((rho(i,k) * qi(i,k)/cldm(i,k)) **0.16) - uni=umi(k) -END IF - - -!RSH if (diag_id%vfall > 0) diag_4d(i,j,k,diag_pt%vfalldiag) = umi(k) - if (diag_id%vfall > 0) diag_4d(i,j,k,diag_pt%vfall ) = umi(k) - - - IF ( scav_by_cloud_ice ) THEN - if ( k > 1 ) then - asnowrt(i,k)= asnowrt(i,k) + cldmax(i,k-1)*qiic(i,k-1)*rho(i,k-1)*umi(k-1)/rhoi - end if - - END IF - - else - umi(k) = 0._mg_pr - uni = 0._mg_pr - end if - - - - fi(k) = grav*rho(i,k)*umi(k) - fni(k) = grav*rho(i,k)*uni - fc(k) = grav*rho(i,k)*umc - fnc(k) = grav*rho(i,k)*unc - -! calculate number of split time steps to ensure courant stability criteria -! for sedimentation calculations - - rgvm = max(fi(k),fc(k),fni(k),fnc(k)) - nstep = max(int(rgvm*deltat/pdel(i,k)+1._mg_pr),nstep) - - - - - - -! redefine dummy variables - sedimentation is calculated over grid-scale -! quantities to ensure conservation - - dumc(i,k) = (qc(i,k)+qctend(i,k)*deltat) - dumi(i,k) = (qi(i,k)+qitend (i,k)*deltat) - dumnc(i,k) = max((nc(i,k)+nctend(i,k)*deltat),0._mg_pr) - dumni(i,k) = max((ni(i,k)+nitend(i,k)*deltat),0._mg_pr) - - - - if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._mg_pr - if (dumi(i,k).lt.qsmall) dumni(i,k)=0._mg_pr - - end do !!! vertical loop - - do n = 1,nstep !! loop over sub-time step to ensure stability - - do k = 1,kdim - falouti(k) = fi(k)*dumi(i,k) - faloutni(k) = fni(k)*dumni(i,k) - faloutc(k) = fc(k)*dumc(i,k) - faloutnc(k) = fnc(k)*dumnc(i,k) - end do - -! top of model - - k = 1 - faltndi = falouti(k)/pdel(i,k) - faltndni = faloutni(k)/pdel(i,k) - faltndc = faloutc(k)/pdel(i,k) - faltndnc = faloutnc(k)/pdel(i,k) - -! add fallout terms to microphysical tendencies - - qitend(i,k) = qitend(i,k)-faltndi/nstep - - - nitend(i,k) = nitend(i,k)-faltndni/nstep - qctend(i,k) = qctend(i,k)-faltndc/nstep - nctend(i,k) = nctend(i,k)-faltndnc/nstep - -!diag++ - IF ( diag_id%qldt_sedi > 0 ) & - diag_4d(i,j,k,diag_pt%qldt_sedi) = diag_4d(i,j,k,diag_pt%qldt_sedi) - faltndc/nstep - - IF ( diag_id%qidt_fall > 0 ) & - diag_4d(i,j,k,diag_pt%qidt_fall) = diag_4d(i,j,k,diag_pt%qidt_fall) -faltndi/nstep - - IF ( diag_id%qndt_sedi > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_sedi) = diag_4d(i,j,k,diag_pt%qndt_sedi) - faltndnc/nstep - - IF ( diag_id%qnidt_sedi > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_sedi) = diag_4d(i,j,k,diag_pt%qnidt_sedi) - faltndni/nstep - - -!diag-- - - dumi(i,k) = dumi(i,k)-faltndi*deltat/nstep - dumni(i,k) = dumni(i,k)-faltndni*deltat/nstep - dumc(i,k) = dumc(i,k)-faltndc*deltat/nstep - dumnc(i,k) = dumnc(i,k)-faltndnc*deltat/nstep - - - - - do k = 2,kdim - -! for cloud liquid and ice, if cloud fraction increases with height -! then add flux from above to both vapor and cloud water of current level -! this means that flux entering clear portion of cell from above evaporates -! instantly - - dum=cldm(i,k)/cldm(i,k-1) - dum=min(dum,1._mg_pr) - - - faltndqie=(falouti(k)-falouti(k-1))/pdel(i,k) - faltndi=(falouti(k)-dum*falouti(k-1))/pdel(i,k) - faltndni=(faloutni(k)-dum*faloutni(k-1))/pdel(i,k) - faltndqce=(faloutc(k)-faloutc(k-1))/pdel(i,k) - faltndc=(faloutc(k)-dum*faloutc(k-1))/pdel(i,k) - faltndnc=(faloutnc(k)-dum*faloutnc(k-1))/pdel(i,k) - - - -! add fallout terms to eulerian tendencies - - qitend(i,k) = qitend(i,k)-faltndi/nstep - - nitend(i,k) = nitend(i,k)-faltndni/nstep - qctend(i,k) = qctend(i,k)-faltndc/nstep - nctend(i,k) = nctend(i,k)-faltndnc/nstep - -!diag++ - IF (diag_id%qidt_fall > 0 ) & - diag_4d(i,j,k,diag_pt%qidt_fall) = diag_4d(i,j,k,diag_pt%qidt_fall) -faltndi/nstep - - IF ( diag_id%qldt_sedi > 0 ) & - diag_4d(i,j,k,diag_pt%qldt_sedi) = diag_4d(i,j,k,diag_pt%qldt_sedi)-faltndc/nstep - - IF ( diag_id%qndt_sedi > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_sedi) = diag_4d(i,j,k,diag_pt%qndt_sedi) - faltndnc/nstep - - - IF ( diag_id%qnidt_sedi > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_sedi) = diag_4d(i,j,k,diag_pt%qnidt_sedi) - faltndni/nstep - - - -!diag-- - - -! add terms to to evap/sub of cloud water - - qvlat(i,k)=qvlat(i,k)-(faltndqie-faltndi)/nstep - qvlat(i,k)=qvlat(i,k)-(faltndqce-faltndc)/nstep - tlat(i,k)=tlat(i,k)+(faltndqie-faltndi)*xxls/nstep - tlat(i,k)=tlat(i,k)+(faltndqce-faltndc)*xxlv/nstep - - - - dumi(i,k) = dumi(i,k)-faltndi*deltat/nstep - dumni(i,k) = dumni(i,k)-faltndni*deltat/nstep - dumc(i,k) = dumc(i,k)-faltndc*deltat/nstep - dumnc(i,k) = dumnc(i,k)-faltndnc*deltat/nstep - - Fni(K)=MAX(Fni(K)/pdel(i,K),Fni(K-1)/pdel(i,K-1))*pdel(i,K) - FI(K)=MAX(FI(K)/pdel(i,K),FI(K-1)/pdel(i,K-1))*pdel(i,K) - fnc(k)=max(fnc(k)/pdel(i,k),fnc(k-1)/pdel(i,k-1))*pdel(i,k) - Fc(K)=MAX(Fc(K)/pdel(i,K),Fc(K-1)/pdel(i,K-1))*pdel(i,K) - - end do !! k loop - -! units below are m/s -! cloud water/ice sedimentation flux at surface -! is added to precip flux at surface to get total precip (cloud + precip water) -! rate - - - - prect(i) = prect(i)+(faloutc(kdim)+falouti(kdim)) & - /grav/nstep/1000._mg_pr - - - preci(i) = preci(i)+(falouti(kdim)) & - /grav/nstep/1000._mg_pr - - - end do !! nstep loop - - - -! end sedimentation -!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - -! get new update for variables that includes sedimentation tendency -! note : here dum variables are grid-average, NOT in-cloud - - - - - - k_loop_sedi: do k=1,kdim - - dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._mg_pr) - dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._mg_pr) - dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._mg_pr) - dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._mg_pr) - - if (dumc(i,k).lt.qsmall) dumnc(i,k)=0._mg_pr - if (dumi(i,k).lt.qsmall) dumni(i,k)=0._mg_pr - -! calculate instantaneous processes (melting, homogeneous freezing) - - if (t(i,k)+tlat(i,k)/cpp*deltat > 273.15_mg_pr) then - if (dumi(i,k) > 0._mg_pr) then - -! limit so that melting does not push temperature below freezing - dum = -dumi(i,k)*xlf/cpp - if (t(i,k)+tlat(i,k)/cpp*deltat+dum.lt.273.15_mg_pr) then - dum = (t(i,k)+tlat(i,k)/cpp*deltat-273.15_mg_pr)*cpp/xlf - dum = dum/dumi(i,k)*xlf/cpp - dum = max(0._mg_pr,dum) - dum = min(1._mg_pr,dum) - else - dum = 1._mg_pr - end if - - qctend(i,k)=qctend(i,k)+dum*dumi(i,k)/deltat - - - -! hm add, 9/15/06, assume melting ice produces droplet -! mean volume radius of 8 micron - - -!diag++ - - IF ( diag_id%qndt_melt > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_melt) = nctend(i,k) - - IF ( diag_id%qidt_melt > 0 ) & - diag_4d(i,j,k,diag_pt%qidt_melt) = qitend(i,k) - - - - IF ( diag_id%qnidt_melt > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_melt) = nitend(i,k) - - -!diag-- -!cms nitend .ne. -nctend - - nctend(i,k)=nctend(i,k)+3._mg_pr*dum*dumi(i,k)/deltat/ & - (4._mg_pr*pi*5.12e-16_mg_pr*rhow) - qitend(i,k)=((1._mg_pr-dum)*dumi(i,k)-qi(i,k))/deltat - nitend(i,k)=((1._mg_pr-dum)*dumni(i,k)-ni(i,k))/deltat - tlat(i,k)=tlat(i,k)-xlf*dum*dumi(i,k)/deltat - - - - -!diag++ - - IF ( diag_id%qndt_melt > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_melt) = nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_melt) - - IF ( diag_id%qidt_melt > 0 ) & - diag_4d(i,j,k,diag_pt%qidt_melt) = qitend(i,k) - diag_4d(i,j,k,diag_pt%qidt_melt) - - IF ( diag_id%qnidt_melt > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_melt) = nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_melt) - - -!diag-- - - end if - end if - - - - -! homogeneously freeze droplets at -40 C - - if (t(i,k)+tlat(i,k)/cpp*deltat < tmin_fice ) then -!cms 2009-3-24 if (dumc(i,k) > 0._mg_pr) then - if (dumc(i,k) .ge. qsmall) then -! limit so that freezing does not push temperature above threshold - dum = dumc(i,k)*xlf/cpp - if (t(i,k)+tlat(i,k)/cpp*deltat+dum .gt. tmin_fice) then - dum = -(t(i,k)+tlat(i,k)/cpp*deltat- tmin_fice)*cpp/xlf - dum = dum/dumc(i,k)*xlf/cpp - dum = max(0._mg_pr,dum) - dum = min(1._mg_pr,dum) - else - dum = 1._mg_pr - end if - - - qitend(i,k)=qitend(i,k)+dum*dumc(i,k)/deltat - -!diag++ - IF ( diag_id%qldt_freez > 0 ) & - diag_4d(i,j,k,diag_pt%qldt_freez) = qctend(i,k) - sum_freeze(i,k) = qctend(i,k) +! hm modify 6/12 + if (k .eq. 1) then + qric(i,k) = prc(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum + nric(i,k) = nprc(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum + else + if (qric(i,k-1) .ge. qsmall) then + dum = umr(k-1) + dum1 = unr(k-1) + end if + +! hm add 4/17/06, no autoconversion of rain number if rain/snow falling +! from above +! this assumes that new drizzle drops formed by autoconversion are +! rapidly collected by the existing rain/snow particles from above + +!RSH 2011: +! NCAR allows no autoconversion of rain number if rain/snow falling from +! above. this assumes that new drizzle drops formed by autoconversion are +! rapidly collected by the existing rain/snow particles falling from above. +! Marc's code allowed autoconversion to change rain number, so variable +! allow_all_cldtop_collection was introduced, which when .true. would turn +! off this effect. By default, it is .false. for GFDL (as in MG) in both +! this subroutine and in the NCAR subroutine(cldwat2m_micro.F90), in +! contrast to the original NCAR code. + + if (allow_all_cldtop_collection) then + if (qric(i,k-1) .ge. 1.e-9_mg_pr .or. & + qniic(i,k-1) .ge. 1.e-9_mg_pr) then + nprc(k) = 0._mg_pr + end if + endif ! allow_all_cldtop_collection + + qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)* & + ((pra(k-1) + prc(k))*cldm(i,k) + & + (pre(k-1) - pracs(k-1) - mnuccr(k-1))* & + cldmax(i,k))))/ & + (dum*rho(i,k)*cldmax(i,k)) + nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*(nprc(k)*cldm(i,k) + & + (nsubr(k-1) - npracs(k-1) - nnuccr(k-1) + & + nragg(k-1))*cldmax(i,k))))/ & + (dum1*rho(i,k)*cldmax(i,k)) + end if + +! cloudice to snow autoconversion. if parameter one_ice is .true., then +! cloudice and snow are retained in the same variable (as in the R-K +! microphysics) + IF (.NOT. one_ice) THEN + + if (t(i,k) .le. tfreeze .and. qiic(i,k) .ge. qsmall) then + + IF (auto_conv_ice_choice .EQ. 1) THEN +!....................................................................... +! Autoconversion of cloud ice to snow +! similar to Ferrier (1994) +! note: assumes autoconversion timescale of 180 sec + nprci(k) = n0i(k)/(lami(k)*auto_conv_time_scale)* & + exp(-lami(k)*dcs) + prci(k) = pi*rhoi*n0i(k)/(6._mg_pr* & + auto_conv_time_scale)* & + (dcs**3/lami(k) + 3._mg_pr*dcs**2/ & + lami(k)**2 + 6._mg_pr*dcs/lami(k)**3 + & + 6._mg_pr/lami(k)**4)*exp(-lami(k)*dcs) + + ELSE IF (auto_conv_ice_choice .EQ. 2) THEN +!....................................................................... +! AUTOCONVERSION OF CLOUD ICE TO SNOW +! FOLLOWING HARRINGTON ET AL. (1995) WITH MODIFICATION +! HERE IT IS ASSUMED THAT AUTOCONVERSION CAN ONLY OCCUR WHEN THE +! ICE IS GROWING, I.E. IN CONDITIONS OF ICE SUPERSATURATION + prci(k) = 0._mg_pr + nprci(k) = 0._mg_pr + esi(i,k) = polysvp_i(t(i,k)) + qvi = 0.622_mg_pr*esi(i,k)/ & + (pfull(i,k) - d378*esi(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi(i,k) = 1._mg_pr + dqsidt*xxls/cpp + IF (Q(i,k) - QVI .GT. qsmall) THEN + NPRCI(K) = 4._mg_pr/(DCS*RHOI)*(Q(i,k) - QVI)* & + rho(i,k)*n0i(K)* & + EXP(-lami(K)*dcs)*dv(i,k)/abi(i,k) + NPRCI(K) = MIN(NPRCI(K), niic(i,K)/deltat) + PRCI(K) = MIN(PI*RHOI*DCS**3/6._mg_pr*NPRCI(K), & + qiic(i,k)/deltat) + END IF + + ELSE IF (auto_conv_ice_choice .EQ. 3) THEN +!....................................................................... +! Autoconversion of cloud ice to snow +! similar to Ferrier (1994) +! note: assumes autoconversion timescale of 180 sec + IF (lami(k) .LT. 1._mg_pr/autoconv_ice_thr) THEN + nprci(k) = n0i(k)/(lami(k)*auto_conv_time_scale)* & + exp(-lami(k)*dcs) + prci(k) = pi*rhoi*n0i(k)/(6._mg_pr* & + auto_conv_time_scale)* & + (dcs**3/lami(k) + & + 3._mg_pr*dcs**2/lami(k)**2 + & + 6._mg_pr*dcs/lami(k)**3 + & + 6._mg_pr/lami(k)**4)*exp(-lami(k)*dcs) + END IF + + ELSE IF (auto_conv_ice_choice .EQ. 4) THEN +! ferrier, 1994, 4.54 + dum = 1._mg_pr/autoconv_ice_thr + IF (lami(k) .LT. dum) THEN + nprci(k) = niic(i,K)/deltat*(1._mg_pr - & + (lami(k)/dum )**3 ) + prci(k) = qiic(i,k)/deltat*(1._mg_pr - & + (lami(k)/dum)**3)/ & + (1._mg_pr + (lami(k)/dum)**3) + END IF + + ELSE IF (auto_conv_ice_choice .EQ. 5) THEN +!....................................................................... +! Autoconversion of cloud ice to snow +! similar to Ferrier (1994) +! note: assumes autoconversion timescale of 180 sec + IF (qiic(i,k) .GE. auto_conv_m_thresh) THEN + nprci(k) = n0i(k)/(lami(k)*auto_conv_time_scale)*& + exp(-lami(k)*dcs) + prci(k) = pi*rhoi*n0i(k)/(6._mg_pr* & + auto_conv_time_scale)* & + (dcs**3/lami(k) + & + 3._mg_pr*dcs**2/lami(k)**2 + & + 6._mg_pr*dcs/lami(k)**3 + & + 6._mg_pr/lami(k)**4)*exp(-lami(k)*dcs) + END IF + END IF + else ! t(i,k) .le. tfreeze .and. qiic(i,k) .ge. qsmall + prci(k) = 0._mg_pr + nprci(k) = 0._mg_pr + end if ! t(i,k) .le. tfreeze .and. qiic(i,k) .ge. qsmall + ELSE ! one_ice + prci(k) = 0._mg_pr + nprci(k) = 0._mg_pr + END IF ! one_ice + +! add autoconversion on current level to flux from level above to get +! provisional snow mixing ratio and number concentration (qniic and nsic) + + dum = (asn(i,k)*dcs**bs) + dum1 = (asn(i,k)*dcs**bs) + + if (k .eq. 1) then + qniic(i,k) = prci(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum + nsic(i,k) = nprci(k)*cldm(i,k)*dz(i,k)/cldmax(i,k)/dum + else + if (qniic(i,k-1) .ge. qsmall) then + dum = ums(k-1) + dum1 = uns(k-1) + end if - IF ( diag_id%qndt_ihom > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_ihom) = nctend(i,k) +!++ag fixed snow bug (from Morrison nov.27.2007) +! qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)* & +! cldmax(i,k-1) + & +! (rho(i,k)*dz(i,k)*(prci(k)*cldm(i,k) + & +! (prai(k-1) + psacws(k-1) + prci(k-1) + & +! bergs(k-1))*cldmax(i,k))))/ & +! (dum*rho(i,k)*cldmax(i,k)) + + qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*((prci(k) + prai(k-1) + & + psacws(k-1) + bergs(k-1))*cldm(i,k) + & + (prds(k-1) + pracs(k-1) + mnuccr(k-1))* & + cldmax(i,k))))/ & + (dum*rho(i,k)*cldmax(i,k)) +!--ag - IF ( diag_id%qnidt_ihom > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_ihom) = nitend(i,k) + nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*(nprci(k)*cldm(i,k) + & + (nsubs(k-1) + nsagg(k-1) + nnuccr(k-1))* & + cldmax(i,k))))/ & + (dum1*rho(i,k)*cldmax(i,k)) + end if +! if precip mix ratio is zero so should number concentration + if (qniic(i,k) .lt. qsmall) then + qniic(i,k) = 0._mg_pr + nsic(i,k) = 0._mg_pr + end if + if (qric(i,k) .lt. qsmall) then + qric(i,k) = 0._mg_pr + nric(i,k) = 0._mg_pr + end if -!diag-- +! make sure number concentration is a positive number to avoid +! taking root of negative later + nric(i,k) = max(nric(i,k), 0._mg_pr) + nsic(i,k) = max(nsic(i,k), 0._mg_pr) +!....................................................................... +! get size distribution parameters for precip +!...................................................................... +! rain + if (qric(i,k) .ge. qsmall) then + lamr(k) = (pi*rhow*nric(i,k)/qric(i,k))** & + (1._mg_pr/3._mg_pr) + n0r(k) = nric(i,k)*lamr(k) +! check for slope + lammax = 1._mg_pr/20.e-6_mg_pr + lammin = 1._mg_pr/500.e-6_mg_pr -! hm add 11/18/06 -! assume 25 micron mean volume radius of homogeneously frozen droplets -! consistent with size of detrained ice in stratiform.F90 -! -! cms nitend .ne. -nctend -! +! adjust vars + if (lamr(k) .lt. lammin) then + lamr(k) = lammin + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + else if (lamr(k).gt.lammax) then + lamr(k) = lammax + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + end if - nitend(i,k)=nitend(i,k)+dum*3._mg_pr*dumc(i,k)/(4._mg_pr*3.14_mg_pr* size_hom**3 * rhoi)/deltat +! provisional rain number and mass weighted mean fallspeed (m/s) + unr(k) = min ( & + arn(i,k)*gamma_mg(1._mg_pr + br)/lamr(k)**br, & + 9.1_mg_pr*rhof(i,k)) + umr(k) = min ( & + arn(i,k)*gamma_mg(4._mg_pr + br)/ & + (6._mg_pr*lamr(k)**br), & + 9.1_mg_pr*rhof(i,k)) + else + lamr(k) = 0._mg_pr + n0r(k) = 0._mg_pr + umr(k) = 0._mg_pr + unr(k) = 0._mg_pr + end if +!...................................................................... +! snow - qctend(i,k)=((1._mg_pr-dum)*dumc(i,k)-qc(i,k))/deltat - nctend(i,k)=((1._mg_pr-dum)*dumnc(i,k)-nc(i,k))/deltat + if (qniic(i,k) .ge. qsmall) then + lams(k) = (gamma_mg(1._mg_pr + ds)*cs*nsic(i,k)/ & + qniic(i,k))**(1._mg_pr/ds) + n0s(k) = nsic(i,k)*lams(k) +! check for slope + lammax = 1._mg_pr/min_diam_ice + lammin = 1._mg_pr/2000.e-6_mg_pr +! adjust vars + if (lams(k) .lt. lammin) then + lams(k) = lammin + n0s(k) = lams(k)**(ds + 1._mg_pr)*qniic(i,k)/ & + (cs*gamma_mg(1._mg_pr + ds)) + nsic(i,k) = n0s(k)/lams(k) + else if (lams(k) .gt. lammax) then + lams(k) = lammax + n0s(k) = lams(k)**(ds + 1._mg_pr)*qniic(i,k)/ & + (cs*gamma_mg(1._mg_pr + ds)) + nsic(i,k) = n0s(k)/lams(k) + end if - tlat(i,k)=tlat(i,k)+xlf*dum*dumc(i,k)/deltat +! provisional snow number and mass weighted mean fallspeed (m/s) + ums(k) = min ( & + asn(i,k)*gamma_mg(4._mg_pr + bs)/ & + (6._mg_pr*lams(k)**bs), & + max_vt_snow*rhof(i,k)) + uns(k) = min ( & + asn(i,k)*gamma_mg(1._mg_pr + bs)/lams(k)**bs, & + max_vt_snow*rhof(i,k)) + else + lams(k) = 0._mg_pr + n0s(k) = 0._mg_pr + ums(k) = 0._mg_pr + uns(k) = 0._mg_pr + end if -!diag++ - IF ( diag_id%qldt_freez > 0 ) & - diag_4d(i,j,k,diag_pt%qldt_freez) = qctend(i,k) - diag_4d(i,j,k,diag_pt%qldt_freez) - sum_freeze(i,k) = qctend(i,k) - sum_freeze(i,k) +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! heterogeneous freezing of cloud water - IF ( diag_id%qndt_ihom > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_ihom) = nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_ihom) + if (qcic(i,k) .ge. qsmall ) then + mnuccc(k) = 0._mg_pr + nnuccc(k) = 0._mg_pr - IF ( diag_id%qnidt_ihom > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_ihom) = nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_ihom) +!contact freezing + IF (do_contact_frz) THEN + tc = ttmp - tfreeze + IF (tc .LE. -3._mg_pr .AND. tc .GE. -40._mg_pr) THEN + IF (rbar_dust(i,k) .GT. 0._mg_pr) THEN +! mean free path + dum = 7.37_mg_pr*t(i,k)/(288._mg_pr*10._mg_pr* & + pfull(i,k))/100._mg_pr -!diag-- +! effective diffusivity based on Brownian collection + dap = 4._mg_pr*pi*1.38e-23_mg_pr*t(i,k)* & + (1._mg_pr + dum/rbar_dust(i,k))/ & + (6._mg_pr*pi*rbar_dust(i,k)*mu(i,k)) +! number of contact nucleii similar Young as in Liu et al. + IF (n_contact_opt .eq. 1 ) THEN + NACNT = ndust(i,k)/rho(i,k)* & + (tfreeze - 3._mg_pr - T(i,k))**1.3 + ELSE IF (n_contact_opt .eq. 2) THEN - end if - end if +!similar Meyers et al., 1992, Eq. 2.6 + NACNT = ndust(i,k)/rho(i,k)* & + EXP(-2.8_mg_pr + 0.262_mg_pr* & + (tfreeze - T(i,k))) + END IF + + MNUCCC(K) = sfac3*PI*PI/3._mg_pr*RHOW*DAP*NACNT* & + EXP(LOG(CDIST1(K)) + & + LOG(GAMMA_mg(PGAM(K) + 5._mg_pr)) - & + 4._mg_pr*LOG(LAMC(K))) + NNUCCC(K) = 2._mg_pr*PI*DAP*NACNT*CDIST1(K)* & + GAMMA_mg(PGAM(K) + 2._mg_pr)/LAMC(K) + + END IF + END IF + END IF ! (do_contact_frz) + IF (do_bigg_frz) THEN +! immersion freezing (Bigg, 1953) + if (t(i,k) .lt. tfreeze - 4._mg_pr) then +! mnuccc(k) = gamma_mg(qcvar+2._mg_pr)/ & +! (gamma_mg(qcvar)*qcvar**2)* & + mnuccc(k) = mnuccc(k) + sfac2*pi*pi/36._mg_pr*rhow* & + cdist1(k)* & + gamma_mg(7._mg_pr + pgam(k))*& +!RSH BUGFIX email 8/9/10 + bimm*(exp(aimm*( & + tfreeze - t(i,k))) - 1._mg_pr)/ & + lamc(k)**3/lamc(k)**3 +! nnuccc(k) = gamma_mg(qcvar+1._mg_pr)/ & +! (gamma_mg(qcvar)*qcvar)* & + nnuccc(k) = nnuccc(k) + sfac3*pi/6._mg_pr*cdist1(k)*& + gamma_mg(pgam(k) + 4._mg_pr)* & +!RSH BUGFIX email 8/9/10 + bimm*(exp(aimm*( & + tfreeze - t(i,k))) - 1._mg_pr)/lamc(k)**3 + end if + END IF + IF (limit_droplet_freeze_opt .EQ. 1) THEN +! hm add 11/17/06 +! make sure number of droplets frozen does not exceed available ice +! nuclei concentration +! this prevents 'runaway' droplet freezing + if (nnuccc(k) .gt. nnuccd(k)/cldm(i,k)) then + dum = (nnuccd(k)/cldm(i,k))/nnuccc(k) +! scale mixing ratio of droplet freezing with limit + mnuccc(k) = mnuccc(k)*dum + nnuccc(k) = nnuccd(k)/cldm(i,k) + end if + ELSE IF (limit_droplet_freeze_opt .EQ. 2) THEN + dum1 = nnuccc(k)*deltat + dum2 = ndust(i,k)/rho(i,k)/cldm(i,k) + if (dum1 .gt. dum2) then + dum = dum2/dum1 -!............................................................................... -! do not calculate effective radius here, -! but do some limiting - -! update cloud variables after instantaneous processes to get effective radius -! variables are in-cloud to calculate size dist parameters - - dumc(i,k) = max(qc(i,k)+qctend(i,k)*deltat,0._mg_pr)/cldm(i,k) - dumi(i,k) = max(qi(i,k)+qitend(i,k)*deltat,0._mg_pr)/cldm(i,k) - dumnc(i,k) = max(nc(i,k)+nctend(i,k)*deltat,0._mg_pr)/cldm(i,k) - dumni(i,k) = max(ni(i,k)+nitend(i,k)*deltat,0._mg_pr)/cldm(i,k) - -! limit in-cloud mixing ratio to reasonable value of 5 g kg-1 - - dumc(i,k)=min(dumc(i,k),in_cloud_limit) - dumi(i,k)=min(dumi(i,k),in_cloud_limit) - -!................... -! cloud ice effective radius - - - - - if (dumi(i,k).ge.qsmall) then - - -!diag++ - IF ( diag_id%qnidt_size_adj > 0 ) THEN - diag_4d(i,j,k,diag_pt%qnidt_size_adj ) = nitend(i,k) - END IF -!diag-- -! add upper limit to in-cloud number concentration to prevent numerical error - dumni(i,k)=min(dumni(i,k),dumi(i,k)*1.e20_mg_pr) - lami(k) = (gamma_mg(1._mg_pr+di_mg)*ci_mg* & - dumni(i,k)/dumi(i,k))**(1._mg_pr/di_mg) - lammax = 1._mg_pr/min_diam_ice - lammin = 1._mg_pr/(2._mg_pr*dcs) - - if (lami(k).lt.lammin) then - lami(k) = lammin - n0i(k) = lami(k)**(di_mg+1._mg_pr)*dumi(i,k)/(ci_mg*gamma_mg(1._mg_pr+di_mg)) - niic(i,k) = n0i(k)/lami(k) -! adjust number conc if needed to keep mean size in reasonable range - nitend(i,k)=(niic(i,k)*cldm(i,k)-ni(i,k))/deltat - else if (lami(k).gt.lammax) then - lami(k) = lammax - n0i(k) = lami(k)**(di_mg+1._mg_pr)*dumi(i,k)/(ci_mg*gamma_mg(1._mg_pr+di_mg)) - niic(i,k) = n0i(k)/lami(k) -! adjust number conc if needed to keep mean size in reasonable range - nitend(i,k)=(niic(i,k)*cldm(i,k)-ni(i,k))/deltat - end if - -!diag++ - IF ( diag_id%qnidt_size_adj > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_size_adj ) = nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_size_adj ) -!diag-- - end if - -!................... -! cloud droplet effective radius - - if (dumc(i,k).ge.qsmall) then - -!diag++ - IF ( diag_id%qndt_size_adj > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_size_adj ) = nctend(i,k) -!diag-- - -! add upper limit to in-cloud number concentration to prevent numerical error - dumnc(i,k)=min(dumnc(i,k),dumc(i,k)*1.e20_mg_pr) -!RSH BUGFIX email of 6/8/10 -! pgam(k)=0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr/rho(i,k))+0.2714_mg_pr - pgam(k)=0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr*rho(i,k))+0.2714_mg_pr - pgam(k)=1._mg_pr/(pgam(k)**2)-1._mg_pr - pgam(k)=max(pgam(k),2._mg_pr) - pgam(k)=min(pgam(k),15._mg_pr) - - lamc(k) = (pi/6._mg_pr*rhow*dumnc(i,k)*gamma_mg(pgam(k)+4._mg_pr)/ & - (dumc(i,k)*gamma_mg(pgam(k)+1._mg_pr)))**(1._mg_pr/3._mg_pr) -! lammin = (pgam(k)+1._mg_pr)/50.e-6_mg_pr -! lammax = (pgam(k)+1._mg_pr)/2.e-6_mg_pr - lammin = (pgam(k)+1._mg_pr)/max_diam_drop - lammax = (pgam(k)+1._mg_pr)/min_diam_drop - if (lamc(k).lt.lammin) then - lamc(k) = lammin - ncic(i,k) = 6._mg_pr*lamc(k)**3*dumc(i,k)* & - gamma_mg(pgam(k)+1._mg_pr)/ & - (pi*rhow*gamma_mg(pgam(k)+4._mg_pr)) -! adjust number conc if needed to keep mean size in reasonable range - nctend(i,k)=(ncic(i,k)*cldm(i,k)-nc(i,k))/deltat - - else if (lamc(k).gt.lammax) then - lamc(k) = lammax - ncic(i,k) = 6._mg_pr*lamc(k)**3*dumc(i,k)* & - gamma_mg(pgam(k)+1._mg_pr)/ & - (pi*rhow*gamma_mg(pgam(k)+4._mg_pr)) -! adjust number conc if needed to keep mean size in reasonable range - nctend(i,k)=(ncic(i,k)*cldm(i,k)-nc(i,k))/deltat - end if - -!diag++ - IF ( diag_id%qndt_size_adj > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_size_adj ) = nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_size_adj ) -!diag-- - end if - +! scale mixing ratio of droplet freezing with limit + mnuccc(k) = mnuccc(k)*dum + nnuccc(k) = nnuccc(k)*dum +!!! nnuccc(k) = nnuccd(k)/cldm(i,k) + end if + END IF + else ! (qcic(i,k) .ge. qsmall ) + mnuccc(k) = 0._mg_pr + nnuccc(k) = 0._mg_pr + end if ! (qcic(i,k) .ge. qsmall ) -!................... -! rain drop effective size +!....................................................................... +! snow self-aggregation from passarelli, 1978, used by reisner, 1998 +! this is hard-wired for bs = 0.4 for now +! ignore self-collection of cloud ice - dumr(i,k)=qrout(i,k)/cldmax(i,k) - dumnr(i,k)=max(nrout(i,k),0._mg_pr) + if (qniic(i,k) .ge. qsmall .and. t(i,k) .le. tfreeze) then + nsagg(k) = -1108._mg_pr*asn(i,k)*Eii* & + pi**((1._mg_pr - bs)/3._mg_pr)* & + rhosn**((-2._mg_pr - bs)/3._mg_pr)* & + rho(i,k)**((2._mg_pr + bs)/3._mg_pr)* & + qniic(i,k)**((2._mg_pr + bs)/3._mg_pr)* & + (nsic(i,k)*rho(i,k))** & + ((4._mg_pr-bs)/3._mg_pr)/ & + (4._mg_pr*720._mg_pr*rho(i,k)) + else + nsagg(k)=0._mg_pr + end if - if (dumr(i,k).ge.qsmall) then + IF (.NOT. one_ice) THEN - lamr(k) = (pi*rhow*dumnr(i,k)/dumr(i,k))**(1._mg_pr/3._mg_pr) +!....................................................................... +! accretion of cloud droplets onto snow/graupel +! here use continuous collection equation with +! simple gravitational collection kernel +! ignore collisions between droplets/cloud ice +! since minimum size ice particle for accretion is 50 - 150 micron -! check for slope -! hm 4/5/07, change lammax and lammin for rain and snow +! ignore collision of snow with droplets above freezing - lammax = 1._mg_pr/20.e-6_mg_pr - lammin = 1._mg_pr/500.e-6_mg_pr + if (qniic(i,k) .ge. qsmall .and. & + t(i,k) .le. tfreeze .and. & + qcic(i,k) .ge. qsmall) then -! adjust vars +! put in size dependent collection efficiency +! mean diameter of snow is area-weighted, since +! accretion is function of crystal geometric area +! collection efficiency is from stoke's law (Thompson et al. 2004) - if (lamr(k).lt.lammin) then - lamr(k) = lammin - else if (lamr(k).gt.lammax) then - lamr(k) = lammax - end if + dc0 = (pgam(k) + 1._mg_pr)/lamc(k) + ds0 = 1._mg_pr/lams(k) + dum = dc0*dc0*uns(k)*rhow/(9._mg_pr*mu(i,k)*ds0) + eci = dum*dum/((dum + 0.4_mg_pr)*(dum + 0.4_mg_pr)) + eci = max(eci, 0._mg_pr) + eci = min(eci, 1._mg_pr) - lsc_rain_size(i,j,k) = 3._mg_pr/lamr(k)*1.e6_mg_pr - - else - - lsc_rain_size(i,j,k) = 100._mg_pr - - end if - - +! no impact of sub-grid distribution of qc since psacws +! is linear in qc -end do k_loop_sedi + psacws(k) = pi/4._mg_pr*asn(i,k)*qcic(i,k)*rho(i,k)* & + n0s(k)*Eci*gamma_mg(bs + 3._mg_pr)/ & + lams(k)**(bs + 3._mg_pr) + npsacws(k) = pi/4._mg_pr*asn(i,k)*ncic(i,k)*rho(i,k)* & + n0s(k)*Eci*gamma_mg(bs + 3._mg_pr)/ & + lams(k)**(bs + 3._mg_pr) + else + psacws(k) = 0._mg_pr + npsacws(k) = 0._mg_pr + end if + psacws_o(k) = 0._mg_pr + npsacws_o(k) = 0._mg_pr + ELSE !one_ice + psacws_o(k) = 0._mg_pr + npsacws_o(k) =0._mg_pr + IF (lami(k) .gt. 1._mg_pr/50.e-6_mg_pr) THEN +! provisional snow number and mass weighted mean fallspeed (m/s) + ums(k) = min ( & + asn(i,k)*gamma_mg(4._mg_pr + bs)/ & + (6._mg_pr*lami(k)**bs), & + max_vt_snow) + uns(k) = min ( & + asn(i,k)*gamma_mg(1._mg_pr + bs)/ & + lami(k)**bs, max_vt_snow) + +!PROBLEM k-1 indices 11/20/11 + qiic(i,k) = (rho(i,k-1)*ums(k-1)*qiic(i,k-1)* & + cldmax(i,k-1) + & + (rho(i,k)*dz(i,k)*((psacws_o(k-1))* & + cldm(i,k))))/ & + (dum*rho(i,k)*cldmax(i,k)) + if (qiic(i,k) .ge. qsmall .and. & + t(i,k) .le. tfreeze .and. & + qcic(i,k) .ge. qsmall) then -500 CONTINUE +! put in size dependent collection efficiency +! mean diameter of snow is area-weighted, since +! accretion is function of crystal geometric area +! collection efficiency is from stoke's law (Thompson et al. 2004) + dc0 = (pgam(k) + 1._mg_pr)/lamc(k) + ds0 = 1._mg_pr/lami(k) + dum = dc0*dc0*uns(k)*rhow/(9._mg_pr*mu(i,k)*ds0) + eci = dum*dum/((dum + 0.4_mg_pr)*(dum + 0.4_mg_pr)) + eci = max(eci, 0._mg_pr) + eci = min(eci, 1._mg_pr) +! no impact of sub-grid distribution of qc since psacws +! is linear in qc + psacws_o(k) = pi/4._mg_pr*asn(i,k)*qcic(i,k)* & + rho(i,k)*n0i(k)*Eci* & + gamma_mg(bs + 3._mg_pr)/ & + lami(k)**(bs + 3._mg_pr) + npsacws_o(k) = pi/4._mg_pr*asn(i,k)*ncic(i,k)* & + rho(i,k)*n0i(k)*Eci* & + gamma_mg(bs + 3._mg_pr)/ & + lami(k)**(bs + 3._mg_pr) + else + psacws_o(k) = 0._mg_pr + npsacws_o(k) = 0._mg_pr + end if + psacws(k) = 0._mg_pr + npsacws(k) = 0._mg_pr + END IF !size + END IF !one_ice + + IF (.NOT. one_ice) THEN +!....................................................................... +! accretion of rain water by snow +! formula from ikawa and saito, 1991, used by reisner et al., 1998 - deltat = deltatin + if (qric(i,k) .ge. 1.e-8_mg_pr .and. & + qniic(i,k) .ge. 1.e-8_mg_pr .and. & + t(i,k).le. tfreeze) then + pracs(k) = pi*pi*ecr*(((1.2_mg_pr*umr(k) - & + 0.95_mg_pr*ums(k))**2 + & + 0.08_mg_pr*ums(k)*umr(k))**0.5_mg_pr*rhow* & + rho(i,k)*n0r(k)*n0s(k)* & + (5._mg_pr/(lamr(k)**6*lams(k)) + & + 2._mg_pr/(lamr(k)**5*lams(k)**2) + & + 0.5_mg_pr/(lamr(k)**4*lams(k)**3))) + + npracs(k) = pi/2._mg_pr*rho(i,k)*ecr*(1.7_mg_pr* & + (unr(k) - uns(k))**2 + & + 0.3_mg_pr*unr(k)*uns(k))**0.5_mg_pr* & + n0r(k)*n0s(k)* & + (1._mg_pr/(lamr(k)**3*lams(k)) + & + 1._mg_pr/(lamr(k)**2*lams(k)**2) + & + 1._mg_pr/(lamr(k)*lams(k)**3)) + else + pracs(k)=0._mg_pr + npracs(k)=0._mg_pr + end if + ELSE !(.NOT. one_ice) + pracs(k)=0._mg_pr + npracs(k)=0._mg_pr + END IF ! (.NOT. one_ice) + IF (.NOT. one_ice) THEN +!....................................................................... +! heterogeneous freezing of rain drops +! follows from Bigg (1953) + if (t(i,k) .lt. tfreeze -4._mg_pr .and. & + qric(i,k) .ge. qsmall) then + mnuccr(k) = 20._mg_pr*pi*pi*rhow*nric(i,k)*bimm* & +!RSH BUGFIX email 8/9/10 + (exp(aimm*(tfreeze - t(i,k))) - 1._mg_pr)/ & + lamr(k)**3/lamr(k)**3 - do k=1,kdim -! if updated q (after microphysics) is zero, then ensure updated n is also zero + nnuccr(k) = pi*nric(i,k)*bimm* & +!RSH BUGFIX email 8/9/10 + (exp(aimm*(tfreeze - t(i,k))) - 1._mg_pr)/ & + lamr(k)**3 + else + mnuccr(k) = 0._mg_pr + nnuccr(k) = 0._mg_pr + end if + ELSE ! (.NOT. one_ice) + mnuccr(k) = 0._mg_pr + nnuccr(k) = 0._mg_pr + END IF ! (.NOT. one_ice) -!diag++ - IF ( diag_id%qndt_fill2 > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_fill2 ) = nctend(i,k) +!....................................................................... +! accretion of cloud liquid water by rain +! formula from Khrouditnov and Kogan (2000) +! gravitational collection kernel, droplet fall speed neglected - IF ( diag_id%qnidt_fill2 > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_fill2 ) = nitend(i,k) + if (qric(i,k) .ge. qsmall .and. & + qcic(i,k) .ge. qsmall) then -!diag-- +! include sub-grid distribution of cloud water +! pra(k) = gamma_mg(qcvar+1.15_mg_pr)/ & +! (gamma_mg(qcvar)*qcvar**1.15_mg_pr) * & + pra(k) = sfac4*67._mg_pr* & + (qcic(i,k)*qric(i,k))**1.15_mg_pr + npra(k) = pra(k)/(qcic(i,k)/ncic(i,k)) + else + pra(k) = 0._mg_pr + npra(k) = 0._mg_pr + end if - if (qc(i,k)+qctend(i,k)*deltat.lt.qsmall) nctend(i,k)=-nc(i,k)/deltat - if (qi(i,k)+qitend(i,k)*deltat.lt.qsmall) nitend(i,k)=-ni(i,k)/deltat +!....................................................................... +! Self-collection of rain drops +! from Beheng(1994) + if (qric(i,k) .ge. qsmall) then + nragg(k) = -8._mg_pr*nric(i,k)*qric(i,k)*rho(i,k) + else + nragg(k) = 0._mg_pr + end if -!diag++ - IF ( diag_id%qndt_fill2 > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_fill2 ) = nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_fill2 ) +!....................................................................... +! Accretion of cloud ice by snow +! For this calculation, it is assumed that the Vs >> Vi +! and Ds >> Di for continuous collection - IF ( diag_id%qnidt_fill2 > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_fill2 ) = nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_fill2 ) + IF (.NOT. one_ice) THEN + if (qniic(i,k) .ge. qsmall .and. & + qiic(i,k) .ge. qsmall .and. & + t(i,k) .le. tfreeze) then + prai(k) = pi/4._mg_pr*asn(i,k)*qiic(i,k)*rho(i,k)* & + n0s(k)*Eii*gamma_mg(bs + 3._mg_pr)/ & + lams(k)**(bs + 3._mg_pr) + nprai(k) = pi/4._mg_pr*asn(i,k)*niic(i,k)*rho(i,k)* & + n0s(k)*Eii*gamma_mg(bs + 3._mg_pr)/ & + lams(k)**(bs + 3._mg_pr) + else + prai(k) = 0._mg_pr + nprai(k) = 0._mg_pr + end if + ELSE + prai(k) = 0._mg_pr + nprai(k) = 0._mg_pr + END IF -!diag-- - end do +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! calculate evaporation/sublimation of rain and snow +! note: evaporation/sublimation occurs only in cloud-free portion of +! grid cell +! in-cloud condensation/deposition of rain and snow is neglected +! except for transfer of cloud water to snow through bergeron process +! initialize evap/sub tendncies + pre(k) = 0._mg_pr + prds(k) = 0._mg_pr +! evaporation of rain +! only calculate if there is some precip fraction > cloud fraction +!RSH 8/7/12: return to using qsmall to avoid model blowups +! if (qcic(i,k) + qiic(i,k) .lt. 1.e-6_mg_pr .or. & +! cldmax(i,k) .gt. cldm(i,k)) then + if (qcic(i,k) + qiic(i,k) .lt. qsmall .or. & + cldmax(i,k) .gt. cldm(i,k)) then -end do i_loop_3 +! set temporary cloud fraction to zero if cloud water + ice is very small +! this will ensure that evaporation/sublimation of precip occurs over +! entire grid cell, since min cloud fraction is specified otherwise +!RSH 8/7/12: return to using qsmall to avoid model blowups +! if (qcic(i,k) + qiic(i,k) .lt. 1.e-6_mg_pr) then + if (qcic(i,k) + qiic(i,k) .lt. qsmall) then + dum = 0._mg_pr + else + dum = cldm(i,k) + end if + ttmp = t(i,k) +! recalculate saturation vapor pressure for liquid and ice + esl(i,k) = polysvp_l(t(i,k)) + esi(i,k) = polysvp_i(t(i,k)) + esn = esl(i,k) + qsn = min ( & + epsqs*esn/(pfull(i,k) - (1._mg_pr - epsqs)*esn), & + 1._mg_pr) + qsn = max (qsn, 0._mg_pr) +! MAKE SURE ICE SATURATION DOESN'T EXCEED WATER SAT. NEAR FREEZING + IF (esi(i,k) .GT. esl(i,k)) esi(i,k) = esl(i,k) +! calculate q for out-of-cloud region + qclr = (q(i,k) - dum*qsn)/(1._mg_pr - dum) + if (qric(i,k) .ge. qsmall) then + qvs = 0.622_mg_pr*esl(i,k)/(pfull(i,k) - d378*esl(i,k)) + dqsdt = xxlv*qvs/(rv*t(i,k)**2) + ab = 1._mg_pr + dqsdt*xxlv/cpp + epsr = 2._mg_pr*pi*n0r(k)*rho(i,k)*Dv(i,k)* & + (f1r/(lamr(k)*lamr(k)) + & + f2r*(arn(i,k)*rho(i,k)/mu(i,k))**0.5_mg_pr* & + sc(i,k)**(1._mg_pr/3._mg_pr)* & + gamma_mg(5._mg_pr/2._mg_pr + br/2._mg_pr)/ & + (lamr(k)**(5._mg_pr/2._mg_pr + br/2._mg_pr))) + pre(k) = epsr*(qclr - qvs)/ab -! - rh_adj_opt: IF ( no_rh_adj_opt .EQ. 0 ) THEN +! only evaporate in out-of-cloud region +! and distribute across cldmax + pre(k) = min(pre(k)*(cldmax(i,k) - dum), 0._mg_pr) + pre(k) = pre(k)/cldmax(i,k) + end if + IF (.NOT. one_ice) THEN - allow_super_ice_if1: IF ( Nml%super_ice_opt .EQ. 0 ) THEN +! sublimation of snow + if (qniic(i,k) .ge. qsmall) then + qvi = 0.622_mg_pr*esi(i,k)/ & + (pfull(i,k) - d378*esi(i,k)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi(i,k) = 1._mg_pr + dqsidt*xxls/cpp + dumt1 = 2._mg_pr*pi*n0s(k)*rho(i,k)*Dv(i,k) + dumt2 = sc(i,k)**(1._mg_pr/3._mg_pr)* & + gamma_mg(5._mg_pr/2._mg_pr + bs/2._mg_pr)/ & + (lams(k)**(5._mg_pr/2._mg_pr + bs/2._mg_pr)) + epss = 2._mg_pr*pi*n0s(k)*rho(i,k)*Dv(i,k)* & + (f1s/(lams(k)*lams(k)) + & + f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_mg_pr* & + sc(i,k)**(1._mg_pr/3._mg_pr)* & + gamma_mg(5._mg_pr/2._mg_pr + bs/2._mg_pr)/ & + (lams(k)**(5._mg_pr/2._mg_pr + bs/2._mg_pr))) + prds(k) = epss*(qclr - qvi)/abi(i,k) + +! only sublimate in out-of-cloud region and distribute over cldmax + prds(k) = min(prds(k)*(cldmax(i,k) - dum), 0._mg_pr) + prds(k) = prds(k)/cldmax(i,k) + end if + ELSE ! (.NOT. one_ice) + prds(k) = 0._mg_pr + END IF ! (.NOT. one_ice) -!--++ -!cms remove supersat +! hm add 2/2/07, make sure RH not pushed above 100% +! get updated RH at end of time step based on +! cloud water/ice condensation/evap - DO k=1,kdim - DO i=1,idim + qtmp = q(i,k) - (D_eros_l(i,k) + D_eros_i(i,k) + & + cmel(i,k) + cmei(i,k) + qvdep_qi(i,k) + & + (pre(k) + prds(k))*cldmax(i,k))*deltat - ttmp=t(i,k)+tlat(i,k)/cpp*deltat - qtmp=q(i,k)+qvlat(i,k)*deltat +!bug? 2/12/09 +!!$ ttmp=t(i,k)+((D_eros_l(i,k)+cmel(i,k)+pre(k)*cldmax(i,k))*xxlv+ & +!!$ (D_eros_i(i,k)+cmei(i,k)+prds(k))*cldmax(i,k)*xxls)*deltat/cpp - eslt=polysvp_l(ttmp) - esit=polysvp_i(ttmp) - esn=min(esit, eslt) + ttmp = t(i,k) + ((D_eros_l(i,k) + cmel(i,k) + & + pre(k)*cldmax(i,k))*xxlv + & + (D_eros_i(i,k) + cmei(i,k) + qvdep_qi(i,k) + & + prds(k)*cldmax(i,k))*xxls)*deltat/cpp + ttmp = MAX(lowest_temp_for_sublimation, & + min(ttmp, 323._mg_pr)) + eslt = polysvp_l(ttmp) + esit = polysvp_i(ttmp) + esn = eslt - tmp2 = pfull(i,k) - d378*esn - tmp2 = max(tmp2,esn) - - call lookup_des(ttmp,tmp7) - tmp7= d622 *pfull(i,k) *tmp7/tmp2/tmp2 - tmp2 = d622*esn/tmp2 - -!the following is not consistent with the apportioning below ... - tmp3 = tmp7 *(min(1.,max(0.,0.05*(ttmp-tfreeze+20._mg_pr)))*hlv + & - min(1.,max(0.,0.05*(tfreeze -ttmp )))*hls)/cp_air - - !compute excess over saturation - tmp1 = max(0., qtmp -tmp2)/(1._mg_pr+tmp3) - - - !change vapor content - qvlat(i,k) = qvlat(i,k)-tmp1/deltat - - + qsn = min (epsqs*esn/ & + (pfull(i,k) - (1._mg_pr - epsqs)*esn), 1._mg_pr) + qsn = max(qsn, 0._mg_pr) + +! modify precip evaporation rate if q > qsat + if (qtmp .gt. qsn ) then + if (pre(k) + prds(k) .lt. -1.e-20_mg_pr) then + dum1 = pre(k)/(pre(k) + prds(k)) +! recalculate q and t after cloud water cond but without precip evap + qtmp = q(i,k) - (D_eros_l(i,k) + D_eros_i(i,k) + & + cmel(i,k) + cmei(i,k) + qvdep_qi(i,k))*deltat -!CHANGE - !add in excess to cloud condensate, change cloud area and - !increment temperature - if (ttmp .le. tfreeze-40. .and. tmp1 .gt. 0.) then +!bug 2/12/09 +!!$ ttmp=t(i,k)+(D_eros_l(i,k)+cmel(i,k)*xxlv+ & +!!$ D_eros_i(i,k)+cmei(i,k)*xxls)*deltat/cpp - IF ( Nml%super_choice ) THEN - qitend(i,k)= qitend(i,k) + tmp1/deltat + ttmp = t(i,k) + ((D_eros_l(i,k) + cmel(i,k))*xxlv +& + (D_eros_i(i,k) + cmei(i,k) + qvdep_qi(i,k))*& + xxls)*deltat/cpp + eslt = polysvp_l(ttmp) + esit = polysvp_i(ttmp) + esn = eslt + + qsn = min( epsqs*esn/ & + (pfull(i,k) - (1._mg_pr - epsqs)*esn), 1._mg_pr) + qsn=max(qsn, 0._mg_pr) + dum = (qtmp - qsn)/ & + (1._mg_pr + xxlv**2*qsn/(cpp*rv*ttmp**2)) + dum = min(dum, 0._mg_pr) -!diag++ - IF ( diag_id%ice_adj > 0 ) & - diag_4d(i,j,k,diag_pt%ice_adj) = tmp1/deltat -!diag-- +! modify rates if needed, divide by cldmax to get local (in-precip) value + pre(k) = dum*dum1/deltat/cldmax(i,k) + qsn = min( epsqs*esit/ & + (pfull(i,k) - (1._mg_pr - epsqs)*esit), & + 1._mg_pr) + dum = (qtmp - qsn)/(1._mg_pr + xxls**2*qsn/ & + (cpp*rv*ttmp**2)) + dum = min(dum, 0._mg_pr) + prds(k) = dum*(1._mg_pr - dum1)/deltat/cldmax(i,k) + end if + end if + end if + + IF (.NOT. one_ice) THEN - - ELSE +! bergeron process - evaporation of droplets and deposition onto snow +! bergeron process for snow is neglected for now............. + if (do_berg_snow ) then + if (qniic(i,k) .ge. qsmall .and. & + qcic(i,k) .ge. qsmall .and. & + t(i,k) .lt. tfreeze) then + qvs = 0.622_mg_pr*esl(i,k)/ & + (pfull(i,k) - d378*esl(i,k)) + qvi = 0.622_mg_pr*esi(i,k)/ & + (pfull(i,k) - d378*esi(i,k)) + +!8/1/12: place limits to avoid negative values which may occur at low pfull +! prevents model blowups + qvs = MAX(0._mg_pr, MIN(qvs, 1.0_mg_pr)) + qvi = MAX(0._mg_pr, MIN(qvi, 1.0_mg_pr)) + dqsidt = xxls*qvi/(rv*t(i,k)**2) + abi(i,k) = 1._mg_pr + dqsidt*xxls/cpp + epss = 2._mg_pr*pi*n0s(k)*rho(i,k)*Dv(i,k)* & + (f1s/(lams(k)*lams(k)) + & + f2s*(asn(i,k)*rho(i,k)/mu(i,k))**0.5_mg_pr* & + sc(i,k)**(1._mg_pr/3._mg_pr)* & + gamma_mg(5._mg_pr/2._mg_pr + bs/2._mg_pr)/ & + (lams(k)**(5._mg_pr/2._mg_pr + bs/2._mg_pr))) +!cms 2009/3/2 bergs(k) = epss*(qvs - qvi)/abi(i,k) + bergs(k) = epss*(qvs - qvi)/abi(i,k) + else + bergs(k) = 0._mg_pr + end if + else + bergs(k) = 0._mg_pr + endif + ELSE + bergs(k) = 0._mg_pr + END IF +!cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! conservation to ensure no negative values of cloud water/precipitation +! in case microphysical process rates are large - prect(i) = prect(i)+ tmp1/deltat * pdel(i,k)/grav /rhow - preci(i) = preci(i)+ tmp1/deltat * pdel(i,k)/grav /rhow - - qsout(i,k)=qsout(i,k)+ tmp1 +! make sure and use end-of-time step values for cloud water, ice, due +! condensation/deposition - asnowrt(i,k) = asnowrt(i,k) + tmp1/deltat* & - pdel(i,k)/grav /rhow - atotrt(i,k) = atotrt(i,k) + tmp1/deltat * & - pdel(i,k)/grav /rhow - +! note: for check on conservation, processes are multiplied by omsm +! to prevent problems due to round off error - END IF +! since activation/nucleation processes are fast, need to take into account +! factor mtime = mixing timescale in cloud / model time step +! mixing time can be interpreted as cloud depth divided by sub-grid +! vertical velocity +! for now mixing timescale is assumed to be 20 min +! could possibly be estimated better from model variables + IF (total_activation) THEN +! since act. is assumed to take place at cloud base: +!cms mtime = deltat/1200._mg_pr + mtime = 1._mg_pr + ELSE IF (dqa_activation) THEN +! since Yi's formulation assumes activation at lateral cloud boundaries + mtime=1._mg_pr + ENDIF + + qce = (qc(i,k) + (D_eros_l(i,k) + cmel(i,k) - & + berg(i,k))*deltat) + nce = (nc(i,k) + npccn(k)*deltat*mtime)/cldm(i,k) + qie = (qi(i,k) + (D_eros_i(i,k) + cmei(i,k) + & + berg(i,k) + qvdep_qi(i,k))*deltat) + nie = (ni(i,k) + nnuccd(k)*deltat*mtime)/cldm(i,k) +! conservation of qc + dum = (prc(k) + pra(k) + mnuccc(k) + & + psacws(k) + bergs(k) + psacws_o(k))*cldm(i,k)*deltat + if (dum .gt. qce) then + if (dum .gt. 1.e-30_mg_pr) then + ratio = qce/deltat/cldm(i,k)/(prc(k) + pra(k) + & + mnuccc(k) + psacws(k) + psacws_o(k) + & + bergs(k))*omsm + else + ratio = 0._mg_pr + endif + prc(k) = prc(k)*ratio + pra(k) = pra(k)*ratio + mnuccc(k) = mnuccc(k)*ratio + psacws(k) = psacws(k)*ratio + psacws_o(k) = psacws_o(k)*ratio + bergs(k) = bergs(k)*ratio + end if - IF ( .NOT. Nml%do_pdf_clouds ) THEN - IF ( .NOT. tiedtke_qa_test ) THEN - IF ( Nml%super_choice ) THEN - if (limit_conv_cloud_frac) then - tmp2s = ahuco(i,k) - else - tmp2s = 0. - endif - SA(i,k) = SA(i,k) + (1.-qa_upd(i,k) -tmp2s) - qa_upd(i,k) = 1. - tmp2s - IF (super_act) THEN - - nitend(i,k)= nitend(i,k) + crystal1(i,k)/rho(i,k) *(1. - qa_upd(i,k)-tmp2s) -!diag++ - IF ( diag_id%qnidt_super > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_super ) = crystal1(i,k)/rho(i,k) *(1. - qa_upd(i,k)-tmp2s) -!diag-- - END IF - - END IF - END IF - END IF - tlat(i,k) = tlat(i,k) + hls*tmp1/deltat - end if - if (ttmp .gt. tfreeze-40. .and. tmp1 .gt. 0.) then - - IF ( Nml%super_choice ) THEN - qctend(i,k) = qctend(i,k) + tmp1/deltat -!diag++ - IF(diag_id%liq_adj > 0 ) & - diag_4d(i,j,k,diag_pt%liq_adj) = tmp1/deltat -!diag-- - ELSE - prect(i) = prect(i)+ tmp1/deltat * pdel(i,k)/grav /rhow - - qrout(i,k)=qrout(i,k)+ tmp1 - atotrt(i,k) = atotrt(i,k) + tmp1/deltat * & - pdel(i,k)/grav /rhow - END IF +! conservation of nc + dum = (nprc1(k) + npra(k) + nnuccc(k) + & + npsacws(k) + npsacws_o(k) - nsubc(k) - & + nerosc(i,k))*deltat + if (dum .gt. nce) then + if (dum .gt. 1.e-30_mg_pr) then + ratio = nce/deltat/(nprc1(k) + npra(k) + nnuccc(k) + & + npsacws(k) + npsacws_o(k) - nsubc(k) - & + nerosc(i,k))*omsm + else + ratio = 0._mg_pr + end if + nprc1(k) = nprc1(k)*ratio + npra(k) = npra(k)*ratio + nnuccc(k) = nnuccc(k)*ratio + npsacws(k) = npsacws(k)*ratio + npsacws_o(k) = npsacws_o(k)*ratio + nsubc(k) = nsubc(k)*ratio + nerosc(i,k) = nerosc(i,k)*ratio + end if +! conservation of qi + dum = (-mnuccc(k) + prci(k) + & + prai(k) - psacws_o(k))*cldm(i,k)*deltat + if (dum .gt. qie) then + if (dum .gt. 1.e-30_mg_pr) then + ratio = (qie/deltat/cldm(i,k) + mnuccc(k) + & + psacws_o(k))/(prci(k) + prai(k))*omsm + else + ratio = 0._mg_pr + end if + prci(k) = prci(k)*ratio + prai(k) = prai(k)*ratio + psacws_o(k) = psacws_o(k)*ratio + end if - IF (.NOT. Nml%do_pdf_clouds ) THEN - IF ( .NOT. tiedtke_qa_test ) THEN - IF ( Nml%super_choice ) THEN - if (limit_conv_cloud_frac) then - tmp2s = ahuco(i,k) - else - tmp2s = 0. - endif +! conservation of ni + dum = (nprci(k) + & + nprai(k) - nsubi(k) - nerosi(i,k))*deltat + if (dum .gt. nie) then + if (dum .gt. 1.e-30_mg_pr) then + ratio = (nie/deltat)/(nprci(k) + nprai(k) & + - nsubi(k) - nerosi(i,k))*omsm + else + ratio = 0._mg_pr + end if + nprci(k) = nprci(k)*ratio + nprai(k) = nprai(k)*ratio + nsubi(k) = nsubi(k)*ratio + nerosi(i,k) = nerosi(i,k)*ratio + end if +! for preciptiation conservation, use logic that vertical integral +! of tendency from current level to top of model (i.e., qrtot) cannot +! be negative - if (max(diag_id%qadt_super,diag_id%qa_super_col) > 0) then - diag_4d(i,j,k,diag_pt%qadt_super ) = (1.-qa_upd(i,k)-tmp2s) * inv_dtcloud - end if +! conservation of rain mixing rat - SA(i,k) = SA(i,k) + (1.-qa_upd(i,k) -tmp2s) - qa_upd(i,k) = 1. - tmp2s - IF (super_act) THEN - nctend(i,k)= nctend(i,k) + drop2(i,k) *(1. - qa_upd(i,k)-tmp2s) - -!diag++ - IF ( diag_id%qndt_super > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_super ) = drop2(i,k) *(1. - qa_upd(i,k)-tmp2s) -!diag-- - END IF + if (((prc(k) + pra(k))*cldm(i,k) + & + (-mnuccr(k) + pre(k) - pracs(k))*cldmax(i,k))* & + rho(i,k)*dz(i,k) + qrtot .lt. 0._mg_pr) then + if (-pre(k) + pracs(k) + mnuccr(k) .ge. qsmall) then + ratio = (qrtot/(rho(i,k)*dz(i,k)) + (prc(k) + & + pra(k))*cldm(i,k))/& + ((-pre(k) + pracs(k) + mnuccr(k))* & + cldmax(i,k))*omsm + else + ratio = 0._mg_pr + end if + pre(k) = pre(k)*ratio + pracs(k) = pracs(k)*ratio + mnuccr(k) = mnuccr(k)*ratio + end if - END IF - END IF - END IF +! conservation of nr +! for now neglect evaporation of nr - tlat(i,k) = tlat(i,k) + hlv*tmp1/deltat - end if + IF (rain_evap_opt) THEN +! calculate evaporation of nr + if (pre(k) .lt. 0._mg_pr .and. & + qric(i,k) .ge. qsmall) then + nsubr(k) = pre(k)/qric(i,k)*nric(i,k) + else + nsubr(k) = 0._mg_pr + end if + ELSE + nsubr(k)=0._mg_pr + END IF + + if ((nprc(k)*cldm(i,k) + (-nnuccr(k) + nsubr(k) - & + npracs(k) + nragg(k))*cldmax(i,k))*rho(i,k)* & + dz(i,k) + nrtot .lt. 0._mg_pr) then + if (-nsubr(k) - nragg(k) + npracs(k) + & + nnuccr(k) .ge. qsmall) then + ratio = (nrtot/(rho(i,k)*dz(i,k)) + & + nprc(k)*cldm(i,k))/ & + ((-nsubr(k) - nragg(k) + npracs(k) + & + nnuccr(k))*cldmax(i,k))*omsm + else + ratio = 0._mg_pr + end if + nsubr(k) = nsubr(k)*ratio + npracs(k) = npracs(k)*ratio + nnuccr(k) = nnuccr(k)*ratio + nragg(k) = nragg(k)*ratio + end if - END DO - END DO -!-- +! conservation of snow mix ratio + if (((bergs(k) + psacws(k) + prai(k) + & + prci(k))*cldm(i,k) + & + (pracs(k) + mnuccr(k) + prds(k))*cldmax(i,k))* & + rho(i,k)*dz(i,k) + qstot .lt. 0._mg_pr) then + if (-prds(k) .ge. qsmall) then + ratio = (qstot/(rho(i,k)*dz(i,k)) + (bergs(k) + & + psacws(k) + prai(k) + prci(k))*cldm(i,k) + & + (pracs(k) + mnuccr(k))*cldmax(i,k))/ & + (-prds(k)*cldmax(i,k))*omsm + else + ratio =0._mg_pr + end if + prds(k) = prds(k)*ratio + end if -ELSE IF ( Nml%super_ice_opt .GE. 1 ) THEN !allow_super_ice_if1 +! conservation of ns - sat_adj_opt_if: IF ( sat_adj_opt .EQ. 1 ) THEN - DO k=1,kdim - DO i=1,idim - ttmp=t(i,k)+tlat(i,k)/cpp*deltat - qtmp=q(i,k)+qvlat(i,k)*deltat +! calculate loss of number due to sublimation + IF (subl_snow) THEN + if (prds(k) .lt. 0._mg_pr .and. & + qniic(i,k) .ge. qsmall) then + nsubs(k) = prds(k)/qniic(i,k)*nsic(i,k) + else + nsubs(k) = 0._mg_pr + end if - qs_t=polysvp_l(ttmp) +! neglect sublimation of ns + ELSE + nsubs(k) = 0._mg_pr + END IF + + if ((nprci(k)*cldm(i,k) + (nnuccr(k) + nsubs(k) + & + nsagg(k))*cldmax(i,k))*& + rho (i,k)*dz(i,k) + nstot .lt. 0._mg_pr) then + if (-nsubs(k) - nsagg(k) .ge. qsmall) then + ratio = (nstot/(rho(i,k)*dz(i,k)) + nprci(k)* & + cldm(i,k) + & + nnuccr(k)*cldmax(i,k))/ & + ((-nsubs(k) - nsagg(k))*cldmax(i,k))*omsm + else + ratio =0._mg_pr + end if + nsubs(k) = nsubs(k)*ratio + nsagg(k) = nsagg(k)*ratio + end if - !calculate denominator in qsat formula - qs_d = pfull(i,k) - d378*qs_t - !limit denominator to esat, and thus qs to d622 - !this is done to avoid blow up in the upper stratosphere - !where pfull ~ esat - qs_d = max(qs_d,qs_t) - !calculate qs - qs_t=d622*qs_t/qs_d +! get tendencies due to microphysical conversion processes +! note: tendencies are multiplied by appropaiate cloud/precip +! fraction to get grid-scale values +! note: cmei,cmel are already grid-average values + qvlat(i,k) = qvlat(i,k) - & + (pre(k) + prds(k))*cldmax(i,k) - cmel(i,k) - & + cmei(i,k) - D_eros_l(i,k) - D_eros_i(i,k) - & + qvdep_qi(i,k) + tlat(i,k) = tlat(i,k) + ((pre(k)*cldmax(i,k) + & + cmel(i,k) + D_eros_l(i,k))*xxlv + & + (prds(k)*cldmax(i,k) + cmei(i,k) + & + D_eros_i(i,k) + qvdep_qi(i,k))*xxls + & + ((bergs(k) + psacws(k) + psacws_o(k) + & + mnuccc(k))*cldm(i,k) + (mnuccr(k) + & + pracs(k))*cldmax(i,k) + berg(i,k))*xlf) + qctend(i,k) = qctend(i,k) + & + (-pra(k) - prc(k) - mnuccc(k) - & + psacws(k) - psacws_o(k) - bergs(k))* & + cldm(i,k) + & + cmel(i,k) - berg(i,k) + D_eros_l(i,k) + qitend(i,k) = qitend(i,k) + & + (mnuccc(k) - prci(k) - prai(k) + & + psacws_o(k))*cldm(i,k) + cmei(i,k) + & + berg(i,k) + D_eros_i(i,k) + qvdep_qi(i,k) + qrtend(i,k) = qrtend(i,k) + & + (pra(k) + prc(k))*cldm(i,k) + (pre(k) - & + pracs(k) - mnuccr(k))*cldmax(i,k) + qnitend(i,k) = qnitend(i,k) + & + (prai(k) + psacws(k) + prci(k) + & + bergs(k))*cldm(i,k) + & + (prds(k) + pracs(k) + mnuccr(k))* & + cldmax(i,k) +! multiply activation/nucleation by mtime to account for fast timescale + dumd = nctend(i,k) + nctend(i,k) = nctend(i,k) + npccn(k)*mtime + & + (-nnuccc(k) - npsacws(k) - npsacws_o(k) + & + nsubc(k) + nerosc(i,k) - npra(k) - & + nprc1(k))*cldm(i,k) + nitend(i,k) = nitend(i,k) + nnuccd(k)*mtime + & + (nsubi(k) + nerosi(i,k) - nprci(k) - & + nprai(k))*cldm(i,k) + nstend(i,k) = nstend(i,k) + (nsubs(k) + & + nsagg(k) + nnuccr(k))*cldmax(i,k) + & + nprci(k)*cldm(i,k) + nrtend(i,k) = nrtend(i,k) + & + nprc(k)*cldm(i,k) + (nsubr(k) - npracs(k) - & + nnuccr(k) + nragg(k))*cldmax(i,k) - !compute super saturation - tmp1 = max(0., ( qtmp -qs_t ) ) / (1.+ hlv*qs_t/(rvgas*ttmp**2) * hlv /cp_air ) +! make sure that nc and ni at advanced time step do not exceed +! maximum (existing N + source terms*dt), which is possible due to +! fast nucleation timescale - !change vapor content - qvlat(i,k) = qvlat(i,k)-tmp1/deltat +! diag++ + IF (diag_id%qndt_nucclim + & + diag_id%qn_nucclim_col > 0) THEN + nucclim(k) = nctend(i,k) + END IF + IF (diag_id%qnidt_nucclim1 + & + diag_id%qni_nucclim1_col > 0 ) THEN + nucclim1i(k) = nitend(i,k) + END IF +! diag-- + + if (nctend(i,k) .gt. 0._mg_pr .and. & + nc(i,k) + nctend(i,k)*deltat .gt. ncmax) then + nctend(i,k) = max(0._mg_pr, (ncmax - nc(i,k))/deltat) + end if + if (nitend(i,k) .gt. 0._mg_pr .and. & + ni(i,k) + nitend(i,k)*deltat .gt. nimax) then + nitend(i,k) = max(0._mg_pr, (nimax - ni(i,k))/deltat) + end if + +! diag++ + IF (diag_id%qndt_nucclim + & + diag_id%qn_nucclim_col > 0) THEN + nucclim(k) = nctend(i,k) - nucclim(k) + END IF + IF (diag_id%qnidt_nucclim1 + & + diag_id%qni_nucclim1_col > 0) THEN + nucclim1i(k) = nitend(i,k) - nucclim1i(k) + END IF +! diag-- + +! cms 2009-2-26 also limit volume mean ice radius (optionally) + IF (limit_volri) THEN + + IF (diag_id%qnidt_nucclim2 + & + diag_id%qni_nucclim2_col > 0) THEN + nucclim2(k) = nitend(i,k) + END IF + + qii_new = (qi(i,k) + qitend(i,k)*deltat)/cldm(i,k) + nii_new = (ni(i,k) + nitend(i,k)*deltat)/cldm(i,k) +!max XXX micron + nii_min = qii_new/rhoi*3._mg_pr/(4._mg_pr*3.14_mg_pr* & + max_diam_ii**3) +!min XXX micron + nii_max = qii_new/rhoi*3._mg_pr/(4._mg_pr*3.14_mg_pr* & + min_diam_ii**3) + if ( nii_new .gt. nii_max) then + nitend(i,k) = (nii_max - ni(i,k)/cldm(i,k))/deltat* & + cldm(i,k) + else if (nii_new .lt. nii_min) then + nitend(i,k) = (nii_min - ni(i,k)/cldm(i,k))/deltat* & + cldm(i,k) + end if + IF (diag_id%qnidt_nucclim2 + & + diag_id%qni_nucclim2_col > 0) THEN + nucclim2(k) = nitend(i,k) - nucclim2(k) + END IF + ELSE + nucclim2(k) = 0. + END IF -!CHANGE - !add in excess to cloud condensate, change cloud area and - !increment temperature - if (ttmp .le. tfreeze-40. .and. tmp1 .gt. 0.) then - qitend(i,k)= qitend(i,k) + tmp1/deltat +! get final values for precipitation q and N, based on +! flux of precip from above, source/sink term, and terminal fallspeed +! see eq. 15-16 in Morrison and Gettelman, 2007, J. Climate +! rain + if (qric(i,k) .ge. qsmall) then + if (k .eq. 1) then + qric(i,k) = qrtend(i,k)*dz(i,k)/cldmax(i,k)/umr(k) + nric(i,k) = nrtend(i,k)*dz(i,k)/cldmax(i,k)/unr(k) + else + qric(i,k) = (rho(i,k-1)*umr(k-1)*qric(i,k-1)* & + cldmax(i,k-1) + (rho(i,k)*dz(i,k)* & + qrtend(i,k)))/(umr(k)* & + rho(i,k)*cldmax(i,k)) + nric(i,k) = (rho(i,k-1)*unr(k-1)*nric(i,k-1)* & + cldmax(i,k-1) + (rho(i,k)*dz(i,k)* & + nrtend(i,k)))/(unr(k)* & + rho(i,k)*cldmax(i,k)) + end if + else + qric(i,k) = 0._mg_pr + nric(i,k) = 0._mg_pr + end if -!diag++ - IF ( diag_id%ice_adj > 0 ) & - diag_4d(i,j,k,diag_pt%ice_adj) = tmp1/deltat -!diag-- +! snow - - IF (.NOT. Nml%do_pdf_clouds ) THEN - IF ( .NOT. tiedtke_qa_test ) THEN - if (limit_conv_cloud_frac) then - tmp2s = ahuco(i,k) - else - tmp2s = 0. - endif - SA(i,k) = SA(i,k) + (1.-qa_upd(i,k) -tmp2s) - qa_upd(i,k) = 1. - tmp2s - END IF - END IF - - IF (super_act) THEN - - nitend(i,k)= nitend(i,k) + crystal1(i,k)/rho(i,k) *(1. - qa_upd(i,k)-tmp2s) -!diag++ - IF ( diag_id%qnidt_super > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_super ) = crystal1(i,k)/rho(i,k) *(1. - qa_upd(i,k)-tmp2s) -!diag-- - END IF + if (qniic(i,k) .ge. qsmall) then + if (k .eq. 1) then + qniic(i,k) = qnitend(i,k)*dz(i,k)/cldmax(i,k)/ums(k) + nsic(i,k) = nstend(i,k)*dz(i,k)/cldmax(i,k)/uns(k) + else + qniic(i,k) = (rho(i,k-1)*ums(k-1)*qniic(i,k-1)* & + cldmax(i,k-1) + (rho(i,k)*dz(i,k)* & + qnitend(i,k)))/(ums(k)* & + rho(i,k)*cldmax(i,k)) + nsic(i,k) = (rho(i,k-1)*uns(k-1)*nsic(i,k-1)* & + cldmax(i,k-1) + (rho(i,k)*dz(i,k)* & + nstend(i,k)))/(uns(k)* & + rho(i,k)*cldmax(i,k)) + end if + else + qniic(i,k) = 0._mg_pr + nsic(i,k) = 0._mg_pr + end if - tlat(i,k) = tlat(i,k) + hls*tmp1/deltat +! calculate precipitation flux at surface +! divide by density of water to get units of m/s + prect(i) = prect(i) + (qrtend(i,k)*rho (i,k)*dz(i,k) + & + qnitend(i,k)*rho(i,k)*dz(i,k))/rhow + preci(i) = preci(i) + qnitend(i,k)*rho(i,k)*dz(i,k)/rhow - end if - if (ttmp .gt. tfreeze-40. .and. tmp1 .gt. 0.) then - qctend(i,k) = qctend(i,k) + tmp1/deltat -!diag++ - IF(diag_id%liq_adj > 0 ) & - diag_4d(i,j,k,diag_pt%liq_adj) = tmp1/deltat -!diag-- +! hm, add 9/5/07 +! convert rain rate from m/s to mm/hr - IF (.NOT. Nml%do_pdf_clouds ) THEN - IF ( .NOT. tiedtke_qa_test ) THEN - if (limit_conv_cloud_frac) then - tmp2s = ahuco(i,k) - else - tmp2s = 0. - endif + rainrt(i,k) = qric(i,k)*rho(i,k)*umr(k)/ & + rhow*3600._mg_pr*1000._mg_pr +! vertically-integrated precip source/sink terms (note: grid-averaged) - if (max(diag_id%qadt_super,diag_id%qa_super_col) > 0) then - diag_4d(i,j,k,diag_pt%qadt_super ) = (1.-qa_upd(i,k)-tmp2s) * inv_dtcloud - end if +! qrtot = max(qrtot + qrtend(i,k)*rho(i,k)*dz(i,k), 0._mg_pr) +! qstot = max(qstot + qnitend(i,k)*rho(i,k)*dz(i,k), & +! 0._mg_pr) +! nrtot = max(nrtot + nrtend(i,k)*rho(i,k)*dz(i,k), 0._mg_pr) +! nstot = max(nstot + nstend(i,k)*rho(i,k)*dz(i,k), 0._mg_pr) + qrtot = qrtot + qrtend(i,k)*rho(i,k)*dz(i,k) + qstot = qstot + qnitend(i,k)*rho(i,k)*dz(i,k) + nrtot = nrtot + nrtend(i,k)*rho(i,k)*dz(i,k) + nstot = nstot + nstend(i,k)*rho(i,k)*dz(i,k) - SA(i,k) = SA(i,k) + (1.-qa_upd(i,k) -tmp2s) - qa_upd(i,k) = 1. - tmp2s +! calculate melting and freezing of precip - IF (super_act) THEN - nctend(i,k)= nctend(i,k) + drop2(i,k) *(1. - qa_upd(i,k)-tmp2s) - -!diag++ - IF ( diag_id%qndt_super > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_super ) = drop2(i,k) *(1. - qa_upd(i,k)-tmp2s) -!diag-- - END IF +! melt snow at +2 C +! NOTE RSH 11/22/11: +! NOTE THAT R-K only starts melting at 0 C -- called a bug to melt at +2 C +! + if (t(i,k) + tlat(i,k)/cpp*deltat > & + tfreeze + 2._mg_pr) then + if (qstot > 0._mg_pr) then +! make sure melting snow doesn't reduce temperature below threshold + dum = -xlf/cpp*qstot/(rho(i,k)*dz(i,k)) + if (t(i,k) + tlat(i,k)/cpp*deltat+dum .lt. & + tfreeze + 2._mg_pr) then + dum = (t(i,k) + tlat(i,k)/cpp*deltat - & + (tfreeze + 2._mg_pr))*cpp/xlf + dum = dum/(xlf/cpp*qstot/(rho(i,k)*dz(i,k))) + dum = max(0._mg_pr, dum) + dum = min(1._mg_pr, dum) + else + dum = 1._mg_pr + end if + qric(i,k) = qric(i,k) + dum*qniic(i,k) + nric(i,k) = nric(i,k) + dum*nsic(i,k) + qniic(i,k) = (1._mg_pr - dum)*qniic(i,k) + nsic(i,k) = (1._mg_pr - dum)*nsic(i,k) + tlat(i,k) = tlat(i,k) - xlf*dum*qstot/ & + (rho(i,k)*dz(i,k)) + qrtot = qrtot + dum*qstot + qstot = (1._mg_pr - dum)*qstot + nrtot = nrtot + dum*nstot + nstot = (1._mg_pr - dum)*nstot + if (diag_id%snow_melt + diag_id%snow_melt_col > 0) & + diag_4d(i,j,k, diag_pt%snow_melt) = & + diag_4d(i,j,k, diag_pt%snow_melt) + & + dum*preci(i)*rhow/(rho(i,k)*dz(i,k)) + preci(i) = (1._mg_pr - dum)*preci(i) - END IF - END IF +!cms++ +! assume that droplets which would condense due to cooling associated +! with melting of snow are rapidly collected by (newly formed) rain drops +! (this is optional, controlled by namelist, set to .false. in Marc's final +! parameterization) + + IF (collect_frzreg) THEN +!only if there is net cooling + IF (tlat(i,k) .LT. 0._mg_pr) THEN + ttmp = t(i,k) + tlat(i,k)/cpp*deltat + qtmp = q(i,k) + qvlat(i,k)*deltat + esn = polysvp_l(ttmp) + qvs = 0.622_mg_pr*esn/(pfull(i,k) - d378*esn) + dqsdt = xxlv*qvs/(rv*ttmp**2) + ab = 1._mg_pr + dqsdt*xxlv/cpp + tmp2 = pfull(i,k) - d378*esn + tmp2 = max(tmp2,esn) + tmp2 = d622*esn/tmp2 + tmp1 = max(0._mg_pr, (qtmp - tmp2)/ab) + +! change vapor content and T + qvlat(i,k) = qvlat(i,k) -tmp1/deltat + snow2vapor(k) = -tmp1/deltat + tlat(i,k) = tlat(i,k) + hlv*tmp1/deltat + +! and rain mixing ratio + qric(i,k) = qric(i,k) + tmp1/cldmax(i,k) + qrtot = qrtot + tmp1/deltat*pdel(i,k)/grav + prect(i) = prect(i) + tmp1/deltat*pdel(i,k)/ & + grav/rhow + END IF + END IF + end if + end if + +! freeze rain at -5 C + if (t(i,k) + tlat(i,k)/cpp*deltat < & + tfreeze - 5._mg_pr ) then + if (qrtot > 0._mg_pr) then +! make sure freezing rain doesn't increase temperature above threshold + dum = xlf/cpp*qrtot/(rho(i,k)*dz(i,k)) + if (t(i,k) + tlat(i,k)/cpp*deltat + dum & + .gt. tfreeze -5._mg_pr ) then + dum = -(t(i,k) + tlat(i,k)/cpp*deltat - & + (tfreeze - 5._mg_pr) )*cpp/xlf + dum = dum/(xlf/cpp*qrtot/(rho(i,k)*dz(i,k))) + dum = max(0._mg_pr, dum) + dum = min(1._mg_pr, dum) + else + dum = 1._mg_pr + end if + qniic(i,k) = qniic(i,k) + dum*qric(i,k) + nsic(i,k) = nsic(i,k) + dum*nric(i,k) + qric(i,k) = (1._mg_pr - dum)*qric(i,k) + nric(i,k) = (1._mg_pr - dum)*nric(i,k) + tlat(i,k) = tlat(i,k) + xlf*dum*qrtot/ & + (rho(i,k)*dz(i,k)) + qstot = qstot + dum*qrtot + qrtot = (1._mg_pr - dum)*qrtot + nstot = nstot + dum*nrtot + nrtot = (1._mg_pr - dum)*nrtot + diag_4d(i,j,k, diag_pt%rain_freeze) = & + diag_4d(i,j,k, diag_pt%rain_freeze) + & + dum*(prect(i) - preci(i))* & + rhow/(rho(i,k)*dz(i,k)) + preci(i) = preci(i) + dum* (prect(i) - preci(i)) + end if + end if +! if rain/snow mix ratio is zero so should number concentration + if (qniic(i,k) .lt. qsmall) then + qniic(i,k) = 0._mg_pr + nsic(i,k) = 0._mg_pr + end if + if (qric(i,k) .lt. qsmall) then + qric(i,k) = 0._mg_pr + nric(i,k) = 0._mg_pr + end if - tlat(i,k) = tlat(i,k) + hlv*tmp1/deltat +! make sure number concentration is a positive number to avoid +! taking root of negative + nric(i,k) = max(nric(i,k), 0._mg_pr) + nsic(i,k) = max(nsic(i,k), 0._mg_pr) +!....................................................................... +! get size distribution parameters for fallspeed calculations +!...................................................................... +! rain + if (qric(i,k) .ge. qsmall) then + lamr(k) = (pi*rhow*nric(i,k)/ & + qric(i,k))**(1._mg_pr/3._mg_pr) + n0r(k) = nric(i,k)*lamr(k) +! check for slope +! hm 4/5/07, change lammax and lammin for rain and snow + lammax = 1._mg_pr/20.e-6_mg_pr + lammin = 1._mg_pr/500.e-6_mg_pr - end if +! adjust vars + if (lamr(k) .lt. lammin) then + lamr(k) = lammin + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + else if (lamr(k) .gt. lammax) then + lamr(k) = lammax + n0r(k) = lamr(k)**4*qric(i,k)/(pi*rhow) + nric(i,k) = n0r(k)/lamr(k) + end if - END DO - END DO +! 'final' values of number and mass weighted mean fallspeed for rain (m/s) + unr(k) = min(arn(i,k)*gamma_mg(1._mg_pr + br)/ & + lamr(k)**br, 9.1_mg_pr*rhof(i,k)) + umr(k) = min(arn(i,k)*gamma_mg(4._mg_pr+br)/ & + (6._mg_pr*lamr(k)**br), 9.1_mg_pr*rhof(i,k)) + else + lamr(k) = 0._mg_pr + n0r(k) = 0._mg_pr + umr(k) = 0._mg_pr + unr(k) = 0._mg_pr + end if +!...................................................................... +! snow + if (qniic(i,k) .ge. qsmall) then + lams(k) = (gamma_mg(1._mg_pr + ds)*cs*nsic(i,k)/ & + qniic(i,k))**(1._mg_pr/ds) + n0s(k) = nsic(i,k)*lams(k) +! check for slope + lammax = 1._mg_pr/min_diam_ice + lammin = 1._mg_pr/2000.e-6_mg_pr -END IF sat_adj_opt_if +! adjust vars + if (lams(k) .lt. lammin) then + lams(k) = lammin + n0s(k) = lams(k)**(ds + 1._mg_pr)*qniic(i,k)/ & + (cs*gamma_mg(1._mg_pr + ds)) + nsic(i,k) = n0s(k)/lams(k) + else if (lams(k).gt.lammax) then + lams(k) = lammax + n0s(k) = lams(k)**(ds + 1._mg_pr)*qniic(i,k)/ & + (cs*gamma_mg(1._mg_pr + ds)) + nsic(i,k) = n0s(k)/lams(k) + end if +! 'final' values of number and mass weighted mean fallspeed for snow (m/s) + ums(k) = min(asn(i,k)*gamma_mg(4._mg_pr + bs)/ & + (6._mg_pr*lams(k)**bs), max_vt_snow*rhof(i,k)) + uns(k) = min(asn(i,k)*gamma_mg(1._mg_pr + bs)/ & + lams(k)**bs, max_vt_snow*rhof(i,k)) + else + lams(k) = 0._mg_pr + n0s(k) = 0._mg_pr + ums(k) = 0._mg_pr + uns(k) = 0._mg_pr + end if +! convert rain/snow q and N for output to history, note, +! output is for gridbox average - END IF allow_super_ice_if1 + qrout(i,k) = qrout(i,k) + qric(i,k)*cldmax(i,k) + qsout(i,k) = qsout(i,k) + qniic(i,k)*cldmax(i,k) + nrout(i,k) = nrout(i,k) + nric(i,k)*rho(i,k)*cldmax(i,k) + nsout(i,k) = nsout(i,k) + nsic(i,k)*rho(i,k)*cldmax(i,k) - END IF rh_adj_opt +!c........................................................................ +! sum over sub-step for average process rates + tlat1(i,k) = tlat1(i,k) + tlat(i,k) + qvlat1(i,k) = qvlat1(i,k) + qvlat(i,k) + qctend1(i,k) = qctend1(i,k) + qctend(i,k) + qitend1(i,k) = qitend1(i,k) + qitend(i,k) + nctend1(i,k) = nctend1(i,k) + nctend(i,k) + nitend1(i,k) = nitend1(i,k) + nitend(i,k) + + t(i,k) = t(i,k) + tlat(i,k)*deltat/cpp + q(i,k) = q(i,k) + qvlat(i,k)*deltat + qc(i,k) = qc(i,k) + qctend(i,k)*deltat + qi(i,k) = qi(i,k) + qitend(i,k)*deltat + nc(i,k) = nc(i,k) + nctend(i,k)*deltat + ni(i,k) = ni(i,k) + nitend(i,k)*deltat + +! hm add 9/5/07 + rainrt1(i,k) = rainrt1(i,k) + rainrt(i,k) + +!CODE MOVED TO HERE: + if ( k > 1 ) then + IF (.NOT. one_ice) THEN + asnowrt(i,k-1) = cldmax(i,k-1)*qniic(i,k-1)* & + rho(i,k-1)*ums(k-1) + if (k == kdim) then + asnowrt(i,kdim) = cldmax(i,kdim)*qniic(i,kdim)* & + rho(i,kdim)*ums(kdim) + endif + ELSE + asnowrt(i,k-1)= cldmax(i,k-1)*qiic(i,k-1)* & + rho(i,k-1)*ums(k-1) + if (k == kdim) then + asnowrt(i,kdim) = cldmax(i,kdim)*qiic(i,kdim)* & + rho(i,kdim)*ums(kdim) + endif + END IF + atotrt(i,k-1) = asnowrt(i,k-1) + cldmax(i,k-1)* & + qric(i,k-1)*rho(i,k-1)*umr(k-1) + if (k == kdim) then + atotrt(i,kdim) = asnowrt(i,kdim) + cldmax(i,kdim)* & + qric(i,kdim)*rho(i,kdim)*umr(kdim) + endif + atotrt1(i,k-1) = atotrt1(i,k-1) + atotrt(i,k-1) + asnowrt1(i,k-1) = asnowrt1(i,k-1) + asnowrt(i,k-1) + end if +!END OF MOVED CODE + + if (k == kdim) then + atotrt1(i,k) = atotrt1(i,k) + atotrt(i,k) + asnowrt1(i,k) = asnowrt1(i,k) + asnowrt(i,k) + endif + + pre1(i,k) = pre1(i,k) - pre(k)*cldmax(i,k) + prds1(i,k) = prds1(i,k) - prds(k)*cldmax(i,k) + snow2vapor1(i,k) = snow2vapor1(i,k) + snow2vapor(k) + cmel1(i,k) = cmel1(i,k) + cmel(i,k) + D_eros_l1(i,k) = D_eros_l1(i,k) + D_eros_l(i,k) + berg1(i,k) = berg1(i,k) + berg(i,k) + qvdep_qi1(i,k) = qvdep_qi1(i,k) + qvdep_qi(i,k) + prc1(i,k) = prc1(i,k) - prc(k)*cldm(i,k) + + pra1(i,k) = pra1(i,k) - pra(k)*cldm(i,k) + mnuccc1(i,k) = mnuccc1(i,k) - mnuccc(k)*cldm(i,k) + + psacws1(i,k) = psacws1(i,k) - & + (psacws(k) + psacws_o(k))*cldm(i,k) + psacws_o1(i,k) = psacws_o1(i,k) - psacws_o(k)*cldm(i,k) + bergs1(i,k) = bergs1(i,k) - bergs(k)*cldm(i,k) + + cmei1(i,k) = cmei1(i,k) + cmei(i,k) + D_eros_i1(i,k) = D_eros_i1(i,k) + D_eros_i(i,k) + prci1(i,k) = prci1(i,k) - prci(k)*cldm(i,k) + prai1(i,k) = prai1(i,k) - prai(k)*cldm(i,k) +!droplet number + npccn1(i,k) = npccn1(i,k) + npccn(k)*mtime + nnuccc1(i,k) = nnuccc1(i,k) - nnuccc(k)*cldm(i,k) + npsacws1(i,k) = npsacws1(i,k) - npsacws(k)*cldm(i,k) + npsacws_o1(i,k) = npsacws_o1(i,k) - npsacws_o(k)*cldm(i,k) + nsubc1(i,k) = nsubc1(i,k) + nsubc(k)*cldm(i,k) + nerosc1(i,k) = nerosc1(i,k) + nerosc(i,k)*cldm(i,k) + npra1(i,k) = npra1(i,k) - npra(k)*cldm(i,k) + nprc11(i,k) = nprc11(i,k) - nprc1(k)*cldm(i,k) + nucclim1(i,k) = nucclim1(i,k) + nucclim(k) -!RSH#3 -! DO i=1,idim - DO k=1,kdim - DO i=1,idim +!ice number + nnuccd1(i,k) = nnuccd1(i,k) + nnuccd(k)*mtime + nsubi1(i,k) = nsubi1(i,k) + nsubi(k)*cldm(i,k) + nerosi1(i,k) = nerosi1(i,k) + nerosi(i,k)*cldm(i,k) + nprci1(i,k) = nprci1(i,k) - nprci(k)*cldm(i,k) + nprai1(i,k) = nprai1(i,k) - nprai(k)*cldm(i,k) + nucclim1_1(i,k) = nucclim1_1(i,k) + nucclim1i(k) + nucclim2_1(i,k) = nucclim2_1(i,k) + nucclim2(k) + + pracs1(i,k) = pracs1(i,k) - pracs(k)*cldmax(i,k) + mnuccr1(i,k) = mnuccr1(i,k) - mnuccr(k)*cldmax(i,k) + end do ! k-loop (do k=1,kdim; starts ~ 1800 lines above) + + prect1(i) = prect1(i) + prect(i) + preci1(i) = preci1(i) + preci(i) + end do ! it loop (do it=1,iter) (sub-step loop) +300 continue ! skip to end of loop if no cloud water + end do ! i loop (do i=1,idim) +! convert dt from sub-step back to full time step + deltat=deltat*real(iter) +!c........................................................................ - ST(i,k) = ST(i,k) + tlat(i,k)/cpp * deltat - SQ(i,k) = SQ(i,k) + qvlat(i,k) * deltat - SL(i,k) = SL(i,k) + qctend(i,k) * deltat - SI(i,k) = SI(i,k) + qitend(i,k) * deltat - SN(i,k) = SN(i,k) +nctend(i,k) * deltat - SNI(i,k) = SNI(i,k) + nitend(i,k) * deltat +!ADD HERE 6/6/12 + ssat_disposal(:,:) = 0._mg_pr + do i=1,idim +! skip all calculations if no cloud water + if (ltrue(i) .eq. 0) then + if (diag_id%vfall > 0) & + diag_4d(i,j,:,diag_pt%vfall) = 0.0_mg_pr + goto 500 + endif + +! initialize nstep for sedimentation sub-steps + nstep = 1 +! divide precip rate by number of sub-steps to get average over time step + prect(i) = prect1(i)/real(iter) + preci(i) = preci1(i)/real(iter) + + diag_4d(i,j,:, diag_pt%snow_melt) = & + diag_4d(i,j,:, diag_pt%snow_melt)/real(iter) + diag_4d(i,j,:, diag_pt%rain_freeze) = & + diag_4d(i,j,:, diag_pt%rain_freeze)/real(iter) + do k=1,kdim + umi(k) = 0._mg_pr + end do + + do k=1,kdim + +! assign variables back to start-of-timestep values before updating +! after sub-steps + t(i,k) = t1(i,k) + q(i,k) = q1(i,k) + qc(i,k) = qc1(i,k) + qi(i,k) = qi1(i,k) + nc(i,k) = nc1(i,k) + ni(i,k) = ni1(i,k) + +! divide microphysical tendencies by number of sub-steps to get average +! over time step + tlat(i,k) = tlat1(i,k)/real(iter) + qvlat(i,k) = qvlat1(i,k)/real(iter) + qctend(i,k) = qctend1(i,k)/real(iter) + qitend(i,k) = qitend1(i,k)/real(iter) + nctend(i,k) = nctend1(i,k)/real(iter) + nitend(i,k) = nitend1(i,k)/real(iter) + +! hm, add 9/5/07 + rainrt(i,k) = rainrt1(i,k)/real(iter) - rain3d(i,j,k+1) = rhow * MAX((atotrt(i,k)-asnowrt(i,k)),0.) - snow3d(i,j,k+1) = rhow * MAX(asnowrt(i,k),0.) + atotrt(i,k) = atotrt1(i,k)/real(iter) + asnowrt(i,k) = asnowrt1(i,k)/real(iter) +! divide output precip q and N by number of sub-steps to get average +! over time step + qrout(i,k) = qrout(i,k)/real(iter) + qsout(i,k) = qsout(i,k)/real(iter) + nrout(i,k) = nrout(i,k)/real(iter) + nsout(i,k) = nsout(i,k)/real(iter) +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! calculate sedimentation for cloud water and ice +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - END DO - END DO +! update in-cloud cloud mixing ratio and number concentration +! with microphsical tendencies to calculate sedimentation, assign +! to dummy vars +! note: these are in-cloud values***, hence we divide by cloud fraction + dumc(i,k) = (qc(i,k) + qctend(i,k)*deltat)/cldm(i,k) + dumi(i,k) = (qi(i,k) + qitend(i,k)*deltat)/cldm(i,k) + dumnc(i,k) = max((nc(i,k) + nctend(i,k)*deltat)/cldm(i,k), & + 0._mg_pr) + dumni(i,k) = max((ni(i,k) + nitend(i,k)*deltat)/cldm(i,k), & + 0._mg_pr) +! obtain new slope parameter to avoid possible singularity + if (dumi(i,k) .ge. qsmall) then + +! add upper limit to in-cloud number concentration to prevent +! numerical error + dumni(i,k) = min(dumni(i,k), dumi(i,k)*1.e20_mg_pr) + + lami(k) = (gamma_mg(1._mg_pr + di_mg)*ci_mg* & + dumni(i,k)/dumi(i,k))**(1._mg_pr/di_mg) + lammax = 1._mg_pr/min_diam_ice + lammin = 1._mg_pr/(2._mg_pr*dcs) + lami(k) = max(lami(k), lammin) + lami(k) = min(lami(k), lammax) + else + lami(k) = 0._mg_pr + end if + if (dumc(i,k) .ge. qsmall) then +! add upper limit to in-cloud number concentration to prevent +! numerical error + dumnc(i,k) = min(dumnc(i,k), dumc(i,k)*1.e20_mg_pr) -!----------------------------------------------------------------------- -! Cloud Destruction +!RSH BUGFIX email of 6/8/10 +! pgam(k)=0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr/rho(i,k))+ & +! 0.2714_mg_pr + pgam(k) = 0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr* & + rho(i,k))+0.2714_mg_pr + pgam(k) = 1._mg_pr/(pgam(k)**2) - 1._mg_pr + pgam(k) = max(pgam(k), 2._mg_pr) + pgam(k) = min(pgam(k), 15._mg_pr) + + lamc(k) = (pi/6._mg_pr*rhow*dumnc(i,k)* & + gamma_mg(pgam(k) + 4._mg_pr)/ & + (dumc(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)))**(1._mg_pr/3._mg_pr) + lammin = (pgam(k) + 1._mg_pr)/max_diam_drop + lammax = (pgam(k) + 1._mg_pr)/min_diam_drop + lamc(k) = max(lamc(k), lammin) + lamc(k) = min(lamc(k), lammax) + else + lamc(k) = 0._mg_pr + end if +! calculate number and mass weighted fall velocity for droplets +! include effects of sub-grid distribution of cloud water + if (dumc(i,k) .ge. qsmall) then -!RSH#4 -! DO i=1,idim - DO k=1,kdim - DO i=1,idim +!RSH bugfix email 6/8/10 +! unc= sfac5 * & + unc = & + acn(i,k)*gamma_mg(1._mg_pr + bc+pgam(k))/ & + (lamc(k)**bc*gamma_mg(pgam(k) + 1._mg_pr)) +!RSH bugfix email 6/8/10 +! umc = sfac5 * & + umc = & + acn(i,k)*gamma_mg(4._mg_pr + bc+pgam(k))/ & + (lamc(k)**bc*gamma_mg(pgam(k) + 4._mg_pr)) + else + umc = 0._mg_pr + unc = 0._mg_pr + end if - ql_new= qc_in(i,k) + qctend(i,k)*deltat - qi_new = qi_in(i,k)+qitend(i,k)*deltat - qn_new = nc_in(i,k)+nctend(i,k)*deltat - qni_new = ni_in(i,k)+nitend(i,k)*deltat - +! calculate number and mass weighted fall velocity for cloud ice + if (dumi(i,k) .ge. qsmall) then + IF (.NOT. one_ice) THEN + uni = ain(i,k)*gamma_mg(1._mg_pr + bi)/lami(k)**bi + umi(k) = ain(i,k)*gamma_mg(4._mg_pr + bi)/ & + (6._mg_pr*lami(k)**bi) + ELSE + umi(k) = min(asn(i,k)*gamma_mg(4._mg_pr + bs)/ & + (6._mg_pr*lami(k)**bs), max_vt_ice) + uni = min(asn(i,k)*gamma_mg(1._mg_pr + bs)/ & + lami(k)**bs, max_vt_ice) + END IF + uni = vfact_n*uni + umi(k) = vfact_m*umi(k) + uni = min(uni, max_vt_ice*rhof(i,k)) + umi(k) = min(umi(k), max_vt_ice*rhof(i,k)) + + IF (hd_sedi_sens) THEN + umi(k) = vfact*3.29_mg_pr* & + ((rho(i,k)*qi(i,k)/cldm(i,k))**0.16_mg_pr) + uni = umi(k) + END IF + + IF (scav_by_cloud_ice) THEN + if ( k > 1 ) then +!RSH: if this activated, should deal with difference between rhoi and rhosn +!RSH in this additional term in asnowrt : + asnowrt(i,k) = asnowrt(i,k) + cldmax(i,k-1)* & + qiic(i,k-1)*rho(i,k-1)*umi(k-1) + end if + END IF + else + umi(k) = 0._mg_pr + uni = 0._mg_pr + end if - IF ((ql_new .le. qsmall .and. qi_new .le. qsmall) & - .OR. (qa_upd(i,k) .le. qsmall) ) THEN - SL(i,k) = SL (i,k) - ql_new - SI(i,k) = SI(i,k) - qi_new - SQ (i,k) = SQ(i,k) + ql_new + qi_new - ST(i,k) = ST(i,k) - (hlv*ql_new + hls*qi_new )/cp_air - SA(i,k) = SA(i,k) - qa_upd(i,k) - SN(i,k) = SN(i,k) - qn_new - SNi(i,k) = SNi(i,k) - qni_new + if (diag_id%vfall > 0) diag_4d(i,j,k,diag_pt%vfall) = umi(k) + fi(k) = grav*rho(i,k)*umi(k) + fni(k) = grav*rho(i,k)*uni + fc(k) = grav*rho(i,k)*umc + fnc(k) = grav*rho(i,k)*unc -!diag++ - IF ( diag_id%qldt_destr > 0 .OR. diag_id%ql_destr_col > 0 ) & - diag_4d(i,j,k,diag_pt%qldt_destr) = - ql_new / deltat - IF ( diag_id%qidt_destr > 0 .OR. diag_id%qi_destr_col > 0 ) & - diag_4d(i,j,k,diag_pt%qidt_destr) = - qi_new / deltat - IF ( diag_id%qadt_destr > 0 .OR. diag_id%qa_destr_col > 0 ) & - diag_4d(i,j,k,diag_pt%qadt_destr) = - qa_upd(i,k) / deltat - IF ( diag_id%qndt_destr > 0 .OR. diag_id%qn_destr_col > 0 ) & - diag_4d(i,j,k,diag_pt%qndt_destr) = - qn_new / deltat - IF ( diag_id%qnidt_destr > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_destr) = - qni_new / deltat - - -!diag-- - - END IF +! calculate number of split time steps to ensure courant stability criteria +! for sedimentation calculations + rgvm = max(fi(k), fc(k), fni(k), fnc(k)) + nstep = max(int(rgvm*deltat/pdel(i,k) + 1._mg_pr), nstep) - END DO - END DO +! redefine dummy variables - sedimentation is calculated over grid-scale +! quantities to ensure conservation + dumc(i,k) = (qc(i,k) + qctend(i,k)*deltat) + dumi(i,k) = (qi(i,k) + qitend (i,k)*deltat) + dumnc(i,k) = max((nc(i,k) + nctend(i,k)*deltat), 0._mg_pr) + dumni(i,k) = max((ni(i,k) + nitend(i,k)*deltat), 0._mg_pr) + + if (dumc(i,k) .lt. qsmall) dumnc(i,k) = 0._mg_pr + if (dumi(i,k) .lt. qsmall) dumni(i,k) = 0._mg_pr + end do !!! vertical loop + + do n = 1,nstep !! loop over sub-time step to ensure stability + do k = 1,kdim + falouti(k) = fi(k)*dumi(i,k) + faloutni(k) = fni(k)*dumni(i,k) + faloutc(k) = fc(k)*dumc(i,k) + faloutnc(k) = fnc(k)*dumnc(i,k) + end do +! top of model + k = 1 + faltndi = falouti(k)/pdel(i,k) + faltndni = faloutni(k)/pdel(i,k) + faltndc = faloutc(k)/pdel(i,k) + faltndnc = faloutnc(k)/pdel(i,k) +! add fallout terms to microphysical tendencies + qitend(i,k) = qitend(i,k) - faltndi/nstep + nitend(i,k) = nitend(i,k) - faltndni/nstep + qctend(i,k) = qctend(i,k) - faltndc/nstep + nctend(i,k) = nctend(i,k) - faltndnc/nstep + IF (diag_id%qldt_sedi + diag_id%ql_sedi_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_sedi) = & + diag_4d(i,j,k,diag_pt%qldt_sedi) - faltndc/nstep + IF (diag_id%sedi_ice > 0) & + diag_4d(i,j,1,diag_pt%sedi_ice) = & + diag_4d(i,j,1,diag_pt%sedi_ice) + & + falouti(kdim)/grav/nstep/rhoi + IF (diag_id%qidt_fall + diag_id%qi_fall_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_fall) = & + diag_4d(i,j,k,diag_pt%qidt_fall) - faltndi/nstep + IF (diag_id%qndt_sedi + diag_id%qn_sedi_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_sedi) = & + diag_4d(i,j,k,diag_pt%qndt_sedi) - faltndnc/nstep + IF (diag_id%qnidt_sedi + diag_id%qni_sedi_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_sedi) = & + diag_4d(i,j,k,diag_pt%qnidt_sedi) - faltndni/nstep + + dumi(i,k) = dumi(i,k) - faltndi*deltat/nstep + dumni(i,k) = dumni(i,k) - faltndni*deltat/nstep + dumc(i,k) = dumc(i,k) - faltndc*deltat/nstep + dumnc(i,k) = dumnc(i,k) - faltndnc*deltat/nstep + + do k = 2,kdim + +! for cloud liquid and ice, if cloud fraction increases with height +! then add flux from above to both vapor and cloud water of current level +! this means that flux entering clear portion of cell from above evaporates +! instantly + dum = cldm(i,k)/cldm(i,k-1) + dum = min(dum, 1._mg_pr) + faltndqie = (falouti(k) - falouti(k-1))/pdel(i,k) + faltndi = (falouti(k) - dum*falouti(k-1))/pdel(i,k) + faltndni = (faloutni(k) - dum*faloutni(k-1))/pdel(i,k) + faltndqce = (faloutc(k) - faloutc(k-1))/pdel(i,k) + faltndc = (faloutc(k) - dum*faloutc(k-1))/pdel(i,k) + faltndnc = (faloutnc(k) - dum*faloutnc(k-1))/pdel(i,k) -!final clean up +! add fallout terms to eulerian tendencies + qitend(i,k) = qitend(i,k) - faltndi/nstep + nitend(i,k) = nitend(i,k) - faltndni/nstep + qctend(i,k) = qctend(i,k)- faltndc/nstep + nctend(i,k) = nctend(i,k) - faltndnc/nstep + + IF (diag_id%qldt_sedi + diag_id%ql_sedi_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_sedi) = & + diag_4d(i,j,k,diag_pt%qldt_sedi) - faltndc/nstep + IF (diag_id%qndt_sedi + diag_id%qn_sedi_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_sedi) = & + diag_4d(i,j,k,diag_pt%qndt_sedi) - faltndnc/nstep + IF (diag_id%qnidt_sedi + diag_id%qni_sedi_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_sedi) = & + diag_4d(i,j,k,diag_pt%qnidt_sedi) - faltndni/nstep -!RSH#5 -! DO i=1,idim - DO k=1,kdim - DO i=1,idim - ql_new = ql0(i,k) + SL(i,k) - IF ( abs(ql_new) .le. qsmall & - .and. qv0(i,k)+SQ(i,k)+ql_new > 0.0 ) THEN - SL(i,k) = -ql0(i,k) - SQ(i,k) = SQ(i,k) + ql_new - ST(i,k) = ST(i,k) - hlv*ql_new/cp_air - END IF +! add terms to to evap/sub of cloud water + qvlat(i,k) = qvlat(i,k) - (faltndqie - faltndi)/nstep + if (diag_id%qdt_sedi_ice2vapor > 0) & + sedi_ice2vapor1(i,k) = sedi_ice2vapor1(i,k) - & + (faltndqie - faltndi)/nstep + qvlat(i,k) = qvlat(i,k) - (faltndqce - faltndc)/nstep + if (diag_id%qdt_sedi_liquid2vapor> 0) & + sedi_liquid2vapor1(i,k) = sedi_liquid2vapor1(i,k) - & + (faltndqce - faltndc)/nstep + tlat(i,k) = tlat(i,k) + (faltndqie - faltndi)*xxls/nstep + tlat(i,k) = tlat(i,k) + (faltndqce - faltndc)*xxlv/nstep + + dumi(i,k) = dumi(i,k) - faltndi*deltat/nstep + dumni(i,k) = dumni(i,k) - faltndni*deltat/nstep + dumc(i,k) = dumc(i,k) - faltndc*deltat/nstep + dumnc(i,k) = dumnc(i,k) - faltndnc*deltat/nstep + + Fni(K) = MAX(Fni(K)/pdel(i,K), Fni(K-1)/pdel(i,K-1))* & + pdel(i,K) + FI(K) = MAX(FI(K)/pdel(i,K), FI(K-1)/pdel(i,K-1))*pdel(i,K) + fnc(k) = max(fnc(k)/pdel(i,k), fnc(k-1)/pdel(i,k-1))* & + pdel(i,k) + Fc(K) = MAX(Fc(K)/pdel(i,K), Fc(K-1)/pdel(i,K-1))*pdel(i,K) + + IF (diag_id%qidt_fall + diag_id%qi_fall_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_fall) = & + diag_4d(i,j,k,diag_pt%qidt_fall) - faltndi/nstep + end do !! k loop - END DO - END DO +! units below are m/s +! cloud water/ice sedimentation flux at surface is added to precip flux +! at surface to get total precip (cloud + precip water) rate + prect(i) = prect(i) + (faloutc(kdim) + falouti(kdim)) & + /grav/nstep/1000._mg_pr + preci(i) = preci(i) + (falouti(kdim))/grav/nstep/1000._mg_pr + + IF (diag_id%sedi_sfc > 0) & + diag_4d(i,j,1,diag_pt%sedi_sfc) = & + diag_4d(i,j,1,diag_pt%sedi_sfc) + & + faloutc(kdim)/grav/nstep/rhow + end do !! nstep loop +! end sedimentation +!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +! get new update for variables that includes sedimentation tendency +! note : here dum variables are grid-average, NOT in-cloud -!RSH#6 -! DO i=1,idim - DO k=1,kdim - DO i=1,idim - qi_new = qi0(i,k) + SI(i,k) - IF ( abs(qi_new) .le. qsmall & - .and. qv0(i,k)+SQ(i,k)+qi_new > 0.0 ) THEN - SI (i,k)= -qi0(i,k) - SQ(i,k) = SQ(i,k) + qi_new - ST(i,k) = ST(i,k) - hls*qi_new/cp_air - END IF - END DO - END DO + do k=1,kdim + dumc(i,k) = max(qc(i,k) + qctend(i,k)*deltat, 0._mg_pr) + dumi(i,k) = max(qi(i,k) + qitend(i,k)*deltat, 0._mg_pr) + dumnc(i,k) = max(nc(i,k) + nctend(i,k)*deltat, 0._mg_pr) + dumni(i,k) = max(ni(i,k) + nitend(i,k)*deltat, 0._mg_pr) + if (dumc(i,k) .lt. qsmall) dumnc(i,k) = 0._mg_pr + if (dumi(i,k) .lt. qsmall) dumni(i,k) = 0._mg_pr +! calculate instantaneous processes (melting, homogeneous freezing) -!RSH#7 -! DO i=1,idim - DO k=1,kdim - DO i=1,idim + if (t(i,k) + tlat(i,k)/cpp*deltat > tfreeze) then + if (dumi(i,k) > 0._mg_pr) then -!diag++ - IF ( diag_id%qnidt_cleanup > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_cleanup) = SNi(i,k) +! limit so that melting does not push temperature below freezing + dum = -dumi(i,k)*xlf/cpp + if (t(i,k) + tlat(i,k)/cpp*deltat + dum & + .lt. tfreeze) then + dum = (t(i,k) + tlat(i,k)/cpp*deltat-tfreeze)*cpp/xlf + dum = dum/dumi(i,k)*xlf/cpp + dum = max(0._mg_pr, dum) + dum = min(1._mg_pr, dum) + else + dum = 1._mg_pr + end if -!diag-- + qctend(i,k) = qctend(i,k) + dum*dumi(i,k)/deltat - qa_new = qa0(i,k) + SA(i,k) - IF ( abs(qa_new) .le. qsmall ) THEN - SA(i,k) = -qa0(i,k) - END IF -!cms /3/20/2009 - SA(i,k) = MAX(SA(i,k),-qa0(i,k)) - SA(i,k) = MIN(SA(i,k), 1.-ahuco(i,k)- qa0(i,k)) +! hm add, 9/15/06, assume melting ice produces droplet +! mean volume radius of 8 micron - SN(i,k) = MAX(SN(i,k),-nc0(i,k)) - SNi(i,k) = MAX(SNi(i,k),-ni0(i,k)) + IF (diag_id%qndt_melt + diag_id%qn_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_melt) = nctend(i,k) + IF (diag_id%qidt_melt2 + diag_id%qi_melt2_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_melt2) = qitend(i,k) + IF (diag_id%qnidt_melt + diag_id%qni_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_melt) = nitend(i,k) + nctend(i,k) = nctend(i,k) + 3._mg_pr*dum*dumi(i,k)/ & + deltat/(4._mg_pr*pi*5.12e-16_mg_pr*rhow) + qitend(i,k) = ((1._mg_pr - dum)*dumi(i,k) - qi(i,k))/ & + deltat + nitend(i,k) = ((1._mg_pr - dum)*dumni(i,k) - ni(i,k))/ & + deltat + tlat(i,k) = tlat(i,k) - xlf*dum*dumi(i,k)/deltat + + IF (diag_id%qndt_melt + diag_id%qn_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_melt) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_melt) + IF (diag_id%qidt_melt2 + diag_id%qi_melt2_col > 0) & + diag_4d(i,j,k,diag_pt%qidt_melt2) = & + qitend(i,k) - diag_4d(i,j,k,diag_pt%qidt_melt2) + IF (diag_id%qnidt_melt + diag_id%qni_melt_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_melt) = & + nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_melt) + end if + end if +! homogeneously freeze droplets at -40 C + if (t(i,k) + tlat(i,k)/cpp*deltat < tmin_fice) then + if (dumc(i,k) .ge. 0._mg_pr) then +! limit so that freezing does not push temperature above threshold + dum = dumc(i,k)*xlf/cpp + if (t(i,k) + tlat(i,k)/cpp*deltat + dum .gt. & + tmin_fice) then + dum = -(t(i,k) + tlat(i,k)/cpp*deltat - tmin_fice)* & + cpp/xlf + dum = dum/dumc(i,k)*xlf/cpp + dum = max(0._mg_pr, dum) + dum = min(1._mg_pr, dum) + else + dum = 1._mg_pr + end if + qitend(i,k) = qitend(i,k) + dum*dumc(i,k)/deltat + IF (diag_id%qldt_freez + diag_id%ql_freez_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_freez) = qctend(i,k) + sum_freeze(i,k) = qctend(i,k) + IF (diag_id%qndt_ihom + diag_id%qn_ihom_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_ihom) = nctend(i,k) + IF (diag_id%qnidt_ihom + diag_id%qni_ihom_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_ihom) = nitend(i,k) +! hm add 11/18/06 +! assume 25 micron mean volume radius of homogeneously frozen droplets +! consistent with size of detrained ice in stratiform.F90 +! +! cms nitend .ne. -nctend +! +! 4/24/12: replace the 1.563 with x**3, here and in nCAR routine. + + nitend(i,k) = nitend(i,k) + dum*3._mg_pr*dumc(i,k)/ & + (4._mg_pr*3.14_mg_pr*1.563e-14_mg_pr*rhoi)/deltat + qctend(i,k) = ((1._mg_pr - dum)*dumc(i,k) - qc(i,k))/ & + deltat + nctend(i,k) = ((1._mg_pr - dum)*dumnc(i,k) - nc(i,k))/ & + deltat + tlat(i,k) = tlat(i,k) + xlf*dum*dumc(i,k)/deltat + + IF (diag_id%qldt_freez + diag_id%ql_freez_col > 0) & + diag_4d(i,j,k,diag_pt%qldt_freez) = & + qctend(i,k) - diag_4d(i,j,k,diag_pt%qldt_freez) + sum_freeze(i,k) = -(qctend(i,k) - sum_freeze(i,k)) + IF (diag_id%qndt_ihom + diag_id%qn_ihom_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_ihom) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_ihom) + IF (diag_id%qnidt_ihom + diag_id%qni_ihom_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_ihom) = & + nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_ihom) + end if + end if -!diag++ - IF ( diag_id%qnidt_cleanup > 0 ) & - diag_4d(i,j,k,diag_pt%qnidt_cleanup) = (diag_4d(i,j,k,diag_pt%qnidt_cleanup) - SNi(i,k))/deltat + ssat_disposal(i,k) = 0._mg_pr -!diag-- + IF (no_rh_adj_opt .EQ. 0) THEN + IF (Nml%super_ice_opt .EQ. 0) THEN - END DO - END DO +!RSH: This is the code section which is intended to mimic the RK treatment. +!RSH (super_ice_opt = 0) +!--++ +!cms remove supersat + rho(i,k) = pfull(i,k)/(rdgas*t_in(i,k)) + ttmp = t(i,k) + tlat(i,k)/cpp*deltat + qtmp = q(i,k) + qvlat(i,k)*deltat + eslt = polysvp_l(ttmp) + esit = polysvp_i(ttmp) + esn = min(esit, eslt) + tmp2 = pfull(i,k) - d378*esn + tmp2 = max(tmp2, esn) + call lookup_des(ttmp, tmp7) + tmp7 = d622*pfull(i,k)*tmp7/tmp2/tmp2 + tmp2 = d622*esn/tmp2 + +! the following is not consistent with the apportioning below ... + tmp3 = tmp7*(min(1., max(0._mg_pr, & + 0.05_mg_pr*(ttmp - tfreeze + 20._mg_pr)))*hlv + & + min(1., max(0._mg_pr, & + 0.05_mg_pr*(tfreeze - ttmp)))*hls)/cp_air + +! compute excess over saturation + tmp1 = max(0._mg_pr, qtmp - tmp2)/(1._mg_pr + tmp3) + +! change vapor content + qvlat(i,k) = qvlat(i,k) - tmp1/deltat + if (diag_id%qdt_super_sat_rm > 0) & + super_saturation_rm1(i,k) = & + super_saturation_rm1(i,k) - tmp1/deltat + if (diag_id%qdt_super_sat_rm > 0) & + diag_4d(i,j,k,diag_pt%qdt_super_sat_rm) = & + super_saturation_rm1(i,k) +!CHANGE +! add in excess to cloud condensate, change cloud area and +! increment temperature + if (ttmp .le. tfreeze - 40._mg_pr .and. & + tmp1 .gt. 0._mg_pr) then + IF (Nml%super_choice) THEN + qitend(i,k) = qitend(i,k) + tmp1/deltat + ssat_disposal(i,k) = 2._mg_pr + IF (diag_id%ice_adj + diag_id%ice_adj_col > 0) & + diag_4d(i,j,k,diag_pt%ice_adj) = tmp1/deltat + sum_ice_adj(i,k) = tmp1/deltat + ELSE + ssat_disposal(i,k) = 0._mg_pr + prect(i) = prect(i) + tmp1/deltat*pdel(i,k)/grav/rhow + preci(i) = preci(i) + tmp1/deltat*pdel(i,k)/grav/rhow + qsout(i,k) = qsout(i,k) + tmp1 + asnowrt(i,k) = asnowrt(i,k) + tmp1/deltat* & + pdel(i,k)/grav + atotrt(i,k) = atotrt(i,k) + tmp1/deltat * & + pdel(i,k)/grav + END IF + tlat(i,k) = tlat(i,k) + hls*tmp1/deltat + end if + + if (ttmp .gt. tfreeze - 40._mg_pr .and. & + tmp1 .gt. 0._mg_pr) then + IF (Nml%super_choice) THEN + qctend(i,k) = qctend(i,k) + tmp1/deltat + ssat_disposal(i,k) = 1._mg_pr + IF (diag_id%liq_adj + diag_id%liq_adj_col > 0 ) & + diag_4d(i,j,k,diag_pt%liq_adj) = tmp1/deltat + ELSE + ssat_disposal(i,k) = 0._mg_pr + prect(i) = prect(i) + tmp1/deltat*pdel(i,k)/ & + grav/rhow + qrout(i,k) = qrout(i,k) + tmp1 + atotrt(i,k) = atotrt(i,k) + tmp1/deltat* & + pdel(i,k)/grav + END IF + tlat(i,k) = tlat(i,k) + hlv*tmp1/deltat + end if + ELSE IF (Nml%super_ice_opt .GE. 1) THEN + ssat_disposal(i,k) = 0._mg_pr + +!RSH: THis is the code section used with M-G (super_ice_opt >= 1). + IF (sat_adj_opt .EQ. 1) THEN + ttmp = t(i,k) + tlat(i,k)/cpp*deltat + qtmp = q(i,k) + qvlat(i,k)*deltat + qs_t = polysvp_l(ttmp) +! calculate denominator in qsat formula + qs_d = pfull(i,k) - d378*qs_t +! limit denominator to esat, and thus qs to d622 +! this is done to avoid blow up in the upper stratosphere +! where pfull ~ esat + qs_d = max(qs_d, qs_t) +! calculate qs + qs_t = d622*qs_t/qs_d + +! compute super saturation + tmp1 = max(0._mg_pr, (qtmp - qs_t))/(1._mg_pr + & + hlv*qs_t/(rvgas*ttmp**2)*hlv/cp_air) + +! change vapor content + qvlat(i,k) = qvlat(i,k) - tmp1/deltat + +! add in excess to cloud condensate, change cloud area and +! increment temperature + if (ttmp .le. tfreeze - 40._mg_pr .and. & + tmp1 .gt. 0._mg_pr) then + ssat_disposal(i,k) = 2._mg_pr + qitend(i,k) = qitend(i,k) + tmp1/deltat + IF (diag_id%ice_adj + diag_id%ice_adj_col > 0) & + diag_4d(i,j,k,diag_pt%ice_adj) = tmp1/deltat + sum_ice_adj(i,k) = tmp1/deltat + if (diag_id%qdt_super_sat_rm > 0) & + super_saturation_rm1(i,k) = & + super_saturation_rm1(i,k) - tmp1/deltat + if (diag_id%qdt_super_sat_rm > 0) & + diag_4d(i,j,k,diag_pt%qdt_super_sat_rm) = & + super_saturation_rm1(i,k) + tlat(i,k) = tlat(i,k) + hls*tmp1/deltat + end if + + if (ttmp .gt. tfreeze - 40._mg_pr .and. & + tmp1 .gt. 0._mg_pr) then + qctend(i,k) = qctend(i,k) + tmp1/deltat + ssat_disposal(i,k) = 1._mg_pr + IF (diag_id%liq_adj + diag_id%liq_adj_col > 0 ) & + diag_4d(i,j,k,diag_pt%liq_adj) = tmp1/deltat + if (diag_id%qdt_super_sat_rm > 0) & + super_saturation_rm1(i,k) = & + super_saturation_rm1(i,k) - tmp1/deltat + if (diag_id%qdt_super_sat_rm > 0) & + diag_4d(i,j,k,diag_pt%qdt_super_sat_rm) = & + super_saturation_rm1(i,k) + tlat(i,k) = tlat(i,k) + hlv*tmp1/deltat + end if + END IF + END IF ! (super_ice_opt .EQ. 0) + END IF ! (no_rh_adj_opt .EQ. 0) +!........................................................................ +! do not calculate effective radius here, +! but do some limiting +! update cloud variables after instantaneous processes to get effective +! radius +! variables are in-cloud to calculate size dist parameters + dumc(i,k) = max(qc(i,k) + qctend(i,k)*deltat, 0._mg_pr)/ & + cldm(i,k) + dumi(i,k) = max(qi(i,k) + qitend(i,k)*deltat, 0._mg_pr)/ & + cldm(i,k) + dumnc(i,k) = max(nc(i,k) + nctend(i,k)*deltat, 0._mg_pr)/ & + cldm(i,k) + dumni(i,k) = max(ni(i,k) + nitend(i,k)*deltat, 0._mg_pr)/ & + cldm(i,k) -!------------------- +! limit in-cloud mixing ratio to reasonable value of 5 g kg-1 + dumc(i,k) = min(dumc(i,k), in_cloud_limit) + dumi(i,k) = min(dumi(i,k), in_cloud_limit) +!................... +! cloud ice effective radius + if (dumi(i,k) .ge. qsmall) then + IF (diag_id%qnidt_size_adj + & + diag_id%qni_size_adj_col > 0) THEN + diag_4d(i,j,k,diag_pt%qnidt_size_adj ) = nitend(i,k) + END IF + +! add upper limit to in-cloud number concentration to prevent +! numerical error + dumni(i,k) = min(dumni(i,k), dumi(i,k)*1.e20_mg_pr) + lami(k) = (gamma_mg(1._mg_pr + di_mg)*ci_mg* & + dumni(i,k)/dumi(i,k))**(1._mg_pr/di_mg) + lammax = 1._mg_pr/min_diam_ice + lammin = 1._mg_pr/(2._mg_pr*dcs) + if (lami(k) .lt. lammin) then + lami(k) = lammin + n0i(k) = lami(k)**(di_mg + 1._mg_pr)*dumi(i,k)/ & + (ci_mg*gamma_mg(1._mg_pr + di_mg)) + niic(i,k) = n0i(k)/lami(k) - DO i=1,idim +! adjust number conc if needed to keep mean size in reasonable range + nitend(i,k) = (niic(i,k)*cldm(i,k) - ni(i,k))/deltat + else if (lami(k) .gt. lammax) then + lami(k) = lammax + n0i(k) = lami(k)**(di_mg + 1._mg_pr)*dumi(i,k)/ & + (ci_mg*gamma_mg(1._mg_pr + di_mg)) + niic(i,k) = n0i(k)/lami(k) +! adjust number conc if needed to keep mean size in reasonable range + nitend(i,k) = (niic(i,k)*cldm(i,k) - ni(i,k))/deltat + end if + IF (diag_id%qnidt_size_adj + diag_id%qni_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_size_adj) = nitend(i,k) - & + diag_4d(i,j,k,diag_pt%qnidt_size_adj) + end if - surfrain(i,j) = MAX( 1.e3 * ( prect(i)-preci(i) ) * deltat, 0._mg_pr ) - surfsnow(i,j) = MAX( 1.e3 * preci(i) * deltat, 0._mg_pr ) - END DO +!................... +! cloud droplet effective radius + if (dumc(i,k) .ge. qsmall) then + IF (diag_id%qndt_size_adj + diag_id%qn_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_size_adj ) = nctend(i,k) +! add upper limit to in-cloud number concentration to prevent +! numerical error + dumnc(i,k) = min(dumnc(i,k), dumc(i,k)*1.e20_mg_pr) +!RSH BUGFIX email of 6/8/10 +! pgam(k)=0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr/rho(i,k))+ & +! 0.2714_mg_pr + pgam(k) = 0.0005714_mg_pr*(dumnc(i,k)/1.e6_mg_pr* & + rho(i,k)) + 0.2714_mg_pr + pgam(k)=1._mg_pr/(pgam(k)**2) - 1._mg_pr + pgam(k) = max(pgam(k), 2._mg_pr) + pgam(k) = min(pgam(k), 15._mg_pr) + lamc(k) = (pi/6._mg_pr*rhow*dumnc(i,k)* & + gamma_mg(pgam(k) + 4._mg_pr)/ & + (dumc(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)))**(1._mg_pr/3._mg_pr) +! lammin = (pgam(k)+1._mg_pr)/50.e-6_mg_pr +! lammax = (pgam(k)+1._mg_pr)/2.e-6_mg_pr + lammin = (pgam(k) + 1._mg_pr)/max_diam_drop + lammax = (pgam(k) + 1._mg_pr)/min_diam_drop + if (lamc(k) .lt. lammin) then + lamc(k) = lammin + ncic(i,k) = 6._mg_pr*lamc(k)**3*dumc(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)/ & + (pi*rhow*gamma_mg(pgam(k) + 4._mg_pr)) +! adjust number conc if needed to keep mean size in reasonable range + nctend(i,k) = (ncic(i,k)*cldm(i,k) - nc(i,k))/deltat + else if (lamc(k).gt.lammax) then + lamc(k) = lammax + ncic(i,k) = 6._mg_pr*lamc(k)**3*dumc(i,k)* & + gamma_mg(pgam(k) + 1._mg_pr)/ & -mass_if: IF ( mass_cons ) THEN + (pi*rhow*gamma_mg(pgam(k) + 4._mg_pr)) +! adjust number conc if needed to keep mean size in reasonable range + nctend(i,k) = (ncic(i,k)*cldm(i,k) - nc(i,k))/deltat + end if + IF (diag_id%qndt_size_adj + diag_id%qn_size_adj_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_size_adj ) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_size_adj) + end if - DO i=1,idim - m1 = 0. - DO k=1,kdim +!................... +! rain drop effective size + if (qrout(i,k) .gt. 1.e-7_mg_pr .and. & + nrout(i,k) .gt. 0._mg_pr) then + lsc_rain_size(i,k) = 3.0_mg_pr*(pi*rhow*nrout(i,k)/ & + qrout(i,k))**(-1._mg_pr/3._mg_pr)*1.e6_mg_pr + else + lsc_rain_size(i,k) = 100._mg_pr + endif + end do ! (k loop) +500 CONTINUE - m1 = m1 + ( qvlat(i,k) + qctend(i,k) + qitend(i,k) ) * deltat * pdel(i,k)/grav - END DO - m2 = 1.e3 * prect(i) *deltat + do k=1,kdim +! if updated q (after microphysics) is zero, then ensure updated n is also zero + IF (diag_id%qndt_fill2 + diag_id%qn_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_fill2 ) = nctend(i,k) + IF (diag_id%qnidt_fill2 + diag_id%qni_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_fill2 ) = nitend(i,k) + if (qc(i,k) + qctend(i,k)*deltat .lt. qsmall) & + nctend(i,k) = -nc(i,k)/deltat + if (qi(i,k) + qitend(i,k)*deltat .lt. qsmall) & + nitend(i,k) = -ni(i,k)/deltat + IF (diag_id%qndt_fill2 + diag_id%qn_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qndt_fill2 ) = & + nctend(i,k) - diag_4d(i,j,k,diag_pt%qndt_fill2) + IF (diag_id%qnidt_fill2 + diag_id%qni_fill2_col > 0) & + diag_4d(i,j,k,diag_pt%qnidt_fill2 ) = & + nitend(i,k) - diag_4d(i,j,k,diag_pt%qnidt_fill2) + end do + end do ! (do i=1,idim) + rain3d(:,:,1) = 0._mg_pr + snow3d(:,:,1) = 0._mg_pr + DO k=1,kdim + DO i=1,idim - IF ( m2 .GT. 1.e-12 ) THEN - scalef = -m1/m2 - +! STILL NEED TO DEAL WITH SSAT GOING to PRECIP RATHER THAN CLOUD - + rain3d(i,j,k+1) = MAX((atotrt(i,k) - asnowrt(i,k)), 0._mg_pr) + snow3d(i,j,k+1) = MAX(asnowrt(i,k), 0._mg_pr) + END DO + END DO + + if (diag_id%rain_evap + diag_id%rain_evap_col > 0) & + diag_4d(:,j,:,diag_pt%rain_evap) = pre1(:,:)/real(iter) - surfrain(i,j) = scalef * surfrain(i,j) - surfsnow(i,j) = scalef * surfsnow(i,j) - - END IF + if (diag_id%qdt_rain_evap > 0) & + diag_4d(:,j,:,diag_pt%qdt_rain_evap) = pre1(:,:)/real(iter) + if (diag_id%qdt_cond > 0) & + diag_4d(:,j,:,diag_pt%qdt_cond) = -cmel1(:,:)/real(iter) - END DO + if (diag_id%qdt_snow_sublim > 0 .or. & + diag_id%q_snow_sublim_col > 0) & + diag_4d(:,j,:,diag_pt%qdt_snow_sublim ) = & + prds1(:,:)/real(iter) + if (diag_id%qdt_deposition > 0) & + diag_4d(:,j,:,diag_pt%qdt_deposition) = & + -cmei1(:,:)/real(iter) -END IF mass_if + if (diag_id%qdt_eros_l > 0) & + diag_4d(:,j,:,diag_pt%qdt_eros_l) = & + -D_eros_l1(:,:)/real(iter) + if (diag_id%qdt_eros_i > 0) & + diag_4d(:,j,:,diag_pt%qdt_eros_i) = & + -D_eros_i1(:,:)/real(iter) - lsc_snow(:,j,:) = qsout - lsc_rain(:,j,:) = qrout + if (diag_id%qdt_qv_on_qi > 0) & + diag_4d(:,j,:,diag_pt%qdt_qv_on_qi) = & + - qvdep_qi1(:,:)/real(iter) + if (diag_id%qdt_snow2vapor + diag_id%q_snow2vapor_col > 0) & + diag_4d(:,j,:,diag_pt%qdt_snow2vapor) = & + snow2vapor1(:,:)/real(iter) + if (diag_id%qdt_sedi_ice2vapor > 0) & + diag_4d(:,j,:,diag_pt%qdt_sedi_ice2vapor) = & + sedi_ice2vapor1(:,:) + if (diag_id%qdt_sedi_liquid2vapor > 0) & + diag_4d(:,j,:,diag_pt%qdt_sedi_liquid2vapor) = & + sedi_liquid2vapor1(:,:) + if (diag_id%qdt_super_sat_rm > 0) & + diag_4d(:,j,:,diag_pt%qdt_super_sat_rm) = & + super_saturation_rm1(:,:) -! ! diagnostics for cloud liquid tendencies -! - - -! diag++ ----- !cloud water - if (diag_id%qldt_cond + diag_id%ql_cond_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_cond) = max(cmel1(:,:),0._mg_pr) /real(iter) + if (diag_id%qldt_cond + diag_id%ql_cond_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_cond) = & + max(cmel1(:,:), 0._mg_pr)/real(iter) - if (diag_id%qldt_evap + diag_id%ql_evap_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_evap) = - max(-1._mg_pr*cmel1(:,:),0._mg_pr) /real(iter) + if (diag_id%qldt_evap + diag_id%ql_evap_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_evap) = & + - max(-1._mg_pr*cmel1(:,:),0._mg_pr)/real(iter) - if (diag_id%qidt_eros + diag_id%qi_eros_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_eros) = - D_eros_l1(:,:) /real(iter) + if (diag_id%qldt_eros + diag_id%ql_eros_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_eros) = D_eros_l1(:,:)/real(iter) - if (diag_id%qldt_berg + diag_id%ql_berg_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_berg) = - berg1(:,:) /real(iter) - sum_berg(:,:) = -berg1(:,:)/real(iter) + if (diag_id%qldt_berg + diag_id%ql_berg_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_berg) = - berg1(:,:)/real(iter) - if (diag_id%qldt_auto + diag_id%ql_auto_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_auto) = - prc1(:,:) /real(iter) + sum_berg(:,:) = berg1(:,:)/real(iter) + if (diag_id%qldt_auto + diag_id%ql_auto_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_auto) = prc1(:,:)/real(iter) - if (diag_id%qldt_freez2 + diag_id%ql_freez2_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_freez2) = mnuccc1(:,:) /real(iter) + if (diag_id%qldt_freez2 + diag_id%ql_freez2_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_freez2) = mnuccc1(:,:)/real(iter) + sum_freeze2(:,:) = -mnuccc1(:,:)/real(iter) - if (diag_id%qldt_accr + diag_id%ql_accr_col > 0) & - diag_4d(:,j,:,diag_pt% qldt_accr) = - pra1(:,:) /real(iter) + if (diag_id%qldt_accr + diag_id%ql_accr_col > 0) & + diag_4d(:,j,:,diag_pt% qldt_accr) = pra1(:,:) /real(iter) - if (diag_id%qldt_accrs + diag_id%ql_accrs_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_accrs) = psacws1(:,:) /real(iter) + if (diag_id%qldt_accrs + diag_id%ql_accrs_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_accrs) = psacws1(:,:)/real(iter) + sum_rime(:,:) = -psacws1(:,:)/real(iter) - sum_rime(:,:) = psacws1(:,:)/real(iter) - - if (diag_id%qldt_bergs + diag_id%ql_bergs_col > 0) & - diag_4d(:,j,:,diag_pt%qldt_bergs) = bergs1(:,:) /real(iter) + if (diag_id%qldt_bergs + diag_id%ql_bergs_col > 0) & + diag_4d(:,j,:,diag_pt%qldt_bergs) = bergs1(:,:)/real(iter) + sum_bergs(:,:) = -bergs1(:,:)/real(iter) !cloud ice + if (diag_id%qidt_dep + diag_id%qi_dep_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_dep) = & + max(cmei1(:,:), 0._mg_pr) /real(iter) + sum_cond (:,:) = max(cmei1(:,:), 0._mg_pr) /real(iter) - if (diag_id%qidt_dep + diag_id%qi_dep_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_dep) = max(cmei1(:,:),0._mg_pr) /real(iter) + if (diag_id%qidt_subl + diag_id%qi_subl_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_subl) = & + -max(-1._mg_pr*cmei1(:,:), 0._mg_pr) /real(iter) - if (diag_id%qidt_subl + diag_id%qi_subl_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_subl) = max(-1._mg_pr*cmei1(:,:),0._mg_pr) /real(iter) + if (diag_id%qidt_eros + diag_id%qi_eros_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_eros) = D_eros_i1(:,:)/real(iter) - if (diag_id%qidt_eros + diag_id%qi_eros_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_eros) = D_eros_i1(:,:) /real(iter) + if (diag_id%qidt_auto + diag_id%qi_auto_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_auto) = prci1(:,:)/real(iter) - if (diag_id%qidt_auto + diag_id%qi_auto_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_auto) = prci1(:,:) / real(iter) - - if (diag_id%qidt_accr + diag_id%qi_accr_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_accr) = prai1(:,:) / real(iter) - - if (diag_id%qidt_accrs + diag_id%qi_accrs_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_accrs) = psacws_o1(:,:) /real(iter) + if (diag_id%qidt_accr + diag_id%qi_accr_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_accr) = prai1(:,:)/real(iter) + if (diag_id%qidt_accrs + diag_id%qi_accrs_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_accrs) = psacws_o1(:,:)/real(iter) - if (diag_id%qidt_qvdep + diag_id%qi_qvdep_col > 0) & - diag_4d(:,j,:,diag_pt%qidt_qvdep) = qvdep_qi1(:,:) /real(iter) + if (diag_id%qidt_qvdep + diag_id%qi_qvdep_col > 0) & + diag_4d(:,j,:,diag_pt%qidt_qvdep) = qvdep_qi1(:,:)/real(iter) !cloud droplet number + if ( diag_id%qndt_nucclim + diag_id%qn_nucclim_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_nucclim) = nucclim1(:,:)/real(iter) + if (diag_id%qndt_cond + diag_id%qn_cond_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_cond) = npccn1(:,:)/real(iter) - if ( diag_id%qndt_nucclim + diag_id%qn_nucclim_col > 0 ) & - diag_4d(:,j,:,diag_pt%qndt_nucclim) = nucclim1(:,:) /real(iter) + if (diag_id%qndt_freez + diag_id%qn_freez_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_freez) = nnuccc1(:,:)/real(iter) - if (diag_id%qndt_cond + diag_id%qn_cond_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_cond) = npccn1(:,:) /real(iter) + if (diag_id%qndt_sacws + diag_id%qn_sacws_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_sacws) = npsacws1(:,:)/real(iter) - if (diag_id%qndt_freez + diag_id%qn_freez_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_freez) = nnuccc1(:,:) /real(iter) + if (diag_id%qndt_sacws_o + diag_id%qn_sacws_o_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_sacws_o) = & + npsacws_o1(:,:)/real(iter) - if (diag_id%qndt_sacws + diag_id%qn_sacws_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_sacws) = npsacws1(:,:) /real(iter) + if (diag_id%qndt_evap + diag_id%qn_evap_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_evap) = nsubc1(:,:)/real(iter) - if (diag_id%qndt_sacws_o + diag_id%qn_sacws_o_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_sacws_o) = npsacws_o1(:,:) /real(iter) + if (diag_id%qndt_eros + diag_id%qn_eros_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_eros) = nerosc1(:,:)/real(iter) - if (diag_id%qndt_evap + diag_id%qn_evap_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_evap) = nsubc1(:,:) /real(iter) - - if (diag_id%qndt_eros + diag_id%qn_eros_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_eros) = nerosc1(:,:) /real(iter) - - if (diag_id%qndt_pra + diag_id%qn_pra_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_pra) = npra1(:,:) /real(iter) - - if (diag_id%qndt_auto + diag_id%qn_auto_col > 0) & - diag_4d(:,j,:,diag_pt%qndt_auto) = nprc11(:,:) /real(iter) + if (diag_id%qndt_pra + diag_id%qn_pra_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_pra) = npra1(:,:)/real(iter) + if (diag_id%qndt_auto + diag_id%qn_auto_col > 0) & + diag_4d(:,j,:,diag_pt%qndt_auto) = nprc11(:,:)/real(iter) !cloud droplet number + if (diag_id%qnidt_nnuccd + diag_id%qni_nnuccd_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nnuccd) = nnuccd1(:,:)/real(iter) + if (diag_id%qnidt_nsubi + diag_id%qni_nsubi_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nsubi) = nsubi1(:,:)/real(iter) - if (diag_id%qnidt_nnuccd > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nnuccd) = nnuccd1(:,:) /real(iter) - + if (diag_id%qnidt_nerosi + diag_id%qni_nerosi_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nerosi) = nerosi1(:,:)/real(iter) - if (diag_id%qnidt_nsubi > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nsubi) = nsubi1(:,:) /real(iter) + if (diag_id%qnidt_nprci + diag_id%qni_nprci_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nprci) = nprci1(:,:)/real(iter) - if (diag_id%qnidt_nerosi > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nerosi) = nerosi1(:,:) /real(iter) + if (diag_id%qnidt_nprai + diag_id%qni_nprai_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nprai) = nprai1(:,:)/real(iter) - if (diag_id%qnidt_nprci > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nprci) = nprci1(:,:) /real(iter) + if (diag_id%qnidt_nucclim1 + diag_id%qni_nucclim1_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nucclim1) = & + nucclim1_1(:,:)/real(iter) - if (diag_id%qnidt_nprai > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nprai) = nprai1(:,:) /real(iter) - - if (diag_id%qnidt_nucclim1 > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nucclim1) = nucclim1_1(:,:) /real(iter) - - if (diag_id%qnidt_nucclim2 > 0) & - diag_4d(:,j,:,diag_pt%qnidt_nucclim2) = nucclim2_1(:,:) /real(iter) + if (diag_id%qnidt_nucclim2 + diag_id%qni_nucclim2_col > 0) & + diag_4d(:,j,:,diag_pt%qnidt_nucclim2) = & + nucclim2_1(:,:)/real(iter) + if (diag_id%srfrain_accrs + diag_id%srfrain_accrs_col > 0) & + diag_4d(:,j,:,diag_pt%srfrain_accrs) = & + pracs1(:,:)/real(iter) + + if (diag_id%srfrain_freez + diag_id%srfrain_freez_col > 0) & + diag_4d(:,j,:,diag_pt%srfrain_freez) = & + mnuccr1(:,:)/real(iter) !RSH: -! calculate bergeron fraction of total cloud water to cloud ice -! conversion - do k=1,kdim - do i=1,idim - qldt_sum = sum_berg(i,k) + sum_rime(i,k) + sum_freeze(i,k) - if (qldt_sum /= 0.0) then - f_snow_berg(i,k) = sum_berg(i,k)/qldt_sum - else - f_snow_berg(i,k) = 0. - endif - end do - end do - - - ! diag-- ----- - -! - -!!$ debugo_if: if (Nml%debugo) then -!!$ do k=1,kdim -!!$ do i=1,idim -!!$ tsum = qldt_cond(i,j,k) & -!!$ - qldt_evap(i,j,k) & -!!$ + qldt_eros(i,j,k) & -!!$ - qldt_berg(i,j,k) & -!!$ + qldt_auto(i,j,k) & -!!$ + qldt_freez(i,j,k) & -!!$ + qldt_freez2(i,j,k) & -!!$ + qldt_accr(i,j,k) & -!!$ + qldt_accrs(i,j,k) & -!!$ + qldt_bergs(i,j,k) & -!!$ + qldt_sedi(i,j,k) & -!!$ + liq_adj(i,j,k) & -!!$ + qldt_destr(i,j,k) & -!!$ + qldt_fill(i,j,k) & -!!$ - qidt_melt(i,j,k) -!!$ IF( ABS(SL(i,k)/deltat - tsum ) .GT. 1.e-13) THEN -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ write(otun,*) "BAL ERROR " -!!$ write(otun,*) " i, j, k, T ", i,j, k, t_in(i,j) -!!$ write(otun,*) " " -!!$ write(otun,*) " SL/dt, tsum ", SL(i,k)/deltat, tsum, SL(i,k)/deltat - tsum -!!$ write(otun,*) " " -!!$ write(otun,*) " qldt_cond ", qldt_cond(i,j,k) -!!$ write(otun,*) " -qldt_evap ", -qldt_evap(i,j,k) -!!$ write(otun,*) " qldt_eros ", qldt_eros(i,j,k) -!!$ write(otun,*) " - qldt_berg ", - qldt_berg(i,j,k) -!!$ write(otun,*) " qldt_auto ", + qldt_auto(i,j,k) -!!$ write(otun,*) " qldt_freez ", + qldt_freez(i,j,k) -!!$ write(otun,*) " qldt_freez2 " , + qldt_freez2(i,j,k) -!!$ write(otun,*) " qldt_accr ", + qldt_accr(i,j,k) -!!$ write(otun,*) " qldt_accrs ", + qldt_accrs(i,j,k) -!!$ write(otun,*) " qldt_bergs ", + qldt_bergs(i,j,k) -!!$ write(otun,*) " qldt_sedi ", + qldt_sedi(i,j,k) -!!$ write(otun,*) " liq_adj ", + liq_adj(i,j,k) -!!$ write(otun,*) " qldt_destr ", + qldt_destr(i,j,k) -!!$ write(otun,*) " qldt_fill ", + qldt_fill(i,j,k) -!!$ write(otun,*) " -qidt_melt ", - qidt_melt(i,j,k) -!!$ errcoun = errcoun + 1 -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ if (errcoun .GT. 20 ) stop -!!$ ENDIF -!!$ end do -!!$end do -!!$ -!!$ RSH : if this code is activated, need to use Nml%isamp, etc or define -!!$ local variables isamp = Nml%isamp, etc. -!!$ if ( j .eq. jsamp ) then -!!$ write(otun,*) " sum0 ", qldt_cond(isamp,jsamp,ksamp) & -!!$ - qldt_evap(isamp,jsamp,ksamp) & -!!$ + qldt_eros(isamp,jsamp,ksamp) & -!!$ - qldt_berg(isamp,jsamp,ksamp) & -!!$ + qldt_auto(isamp,jsamp,ksamp) & -!!$ + qldt_freez(isamp,jsamp,ksamp) & -!!$ + qldt_freez2(isamp,jsamp,ksamp) & -!!$ + qldt_accr(isamp,jsamp,ksamp) & -!!$ + qldt_accrs(isamp,jsamp,ksamp) & -!!$ + qldt_bergs(isamp,jsamp,ksamp) -!!$ -!!$ -!!$ write(otun,*) "------------------ " -!!$ write(otun,*) "x qldt_cond ", qldt_cond(isamp,jsamp,ksamp) -!!$ write(otun,*) "x -qldt_evap ", -qldt_evap(isamp,jsamp,ksamp) -!!$ write(otun,*) "x qldt_eros ", qldt_eros(isamp,jsamp,ksamp) -!!$ write(otun,*) "x -qldt_berg ", -qldt_berg(isamp,jsamp,ksamp) -!!$ write(otun,*) "x qldt_auto ", qldt_auto(isamp,jsamp,ksamp) -!!$ write(otun,*) "x qldt_freez ", qldt_freez(isamp,jsamp,ksamp) -!!$ write(otun,*) "x qldt_accr ", qldt_accr(isamp,jsamp,ksamp) -!!$ write(otun,*) "x qldt_accrs ", qldt_accrs(isamp,jsamp,ksamp) -!!$ write(otun,*) "x qldt_bergs ", qldt_bergs(isamp,jsamp,ksamp) -!!$ write(otun,*) "y qldt_sedi ", qldt_sedi(isamp,jsamp,ksamp) -!!$ write(otun,*) "y liq_adj ", liq_adj(isamp,jsamp,ksamp) -!!$ write(otun,*) "y qldt_freez2 ", qldt_freez2(isamp,jsamp,ksamp) -!!$ write(otun,*) " --------- " -!!$ write(otun,*) " sum, qctend ", qldt_cond(isamp,jsamp,ksamp) & -!!$ - qldt_evap(isamp,jsamp,ksamp) & -!!$ + qldt_eros(isamp,jsamp,ksamp) & -!!$ - qldt_berg(isamp,jsamp,ksamp) & -!!$ + qldt_auto(isamp,jsamp,ksamp) & -!!$ + qldt_freez(isamp,jsamp,ksamp) & -!!$ + qldt_freez2(isamp,jsamp,ksamp) & -!!$ + qldt_accr(isamp,jsamp,ksamp) & -!!$ + qldt_accrs(isamp,jsamp,ksamp) & -!!$ + qldt_bergs(isamp,jsamp,ksamp) & -!!$ + qldt_sedi(isamp,jsamp,ksamp) & -!!$ + liq_adj(isamp,jsamp,ksamp) & -!!$ - qidt_melt(isamp,jsamp,ksamp), & -!!$ qctend(isamp,ksamp) -!!$ write(otun,*) "=================================== " -!!$ -!!$ write(otun,*) " SL/dt, sum ", SL(isamp,ksamp)/deltat, qldt_cond(isamp,jsamp,ksamp) & -!!$ - qldt_evap(isamp,jsamp,ksamp) & -!!$ + qldt_eros(isamp,jsamp,ksamp) & -!!$ - qldt_berg(isamp,jsamp,ksamp) & -!!$ + qldt_auto(isamp,jsamp,ksamp) & -!!$ + qldt_freez(isamp,jsamp,ksamp) & -!!$ + qldt_freez2(isamp,jsamp,ksamp) & -!!$ + qldt_accr(isamp,jsamp,ksamp) & -!!$ + qldt_accrs(isamp,jsamp,ksamp) & -!!$ + qldt_bergs(isamp,jsamp,ksamp) & -!!$ + qldt_sedi(isamp,jsamp,ksamp) & -!!$ + liq_adj(isamp,jsamp,ksamp) & -!!$ + qldt_destr(isamp,jsamp,ksamp) & -!!$ + qldt_fill(isamp,jsamp,ksamp) & -!!$ - qidt_melt(isamp,jsamp,ksamp) -!!$ -!!$ -!!$ -!!$ -!!$ write(otun,*) "=================================== " -!!$ write(otun,*) " ICE " -!!$ write(otun,*) "=================================== " -!!$ -!!$ -!!$ write(otun,*) " sumi0 ", & -!!$ + qidt_auto(isamp,jsamp,ksamp) & -!!$ - qldt_freez2(isamp,jsamp,ksamp) & -!!$ + qidt_accrs(isamp,jsamp,ksamp) & -!!$ - qidt_subl(isamp,jsamp,ksamp) & -!!$ + qidt_dep(isamp,jsamp,ksamp) & -!!$ + qldt_berg(isamp,jsamp,ksamp) & -!!$ + qidt_eros(isamp,jsamp,ksamp) -!!$ -!!$ -!!$ write(otun,*) " SI/dt, sumi ", SI(isamp,ksamp)/deltat, & -!!$ + qidt_auto(isamp,jsamp,ksamp) & -!!$ + qidt_accrs(isamp,jsamp,ksamp) & -!!$ - qidt_subl(isamp,jsamp,ksamp) & -!!$ + qidt_dep(isamp,jsamp,ksamp) & -!!$ + qldt_berg(isamp,jsamp,ksamp) & -!!$ + qidt_eros(isamp,jsamp,ksamp) & -!!$ + qidt_fall(isamp,jsamp,ksamp) & -!!$ + ice_adj(isamp,jsamp,ksamp) & -!!$ + qidt_melt(isamp,jsamp,ksamp) & -!!$ + qidt_destr(isamp,jsamp,ksamp) & -!!$ - qldt_freez2(isamp,jsamp,ksamp) & -!!$ + qidt_fill(isamp,jsamp,ksamp) & -!!$ - qldt_freez(isamp,jsamp,ksamp) -!!$ -!!$ -!!$ -!!$ do k=1,kdim -!!$ do i=1,idim -!!$ tsum = qidt_auto(i,j,k) & -!!$ + qidt_accr(i,j,k) & -!!$ + qidt_accrs(i,j,k) & -!!$ - qidt_subl(i,j,k) & -!!$ + qidt_dep(i,j,k) & -!!$ + qldt_berg(i,j,k) & -!!$ + qidt_eros(i,j,k) & -!!$ + qidt_fall(i,j,k) & -!!$ + ice_adj(i,j,k) & -!!$ + qidt_melt(i,j,k) & -!!$ + qidt_destr(i,j,k) & -!!$ - qldt_freez2(i,j,k) & -!!$ + qidt_fill(i,j,k) & -!!$ - qldt_freez(i,j,k) -!!$ -!!$ -!!$ IF( ABS(SI(i,k)/deltat - tsum ) .GT. 1.e-13) THEN -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ write(otun,*) "BAL ICE ERROR " -!!$ write(otun,*) " i, j, k, T ", i,j, k, t_in(i,j) -!!$ write(otun,*) " " -!!$ write(otun,*) " SI/dt, tsum ", SI(i,k)/deltat, tsum, SI(i,k)/deltat - tsum -!!$ write(otun,*) " " -!!$ write(otun,*) " qidt_auto ", qidt_auto(i,j,k) -!!$ write(otun,*) " qidt_accr ", + qidt_accr(i,j,k) -!!$ write(otun,*) " qidt_accrs ", + qidt_accrs(i,j,k) -!!$ write(otun,*) " qidt_subl ", - qidt_subl(i,j,k) -!!$ write(otun,*) " qidt_dep ", + qidt_dep(i,j,k) -!!$ write(otun,*) " qldt_berg ", + qldt_berg(i,j,k) -!!$ write(otun,*) " qidt_eros ", + qidt_eros(i,j,k) -!!$ write(otun,*) " qidt_fall ", + qidt_fall(i,j,k) -!!$ write(otun,*) " ice_adj ", + ice_adj(i,j,k) -!!$ write(otun,*) " qidt_melt ", + qidt_melt(i,j,k) -!!$ write(otun,*) " qidt_destr ", + qidt_destr(i,j,k) -!!$ write(otun,*) " qldt_freez2 ", - qldt_freez2(i,j,k) -!!$ write(otun,*) " qidt_fill ", + qidt_fill(i,j,k) -!!$ write(otun,*) " qldt_freez ", - qldt_freez(i,j,k) -!!$ errcoun = errcoun + 1 -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ if (errcoun .GT. 20 ) stop -!!$ ENDIF -!!$ end do -!!$end do -!!$ -!!$ write(otun,*) "=================================== " -!!$ -!!$ do k=1,kdim -!!$ do i=1,idim -!!$ tsum = diag_4d(i,j,k,diag_pt%qndt_nucclim) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_sedi) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_melt) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_ihom) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_size_adj ) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_fill2 ) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_super ) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_destr) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_cond) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_freez) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_sacws) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_sacws_o) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_eros) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_pra) & -!!$ + diag_4d(i,j,k,diag_pt%qndt_auto) -!!$ -!!$ -!!$ IF( ABS(SN(i,k)/deltat - tsum ) .GT. 1.e-13) THEN -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ write(otun,*) "BAL DROP NUMBER ERROR " -!!$ write(otun,*) " i, j, k, T ", i,j, k, t_in(i,j) -!!$ write(otun,*) " " -!!$ write(otun,*) " SN/dt, tsum ", SN(i,k)/deltat, tsum, SN(i,k)/deltat - tsum -!!$ write(otun,*) " " -!!$ write(otun,*) "nucclim ", diag_4d(i,j,k,diag_pt%qndt_nucclim) -!!$ write(otun,*) "sedi ", diag_4d(i,j,k,diag_pt%qndt_sedi) -!!$ write(otun,*) "melt ", diag_4d(i,j,k,diag_pt%qndt_melt) -!!$ write(otun,*) "ihom ", diag_4d(i,j,k,diag_pt%qndt_ihom) -!!$ write(otun,*) "size_adj ", diag_4d(i,j,k,diag_pt%qndt_size_adj ) -!!$ write(otun,*) "fill2 ", diag_4d(i,j,k,diag_pt%qndt_fill2 ) -!!$ write(otun,*) "super ", diag_4d(i,j,k,diag_pt%qndt_super ) -!!$ write(otun,*) "destr ", diag_4d(i,j,k,diag_pt%qndt_destr) -!!$ write(otun,*) "cond ", diag_4d(i,j,k,diag_pt%qndt_cond) -!!$ write(otun,*) "freez ", diag_4d(i,j,k,diag_pt%qndt_freez) -!!$ write(otun,*) "sacws ", diag_4d(i,j,k,diag_pt%qndt_sacws) -!!$ write(otun,*) "sacws_o ", diag_4d(i,j,k,diag_pt%qndt_sacws_o) -!!$ write(otun,*) "eros ", diag_4d(i,j,k,diag_pt%qndt_eros) -!!$ write(otun,*) "pra ", diag_4d(i,j,k,diag_pt%qndt_pra) -!!$ write(otun,*) "auto ", diag_4d(i,j,k,diag_pt%qndt_auto) -!!$ errcoun = errcoun + 1 -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ if (errcoun .GT. 20 ) then -!!$ call error_mesg ( 'morrison_gettelman', & -!!$ 'BAL DROP NUMBER ERROR ', FATAL) -!!$ ENDIF -!!$ end do -!!$end do -!!$ -!!$ -!!$ - -!!$ do k=1,kdim -!!$ do i=1,idim -!!$ -!!$ tsum = diag_4d(i,j,k,diag_pt%qnidt_nnuccd ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_nsubi ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_nerosi ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_nprci ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_nprai ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_nucclim1 ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_nucclim2 ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_sedi ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_melt ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_size_adj ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_fill2 ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_super ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_ihom ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_destr ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_fill ) & -!!$ + diag_4d(i,j,k,diag_pt%qnidt_cleanup ) -!!$ -!!$ IF( ABS(SNi(i,k)/deltat - tsum ) .GT. 1.e-2) THEN -!!$ -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ write(otun,*) "BAL ICE NUMBER ERROR " -!!$ write(otun,*) " i, j, k, T ", i,j, k, t_in(i,j) -!!$ write(otun,*) " " -!!$ write(otun,*) " SNi/dt, tsum ", SNi(i,k)/deltat, tsum, SNi(i,k)/deltat - tsum -!!$ write(otun,*) " " -!!$ write(otun,*) " nitend ", nitend(i,k) -!!$ write(otun,*) " " -!!$ write(otun,*) "nnuccd", diag_4d(i,j,k,diag_pt%qnidt_nnuccd ) -!!$ write(otun,*) "nsubi ", diag_4d(i,j,k,diag_pt%qnidt_nsubi ) -!!$ write(otun,*)"nerosi ", diag_4d(i,j,k,diag_pt%qnidt_nerosi ) -!!$ write(otun,*) "nprci ", diag_4d(i,j,k,diag_pt%qnidt_nprci ) -!!$ write(otun,*) "nprai ", diag_4d(i,j,k,diag_pt%qnidt_nprai ) -!!$ write(otun,*)"nucclim1 ", diag_4d(i,j,k,diag_pt%qnidt_nucclim1 ), diag_pt%qnidt_nucclim1 -!!$ write(otun,*)"nucclim2 ", diag_4d(i,j,k,diag_pt%qnidt_nucclim2 ) , diag_pt%qnidt_nucclim2 -!!$ write(otun,*) "sedi ", diag_4d(i,j,k,diag_pt%qnidt_sedi ) -!!$ write(otun,*) "melt ", diag_4d(i,j,k,diag_pt%qnidt_melt ) -!!$ write(otun,*) "size_adj ", diag_4d(i,j,k,diag_pt%qnidt_size_adj ) -!!$ write(otun,*) "fill2 ", diag_4d(i,j,k,diag_pt%qnidt_fill2 ), diag_pt%qnidt_fill2 -!!$ write(otun,*) "super ", diag_4d(i,j,k,diag_pt%qnidt_super ) -!!$ write(otun,*) "ihom ",diag_4d(i,j,k,diag_pt%qnidt_ihom ) -!!$ write(otun,*) "destr ",diag_4d(i,j,k,diag_pt%qnidt_destr ) -!!$ write(otun,*) " fill ", diag_4d(i,j,k,diag_pt%qnidt_fill ) -!!$ write(otun,*) " cleanup ", diag_4d(i,j,k,diag_pt%qnidt_cleanup ) -!!$ write(otun,*) " " -!!$ errcoun = errcoun + 1 -!!$ write(otun,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -!!$ if (errcoun .GT. 20 ) then -!!$ call error_mesg ( 'morrison_gettelman', & -!!$ 'BAL ICE NUMBER ERROR ', FATAL) -!!$ end if -!!$ ENDIF -!!$ end do -!!$end do -!!$ -!!$ write(otun,*) "=================================== " - -!!$ end if -!!$ en end if debugo_if +! calculate fraction of total ice/snow creation that requires +! ice-forming nuclei + do k=1,kdim + do i=1,idim + qldt_sum = sum_berg(i,k) + sum_rime(i,k) + sum_freeze(i,k) +& + MAX(sum_bergs(i,k), 0.0_mg_pr) + sum_cond(i,k) + & + sum_ice_adj(i,k) + sum_freeze2(i,k) + if (qldt_sum > 0.0_mg_pr) then + f_snow_berg(i,k) = (sum_berg(i,k) + sum_cond(i,k) + & + sum_ice_adj(i,k) + sum_freeze(i,k) + & + MAX(sum_bergs(i,k), 0.0))/qldt_sum + else + f_snow_berg(i,k) = 0._mg_pr + endif + end do + end do !----------------------------------------------------------------------- diff --git a/src/atmos_param/strat_cloud/nc_cond.F90 b/src/atmos_param/strat_cloud/nc_cond.F90 index 08774e62ee..b4ef8ad5ef 100644 --- a/src/atmos_param/strat_cloud/nc_cond.F90 +++ b/src/atmos_param/strat_cloud/nc_cond.F90 @@ -31,8 +31,8 @@ module nc_cond_mod !----------------------------------------------------------------------- !---version number------------------------------------------------------ -Character(len=128) :: Version = '$Id: nc_cond.F90,v 19.0 2012/01/06 20:26:15 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: nc_cond.F90,v 20.0 2013/12/13 23:22:01 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !----------------------------------------------------------------------- !---namelist------------------------------------------------------------ @@ -62,7 +62,6 @@ module nc_cond_mod do_aero_eros, ae_lb, ae_ub, ae_N_lb, ae_N_ub !------------------------------------------------------------------------ - logical :: module_is_initialized = .false. @@ -472,8 +471,8 @@ SUBROUTINE nc_cond (idim, jdim, kdim, Nml, Constants, Atmos_state, & !----------------------------------------------------------------------- ! save a diagnostic if desired. !----------------------------------------------------------------------- - if ( diag_id%tmp5_3d > 0 ) then - diag_4d(:,:,:,diag_pt%tmp5_3d) = Cloud_processes%tmp5 + if ( diag_id%delta_cf > 0 ) then + diag_4d(:,:,:,diag_pt%delta_cf) = Cloud_processes%delta_cf end if !----------------------------------------------------------------------- @@ -841,7 +840,7 @@ SUBROUTINE nc_cond_nopdf_nosuper (idim, jdim, kdim, Nml, Constants, & do j=1,jdim do i=1,idim A_dt(i,j,k) = Cloud_processes%da_ls(i,j,k)/ & - max((1.-Cloud_state%qa_upd(i,j,k)), Nml%qmin) + max((1.-Cloud_state%qa_upd(i,j,k)), Nml%qmin) B_dt(i,j,k) = Cloud_processes%D_eros(i,j,k) !------------------------------------------------------------------------ @@ -865,6 +864,47 @@ SUBROUTINE nc_cond_nopdf_nosuper (idim, jdim, kdim, Nml, Constants, & END DO END DO + do k=1,kdim + do j=1,jdim + do i=1,idim +!------------------------------------------------------------------------ +! save some diagnostics. +!------------------------------------------------------------------------ +! if ( (A_dt(i,j,k) .gt. Nml%Dmin) .or. & + if ( (A_dt(i,j,k) .gt. Nml%Dmin) .and. & + (B_dt(i,j,k) .gt. Nml%Dmin) ) then + if (diag_id%qadt_lsform + diag_id%qa_lsform_col > 0) then + diag_4d(i,j,k,diag_pt%qadt_lsform) = A_dt(i,j,k)*(1.-qabar(i,j,k)) * & + Constants%inv_dtcloud + end if + if ( diag_id%qadt_eros + diag_id%qa_eros_col > 0 ) then + diag_4d(i,j,k,diag_pt%qadt_eros) = ((qa1(i,j,k) - qa0(i,j,k))* & + Constants%inv_dtcloud )- & + diag_4d(i,j,k,diag_pt%qadt_lsform) + + end if + + else if (A_dt(i,j,k) .gt. Nml%Dmin) then + if (diag_id%qadt_lsform + diag_id%qa_lsform_col > 0) then + + diag_4d(i,j,k,diag_pt%qadt_lsform) = (qa1(i,j,k) - qa0(i,j,k))* & + Constants%inv_dtcloud + end if + else if (B_dt(i,j,k) .gt. Nml%Dmin) then + if ( diag_id%qadt_eros + diag_id%qa_eros_col > 0 ) then + diag_4d(i,j,k,diag_pt%qadt_eros) = (qa1(i,j,k) - qa0(i,j,k))*& + Constants%inv_dtcloud + end if + endif + + END DO + END DO + END DO + if (diag_id%qadt_ahuco + diag_id%qa_ahuco_col > 0) then + diag_4d(:,:,:,diag_pt%qadt_ahuco) = & + qa1(:,:,:) + end if + !------------------------------------------------------------------------ ! limit cloud area to be no more than that which is not being ! taken by convective clouds @@ -873,32 +913,24 @@ SUBROUTINE nc_cond_nopdf_nosuper (idim, jdim, kdim, Nml, Constants, & qa1 = MIN(qa1, 1.0 -Atmos_state%ahuco) endif + if (diag_id%qadt_ahuco + diag_id%qa_ahuco_col > 0) then + diag_4d(:,:,:,diag_pt%qadt_ahuco) = & + (qa1(:,:,:) - diag_4d(:,:,:,diag_pt%qadt_ahuco))* & + Constants%inv_dtcloud + end if + !------------------------------------------------------------------------ ! set total tendency term and update cloud fraction !------------------------------------------------------------------------ + + SA = (SA + qa1) - qa0 + + + + Cloud_state%qa_upd = qa1 -!------------------------------------------------------------------------ -! save some diagnostics. -!------------------------------------------------------------------------ - if (diag_id%qadt_lsform > 0) then - diag_4d(:,:,:,diag_pt%qadt_lsform) = A_dt*(1.-qabar)* & - Constants%inv_dtcloud - end if - if ( diag_id%qadt_eros > 0 ) then - diag_4d(:,:,:,diag_pt%qadt_eros) = B_dt*qabar* & - Constants%inv_dtcloud - end if - -!------------------------------------------------------------------------ -! save term needed when predicted droplets is active. -!------------------------------------------------------------------------ -! IF (use_qabar) THEN -! Cloud_processes%tmp5 = A_dt*(1.-qabar) -! ELSE -! Cloud_processes%tmp5 = A_dt*(1.-CLoud_state%qa_upd) -! END IF !------------------------------------------------------------------------ ! The next step is to calculate the change in condensate @@ -916,10 +948,10 @@ SUBROUTINE nc_cond_nopdf_nosuper (idim, jdim, kdim, Nml, Constants, & !------------------------------------------------------------------------ IF (use_qabar) THEN Cloud_processes%dcond_ls = -1.*qabar*dqs_ls - Cloud_processes%tmp5 = A_dt*(1.-qabar) + Cloud_processes%delta_cf = A_dt*(1.-qabar) ELSE Cloud_processes%dcond_ls = -1.*Cloud_state%qa_upd*dqs_ls - Cloud_processes%tmp5 = A_dt*(1.-Cloud_state%qa_upd) + Cloud_processes%delta_cf = A_dt*(1.-Cloud_state%qa_upd) END IF !----------------------------------------------------------------------- @@ -1021,7 +1053,7 @@ SUBROUTINE nc_cond_nopdf_super (idim, jdim, kdim, Nml, Constants, & do k=1,kdim do j=1,jdim do i=1,idim - if (Atmos_state%T_in(i,j,k) .GE. 233.15 ) then + if (Atmos_state%T_in(i,j,k) .GE. tfreeze - 40. ) then drhcqsdT(i,j,k) = hlv*Atmos_state%qsl(i,j,k)/ & (rvgas*Atmos_state%T_in(i,j,k)**2) beta(i,j,k) = drhcqsdT(i,j,k) * hlv /cp_air @@ -1032,7 +1064,7 @@ SUBROUTINE nc_cond_nopdf_super (idim, jdim, kdim, Nml, Constants, & Particles%hom(i,j,k)* & Atmos_state%qsi(i,j,k)* & ( 2.*0.0073*(Atmos_state%T_in(i,j,k) -& - 273.15 ) + 1.466) + tfreeze ) + 1.466) beta(i,j,k) = drhcqsdT(i,j,k) * hls/ cp_air endif end do @@ -1233,8 +1265,7 @@ SUBROUTINE nc_cond_nopdf_super (idim, jdim, kdim, Nml, Constants, & if ( (A_dt(i,j,k) .gt. Nml%Dmin) .or. & (B_dt(i,j,k) .gt. Nml%Dmin) ) then qa0(i,j,k) = Cloud_state%qa_upd(i,j,k) -! note the ahuco - qaeq(i,j,k) = (1. - Atmos_state%ahuco(i,j,k))* & + qaeq(i,j,k) = & A_dt(i,j,k)/(A_dt(i,j,k) + B_dt(i,j,k)) qa1(i,j,k) = qaeq(i,j,k) - (qaeq(i,j,k) - qa0(i,j,k))* & exp(-1.*(A_dt(i,j,k) + B_dt(i,j,k)) ) @@ -1253,29 +1284,61 @@ SUBROUTINE nc_cond_nopdf_super (idim, jdim, kdim, Nml, Constants, & !------------------------------------------------------------------------- ! output some diagnostics. !------------------------------------------------------------------------- - if ( diag_id%qadt_lsform > 0 ) then - diag_4d(:,:,:,diag_pt%qadt_lsform) = A_dt*(1. - qabar)* & + do k=1,kdim + do j=1,jdim + do i=1,idim + if ( (A_dt(i,j,k) .gt. Nml%Dmin) .and. & + (B_dt(i,j,k) .gt. Nml%Dmin) ) then + if (diag_id%qadt_lsform + diag_id%qa_lsform_col > 0) then + diag_4d(i,j,k,diag_pt%qadt_lsform) = A_dt(i,j,k)*(1. - qabar(i,j,k))* & Constants%inv_dtcloud end if - if ( diag_id%qadt_eros > 0 ) then - diag_4d(:,:,:,diag_pt%qadt_eros) = B_dt*qabar* & - Constants%inv_dtcloud + if ( diag_id%qadt_eros + diag_id%qa_eros_col > 0 ) then + diag_4d(i,j,k,diag_pt%qadt_eros) = ((qa1(i,j,k) - qa0(i,j,k))* & + Constants%inv_dtcloud )- & + diag_4d(i,j,k,diag_pt%qadt_lsform) end if + else if (A_dt(i,j,k) .gt. Nml%Dmin) then + if (diag_id%qadt_lsform + diag_id%qa_lsform_col > 0) then + + diag_4d(i,j,k,diag_pt%qadt_lsform) = (qa1(i,j,k) - qa0(i,j,k))* & + Constants%inv_dtcloud + end if + else if (B_dt(i,j,k) .gt. Nml%Dmin) then + if ( diag_id%qadt_eros + diag_id%qa_eros_col > 0 ) then + diag_4d(i,j,k,diag_pt%qadt_eros) = (qa1(i,j,k) - qa0(i,j,k))*& + Constants%inv_dtcloud + end if + endif + end do + end do + end do + !------------------------------------------------------------------------- ! limit cloud area to be no more than that which is not being ! taken by convective clouds. !------------------------------------------------------------------------- + if ( diag_id%qadt_ahuco + diag_id%qa_ahuco_col > 0 ) then + diag_4d(:,:,:,diag_pt%qadt_ahuco) = qa1 + end if + if (Constants%limit_conv_cloud_frac) then qa1 = MIN(qa1, 1.0 - Atmos_state%ahuco) endif + + if ( diag_id%qadt_ahuco + diag_id%qa_ahuco_col > 0 ) then + diag_4d(:,:,:,diag_pt%qadt_ahuco) = & + (qa1(:,:,:) - diag_4d(:,:,:,diag_pt%qadt_ahuco))* & + Constants%inv_dtcloud + end if !------------------------------------------------------------------------- ! set total tendency term and update cloud fraction. !------------------------------------------------------------------------- SA = (SA + qa1) - qa0 Cloud_state%qa_upd = qa1 - Cloud_processes%tmp5 = MAX(qa1 - qa0 , 0.) + Cloud_processes%delta_cf = MAX(qa1 - qa0 , 0.) !------------------------------------------------------------------------- ! The next step is to calculate the change in condensate @@ -1643,17 +1706,17 @@ SUBROUTINE nc_cond_pdf (idim, jdim, kdim, Nml, Constants, Atmos_state, & Cloud_state%qa_upd = qa1 - if ( diag_id%qadt_lsform > 0 ) then + if (diag_id%qadt_lsform + diag_id%qa_lsform_col > 0) then diag_4d(:,:,:,diag_pt%qadt_lsform ) = max(qa1 - qa0, 0.)* & Constants%inv_dtcloud end if - if ( diag_id%qadt_lsdiss > 0 ) then + if ( diag_id%qadt_lsdiss + diag_id%qa_lsdiss_col > 0 ) then diag_4d(:,:,:,diag_pt%qadt_lsdiss ) = max(qa0 - qa1, 0.)* & Constants%inv_dtcloud end if !define da_ls and tmp5 needed when do_liq_num = .true. (cjg) Cloud_processes%da_ls = max(qa1-qa0,0.) - Cloud_processes%tmp5 = max(qa1-qa0,0.) + Cloud_processes%delta_cf = max(qa1-qa0,0.) !compute large-scale condensation / evaporation Cloud_processes%dcond_ls = qcg - & diff --git a/src/atmos_param/strat_cloud/polysvp.F90 b/src/atmos_param/strat_cloud/polysvp.F90 index d4a5164922..07c426ab0b 100644 --- a/src/atmos_param/strat_cloud/polysvp.F90 +++ b/src/atmos_param/strat_cloud/polysvp.F90 @@ -29,8 +29,8 @@ MODULE polysvp_mod !------------------------------------------------------------------------- !----version number------------------------------------------------------- -Character(len=128) :: Version = '$Id: polysvp.F90,v 19.0 2012/01/06 20:26:46 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: polysvp.F90,v 20.0 2013/12/13 23:22:03 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -438,7 +438,12 @@ SUBROUTINE compute_qs_x1 (idim, jdim, kdim, ttmp, pfull, qs, qs_l, qs_i,& ELSE qs(i,j,k) = qs_i(i,j,k) END IF - IF (ttmp(i,j,k) .GE. 233.15) THEN +!REV#1 +!888 +! IF (ttmp(i,j,k) .GE. 233.15) THEN +! IF (ttmp(i,j,k) .GE. 233.16) THEN + IF (ttmp(i,j,k) .GE. tfreeze - 40.) THEN +!END REV#1 dqsdT(i,j,k) = hlv*qs_l(i,j,k)/(rvgas*ttmp(i,j,k)**2) gamma(i,j,k) = dqsdT(i,j,k)*hlv/cp_air ELSE @@ -513,7 +518,12 @@ SUBROUTINE compute_qs_x2 (ttmp, pfull, qs, qs_l, qs_i, dqsdT, gamma, & ELSE qs = qs_i END IF - IF (ttmp .GE. 233.15 .and. ifrac .LT. 0.9 ) THEN +!REV#2 +!888 +! IF (ttmp .GE. 233.15 .and. ifrac .LT. 0.9 ) THEN +! IF (ttmp .GE. 233.16 .and. ifrac .LT. 0.9 ) THEN + IF (ttmp .GE. tfreeze - 40. .and. ifrac .LT. 0.9 ) THEN +!END REV#2 dqsdT = hlv*qs_l/(rvgas*ttmp**2) gamma = dqsdT * hlv /cp_air ELSE diff --git a/src/atmos_param/strat_cloud/rotstayn_klein_mp.F90 b/src/atmos_param/strat_cloud/rotstayn_klein_mp.F90 index 2ad1da1256..2d511cdb9a 100644 --- a/src/atmos_param/strat_cloud/rotstayn_klein_mp.F90 +++ b/src/atmos_param/strat_cloud/rotstayn_klein_mp.F90 @@ -30,8 +30,8 @@ MODULE rotstayn_klein_mp_mod !------------------------------------------------------------------------- !---version number------------------------------------------------------- -Character(len=128) :: Version = '$Id: rotstayn_klein_mp.F90,v 19.0 2012/01/06 20:26:47 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: rotstayn_klein_mp.F90,v 20.0 2013/12/13 23:22:05 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------- !---namelist------------------------------------------------------------- @@ -140,7 +140,7 @@ SUBROUTINE rotstayn_klein_microp (& inv_dtcloud, pfull, deltpg, airdens, mask_present, & mask, esat0, ql, qi, qa, ql_mean, qa_mean, qn_mean, & omega, T, U, qv, qs, D_eros, dcond_ls, dcond_ls_ice, & - qvg, gamma, tmp5, drop1, concen_dust_sub, ql_upd, & + qvg, gamma, delta_cf, drop1, concen_dust_sub, ql_upd,& qi_upd, qn_upd, qi_mean, qa_upd, ahuco, n_diag_4d, & diag_4d, diag_id, diag_pt, n_diag_4d_kp1, & diag_4d_kp1, limit_conv_cloud_frac, SA, SN, ST, SQ, & @@ -164,7 +164,7 @@ SUBROUTINE rotstayn_klein_microp (& omega, ahuco real, dimension(idim,jdim,kdim), INTENT(INOUT):: & SN, qi_mean, ST, SQ, SL, SI, SA, qa_upd, & - ql_upd, qi_upd, qn_upd, qs, tmp5, & + ql_upd, qi_upd, qn_upd, qs, delta_cf, & dcond_ls,dcond_ls_ice REAL, dimension(idim,jdim,kdim,0:n_diag_4d), & INTENT(INOUT):: diag_4d @@ -295,12 +295,13 @@ SUBROUTINE rotstayn_klein_microp (& da_cld2clr, da_clr2cld, & dprec_clr2cld, dprec_cld2clr, & Vfall, lamda_f, tmp1, tmp2, & - tmp3, tmp8, crystal, crystal2,& + tmp3, tmp8, crystal, & rad_liq, D1_dt, D2_dt, qc1, & qc0, qceq, qcbar, U_clr, & qs_d_a, tmp2s_a, tmp3s_a, & tmp5s_a, est_a, sum_freeze, & - sum_rime, sum_berg + sum_cond, sum_ice_adj, & + sum_rime, sum_berg, tmp5 real :: dum, Si0, qs_t, qs_d, tmp2s, & tmp3s, tmp5s, est, rhi, tc, & tcrit, qldt_sum @@ -351,6 +352,8 @@ SUBROUTINE rotstayn_klein_microp (& sum_freeze = 0. sum_rime = 0. sum_berg = 0. + sum_ice_adj = 0. + sum_cond = 0. !------------------------------------------------------------------------ ! begin big vertical loop. @@ -621,12 +624,12 @@ SUBROUTINE rotstayn_klein_microp (& !----------------------------------------------------------------------- ! snow falling into cloud reduces the amount that falls out of cloud: -! a loss of cloud ice from settling is defined to be positive. define +! a loss of cloud ice from settling is defined to be negative. define ! the ice-fall diagnostic. !----------------------------------------------------------------------- if (diag_id%qidt_fall + diag_id%qi_fall_col > 0) & diag_4d(:,:,k,diag_pt%qidt_fall) = & - -1.*snow_cld(:,:,k)/deltpg(:,:,k) + snow_cld(:,:,k)/deltpg(:,:,k) !----------------------------------------------------------------------- ! compute slope factor lamda_f. @@ -775,9 +778,9 @@ SUBROUTINE rotstayn_klein_microp (& ! save accretion process diagnostics. !------------------------------------------------------------------------ if (diag_id%qldt_accr + diag_id%ql_accr_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_accr) = D1_dt(:,:,k) + diag_4d(:,:,k,diag_pt%qldt_accr) = -D1_dt(:,:,k) if (diag_id%qndt_pra + diag_id%qn_pra_col > 0) & - diag_4d(:,:,k,diag_pt%qndt_pra) = D1_dt(:,:,k) + diag_4d(:,:,k,diag_pt%qndt_pra) = -D1_dt(:,:,k) !------------------------------------------------------------------------ ! Autoconversion @@ -952,12 +955,12 @@ SUBROUTINE rotstayn_klein_microp (& ! save autoconversion diagnostics. !------------------------------------------------------------------------ if (diag_id%qldt_auto + diag_id%ql_auto_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_auto) = tmp1(:,:,k) + diag_4d(:,:,k,diag_pt%qldt_auto) = -tmp1(:,:,k) if (diag_id%qndt_auto + diag_id%qn_auto_col > 0) & - diag_4d(:,:,k,diag_pt%qndt_auto) = tmp1(:,:,k) - if ( diag_id%autocv > 0 ) then + diag_4d(:,:,k,diag_pt%qndt_auto) = -tmp1(:,:,k) + if ( diag_id%aauto > 0 ) then where ( rad_liq(:,:,k) .gt. Nml%rthresh ) & - diag_4d(:,:,k,diag_pt%autocv) = qa_mean(:,:,k) + diag_4d(:,:,k,diag_pt%aauto) = qa_mean(:,:,k) end if !----------------------------------------------------------------------- @@ -1015,27 +1018,19 @@ SUBROUTINE rotstayn_klein_microp (& Si0 = 1. + 0.0125*(tfreeze-T(i,j,k)) call Jhete_dep (T(i,j,k), Si0, concen_dust_sub(i,j,k), & crystal(i,j,k)) + if (diag_id%dust_berg_flag > 0) & + diag_4d(i,k,j,diag_pt%dust_berg_flag) = 1. else crystal(i,j,k)=0. endif end do end do - where ( (T(:,:,k) .lt. tfreeze) .and. & - (ql_mean(:,:,k) .gt. Nml%qmin) .and. & - (qa_mean(:,:,k) .gt. Nml%qmin)) - crystal2(:,:,k) = 1.e-3*exp((12.96*0.0125* & - (tfreeze - T(:,:,k))) - 0.639) - elsewhere - crystal2(:,:,k) = 0. - end where !------------------------------------------------------------------------ ! save ice crystal diagnostics. !------------------------------------------------------------------------ if (diag_id%qndt_cond + diag_id%qn_cond_col > 0) & diag_4d(:,:,k,diag_pt%qndt_cond) = crystal(:,:,k) - if (diag_id%qndt_evap + diag_id%qn_evap_col > 0) & - diag_4d(:,:,k,diag_pt%qndt_evap) = crystal2(:,:,k) !------------------------------------------------------------------------ ! do Bergeron process @@ -1136,7 +1131,7 @@ SUBROUTINE rotstayn_klein_microp (& ! save the riming diagnostics. !----------------------------------------------------------------------- if (diag_id%qldt_rime + diag_id%ql_rime_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_rime) = tmp1(:,:,k) + diag_4d(:,:,k,diag_pt%qldt_rime) = -tmp1(:,:,k) !------------------------------------------------------------------------ ! Freezing of cloud liquid to cloud ice occurs when @@ -1165,7 +1160,7 @@ SUBROUTINE rotstayn_klein_microp (& sum_rime(i,j,k) = 0. sum_berg(i,j,k) = 0. if (diag_id%qldt_freez + diag_id%ql_freez_col > 0) then - diag_4d(i,j,k,diag_pt%qldt_freez) = D2_dt(i,j,k) + diag_4d(i,j,k,diag_pt%qldt_freez) = -D2_dt(i,j,k) endif if (diag_id%qldt_rime + diag_id%ql_rime_col > 0) then diag_4d(i,j,k,diag_pt%qldt_rime) = 0. @@ -1177,19 +1172,6 @@ SUBROUTINE rotstayn_klein_microp (& end do end do -! Used for BC aerosol in-cloud scavenging: - do j=1,jdim - do i=1,idim - qldt_sum = sum_berg(i,j,k) + sum_rime(i,j,k) + & - sum_freeze(i,j,k) - if (qldt_sum > 0.) then - f_snow_berg(i,j,k) = sum_berg(i,j,k)/qldt_sum - else - f_snow_berg(i,j,k) = 0. - endif - end do - end do - !------------------------------------------------------------------------ ! Analytic integration of ql equation ! @@ -1263,6 +1245,7 @@ SUBROUTINE rotstayn_klein_microp (& qceq(:,:,k) = qc0(:,:,k) + C_dt(:,:,k) qc1(:,:,k) = qc0(:,:,k) + C_dt(:,:,k) qcbar(:,:,k) = qc0(:,:,k) + 0.5*C_dt(:,:,k) + end where !------------------------------------------------------------------------ @@ -1298,8 +1281,45 @@ SUBROUTINE rotstayn_klein_microp (& ! initialize tmp2 to hold (-Dterm)/D !------------------------------------------------------------------------ + if (Nml%retain_cm3_bug) then tmp2(:,:,k) = D_dt(:,:,k)*qcbar(:,:,k)/max(D_dt(:,:,k), Nml%Dmin) + else + where (D_dt(:,:,k) > Nml%Dmin) + tmp2(:,:,k) = D_dt(:,:,k)*qcbar(:,:,k)/max(D_dt(:,:,k), Nml%Dmin) + elsewhere + tmp2(:,:,k) = 0.0 + endwhere + endif + + if (diag_id%qldt_cond + diag_id%ql_cond_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_cond) = & + max(dcond_ls(:,:,k),0.) *inv_dtcloud + if (diag_id%qldt_evap + diag_id%ql_evap_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_evap) = & + - (max(0., -1.*dcond_ls(:,:,k) )/ & + max(ql_mean(:,:,k), Nml%qmin))*tmp2(:,:,k)*inv_dtcloud + if (diag_id%qldt_accr + diag_id%ql_accr_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_accr) = & + diag_4d(:,:,k,diag_pt%qldt_accr)*tmp2(:,:,k)*inv_dtcloud + if (diag_id%qldt_auto + diag_id%ql_auto_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_auto) = & + diag_4d (:,:,k,diag_pt%qldt_auto)*tmp2(:,:,k)*inv_dtcloud + if (diag_id%qldt_eros + diag_id%ql_eros_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_eros) = & + - D_eros(:,:,k)*tmp2(:,:,k)*inv_dtcloud + if (diag_id%qldt_berg + diag_id%ql_berg_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_berg) = & + diag_4d (:,:,k,diag_pt%qldt_berg)*tmp2(:,:,k)*inv_dtcloud + sum_berg(:,:,k) = sum_berg(:,:,k)*tmp2(:,:,k)*inv_dtcloud + if (diag_id%qldt_rime + diag_id%ql_rime_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_rime) = & + diag_4d (:,:,k,diag_pt%qldt_rime)*tmp2(:,:,k)*inv_dtcloud + sum_rime(:,:,k) = sum_rime(:,:,k)*tmp2(:,:,k)*inv_dtcloud + if (diag_id%qldt_freez + diag_id%ql_freez_col > 0) & + diag_4d(:,:,k,diag_pt%qldt_freez) = & + diag_4d(:,:,k,diag_pt%qldt_freez)*tmp2(:,:,k)*inv_dtcloud + sum_freeze(:,:,k) = sum_freeze(:,:,k)*tmp2(:,:,k)*inv_dtcloud !------------------------------------------------------------------------- ! do phase changes from large-scale processes and boundary ! layer condensation/evaporation @@ -1396,13 +1416,13 @@ SUBROUTINE rotstayn_klein_microp (& !------------------------------------------------------------------------ IF ( rk_act_only_if_ql_gt_qmin) THEN where (ql_upd(:,:,k) .GT. Nml%qmin ) - C_dt(:,:,k) = max (tmp5(:,:,k), 0.)*drop1(:,:,k)* & + C_dt(:,:,k) = max (delta_cf(:,:,k), 0.)*drop1(:,:,k)* & 1.e6/airdens(:,:,k) elsewhere C_dt(:,:,k)=0. end where ELSE - C_dt(:,:,k)=max(tmp5(:,:,k), 0.)*drop1(:,:,k)* & + C_dt(:,:,k)=max(delta_cf(:,:,k), 0.)*drop1(:,:,k)* & 1.e6/airdens(:,:,k) END IF @@ -1451,7 +1471,16 @@ SUBROUTINE rotstayn_klein_microp (& diag_4d(:,:,k,diag_pt%qndt_cond) = 0. endwhere end if + if (Nml%retain_cm3_bug) then + tmp8(:,:,k) = D_dt(:,:,k)*qcbar(:,:,k)/max(D_dt(:,:,k), Nml%Dmin) + else + where (D_dt(:,:,k) > Nml%Dmin) tmp8(:,:,k) = D_dt(:,:,k)*qcbar(:,:,k)/max(D_dt(:,:,k), Nml%Dmin) + elsewhere + tmp8(:,:,k) = 0.0 + endwhere + endif + if (diag_id%qndt_pra + diag_id%qn_pra_col > 0) then diag_4d(:,:,k,diag_pt%qndt_pra) = & Nml%num_mass_ratio1*diag_4d(:,:,k,diag_pt%qndt_pra)* & @@ -1468,39 +1497,11 @@ SUBROUTINE rotstayn_klein_microp (& tmp8(:,:,k) *inv_dtcloud end if if (diag_id%qndt_eros + diag_id%qn_eros_col > 0) then - diag_4d(:,:,k,diag_pt%qndt_eros) = D_eros(:,:,k)* & + diag_4d(:,:,k,diag_pt%qndt_eros) = -D_eros(:,:,k)* & tmp8(:,:,k)*inv_dtcloud end if end if ! (Nml%do_liq_num) -!------------------------------------------------------------------------ -! remaining diagnostics for cloud liquid tendencies -!------------------------------------------------------------------------ - if (diag_id%qldt_cond + diag_id%ql_cond_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_cond) = & - max(dcond_ls(:,:,k),0.) *inv_dtcloud - if (diag_id%qldt_evap + diag_id%ql_evap_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_evap) = & - - (max(0., -1.*dcond_ls(:,:,k) )/ & - max(ql_mean(:,:,k), Nml%qmin))*tmp2(:,:,k)*inv_dtcloud - if (diag_id%qldt_accr + diag_id%ql_accr_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_accr) = & - diag_4d(:,:,k,diag_pt%qldt_accr)*tmp2(:,:,k)*inv_dtcloud - if (diag_id%qldt_auto + diag_id%ql_auto_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_auto) = & - diag_4d (:,:,k,diag_pt%qldt_auto)*tmp2(:,:,k)*inv_dtcloud - if (diag_id%qidt_eros + diag_id%qi_eros_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_eros) = & - D_eros(:,:,k)*tmp2(:,:,k)*inv_dtcloud - if (diag_id%qldt_berg + diag_id%ql_berg_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_berg) = & - diag_4d (:,:,k,diag_pt%qldt_berg)*tmp2(:,:,k)*inv_dtcloud - if (diag_id%qldt_rime + diag_id%ql_rime_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_rime) = & - diag_4d (:,:,k,diag_pt%qldt_rime)*tmp2(:,:,k)*inv_dtcloud - if (diag_id%qldt_freez + diag_id%ql_freez_col > 0) & - diag_4d(:,:,k,diag_pt%qldt_freez) = & - diag_4d(:,:,k,diag_pt%qldt_freez)*tmp2(:,:,k)*inv_dtcloud if (Nml%do_liq_num) then if (diag_id%qndt_cond + diag_id%qn_cond_col > 0) & diag_4d(:,:,k,diag_pt%qndt_cond) = & @@ -1575,7 +1576,7 @@ SUBROUTINE rotstayn_klein_microp (& elsewhere Vfall(:,:,k) = 0. end where - if (diag_id%vfall > 0) diag_4d(:,:,k,diag_pt%vfall) = Vfall(:,:,k) + if (diag_id%vfall > 0) diag_4d(:,:,k,diag_pt%vfall) = Vfall(:,:,k)* qa_mean(:,:,k) !------------------------------------------------------------------------ ! add to ice source the settling ice flux from above @@ -1671,6 +1672,7 @@ SUBROUTINE rotstayn_klein_microp (& !scale sublimation (note use of qi mean). !----------------------------------------------------------------------- C_dt(:,:,k) = C_dt(:,:,k) + max(dcond_ls_ice(:,:,k), 0.) + sum_cond(:,:,k) = max(dcond_ls_ice(:,:,k), 0.)*inv_dtcloud D_dt(:,:,k) = D1_dt(:,:,k) + D2_dt(:,:,k) + D_eros(:,:,k) + & (max(-1.*dcond_ls_ice(:,:,k), 0.)/ & max(qi_mean(:,:,k), Nml%qmin)) @@ -1723,7 +1725,15 @@ SUBROUTINE rotstayn_klein_microp (& !------------------------------------------------------------------------ ! initialize tmp2 to hold (-Dterm)/D !------------------------------------------------------------------------ + if (Nml%retain_cm3_bug) then tmp2 (:,:,k) = D_dt(:,:,k)*qcbar(:,:,k)/max(D_dt(:,:,k), Nml%Dmin) + else + where (D_dt(:,:,k) > Nml%Dmin) + tmp2(:,:,k) = D_dt(:,:,k)*qcbar(:,:,k)/max(D_dt(:,:,k), Nml%Dmin) + elsewhere + tmp2(:,:,k) = 0.0 + endwhere + endif !------------------------------------------------------------------------ ! do phase changes from large-scale processes @@ -1766,14 +1776,14 @@ SUBROUTINE rotstayn_klein_microp (& max(dcond_ls_ice(:,:,k), 0.)*inv_dtcloud if (diag_id%qidt_subl + diag_id%qi_subl_col > 0) & diag_4d(:,:,k,diag_pt%qidt_subl) = & - (max(0., -1.*dcond_ls_ice(:,:,k) )/ & + -(max(0., -1.*dcond_ls_ice(:,:,k) )/ & max(qi_mean(:,:,k), Nml%qmin))*tmp2(:,:,k) & *inv_dtcloud if (diag_id%qidt_melt + diag_id%qi_melt_col > 0) & - diag_4d(:,:,k,diag_pt%qidt_melt) = D2_dt(:,:,k)* & + diag_4d(:,:,k,diag_pt%qidt_melt) = -D2_dt(:,:,k)* & tmp2(:,:,k) *inv_dtcloud if (diag_id%qidt_eros + diag_id%qi_eros_col > 0) & - diag_4d(:,:,k,diag_pt%qidt_eros) = D_eros(:,:,k)* & + diag_4d(:,:,k,diag_pt%qidt_eros) = - D_eros(:,:,k)* & tmp2(:,:,k) *inv_dtcloud !----------------------------------------------------------------------! @@ -2013,8 +2023,8 @@ SUBROUTINE rotstayn_klein_microp (& !------------------------------------------------------------------------- ! save snow sublimation diagnostics. !------------------------------------------------------------------------- - if (diag_id%snow_subl + diag_id%snow_subl_col > 0) & - diag_4d(:,:,k,diag_pt%snow_subl) = tmp2(:,:,k)/deltpg(:,:,k) + if (diag_id%qdt_snow_sublim + diag_id%q_snow_sublim_col > 0) & + diag_4d(:,:,k,diag_pt%qdt_snow_sublim) = tmp2(:,:,k)/deltpg(:,:,k) !------------------------------------------------------------------------ ! save diagnostics for the predicted cloud tendencies so that @@ -2261,14 +2271,6 @@ SUBROUTINE rotstayn_klein_microp (& !------------------------------------------------------------------------ if (Nml%super_choice) then -!------------------------------------------------------------------------ -! cloud fraction source diagnostic -!------------------------------------------------------------------------ - if (diag_id%qadt_super + diag_id%qa_super_col > 0) then - where (tmp1 .gt. 0.) - diag_4d(:,:,:,diag_pt%qadt_super) = (1.-qa_upd)*inv_dtcloud - endwhere - end if !------------------------------------------------------------------------ ! assign additional droplets where supersaturation is predicted. @@ -2288,6 +2290,15 @@ SUBROUTINE rotstayn_klein_microp (& end do end do endif + if (diag_id%qndt_super + diag_id%qn_super_col > 0) then + if (Nml%do_liq_num) then + where (T .gt. tfreeze - 40. .and. tmp1 .gt. 0.) + diag_4d(:,:,:,diag_pt%qndt_super) = & + diag_4d(:,:,:,diag_pt%qndt_super) + drop1*1.e6/ & + airdens*(1. - qa_upd)*inv_dtcloud + endwhere + endif + end if !------------------------------------------------------------------------ ! THE -40C THRESHOLD IN THE FOLLOWING IS NOT CONSISTENT WITH THE @@ -2319,6 +2330,13 @@ SUBROUTINE rotstayn_klein_microp (& else tmp2s = 0. endif +!moved from above: +!------------------------------------------------------------------------ +! cloud fraction source diagnostic +!------------------------------------------------------------------------ + if (diag_id%qadt_super + diag_id%qa_super_col > 0) then + diag_4d(i,j,k,diag_pt%qadt_super) = (1.-qa_upd(i,j,k)-tmp2s)*inv_dtcloud + end if SA(i,j,k) = SA(i,j,k) + (1.-qa_upd(i,j,k) - tmp2s) qa_upd(i,j,k) = 1. - tmp2s endif @@ -2329,6 +2347,9 @@ SUBROUTINE rotstayn_klein_microp (& !------------------------------------------------------------------------ ! save adjustment diagnostics. !------------------------------------------------------------------------ + where (T .le. tfreeze - 40.) + sum_ice_adj(:,:,:) = tmp1*inv_dtcloud + endwhere if (diag_id%liq_adj + diag_id%liq_adj_col + & diag_id%ice_adj + diag_id%ice_adj_col > 0) then where (T .le. tfreeze - 40.) @@ -2337,15 +2358,6 @@ SUBROUTINE rotstayn_klein_microp (& diag_4d(:,:,:,diag_pt%liq_adj) = tmp1*inv_dtcloud endwhere end if - if (diag_id%qndt_super + diag_id%qn_super_col > 0) then - if (Nml%do_liq_num) then - where (T .gt. tfreeze - 40. .and. tmp1 .gt. 0.) - diag_4d(:,:,:,diag_pt%qndt_super) = & - diag_4d(:,:,:,diag_pt%qndt_super) + drop1*1.e6/ & - airdens*(1. - qa_upd)*inv_dtcloud - endwhere - endif - end if !----------------------------------------------------------------------- ! put supersaturation into precip. add in excess to precipitation @@ -2370,6 +2382,9 @@ SUBROUTINE rotstayn_klein_microp (& !------------------------------------------------------------------------- ! save adjustment diagnostics. !------------------------------------------------------------------------- + where (T .le. tfreeze - 20.) + sum_ice_adj(:,:,:) = tmp1*inv_dtcloud + endwhere if (diag_id%liq_adj + diag_id%liq_adj_col + & diag_id%ice_adj + diag_id%ice_adj_col > 0) then where (T .le. tfreeze - 20.) @@ -2428,23 +2443,33 @@ SUBROUTINE rotstayn_klein_microp (& if (diag_id%qadt_destr + diag_id%qa_destr_col > 0) & diag_4d(:,:,:,diag_pt%qadt_destr) = & diag_4d(:,:,:,diag_pt%qadt_destr) - SA*inv_dtcloud + diag_4d(:,:,:,diag_pt%qadt_destr) = & + -diag_4d(:,:,:,diag_pt%qadt_destr) if (diag_id%qldt_destr + diag_id%ql_destr_col > 0) & diag_4d(:,:,:,diag_pt%qldt_destr) = & diag_4d(:,:,:,diag_pt%qldt_destr) - SL*inv_dtcloud if (diag_id%qidt_destr + diag_id%qi_destr_col > 0) & diag_4d(:,:,:,diag_pt%qidt_destr) = & - diag_4d(:,:,:,diag_pt%qidt_destr) - SI*inv_dtcloud + -( diag_4d(:,:,:,diag_pt%qidt_destr) - SI*inv_dtcloud) if (diag_id%qndt_destr + diag_id%qn_destr_col > 0 .and. & Nml%do_liq_num ) & diag_4d(:,:,:,diag_pt%qndt_destr) = & diag_4d(:,:,:,diag_pt%qndt_destr) - SN *inv_dtcloud + if (diag_id%qldt_destr + diag_id%ql_destr_col > 0) & + diag_4d(:,:,:,diag_pt%qldt_destr) = & + -diag_4d(:,:,:,diag_pt%qldt_destr) + if (diag_id%qndt_destr + diag_id%qn_destr_col > 0 .and. & + Nml%do_liq_num ) & + diag_4d(:,:,:,diag_pt%qndt_destr) = & + -diag_4d(:,:,:,diag_pt%qndt_destr) + !----------------------------------------------------------------------- ! add the ice falling out from cloud to the qidt_fall diagnostic. !----------------------------------------------------------------------- - if ( diag_id%qidt_fall > 0 ) & + if (diag_id%qidt_fall + diag_id%qi_fall_col > 0) & diag_4d(:,:,:,diag_pt%qidt_fall) = & - diag_4d(:,:,:,diag_pt%qidt_fall) + (snow_cld/deltpg) + diag_4d(:,:,:,diag_pt%qidt_fall) - (snow_cld/deltpg) !----------------------------------------------------------------------- ! save output fields of profiles of total rain and snow and clear-sky @@ -2535,6 +2560,23 @@ SUBROUTINE rotstayn_klein_microp (& end if !----------------------------------------------------------------------- +! Used for BC aerosol in-cloud scavenging: + do k=1,kdim + do j=1,jdim + do i=1,idim + qldt_sum = sum_berg(i,j,k) + sum_rime(i,j,k) + & + sum_ice_adj(i,j,k) + sum_cond(i,j,k) + & + sum_freeze(i,j,k) + if (qldt_sum > 0.) then + f_snow_berg(i,j,k) = (sum_berg(i,j,k) + sum_freeze(i,j,k) + & + sum_ice_adj(i,j,k) + sum_cond(i,j,k))/qldt_sum + else + f_snow_berg(i,j,k) = 0. + endif + end do + end do + end do + diff --git a/src/atmos_param/strat_cloud/simple_pdf.F90 b/src/atmos_param/strat_cloud/simple_pdf.F90 index 324a842008..30ec8b5b8e 100644 --- a/src/atmos_param/strat_cloud/simple_pdf.F90 +++ b/src/atmos_param/strat_cloud/simple_pdf.F90 @@ -17,8 +17,8 @@ MODULE simple_pdf_mod !---------------------------------------------------------------------- !----version number---------------------------------------------------- -Character(len=128) :: Version = '$Id: simple_pdf.F90,v 19.0 2012/01/06 20:26:48 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: simple_pdf.F90,v 20.0 2013/12/13 23:22:07 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' @@ -203,11 +203,11 @@ SUBROUTINE simple_pdf (j, idim, jdim, kdim, qmin, qa, qtot, qs, gamma, & !-------------------------------------------------------------------------- ! fill desired diagnostics. !-------------------------------------------------------------------------- - if (diag_id%qadt_lsform > 0) then + if (diag_id%qadt_lsform + diag_id%qa_lsform_col > 0) then diag_4d(:,j,:,diag_pt%qadt_lsform ) = & max(qa1 - qa0, 0.)*inv_dtcloud end if - if (diag_id%qadt_lsdiss > 0) then + if (diag_id%qadt_lsdiss + diag_id%qa_lsdiss_col > 0) then diag_4d(:,j,:,diag_pt%qadt_lsdiss ) = & max(qa0 - qa1, 0.)*inv_dtcloud end if diff --git a/src/atmos_param/strat_cloud/strat_cloud.F90 b/src/atmos_param/strat_cloud/strat_cloud.F90 index 47c6bbb9b0..8552175695 100644 --- a/src/atmos_param/strat_cloud/strat_cloud.F90 +++ b/src/atmos_param/strat_cloud/strat_cloud.F90 @@ -111,7 +111,7 @@ module strat_cloud_mod register_restart_field, & restart_file_type, save_restart, & get_mosaic_tile_file -use constants_mod, only : rdgas, rvgas, hlv, hls, cp_air, grav +use constants_mod, only : rdgas, rvgas, hlv, hls, hlf, cp_air, grav use cloud_rad_mod, only : cloud_rad_init use diag_manager_mod, only : register_diag_field, send_data use time_manager_mod, only : time_type, get_date, get_time @@ -190,7 +190,7 @@ module strat_cloud_mod public strat_cloud_init, strat_cloud, strat_cloud_new, strat_cloud_end, & strat_cloud_sum, strat_cloud_avg, do_strat_cloud, & - strat_cloud_restart + strat_cloud_restart, strat_cloud_time_vary private fill_nml_variable, strat_debug, impose_realizability, strat_alloc,& strat_dealloc @@ -198,8 +198,8 @@ module strat_cloud_mod !------------------------------------------------------------------------ !---version number------------------------------------------------------- -Character(len=128) :: Version = '$Id: strat_cloud.F90,v 19.0 2012/01/06 20:26:50 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: strat_cloud.F90,v 20.0 2013/12/13 23:22:09 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------ !---namelist------------------------------------------------------------- @@ -431,15 +431,47 @@ subroutine strat_cloud_init (axes, Time, idim, jdim, kdim, & if (trim(microphys_scheme) =='rotstayn_klein') then Constants%do_rk_microphys = .true. Constants%do_mg_microphys = .false. + Constants%do_mg_ncar_microphys = .false. + Constants%do_predicted_ice_number = .false. else if (trim(microphys_scheme) == 'morrison_gettelman') then Constants%do_rk_microphys = .false. Constants%do_mg_microphys = .true. + Constants%do_mg_ncar_microphys = .false. + Constants%do_predicted_ice_number = .true. + else if (trim(microphys_scheme) == 'mg_ncar') then + Constants%do_rk_microphys = .false. + Constants%do_mg_microphys = .false. + Constants%do_mg_ncar_microphys = .true. + Constants%do_predicted_ice_number = .true. else call error_mesg ('strat_cloud_init', & 'invalid expression supplied for nml variable microphys_scheme', & FATAL) endif +!------------------------------------------------------------------------ +! define logicals defining macrophysics scheme which is active. +!------------------------------------------------------------------------ + if (trim(macrophys_scheme) == 'tiedtke') then + Constants%tiedtke_macrophysics = .true. + else + Constants%tiedtke_macrophysics = .false. + endif + +!------------------------------------------------------------------------ +! define logicals defining aerosol activation scheme which is active. +!------------------------------------------------------------------------ + if (trim(aerosol_activation_scheme) == 'dqa') then + Constants%dqa_activation = .true. + Constants%total_activation = .false. + else if (trim(aerosol_activation_scheme) == 'total') then + Constants%dqa_activation = .false. + Constants%total_activation = .true. + else + call error_mesg ('strat_cloud_init', & + 'invalid value for aerosol_activation_scheme specified', FATAL) + endif + !----------------------------------------------------------------------- ! pass values of qmin, N_land, N_ocean and as needed, do_liq_num and ! do_mg_microphys to cloud_rad_mod for use there. retrieve the value of @@ -453,12 +485,15 @@ subroutine strat_cloud_init (axes, Time, idim, jdim, kdim, & N_ocean_in=N_ocean, & prog_droplet_in=do_liq_num, & overlap_out=overlap) - else if (Constants%do_mg_microphys) then + else if (Constants%do_mg_microphys .or. & + Constants%do_mg_ncar_microphys) then call cloud_rad_init (axes, Time, qmin_in=qmin, N_land_in=N_land,& N_ocean_in=N_ocean, & prog_droplet_in=do_liq_num, & overlap_out=overlap, & - prog_ice_num_in=Constants%do_mg_microphys) + qcvar_in = Nml%qcvar, & + prog_ice_num_in=Constants%do_mg_microphys .or.& + Constants%do_mg_ncar_microphys) endif else call cloud_rad_init (axes, Time, qmin_in=qmin, N_land_in=N_land,& @@ -785,8 +820,8 @@ end subroutine strat_cloud_init subroutine strat_cloud & (Time, is, ie, js, je, dtcloud, pfull, phalf, radturbten2,& T, qv, ql, qi ,qa, omega, Mc, diff_t, LAND, & - ST, SQ, SL, SI, SA, f_snow_berg, rain3d, snow3d, snowclr3d, & - surfrain, surfsnow, qrat, ahuco, limit_conv_cloud_frac, MASK, & + ST, SQ, SL, SI, SA, f_snow_berg, rain3d, snow3d, snowclr3d, & + surfrain, surfsnow, qrat, ahuco, limit_conv_cloud_frac, MASK, & qn, Aerosol, SN) !------------------------------------------------------------------------- @@ -800,7 +835,7 @@ subroutine strat_cloud & logical, intent(in) :: limit_conv_cloud_frac real, dimension(:,:), intent (in) :: LAND real, dimension(:,:,:), intent (out) :: ST, SQ, SL, SI, SA, & - rain3d, snow3d, & + rain3d, snow3d, & snowclr3d, f_snow_berg real, dimension(:,:), intent (out) :: surfrain, surfsnow real, dimension(:,:,:), intent (in), optional :: MASK, qn @@ -870,6 +905,16 @@ subroutine strat_cloud & end subroutine strat_cloud +subroutine strat_cloud_time_vary (dtcloud, limit_conv_cloud_frac) + +real, intent(in) :: dtcloud +logical, intent(in) :: limit_conv_cloud_frac + + Constants%dtcloud = dtcloud + Constants%inv_dtcloud = 1.0/dtcloud + Constants%limit_conv_cloud_frac = limit_conv_cloud_frac + +end subroutine strat_cloud_time_vary !######################################################################### @@ -1047,7 +1092,7 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & phalf, zhalf, zfull, radturbten2, & T_in, qv_in, ql_in, qi_in, qa_in, omega, Mc, & diff_t, LAND, ST_out, SQ_out, SL_out, SI_out, & - SA_out, f_snow_berg, rain3d, snow3d, & + SA_out, f_snow_berg, rain3d, snow3d, & snowclr3d, surfrain, & surfsnow, qrat, ahuco, limit_conv_cloud_frac, & Aerosol, MASK3d, qn_in, SN_out, qni_in, & @@ -1124,8 +1169,8 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & !------------------------------------------------------------------------ ! counter of columns in which mg_micro is not computed due to negative ! water in column (activated by setting debugo4 to .true.) - integer :: nrefuse - + integer :: nrefuse + outunit = stdout() !----------------------------------------------------------------------- @@ -1143,7 +1188,8 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & Constants%mask_present = .false. Constants%mask = 1.0 END IF - ELSE if (Constants%do_mg_microphys) then + ELSE if (Constants%do_mg_microphys .or. & + Constants%do_mg_ncar_microphys) then IF ( .NOT. present(SNi_out)) THEN call error_mesg ('strat_cloud_new_mod', & 'morrison gettelman microp requires progn. ice num ', FATAL) @@ -1238,9 +1284,6 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & !----------------------------------------------------------------------- ST_out = 0. SQ_out = 0. - Constants%dtcloud = dtcloud - Constants%inv_dtcloud = 1.0/dtcloud - Constants%limit_conv_cloud_frac = limit_conv_cloud_frac call mpp_clock_end (sc_init) !----------------------------------------------------------------------- @@ -1310,23 +1353,30 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & Cloud_state, ST_out, SQ_out, Cloud_processes, & Particles, n_diag_4d, diag_4d, diag_id, diag_pt, otun) call mpp_clock_end (sc_nccond) - + !------------------------------------------------------------------------ ! define the mean droplet number after this timestep's activation. note ! that if the cloud area has not increased during the timestep in r-k ! microphysics, then droplet number does not increase. -! tmp5: A_dt * (1.-qabar) where A_dt = A*dt , A source rate +! delta_cf: A_dt * (1.-qabar) where A_dt = A*dt , A source rate ! Eq. 7 of Yi's 2007 paper !------------------------------------------------------------------------ call mpp_clock_begin (sc_after) do k=1,kdim do j=1,jdim do i=1,idim + if (diag_id%potential_droplets > 0 .and. & + Cloud_processes%da_ls(i,j,k) <= 0.0) & + diag_4d(i,j,k,diag_pt%potential_droplets) = 0.0 + if (diag_id%subgrid_w_variance > 0 .and. & + Cloud_processes%da_ls(i,j,k) <= 0.0) & + diag_4d(i,j,k,diag_pt%subgrid_w_variance) = 0.0 if (Cloud_processes%da_ls(i,j,k) > 0.0 .or. & + Constants%do_mg_ncar_microphys .or. & Constants%do_mg_microphys) then Cloud_state%qn_mean(i,j,k) = & Cloud_state%qn_upd(i,j,k) + & - max(Cloud_processes%tmp5(i,j,k),0.)* & + max(Cloud_processes%delta_cf(i,j,k),0.)* & Particles%drop1(i,j,k)*1.e6/ & Atmos_state%airdens(i,j,k) else @@ -1350,6 +1400,14 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & Cloud_state%qa_upd_0, Cloud_state%SA_0, & nrefuse, isamp, jsamp, ksamp, debugo, debugo0, & debugo1) + if (Constants%do_mg_ncar_microphys .or. & + Constants%do_mg_microphys) then + if (diag_id%qadt_limits + diag_id%qa_limits_col > 0) & + diag_4d(:,:,:,diag_pt%qadt_limits) = & + (Cloud_state%SA_out(:,:,:) - & + diag_4d(:,:,:,diag_pt%qadt_limits)) * & + Constants%inv_dtcloud + endif call mpp_clock_end (sc_micro) !----------------------------------------------------------------------- @@ -1361,7 +1419,17 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & SA_out = Cloud_state%SA_out rain3d = Precip_state%rain3d snow3d = Precip_state%snow3d - snowclr3d = Precip_state%snowclr3d +!RSH +! for r-k, snow in cloud is included in cloud ice. For mg and ncar, +! snow is not included in cloud ice, so all snow must be put into +! snowclr3d which for those schemes is used to hold the total +! precipitating ice field. + if (Constants%do_mg_ncar_microphys .or. & + Constants%do_mg_microphys) then + snowclr3d = Precip_state%snow3d + else + snowclr3d = Precip_state%snowclr3d + endif surfrain = Precip_state%surfrain surfsnow = Precip_state%surfsnow f_snow_berg = Cloud_processes%f_snow_berg @@ -1379,27 +1447,244 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & !----------------------------------------------------------------------- ! define some diagnostics. !----------------------------------------------------------------------- - if (diag_id%rain3d > 0) then - diag_4d_kp1(:,:,:,diag_pt%rain3d) = Precip_state%rain3d(:,:,:) + if (diag_id%SA3d + diag_id%SA2d > 0) then + diag_4d(:,:,:,diag_pt%SA3d) = SA_out(:,:,:)*Constants%inv_dtcloud + endif + if (diag_id%ST3d + diag_id%ST2d > 0) then + diag_4d(:,:,:,diag_pt%ST3d) = ST_out(:,:,:)*Constants%inv_dtcloud + endif + if (diag_id%SQ3d + diag_id%SQ2d > 0) then + diag_4d(:,:,:,diag_pt%SQ3d) = SQ_out(:,:,:)*Constants%inv_dtcloud + endif + if (diag_id%SL3d + diag_id%SL2d > 0) then + diag_4d(:,:,:,diag_pt%SL3d) = SL_out(:,:,:)*Constants%inv_dtcloud + endif + if (diag_id%SI3d + diag_id%SI2d > 0) then + diag_4d(:,:,:,diag_pt%SI3d) = SI_out(:,:,:)*Constants%inv_dtcloud + endif + if (diag_id%SN3d + diag_id%SN2d > 0) then + diag_4d(:,:,:,diag_pt%SN3d) = Cloud_state%SN_out(:,:,:)* & + Constants%inv_dtcloud + endif + if (diag_id%SNI3d + diag_id%SNI2d > 0) then + diag_4d(:,:,:,diag_pt%SNI3d) = Cloud_state%SNI_out(:,:,:)* & + Constants%inv_dtcloud + endif + +!----------------------------------------------------------------------- +! define some diagnostics. +!----------------------------------------------------------------------- + if (diag_id%SA_imb + diag_id%SA_imb_col > 0) then + diag_4d(:,:,:,diag_pt%SA_imb) = & + diag_4d(:,:,:,diag_pt%SA3d) - ( & + diag_4d(:,:,:,diag_pt%qadt_lsform) & + + diag_4d(:,:,:,diag_pt%qadt_lsdiss) & + + diag_4d(:,:,:,diag_pt%qadt_rhred) & + + diag_4d(:,:,:,diag_pt%qadt_eros) & + + diag_4d(:,:,:,diag_pt%qadt_fill) & + + diag_4d(:,:,:,diag_pt%qadt_super) & + + diag_4d(:,:,:,diag_pt%qadt_destr) & + + diag_4d(:,:,:,diag_pt%qadt_limits) & + + diag_4d(:,:,:,diag_pt%qadt_ahuco) & + ) endif - if (diag_id%snow3d > 0) then - diag_4d_kp1(:,:,:,diag_pt%snow3d) = Precip_state%snow3d(:,:,:) + if (diag_id%SL_imb + diag_id%SL_imb_col > 0) then + diag_4d(:,:,:,diag_pt%SL_imb) = & + diag_4d(:,:,:,diag_pt%SL3d) - ( & + diag_4d(:,:,:,diag_pt%qldt_cond ) & + + diag_4d(:,:,:,diag_pt%qldt_evap ) & + + diag_4d(:,:,:,diag_pt%qldt_eros ) & + + diag_4d(:,:,:,diag_pt%qldt_berg) & + + diag_4d(:,:,:,diag_pt%qldt_freez ) & + + diag_4d(:,:,:,diag_pt%liq_adj ) & + + diag_4d(:,:,:,diag_pt%qldt_rime ) & + + diag_4d(:,:,:,diag_pt%qldt_accr) & + + diag_4d(:,:,:,diag_pt%qldt_auto) & + + diag_4d(:,:,:,diag_pt%qldt_fill ) & + + diag_4d(:,:,:,diag_pt%qldt_destr ) & + + diag_4d(:,:,:,diag_pt%qldt_freez2) & + + diag_4d(:,:,:,diag_pt%qldt_sedi ) & + + diag_4d(:,:,:,diag_pt%qldt_accrs) & + + diag_4d(:,:,:,diag_pt%qldt_bergs) & + + diag_4d(:,:,:,diag_pt%qldt_HM_splinter) & + - diag_4d(:,:,:,diag_pt%qidt_melt2 ) & + - diag_4d(:,:,:,diag_pt%qidt_accrs) & + - diag_4d(:,:,:,diag_pt%qdt_cleanup_liquid) & + ) endif - if ( diag_id%debug5_3d > 0 ) then - diag_4d(:,:,:,diag_pt%debug5_3d) = & - MIN(diag_4d(:,:,:,diag_pt%debug5_3d), 1.) + if (diag_id%SI_imb + diag_id%SI_imb_col > 0) then + diag_4d(:,:,:,diag_pt%SI_imb) = & + diag_4d(:,:,:,diag_pt%SI3d) - ( & + - diag_4d(:,:,:,diag_pt%qldt_berg) & + - diag_4d(:,:,:,diag_pt%qldt_freez ) & + - diag_4d(:,:,:,diag_pt%qldt_rime ) & + - diag_4d(:,:,:,diag_pt%qldt_freez2) & + - diag_4d(:,:,:,diag_pt%qldt_HM_splinter) & + + diag_4d(:,:,:,diag_pt%qidt_dep ) & + + diag_4d(:,:,:,diag_pt%qidt_subl ) & + + diag_4d(:,:,:,diag_pt%qidt_fall ) & + + diag_4d(:,:,:,diag_pt%qidt_eros ) & + + diag_4d(:,:,:,diag_pt%qidt_melt ) & + + diag_4d(:,:,:,diag_pt%qidt_melt2 ) & + + diag_4d(:,:,:,diag_pt%qidt_fill ) & + + diag_4d(:,:,:,diag_pt%qidt_destr ) & + + diag_4d(:,:,:,diag_pt%qidt_qvdep ) & + + diag_4d(:,:,:,diag_pt%qidt_auto) & + + diag_4d(:,:,:,diag_pt%qidt_accr) & + + diag_4d(:,:,:,diag_pt%qidt_accrs) & + + diag_4d(:,:,:,diag_pt%ice_adj ) & + - diag_4d(:,:,:,diag_pt%qdt_cleanup_ice) & + ) + endif + + + if (diag_id%SN_imb + diag_id%SN_imb_col > 0) then + diag_4d(:,:,:,diag_pt%SN_imb) = & + diag_4d(:,:,:,diag_pt%SN3d) - ( & + diag_4d(:,:,:,diag_pt%qndt_cond ) & + + diag_4d(:,:,:,diag_pt%qndt_evap ) & + + diag_4d(:,:,:,diag_pt%qndt_fill ) & + + diag_4d(:,:,:,diag_pt%qndt_berg ) & + + diag_4d(:,:,:,diag_pt%qndt_destr ) & + + diag_4d(:,:,:,diag_pt%qndt_super ) & + + diag_4d(:,:,:,diag_pt%qndt_freez ) & + + diag_4d(:,:,:,diag_pt%qndt_sacws ) & + + diag_4d(:,:,:,diag_pt%qndt_sacws_o) & + + diag_4d(:,:,:,diag_pt%qndt_eros ) & + + diag_4d(:,:,:,diag_pt%qndt_pra ) & + + diag_4d(:,:,:,diag_pt%qndt_auto ) & + + diag_4d(:,:,:,diag_pt%qndt_nucclim) & + + diag_4d(:,:,:,diag_pt%qndt_sedi ) & + + diag_4d(:,:,:,diag_pt%qndt_melt) & + + diag_4d(:,:,:,diag_pt%qndt_ihom) & + + diag_4d(:,:,:,diag_pt%qndt_size_adj) & + + diag_4d(:,:,:,diag_pt%qndt_fill2) & + + diag_4d(:,:,:,diag_pt%qndt_contact_frz) & + + diag_4d(:,:,:,diag_pt%qndt_cleanup) & + + diag_4d(:,:,:,diag_pt%qndt_cleanup2) & + ) + endif + + if (diag_id%SNi_imb + diag_id%SNi_imb_col > 0) then + diag_4d(:,:,:,diag_pt%SNi_imb) = & + diag_4d(:,:,:,diag_pt%SNi3d) - ( & + diag_4d(:,:,:,diag_pt%qnidt_fill ) & + + diag_4d(:,:,:,diag_pt%qnidt_nnuccd) & + + diag_4d(:,:,:,diag_pt%qnidt_nsubi) & + + diag_4d(:,:,:,diag_pt%qnidt_nerosi) & + + diag_4d(:,:,:,diag_pt%qnidt_nprci) & + + diag_4d(:,:,:,diag_pt%qnidt_nprai) & + + diag_4d(:,:,:,diag_pt%qnidt_nucclim1) & + + diag_4d(:,:,:,diag_pt%qnidt_nucclim2) & + + diag_4d(:,:,:,diag_pt%qnidt_sedi ) & + + diag_4d(:,:,:,diag_pt%qnidt_melt ) & + + diag_4d(:,:,:,diag_pt%qnidt_size_adj ) & + + diag_4d(:,:,:,diag_pt%qnidt_fill2 ) & + + diag_4d(:,:,:,diag_pt%qnidt_super ) & + + diag_4d(:,:,:,diag_pt%qnidt_ihom ) & + + diag_4d(:,:,:,diag_pt%qnidt_destr ) & + + diag_4d(:,:,:,diag_pt%qnidt_cleanup) & + + diag_4d(:,:,:,diag_pt%qnidt_cleanup2) & + + diag_4d(:,:,:,diag_pt%qnidt_nsacwi) & + ) + endif + + if (diag_id%SQ_imb + diag_id%SQ_imb_col > 0) then + diag_4d(:,:,:,diag_pt%SQ_imb) = & + diag_4d(:,:,:,diag_pt%SQ3d) - ( & + - diag_4d(:,:,:,diag_pt%qldt_cond ) & + - diag_4d(:,:,:,diag_pt%qldt_evap ) & + - diag_4d(:,:,:,diag_pt%qldt_eros ) & + - diag_4d(:,:,:,diag_pt%liq_adj ) & + - diag_4d(:,:,:,diag_pt%qldt_fill ) & + - diag_4d(:,:,:,diag_pt%qldt_destr ) & + - diag_4d(:,:,:,diag_pt%qidt_dep ) & + - diag_4d(:,:,:,diag_pt%qidt_subl ) & + - diag_4d(:,:,:,diag_pt%qidt_eros ) & + - diag_4d(:,:,:,diag_pt%qidt_fill ) & + - diag_4d(:,:,:,diag_pt%qidt_destr ) & + - diag_4d(:,:,:,diag_pt%qidt_qvdep ) & + - diag_4d(:,:,:,diag_pt%ice_adj ) & + + diag_4d(:,:,:,diag_pt%rain_evap ) & + + diag_4d(:,:,:,diag_pt%qdt_sedi_ice2vapor) & + + diag_4d(:,:,:,diag_pt%qdt_sedi_liquid2vapor) & + + diag_4d(:,:,:,diag_pt%qdt_cleanup_ice) & + + diag_4d(:,:,:,diag_pt%qdt_cleanup_liquid) & + + diag_4d(:,:,:,diag_pt%qdt_snow_sublim ) & + + diag_4d(:,:,:,diag_pt%qdt_snow2vapor ) & + ) + endif + + if (diag_id%ST_imb + diag_id%ST_imb_col > 0) then + diag_4d(:,:,:,diag_pt%ST_imb) = & + diag_4d(:,:,:,diag_pt%ST3d) - ( & + - hlf*diag_4d(:,:,:,diag_pt%qldt_berg) & + - hlf*diag_4d(:,:,:,diag_pt%qldt_freez ) & + - hlf*diag_4d(:,:,:,diag_pt%qldt_rime ) & + - hlf*diag_4d(:,:,:,diag_pt%qldt_freez2) & + - hlf*diag_4d(:,:,:,diag_pt%qldt_accrs) & + - hlf*diag_4d(:,:,:,diag_pt%qldt_bergs) & + - hlf*diag_4d(:,:,:,diag_pt%qldt_HM_splinter) & + + hlf*diag_4d(:,:,:,diag_pt%qidt_melt ) & + + hlf*diag_4d(:,:,:,diag_pt%qidt_melt2 ) & + + hlf*diag_4d(:,:,:,diag_pt%qidt_accrs) & + + hlf*diag_4d(:,:,:,diag_pt%rain_freeze) & + - hlf*diag_4d(:,:,:,diag_pt%srfrain_accrs ) & + - hlf*diag_4d(:,:,:,diag_pt%srfrain_freez ) & + - hlf*diag_4d(:,:,:,diag_pt%snow_melt) & + + + hlv*diag_4d(:,:,:,diag_pt%qldt_cond ) & + + hlv*diag_4d(:,:,:,diag_pt%qldt_evap ) & + + hlv*diag_4d(:,:,:,diag_pt%qldt_eros ) & + + hlv*diag_4d(:,:,:,diag_pt%liq_adj ) & + + hlv*diag_4d(:,:,:,diag_pt%qldt_fill ) & + + hlv*diag_4d(:,:,:,diag_pt%qldt_destr ) & + - hlv*diag_4d(:,:,:,diag_pt%rain_evap ) & + - hlv*diag_4d(:,:,:,diag_pt%qdt_sedi_liquid2vapor) & + - hlv*diag_4d(:,:,:,diag_pt%qdt_cleanup_liquid) & + + + hls*diag_4d(:,:,:,diag_pt%qidt_dep ) & + + hls*diag_4d(:,:,:,diag_pt%qidt_subl ) & + + hls*diag_4d(:,:,:,diag_pt%qidt_eros ) & + + hls*diag_4d(:,:,:,diag_pt%qidt_fill ) & + + hls*diag_4d(:,:,:,diag_pt%qidt_destr ) & + + hls*diag_4d(:,:,:,diag_pt%qidt_qvdep ) & + + hls*diag_4d(:,:,:,diag_pt%ice_adj ) & + - hls*diag_4d(:,:,:,diag_pt%qdt_sedi_ice2vapor) & + - hls*diag_4d(:,:,:,diag_pt%qdt_cleanup_ice) & + - hls*diag_4d(:,:,:,diag_pt%qdt_snow_sublim ) & + - hls*diag_4d(:,:,:,diag_pt%qdt_snow2vapor ) & + )/cp_air + endif + + if (diag_id%rain3d > 0) then + diag_4d_kp1(:,:,:,diag_pt%rain3d) = Precip_state%rain3d(:,:,:) + endif + if (diag_id%snow3d > 0) then + diag_4d_kp1(:,:,:,diag_pt%snow3d) = Precip_state%snow3d(:,:,:) + endif + + if ( diag_id%cf_ice_init > 0 ) then + diag_4d(:,:,:,diag_pt%cf_ice_init) = & + MIN(diag_4d(:,:,:,diag_pt%cf_ice_init), 1.) end if if (diag_id%droplets > 0) then diag_4d(:,:,:,diag_pt%droplets) = N3D(:,:,:) end if + if (diag_id%droplets_wtd > 0) then + diag_4d(:,:,:,diag_pt%droplets_wtd) = N3D(:,:,:)*ql_in(:,:,:) + end if + if (diag_id%ql_wt > 0) then + diag_4d(:,:,:,diag_pt%ql_wt) = ql_in(:,:,:) + end if if (diag_id%nice > 0) then diag_4d(:,:,:,diag_pt%nice) = N3Di(:,:,:) end if if (diag_id%qrout > 0) then - diag_4d(:,:,:,diag_pt%qrout) = Precip_state%qrout3d_mg(:,:,:) + diag_4d(:,:,:,diag_pt%qrout) = Precip_state%lsc_rain (:,:,:) end if if (diag_id%qsout > 0) then - diag_4d(:,:,:,diag_pt%qsout) = Precip_state%qsout3d_mg(:,:,:) + diag_4d(:,:,:,diag_pt%qsout) = Precip_state%lsc_snow (:,:,:) end if !------------------------------------------------------------------------- @@ -1463,12 +1748,94 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & + diag_4d(:,:,k,nn)*Atmos_state%deltpg(:,:,k) enddo enddo - +!------------------------------------------------------------------------ +!SPECIAL CASES not following general pattern of above: +!rain, snow cloud ice and cloud liquid fallout -- only column integrals +!are valid +!------------------------------------------------------------------------ + if (Constants%do_mg_microphys .or. & + Constants%do_mg_ncar_microphys) then + if (diag_id%cld_liq_imb + diag_id%cld_liq_imb_col > 0) then + diag_3d(:,:,diag_pt%cld_liq_imb) = - ( & + diag_3d(:,:,diag_pt%qldt_sedi ) + & + diag_3d(:,:,diag_pt%qdt_sedi_liquid2vapor) ) + endif + if (diag_id%cld_ice_imb + diag_id%cld_ice_imb_col > 0) then + diag_3d(:,:,diag_pt%cld_ice_imb) = - ( & + diag_3d(:,:,diag_pt%qidt_fall ) + & + diag_3d(:,:,diag_pt%qdt_sedi_ice2vapor) ) + endif + endif + IF ( diag_id%neg_rain > 0 ) & + diag_3d(:,:,diag_pt%neg_rain) = & + diag_4d(:,:,1,diag_pt%neg_rain) + IF ( diag_id%neg_snow > 0 ) & + diag_3d(:,:,diag_pt%neg_snow) = & + diag_4d(:,:,1,diag_pt%neg_snow) + if (diag_id%rain_imb + diag_id%rain_imb_col > 0) then + diag_3d(:,:,diag_pt%rain_imb) = & + Precip_state%surfrain(:,:)*Constants%inv_dtcloud - & + diag_3d(:,:,diag_pt%cld_liq_imb) + ( & + diag_3d(:,:,diag_pt%qldt_accr) & + + diag_3d(:,:,diag_pt%qldt_auto ) & + + diag_3d(:,:,diag_pt%qidt_melt ) & + + diag_3d(:,:,diag_pt%rain_evap) & + + diag_3d(:,:,diag_pt%rain_freeze) & + - diag_3d(:,:,diag_pt%srfrain_accrs) & + - diag_3d(:,:,diag_pt%srfrain_freez) & + + diag_3d(:,:,diag_pt%neg_rain) & + - diag_3d(:,:,diag_pt%snow_melt ) & + + diag_3d(:,:,diag_pt%qdt_snow2vapor) & + ) + endif + if (diag_id%snow_imb + diag_id%snow_imb_col > 0) then + + if (Constants%do_rk_microphys) then + diag_3d(:,:,diag_pt%snow_imb) = & + Precip_state%surfsnow(:,:)*Constants%inv_dtcloud - & + diag_3d(:,:,diag_pt%cld_ice_imb) + ( & + diag_3d(:,:,diag_pt%qldt_accrs) & + + diag_3d(:,:,diag_pt%qldt_bergs) & + + diag_3d(:,:,diag_pt%qidt_fall) & + + diag_3d(:,:,diag_pt%qidt_auto ) & + + diag_3d(:,:,diag_pt%qidt_accr ) & + - diag_3d(:,:,diag_pt%rain_freeze) & + + diag_3d(:,:,diag_pt%srfrain_accrs) & + + diag_3d(:,:,diag_pt%srfrain_freez) & + + diag_3d(:,:,diag_pt%snow_melt ) & + + diag_3d(:,:,diag_pt%neg_snow) & + + diag_3d(:,:,diag_pt%qdt_snow_sublim) & + ) + else + diag_3d(:,:,diag_pt%snow_imb) = & + Precip_state%surfsnow(:,:)*Constants%inv_dtcloud - & + diag_3d(:,:,diag_pt%cld_ice_imb) + ( & + diag_3d(:,:,diag_pt%qldt_accrs) & + + diag_3d(:,:,diag_pt%qldt_bergs) & + + diag_3d(:,:,diag_pt%qidt_auto ) & + + diag_3d(:,:,diag_pt%qidt_accr ) & + - diag_3d(:,:,diag_pt%rain_freeze) & + + diag_3d(:,:,diag_pt%srfrain_accrs) & + + diag_3d(:,:,diag_pt%srfrain_freez) & + + diag_3d(:,:,diag_pt%snow_melt ) & + + diag_3d(:,:,diag_pt%neg_snow) & + + diag_3d(:,:,diag_pt%qdt_snow_sublim) & + ) + endif + endif !------------------------------------------------------------------------ !SPECIAL CASES not following general pattern of above: !yim: in-cloud droplet column burden !------------------------------------------------------------------------ - if (diag_id%droplets_col > 0 .or. diag_id%gb_droplets_col > 0 ) then + IF ( diag_id%rain_mass_conv > 0 ) & + diag_3d(:,:,diag_pt%rain_mass_conv) = & + diag_4d(:,:,1,diag_pt%rain_mass_conv) + IF ( diag_id%snow_mass_conv > 0 ) & + diag_3d(:,:,diag_pt%snow_mass_conv) = & + diag_4d(:,:,1,diag_pt%snow_mass_conv) + + if (diag_id%droplets_col > 0 .or. diag_id%gb_droplets_col > 0 .or. & + diag_id%droplets_col250 > 0 ) then if (present (qn_in)) then N3D_col(:,:) = 0. N3D_col250(:,:) = 0. @@ -1476,14 +1843,19 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & do k =1,kdim do j=1,jdim do i=1,idim +! the current code: qa_new = qa_in(i,j,k) + SA_out(i,j,k) ql_new = ql_in(i,j,k) + SL_out(i,j,k) qn_new = qn_in(i,j,k) + SN_out(i,j,k) if (ql_new > qmin .and. & qa_new > qmin .and. & qn_new > qmin ) then - dum = qn_new*Atmos_state%airdens(i,j,k)* & - Atmos_state%deltpg(i,j,k)*1.e-6 +!RSH 12/22/11 fix as per email from yim 11/3/11: +! dum = qn_new*Atmos_state%airdens(i,j,k)* & + dum = qn_new* & +!RSH 12/22/11 fix as per email from yim 11/3/11: +! Atmos_state%deltpg(i,j,k)*1.e-6 + Atmos_state%deltpg(i,j,k)*1.e-4 if (qa_new > 0.05) then !count only columns with qa > 5% N3D_col(i,j) = N3D_col(i,j) + dum /min(qa_new,1.) if (T_in(i,j,k) + st_out(i,j,k) .ge. 250.) then @@ -1496,7 +1868,30 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & end do end do end do - diag_3d(:,:,diag_pt%droplets_col_s) = N3D_col +! end of current code +! the legacy equivalent +!NOTE: in addition to the error correction, the legacy code differs from +! the new code in that it is appplied to input fields rather than output i +! fields. +! if (ql_in(i,j,k) > qmin .and. & +! qa_in(i,j,k) > qmin .and. & +! qn_in(i,j,k) > qmin ) then +! dum = qn_in(i,j,k)*Atmos_state%airdens(i,j,k)* & +! Atmos_state%deltpg(i,j,k)*1.e-6 +! if (qa_new > 0.05) then !count only columns with qa > 5% +! N3D_col(i,j) = N3D_col(i,j) + dum /min(qa_in(i,j,k),1.) +! if (T_in(i,j,k) + st_out(i,j,k) .ge. 250.) then +! N3D_col250(i,j) = N3D_col250(i,j) + & +! dum /min (qa_in(i,j,k), 1.) +! endif +! endif +! gb_N3D_col(i,j) = gb_N3D_col(i,j) + dum +! endif +! end do +! end do +! end do +! end of the legacy equivalent + diag_3d(:,:,diag_pt%droplets_col) = N3D_col diag_3d(:,:,diag_pt%droplets_col250) = N3D_col250 diag_3d(:,:,diag_pt%gb_droplets_col) = gb_N3D_col endif @@ -1534,6 +1929,8 @@ subroutine strat_cloud_new (Time, is, ie, js, je, dtcloud, pfull, & endif endif + + !------------------------------------------------------------------------- ! call strat_netcdf to output the requested netcdf diagnostics. !------------------------------------------------------------------------- @@ -1950,6 +2347,7 @@ subroutine fill_nml_variable Nml%vfact = vfact Nml%cfact = cfact Nml%do_old_snowmelt = do_old_snowmelt + Nml%retain_cm3_bug = retain_cm3_bug Nml%do_pdf_clouds = do_pdf_clouds Nml%betaP = betaP Nml%iwc_crit = iwc_crit @@ -1965,14 +2363,21 @@ subroutine fill_nml_variable Nml%num_mass_ratio1 = num_mass_ratio1 Nml%num_mass_ratio2 = num_mass_ratio2 Nml%microphys_scheme = microphys_scheme + Nml%macrophys_scheme = macrophys_scheme + Nml%aerosol_activation_scheme = aerosol_activation_scheme + Nml%mass_cons = mass_cons Nml%super_ice_opt = super_ice_opt Nml%pdf_org = pdf_org Nml%do_ice_nucl_wpdf = do_ice_nucl_wpdf + Nml%do_hallet_mossop = do_hallet_mossop + Nml%activate_all_ice_always = activate_all_ice_always Nml%debugo = debugo Nml%isamp = isamp Nml%jsamp = jsamp Nml%ksamp = ksamp + Nml%qcvar = qcvar + !---------------------------------------------------------------------- end subroutine fill_nml_variable @@ -1995,127 +2400,127 @@ subroutine strat_debug (otun, ST_out, SQ_out, Cloud_state, Precip_state, & !------------------------------------------------------------------------ ! write numerous diagnostics to file otun to aid in debugging. !------------------------------------------------------------------------ - write(otun, *) , "eee max, min ST ", MAXVAL(ST_out), MINVAL(ST_out) - write(otun, *) , "eee maxloc, minloc ", MAXLOC(ST_out), & + write(otun, *) "eee max, min ST ", MAXVAL(ST_out), MINVAL(ST_out) + write(otun, *) "eee maxloc, minloc ", MAXLOC(ST_out), & MINLOC(ST_out) call check_nan (ST_out,'ST_out') - write(otun, *) , "eee max, min SQ ", MAXVAL(SQ_out), MINVAL(SQ_out) - write(otun, *) , "eee maxloc, minloc ", MAXLOC(SQ_out), & + write(otun, *) "eee max, min SQ ", MAXVAL(SQ_out), MINVAL(SQ_out) + write(otun, *) "eee maxloc, minloc ", MAXLOC(SQ_out), & MINLOC(SQ_out) call check_nan (SQ_out,'SQ_out') - write(otun, *) , "eee max, min SL ", MAXVAL(Cloud_state%SL_out), & + write(otun, *) "eee max, min SL ", MAXVAL(Cloud_state%SL_out), & MINVAL(Cloud_state%SL_out) - write(otun, *) , "eee maxloc, minloc ", MAXLOC(Cloud_state%SL_out),& + write(otun, *) "eee maxloc, minloc ", MAXLOC(Cloud_state%SL_out),& MINLOC(Cloud_state%SL_out) - write(otun, *) , "eee max, min SI ", MAXVAL(Cloud_state%SI_out), & + write(otun, *) "eee max, min SI ", MAXVAL(Cloud_state%SI_out), & MINVAL(Cloud_state%SI_out) - write(otun, *) , "eee maxloc, minloc ", MAXLOC(Cloud_state%SI_out),& + write(otun, *) "eee maxloc, minloc ", MAXLOC(Cloud_state%SI_out),& MINLOC(Cloud_state%SI_out) call check_nan (Cloud_state%SI_out,'SI_out') - write(otun, *) , "eee max, min SA ", MAXVAL(Cloud_state%SA_out), & + write(otun, *) "eee max, min SA ", MAXVAL(Cloud_state%SA_out), & MINVAL(Cloud_state%SA_out) - write(otun, *) , "eee maxloc, minloc ", MAXLOC(Cloud_state%SA_out),& + write(otun, *) "eee maxloc, minloc ", MAXLOC(Cloud_state%SA_out),& MINLOC(Cloud_state%SA_out) call check_nan (Cloud_state%SA_out,'SA_out') - write(otun, *) , "eee max, min SN ", MAXVAL(Cloud_state%SN_out), & + write(otun, *) "eee max, min SN ", MAXVAL(Cloud_state%SN_out), & MINVAL(Cloud_state%SN_out) - write(otun, *) , "eee maxloc, minloc ", & + write(otun, *) "eee maxloc, minloc ", & MAXLOC(Cloud_state%SN_out), MINLOC(Cloud_state%SN_out) call check_nan (Cloud_state%SN_out,'SN_out') - write(otun, *) , "eee max, min SNi ", MAXVAL(Cloud_state%SNi_out),& + write(otun, *) "eee max, min SNi ", MAXVAL(Cloud_state%SNi_out),& MINVAL(Cloud_state%SNi_out) - write(otun, *) , "eee maxloc, minloc ", & + write(otun, *) "eee maxloc, minloc ", & MAXLOC(Cloud_state%SNi_out), MINLOC(Cloud_state%SNi_out) call check_nan (Cloud_state%SNi_out,'SNi_out') - write(otun, *) , "--" - write(otun, *) , "eee max, min T+ST ", & + write(otun, *) "--" + write(otun, *) "eee max, min T+ST ", & MAXVAL(Atmos_state%T_in + ST_out), & MINVAL(Atmos_state%T_in + ST_out) - write(otun, *) , "eee max, min qv+SQ ", & + write(otun, *) "eee max, min qv+SQ ", & MAXVAL(Atmos_state%qv_in + SQ_out), & MINVAL(Atmos_state%qv_in + SQ_out) - write(otun, *) , "eee max, min ql+ SL ", & + write(otun, *) "eee max, min ql+ SL ", & MAXVAL(Cloud_state%ql_in+Cloud_state%SL_out), & MINVAL(Cloud_state%ql_in+Cloud_state%SL_out) - write(otun, *) , "eee max, min qi +SI ", & + write(otun, *) "eee max, min qi +SI ", & MAXVAL(Cloud_state%qi_in+ Cloud_state%SI_out), & MINVAL(Cloud_state%qi_in + Cloud_state%SI_out) - write(otun, *) , "eee max, min qa + SA ", & + write(otun, *) "eee max, min qa + SA ", & MAXVAL(Cloud_state%qa_in+Cloud_state%SA_out), & MINVAL(Cloud_state%qa_in+Cloud_state%SA_out) - write(otun, *) , "eee max, min qn + SN ", & + write(otun, *) "eee max, min qn + SN ", & MAXVAL(Cloud_state%qn_in + Cloud_state%SN_out), & MINVAL(Cloud_state%qn_in + Cloud_state%SN_out) - write(otun, *) , "eee max, min qni SNi ", & + write(otun, *) "eee max, min qni SNi ", & MAXVAL(Cloud_state%qni_in+ Cloud_state%SNi_out), & MINVAL(Cloud_state%qni_in+Cloud_state%SNi_out) - write(otun, *) , "--" - write(otun, *) , "--" + write(otun, *) "--" + write(otun, *) "--" - write(otun, *) , "eee max, min rain3d ", & + write(otun, *) "eee max, min rain3d ", & MAXVAL(Precip_state%rain3d), MINVAL(Precip_state%rain3d) - write(otun, *) , "eee maxloc, minloc ", & + write(otun, *) "eee maxloc, minloc ", & MAXLOC(Precip_state%rain3d), MINLOC(Precip_state%rain3d) call check_nan (Precip_state%rain3d,'rain3d') - write(otun, *) , "eee max, min snow3d ", & + write(otun, *) "eee max, min snow3d ", & MAXVAL(Precip_state%snow3d), MINVAL(Precip_state%snow3d) - write(otun, *) , "eee maxloc, minloc ", & + write(otun, *) "eee maxloc, minloc ", & MAXLOC(Precip_state%snow3d), MINLOC(Precip_state%snow3d) call check_nan (Precip_state%snow3d,'snow3d') - write(otun, *) , "--" - write(otun, *) , "eee max, min surfrain ", & + write(otun, *) "--" + write(otun, *) "eee max, min surfrain ", & MAXVAL(Precip_state%surfrain), MINVAL(Precip_state%surfrain) - write(otun, *) , "eee maxloc, minloc ", & + write(otun, *) "eee maxloc, minloc ", & MAXLOC(Precip_state%surfrain), MINLOC(Precip_state%surfrain) - write(otun, *) , "eee max, min surfsnow ", & + write(otun, *) "eee max, min surfsnow ", & MAXVAL(Precip_state%surfsnow), MINVAL(Precip_state%surfsnow) - write(otun, *) , "eee maxloc, minloc ", & + write(otun, *) "eee maxloc, minloc ", & MAXLOC(Precip_state%surfsnow), MINLOC(Precip_state%surfsnow) - write(otun, *) , "--" + write(otun, *) "--" IF ( MAXVAL(SQ_out + Cloud_state%ql_in) .GT. 1.e-1 ) & - write(otun, *) ," MMMMM Q1 " + write(otun, *) " MMMMM Q1 " IF ( MAXVAL(SQ_out + Cloud_state%ql_in) .LT. 0. ) & - write(otun, *) ," MMMMM Q2 " + write(otun, *) " MMMMM Q2 " IF ( MAXVAL(Cloud_state%SI_out + Cloud_state%qi_in) .LT. 0. ) & - write(otun, *) ," MMMMM I11 " + write(otun, *) " MMMMM I11 " IF ( MAXVAL(Cloud_state%SL_out + Cloud_state%ql_in) .LT. 0. ) & - write(otun, *) ," MMMMM L11 " + write(otun, *) " MMMMM L11 " IF ( MAXVAL( & Cloud_state%qa_in+Cloud_state%SA_out+Atmos_state%ahuco) & .GT. 1.00000000001 ) THEN - write(otun, *) ," MMMMMA1 ahuco " + write(otun, *) " MMMMMA1 ahuco " maxl = maxloc (Cloud_state%qa_in + Cloud_state%SA_out + & Atmos_state%ahuco) - write(otun, *) ," maxloc(qa+SA) ", & + write(otun, *) " maxloc(qa+SA) ", & maxloc (Cloud_state%qa_in + Cloud_state%SA_out + & Atmos_state%ahuco) - write(otun, *) ," qa+SA+ahuco ", & + write(otun, *) " qa+SA+ahuco ", & Cloud_state%qa_in(maxl(1),maxl(2),maxl(3)) + & Cloud_state%SA_out(maxl(1),maxl(2),maxl(3)) +& Atmos_state%ahuco(maxl(1),maxl(2),maxl(3)) - write(otun, *) ," qa, ahuco, SA ", & + write(otun, *) " qa, ahuco, SA ", & Cloud_state%qa_in(maxl(1),maxl(2),maxl(3)), & Atmos_state%ahuco(maxl(1),maxl(2),maxl(3)), & Cloud_state%SA_out(maxl(1),maxl(2),maxl(3)) @@ -2124,23 +2529,23 @@ subroutine strat_debug (otun, ST_out, SQ_out, Cloud_state, Precip_state, & IF ( MINVAL(Cloud_state%qa_in+Cloud_state%SA_out) .LT. 0. ) THEN minl = minloc(Cloud_state%qa_in+Cloud_state%SA_out) - write(otun, *) ," MMMMMA2" - write(otun, *) ," minloc(qa+SA) ", & + write(otun, *) " MMMMMA2" + write(otun, *) " minloc(qa+SA) ", & minloc(Cloud_state%qa_in+Cloud_state%SA_out) - write(otun, *) ," qa+SA ", & + write(otun, *) " qa+SA ", & Cloud_state%qa_in(minl(1),minl(2),minl(3)) + & Cloud_state%SA_out(minl(1),minl(2),minl(3)) - write(otun, *) ," qa, SA ", & + write(otun, *) " qa, SA ", & Cloud_state%qa_in(minl(1),minl(2),minl(3)), & Cloud_state%SA_out(minl(1),minl(2),minl(3)) END IF IF ( MINVAL(Cloud_state%qn_in+Cloud_state%SN_out) .LT. 0. ) THEN - write(otun, *) ," MMMMMN1" + write(otun, *) " MMMMMN1" minl = minloc(Cloud_state%qn_in+Cloud_state%SN_out) - write(otun, *) ," minloc(qn+SN) ", & + write(otun, *) " minloc(qn+SN) ", & minloc(Cloud_state%qn_in+Cloud_state%SN_out) - write(otun, *) ," qn, SN ", & + write(otun, *) " qn, SN ", & Cloud_state%qn_in(minl(1),minl(2),minl(3)), & Cloud_state%SN_out(minl(1),minl(2),minl(3)) END IF @@ -2148,40 +2553,40 @@ subroutine strat_debug (otun, ST_out, SQ_out, Cloud_state, Precip_state, & IF ( MAXVAL(Cloud_state%qi_in + & Cloud_state%SI_out) .GT. 1.e-2 ) then maxl = MAXLOC(Cloud_state%qi_in + Cloud_state%SI_out) - write(otun, *) ," MMMMMII" - write(otun, *) ," maxloc(qi+SI) ", & + write(otun, *) " MMMMMII" + write(otun, *) " maxloc(qi+SI) ", & maxloc(Cloud_state%qi_in+Cloud_state%SI_out) - write(otun, *) ," qi+SI " , & + write(otun, *) " qi+SI " , & Cloud_state%qi_in(maxl(1),maxl(2),maxl(3))+ & Cloud_state%SI_out(maxl(1),maxl(2),maxl(3)) - write(otun, *) ," qi, SI " , & + write(otun, *) " qi, SI " , & Cloud_state%qi_in(maxl(1),maxl(2),maxl(3)), & Cloud_state%SI_out(maxl(1),maxl(2),maxl(3)) - write(otun, *) ," T ", & + write(otun, *) " T ", & Atmos_state%T_in(maxl(1),maxl(2),maxl(3)), & Cloud_state%SI_out(maxl(1),maxl(2),maxl(3)) END IF IF ( MAXVAL(Cloud_state%ql_in + Cloud_state%SL_out) .GT. 1.e-2 ) & - write(otun, *) ," MMMMMLL" + write(otun, *) " MMMMMLL" IF ( MINVAL(Cloud_state%qni_in+Cloud_state%SNi_out) .LT. -1.e-5) & - write(otun, *) ," MMMMMN2" - IF ( MAXVAL(ST_out) .GT. 7. ) write(otun, *) ," MMMMMT1 " - IF ( MINVAL(ST_out) .LT. - 7. ) write(otun, *) ," MMMMMT2 " + write(otun, *) " MMMMMN2" + IF ( MAXVAL(ST_out) .GT. 7. ) write(otun, *) " MMMMMT1 " + IF ( MINVAL(ST_out) .LT. - 7. ) write(otun, *) " MMMMMT2 " IF ( MAXVAL(Atmos_state%T_in+ST_out) .GT. 330. ) & - write(otun, *) ," MMMMMT3 " + write(otun, *) " MMMMMT3 " IF ( MINVAL(Atmos_state%T_in+ST_out) .LT. 170. ) & - write(otun, *) ," MMMMMT4 " + write(otun, *) " MMMMMT4 " IF ( MINVAL(Precip_state%rain3d) .LT. 0. ) & - write(otun, *) ," MMMMMR1 " + write(otun, *) " MMMMMR1 " IF ( MINVAL(Precip_state%snow3d) .LT. 0. ) & - write(otun, *) ," MMMMMS1 " + write(otun, *) " MMMMMS1 " IF ( MINVAL(Precip_state%surfrain) .LT. 0. ) & - write(otun, *) ," MMMMMX1 " + write(otun, *) " MMMMMX1 " IF ( MINVAL(Precip_state%surfsnow) .LT. 0. ) & - write(otun, *) ," MMMMMX2 " + write(otun, *) " MMMMMX2 " !------------------------------------------------------------------------- @@ -2242,7 +2647,7 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & elsewhere Cloud_state%qa_upd = Cloud_state%qa_in end where - if (diag_id%qadt_fill > 0 ) then + if (diag_id%qadt_fill + diag_id%qa_fill_col > 0 ) then where (Cloud_state%qa_in .le. Nml%qmin) diag_4d(:,:,:,diag_pt%qadt_fill) = -Cloud_state%qa_in* & Constants% inv_dtcloud @@ -2257,9 +2662,9 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & ! to this requirenment, !------------------------------------------------------------------------ Atmos_state%U01 = min(Atmos_state%U01, 1.) - if (diag_id%qadt_rhred >0) then + if (diag_id%qadt_rhred + diag_id%qa_rhred_col >0) then where (Cloud_state%qa_upd .gt. Atmos_state%U01) - diag_4d(:,:,:,diag_pt%qadt_rhred) = (Cloud_state%qa_upd - & + diag_4d(:,:,:,diag_pt%qadt_rhred) = -(Cloud_state%qa_upd - & Atmos_state%U01)*Constants%inv_dtcloud endwhere end if @@ -2288,9 +2693,14 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & ql_too_small = (Cloud_state%ql_in .le. Nml%qmin .or. & Cloud_state%qa_in .le. Nml%qmin) endif - qi_too_small = (Cloud_state%qi_in .le. Nml%qmin .or. & - Cloud_state%qa_in .le. Nml%qmin ) -!!RSH should qi_too_small include qni .le. qmin when ice particles pred??? + if (Constants%do_predicted_ice_number) then + qi_too_small = (Cloud_state%qi_in .le. Nml%qmin .or. & + Cloud_state%qa_in .le. Nml%qmin .or. & + Cloud_state%qni_in .le. Nml%qmin) + else + qi_too_small = (Cloud_state%qi_in .le. Nml%qmin .or. & + Cloud_state%qa_in .le. Nml%qmin) + endif else if ( Nml%do_liq_num) then ql_too_small = (Cloud_state%ql_in .le. Nml%qmin .or. & @@ -2298,8 +2708,12 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & else ql_too_small = (Cloud_state%ql_in .le. Nml%qmin) endif - qi_too_small = (Cloud_state%qi_in .le. Nml%qmin ) -!!RSH should qi_too_small include qni .le. qmin when ice particles pred??? + if (Constants%do_predicted_ice_number) then + qi_too_small = (Cloud_state%qi_in .le. Nml%qmin .or. & + Cloud_state%qni_in .le. Nml%qmin) + else + qi_too_small = (Cloud_state%qi_in .le. Nml%qmin ) + endif endif !------------------------------------------------------------------------ @@ -2330,6 +2744,12 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & -1.*Cloud_state%ql_in*Constants%inv_dtcloud endwhere end if + if ( diag_id%qdt_liquid_init > 0 ) then + where (ql_too_small ) + diag_4d(:,:,:,diag_pt%qdt_liquid_init) = & + Cloud_state%ql_in*Constants%inv_dtcloud + endwhere + end if !------------------------------------------------------------------------ ! adjust cloud droplet numbers as needed when those fields @@ -2354,21 +2774,22 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & end do end do end do - if (diag_id%debug1_3d > 0) then + if (diag_id%cf_liq_init > 0) then do k = 1,kdim do j=1,jdim do i = 1,idim if (ql_too_small(i,j,k)) then - diag_4d(i,j,k,diag_pt%debug1_3d) = 0. + diag_4d(i,j,k,diag_pt%cf_liq_init ) = 0. else - diag_4d(i,j,k,diag_pt%debug1_3d) = & + diag_4d(i,j,k,diag_pt%cf_liq_init ) = & min(Cloud_state%qa_in(i,j,k),1.) endif end do end do end do endif - if ( diag_id%qndt_fill + diag_id%qn_fill_col > 0 ) then + if ( diag_id%qndt_fill + diag_id%qn_fill_col + & + diag_id%qldt_fill + diag_id%ql_fill_col > 0 ) then where (ql_too_small ) diag_4d(:,:,:,diag_pt%qndt_fill) = & -1.*Cloud_state%qn_in*Constants%inv_dtcloud @@ -2399,13 +2820,27 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & end do end do end do - if (diag_id%qidt_fill > 0.) then + if (diag_id%qidt_fill + diag_id%qi_fill_col > 0 ) then where (qi_too_small ) diag_4d(:,:,:,diag_pt%qidt_fill) = & -1.*Cloud_state%qi_in *Constants%inv_dtcloud endwhere end if - if (Constants%do_mg_microphys) then + if (diag_id%qdt_ice_init > 0 ) then + where (qi_too_small ) + diag_4d(:,:,:,diag_pt%qdt_ice_init) = & + Cloud_state%qi_in *Constants%inv_dtcloud + endwhere + end if + if (diag_id%cf_ice_init > 0) then + where (qi_too_small) + diag_4d(:,:,:,diag_pt%cf_ice_init) = 0. + elsewhere + diag_4d(:,:,:,diag_pt%cf_ice_init) = Cloud_state%qa_in + end where + endif + if (Constants%do_mg_microphys .or. & + Constants%do_mg_ncar_microphys) then if (Nml%debugo) then write(otun, *) " SNi 00 ", & Cloud_state%SNi_out(Nml%isamp,Nml%jsamp,NMl%ksamp)* & @@ -2420,15 +2855,7 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & N3Di = Cloud_state%qni_in*Atmos_state%airdens*1.e-6 end where - if (diag_id%debug5_3d > 0) then - where (qi_too_small) - diag_4d(:,:,:,diag_pt%debug5_3d) = 0. - elsewhere - diag_4d(:,:,:,diag_pt%debug5_3d) = Cloud_state%qa_in - end where - endif - - if (diag_id%qnidt_fill > 0 ) then + if (diag_id%qnidt_fill + diag_id%qni_fill_col > 0 ) then where (qi_too_small) diag_4d(:,:,:,diag_pt%qnidt_fill) = & -1.*Cloud_state%qni_in *Constants%inv_dtcloud @@ -2450,7 +2877,8 @@ subroutine impose_realizability (idim, jdim, kdim, Atmos_state, & ! save the cloud area tendency and updated area values at this point ! for later use in the m-g microphysics. !------------------------------------------------------------------------ - if (Constants%do_mg_microphys) then + if (Constants%do_mg_microphys .or. & + Constants%do_mg_ncar_microphys) then Cloud_state%qa_upd_0 = Cloud_state%qa_upd Cloud_state%SA_0 = Cloud_State%SA_out endif @@ -2691,7 +3119,7 @@ subroutine strat_alloc (idim, jdim, kdim, pfull, phalf, zhalf, & allocate (Cloud_processes%dcond_ls (idim, jdim, kdim) ) allocate (Cloud_processes%dcond_ls_ice (idim, jdim, kdim) ) allocate (Cloud_processes%dcond_ls_tot (idim, jdim, kdim) ) - allocate (Cloud_processes%tmp5 (idim, jdim, kdim) ) + allocate (Cloud_processes%delta_cf (idim, jdim, kdim) ) allocate (Cloud_processes%f_snow_berg (idim, jdim, kdim) ) Cloud_processes%da_ls = 0. @@ -2700,7 +3128,7 @@ subroutine strat_alloc (idim, jdim, kdim, pfull, phalf, zhalf, & Cloud_processes%dcond_ls = 0. Cloud_processes%dcond_ls_ice = 0. Cloud_processes%dcond_ls_tot = 0. - Cloud_processes%tmp5 = 0. + Cloud_processes%delta_cf = 0. Cloud_processes%f_snow_berg = 0. !-------------------------------------------------------------------------- @@ -2820,7 +3248,7 @@ subroutine strat_dealloc (Atmos_state, Particles, Cloud_State, & deallocate (Cloud_processes%dcond_ls ) deallocate (Cloud_processes%dcond_ls_ice) deallocate (Cloud_processes%dcond_ls_tot) - deallocate (Cloud_processes%tmp5 ) + deallocate (Cloud_processes%delta_cf ) deallocate (Cloud_processes%f_snow_berg ) !------------------------------------------------------------------------- diff --git a/src/atmos_param/strat_cloud/strat_cloud_legacy.F90 b/src/atmos_param/strat_cloud/strat_cloud_legacy.F90 index 967c24ac47..965b72c809 100644 --- a/src/atmos_param/strat_cloud/strat_cloud_legacy.F90 +++ b/src/atmos_param/strat_cloud/strat_cloud_legacy.F90 @@ -283,7 +283,7 @@ module strat_cloud_legacy_mod logical :: do_netcdf_restart, u00_profile, use_kk_auto, & use_online_aerosol, use_sub_seasalt, eros_choice, & - super_choice, tracer_advec, do_old_snowmelt, do_pdf_clouds, & + super_choice, tracer_advec, do_old_snowmelt, retain_cm3_bug, do_pdf_clouds, & do_liq_num, do_dust_berg, pdf_org, do_ice_nucl_wpdf, debugo integer :: num_strat_pts, betaP, nsublevels, kmap, kord, & @@ -305,8 +305,8 @@ module strat_cloud_legacy_mod ! DECLARE VERSION NUMBER OF SCHEME ! - Character(len=128) :: Version = '$Id: strat_cloud_legacy.F90,v 19.0 2012/01/06 20:27:21 fms Exp $' - Character(len=128) :: Tagname = '$Name: siena_201207 $' + Character(len=128) :: Version = '$Id: strat_cloud_legacy.F90,v 20.0 2013/12/13 23:22:13 fms Exp $' + Character(len=128) :: Tagname = '$Name: tikal $' logical :: module_is_initialized = .false. integer, dimension(1) :: restart_versions = (/ 1 /) integer :: vers @@ -967,7 +967,7 @@ subroutine strat_cloud_legacy( Nml, & concen_dust_sub real, dimension(size(T,1),size(T,2)) :: Vfall,iwc,lamda_f real, dimension(size(T,1),size(T,2)) :: U_clr - real, dimension(size(T,1),size(T,2)) :: tmp1,tmp2,tmp3,tmp5,drop1,crystal + real, dimension(size(T,1),size(T,2)) :: tmp1,tmp2,tmp3,tmp5, delta_cf,drop1,crystal real, dimension(size(T,1),size(T,2)) :: sum_freeze, sum_rime, & sum_berg real, dimension(size(T,1),size(T,2)) :: qtbar,deltaQ @@ -1021,6 +1021,7 @@ subroutine strat_cloud_legacy( Nml, & vfact = Nml%vfact cfact = Nml%cfact do_old_snowmelt = Nml%do_old_snowmelt + retain_cm3_bug = Nml%retain_cm3_bug do_pdf_clouds = Nml%do_pdf_clouds betaP = Nml%betaP iwc_crit = Nml%iwc_crit @@ -1270,7 +1271,7 @@ subroutine strat_cloud_legacy( Nml, & !a N3D = qn*airdens*1.e-6 diag_4d(:,:,:,diag_pt%droplets) = qn(:,:,:)*airdens(:,:,:)*1.e-6 ! if (diag_id%debug1_3d > 0) debug1 = min(qa,1.) - if (diag_id%debug1_3d > 0) diag_4d(:,:,:,diag_pt%debug1_3d) = min(qa,1.) + if (diag_id%cf_liq_init > 0) diag_4d(:,:,:,diag_pt%cf_liq_init ) = min(qa,1.) do j=1,kdim do k=1,jdim do i=1,idim @@ -1280,9 +1281,11 @@ subroutine strat_cloud_legacy( Nml, & ! if (max(diag_id%qldt_fill,diag_id%ql_fill_col) > 0) qldt_fill(i,k,j) = -ql(i,k,j) * inv_dtcloud if (max(diag_id%qldt_fill,diag_id%ql_fill_col) > 0) diag_4d(i,k,j,diag_pt%qldt_fill) = -ql(i,k,j) * inv_dtcloud ! if (max(diag_id%qndt_fill,diag_id%qn_fill_col) > 0) qndt_fill(i,k,j) = -qn(i,k,j) * inv_dtcloud - if (max(diag_id%qndt_fill,diag_id%qn_fill_col) > 0) diag_4d(i,k,j,diag_pt%qndt_fill) = -qn(i,k,j) * inv_dtcloud + if (max(diag_id%qndt_fill,diag_id%qn_fill_col, & + diag_id%qldt_fill,diag_id%ql_fill_col) > 0) & + diag_4d(i,k,j,diag_pt%qndt_fill) = -qn(i,k,j) * inv_dtcloud ! if (diag_id%debug1_3d > 0) debug1(i,k,j) = 0. - if (diag_id%debug1_3d > 0) diag_4d(i,k,j,diag_pt%debug1_3d) = 0. + if (diag_id%cf_liq_init > 0) diag_4d(i,k,j,diag_pt%cf_liq_init ) = 0. endif enddo enddo @@ -1311,7 +1314,7 @@ subroutine strat_cloud_legacy( Nml, & !a N3D = qn*airdens*1.e-6 diag_4d(:,:,:,diag_pt%droplets) = qn(:,:,:)*airdens(:,:,:)*1.e-6 ! if (diag_id%debug1_3d > 0) debug1 = min(qa,1.) - if (diag_id%debug1_3d > 0) diag_4d(:,:,:,diag_pt%debug1_3d) = min(qa,1.) + if (diag_id%cf_liq_init > 0) diag_4d(:,:,:,diag_pt%cf_liq_init ) = min(qa,1.) do j=1,kdim do k=1,jdim do i=1,idim @@ -1322,11 +1325,12 @@ subroutine strat_cloud_legacy( Nml, & if (max(diag_id%qldt_fill,diag_id%ql_fill_col) > 0) diag_4d(i,k,j,diag_pt%qldt_fill) = -ql(i,k,j) * inv_dtcloud ! Should this just be diag_id%qndt_fill + diag_id%qn_fill_col ? !ORIGINAL: if (diag_id%qldt_fill > 0) & - if (max(diag_id%qldt_fill,diag_id%qndt_fill,diag_id%qndt_fill) > 0) & + if (max(diag_id%qndt_fill,diag_id%qn_fill_col, & + diag_id%qldt_fill,diag_id%ql_fill_col) > 0) & ! qndt_fill(i,k,j) = -qn(i,k,j) * inv_dtcloud diag_4d(i,k,j,diag_pt%qndt_fill) = -qn(i,k,j) * inv_dtcloud ! if (diag_id%debug1_3d > 0) debug1(i,k,j) = 0. - if (diag_id%debug1_3d > 0) diag_4d(i,k,j,diag_pt%debug1_3d) = 0. + if (diag_id%cf_liq_init > 0) diag_4d(i,k,j,diag_pt%cf_liq_init ) = 0. endif enddo enddo @@ -1773,7 +1777,7 @@ subroutine strat_cloud_legacy( Nml, & if (max(diag_id%qadt_lsform,diag_id%qa_lsform_col) > 0) diag_4d(i,k,j,diag_pt%qadt_lsform) = C_dts * (1.-qcbars) * inv_dtcloud ! if (max(diag_id%qadt_eros,diag_id%qa_eros_col) > 0) qadt_eros (i,k,j) = D_dts * qcbars * inv_dtcloud if (max(diag_id%qadt_eros,diag_id%qa_eros_col) > 0) diag_4d(i,k,j,diag_pt%qadt_eros) = D_dts * qcbars * inv_dtcloud - tmp5(i,k) = C_dts * (1.-qcbars) + delta_cf(i,k) = C_dts * (1.-qcbars) ! The next step is to calculate the change in condensate ! due to non-convective condensation, dcond_ls. Note that this is @@ -1970,9 +1974,9 @@ subroutine strat_cloud_legacy( Nml, & ! if (max(diag_id%qadt_lsdiss,diag_id%qa_lsdiss_col) > 0) qadt_lsdiss(:,:,j) = max(qa(:,:,j)-qag,0.) * inv_dtcloud if (max(diag_id%qadt_lsdiss,diag_id%qa_lsdiss_col) > 0) diag_4d(:,:,j,diag_pt%qadt_lsdiss) = max(qa(:,:,j)-qag,0.) * inv_dtcloud - !define da_ls and tmp5 needed when do_liq_num = .true. (cjg) + !define da_ls and delta_cf needed when do_liq_num = .true. (cjg) da_ls = max(qag-qa(:,:,j),0.) - tmp5 = max(qag-qa(:,:,j),0.) + delta_cf = max(qag-qa(:,:,j),0.) !compute large-scale condensation / evaporation dcond_ls = qcg - (ql_upd + qi_upd) @@ -2081,22 +2085,21 @@ subroutine strat_cloud_legacy( Nml, & !rab take care of it when writing diags.... !rab debug2(i,k,j) = wp2**0.5 ! if (diag_id%debug2_3d > 0) debug2(i,k,j) = wp2 - if (diag_id%debug2_3d > 0) diag_4d(i,k,j,diag_pt%debug2_3d) = wp2 -! if (diag_id%debug3_3d > 0) debug3(i,k,j) = 1. - if (diag_id%debug3_3d > 0) diag_4d(i,k,j,diag_pt%debug3_3d) = 1. + if (diag_id%subgrid_w_variance > 0 .and. up_strat > 0.0) diag_4d(i,k,j,diag_pt%subgrid_w_variance) = wp2 call aer_ccn_act_wpdf (T(i,k,j), pfull(i,k,j), & up_strat, wp2, & totalmass1(i,k,j,:), drop1(i,k)) ! if (diag_id%debug3_3d > 0) debug3(i,k,j) = drop1(i,k) - if (diag_id%debug3_3d > 0) diag_4d(i,k,j,diag_pt%debug3_3d) = drop1(i,k) + if (diag_id%potential_droplets > 0 .and. up_strat > 0.0) diag_4d(i,k,j,diag_pt%potential_droplets) = drop1(i,k) ! if (diag_id%debug2_3d > 0) debug2(i,k,j) = 1. - if (diag_id%debug2_3d > 0) diag_4d(i,k,j,diag_pt%debug2_3d) = 1. !<--cjg: end of modification - qn_mean(i,k) = qn_upd(i,k) + max(tmp5(i,k),0.)* & + qn_mean(i,k) = qn_upd(i,k) + max(delta_cf(i,k),0.)* & drop1(i,k)*1.e6/airdens(i,k,j) else drop1(i,k) = 0. qn_mean(i,k) = qn_upd(i,k) + if (diag_id%subgrid_w_variance > 0) diag_4d(i,k,j,diag_pt%subgrid_w_variance) = 0.0 + if (diag_id%potential_droplets > 0) diag_4d(i,k,j,diag_pt%potential_droplets) = 0.0 endif end do end do @@ -2631,9 +2634,9 @@ subroutine strat_cloud_legacy( Nml, & ! if (max(diag_id%qldt_auto,diag_id%ql_auto_col) > 0) qldt_auto(:,:,j) = tmp1 if (max(diag_id%qldt_auto,diag_id%ql_auto_col) > 0) diag_4d(:,:,j,diag_pt%qldt_auto) = tmp1 - if ( diag_id%autocv > 0 ) then + if ( diag_id%aauto > 0 ) then ! where ( rad_liq .gt. rthresh ) areaautocv(:,:,j) = qa_mean - where ( rad_liq .gt. rthresh ) diag_4d(:,:,j,diag_pt%autocv) = qa_mean + where ( rad_liq .gt. rthresh ) diag_4d(:,:,j,diag_pt%aauto) = qa_mean end if @@ -2691,7 +2694,7 @@ subroutine strat_cloud_legacy( Nml, & Si0=1+0.0125*(tfreeze-T(i,k,j)) call Jhete_dep(T(i,k,j),Si0,concen_dust_sub(i,k,j),crystal(i,k)) ! if (diag_id%debug4_3d > 0) debug4(i,k,j) = 1. - if (diag_id%debug4_3d > 0) diag_4d(i,k,j,diag_pt%debug4_3d) = 1. + if (diag_id%dust_berg_flag > 0) diag_4d(i,k,j,diag_pt%dust_berg_flag) = 1. endif end do end do @@ -2924,7 +2927,16 @@ subroutine strat_cloud_legacy( Nml, & !initialize tmp2 to hold (-Dterm)/D !rab tmp2 = -Dterm/max(D_dt,Dmin) + + if (Nml%retain_cm3_bug) then + tmp2(i,k) = D_dts*qcbars/max(D_dts,Dmin) + else + if ( D_dts.gt.Dmin ) then tmp2(i,k) = D_dts*qcbars/max(D_dts,Dmin) + else + tmp2(i,k) = 0. + endif + endif !do phase changes from large-scale processes and boundary !layer condensation/evaporation @@ -3012,7 +3024,7 @@ subroutine strat_cloud_legacy( Nml, & do k=1,jdim do i=1,idim !Calculate C_dt - C_dts=max(tmp5(i,k),0.)*drop1(i,k)*1.e6/airdens(i,k,j) + C_dts=max(delta_cf(i,k),0.)*drop1(i,k)*1.e6/airdens(i,k,j) D_dts = num_mass_ratio1*D1_dt(i,k) + (num_mass_ratio2*D2_dt(i,k) + D_eros(i,k)) qc0s = qn_upd(i,k) if (D_dts > Dmin) then @@ -3285,7 +3297,15 @@ subroutine strat_cloud_legacy( Nml, & !initialize tmp2 to hold (-Dterm)/D !rab tmp2 = -Dterm/max(D_dt,Dmin) + if (Nml%retain_cm3_bug) then tmp2s = D_dts*qcbars/max(D_dts,Dmin) + else + if ( D_dts.gt.Dmin ) then + tmp2s = D_dts*qcbars/max(D_dts,Dmin) + else + tmp2s = 0. + endif + endif !do phase changes from large-scale processes ST(i,k,j) = ST(i,k,j) + hls*max(dcond_ls_ice(i,k),0.)/cp_air - & @@ -3533,7 +3553,7 @@ subroutine strat_cloud_legacy( Nml, & endif ! if (max(diag_id%snow_subl,diag_id%snow_subl_col) > 0) snow_subl(i,k,j) = tmp2s/deltpg(i,k) - if (max(diag_id%snow_subl,diag_id%snow_subl_col) > 0) diag_4d(i,k,j,diag_pt%snow_subl) = tmp2s/deltpg(i,k) + if (max(diag_id%qdt_snow_sublim,diag_id%q_snow_sublim_col) > 0) diag_4d(i,k,j,diag_pt%qdt_snow_sublim) = tmp2s/deltpg(i,k) enddo enddo @@ -4000,14 +4020,16 @@ subroutine strat_cloud_legacy( Nml, & endwhere endif + if ( diag_id%droplets_wtd > 0 ) then !a diag_4d(:,:,:, diag_pt%droplets_wtd) = N3D*ql diag_4d(:,:,:, diag_pt%droplets_wtd) = & diag_4d(:,:,:,diag_pt%droplets)*ql(:,:,:) + endif - if ( diag_id%debug2_3d > 0 ) then + if ( diag_id%subgrid_w_variance > 0 ) then ! debug2=debug2**0.5 ! diag_4d(:,:,:,diag_pt%debug2_3d) = debug2 - diag_4d(:,:,:,diag_pt%debug2_3d) = diag_4d(:,:,:,diag_pt%debug2_3d)**0.5 + diag_4d(:,:,:,diag_pt%subgrid_w_variance) = diag_4d(:,:,:,diag_pt%subgrid_w_variance)**0.5 endif @@ -4069,10 +4091,18 @@ subroutine strat_cloud_legacy( Nml, & if (ql(i,j,k) > qmin .and. & qa(i,j,k) > qmin .and. & qn(i,j,k) > qmin ) then + if (qa(i,j,k) > 0.05) then N3D_col(i,j) = N3D_col(i,j) + qn(i,j,k)* & ! airdens(i,j,k)*deltpg(i,j)* & - airdens(i,j,k)*deltpg_3d(i,j,k)* & - 1.e-6/min(qa(i,j,k),1.) +!RSH 12/22/11 fix as per email from yim 11/3/11: +! airdens(i,j,k)*deltpg_3d(i,j,k)* & +! 1.e-6/min(qa(i,j,k),1.) +!RSH 12/22/11 +!NOTE still differs from new strat_cloud code in that is appplied to +! input fields rather than output fields + deltpg_3d(i,j,k)* & + 1.e-4/min(qa(i,j,k),1.) + endif endif end do end do diff --git a/src/atmos_param/strat_cloud/strat_cloud_utilities.F90 b/src/atmos_param/strat_cloud/strat_cloud_utilities.F90 index 43f79742ce..245d7e13cf 100644 --- a/src/atmos_param/strat_cloud/strat_cloud_utilities.F90 +++ b/src/atmos_param/strat_cloud/strat_cloud_utilities.F90 @@ -17,8 +17,8 @@ module strat_cloud_utilities_mod !---------------------------------------------------------------------- !----version number---------------------------------------------------- -Character(len=128) :: Version = '$Id: strat_cloud_utilities.F90,v 19.0 2012/01/06 20:27:23 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: strat_cloud_utilities.F90,v 20.0 2013/12/13 23:22:15 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' logical :: module_is_initialized = .false. @@ -27,62 +27,123 @@ module strat_cloud_utilities_mod TYPE diag_id_type - integer & - qldt_cond, ql_cond_col, qldt_evap, ql_evap_col, & - qldt_eros, ql_eros_col, qldt_berg, ql_berg_col, & - qldt_freez, ql_freez_col, qldt_rime, ql_rime_col, & - qldt_accr, ql_accr_col, qldt_auto, ql_auto_col, & - qldt_fill, ql_fill_col, qldt_destr, ql_destr_col, & - liq_adj, liq_adj_col, ice_adj, ice_adj_col, & - snow_melt, snow_melt_col, snow_subl, snow_subl_col, & - qidt_dep, qi_dep_col, qidt_eros, qi_eros_col, & - qidt_fall, qi_fall_col, qidt_fill, qi_fill_col, & - qidt_subl, qi_subl_col, qidt_melt, qi_melt_col, & - qidt_destr, qi_destr_col, qidt_qvdep, qi_qvdep_col, & - qadt_lsform, qa_lsform_col, & - qadt_lsdiss, qa_lsdiss_col, qadt_eros, qa_eros_col, & - qadt_rhred, qa_rhred_col, qadt_destr, qa_destr_col, & - qadt_fill, qa_fill_col, qadt_super, qa_super_col, & - qndt_evap, qn_evap_col, qndt_fill, qn_fill_col, & - qndt_destr, qn_destr_col, qndt_super, qn_super_col, & - qldt_freez2, ql_freez2_col, qldt_sedi, ql_sedi_col, & - qldt_accrs, ql_accrs_col, qldt_bergs, ql_bergs_col, & - qidt_auto, qi_auto_col, qidt_accr, qi_accr_col, & - qidt_accrs, qi_accrs_col, qndt_cond , qn_cond_col, & - rain_evap, rain_evap_col, debug1_3d, debug2_3d, & - debug3_3d, debug4_3d, debug5_3d, tmp5_3d, & - qndt_freez, qndt_sacws, qndt_sacws_o, & - qndt_eros, qndt_pra, qndt_auto, & - qndt_berg, & - qn_freez_col, qn_sacws_col, qn_sacws_o_col, & - qn_eros_col, qn_pra_col, qn_auto_col, & - qndt_nucclim, qndt_sedi, qndt_melt, qndt_ihom, & - qndt_size_adj, qndt_fill2, & - qn_nucclim_col, qn_sedi_col, qn_melt_col, qn_ihom_col, & - qn_size_adj_col, qn_fill2_col, & - qn_berg_col, & - rhcrit, rhcrit_min, ni_dust, ni_sulf, ni_bc, & - rhiin, rhlin, cfin, imass7, & - ndust1, ndust2, ndust3, ndust4, ndust5, & - qnidt_fill, qnidt_nnuccd, qnidt_nsubi, & - qnidt_nerosi, qnidt_nprci, qnidt_nprai, & - qnidt_nucclim1, qnidt_nucclim2, qnidt_sedi, & - qnidt_melt, qnidt_size_adj, qnidt_fill2, & - qnidt_super, qnidt_ihom, qnidt_destr, & - qnidt_cleanup - - integer :: nice, nice_col, gb_nice_col, qrout, qsout - integer :: rain3d, snow3d - integer :: droplets_s, droplets_col_s, droplets_col250, & - gb_droplets_col, sulfate, seasalt_sub, seasalt_sup, om - integer :: aliq, aice, aall, autocv, vfall - integer :: rain_clr, rain_cld, a_rain_clr, a_rain_cld - integer :: snow_clr, snow_cld, a_snow_clr, a_snow_cld - integer :: a_precip_cld, a_precip_clr - integer :: areaall, arealiq, dcond, areaice, & - rvolume, areaautocv, vfalldiag - integer :: droplets, droplets_wtd, ql_wt, droplets_col, & - lsf_strat, lcf_strat, mfls_strat +! cloud area variables + + integer :: aall, aliq, aice, cf_liq_init, cf_ice_init, aauto + integer :: SA3d, qadt_lsform, qadt_lsdiss, qadt_rhred, qadt_eros, & + qadt_fill, qadt_super, qadt_destr, qadt_limits, qadt_ahuco, & + SA_imb + integer :: SA2d, qa_lsform_col, qa_lsdiss_col, qa_rhred_col, & + qa_eros_col, qa_fill_col, qa_super_col, qa_destr_col, & + qa_limits_col, qa_ahuco_col, SA_imb_col + +! cloud liquid variables + + integer :: SL3d, qldt_cond, qldt_evap, qldt_eros, qldt_berg, qldt_freez,& + liq_adj, qldt_rime, qldt_accr, qldt_auto, qldt_fill, & + qldt_destr, qldt_freez2, qldt_sedi, qldt_accrs, qldt_bergs, & + qldt_HM_splinter, SL_imb + integer :: SL2d, ql_cond_col, ql_evap_col, ql_eros_col, ql_berg_col, & + ql_freez_col, liq_adj_col, ql_rime_col, ql_accr_col, & + ql_auto_col, ql_fill_col, ql_destr_col, ql_freez2_col, & + ql_sedi_col, ql_accrs_col, ql_bergs_col, ql_HM_splinter_col, & + SL_imb_col + +! cloud ice variables + + integer :: SI3d, qidt_dep, qidt_subl, qidt_fall, qidt_eros, qidt_melt, & + qidt_melt2, qidt_fill, qidt_destr, qidt_qvdep, qidt_auto, & + qidt_accr, qidt_accrs, ice_adj, SI_imb + integer :: SI2d, qi_dep_col, qi_subl_col, qi_fall_col, qi_eros_col, & + qi_melt_col, qi_melt2_col, qi_fill_col, qi_destr_col, & + qi_qvdep_col, qi_auto_col, qi_accr_col, qi_accrs_col, & + ice_adj_col, SI_imb_col + +! cloud droplet variables + + integer :: droplets_col250, gb_droplets_col, potential_droplets, & + droplets, droplets_wtd, ql_wt, droplets_col, rvolume + integer :: SN3d, qndt_cond , qndt_evap, qndt_fill, qndt_berg, & + qndt_destr, qndt_super, qndt_freez, qndt_sacws, qndt_sacws_o, & + qndt_eros, qndt_pra, qndt_auto, qndt_nucclim, qndt_sedi, & + qndt_melt, qndt_ihom, qndt_size_adj, qndt_fill2, & + qndt_contact_frz, qndt_cleanup, qndt_cleanup2, SN_imb + integer :: SN2d, qn_cond_col, qn_evap_col, qn_fill_col, qn_berg_col, & + qn_destr_col, qn_super_col, qn_freez_col, qn_sacws_col, & + qn_sacws_o_col, qn_eros_col, qn_pra_col, qn_auto_col, & + qn_nucclim_col, qn_sedi_col, qn_melt_col, qn_ihom_col, & + qn_size_adj_col, qn_fill2_col, qn_contact_frz_col, & + qn_cleanup_col, qn_cleanup2_col, SN_imb_col + +! cloud ice particle variables + + integer :: nice, nice_col, gb_nice_col, potential_crystals + integer :: SNi3d, qnidt_fill, qnidt_nnuccd, qnidt_nsubi, & + qnidt_nerosi, qnidt_nprci, qnidt_nprai, & + qnidt_nucclim1, qnidt_nucclim2, qnidt_sedi, & + qnidt_melt, qnidt_size_adj, qnidt_fill2, & + qnidt_super, qnidt_ihom, qnidt_destr, & + qnidt_cleanup, qnidt_cleanup2, qnidt_nsacwi, SNi_imb + integer :: SNi2d, qni_fill_col, qni_nnuccd_col, qni_nsubi_col, & + qni_nerosi_col, qni_nprci_col, qni_nprai_col, & + qni_nucclim1_col, qni_nucclim2_col, qni_sedi_col, & + qni_melt_col, qni_size_adj_col, qni_fill2_col, & + qni_super_col, qni_ihom_col, qni_destr_col, & + qni_cleanup_col, qni_cleanup2_col, & + qni_nsacwi_col, SNi_imb_col + +! aerosol diagnostics + + integer :: delta_cf, sulfate, seasalt_sub, seasalt_sup, om, & + rhcrit, rhcrit_min, rhiin, rhlin, cfin, imass7, & + ni_dust, ni_sulf, ni_bc, ndust1, ndust2, ndust3, & + ndust4, ndust5, dust_berg_flag, subgrid_w_variance + +! rain diagnostics + + integer :: rain3d, qrout, rain_clr, rain_cld, a_rain_clr, a_rain_cld, & + rain_evap, rain_freeze, srfrain_accrs, srfrain_freez, & + srfrain_evap, rain_evap_col, rain_freeze_col, & + srfrain_accrs_col, srfrain_freez_col, srfrain_evap_col, & + rain_mass_conv, rain_imb, rain_imb_col, cld_liq_imb, & + cld_liq_imb_col, neg_rain, qrout_col + +! snow diagnostics + + integer :: snow3d, qsout, snow_clr, snow_cld, a_snow_clr, a_snow_cld, & + snow_melt, snow_melt_col, snow_mass_conv, sedi_ice, snow_imb, & + snow_imb_col, cld_ice_imb, cld_ice_imb_col, neg_snow, qsout_col + + +! total precip diagnostics + + integer :: a_precip_cld, a_precip_clr, sedi_sfc + +! temperature diagnostics + + integer :: ST3d, ST_imb + integer :: ST2d, ST_imb_col + +! vapor diagnostics + + integer :: SQ3d, qdt_liquid_init, qdt_ice_init, qdt_rain_evap, & + qdt_cond, qdt_deposition, qdt_eros_l, qdt_eros_i, & + qdt_qv_on_qi, qdt_sedi_ice2vapor, qdt_sedi_liquid2vapor, & + qdt_super_sat_rm, qdt_destr, qdt_cleanup_liquid, & + qdt_cleanup_ice, qdt_snow_sublim, qdt_snow2vapor, SQ_imb + integer :: SQ2d, q_liquid_init_col, q_ice_init_col, q_rain_evap_col, & + q_cond_col, q_deposition_col, q_eros_l_col, q_eros_i_col, & + q_qv_on_qi_col, q_sedi_ice2vapor_col, q_sedi_liquid2vapor_col,& + q_super_sat_rm_col, q_destr_col, q_cleanup_liquid_col, & + q_cleanup_ice_col, q_snow_sublim_col, q_snow2vapor_col, & + SQ_imb_col + +! miscellaneous diagnostics + + integer :: f_snow_berg, f_snow_berg_col, & + lsf_strat, lcf_strat, mfls_strat, & + dcond, vfall + END TYPE diag_id_type @@ -91,43 +152,86 @@ module strat_cloud_utilities_mod TYPE diag_pt_type - integer :: & - qldt_cond, qldt_evap, qldt_berg, qldt_freez, & - qldt_rime, qldt_accr, qldt_auto, qldt_fill, & - qldt_destr, qldt_eros, liq_adj, rain_evap, & - qidt_dep, qidt_subl, qidt_fill, qidt_melt, & - qidt_fall, qidt_destr, qidt_qvdep, qidt_eros, & - ice_adj, snow_subl, snow_melt, qadt_lsform, & - qadt_eros, qadt_rhred, qadt_destr, qadt_fill, & - qadt_lsdiss, qadt_super, qndt_cond, qndt_evap, & - qndt_fill, qndt_destr, qndt_super, & - debug1_3d, debug2_3d, debug3_3d, debug4_3d, & - debug5_3d, tmp5_3d, qldt_freez2, qldt_sedi, & - qldt_accrs, qldt_bergs, qidt_auto, qidt_accr, & - qidt_accrs, qndt_freez, qndt_sacws, & - qndt_sacws_o, qndt_eros, qndt_pra, qndt_auto, & - qndt_nucclim, qndt_sedi, qndt_melt, qndt_ihom, & - qndt_size_adj, qndt_fill2, rhcrit, rhcrit_min, & - ni_dust, ni_sulf, ni_bc, rhiin, rhlin, cfin, & - imass7, ndust1, ndust2, ndust3, ndust4, ndust5, & - qnidt_fill, qnidt_nnuccd, qnidt_nsubi, & - qnidt_nerosi, qnidt_nprci, qnidt_nprai, & - qnidt_nucclim1, qnidt_nucclim2, qnidt_sedi, & - qnidt_melt, qnidt_size_adj, qnidt_fill2, & - qnidt_super, qnidt_ihom, qnidt_destr, & - qnidt_cleanup, qndt_berg - integer :: areaall, arealiq, dcond, areaice, & - rvolume, areaautocv, vfalldiag - integer :: droplets, droplets_wtd, ql_wt, droplets_col, & - lsf_strat, lcf_strat, mfls_strat - integer :: droplets_s, droplets_col_s, droplets_col250, & - gb_droplets_col - integer :: nice, qrout, qsout, nice_col, gb_nice_col, & - rain3d, snow3d, sulfate, seasalt_sub, & - seasalt_sup, om, aall, aliq, aice, autocv, & - vfall, rain_clr, rain_cld, a_rain_clr, & - a_rain_cld, a_precip_clr, a_precip_cld, & - snow_clr, snow_cld, a_snow_cld, a_snow_clr +! cloud area variables + + integer :: aall, aliq, aice, cf_liq_init, cf_ice_init, aauto + integer :: SA3d, qadt_lsform, qadt_lsdiss, qadt_rhred, qadt_eros, & + qadt_fill, qadt_super, qadt_destr, qadt_limits, qadt_ahuco, & + SA_imb + +! cloud liquid variables + + integer :: SL3d, qldt_cond, qldt_evap, qldt_eros, qldt_berg, qldt_freez,& + liq_adj, qldt_rime, qldt_accr, qldt_auto, qldt_fill, & + qldt_destr, qldt_freez2, qldt_sedi, qldt_accrs, qldt_bergs, & + qldt_HM_splinter, SL_imb + +! cloud ice variables + + integer :: SI3d, qidt_dep, qidt_subl, qidt_fall, qidt_eros, qidt_melt, & + qidt_melt2, qidt_fill, qidt_destr, qidt_qvdep, qidt_auto, & + qidt_accr, qidt_accrs, ice_adj, SI_imb + +! cloud droplet variables + + integer :: droplets_col250, gb_droplets_col, potential_droplets, & + droplets, droplets_wtd, ql_wt, droplets_col, rvolume + integer :: SN3d, qndt_cond , qndt_evap, qndt_fill, qndt_berg, & + qndt_destr, qndt_super, qndt_freez, qndt_sacws, qndt_sacws_o, & + qndt_eros, qndt_pra, qndt_auto, qndt_nucclim, qndt_sedi, & + qndt_melt, qndt_ihom, qndt_size_adj, qndt_fill2, & + qndt_contact_frz, qndt_cleanup, qndt_cleanup2, SN_imb + +! cloud ice particle variables + + integer :: nice, nice_col, gb_nice_col, potential_crystals + integer :: SNi3d, qnidt_fill, qnidt_nnuccd, qnidt_nsubi, & + qnidt_nerosi, qnidt_nprci, qnidt_nprai, & + qnidt_nucclim1, qnidt_nucclim2, qnidt_sedi, & + qnidt_melt, qnidt_size_adj, qnidt_fill2, & + qnidt_super, qnidt_ihom, qnidt_destr, & + qnidt_cleanup, qnidt_cleanup2, qnidt_nsacwi, SNi_imb + +! aerosol diagnostics + + integer :: delta_cf, sulfate, seasalt_sub, seasalt_sup, om, & + rhcrit, rhcrit_min, rhiin, rhlin, cfin, imass7, & + ni_dust, ni_sulf, ni_bc, ndust1, ndust2, ndust3, & + ndust4, ndust5, dust_berg_flag, subgrid_w_variance + +! rain diagnostics + + integer :: rain3d, qrout, rain_clr, rain_cld, a_rain_clr, a_rain_cld, & + rain_evap, rain_freeze, srfrain_accrs, srfrain_freez, & + srfrain_evap, rain_mass_conv, rain_imb, cld_liq_imb, neg_rain + +! snow diagnostics + + integer :: snow3d, qsout, snow_clr, snow_cld, a_snow_clr, a_snow_cld, & + snow_melt, snow_mass_conv, sedi_ice, snow_imb, cld_ice_imb, & + neg_snow + +! total precip diagnostics + + integer :: a_precip_cld, a_precip_clr, sedi_sfc + +! temperature diagnostics + + integer :: ST3d, ST_imb + +! vapor diagnostics + + integer :: SQ3d, qdt_liquid_init, qdt_ice_init, qdt_rain_evap, & + qdt_cond, qdt_deposition, qdt_eros_l, qdt_eros_i, & + qdt_qv_on_qi, qdt_sedi_ice2vapor, qdt_sedi_liquid2vapor, & + qdt_super_sat_rm, qdt_destr, qdt_cleanup_liquid, & + qdt_cleanup_ice, qdt_snow_sublim, qdt_snow2vapor, SQ_imb + +! miscellaneous diagnostics + + integer :: f_snow_berg, & + lsf_strat, lcf_strat, mfls_strat, & + dcond, vfall END TYPE diag_pt_type @@ -146,18 +250,21 @@ module strat_cloud_utilities_mod diff_thresh, qmin, Dmin, efact, vfact, cfact, & iwc_crit, vfall_const2, vfall_exp2, & qthalfwidth, N_min, num_mass_ratio1, & - num_mass_ratio2 + num_mass_ratio2, qcvar logical :: do_netcdf_restart, u00_profile, use_kk_auto, & use_online_aerosol, use_sub_seasalt, & eros_choice, super_choice, tracer_advec, & - do_old_snowmelt, do_pdf_clouds, do_liq_num, & - do_dust_berg, pdf_org, do_ice_nucl_wpdf, debugo + do_old_snowmelt, retain_cm3_bug, do_pdf_clouds, do_liq_num, & + do_dust_berg, pdf_org, do_ice_nucl_wpdf, debugo, & + mass_cons, do_hallet_mossop, activate_all_ice_always integer :: num_strat_pts, betaP, nsublevels, kmap, kord, & super_ice_opt, isamp, jsamp, ksamp - character(len=64) :: microphys_scheme + character(len=64) :: microphys_scheme, & + macrophys_scheme, & + aerosol_activation_scheme integer, dimension(:,:), pointer :: strat_pts=>NULL() @@ -328,7 +435,7 @@ module strat_cloud_utilities_mod dcond_ls =>NULL(), & dcond_ls_ice =>NULL(), & dcond_ls_tot =>NULL(), & - tmp5 =>NULL(), & + delta_cf =>NULL(), & f_snow_berg =>NULL() end type cloud_processes_type @@ -345,7 +452,12 @@ module strat_cloud_utilities_mod logical :: limit_conv_cloud_frac, & mask_present, & do_rk_microphys, & - do_mg_microphys + do_mg_microphys, & + do_mg_ncar_microphys, & + tiedtke_macrophysics, & + dqa_activation, & + total_activation, & + do_predicted_ice_number end type strat_constants_type diff --git a/src/atmos_param/strat_cloud/strat_netcdf.F90 b/src/atmos_param/strat_cloud/strat_netcdf.F90 index 79d50f5647..94aea31b59 100644 --- a/src/atmos_param/strat_cloud/strat_netcdf.F90 +++ b/src/atmos_param/strat_cloud/strat_netcdf.F90 @@ -17,8 +17,8 @@ module strat_netcdf_mod !---------------------------------------------------------------------- !----version number---------------------------------------------------- -Character(len=128) :: Version = '$Id: strat_netcdf.F90,v 19.0 2012/01/06 20:27:24 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: strat_netcdf.F90,v 20.0 2013/12/13 23:22:17 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !----------------------------------------------------------------------- !-------------------- diagnostics variables----------------------------- @@ -89,6 +89,7 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & !---local variables------------------------------------------------------ real, dimension (size(diag_4d,1), size(diag_4d,2), kdim+1) :: mask3 + logical, dimension (size(diag_4d,1), size(diag_4d,2), kdim) :: mask4 logical :: used !---------------------------------------------------------------------- @@ -117,9 +118,6 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%droplets_wtd, diag_4d(:,:,:,diag_pt%droplets_wtd),& Time, is, js, 1, mask=diag_4d(:,:,:,diag_pt%droplets) > 0.0) - used = send_data & - (diag_id%droplets_s, diag_4d(:,:,:,diag_pt%droplets_s), & - Time, is, js, 1, rmask=mask3d) used = send_data & (diag_id%rvolume, diag_4d(:,:,:,diag_pt%rvolume), & Time, is, js, 1, rmask=mask3d) @@ -141,35 +139,46 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & (diag_id%dcond, diag_4d(:,:,:,diag_pt%dcond), & Time, is, js, 1, rmask=mask3d ) used = send_data & - (diag_id%autocv, diag_4d(:,:,:,diag_pt%autocv), & + (diag_id%aauto, diag_4d(:,:,:,diag_pt%aauto), & Time, is, js, 1, rmask=mask3d) used = send_data & (diag_id%vfall, diag_4d(:,:,:,diag_pt%vfall), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%tmp5_3d, diag_4d(:,:,:,diag_pt%tmp5_3d), & + (diag_id%delta_cf, diag_4d(:,:,:,diag_pt%delta_cf), & + Time, is, js, 1, rmask=mask3d) + used = send_data & + (diag_id%cf_liq_init , diag_4d(:,:,:,diag_pt%cf_liq_init ), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%debug1_3d, diag_4d(:,:,:,diag_pt%debug1_3d), & + (diag_id%subgrid_w_variance, & + diag_4d(:,:,:,diag_pt%subgrid_w_variance), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%debug2_3d, diag_4d(:,:,:,diag_pt%debug2_3d), & + (diag_id%potential_droplets, & + diag_4d(:,:,:,diag_pt%potential_droplets), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%debug3_3d, diag_4d(:,:,:,diag_pt%debug3_3d), & + (diag_id%potential_crystals, & + diag_4d(:,:,:,diag_pt%potential_crystals), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%debug4_3d, diag_4d(:,:,:,diag_pt%debug4_3d), & + (diag_id%dust_berg_flag, & + diag_4d(:,:,:,diag_pt%dust_berg_flag), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%debug5_3d, diag_4d(:,:,:,diag_pt%debug5_3d), & + (diag_id%cf_ice_init, diag_4d(:,:,:,diag_pt%cf_ice_init), & Time, is, js, 1, rmask=mask3d) used = send_data & - (diag_id%snow_subl, diag_4d(:,:,:,diag_pt%snow_subl), & + (diag_id%qdt_snow_sublim, & + diag_4d(:,:,:,diag_pt%qdt_snow_sublim), & Time, is, js, 1, rmask=mask3d) used = send_data & (diag_id%snow_melt, diag_4d(:,:,:,diag_pt%snow_melt), & Time, is, js, 1, rmask=mask3d) + used = send_data & + (diag_id%rain_freeze, diag_4d(:,:,:,diag_pt%rain_freeze), & + Time, is, js, 1, rmask=mask3d) !----------------------------------------------------------------------- ! 4) variables associated with model convection: @@ -248,9 +257,10 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%aice, diag_4d(:,:,:,diag_pt%aice), & Time, is, js, 1, rmask=mask3d) + mask4 = diag_4d(:,:,:,diag_pt%cfin) .ne. -1.e30 used = send_data & (diag_id%cfin, diag_4d(:,:,:,diag_pt%cfin), & - Time, is, js, 1, rmask=mask3d) + Time, is, js, 1, mask=mask4) !----------------------------------------------------------------------- ! 8) variables associated with cloud liquid time tendency: @@ -414,6 +424,10 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & (diag_id%qnidt_cleanup, & diag_4d(:,:,:,diag_pt%qnidt_cleanup), & Time, is, js, 1, rmask=mask3d) + used = send_data & + (diag_id%qnidt_cleanup2, & + diag_4d(:,:,:,diag_pt%qnidt_cleanup2), & + Time, is, js, 1, rmask=mask3d) !----------------------------------------------------------------------- ! 11) variables associated with relative humidity: @@ -424,12 +438,14 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%rhcrit_min, diag_4d(:,:,:,diag_pt%rhcrit_min), & Time, is, js, 1, rmask=mask3d) + mask4 = diag_4d(:,:,:,diag_pt%rhiin) .ne. -1.e30 used = send_data & - (diag_id%rhiin, diag_4d(:,:,:,diag_pt%rhiin), & - Time, is, js, 1, rmask=mask3d) + (diag_id%rhiin, 100.*diag_4d(:,:,:,diag_pt%rhiin), & + Time, is, js, 1, mask=mask4) + mask4 = diag_4d(:,:,:,diag_pt%rhlin) .ne. -1.e30 used = send_data & - (diag_id%rhlin, diag_4d(:,:,:,diag_pt%rhlin), & - Time, is, js, 1, rmask=mask3d) + (diag_id%rhlin, 100.*diag_4d(:,:,:,diag_pt%rhlin), & + Time, is, js, 1, mask=mask4) !----------------------------------------------------------------------- ! 12) variables associated with aerosol nucleation: @@ -499,6 +515,9 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%qidt_melt, diag_4d(:,:,:,diag_pt%qidt_melt), & Time, is, js, 1, rmask=mask3d) + used = send_data & + (diag_id%qidt_melt2, diag_4d(:,:,:,diag_pt%qidt_melt2), & + Time, is, js, 1, rmask=mask3d) used = send_data & (diag_id%ice_adj, diag_4d(:,:,:,diag_pt%ice_adj), & Time, is, js, 1, rmask=mask3d) @@ -545,6 +564,143 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%qadt_destr, diag_4d(:,:,:,diag_pt%qadt_destr), & Time, is, js, 1, rmask=mask3d) + used = send_data & + (diag_id%qadt_limits, diag_4d(:,:,:,diag_pt%qadt_limits), & + Time, is, js, 1, rmask=mask3d) + used = send_data & + (diag_id%qadt_ahuco, diag_4d(:,:,:,diag_pt%qadt_ahuco), & + Time, is, js, 1, rmask=mask3d) + +!------------------------------------------------------------------------ +! 16) variables added by h1g with ncar M-G microphysics +!------------------------------------------------------------------------ + used = send_data ( diag_id%SA3d, diag_4d(:,:,:,diag_pt%SA3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%ST3d, diag_4d(:,:,:,diag_pt%ST3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SQ3d, diag_4d(:,:,:,diag_pt%SQ3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SL3d, diag_4d(:,:,:,diag_pt%SL3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SI3d, diag_4d(:,:,:,diag_pt%SI3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SN3d, diag_4d(:,:,:,diag_pt%SN3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SNI3d, diag_4d(:,:,:,diag_pt%SNI3d), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qndt_contact_frz, & + diag_4d(:,:,:,diag_pt%qndt_contact_frz), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qndt_cleanup, & + diag_4d(:,:,:,diag_pt%qndt_cleanup), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qndt_cleanup2, & + diag_4d(:,:,:,diag_pt%qndt_cleanup2), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qnidt_nsacwi, & + diag_4d(:,:,:,diag_pt%qnidt_nsacwi), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_liquid_init, & + diag_4d(:,:,:,diag_pt%qdt_liquid_init), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_ice_init, & + diag_4d(:,:,:,diag_pt%qdt_ice_init), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_rain_evap, & + diag_4d(:,:,:,diag_pt%qdt_rain_evap), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_snow_sublim, & + diag_4d(:,:,:,diag_pt%qdt_snow_sublim), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_cond, & + diag_4d(:,:,:,diag_pt%qdt_cond), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_deposition, & + diag_4d(:,:,:,diag_pt%qdt_deposition), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_eros_l, & + diag_4d(:,:,:,diag_pt%qdt_eros_l), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_eros_i, & + diag_4d(:,:,:,diag_pt%qdt_eros_i), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_qv_on_qi, & + diag_4d(:,:,:,diag_pt%qdt_qv_on_qi), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_snow2vapor, & + diag_4d(:,:,:,diag_pt%qdt_snow2vapor), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_sedi_ice2vapor, & + diag_4d(:,:,:,diag_pt%qdt_sedi_ice2vapor), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_sedi_liquid2vapor, & + diag_4d(:,:,:,diag_pt%qdt_sedi_liquid2vapor), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_super_sat_rm, & + diag_4d(:,:,:,diag_pt%qdt_super_sat_rm), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_destr, & + diag_4d(:,:,:,diag_pt%qdt_destr), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_cleanup_liquid, & + diag_4d(:,:,:,diag_pt%qdt_cleanup_liquid), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%qdt_cleanup_ice, & + diag_4d(:,:,:,diag_pt%qdt_cleanup_ice), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%srfrain_evap, & + diag_4d(:,:,:,diag_pt%srfrain_evap ), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%srfrain_accrs, & + diag_4d(:,:,:,diag_pt%srfrain_accrs ), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%srfrain_freez, & + diag_4d(:,:,:,diag_pt%srfrain_freez ), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%snow_mass_conv, & + diag_3d(:,:, diag_pt%snow_mass_conv), & + Time, is, js ) + used = send_data ( diag_id%neg_snow, & + diag_3d(:,:, diag_pt%neg_snow), & + Time, is, js ) + used = send_data ( diag_id%rain_mass_conv, & + diag_3d(:,:, diag_pt%rain_mass_conv), & + Time, is, js ) + used = send_data ( diag_id%neg_rain, & + diag_3d(:,:,diag_pt%neg_rain), & + Time, is, js ) + used = send_data ( diag_id%qldt_HM_splinter, & + diag_4d(:,:,:,diag_pt%qldt_HM_splinter), & + Time, is, js, 1, rmask=mask3d ) + +!----------------------------------------------------------------------- +! 17) variables associated with budget verification: +!----------------------------------------------------------------------- + used = send_data ( diag_id%SA_imb, diag_4d(:,:,:,diag_pt%SA_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%ST_imb, diag_4d(:,:,:,diag_pt%ST_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SQ_imb, diag_4d(:,:,:,diag_pt%SQ_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SL_imb, diag_4d(:,:,:,diag_pt%SL_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SI_imb, diag_4d(:,:,:,diag_pt%SI_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SN_imb, diag_4d(:,:,:,diag_pt%SN_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%SNi_imb, diag_4d(:,:,:,diag_pt%SNi_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%rain_imb, diag_4d(:,:,:,diag_pt%rain_imb),& + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%cld_liq_imb, & + diag_4d(:,:,:,diag_pt%cld_liq_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%snow_imb, & + diag_4d(:,:,:,diag_pt%snow_imb), & + Time, is, js, 1, rmask=mask3d ) + used = send_data ( diag_id%cld_ice_imb, & + diag_4d(:,:,:,diag_pt%cld_ice_imb), & + Time, is, js, 1, rmask=mask3d ) !----------------------------------------------------------------------- ! @@ -559,10 +715,6 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%droplets_col, diag_3d(:,:,diag_pt%droplets_col), & Time, is, js) - used = send_data & - (diag_id%droplets_col_s, & - diag_3d(:,:,diag_pt%droplets_col_s), & - Time, is, js) used = send_data & (diag_id%gb_droplets_col, & diag_3d(:,:,diag_pt%gb_droplets_col), & @@ -575,11 +727,22 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & !----------------------------------------------------------------------- ! 3) variables associated with cloud and precipitation processes: !----------------------------------------------------------------------- + used = send_data & + (diag_id%sedi_ice, diag_3d(:,:,diag_pt%sedi_ice), & + Time, is, js) used = send_data & (diag_id%snow_melt_col, diag_3d(:,:, diag_pt%snow_melt), & Time, is, js) used = send_data & - (diag_id%snow_subl_col, diag_3d(:,:, diag_pt%snow_subl), & + (diag_id%rain_freeze_col, diag_3d(:,:, diag_pt%rain_freeze), & + Time, is, js) + used = send_data & + (diag_id%q_snow_sublim_col, & + diag_3d(:,:, diag_pt%qdt_snow_sublim), & + Time, is, js) + + used = send_data & + (diag_id%sedi_sfc, diag_3d(:,:, diag_pt%sedi_sfc), & Time, is, js) !----------------------------------------------------------------------- @@ -592,6 +755,16 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & (diag_id%gb_nice_col, diag_3d(:,:,diag_pt%gb_nice_col), & Time, is, js) +!----------------------------------------------------------------------- +! 6) variables associated with precipitation and precipitation area: +!----------------------------------------------------------------------- + used = send_data & + (diag_id%qrout_col, diag_3d(:,:,diag_pt%qrout), & + Time, is, js) + used = send_data & + (diag_id%qsout_col, diag_3d(:,:,diag_pt%qsout), & + Time, is, js) + !----------------------------------------------------------------------- ! 8) variables associated with cloud liquid time tendency: !----------------------------------------------------------------------- @@ -677,6 +850,9 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%qn_pra_col, diag_3d(:,:, diag_pt%qndt_pra), & Time, is, js) + used = send_data & + (diag_id%qn_auto_col, diag_3d(:,:, diag_pt%qndt_auto), & + Time, is, js) used = send_data & (diag_id%qn_nucclim_col, diag_3d(:,:,diag_pt%qndt_nucclim), & Time, is, js) @@ -696,6 +872,18 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%qn_fill2_col, diag_3d(:,:, diag_pt%qndt_fill2), & Time, is, js) + used = send_data & + (diag_id%qn_contact_frz_col, & + diag_3d(:,:, diag_pt%qndt_contact_frz), & + Time, is, js) + used = send_data & + (diag_id%qn_cleanup_col, & + diag_3d(:,:, diag_pt%qndt_cleanup), & + Time, is, js) + used = send_data & + (diag_id%qn_cleanup2_col, & + diag_3d(:,:, diag_pt%qndt_cleanup2), & + Time, is, js) !----------------------------------------------------------------------- ! 13) variables associated with water vapor tendency: @@ -731,6 +919,9 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%qi_melt_col, diag_3d(:,:, diag_pt%qidt_melt), & Time, is, js) + used = send_data & + (diag_id%qi_melt2_col, diag_3d(:,:, diag_pt%qidt_melt2), & + Time, is, js) used = send_data & (diag_id%ice_adj_col, diag_3d(:,:, diag_pt%ice_adj), & Time, is, js) @@ -768,6 +959,162 @@ subroutine strat_netcdf (diag_id, diag_pt, diag_4d, diag_4d_kp1, & used = send_data & (diag_id%qa_destr_col, diag_3d (:,:, diag_pt%qadt_destr), & Time, is, js) + used = send_data & + (diag_id%qa_limits_col, diag_3d (:,:, diag_pt%qadt_limits), & + Time, is, js) + used = send_data & + (diag_id%qa_ahuco_col, diag_3d (:,:, diag_pt%qadt_ahuco), & + Time, is, js) + +!------------------------------------------------------------------------ +! 16) variables added by h1g with ncar M-G microphysics +!------------------------------------------------------------------------ + used = send_data ( diag_id%SA2d, diag_3d(:,:,diag_pt%SA3d), & + Time, is, js ) + used = send_data ( diag_id%ST2d, diag_3d(:,:,diag_pt%ST3d), & + Time, is, js ) + used = send_data ( diag_id%SQ2d, diag_3d(:,:,diag_pt%SQ3d), & + Time, is, js ) + used = send_data ( diag_id%SL2d, diag_3d(:,:,diag_pt%SL3d), & + Time, is, js ) + used = send_data ( diag_id%SI2d, diag_3d(:,:,diag_pt%SI3d), & + Time, is, js ) + used = send_data ( diag_id%SN2d, diag_3d(:,:,diag_pt%SN3d), & + Time, is, js ) + used = send_data ( diag_id%SNI2d, diag_3d(:,:,diag_pt%SNI3d), & + Time, is, js ) + used = send_data (diag_id%q_liquid_init_col, & + diag_3d(:,:,diag_pt%qdt_liquid_init), Time, is, js ) + used = send_data (diag_id%q_ice_init_col, & + diag_3d(:,:,diag_pt%qdt_ice_init), Time, is, js ) + used = send_data (diag_id%q_rain_evap_col, & + diag_3d(:,:,diag_pt%qdt_rain_evap), Time, is, js ) + used = send_data (diag_id%q_cond_col, & + diag_3d(:,:,diag_pt%qdt_cond), Time, is, js ) + used = send_data (diag_id%q_deposition_col, & + diag_3d(:,:,diag_pt%qdt_deposition), Time, is, js ) + used = send_data (diag_id%q_eros_l_col, & + diag_3d(:,:,diag_pt%qdt_eros_l), Time, is, js ) + used = send_data (diag_id%q_eros_i_col, & + diag_3d(:,:,diag_pt%qdt_eros_i), Time, is, js ) + used = send_data (diag_id%q_qv_on_qi_col, & + diag_3d(:,:,diag_pt%qdt_qv_on_qi), Time, is, js ) + used = send_data (diag_id%q_sedi_ice2vapor_col, & + diag_3d(:,:,diag_pt%qdt_sedi_ice2vapor), Time, is, js ) + used = send_data (diag_id%q_sedi_liquid2vapor_col, & + diag_3d(:,:,diag_pt%qdt_sedi_liquid2vapor), Time, is, js) + used = send_data (diag_id%q_super_sat_rm_col, & + diag_3d(:,:,diag_pt%qdt_super_sat_rm), Time, is, js ) + used = send_data (diag_id%q_destr_col, & + diag_3d(:,:,diag_pt%qdt_destr), Time, is, js ) + used = send_data (diag_id%q_cleanup_liquid_col, & + diag_3d(:,:,diag_pt%qdt_cleanup_liquid), Time, is, js ) + used = send_data (diag_id%q_cleanup_ice_col, & + diag_3d(:,:,diag_pt%qdt_cleanup_ice), Time, is, js ) + used = send_data (diag_id%q_snow2vapor_col, & + diag_3d(:,:,diag_pt%qdt_snow2vapor), Time, is, js ) + used = send_data (diag_id%srfrain_accrs_col, & + diag_3d(:,:,diag_pt%srfrain_accrs), Time, is, js ) + used = send_data (diag_id%srfrain_freez_col, & + diag_3d(:,:,diag_pt%srfrain_freez), Time, is, js ) + used = send_data (diag_id%srfrain_evap_col, & + diag_3d(:,:,diag_pt%srfrain_evap), Time, is, js ) + used = send_data (diag_id%ql_HM_splinter_col, & + diag_3d(:,:,diag_pt%qldt_HM_splinter), Time, is, js ) + +!----------------------------------------------------------------------- +! 17) variables associated with budget verification: +!----------------------------------------------------------------------- + used = send_data ( diag_id%SA_imb_col, diag_3d(:,:,diag_pt%SA_imb), & + Time, is, js ) + used = send_data ( diag_id%ST_imb_col, diag_3d(:,:,diag_pt%ST_imb), & + Time, is, js ) + used = send_data ( diag_id%SQ_imb_col, diag_3d(:,:,diag_pt%SQ_imb), & + Time, is, js ) + used = send_data ( diag_id%SL_imb_col, diag_3d(:,:,diag_pt%SL_imb), & + Time, is, js ) + used = send_data ( diag_id%SI_imb_col, diag_3d(:,:,diag_pt%SI_imb), & + Time, is, js ) + used = send_data ( diag_id%SN_imb_col, diag_3d(:,:,diag_pt%SN_imb), & + Time, is, js ) + used = send_data ( diag_id%SNi_imb_col, diag_3d(:,:,diag_pt%SNi_imb),& + Time, is, js ) + used = send_data ( diag_id%rain_imb_col, & + diag_3d(:,:,diag_pt%rain_imb),& + Time, is, js ) + used = send_data ( diag_id%cld_liq_imb_col, & + diag_3d(:,:,diag_pt%cld_liq_imb),& + Time, is, js ) + used = send_data ( diag_id%snow_imb_col, & + diag_3d(:,:,diag_pt%snow_imb),& + Time, is, js ) + used = send_data ( diag_id%cld_ice_imb_col, & + diag_3d(:,:,diag_pt%cld_ice_imb),& + Time, is, js ) + +!----------------------------------------------------------------------- +! 17) variables associated with ice particle number time tendency: +!----------------------------------------------------------------------- + used = send_data & + (diag_id%qni_fill_col, diag_3d(:,:,diag_pt%qnidt_fill), & + Time, is, js) + used = send_data & + (diag_id%qni_nnuccd_col, diag_3d(:,:,diag_pt%qnidt_nnuccd), & + Time, is, js) + used = send_data & + (diag_id%qni_nsubi_col, diag_3d(:,:,diag_pt%qnidt_nsubi), & + Time, is, js) + used = send_data & + (diag_id%qni_nerosi_col, diag_3d(:,:,diag_pt%qnidt_nerosi), & + Time, is, js) + used = send_data & + (diag_id%qni_nprci_col, diag_3d(:,:,diag_pt%qnidt_nprci), & + Time, is, js) + used = send_data & + (diag_id%qni_nprai_col, diag_3d(:,:,diag_pt%qnidt_nprai), & + Time, is, js) + used = send_data & + (diag_id%qni_nucclim1_col, & + diag_3d(:,:,diag_pt%qnidt_nucclim1), & + Time, is, js) + used = send_data & + (diag_id%qni_nucclim2_col, & + diag_3d(:,:,diag_pt%qnidt_nucclim2), & + Time, is, js) + used = send_data & + (diag_id%qni_sedi_col, diag_3d(:,:,diag_pt%qnidt_sedi), & + Time, is, js) + used = send_data & + (diag_id%qni_melt_col, diag_3d(:,:,diag_pt%qnidt_melt), & + Time, is, js) + used = send_data & + (diag_id%qni_size_adj_col, & + diag_3d(:,:,diag_pt%qnidt_size_adj), & + Time, is, js) + used = send_data & + (diag_id%qni_fill2_col, diag_3d(:,:,diag_pt%qnidt_fill2), & + Time, is, js) + used = send_data & + (diag_id%qni_super_col, diag_3d(:,:,diag_pt%qnidt_super), & + Time, is, js) + used = send_data & + (diag_id%qni_ihom_col, diag_3d(:,:,diag_pt%qnidt_ihom), & + Time, is, js) + used = send_data & + (diag_id%qni_destr_col, diag_3d(:,:,diag_pt%qnidt_destr), & + Time, is, js) + used = send_data & + (diag_id%qni_cleanup_col, & + diag_3d(:,:,diag_pt%qnidt_cleanup), & + Time, is, js) + used = send_data & + (diag_id%qni_nsacwi_col, & + diag_3d(:,:,diag_pt%qnidt_nsacwi), & + Time, is, js) + used = send_data & + (diag_id%qni_cleanup2_col, & + diag_3d(:,:,diag_pt%qnidt_cleanup2), & + Time, is, js) !------------------------------------------------------------------------ @@ -837,18 +1184,14 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & !------------------------------------------------------------------------ diag_id%droplets = register_diag_field (mod_name, & 'droplets', axes(1:3), Time, & - 'Droplet number concentration', '/m3', & + 'Droplet number concentration', '/cm3', & missing_value=missing_value ) diag_id%droplets_wtd = register_diag_field (mod_name, & 'droplets_wtd', axes(1:3), Time, & 'Droplet number conc*Cld liq', 'kg/(kg*m3)', & mask_variant=.true., missing_value=missing_value) - diag_id%droplets_s = register_diag_field (mod_name, & - 'droplets_s', axes(1:3), Time, & - 'Droplet number conentration aft strat_cloud_new', '/cm3', & - missing_value=missing_value) diag_id%rvolume = register_diag_field (mod_name, & - 'rv', axes(1:3), Time, & + 'rvolume', axes(1:3), Time, & 'Cloud liquid mean volume radius', 'microns', & missing_value=missing_value ) @@ -871,7 +1214,7 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & 'dcond', axes(1:3), Time, & 'condensation/evaporation', 'kg/kg/s', & missing_value=missing_value) - diag_id%autocv = register_diag_field (mod_name, & + diag_id%aauto = register_diag_field (mod_name, & 'aauto', axes(1:3), Time, & 'Cloud fraction where autoconversion is occurring', & 'dimensionless', & @@ -880,38 +1223,45 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & 'vfall', axes(1:3), Time, & 'Ice crystal fall speed', 'meters/second', & missing_value=missing_value) - diag_id%tmp5_3d = register_diag_field (mod_name, & - 'tmp5', axes(1:3), Time, & - 'tmp5', '/m3', & + diag_id%delta_cf = register_diag_field (mod_name, & + 'delta_cf', axes(1:3), Time, & + 'increase in cloud area due to condensation ', & + 'dimensionless', & missing_value=missing_value) - diag_id%debug1_3d = register_diag_field (mod_name, & - 'debug1', axes(1:3), Time, & - 'fractional area in strat cloud', 'none', & + diag_id%cf_liq_init = register_diag_field (mod_name, & + 'cf_liq_init', axes(1:3), Time, & + 'adjusted large-scale liquid cloud area before physics', & + 'dimensionless', & missing_value=missing_value) - diag_id%debug2_3d = register_diag_field (mod_name, & - 'debug2', axes(1:3), Time, & - 'Droplet number concentration', '/m3', & + diag_id%subgrid_w_variance = register_diag_field (mod_name, & + 'subgrid_w_variance', axes(1:3), Time, & + 'standard dev of subgrid vert vel distribution', 'm/s', & missing_value=missing_value) - diag_id%debug3_3d = register_diag_field (mod_name, & - 'debug3', axes(1:3), Time, & - 'Droplet number concentration', '/m3', & + diag_id%potential_droplets = register_diag_field (mod_name, & + 'potential_droplets', axes(1:3), Time, & + 'number of droplets which may be activated', '/cm3', & missing_value=missing_value) - diag_id%debug4_3d = register_diag_field (mod_name, & - 'debug4', axes(1:3), Time, & - 'xxxxx', 'xxxx', & + diag_id%potential_crystals = register_diag_field (mod_name, & + 'potential_crystals', axes(1:3), Time, & + 'number of crystals which may be activated', '/m3', & missing_value=missing_value) - diag_id%debug5_3d = register_diag_field (mod_name, & - 'debug5', axes(1:3), Time, & - 'fractional area in strat cloud ice', 'none', & + diag_id%dust_berg_flag = register_diag_field (mod_name, & + 'dust_berg_flag', axes(1:3), Time, & + 'frequency of active dust_berg process', 'none', & missing_value=missing_value) - diag_id%snow_subl = register_diag_field (mod_name, & - 'snow_subl', axes(1:3), Time, & - 'Water vapor tendency from snow sublimation', 'kg/kg/sec', & + diag_id%cf_ice_init = register_diag_field (mod_name, & + 'cf_ice_init', axes(1:3), Time, & + 'adjusted large-scale ice cloud area before physics', & + 'dimensionless', & missing_value=missing_value) diag_id%snow_melt = register_diag_field (mod_name, & 'snow_melt', axes(1:3), Time, & 'Rain water tendency from snow melting', 'kg/kg/sec', & missing_value=missing_value) + diag_id%rain_freeze = register_diag_field (mod_name, & + 'rain_freeze', axes(1:3), Time, & + 'Rain loss from rain freezing', 'kg/kg/sec', & + missing_value=missing_value) !------------------------------------------------------------------------ ! 4) variables associated with model convection: @@ -929,8 +1279,8 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & ! 5) variables associated with ice particle number: !------------------------------------------------------------------------ diag_id%nice = register_diag_field (mod_name, & - 'nice_s', axes(1:3), Time, & - 'ice number conentration', '/cm3', & + 'nice', axes(1:3), Time, & + 'ice number concentration', '/cm3', & missing_value=missing_value) !------------------------------------------------------------------------ @@ -998,21 +1348,23 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & !------------------------------------------------------------------------ diag_id%aall = register_diag_field (mod_name, & 'aall', axes(1:3), Time, & - 'Cloud fraction for all clouds at midtimestep', & + 'Cloud fraction for all large-scale clouds at midtimestep', & 'dimensionless', & missing_value=missing_value) diag_id%aliq = register_diag_field (mod_name, & 'aliq', axes(1:3), Time, & - 'Cloud fraction for liquid clouds', 'dimensionless',& + 'Cloud fraction for large-scale liquid clouds', & + 'dimensionless',& missing_value=missing_value) diag_id%aice = register_diag_field (mod_name, & 'aice', axes(1:3), Time, & - 'Cloud fraction for ice clouds', 'dimensionless', & + 'Cloud fraction for large-scale ice clouds', & + 'dimensionless', & missing_value=missing_value) diag_id%cfin = register_diag_field (mod_name, & 'cfin', axes(1:3), Time, & - 'cfin', 'none', & - missing_value=missing_value) + 'cloud fraction at T < 268 K', 'dimensionless', & + mask_variant = .true., missing_value=missing_value) !----------------------------------------------------------------------- ! 8) variables associated with cloud liquid time tendency: @@ -1033,24 +1385,24 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & 'kg/kg/sec', missing_value=missing_value) diag_id%qldt_accr = register_diag_field (mod_name, & 'qldt_accr', axes(1:3), Time, & - 'Liquid water specific humidity tendency from accretion', & - 'kg/kg/sec', & - missing_value=missing_value) + 'Liquid water specific humidity tendency from & + &accretion by rain', & + 'kg/kg/sec', missing_value=missing_value) diag_id%qldt_auto = register_diag_field (mod_name, & 'qldt_auto', axes(1:3), Time, & - 'Liq water specific humidity tendency from autoconversion',& - 'kg/kg/sec', & - missing_value=missing_value) + 'Liq water specific humidity tendency from & + &autoconversion to rain',& + 'kg/kg/sec', missing_value=missing_value) diag_id%liq_adj = register_diag_field (mod_name, & 'liq_adj', axes(1:3), Time, & - 'Liquid condensation rate from removal of supersaturation',& - 'kg/kg/sec', & - missing_value=missing_value) + 'Liquid water specific humidity tendency from & + &the removal of supersaturation',& + 'kg/kg/sec', missing_value=missing_value) diag_id%qldt_fill = register_diag_field (mod_name, & 'qldt_fill', axes(1:3), Time, & - 'Liquid water specific humidity tendency from filler', & - 'kg/kg/sec', & - missing_value=missing_value) + 'Liquid water specific humidity tendency -- & + &pre-microphysics filler', & + 'kg/kg/sec', missing_value=missing_value) diag_id%qldt_berg = register_diag_field (mod_name, & 'qldt_berg', axes(1:3), Time, & 'Liq water specific humidity tendency from Bergeron process',& @@ -1081,11 +1433,16 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & 'Liq water spec hum tendency from droplet sedimentation', & 'kg/kg/sec', & missing_value=missing_value) + diag_id%sedi_sfc = register_diag_field (mod_name, & + 'sedi_sfc', axes(1:2), Time, & + 'Liquid sedimentation flux at surface', & + 'm/sec', & + missing_value=missing_value) diag_id%qldt_accrs = register_diag_field (mod_name, & 'qldt_accrs', axes(1:3), Time, & - 'Liq water spec hum tend from collection of drops by snow ', & - 'kg/kg/sec', & - missing_value=missing_value) + 'Liq water spec hum tend from collection of & + &cloud liquid by snow ', & + 'kg/kg/sec', missing_value=missing_value) diag_id%qldt_bergs = register_diag_field (mod_name, & 'qldt_bergs', axes(1:3), Time, & 'Liq water spec hum tendency from bergeron process for snow',& @@ -1097,306 +1454,310 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & !----------------------------------------------------------------------- diag_id%qndt_cond = register_diag_field (mod_name, & 'qndt_cond', axes(1:3), Time, & - 'Cloud droplet tendency from LS condensation', & + 'Cloud droplet number tendency from LS condensation', & '#/kg/sec', & missing_value=missing_value) diag_id%qndt_evap = register_diag_field (mod_name, & 'qndt_evap', axes(1:3), Time, & - 'Cloud droplet tendency from LS evaporation', '#/kg/sec', & + 'Cloud droplet number tendency from LS evaporation', & + '#/kg/sec', & missing_value=missing_value) diag_id%qndt_fill = register_diag_field (mod_name, & 'qndt_fill', axes(1:3), Time, & - 'Cloud droplet tendency from filler', '#/kg/sec', & + 'Cloud droplet number tendency from filler', '#/kg/sec', & missing_value=missing_value) diag_id%qndt_destr = register_diag_field (mod_name, & 'qndt_destr', axes(1:3), Time, & - 'Cloud droplet tendency from cloud destruction', '#/kg/sec', & + 'Cloud droplet number tendency from cloud destruction', & + '#/kg/sec', & missing_value=missing_value) diag_id%qndt_super = register_diag_field (mod_name, & 'qndt_super', axes(1:3), Time, & - 'Cloud droplet tendency from supersaturation formation', & + 'Cloud droplet number tendency from supersaturation removal',& '#/kg/sec', & missing_value=missing_value) diag_id%qndt_berg = register_diag_field (mod_name, & 'qndt_berg', axes(1:3), Time, & - 'Cloud droplet tendency from Bergeron', '#/kg/sec', & + 'Cloud droplet number tendency from Bergeron', '#/kg/sec', & missing_value=missing_value) diag_id%qndt_freez = register_diag_field (mod_name, & 'qndt_freez', axes(1:3), Time, & - 'Cloud droplet tendency from freezing', '#/kg/sec', & + 'Cloud droplet number tendency from heterogeneous freezing', & + '#/kg/sec', & missing_value=missing_value) diag_id%qndt_sacws = register_diag_field (mod_name, & 'qndt_sacws', axes(1:3), Time, & - 'Cloud droplet tendency from collection by snow', '#/kg/sec',& + 'Cloud droplet number tendency from collection by snow', & + '#/kg/sec',& missing_value=missing_value) diag_id%qndt_sacws_o = register_diag_field (mod_name, & 'qndt_sacws_o', axes(1:3), Time, & - 'Cld drop tend from collection by snw - one ice cat scheme', & - '#/kg/sec', & - missing_value=missing_value) + 'Cld drop number tend from collection by snw & + &- one ice cat scheme', & + '#/kg/sec', missing_value=missing_value) diag_id%qndt_eros = register_diag_field (mod_name, & 'qndt_eros', axes(1:3), Time, & - 'Cloud droplet tendency from erosion', '#/kg/sec', & + 'Cloud droplet number tendency from erosion', '#/kg/sec', & missing_value=missing_value) diag_id%qndt_pra = register_diag_field (mod_name, & 'qndt_pra', axes(1:3), Time, & - 'Cloud droplet tendency from collection by rain', '#/kg/sec',& + 'Cloud droplet number tendency from collection by rain', & + '#/kg/sec',& missing_value=missing_value) diag_id%qndt_auto = register_diag_field (mod_name, & 'qndt_auto', axes(1:3), Time, & - 'Cloud droplet tendency autoconversion', '#/kg/sec', & - missing_value=missing_value) + 'Cloud droplet number tendency from autoconversion', & + '#/kg/sec', & + missing_value=missing_value) diag_id%qndt_nucclim = register_diag_field (mod_name, & 'qndt_nucclim', axes(1:3), Time, & - 'Cloud droplet tendency from nucleation limiter', '#/kg/sec',& - missing_value=missing_value) + 'Cloud droplet number tendency from nucleation limiter', & + '#/kg/sec', missing_value=missing_value) diag_id%qndt_sedi = register_diag_field (mod_name, & 'qndt_sedi', axes(1:3), Time, & - 'Cloud droplet tendency from sedimentation', '#/kg/sec', & - missing_value=missing_value) + 'Cloud droplet number tendency from sedimentation', & + '#/kg/sec', missing_value=missing_value) diag_id%qndt_melt = register_diag_field (mod_name, & 'qndt_melt', axes(1:3), Time, & - 'Cloud droplet tendency from melting', '#/kg/sec', & + 'Cloud droplet number tendency from melting', '#/kg/sec', & missing_value=missing_value) diag_id%qndt_ihom = register_diag_field (mod_name, & 'qndt_ihom', axes(1:3), Time, & - 'Cloud drop tend from homogeneous freezing', '#/kg/sec', & - missing_value=missing_value) + 'Cloud drop number tend from homogeneous freezing', & + '#/kg/sec', missing_value=missing_value) diag_id%qndt_size_adj = register_diag_field (mod_name, & 'qndt_size_adj', axes(1:3), Time, & - 'Cloud droplet tendency from size adjustment', '#/kg/sec', & - missing_value=missing_value) + 'Cloud droplet number tendency from size adjustment', & + '#/kg/sec', missing_value=missing_value) diag_id%qndt_fill2 = register_diag_field (mod_name, & 'qndt_fill2', axes(1:3), Time, & - 'Cloud droplet tendency from second filler', '#/kg/sec', & - missing_value=missing_value) + 'Cloud droplet number tendency from second filler', & + '#/kg/sec', missing_value=missing_value) -!----------------------------------------------------------------------- -! 10) variables associated with ice particle number time tendency: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 10) variables associated with ice particle number time tendency: + !----------------------------------------------------------------------- diag_id%qnidt_fill = register_diag_field (mod_name, & 'qnidt_fill', axes(1:3), Time, & - 'Cloud ice tendency from filler', '#/kg/sec', & + 'Ice particle number tendency from filler', '#/kg/sec', & missing_value=missing_value) diag_id%qnidt_nnuccd = register_diag_field (mod_name, & 'qnidt_nnuccd', axes(1:3), Time, & - 'Cloud ice tendency from nucleation', '#/kg/sec', & + 'Ice particle number tendency from nucleation', '#/kg/sec', & missing_value=missing_value) diag_id%qnidt_nsubi = register_diag_field (mod_name, & 'qnidt_nsubi', axes(1:3), Time, & - 'Cloud ice tendency from sublimation', '#/kg/sec', & + 'Ice particle number tendency from sublimation', '#/kg/sec', & missing_value=missing_value) diag_id%qnidt_nerosi = register_diag_field (mod_name, & 'qnidt_nerosi', axes(1:3), Time, & - 'Cloud ice tendency from erosion', '#/kg/sec', & + 'Ice particle number tendency from erosion', '#/kg/sec', & missing_value=missing_value) diag_id%qnidt_nprci = register_diag_field (mod_name, & 'qnidt_nprci', axes(1:3), Time, & - 'Cloud ice tendency from autoconversion', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from autoconversion', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_nprai = register_diag_field (mod_name, & 'qnidt_nprai', axes(1:3), Time, & - 'Cloud ice tendency from accretion by snow', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from accretion by snow', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_nucclim1 = register_diag_field (mod_name, & 'qnidt_nucclim1', axes(1:3), Time, & - 'Cld ice tendency from first nucleation limiter', '#/kg/sec',& - missing_value=missing_value) + 'Ice particle number tendency from first nucleation limiter',& + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_nucclim2 = register_diag_field (mod_name, & 'qnidt_nucclim2', axes(1:3), Time, & - 'Cld ice tendency from second nucleation limiter','#/kg/sec',& - missing_value=missing_value) + 'Ice particle number tendency from second nucleation & + &limiter','#/kg/sec', missing_value=missing_value) diag_id%qnidt_sedi = register_diag_field (mod_name, & 'qnidt_sedi', axes(1:3), Time, & - 'Cloud ice tendency from sedimentation', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from sedimentation', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_melt = register_diag_field (mod_name, & 'qnidt_melt', axes(1:3), Time, & - 'Cloud ice tendency from melting', '#/kg/sec', & + 'Ice particle number tendency from melting', '#/kg/sec', & missing_value=missing_value) diag_id%qnidt_size_adj = register_diag_field (mod_name, & 'qnidt_size_adj', axes(1:3), Time, & - 'Cloud ice tendency from size adjustment', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from size adjustment', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_fill2 = register_diag_field (mod_name, & 'qnidt_fill2', axes(1:3), Time, & - 'Cloud ice tendency from second filler', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from second filler', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_super = register_diag_field (mod_name, & 'qnidt_super', axes(1:3), Time, & - 'Cloud ice tendency from sat adj', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from removal of & + &supersaturation', '#/kg/sec', missing_value=missing_value) diag_id%qnidt_ihom = register_diag_field (mod_name, & 'qnidt_ihom', axes(1:3), Time, & - 'Cloud ice tendency from homogeneous freezing', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from homogeneous freezing', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_destr = register_diag_field (mod_name, & 'qnidt_destr', axes(1:3), Time, & - 'Cloud ice tendency from homogeneous freezing', '#/kg/sec', & - missing_value=missing_value) + 'Ice particle number tendency from cloud destruction', & + '#/kg/sec', missing_value=missing_value) diag_id%qnidt_cleanup = register_diag_field (mod_name, & 'qnidt_cleanup', axes(1:3), Time, & - 'Cloud ice tendency from cleanup', '#/kg/sec', & + 'Ice particle number tendency from cleanup', '#/kg/sec', & + missing_value=missing_value) + diag_id%qnidt_cleanup2 = register_diag_field (mod_name, & + 'qnidt_cleanup2', axes(1:3), Time, & + 'Ice particle number tendency from cleanup2', '#/kg/sec', & missing_value=missing_value) -!----------------------------------------------------------------------- -! 11) variables associated with relative humidity: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 11) variables associated with relative humidity: + !----------------------------------------------------------------------- diag_id%rhcrit = register_diag_field (mod_name, & 'rhcrit', axes(1:3), Time, & - 'rhcrit', 'none', & - missing_value=missing_value) + 'spectral avgd critical rh used for ice nuclei activation', & + 'percent', missing_value=missing_value) diag_id%rhcrit_min = register_diag_field (mod_name, & 'rhcrit_min', axes(1:3), Time, & - 'rhcrit_min', 'none', & - missing_value=missing_value) + 'minimum critical rh for ice nuclei activation in any & + &spectral band', 'percent', missing_value=missing_value) diag_id%rhiin = register_diag_field (mod_name, & 'rhiin', axes(1:3), Time, & - 'rhiin', 'none', & - missing_value=missing_value) + 'rh wrt ice calculated for ice nulei activation', 'percent', & + mask_variant = .true., missing_value=missing_value) diag_id%rhlin = register_diag_field (mod_name, & 'rhlin', axes(1:3), Time, & - 'rhlin', 'none', & + 'rh wrt liquid calculated for ice nulei activation', & + 'percent', mask_variant = .true., & missing_value=missing_value) -!----------------------------------------------------------------------- -! 12) variables associated with aerosol nucleation: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 12) variables associated with aerosol nucleation: + !----------------------------------------------------------------------- diag_id%imass7 = register_diag_field (mod_name, & 'imass7', axes(1:3), Time, & - 'imass7', 'xxxx', & + 'sub-micron dust concentration', 'ug dust /m3', & missing_value=missing_value) diag_id%ni_dust = register_diag_field (mod_name, & 'ni_dust', axes(1:3), Time, & - 'ni_dust', 'none', & + 'number of activated dust ice nuclei', '# / m3', & missing_value=missing_value) diag_id%ni_sulf = register_diag_field (mod_name, & 'ni_sulf', axes(1:3), Time, & - 'ni_sulf', 'none', & + 'number of activated sulfate/seasalt ice nuclei', '# / m3', & missing_value=missing_value) diag_id%ni_bc = register_diag_field (mod_name, & 'ni_bc', axes(1:3), Time, & - 'ni_bc', 'none', & + 'number of activated bc ice nuclei', '# / m3', & missing_value=missing_value) diag_id%ndust1 = register_diag_field (mod_name, & 'ndust1', axes(1:3), Time, & - 'ndust1', 'none', & + 'number of particles in dust bin1', 'none', & missing_value=missing_value) diag_id%ndust2 = register_diag_field (mod_name, & 'ndust2', axes(1:3), Time, & - 'ndust2', 'none', & + 'number of particles in dust bin2', 'none', & missing_value=missing_value) diag_id%ndust3 = register_diag_field (mod_name, & 'ndust3', axes(1:3), Time, & - 'ndust3', 'none', & + 'number of particles in dust bin3', 'none', & missing_value=missing_value) diag_id%ndust4 = register_diag_field (mod_name, & 'ndust4', axes(1:3), Time, & - 'ndust4', 'none', & + 'number of particles in dust bin4', 'none', & missing_value=missing_value) diag_id%ndust5 = register_diag_field (mod_name, & 'ndust5', axes(1:3), Time, & - 'ndust5', 'none', & + 'number of particles in dust bin5', 'none', & missing_value=missing_value) diag_id%sulfate = register_diag_field (mod_name, & 'sulfate', axes(1:3), Time, & - 'sulfate mass conentration', 'ug so4/m3', & + 'sulfate mass concentration', 'ug so4/m3', & missing_value=missing_value) diag_id%seasalt_sub = register_diag_field (mod_name, & 'seasalt_sub', axes(1:3), Time, & - 'sub-micron sea salt mass conentration', 'ug/m3', & + 'sub-micron sea salt mass concentration', 'ug/m3', & missing_value=missing_value) diag_id%seasalt_sup = register_diag_field (mod_name, & 'seasalt_sup', axes(1:3), Time, & - 'super-micron sea salt mass conentration', 'ug/m3', & + 'super-micron sea salt mass concentration', 'ug/m3', & missing_value=missing_value) diag_id%om = register_diag_field (mod_name, & 'OM', axes(1:3), Time, & - 'OM mass conentration', 'ug/m3', & + 'OM mass concentration', 'ug/m3', & missing_value=missing_value) -!----------------------------------------------------------------------- -! 13) variables associated with water vapor tendency: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 13) variables associated with water vapor tendency: + !----------------------------------------------------------------------- diag_id%rain_evap = register_diag_field (mod_name, & 'rain_evap', axes(1:3), Time, & 'Water vapor tendency from rain evaporation', 'kg/kg/sec', & missing_value=missing_value) -!----------------------------------------------------------------------- -! 14) variables associated with cloud ice time tendency: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 14) variables associated with cloud ice time tendency: + !----------------------------------------------------------------------- diag_id%qidt_dep = register_diag_field (mod_name, & 'qidt_dep', axes(1:3), Time, & 'Ice water specific humidity tendency from LS deposition', & - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_subl = register_diag_field (mod_name, & 'qidt_subl', axes(1:3), Time, & 'Ice water specific humidity tendency from LS sublimation', & - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_eros = register_diag_field (mod_name, & 'qidt_eros', axes(1:3), Time, & 'Ice water specific humidity tendency from erosion', & - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_fall = register_diag_field (mod_name, & 'qidt_fall', axes(1:3), Time, & 'Ice water specific humidity tendency from ice settling', & - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_melt = register_diag_field (mod_name, & 'qidt_melt', axes(1:3), Time, & 'Ice water specific humidity tendency from melting to rain',& - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) + diag_id%qidt_melt2 = register_diag_field (mod_name, & + 'qidt_melt2', axes(1:3), Time, & + 'Ice water specific humidity tendency from melting to & + &cloud droplets', 'kg/kg/sec', missing_value=missing_value) diag_id%ice_adj = register_diag_field (mod_name, & 'ice_adj', axes(1:3), Time, & - 'Frozen condensation rate from removal of supersaturation', & - 'kg/kg/sec', & + 'Ice water specific humidity tendency from the removal & + &of supersaturation', 'kg/kg/sec', & missing_value=missing_value) diag_id%qidt_destr = register_diag_field (mod_name, & 'qidt_destr', axes(1:3), Time, & - 'Ice water spec hum tendency from cloud destruction',& - 'kg/kg/sec', & - missing_value=missing_value) + 'Ice water spec hum tendency from cloud destruction', & + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_qvdep = register_diag_field (mod_name, & 'qidt_qvdep', axes(1:3), Time, & 'Ice water specific humidity tendency from vapor deposition',& - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_fill = register_diag_field (mod_name, & 'qidt_fill', axes(1:3), Time, & - 'Ice water specific humidity tendency from filler', & - 'kg/kg/sec', & - missing_value=missing_value) + 'Ice water specific humidity tendency -- pre-microphysics & + & filler', 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_auto = register_diag_field (mod_name, & 'qidt_auto', axes(1:3), Time, & - 'Ice water specific humidity tendency from autoconversion', & - 'kg/kg/sec', & - missing_value=missing_value) + 'Ice water specific humidity tendency from autoconversion & + &to snow', 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_accr = register_diag_field (mod_name, & 'qidt_accr', axes(1:3), Time, & 'Ice water spec hum tendency from accretion by snow', & - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) diag_id%qidt_accrs = register_diag_field (mod_name, & 'qidt_accrs', axes(1:3), Time, & 'Ice wat spec hum tend from selfcollection (1 class scheme)',& - 'kg/kg/sec', & - missing_value=missing_value) + 'kg/kg/sec', missing_value=missing_value) -!----------------------------------------------------------------------- -! 15) variables associated with cloud area time tendency: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 15) variables associated with cloud area time tendency: + !----------------------------------------------------------------------- diag_id%qadt_lsform = register_diag_field (mod_name, & 'qadt_lsform', axes(1:3), Time, & 'cloud fraction tendency from LS condensation', '1/sec', & missing_value=missing_value) diag_id%qadt_lsdiss = register_diag_field (mod_name, & 'qadt_lsdiss', axes(1:3), Time, & - 'cloud fraction tendency from LS evaporation', '1/sec', & + 'cloud fraction tendency from LS dissipation', '1/sec', & missing_value=missing_value) diag_id%qadt_rhred = register_diag_field (mod_name, & 'qadt_rhred', axes(1:3), Time, & @@ -1413,33 +1774,216 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_id%qadt_super = register_diag_field (mod_name, & 'qadt_super', axes(1:3), Time, & 'cloud fraction tendency from supersaturation formation', & - '1/sec', & - missing_value=missing_value) + '1/sec', missing_value=missing_value) diag_id%qadt_destr = register_diag_field (mod_name, & 'qadt_destr', axes(1:3), Time, & 'cloud fraction tendency from cloud destruction', '1/sec', & missing_value=missing_value) + diag_id%qadt_limits = register_diag_field (mod_name, & + 'qadt_limits', axes(1:3), Time, & + 'cloud fraction tendency from imposing limits', '1/sec', & + missing_value=missing_value) + diag_id%qadt_ahuco = register_diag_field (mod_name, & + 'qadt_ahuco', axes(1:3), Time, & + 'cloud fraction tendency from convective area restriction', & + '1/sec', missing_value=missing_value) + + !------------------------------------------------------------------------ + ! 16) variables added by h1g with ncar M-G microphysics + !------------------------------------------------------------------------ + diag_id%SA3d = register_diag_field ( mod_name, & + 'SA3d', axes(1:3), Time, & + 'Total cloud area tendency', '1/sec', & + missing_value=missing_value) + diag_id%ST3d = register_diag_field ( mod_name, & + 'ST3d', axes(1:3), Time, & + 'Total temperature tendency', & + 'K/sec', missing_value=missing_value) + diag_id%SQ3d = register_diag_field ( mod_name, & + 'SQ3d', axes(1:3), Time, & + 'Total Water vapor specific humidity tendency ', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_liquid_init = register_diag_field ( mod_name, & + 'qdt_liquid_init', axes(1:3), Time, & + 'Water vapor specific humidity tendency from initial & + &adjustment of liquid water', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_ice_init = register_diag_field ( mod_name, & + 'qdt_ice_init', axes(1:3), Time, & + 'Water vapor specific humidity tendency from initial & + &adjustment of ice', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_rain_evap = register_diag_field ( mod_name, & + 'qdt_rain_evap', axes(1:3), Time, & + 'Water vapor specific humidity tendency from rain & + &evaporation', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_snow_sublim = register_diag_field ( mod_name, & + 'qdt_snow_sublim', axes(1:3), Time, & + 'Water vapor specific humidity tendency from snow & + &sublimation', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_cond = register_diag_field ( mod_name, & + 'qdt_cond', axes(1:3), Time, & + 'Water vapor specific humidity tendency from LS & + &condensation', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_deposition = register_diag_field ( mod_name, & + 'qdt_deposition', axes(1:3), Time, & + 'Water vapor specific humidity tendency from LS deposition', & + 'kg/kg/sec', missing_value=missing_value ) + diag_id%qdt_eros_l = register_diag_field ( mod_name, & + 'qdt_eros_l', axes(1:3), Time, & + 'Water vapor specific humidity tendency from liquid water & + & erosion', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_eros_i = register_diag_field ( mod_name, & + 'qdt_eros_i', axes(1:3), Time, & + 'Water vapor specific humidity tendency from ice water & + &erosion', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_qv_on_qi = register_diag_field ( mod_name, & + 'qdt_qv_on_qi', axes(1:3), Time, & + 'Water vapor specific humidity tendency from direct & + &deposition on ice', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_snow2vapor = register_diag_field ( mod_name, & + 'qdt_snow2vapor', axes(1:3), Time, & + 'Water vapor specific humidity tendency from condensation & + &resulting from cooling of the air by melting snow', & + 'kg/kg/sec', missing_value=missing_value ) + diag_id%qdt_sedi_ice2vapor = register_diag_field ( mod_name, & + 'qdt_sedi_ice2vapor', axes(1:3), Time, & + 'Water vapor specific humidity tendency from the & + &sublimation of falling cloud ice', 'kg/kg/sec', & + missing_value=missing_value) + diag_id%qdt_sedi_liquid2vapor = register_diag_field ( mod_name, & + 'qdt_sedi_liquid2vapor', axes(1:3), Time, & + 'Water vapor specific humidity tendency from the evaporation & + &of falling cloud liquid', 'kg/kg/sec', & + missing_value=missing_value) + diag_id%qdt_super_sat_rm = register_diag_field ( mod_name, & + 'qdt_super_sat_rm', axes(1:3), Time, & + 'Water vapor specific humidity tendency from removing super & + &saturation', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_destr = register_diag_field ( mod_name, & + 'qdt_destr', axes(1:3), Time, & + 'Water vapor specific humidity tendency from Cloud & + &Destruction', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_cleanup_liquid = register_diag_field ( mod_name, & + 'qdt_cleanup_liquid', axes(1:3), Time, & + 'Water vapor specific humidity tendency from cleaning up & + &liquid cloud', 'kg/kg/sec', missing_value=missing_value) + diag_id%qdt_cleanup_ice = register_diag_field ( mod_name, & + 'qdt_cleanup_ice', axes(1:3), Time, & + 'Water vapor specific humidity tendency from cleaning up & + &ice cloud', 'kg/kg/sec', missing_value=missing_value) + diag_id%SL3d = register_diag_field ( mod_name, & + 'SL3d', axes(1:3), Time, & + 'Total Liquid Water specific humidity tendency ', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%qldt_HM_splinter = register_diag_field ( mod_name, & + 'qldt_HM_splinter', axes(1:3), Time, & + 'Liquid water specific humidity tendency from H-M & + &splintering ', 'kg/kg/sec', missing_value=missing_value) + diag_id%SN3d = register_diag_field ( mod_name, & + 'SN3d', axes(1:3), Time, & + 'Total cloud drop number tendency', & + '#/kg/sec', missing_value=missing_value) + diag_id%qndt_contact_frz = register_diag_field ( mod_name, & + 'qndt_contact_frz', axes(1:3), Time, & + 'Cloud droplet number tendency from contact freezing of& + & liquid water', '#/kg/sec', missing_value=missing_value) + diag_id%qndt_cleanup = register_diag_field ( mod_name, & + 'qndt_cleanup', axes(1:3), Time, & + 'Cloud droplet number tendency from cloud cleanup', & + '#/kg/sec', missing_value=missing_value) + diag_id%qndt_cleanup2 = register_diag_field ( mod_name, & + 'qndt_cleanup2', axes(1:3), Time, & + 'Cloud droplet number tendency from cloud cleanup2', & + '#/kg/sec', missing_value=missing_value) + diag_id%SNI3d = register_diag_field ( mod_name, & + 'SNI3d', axes(1:3), Time, & + 'Total ice crystal number tendency', & + '#/kg/sec', missing_value=missing_value) + diag_id%qnidt_nsacwi = register_diag_field ( mod_name, & + 'qnidt_nsacwi', axes(1:3), Time, & + 'Cloud ice tendency from HM ice multiplication', & + '#/kg/sec', missing_value=missing_value) + diag_id%srfrain_evap = register_diag_field ( mod_name, & + 'srfrain_evap', axes(1:3), Time, & + 'rain water sink from evaporation', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%srfrain_accrs= register_diag_field ( mod_name, & + 'srfrain_accrs', axes(1:3), Time, & + 'rain water sink from collection by snow', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%srfrain_freez= register_diag_field ( mod_name, & + 'srfrain_freez', axes(1:3), Time, & + 'rain water sink from freezing', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%SI3d = register_diag_field ( mod_name, & + 'SI3d', axes(1:3), Time, & + 'Total Ice water specific humidity tendency ', & + 'kg/kg/sec', missing_value=missing_value) - -!----------------------------------------------------------------------- -! -! COLUMN-INTEGRATED DIAGNOSTICS -! -!----------------------------------------------------------------------- - -!------------------------------------------------------------------------ -! 1) variables associated with droplet number and size: -!------------------------------------------------------------------------ + !------------------------------------------------------------------------ + ! 17) variables associated with budget analysis + !------------------------------------------------------------------------ + diag_id%SA_imb = register_diag_field ( mod_name, & + 'SA_imb', axes(1:3), Time, & + 'difference between qa tendency and sum of individ terms', & + '1/sec', missing_value=missing_value) + diag_id%ST_imb = register_diag_field ( mod_name, & + 'ST_imb', axes(1:3), Time, & + 'difference between temp tendency and sum of individ terms', & + 'K/sec', missing_value=missing_value) + diag_id%SQ_imb = register_diag_field ( mod_name, & + 'SQ_imb', axes(1:3), Time, & + 'difference between qv tendency and sum of individ terms', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%SL_imb = register_diag_field ( mod_name, & + 'SL_imb', axes(1:3), Time, & + 'difference between ql tendency and sum of individ terms', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%SI_imb = register_diag_field ( mod_name, & + 'SI_imb', axes(1:3), Time, & + 'difference between qi tendency and sum of individ terms', & + 'kg/kg/sec', missing_value=missing_value) + diag_id%SN_imb = register_diag_field ( mod_name, & + 'SN_imb', axes(1:3), Time, & + 'difference between qn tendency and sum of individ terms', & + '#/kg/sec', missing_value=missing_value) + diag_id%SNi_imb = register_diag_field ( mod_name, & + 'SNi_imb', axes(1:3), Time, & + 'difference between qni tendency and sum of individ terms', & + '#/kg/sec', missing_value=missing_value) + diag_id%rain_imb = register_diag_field ( mod_name, & + 'rain_imb', axes(1:3), Time, & + 'difference between rain rate at sfc and sum of & + &individ terms', 'kg/kg/sec', missing_value=missing_value) + diag_id%cld_liq_imb = register_diag_field ( mod_name, & + 'cld_liq_imb', axes(1:3), Time, & + 'difference between ql fallout rate at sfc and sum of & + &individ terms', 'kg/kg/sec', missing_value=missing_value) + diag_id%snow_imb = register_diag_field ( mod_name, & + 'snow_imb', axes(1:3), Time, & + 'difference between snow rate at sfc and sum of & + &individ terms', 'kg/kg/sec', missing_value=missing_value) + diag_id%cld_ice_imb = register_diag_field ( mod_name, & + 'cld_ice_imb', axes(1:3), Time, & + 'difference between qi fallout rate at sfc and sum of & + &individ terms', 'kg/kg/sec', missing_value=missing_value) + + !----------------------------------------------------------------------- + ! + ! COLUMN-INTEGRATED DIAGNOSTICS + ! + !----------------------------------------------------------------------- + + !------------------------------------------------------------------------ + ! 1) variables associated with droplet number and size: + !------------------------------------------------------------------------ diag_id%droplets_col = register_diag_field (mod_name, & - 'droplets_col', axes(1:2), Time, & - 'Droplet number column burden', '/m2', & - missing_value=missing_value) - diag_id%droplets_col_s = register_diag_field (mod_name, & - 'droplets_col_s', axes(1:2), Time, & + 'droplets_col', axes(1:2), Time, & 'Droplet number in cloud column burden', '/cm2', & missing_value=missing_value) diag_id%gb_droplets_col = register_diag_field (mod_name, & - 'gb_droplets_col_s', axes(1:2), Time, & + 'gb_droplets_col', axes(1:2), Time, & 'Droplet number grid box column burden', '/cm2', & missing_value=missing_value) diag_id%droplets_col250 = register_diag_field (mod_name, & @@ -1447,33 +1991,49 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & 'Droplet number in cloud column burden for T> 250K', '/cm2', & missing_value=missing_value) -!------------------------------------------------------------------------ -! 3) variables associated with cloud and precipitation processes: -!------------------------------------------------------------------------ - diag_id%snow_subl_col = register_diag_field (mod_name, & - 'snow_subl_col', axes(1:2), Time, & - 'Column integrated snow sublimation', 'kg/m2/sec', & + !------------------------------------------------------------------------ + ! 3) variables associated with cloud and precipitation processes: + !------------------------------------------------------------------------ + diag_id%sedi_ice = register_diag_field (mod_name, & + 'sedi_ice', axes(1:2), Time, & + 'ice sedimentation flux to surface', 'm/sec', & missing_value=missing_value) diag_id%snow_melt_col = register_diag_field (mod_name, & 'snow_melt_col', axes(1:2), Time, & 'Column integrated snow melting', 'kg/m2/sec', & missing_value=missing_value) + diag_id%rain_freeze_col = register_diag_field (mod_name, & + 'rain_freeze_col', axes(1:2), Time, & + 'Column integrated loss of rain from freezing', 'kg/m2/sec', & + missing_value=missing_value) -!------------------------------------------------------------------------ -! 5) variables associated with ice particle number: -!------------------------------------------------------------------------ + !------------------------------------------------------------------------ + ! 5) variables associated with ice particle number: + !------------------------------------------------------------------------ diag_id%nice_col = register_diag_field (mod_name, & - 'nice_col_s', axes(1:2), Time, & + 'nice_col', axes(1:2), Time, & 'ice number in cloud column burden', '/cm2', & missing_value=missing_value) diag_id%gb_nice_col = register_diag_field (mod_name, & - 'gb_nice_col_s', axes(1:2), Time, & + 'gb_nice_col', axes(1:2), Time, & 'ice number grid box column burden', '/cm2', & missing_value=missing_value) -!----------------------------------------------------------------------- -! 8) variables associated with cloud liquid time tendency: -!----------------------------------------------------------------------- +!------------------------------------------------------------------------ +! 6) variables associated with precipitation and precipitation area: +!------------------------------------------------------------------------ + diag_id%qrout_col = register_diag_field (mod_name, & + 'rain_path', axes(1:2), Time, & + 'rain water path from stratiform', 'kg/m2', & + missing_value=missing_value) + diag_id%qsout_col = register_diag_field (mod_name, & + 'snow_path', axes(1:2), Time, & + 'snow water path from stratiform', 'kg/m2', & + missing_value=missing_value) + + !----------------------------------------------------------------------- + ! 8) variables associated with cloud liquid time tendency: + !----------------------------------------------------------------------- diag_id%ql_cond_col = register_diag_field (mod_name, & 'ql_cond_col', axes(1:2), Time, & 'Column integrated condensation', 'kg/m2/sec', & @@ -1488,12 +2048,12 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & missing_value=missing_value) diag_id%ql_accr_col = register_diag_field (mod_name, & 'ql_accr_col', axes(1:2), Time, & - 'Column integrated accretion', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated accretion of cloud water by rain', & + 'kg/m2/sec', missing_value=missing_value) diag_id%ql_auto_col = register_diag_field (mod_name, & 'ql_auto_col', axes(1:2), Time, & - 'Column integrated autoconversion', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated autoconversion of cloud water to rain', & + 'kg/m2/sec', missing_value=missing_value) diag_id%ql_berg_col = register_diag_field (mod_name, & 'ql_berg_col', axes(1:2), Time, & 'Column integrated Bergeron process', 'kg/m2/sec', & @@ -1512,12 +2072,12 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & missing_value=missing_value) diag_id%ql_fill_col = register_diag_field (mod_name, & 'ql_fill_col', axes(1:2), Time, & - 'Column integrated liquid filler', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated pre-microphysics liquid filler', & + 'kg/m2/sec', missing_value=missing_value) diag_id%liq_adj_col = register_diag_field (mod_name, & 'liq_adj_col', axes(1:2), Time, & - 'Column integrated liquid condensation by adjustment', & - 'kg/m2/sec', & + 'Column integrated liquid water specific humidity & + &tendency from supersaturation removal', 'kg/m2/sec', & missing_value=missing_value) diag_id%ql_freez2_col = register_diag_field (mod_name, & 'ql_freez2_col', axes(1:2), Time, & @@ -1529,36 +2089,106 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & missing_value=missing_value) diag_id%ql_accrs_col = register_diag_field (mod_name, & 'ql_accrs_col', axes(1:2), Time, & - 'Column integrated droplet collection by snow', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated cloud liquid collection by snow', & + 'kg/m2/sec', missing_value=missing_value) diag_id%ql_bergs_col = register_diag_field (mod_name, & 'ql_bergs_col', axes(1:2), Time, & 'Column integrated bergeron process for snow ', 'kg/m2/sec', & missing_value=missing_value) -!----------------------------------------------------------------------- -! 9) variables associated with cloud droplet number time tendency: -!----------------------------------------------------------------------- + !----------------------------------------------------------------------- + ! 9) variables associated with cloud droplet number time tendency: + !----------------------------------------------------------------------- diag_id%qn_cond_col = register_diag_field (mod_name, & 'qn_cond_col', axes(1:2), Time, & - 'Column integrated drop number condensation', 'kg/m2/sec', & + 'Column integrated drop number condensation', '#/m2/sec', & missing_value=missing_value) diag_id%qn_evap_col = register_diag_field (mod_name, & 'qn_evap_col', axes(1:2), Time, & - 'Column integrated drop number evaporation', 'kg/m2/sec', & + 'Column integrated drop number evaporation', '#/m2/sec', & missing_value=missing_value) + diag_id%qn_berg_col = register_diag_field (mod_name, & + 'qn_berg_col', axes(1:2), Time, & + 'Column integrated drop number bergeron tendency', & + '#/m2/sec', missing_value=missing_value) diag_id%qn_fill_col = register_diag_field (mod_name, & 'qn_fill_col', axes(1:2), Time, & - 'Column integrated drop number filler', 'kg/m2/sec', & + 'Column integrated drop number filler', '#/m2/sec', & missing_value=missing_value) diag_id%qn_destr_col = register_diag_field (mod_name, & 'qn_destr_col', axes(1:2), Time, & - 'Column integrated drop number destruction', 'kg/m2/sec', & + 'Column integrated drop number destruction', '#/m2/sec', & missing_value=missing_value) diag_id%qn_super_col = register_diag_field (mod_name, & 'qn_super_col', axes(1:2), Time, & - 'Column integrated drop number supersaturation', 'kg/m2/sec',& - missing_value=missing_value) + 'Column integrated drop number tendency from & + &supersaturation removal', '#/m2/sec',& + missing_value=missing_value) + diag_id%qn_freez_col = register_diag_field (mod_name, & + 'qn_freez_col', axes(1:2), Time, & + 'Column integrated drop number tendency from & + &heterogeneous freezing', '#/m2/sec',& + missing_value=missing_value) + diag_id%qn_sacws_col = register_diag_field (mod_name, & + 'qn_sacws_col', axes(1:2), Time, & + 'Column integrated drop number tendency from droplet & + &collection by snow', '#/m2/sec',& + missing_value=missing_value) + diag_id%qn_sacws_o_col = register_diag_field (mod_name, & + 'qn_sacws_o_col', axes(1:2), Time, & + 'Column integrated drop number tendency from droplet & + &collection by snow (one ice cat)', '#/m2/sec',& + missing_value=missing_value) + diag_id%qn_eros_col = register_diag_field (mod_name, & + 'qn_eros_col', axes(1:2), Time, & + 'Column integrated drop number tendency from cloud erosion', & + '#/m2/sec', missing_value=missing_value) + diag_id%qn_pra_col = register_diag_field (mod_name, & + 'qn_pra_col', axes(1:2), Time, & + 'Column integrated drop number tendency from collection & + &by rain', '#/m2/sec', missing_value=missing_value) + diag_id%qn_auto_col = register_diag_field (mod_name, & + 'qn_auto_col', axes(1:2), Time, & + 'Column integrated drop number tendency from autoconversion & + &to rain', '#/m2/sec', missing_value=missing_value) + diag_id%qn_nucclim_col = register_diag_field (mod_name, & + 'qn_nucclim_col', axes(1:2), Time, & + 'Column integrated drop number tendency from nucleation & + &limiter', '#/m2/sec', missing_value=missing_value) + diag_id%qn_sedi_col = register_diag_field (mod_name, & + 'qn_sedi_col', axes(1:2), Time, & + 'Column integrated drop number tendency from sedimentation & + &of droplets', '#/m2/sec', missing_value=missing_value) + diag_id%qn_melt_col = register_diag_field (mod_name, & + 'qn_melt_col', axes(1:2), Time, & + 'Column integrated drop number tendency from melting of ice',& + '#/m2/sec', missing_value=missing_value) + diag_id%qn_ihom_col = register_diag_field (mod_name, & + 'qn_ihom_col', axes(1:2), Time, & + 'Column integrated drop number tendency from homogeneous & + &freezing of droplets', '#/m2/sec',& + missing_value=missing_value) + diag_id%qn_size_adj_col = register_diag_field (mod_name, & + 'qn_size_adj_col', axes(1:2), Time, & + 'Column integrated drop number tendency from droplet & + &size adjustment', '#/m2/sec',& + missing_value=missing_value) + diag_id%qn_fill2_col = register_diag_field (mod_name, & + 'qn_fill2_col', axes(1:2), Time, & + 'Column integrated drop number tendency from second filler', & + '#/m2/sec', missing_value=missing_value) + diag_id%qn_contact_frz_col = register_diag_field (mod_name, & + 'qn_contact_frz_col', axes(1:2), Time, & + 'Column integrated drop number tendency from contact & + &freezing', '#/m2/sec', missing_value=missing_value) + diag_id%qn_cleanup_col = register_diag_field (mod_name, & + 'qn_cleanup_col', axes(1:2), Time, & + 'Column integrated drop number tendency from cleanup', & + '#/m2/sec', missing_value=missing_value) + diag_id%qn_cleanup2_col = register_diag_field (mod_name, & + 'qn_cleanup2_col', axes(1:2), Time, & + 'Column integrated drop number tendency from second cleanup',& + '#/m2/sec', missing_value=missing_value) !----------------------------------------------------------------------- ! 13) variables associated with water vapor tendency: @@ -1577,7 +2207,7 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & missing_value=missing_value) diag_id%qi_fill_col = register_diag_field (mod_name, & 'qi_fill_col', axes(1:2), Time, & - 'Column integrated ice filler', 'kg/m2/sec', & + 'Column integrated pre-microphysics ice filler', 'kg/m2/sec',& missing_value=missing_value) diag_id%qi_dep_col = register_diag_field (mod_name, & 'qi_dep_col', axes(1:2), Time, & @@ -1601,60 +2231,357 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & missing_value=missing_value) diag_id%qi_melt_col = register_diag_field (mod_name, & 'qi_melt_col', axes(1:2), Time, & - 'Column integrated ice melting', 'kg/m2/sec', & + 'Column integrated ice melting to rain', 'kg/m2/sec', & missing_value=missing_value) + diag_id%qi_melt2_col = register_diag_field (mod_name, & + 'qi_melt2_col', axes(1:2), Time, & + 'Column integrated ice melting to cloud droplets', & + 'kg/m2/sec', missing_value=missing_value) diag_id%ice_adj_col = register_diag_field (mod_name, & 'ice_adj_col', axes(1:2), Time, & - 'Column integrated frozen condesation by adjustment',& - 'kg/m2/sec', & + 'Column integrated ice water specific humidity tendency & + &from the removal of supersaturation', 'kg/m2/sec', & missing_value=missing_value) diag_id%qi_auto_col = register_diag_field (mod_name, & 'qi_auto_col', axes(1:2), Time, & - 'Column integrated ice autoconversion ', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated autoconversion from cloud ice to snow ', & + 'kg/m2/sec', missing_value=missing_value) diag_id%qi_accr_col = register_diag_field (mod_name, & 'qi_accr_col', axes(1:2), Time, & - 'Column integrated accretion by snow ', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated accretion of cloud ice by snow ', & + 'kg/m2/sec', missing_value=missing_value) diag_id%qi_accrs_col = register_diag_field (mod_name, & 'qi_accrs_col', axes(1:2), Time, & 'Column integrated self collection (one class scheme)', & - 'kg/m2/sec', & - missing_value=missing_value) + 'kg/m2/sec', missing_value=missing_value) !----------------------------------------------------------------------- ! 15) variables associated with cloud area time tendency: !----------------------------------------------------------------------- diag_id%qa_lsform_col = register_diag_field (mod_name, & 'qa_lsform_col', axes(1:2), Time, & - 'Column integrated large-scale formation', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated cloud fraction tendency from & + &condensation', 'kg/m2/sec', missing_value=missing_value) diag_id%qa_lsdiss_col = register_diag_field (mod_name, & 'qa_lsdiss_col', axes(1:2), Time, & - 'Column integrated large-scale dissipation', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated cloud fraction tendency from dissipation',& + 'kg/m2/sec', missing_value=missing_value) diag_id%qa_rhred_col = register_diag_field (mod_name, & 'qa_rhred_col', axes(1:2), Time, & - 'Column integrated RH reduction', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated cloud fraction tendency from RH limiter', & + 'kg/m2/sec', missing_value=missing_value) diag_id%qa_eros_col = register_diag_field (mod_name, & 'qa_eros_col', axes(1:2), Time, & - 'Column integrated cloud fraction erosion', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated cloud fraction tendency from erosion', & + 'kg/m2/sec', missing_value=missing_value) diag_id%qa_fill_col = register_diag_field (mod_name, & 'qa_fill_col', axes(1:2), Time, & - 'Column integrated cloud fraction filler', 'kg/m2/sec', & - missing_value=missing_value) + 'Column integrated cloud fraction tendency from filler', & + 'kg/m2/sec', missing_value=missing_value) diag_id%qa_super_col = register_diag_field (mod_name, & 'qa_super_col', axes(1:2), Time, & - 'Column integrated cld fraction supersaturation formation', & - 'kg/m2/sec', & + 'Column integrated cloud fraction tendency from & + &supersaturation removal', 'kg/m2/sec', & missing_value=missing_value) diag_id%qa_destr_col = register_diag_field (mod_name, & 'qa_destr_col', axes(1:2), Time, & - 'Column integrated cloud fraction destruction', 'kg/m2/sec', & + 'Column integrated cloud fraction tendency from destruction',& + 'kg/m2/sec', missing_value=missing_value) + diag_id%qa_limits_col = register_diag_field (mod_name, & + 'qa_limits_col', axes(1:2), Time, & + 'Column integrated cloud fraction tendency from limits & + &imposition', 'kg/m2/sec', missing_value=missing_value) + diag_id%qa_ahuco_col = register_diag_field (mod_name, & + 'qa_ahuco_col', axes(1:2), Time, & + 'Column integrated cloud fraction tendency from conv & + &area restriction', 'kg/m2/sec', & + missing_value=missing_value) + +!------------------------------------------------------------------------ +! 16) variables added by h1g with ncar M-G microphysics +!------------------------------------------------------------------------ + diag_id%SA2d = register_diag_field ( mod_name, & + 'SA2d', axes(1:2), Time, & + 'column integrated total cld fraction tendency', & + ' kg/ (m2 sec)', missing_value=missing_value) + diag_id%ST2d = register_diag_field ( mod_name, & + 'ST2d', axes(1:2), Time, & + 'column integrated total temperature tendency', & + 'K kg/ (m2 sec)', missing_value=missing_value) + diag_id%SQ2d = register_diag_field ( mod_name, & + 'SQ2d', axes(1:2), Time, & + 'Column integrated total Water vapor specific & + &humidity tendency ', 'kg/m2/sec', & + missing_value=missing_value) + diag_id%SL2d = register_diag_field ( mod_name, & + 'SL2d', axes(1:2), Time, & + 'Column integrated total Liquid Water specific humidity', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%SI2d = register_diag_field ( mod_name, & + 'SI2d', axes(1:2), Time, & + 'column integrated total Ice water specific humidity & + &tendency ', 'kg/m2/sec', missing_value=missing_value) + diag_id%SN2d = register_diag_field ( mod_name, & + 'SN2d', axes(1:2), Time, & + 'Column integrated total cloud drop number tendency', & + '#/m2/sec', missing_value=missing_value) + diag_id%SNI2d = register_diag_field ( mod_name, & + 'SNI2d', axes(1:2), Time, & + 'Column integrated total ice crystal number tendency', & + '#/m2/sec', missing_value=missing_value) + diag_id%srfrain_accrs_col= register_diag_field ( mod_name, & + 'srfrain_accrs_col', axes(1:2), Time, & + 'Column integrated rain water sink from collection by snow', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%srfrain_freez_col= register_diag_field ( mod_name, & + 'srfrain_freez_col', axes(1:2), Time, & + 'Column integrated rain water sink from freezing', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%srfrain_evap_col= register_diag_field ( mod_name, & + 'srfrain_evap_col', axes(1:2), Time, & + 'Column integrated rain water sink from evaporation', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%snow_mass_conv = register_diag_field ( mod_name, & + 'snow_mass_conv', axes(1:2), Time, & + 'Change necessary to surface snowfall to ensure h2o & + & balance in column', 'kg/m2/sec', & + missing_value=missing_value) + diag_id%neg_snow = register_diag_field ( mod_name, & + 'neg_snow', axes(1:2), Time, & + 'magnitude of negative snow removed in column', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%rain_mass_conv = register_diag_field ( mod_name, & + 'rain_mass_conv', axes(1:2), Time, & + 'Change necessary to surface rainfall to ensure h2o& + & balance in column', 'kg/m2/sec', & + missing_value=missing_value) + diag_id%neg_rain = register_diag_field ( mod_name, & + 'neg_rain', axes(1:2), Time, & + 'magnitude of negative rain removed in column', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_liquid_init_col = register_diag_field ( mod_name, & + 'q_liquid_init_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from initial adjustment of liquid cloud', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_ice_init_col = register_diag_field ( mod_name, & + 'q_ice_init_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from initial adjustment of ice cloud', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_rain_evap_col = register_diag_field ( mod_name, & + 'q_rain_evap_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from rain evaporation', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_cond_col = register_diag_field ( mod_name, & + 'q_cond_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from condensation of vapor', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_deposition_col = register_diag_field ( mod_name, & + 'q_deposition_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from deposition of vapor onto ice', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_eros_l_col = register_diag_field ( mod_name, & + 'q_eros_l_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from erosion of liquid cloud', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_eros_i_col = register_diag_field ( mod_name, & + 'q_eros_i_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from erosion of ice cloud', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_qv_on_qi_col = register_diag_field ( mod_name, & + 'q_qv_on_qi_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from direct deposition on ice', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_sedi_ice2vapor_col = register_diag_field ( mod_name, & + 'q_sedi_ice2vapor_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from the sublimation of falling cloud ice', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_sedi_liquid2vapor_col = register_diag_field ( mod_name, & + 'q_sedi_liquid2vapor_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from the evaporation of falling cloud liquid', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_super_sat_rm_col = register_diag_field ( mod_name, & + 'q_super_sat_rm_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from removal of supersaturation', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_destr_col = register_diag_field ( mod_name, & + 'q_destr_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from cloud destruction', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_cleanup_liquid_col = register_diag_field ( mod_name, & + 'q_cleanup_liquid_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from cleaning up liquid cloud', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_cleanup_ice_col = register_diag_field ( mod_name, & + 'q_cleanup_ice_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from cleaning up ice cloud', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_snow_sublim_col = register_diag_field ( mod_name, & + 'q_snow_sublim_col', axes(1:2), Time, & + 'Column integrated Water vapor specific humidity tendency & + &from sublimation of snow', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%q_snow2vapor_col = register_diag_field ( mod_name, & + 'q_snow2vapor_col', axes(1:2), Time, & + 'Column integrated water vapor specific humidity tendency & + &from condensation resulting from cooling of the air & + &by melting snow', 'kg/m2/sec', missing_value=missing_value) + diag_id%ql_HM_splinter_col = register_diag_field ( mod_name, & + 'ql_HM_splinter_col', axes(1:2), Time, & + 'Column integrated liquid water specific humidity tendency & + &from H-M splintering ', 'kg/m2/sec', & missing_value=missing_value) +!------------------------------------------------------------------------ +! 17) variables associated with budget analysis +!------------------------------------------------------------------------ + diag_id%SA_imb_col = register_diag_field ( mod_name, & + 'SA_imb_col', axes(1:2), Time, & + 'difference between column-integrated qa tendency and & + &sum of individ terms', 'kg/ (m2 sec)', & + missing_value=missing_value) + diag_id%ST_imb_col = register_diag_field ( mod_name, & + 'ST_imb_col', axes(1:2), Time, & + 'difference between column-integrated temp tendency and & + &sum of individ terms', 'K kg/(m2 sec)', & + missing_value=missing_value) + diag_id%SQ_imb_col = register_diag_field ( mod_name, & + 'SQ_imb_col', axes(1:2), Time, & + 'difference between column-integrated qv tendency and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%SL_imb_col = register_diag_field ( mod_name, & + 'SL_imb_col', axes(1:2), Time, & + 'difference between column-integrated ql tendency and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%SI_imb_col = register_diag_field ( mod_name, & + 'SI_imb_col', axes(1:2), Time, & + 'difference between column-integrated qi tendency and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%SN_imb_col = register_diag_field ( mod_name, & + 'SN_imb_col', axes(1:2), Time, & + 'difference between column-integrated qn tendency and & + &sum of individ terms', & + '#/m2/sec', missing_value=missing_value) + diag_id%SNi_imb_col = register_diag_field ( mod_name, & + 'SNi_imb_col', axes(1:2), Time, & + 'difference between column-integrated qni tendency and & + &sum of individ terms', & + '#/m2/sec', missing_value=missing_value) + diag_id%rain_imb_col = register_diag_field ( mod_name, & + 'rain_imb_col', axes(1:2), Time, & + 'difference between column-integrated rainfall rate and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%cld_liq_imb_col = register_diag_field ( mod_name, & + 'cld_liq_imb_col', axes(1:2), Time, & + 'difference between column-integrated ql fallout rate and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%snow_imb_col = register_diag_field ( mod_name, & + 'snow_imb_col', axes(1:2), Time, & + 'difference between column-integrated snowfall rate and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + diag_id%cld_ice_imb_col = register_diag_field ( mod_name, & + 'cld_ice_imb_col', axes(1:2), Time, & + 'difference between column-integrated qi fallout rate and & + &sum of individ terms', & + 'kg/m2/sec', missing_value=missing_value) + +!----------------------------------------------------------------------- +! 17) variables associated with ice particle number time tendency: +!----------------------------------------------------------------------- + diag_id%qni_fill_col = register_diag_field (mod_name, & + 'qni_fill_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from filler',& + '#/m2/sec', missing_value=missing_value) + diag_id%qni_nnuccd_col = register_diag_field (mod_name, & + 'qni_nnuccd_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &nucleation', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nsubi_col = register_diag_field (mod_name, & + 'qni_nsubi_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &sublimation', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nerosi_col = register_diag_field (mod_name, & + 'qni_nerosi_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &erosion', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nprci_col = register_diag_field (mod_name, & + 'qni_nprci_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &autoconversion', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nprai_col = register_diag_field (mod_name, & + 'qni_nprai_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &accretion by snow', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nucclim1_col = register_diag_field (mod_name, & + 'qni_nucclim1_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from first & + &nucleation limiter', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nucclim2_col = register_diag_field (mod_name, & + 'qni_nucclim2_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from second & + &nucleation limiter','#/m2/sec', missing_value=missing_value) + diag_id%qni_sedi_col = register_diag_field (mod_name, & + 'qni_sedi_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &sedimentation', '#/m2/sec', missing_value=missing_value) + diag_id%qni_melt_col = register_diag_field (mod_name, & + 'qni_melt_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &melting', '#/m2/sec', missing_value=missing_value) + diag_id%qni_size_adj_col = register_diag_field (mod_name, & + 'qni_size_adj_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from size & + &adjustment', '#/m2/sec', missing_value=missing_value) + diag_id%qni_fill2_col = register_diag_field (mod_name, & + 'qni_fill2_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from second & + &filler', '#/m2/sec', missing_value=missing_value) + diag_id%qni_super_col = register_diag_field (mod_name, & + 'qni_super_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &removal of supersaturation', '#/m2/sec', & + missing_value=missing_value) + diag_id%qni_ihom_col = register_diag_field (mod_name, & + 'qni_ihom_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &homogeneous freezing', '#/m2/sec', & + missing_value=missing_value) + diag_id%qni_destr_col = register_diag_field (mod_name, & + 'qni_destr_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from cloud & + &destruction', '#/m2/sec', missing_value=missing_value) + diag_id%qni_cleanup_col = register_diag_field (mod_name, & + 'qni_cleanup_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &cleanup', '#/m2/sec', missing_value=missing_value) + diag_id%qni_cleanup2_col = register_diag_field (mod_name, & + 'qni_cleanup2_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from & + &cleanup2', '#/m2/sec', missing_value=missing_value) + diag_id%qni_nsacwi_col = register_diag_field (mod_name, & + 'qni_nsacwi_col', axes(1:2), Time, & + 'Column integrated ice particle number tendency from HM & + &ice multiplication', '#/m2/sec', missing_value=missing_value) + !------------------------------------------------------------------------ ! determine the number of activated diagnostic variables on both ! full and half levels in the vertical. thesde values will be used @@ -1674,16 +2601,12 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%droplets_wtd = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%droplets_s > 0) then - diag_pt%droplets_s = n_diag_4d - n_diag_4d = n_diag_4d + 1 - end if if (diag_id%rvolume > 0 ) then diag_pt%rvolume = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%droplets_col_s > 0) then - diag_pt%droplets_col_s = n_diag_4d + if (diag_id%droplets_col > 0) then + diag_pt%droplets_col = n_diag_4d n_diag_4d = n_diag_4d + 1 end if if (diag_id%droplets_col250 > 0) then @@ -1694,10 +2617,6 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%gb_droplets_col = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%droplets_col > 0) then - diag_pt%droplets_col = n_diag_4d - n_diag_4d = n_diag_4d + 1 - end if !------------------------------------------------------------------------ ! 2) variables associated with cloud liquid content: @@ -1718,46 +2637,50 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%dcond = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%autocv > 0) then - diag_pt%autocv = n_diag_4d + if (diag_id%aauto > 0) then + diag_pt%aauto = n_diag_4d n_diag_4d = n_diag_4d + 1 end if if (diag_id%vfall > 0) then diag_pt%vfall = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%tmp5_3d > 0 ) then - diag_pt%tmp5_3d = n_diag_4d + if (diag_id%delta_cf > 0 ) then + diag_pt%delta_cf = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%debug1_3d > 0 ) then - diag_pt%debug1_3d = n_diag_4d + if (diag_id%cf_liq_init > 0 ) then + diag_pt%cf_liq_init = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%debug2_3d > 0 ) then - diag_pt%debug2_3d = n_diag_4d + if (diag_id%subgrid_w_variance > 0 ) then + diag_pt%subgrid_w_variance = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%debug3_3d > 0 ) then - diag_pt%debug3_3d = n_diag_4d + if (diag_id%potential_droplets > 0 ) then + diag_pt%potential_droplets = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%debug4_3d > 0 ) then - diag_pt%debug4_3d = n_diag_4d + if (diag_id%potential_crystals > 0 ) then + diag_pt%potential_crystals = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%debug5_3d > 0 ) then - diag_pt%debug5_3d = n_diag_4d + if (diag_id%dust_berg_flag > 0 ) then + diag_pt%dust_berg_flag = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%snow_subl + diag_id%snow_subl_col > 0) then - diag_pt%snow_subl = n_diag_4d + if (diag_id%cf_ice_init > 0 ) then + diag_pt%cf_ice_init = n_diag_4d n_diag_4d = n_diag_4d + 1 end if if (diag_id%snow_melt + diag_id%snow_melt_col > 0) then diag_pt%snow_melt = n_diag_4d n_diag_4d = n_diag_4d + 1 end if + if (diag_id%rain_freeze + diag_id%rain_freeze_col > 0) then + diag_pt%rain_freeze = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if !------------------------------------------------------------------------ ! 4) variables associated with model convection: @@ -1790,11 +2713,11 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & !------------------------------------------------------------------------ ! 6) variables associated with precipitation and precipitation area: !------------------------------------------------------------------------ - if (diag_id%qrout > 0) then + if (diag_id%qrout + diag_id%qrout_col > 0) then diag_pt%qrout = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qsout > 0) then + if (diag_id%qsout + diag_id%qsout_col > 0) then diag_pt%qsout = n_diag_4d n_diag_4d = n_diag_4d + 1 end if @@ -1925,6 +2848,10 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%qldt_sedi = n_diag_4d n_diag_4d = n_diag_4d + 1 end if + if (diag_id%sedi_sfc > 0) then + diag_pt%sedi_sfc = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if if (diag_id%qldt_accrs + diag_id%ql_accrs_col > 0) then diag_pt%qldt_accrs = n_diag_4d n_diag_4d = n_diag_4d + 1 @@ -1946,7 +2873,7 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & n_diag_4d = n_diag_4d + 1 end if if (diag_id%qndt_fill + diag_id%qn_fill_col + & - diag_id%qldt_fill > 0) then + diag_id%qldt_fill + diag_id%ql_fill_col > 0) then diag_pt%qndt_fill = n_diag_4d n_diag_4d = n_diag_4d + 1 end if @@ -2015,70 +2942,74 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & !----------------------------------------------------------------------- ! 10) variables associated with ice particle number time tendency: !----------------------------------------------------------------------- - if (diag_id%qnidt_fill > 0) then + if (diag_id%qnidt_fill + diag_id%qni_fill_col > 0) then diag_pt%qnidt_fill = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nnuccd > 0) then + if (diag_id%qnidt_nnuccd + diag_id%qni_nnuccd_col > 0) then diag_pt%qnidt_nnuccd = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nsubi > 0) then + if (diag_id%qnidt_nsubi + diag_id%qni_nsubi_col > 0) then diag_pt%qnidt_nsubi = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nerosi > 0) then + if (diag_id%qnidt_nerosi + diag_id%qni_nerosi_col > 0) then diag_pt%qnidt_nerosi = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nprci > 0) then + if (diag_id%qnidt_nprci + diag_id%qni_nprci_col > 0) then diag_pt%qnidt_nprci = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nprai> 0) then + if (diag_id%qnidt_nprai + diag_id%qni_nprai_col > 0) then diag_pt%qnidt_nprai = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nucclim1 > 0) then + if (diag_id%qnidt_nucclim1 + diag_id%qni_nucclim1_col > 0) then diag_pt%qnidt_nucclim1 = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_nucclim2 > 0) then + if (diag_id%qnidt_nucclim2 + diag_id%qni_nucclim2_col > 0) then diag_pt%qnidt_nucclim2 = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_sedi > 0) then + if (diag_id%qnidt_sedi + diag_id%qni_sedi_col > 0) then diag_pt%qnidt_sedi = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_melt > 0) then + if (diag_id%qnidt_melt + diag_id%qni_melt_col > 0) then diag_pt%qnidt_melt = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_size_adj > 0) then + if (diag_id%qnidt_size_adj + diag_id%qni_size_adj_col > 0) then diag_pt%qnidt_size_adj = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_fill2 > 0) then + if (diag_id%qnidt_fill2 + diag_id%qni_fill2_col > 0) then diag_pt%qnidt_fill2 = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_super > 0) then + if (diag_id%qnidt_super + diag_id%qni_super_col > 0) then diag_pt%qnidt_super = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_ihom > 0) then + if (diag_id%qnidt_ihom + diag_id%qni_ihom_col > 0) then diag_pt%qnidt_ihom = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_destr > 0) then + if (diag_id%qnidt_destr + diag_id%qni_destr_col > 0) then diag_pt%qnidt_destr = n_diag_4d n_diag_4d = n_diag_4d + 1 end if - if (diag_id%qnidt_cleanup > 0) then + if (diag_id%qnidt_cleanup + diag_id%qni_cleanup_col > 0) then diag_pt%qnidt_cleanup = n_diag_4d n_diag_4d = n_diag_4d + 1 end if + if (diag_id%qnidt_cleanup2 + diag_id%qni_cleanup2_col > 0) then + diag_pt%qnidt_cleanup2 = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if !----------------------------------------------------------------------- ! 11) variables associated with relative humidity: @@ -2179,6 +3110,10 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%qidt_eros = n_diag_4d n_diag_4d = n_diag_4d + 1 end if + if (diag_id%sedi_ice > 0) then + diag_pt%sedi_ice = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if if (diag_id%qidt_fall + diag_id%qi_fall_col > 0) then diag_pt%qidt_fall = n_diag_4d n_diag_4d = n_diag_4d + 1 @@ -2187,6 +3122,10 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%qidt_melt = n_diag_4d n_diag_4d = n_diag_4d + 1 end if + if (diag_id%qidt_melt2 + diag_id%qi_melt2_col > 0) then + diag_pt%qidt_melt2 = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if if (diag_id%qidt_destr + diag_id%qi_destr_col > 0) then diag_pt%qidt_destr = n_diag_4d n_diag_4d = n_diag_4d + 1 @@ -2243,7 +3182,209 @@ subroutine diag_field_init (axes, Time, diag_id, diag_pt, n_diag_4d, & diag_pt%qadt_destr = n_diag_4d n_diag_4d = n_diag_4d + 1 end if + if (diag_id%qadt_limits + diag_id%qa_limits_col > 0) then + diag_pt%qadt_limits = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qadt_ahuco + diag_id%qa_ahuco_col > 0) then + diag_pt%qadt_ahuco = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if +!REV#9 +!------------------------------------------------------------------------ +! 16) variables added by h1g with ncar M-G microphysics +!------------------------------------------------------------------------ + if (diag_id%SA3d + diag_id%SA2d > 0) then + diag_pt%SA3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%ST3d + diag_id%ST2d > 0) then + diag_pt%ST3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SQ3d + diag_id%SQ2d > 0) then + diag_pt%SQ3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SL3d + diag_id%SL2d > 0) then + diag_pt%SL3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SI3d + diag_id%SI2d > 0) then + diag_pt%SI3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SN3d + diag_id%SN2d > 0) then + diag_pt%SN3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SNI3d + diag_id%SNI2d > 0) then + diag_pt%SNI3d = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qndt_contact_frz + diag_id%qn_contact_frz_col > 0) then + diag_pt%qndt_contact_frz = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qndt_cleanup + diag_id%qn_cleanup_col > 0) then + diag_pt%qndt_cleanup = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qndt_cleanup2 + diag_id%qn_cleanup2_col > 0) then + diag_pt%qndt_cleanup2 = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qnidt_nsacwi + diag_id%qni_nsacwi_col > 0) then + diag_pt%qnidt_nsacwi = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_liquid_init + diag_id%q_liquid_init_col > 0) then + diag_pt%qdt_liquid_init = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_ice_init + diag_id%q_ice_init_col > 0) then + diag_pt%qdt_ice_init = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_rain_evap + diag_id%q_rain_evap_col > 0) then + diag_pt%qdt_rain_evap = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_cond + diag_id%q_cond_col > 0) then + diag_pt%qdt_cond = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_deposition + diag_id%q_deposition_col > 0) then + diag_pt%qdt_deposition = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_eros_l + diag_id%q_eros_l_col > 0) then + diag_pt%qdt_eros_l = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_eros_i + diag_id%q_eros_i_col > 0) then + diag_pt%qdt_eros_i = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_qv_on_qi + diag_id%q_qv_on_qi_col > 0) then + diag_pt%qdt_qv_on_qi = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_sedi_ice2vapor + & + diag_id%q_sedi_ice2vapor_col > 0) then + diag_pt%qdt_sedi_ice2vapor = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_sedi_liquid2vapor + & + diag_id%q_sedi_liquid2vapor_col > 0) then + diag_pt%qdt_sedi_liquid2vapor = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_super_sat_rm + diag_id%q_super_sat_rm_col > 0) then + diag_pt%qdt_super_sat_rm = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_destr + diag_id%q_destr_col > 0) then + diag_pt%qdt_destr = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_cleanup_liquid + & + diag_id%q_cleanup_liquid_col > 0) then + diag_pt%qdt_cleanup_liquid = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_cleanup_ice + diag_id%q_cleanup_ice_col > 0) then + diag_pt%qdt_cleanup_ice = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%srfrain_evap + diag_id%srfrain_evap_col > 0) then + diag_pt%srfrain_evap = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%rain_mass_conv > 0) then + diag_pt%rain_mass_conv = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%neg_rain > 0) then + diag_pt%neg_rain = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%snow_mass_conv > 0) then + diag_pt%snow_mass_conv = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%neg_snow > 0) then + diag_pt%neg_snow = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_snow_sublim + diag_id%q_snow_sublim_col > 0) then + diag_pt%qdt_snow_sublim = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qdt_snow2vapor + diag_id%q_snow2vapor_col > 0) then + diag_pt%qdt_snow2vapor = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%srfrain_accrs + diag_id%srfrain_accrs_col > 0) then + diag_pt%srfrain_accrs = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%srfrain_freez + diag_id%srfrain_freez_col > 0) then + diag_pt%srfrain_freez = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%qldt_HM_splinter + diag_id%ql_HM_splinter_col > 0) then + diag_pt%qldt_HM_splinter = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if +!------------------------------------------------------------------------ +! 17) variables associated with budget analysis +!------------------------------------------------------------------------ + if (diag_id%SA_imb + diag_id%SA_imb_col > 0) then + diag_pt%SA_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%ST_imb + diag_id%ST_imb_col > 0) then + diag_pt%ST_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SQ_imb + diag_id%SQ_imb_col > 0) then + diag_pt%SQ_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SL_imb + diag_id%SL_imb_col > 0) then + diag_pt%SL_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SI_imb + diag_id%SI_imb_col > 0) then + diag_pt%SI_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SN_imb + diag_id%SN_imb_col > 0) then + diag_pt%SN_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%SNi_imb + diag_id%SNi_imb_col > 0) then + diag_pt%SNi_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%rain_imb + diag_id%rain_imb_col > 0) then + diag_pt%rain_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%cld_liq_imb + diag_id%cld_liq_imb_col > 0) then + diag_pt%cld_liq_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%snow_imb + diag_id%snow_imb_col > 0) then + diag_pt%snow_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if + if (diag_id%cld_ice_imb + diag_id%cld_ice_imb_col > 0) then + diag_pt%cld_ice_imb = n_diag_4d + n_diag_4d = n_diag_4d + 1 + end if !---------------------------------------------------------------------- diff --git a/src/atmos_param/strat_cloud/strat_nml.h b/src/atmos_param/strat_cloud/strat_nml.h index 816fd94d74..3decb167aa 100644 --- a/src/atmos_param/strat_cloud/strat_nml.h +++ b/src/atmos_param/strat_cloud/strat_nml.h @@ -1,5 +1,5 @@ -! $Id: strat_nml.h,v 19.0 2012/01/06 20:27:25 fms Exp $ -! $Name: siena_201207 $ +! $Id: strat_nml.h,v 20.0 2013/12/13 23:22:19 fms Exp $ +! $Name: tikal $ !------------------------------------------------------------------------ !---namelist------ @@ -101,6 +101,30 @@ ! the microphysics scheme being used (currently either ! "morrison_gettelman" or "rotstayn_klein") ! +! +! the macrophysics scheme being used (currently either +! "tiedtke" or " ") +! +! +! the aerosol activation scheme being used (currently either +! "dqa" or "total") +! +! +! should we use ensure water mass conservation by adjusting precip to +! balance column water mass change ? +! +! +! should all potentially available ice particles be activated under all +! conditions ? (or only when dqa is increasing) +! +! +! the hallet-mossop process should be included in the NCAR microphysics? +! +! +! the minor bug present in CM3, in which several small terms in qv and +! temp equations were retained while corresponding terms in ql and qi +! were not, is retained? +! ! ! flag to indicate how to treat supersaturation; 0 => don't allow. ! @@ -225,6 +249,12 @@ INTEGER, PARAMETER :: max_strat_pts = 5 real :: num_mass_ratio1= 1. real :: num_mass_ratio2= 1. character(len=64) :: microphys_scheme = 'rotstayn_klein' + character(len=64) :: macrophys_scheme = 'tiedtke' + character(len=64) :: aerosol_activation_scheme = 'dqa' + logical :: mass_cons = .true. + logical :: activate_all_ice_always= .true. + logical :: do_hallet_mossop = .false. + logical :: retain_cm3_bug = .false. integer :: super_ice_opt = 0 logical :: do_ice_nucl_wpdf = .false. @@ -253,6 +283,10 @@ INTEGER, PARAMETER :: max_strat_pts = 5 integer :: isamp = 1 integer :: jsamp = 1 integer :: ksamp = 1 + +! 1 / relative variance of sub-grid cloud water distribution +! see morrison and gettelman, 2007, J. Climate for details + real :: qcvar = 2. namelist / strat_cloud_nml / & @@ -261,13 +295,17 @@ namelist / strat_cloud_nml / & mc_thresh, diff_thresh, super_choice, tracer_advec, qmin, Dmin, & efact, vfact, cfact, do_old_snowmelt, iwc_crit, vfall_const2, & vfall_exp2, num_mass_ratio1, num_mass_ratio2, & - microphys_scheme, super_ice_opt, do_ice_nucl_wpdf, & + microphys_scheme, macrophys_scheme, aerosol_activation_scheme, & + mass_cons, activate_all_ice_always, do_hallet_mossop, & + retain_cm3_bug, super_ice_opt, do_ice_nucl_wpdf, & use_online_aerosol, use_sub_seasalt, sea_salt_scale, om_to_oc, & N_land, N_ocean, var_limit, do_liq_num, do_dust_berg, N_min, & do_pdf_clouds, betaP, qthalfwidth, nsublevels, kmap, kord, pdf_org, & - num_strat_pts, strat_pts, debugo, isamp, jsamp, ksamp + num_strat_pts, strat_pts, debugo, isamp, jsamp, ksamp, & + + qcvar diff --git a/src/atmos_param/topo_drag/null/topo_drag.F90 b/src/atmos_param/topo_drag/null/topo_drag.F90 deleted file mode 100644 index 055f670847..0000000000 --- a/src/atmos_param/topo_drag/null/topo_drag.F90 +++ /dev/null @@ -1,128 +0,0 @@ -module topo_drag_mod - -!========================================================================== -! TOPOGRAPHIC DRAG CLOSURE FOR GENERAL CIRCULATION MODELS -- Garner (2005) -!========================================================================== - -!-------------------------------------------------------------------------- -! Calculates horizontal velocity tendency due to topographic drag -!-------------------------------------------------------------------------- - - use Fms_Mod, only: ERROR_MESG, FATAL, & - mpp_pe, mpp_root_pe, & - write_version_number, stdlog - - implicit none - - private - - character(len=128) :: version = '$Id: topo_drag.F90,v 17.0 2009/07/21 02:58:21 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' - logical :: module_is_initialized = .false. - - public topo_drag, topo_drag_init, topo_drag_end - public topo_drag_restart - -contains - -!############################################################################# -subroutine topo_drag & - ( is, js, delt, uwnd, vwnd, atmp, & - pfull, phalf, zfull, zhalf, & - dtaux, dtauy, dtemp, taux, tauy, taus, kbot ) - -integer, intent(in) :: is, js -real, intent(in) :: delt -integer, intent(in), optional, dimension(:,:) :: kbot - -! INPUT -! ----- - -! UWND Zonal wind (dimensioned IDIM x JDIM x KDIM) -! VWND Meridional wind (dimensioned IDIM x JDIM x KDIM) -! ATMP Temperature at full levels (IDIM x JDIM x KDIM) -! PFULL Pressure at full levels (IDIM x JDIM x KDIM) -! PHALF Pressure at half levels (IDIM x JDIM x KDIM+1) -! ZFULL Height at full levels (IDIM x JDIM x KDIM) -! ZHALF Height at half levels (IDIM x JDIM x KDIM+1) - -real, intent(in), dimension(:,:,:) :: uwnd, vwnd, atmp -real, intent(in), dimension(:,:,:) :: pfull, phalf, zfull, zhalf - - -! OUTPUT -! ------ - - -! DTAUX,DTAUY Tendency of the vector wind in m/s^2 (IDIM x JDIM x KDIM) -! DTEMP Tendency of the temperature in K/s (IDIM x JDIM x KDIM) -! TAUX,TAUY Base momentum flux in kg/m/s^2 (IDIM x JDIM) for diagnostics -! TAUS clipped saturation momentum flux (IDIM x JDIM x KDIM) for diagnostics - -real, intent(out), dimension(:,:) :: taux, tauy -real, intent(out), dimension(:,:,:) :: dtaux, dtauy, dtemp, taus - - - -!--------------------------------------------------------------------- - - call error_mesg('topo_drag', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine topo_drag - - !===================================================================== - - subroutine topo_drag_init(lonb,latb) - - real, intent(in), dimension(:,:) :: lonb,latb - - -!------- write version number and namelist --------- - - if ( mpp_pe() == mpp_root_pe() ) then - call write_version_number(version, tagname) - endif - - module_is_initialized = .true. - -!--------------------------------------------------------------------- - - call error_mesg('topo_drag_init', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine topo_drag_init - - !===================================================================== - - subroutine topo_drag_end - - module_is_initialized = .false. - -!--------------------------------------------------------------------- - - call error_mesg('topo_drag_end', & - 'This module is not supported as part of the public release', FATAL) - - end subroutine topo_drag_end - -!############################################################################# - -!####################################################################### -! -! -! - -end module topo_drag_mod diff --git a/src/atmos_param/topo_drag/topo_drag.F90 b/src/atmos_param/topo_drag/topo_drag.F90 index 664f85c4d5..17217b1964 100644 --- a/src/atmos_param/topo_drag/topo_drag.F90 +++ b/src/atmos_param/topo_drag/topo_drag.F90 @@ -25,7 +25,7 @@ module topo_drag_mod private character(len=128) :: version = '$Id: topo_drag.F90,v 19.0 2012/01/06 20:27:27 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_param/vert_diff/vert_diff.F90 b/src/atmos_param/vert_diff/vert_diff.F90 index 8f34eabf73..38b97f46e7 100644 --- a/src/atmos_param/vert_diff/vert_diff.F90 +++ b/src/atmos_param/vert_diff/vert_diff.F90 @@ -54,13 +54,20 @@ module vert_diff_mod end type surf_diff_type -real, allocatable, dimension(:,:,:) :: e_global, f_t_global, f_q_global +real, allocatable, dimension(:,:,:) :: e_global, f_t_global, f_q_global +!-->cjg +real, allocatable, dimension(:,:,:) :: e_clubb +!<--cjg ! storage compartment for tracer vert. diffusion options, and for f ! coefficient if necessary type :: tracer_data_type real, pointer :: f(:,:,:) => NULL() ! f coefficient field logical :: do_vert_diff +!-->cjg: flag for tracers that should be diffused with diff_t_clubb instead of diff_t +! i.e. all tracers except sphum, liq_wat, ice_wat, cld_amt, liq_drp, ice_num + logical :: do_clubb_diff +!<--cjg logical :: do_surf_exch end type tracer_data_type ! tracer diffusion options and storage for f coefficients @@ -70,11 +77,15 @@ module vert_diff_mod logical :: do_conserve_energy = .true. logical :: use_virtual_temp_vert_diff, do_mcm_plev integer :: sphum, mix_rat +!-->cjg +integer :: do_clubb +integer :: liq_wat, ice_wat, cld_amt, liq_drp, ice_num +!<--cjg !--------------------- version number --------------------------------- -character(len=128) :: version = '$Id: vert_diff.F90,v 19.0 2012/01/06 20:27:29 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: vert_diff.F90,v 20.0 2013/12/13 23:22:25 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. real, parameter :: d608 = (RVGAS-RDGAS)/RDGAS @@ -86,13 +97,16 @@ module vert_diff_mod subroutine vert_diff_init (Tri_surf, idim, jdim, kdim, & do_conserve_energy_in, & use_virtual_temp_vert_diff_in, & - do_mcm_plev_in ) + do_mcm_plev_in, do_clubb_in ) !cjg type(surf_diff_type), intent(inout) :: Tri_surf integer, intent(in) :: idim, jdim, kdim logical, intent(in) :: do_conserve_energy_in logical, optional, intent(in) :: use_virtual_temp_vert_diff_in logical, optional, intent(in) :: do_mcm_plev_in +!-->cjg + integer, optional, intent(in) :: do_clubb_in +!<--cjg integer :: ntprog ! number of prognostic tracers in the atmosphere character(len=32) :: tr_name ! tracer name @@ -120,6 +134,20 @@ subroutine vert_diff_init (Tri_surf, idim, jdim, kdim, & if(sphum==NO_TRACER) sphum=mix_rat +!-->cjg + if (present(do_clubb_in)) then + do_clubb = do_clubb_in + else + do_clubb = 0 + endif + + liq_wat = get_tracer_index( MODEL_ATMOS, 'liq_wat') + ice_wat = get_tracer_index( MODEL_ATMOS, 'ice_wat') + cld_amt = get_tracer_index( MODEL_ATMOS, 'cld_amt') + liq_drp = get_tracer_index( MODEL_ATMOS, 'liq_drp') + ice_num = get_tracer_index( MODEL_ATMOS, 'ice_num') +!<--cjg + if(present(use_virtual_temp_vert_diff_in)) then use_virtual_temp_vert_diff = use_virtual_temp_vert_diff_in else @@ -141,6 +169,13 @@ subroutine vert_diff_init (Tri_surf, idim, jdim, kdim, & allocate(f_t_global (idim, jdim, kdim-1)) ; f_t_global = 0.0 allocate(f_q_global (idim, jdim, kdim-1)) ; f_q_global = 0.0 +!-->cjg + if (do_clubb > 0) then + if (allocated( e_clubb )) deallocate ( e_clubb ) + allocate( e_clubb (idim, jdim, kdim-1)) ; e_clubb = 0.0 + end if +!<--cjg + module_is_initialized = .true. endif @@ -157,6 +192,17 @@ subroutine vert_diff_init (Tri_surf, idim, jdim, kdim, & if (query_method('diff_vert',MODEL_ATMOS,n,scheme)) then tracers(n)%do_vert_diff = (uppercase(scheme) /= 'NONE') endif + + !-->cjg: if clubb is activated, any tracer except should use do_clubb_diff + if (do_clubb > 0 .and. (n/=sphum .and. n/=liq_wat .and. n/=ice_wat .and. & + n/=cld_amt .and. n/=liq_drp .and. n/=ice_num )) then + tracers(n)%do_vert_diff = .false. + tracers(n)%do_clubb_diff = .true. + else + tracers(n)%do_clubb_diff = .false. + endif + !<--cjg + ! do not exchange tracer with surface if it is not present in either land or ! ice model if (n==sphum) then @@ -251,8 +297,7 @@ subroutine gcm_vert_diff_down (is, js, delt, & dtau_du, dtau_dv, & dt_u, dt_v, dt_t, dt_q, dt_tr, & dissipative_heat, Tri_surf, & - kbot ) - + diff_t_clubb, kbot ) !cjg integer, intent(in) :: is, js real, intent(in) :: delt real, intent(in) , dimension(:,:,:) :: u, v, t, q, & @@ -268,6 +313,9 @@ subroutine gcm_vert_diff_down (is, js, delt, & real, intent(out) , dimension(:,:,:) :: dissipative_heat type(surf_diff_type), intent(inout) :: Tri_surf +!-->cjg +real, intent(in) , dimension(:,:,:), optional :: diff_t_clubb +!<--cjg integer, intent(in) , dimension(:,:), optional :: kbot ! ---- local vars @@ -285,6 +333,13 @@ subroutine gcm_vert_diff_down (is, js, delt, & if(.not. module_is_initialized) call error_mesg ('gcm_vert_diff_down in vert_diff_mod', & 'the initialization routine gcm_vert_diff_init has not been called', & FATAL) + +!-->cjg + if(do_clubb > 0 .and. .not.present(diff_t_clubb)) then + call error_mesg ('gcm_vert_diff_down in vert_diff_mod', & + 'diff_t_clubb must be present when do_clubb > 0', FATAL) + endif +!<--cjg ie = is + size(t,1) -1 je = js + size(t,2) -1 @@ -378,6 +433,64 @@ subroutine gcm_vert_diff_down (is, js, delt, & Tri_surf%delta_u (is:ie,js:je) = delta_u_n Tri_surf%delta_v (is:ie,js:je) = delta_v_n +!--> cjg + ! Perform diffusion for tracers using diff_t_clubb mixing coefficients + if (do_clubb > 0) then + ! recompute nu for a different diffusivity + call compute_nu (diff_t_clubb, p_half, p_full, z_full, t, q, nu) + ! calculate e, the same for all tracers since their diffusivities are + ! the same, and mu_delt_n, nu_n, e_n1 + call compute_e (delt, mu, nu, e, a, b, c, g) + do j = 1,size(mu,2) + do i = 1,size(mu,1) + kb = nlev ; if(present(kbot)) kb=kbot(i,j) + mu_delt_n(i,j) = mu(i,j,kb )*delt + nu_n(i,j) = nu(i,j,kb ) + e_n1(i,j) = e (i,j,kb-1) + enddo + enddo + + do n = 1,ntr + ! calculate f_tr, f_tr_delt_n1, delta_tr_n for this tracer + if(.not.tracers(n)%do_clubb_diff) cycle ! skip non-diffusive tracers + call explicit_tend (mu, nu, tr(:,:,:,n), dt_tr(:,:,:,n)) + call compute_f (dt_tr(:,:,:,n), b, c, g, f_tr) + do j = 1,size(mu,2) + do i = 1,size(mu,1) + kb = nlev ; if(present(kbot)) kb=kbot(i,j) + f_tr_delt_n1(i,j) = f_tr (i,j,kb-1)*delt + delta_tr_n(i,j) = dt_tr(i,j,kb,n)*delt + enddo + enddo + + ! store information needed by flux_exchange module + Tri_surf%delta_tr(is:ie,js:je,n) = & + delta_tr_n(:,:) + mu_delt_n(:,:)*nu_n(:,:)*f_tr_delt_n1(:,:) + Tri_surf%dflux_tr(is:ie,js:je,n) = -nu_n(:,:)*(1.0 - e_n1(:,:)) + + if(tracers(n)%do_surf_exch) then + ! store f for future use on upward sweep + tracers(n)%f(is:ie,js:je,:) = f_tr(:,:,:) + else + ! upward sweep of tridaigonal solver for tracers that do not exchange + ! with surface + flux_tr (:,:) = 0.0 ! surface flux of tracer + dflux_dtr(:,:) = 0.0 ! d(sfc flux)/d(tr atm) + call diff_surface ( & + mu_delt_n(:,:), nu_n(:,:), e_n1(:,:), f_tr_delt_n1(:,:), & + dflux_dtr(:,:), flux_tr(:,:), 1.0, delta_tr_n(:,:) ) + call vert_diff_up ( & + delt, e(:,:,:), f_tr(:,:,:), delta_tr_n(:,:), dt_tr(:,:,:,n), & + kbot ) + endif + enddo + + ! Store e for upward pass + e_clubb = e + + endif +!<--cjg + !----------------------------------------------------------------------- end subroutine gcm_vert_diff_down @@ -438,6 +551,14 @@ subroutine gcm_vert_diff_up (is, js, delt, Tri_surf, dt_t, dt_q, dt_tr, kbot) tracers(n)%f (is:ie,js:je,:) , & Tri_surf%delta_tr (is:ie,js:je,n) , & dt_tr(:,:,:,n), kbot ) +!-->cjg + elseif (tracers(n)%do_clubb_diff.and.tracers(n)%do_surf_exch) then + call vert_diff_up (delt , & + e_clubb (is:ie,js:je,:) , & + tracers(n)%f (is:ie,js:je,:) , & + Tri_surf%delta_tr (is:ie,js:je,n) , & + dt_tr(:,:,:,n), kbot ) +!<--cjg endif enddo diff --git a/src/atmos_param/vert_diff_driver/vert_diff_driver.F90 b/src/atmos_param/vert_diff_driver/vert_diff_driver.F90 index acb40caafb..cbbd0684c4 100644 --- a/src/atmos_param/vert_diff_driver/vert_diff_driver.F90 +++ b/src/atmos_param/vert_diff_driver/vert_diff_driver.F90 @@ -78,8 +78,8 @@ module vert_diff_driver_mod !----------------------------------------------------------------------- !---- version number ---- -character(len=128) :: version = '$Id: vert_diff_driver.F90,v 19.0 2012/01/06 20:27:31 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: vert_diff_driver.F90,v 20.0 2013/12/13 23:22:29 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. @@ -93,7 +93,7 @@ subroutine vert_diff_driver_down (is, js, Time, delt, p_half, p_full, & u, v, t, q, trs, & dtau_du, dtau_dv, tau_x, tau_y, & dt_u, dt_v, dt_t, dt_q, dt_trs, & - Surf_diff, mask, kbot ) + Surf_diff, diff_t_clubb, mask, kbot ) !cjg integer, intent(in) :: is, js type(time_type), intent(in) :: Time @@ -110,6 +110,9 @@ subroutine vert_diff_driver_down (is, js, Time, delt, p_half, p_full, & type(surf_diff_type), intent(inout) :: Surf_diff +!-->cjg +real, intent(in) , dimension(:,:,:), optional :: diff_t_clubb +!<--cjg real , intent(in), dimension(:,:,:), optional :: mask integer, intent(in), dimension(:,:), optional :: kbot @@ -203,11 +206,14 @@ subroutine vert_diff_driver_down (is, js, Time, delt, p_half, p_full, & where (q_2 < 0.0) q_2 = 0.0 endif +!--> cjg call gcm_vert_diff_down (is, js, delt, u, v, tt, q_2, trs(:,:,:,1:ntp), & - diff_mom, diff_heat, p_half, p_full, z_full, & + diff_mom, diff_heat, & + p_half, p_full, z_full, & tau_x, tau_y, dtau_du, dtau_dv, & - dt_u, dt_v, dt_t, dt_q, dt_trs(:,:,:,1:ntp), & - dissipative_heat, Surf_diff, kbot ) + dt_u, dt_v, dt_t, dt_q, dt_trs(:,:,:,1:ntp), & + dissipative_heat, Surf_diff, diff_t_clubb, kbot ) !cjg +!<--cjg !----------------------------------------------------------------------- !----------------------------------------------------------------------- @@ -372,11 +378,14 @@ end subroutine vert_diff_driver_up !####################################################################### subroutine vert_diff_driver_init ( Surf_diff, idim, jdim, kdim, & - axes, Time ) + axes, Time, do_clubb ) !cjg type(surf_diff_type), intent(inout) :: Surf_diff integer , intent(in) :: idim, jdim, kdim, axes(4) type(time_type) , intent(in) :: Time +!-->cjg + integer, intent(in) :: do_clubb +!<--cjg integer :: unit, io, ierr, tr, logunit integer :: ntprog ! number of prognostic tracers in the atmosphere @@ -409,7 +418,7 @@ subroutine vert_diff_driver_init ( Surf_diff, idim, jdim, kdim, & !-------- initialize gcm vertical diffusion ------ call vert_diff_init (Surf_diff, idim, jdim, kdim, do_conserve_energy, & - use_virtual_temp_vert_diff, do_mcm_plev) + use_virtual_temp_vert_diff, do_mcm_plev, do_clubb) !cjg !----------------------------------------------------------------------- diff --git a/src/atmos_param/vert_turb_driver/vert_turb_driver.F90 b/src/atmos_param/vert_turb_driver/vert_turb_driver.F90 index 6917779b10..cebd8d8571 100644 --- a/src/atmos_param/vert_turb_driver/vert_turb_driver.F90 +++ b/src/atmos_param/vert_turb_driver/vert_turb_driver.F90 @@ -60,8 +60,8 @@ module vert_turb_driver_mod !----------------------------------------------------------------------- !--------------------- version number ---------------------------------- -character(len=128) :: version = '$Id: vert_turb_driver.F90,v 19.0 2012/01/06 20:27:33 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: vert_turb_driver.F90,v 20.0 2013/12/13 23:22:34 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !----------------------------------------------------------------------- @@ -95,12 +95,27 @@ module vert_turb_driver_mod ! => 'beljaars' real :: constant_gust = 1.0 real :: gust_factor = 1.0 + +!-->h1g, 2012-07-16 + integer :: do_clubb + integer :: nwp2 + real :: wp2_min = 4.e-4 + real :: diff_min = 1.e-3 ! minimum value of a diffusion + ! coefficient beneath which the + ! coefficient is reset to zero + + integer :: id_clubb_on + integer :: id_stable_on ! ( diff_m_stab > diff_m or diff_t_stab > diff_t) + + integer :: id_stable_effective ! ( diff_m_stab > diff_m or diff_t_stab > diff_t) + ! and ( diff_m_stab > diff_min or diff_t_stab > diff_min) +!<--h1g, 2012-07-16 namelist /vert_turb_driver_nml/ do_shallow_conv, do_mellor_yamada, & gust_scheme, constant_gust, use_tau, & do_molecular_diffusion, do_stable_bl, & do_diffusivity, do_edt, do_entrain, & - gust_factor, do_simple + gust_factor, do_simple, wp2_min !-------------------- diagnostics fields ------------------------------- @@ -162,6 +177,13 @@ subroutine vert_turb_driver (is, js, Time, Time_next, dt, tdtlw, & real :: dt_tke integer :: ie, je, nlev, sec, day, nt logical :: used +!-->h1g, 2012-08-07 +real , dimension(size(diff_t,1),size(diff_t,2), & + size(diff_t,3)) :: clubb_on, & + stable_on, & + stable_effective +!<--h1g, 2012-08-07 + !----------------------------------------------------------------------- !----------------------- vertical turbulence --------------------------- !----------------------------------------------------------------------- @@ -329,6 +351,11 @@ subroutine vert_turb_driver (is, js, Time, Time_next, dt, tdtlw, & !----------------------------------------------------------------------- ! --- stable boundary layer parameterization +! --> h1g, 2012-08-08, pre-set stable_on is 0 + stable_on = 0.0 + stable_effective = 0.0 +! <-- h1g, 2012-08-08 + if( do_stable_bl ) then if (do_entrain) then @@ -353,9 +380,26 @@ subroutine vert_turb_driver (is, js, Time, Time_next, dt, tdtlw, & vv, z_half, z_full, u_star, b_star, lat, & diff_m_stab, diff_t_stab,kbot=kbot) +! --->h1g, 2012-07-16 + if( do_clubb > 0 ) then + clubb_on = 1.0 + where ( r(:,:,:, nwp2) <= wp2_min ) + where( diff_m_stab > diff_m .or. diff_t_stab > diff_t ) + stable_on = 1.0 + where( diff_m_stab >= diff_min .or. diff_t_stab >= diff_min ) + stable_effective = 1.0 + endwhere + endwhere diff_m = diff_m + MAX( diff_m_stab - diff_m, 0.0 ) diff_t = diff_t + MAX( diff_t_stab - diff_t, 0.0 ) - + clubb_on = 0.0 + endwhere + else + diff_m = diff_m + MAX( diff_m_stab - diff_m, 0.0 ) + diff_t = diff_t + MAX( diff_t_stab - diff_t, 0.0 ) + endif +! <---h1g, 2012-07-16 + end if endif @@ -493,6 +537,15 @@ subroutine vert_turb_driver (is, js, Time, Time_next, dt, tdtlw, & diag3(:,:,1:nlev) = diff_m_stab(:,:,1:nlev) used = send_data ( id_diff_m_stab, diag3, Time_next, is, js, 1, mask=lmask ) endif + + if ( id_stable_on > 0 ) then + used = send_data ( id_stable_on, stable_on, Time_next, is, js, 1, mask=lmask ) + endif + + if ( id_stable_effective > 0 ) then + used = send_data ( id_stable_effective, stable_effective, Time_next, is, js, 1, mask=lmask ) + endif + endif !------- diffusion coefficients for entrainment module ------- @@ -534,7 +587,13 @@ subroutine vert_turb_driver (is, js, Time, Time_next, dt, tdtlw, & used = send_data ( id_vwnd, vv, Time_next, is, js, 1, rmask=mask) endif - +! --->h1g, 2012-08-07, dump whether stable-scheme is on, clubb_on + if( do_clubb > 0) then + if ( id_clubb_on > 0 ) then + used = send_data ( id_clubb_on, clubb_on, Time_next, is, js, 1, mask=lmask ) + endif + endif +! <---h1g, 2012-08-07 !----------------------------------------------------------------------- @@ -543,13 +602,17 @@ end subroutine vert_turb_driver !####################################################################### subroutine vert_turb_driver_init (lonb, latb, id, jd, kd, axes, Time, & - doing_edt, doing_entrain) + doing_edt, doing_entrain, do_clubb_in) !----------------------------------------------------------------------- real, dimension(:,:), intent(in) :: lonb, latb integer, intent(in) :: id, jd, kd, axes(4) type(time_type), intent(in) :: Time logical, intent(out) :: doing_edt, doing_entrain + +!-->h1g + integer, optional, intent(in) :: do_clubb_in +!<--h1g !----------------------------------------------------------------------- integer, dimension(3) :: full = (/1,2,3/), half = (/1,2,4/) integer :: ierr, unit, io, logunit @@ -599,7 +662,19 @@ subroutine vert_turb_driver_init (lonb, latb, id, jd, kd, axes, Time, & 'molecular diffusion with EDT', FATAL) !----------------------------------------------------------------------- - +! -->h1g, 2012-07-16 + if (present(do_clubb_in)) then + do_clubb = do_clubb_in + else + do_clubb = 0 + endif + + if( do_entrain .and. do_clubb>0 ) & + call error_mesg ( 'vert_turb_driver_mod', 'cannot activate '//& + 'both do_entrain and CLUBB', FATAL) + nwp2 = get_tracer_index ( MODEL_ATMOS, 'wp2' ) +!<--h1g, 2012-07-16 + if (strat_cloud_on) then ! get tracer indices for stratiform cloud variables nql = get_tracer_index ( MODEL_ATMOS, 'liq_wat' ) @@ -708,6 +783,17 @@ subroutine vert_turb_driver_init (lonb, latb, id, jd, kd, axes, Time, & register_diag_field ( mod_name, 'diff_m_stab', axes(half), Time, & 'vert diff coeff for momentum', 'm2/s', & missing_value=missing_value ) + + id_stable_on = & + register_diag_field ( mod_name, 'stable_on', axes(half), Time, & + 'frequency of stable is on (diff_m_stab > diff_m or diff_t_stab > diff_t)', ' ', & + missing_value=missing_value ) + + id_stable_effective = & + register_diag_field ( mod_name, 'stable_effective', axes(half), Time, & + 'frequency of stable is effective (diff_m_stab > diff_m or diff_t_stab > diff_t and diff_m_stab > diff_min or diff_t_stab > diff_min)', ' ', & + missing_value=missing_value ) + endif @@ -724,6 +810,15 @@ subroutine vert_turb_driver_init (lonb, latb, id, jd, kd, axes, Time, & endif +! --->h1g, 2012-08-07, register id_clubb_on +if( do_clubb > 0 ) then + id_clubb_on = & + register_diag_field ( mod_name, 'clubb_on', axes(half), Time, & + 'frequency of clubb is on', ' ', & + missing_value=missing_value ) +endif +! <---h1g, 2012-08-07 + !----------------------------------------------------------------------- diff --git a/src/atmos_shared/atmos_nudge/atmos_nudge.F90 b/src/atmos_shared/atmos_nudge/atmos_nudge.F90 index d4f3f712de..58ebe89c17 100644 --- a/src/atmos_shared/atmos_nudge/atmos_nudge.F90 +++ b/src/atmos_shared/atmos_nudge/atmos_nudge.F90 @@ -21,7 +21,7 @@ module atmos_nudge_mod public :: atmos_nudge_init, get_atmos_nudge, atmos_nudge_end, do_ps character(len=128), parameter :: version = '$Id: atmos_nudge.F90,v 19.0 2012/01/06 20:28:34 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_shared/interpolator/interpolator.F90 b/src/atmos_shared/interpolator/interpolator.F90 index e828fab97e..fbe29d3ed5 100644 --- a/src/atmos_shared/interpolator/interpolator.F90 +++ b/src/atmos_shared/interpolator/interpolator.F90 @@ -100,8 +100,8 @@ module interpolator_mod module procedure interp_weighted_scalar_2D end interface interp_weighted_scalar character(len=128) :: version = & -'$Id: interpolator.F90,v 19.0.8.2 2012/06/11 19:26:57 Seth.Underwood Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +'$Id: interpolator.F90,v 20.0 2013/12/13 23:23:41 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. logical :: clim_diag_initialized = .false. @@ -1241,23 +1241,28 @@ subroutine obtain_interpolator_time_slices (clim_type, Time) type(time_type), dimension(2) :: month integer :: indexm, indexp, yearm, yearp integer :: i, n - +character(len=256) :: err_msg if (clim_type%climatological_year) then -!++lwh + !++lwh if (size(clim_type%time_slice) > 1) then - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_timeslice 1: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif else taum = 1 taup = 1 clim_type%tweight = 0. end if -!--lwh + !--lwh else - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_timeslice 2: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif endif - if(clim_type%TIME_FLAG .eq. BILINEAR ) then ! Check if delta-time is greater than delta of first two climatology time-slices. if ( (Time - clim_type%time_slice(taum) ) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) .or. & @@ -1313,18 +1318,28 @@ subroutine obtain_interpolator_time_slices (clim_type, Time) climyear, climmonth, climday, climhour, climminute, climsecond) month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond) - call time_interp(Time, month, clim_type%tweight3, taum, taup ) ! tweight3 is the time weight between the months. + call time_interp(Time, month, clim_type%tweight3, taum, taup, err_msg=err_msg ) ! tweight3 is the time weight between the months. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_timeslice 3: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexm+(climatology-1)*12) month(2) = clim_type%time_slice(indexm+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_prev, month, clim_type%tweight1, taum, taup ) !tweight1 is the time weight between the climatology years. + call time_interp(t_prev, month, clim_type%tweight1, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_timeslice 4: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif + month(1) = clim_type%time_slice(indexp+(climatology-1)*12) month(2) = clim_type%time_slice(indexp+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_next, month, clim_type%tweight2, taum, taup ) !tweight1 is the time weight between the climatology years. + call time_interp(t_next, month, clim_type%tweight2, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_timeslice 5: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif if (indexm == clim_type%indexm(1) .and. & indexp == clim_type%indexp(1) .and. & @@ -1501,7 +1516,7 @@ subroutine interpolator_4D(clim_type, Time, phalf, interp_data, & type(time_type), dimension(2) :: month integer :: indexm, indexp, yearm, yearp integer :: i, j, k, n - +character(len=256) :: err_msg if (.not. module_is_initialized .or. .not. associated(clim_type%lon)) & call mpp_error(FATAL, "interpolator_4D : You must call interpolator_init before calling interpolator") @@ -1559,7 +1574,10 @@ subroutine interpolator_4D(clim_type, Time, phalf, interp_data, & if (clim_type%climatological_year) then !++lwh if (size(clim_type%time_slice) > 1) then - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_4D 1: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif else taum = 1 taup = 1 @@ -1567,10 +1585,12 @@ subroutine interpolator_4D(clim_type, Time, phalf, interp_data, & end if !--lwh else - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_4D 2: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif endif - if(clim_type%TIME_FLAG .eq. BILINEAR ) then ! Check if delta-time is greater than delta of first two climatology time-slices. if ( (Time - clim_type%time_slice(taum) ) > ( clim_type%time_slice(2)- clim_type%time_slice(1) ) .or. & @@ -1626,18 +1646,27 @@ subroutine interpolator_4D(clim_type, Time, phalf, interp_data, & climyear, climmonth, climday, climhour, climminute, climsecond) month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond) - call time_interp(Time, month, clim_type%tweight3, taum, taup ) ! tweight3 is the time weight between the months. + call time_interp(Time, month, clim_type%tweight3, taum, taup, err_msg=err_msg ) ! tweight3 is the time weight between the months. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_4D 3: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexm+(climatology-1)*12) month(2) = clim_type%time_slice(indexm+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_prev, month, clim_type%tweight1, taum, taup ) !tweight1 is the time weight between the climatology years. + call time_interp(t_prev, month, clim_type%tweight1, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_4D 4: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexp+(climatology-1)*12) month(2) = clim_type%time_slice(indexp+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_next, month, clim_type%tweight2, taum, taup ) !tweight1 is the time weight between the climatology years. + call time_interp(t_next, month, clim_type%tweight2, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_4D 5: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif if (indexm == clim_type%indexm(1) .and. & indexp == clim_type%indexp(1) .and. & @@ -1920,6 +1949,7 @@ subroutine interpolator_3D(clim_type, Time, phalf, interp_data,field_name, is,js type(time_type), dimension(2) :: month integer :: indexm, indexp, yearm, yearp integer :: i, j, k, n +character(len=256) :: err_msg @@ -1957,7 +1987,10 @@ subroutine interpolator_3D(clim_type, Time, phalf, interp_data,field_name, is,js if (clim_type%climatological_year) then !++lwh if (size(clim_type%time_slice) > 1) then - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_3D 1: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif else taum = 1 taup = 1 @@ -1965,7 +1998,10 @@ subroutine interpolator_3D(clim_type, Time, phalf, interp_data,field_name, is,js end if !--lwh else - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_3D 2: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif endif ! if(clim_type%TIME_FLAG .ne. LINEAR ) then @@ -2029,20 +2065,28 @@ subroutine interpolator_3D(clim_type, Time, phalf, interp_data,field_name, is,js climyear, climmonth, climday, climhour, climminute, climsecond) month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond) - call time_interp(Time, month, clim_type%tweight3, taum, taup ) ! tweight3 is the time weight between the months. + call time_interp(Time, month, clim_type%tweight3, taum, taup, err_msg=err_msg ) ! tweight3 is the time weight between the months. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_3D 3: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexm+(climatology-1)*12) month(2) = clim_type%time_slice(indexm+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_prev, month, clim_type%tweight1, taum, taup ) !tweight1 is the time weight between the climatology years. + call time_interp(t_prev, month, clim_type%tweight1, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_3D 4: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexp+(climatology-1)*12) month(2) = clim_type%time_slice(indexp+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_next, month, clim_type%tweight2, taum, taup ) !tweight1 is the time weight between the climatology years. - + call time_interp(t_next, month, clim_type%tweight2, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_3D 5: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif if (indexm == clim_type%indexm(i) .and. & @@ -2293,6 +2337,7 @@ subroutine interpolator_2D(clim_type, Time, interp_data, field_name, is, js, cli type(time_type), dimension(2) :: month integer :: indexm, indexp, yearm, yearp integer :: j, i, n +character(len=256) :: err_msg if (.not. module_is_initialized .or. .not. associated(clim_type%lon)) & call mpp_error(FATAL, "interpolator_2D : You must call interpolator_init before calling interpolator") @@ -2330,7 +2375,10 @@ subroutine interpolator_2D(clim_type, Time, interp_data, field_name, is, js, cli if (clim_type%climatological_year) then !++lwh if (size(clim_type%time_slice) > 1) then - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, modtime=YEAR, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_2D 1: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif else taum = 1 taup = 1 @@ -2338,7 +2386,10 @@ subroutine interpolator_2D(clim_type, Time, interp_data, field_name, is, js, cli end if !--lwh else - call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup ) + call time_interp(Time, clim_type%time_slice, clim_type%tweight, taum, taup, err_msg=err_msg ) + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_2D 2: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif endif ! If the climatology file has seasonal, a split time-line or has all the data @@ -2428,20 +2479,28 @@ subroutine interpolator_2D(clim_type, Time, interp_data, field_name, is, js, cli climyear, climmonth, climday, climhour, climminute, climsecond) month(2) = set_date(yearp, indexp, climday, climhour, climminute, climsecond) - call time_interp(Time, month, clim_type%tweight3, taum, taup ) ! tweight3 is the time weight between the months. + call time_interp(Time, month, clim_type%tweight3, taum, taup, err_msg=err_msg ) ! tweight3 is the time weight between the months. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_2D 3: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexm+(climatology-1)*12) month(2) = clim_type%time_slice(indexm+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_prev = set_date(yearm, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_prev, month, clim_type%tweight1, taum, taup ) !tweight1 is the time weight between the climatology years. + call time_interp(t_prev, month, clim_type%tweight1, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_2D 4: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif month(1) = clim_type%time_slice(indexp+(climatology-1)*12) month(2) = clim_type%time_slice(indexp+climatology*12) call get_date(month(1), climyear, climmonth, climday, climhour, climminute, climsecond) t_next = set_date(yearp, climmonth, climday, climhour, climminute, climsecond) - call time_interp(t_next, month, clim_type%tweight2, taum, taup ) !tweight1 is the time weight between the climatology years. - + call time_interp(t_next, month, clim_type%tweight2, taum, taup, err_msg=err_msg ) !tweight1 is the time weight between the climatology years. + if(err_msg /= '') then + call mpp_error(FATAL,'interpolator_2D 5: '//trim(err_msg)//' file='//trim(clim_type%file_name), FATAL) + endif if (indexm == clim_type%indexm(i) .and. & diff --git a/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act.F90 b/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act.F90 index 37aa6992ed..1df4530c5b 100644 --- a/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act.F90 +++ b/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act.F90 @@ -19,7 +19,7 @@ module aer_ccn_act_mod !--------------------- version number --------------------------------- character(len=128) :: version = '$Id: aer_ccn_act.F90,v 19.0 2012/01/06 20:31:34 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !---------------- private data ------------------- diff --git a/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act_k.F90 b/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act_k.F90 index bc7785eebf..b1d5bb8161 100644 --- a/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act_k.F90 +++ b/src/atmos_shared/tracer_driver/aer_ccn_act/aer_ccn_act_k.F90 @@ -11,7 +11,7 @@ module aer_ccn_act_k_mod !--------------------- version number --------------------------------- character(len=128) :: version = '$Id: aer_ccn_act_k.F90,v 19.0 2012/01/06 20:31:36 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !---------------- private data ------------------- diff --git a/src/atmos_shared/tracer_driver/aer_ccn_act/aer_in_act.F90 b/src/atmos_shared/tracer_driver/aer_ccn_act/aer_in_act.F90 index 43963919fb..c03ed10539 100644 --- a/src/atmos_shared/tracer_driver/aer_ccn_act/aer_in_act.F90 +++ b/src/atmos_shared/tracer_driver/aer_ccn_act/aer_in_act.F90 @@ -34,7 +34,7 @@ module aer_in_act_mod real, dimension(tpDIM,msDIM,upDIM) :: crystal2 character(len=128) :: version = '$Id: aer_in_act.F90,v 19.0 2012/01/06 20:31:38 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/aer_ccn_act/aerosol_params.F90 b/src/atmos_shared/tracer_driver/aer_ccn_act/aerosol_params.F90 index e31e6a6214..71dad6502a 100644 --- a/src/atmos_shared/tracer_driver/aer_ccn_act/aerosol_params.F90 +++ b/src/atmos_shared/tracer_driver/aer_ccn_act/aerosol_params.F90 @@ -12,7 +12,7 @@ MODULE aerosol_params_mod !------------------------------------------------------------------------ !----version number------------------------------------------------------ Character(len=128) :: Version = '$Id: aerosol_params.F90,v 19.0 2012/01/06 20:31:39 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------ !--namelist-------------------------------------------------------------- diff --git a/src/atmos_shared/tracer_driver/aer_ccn_act/ice_nucl.F90 b/src/atmos_shared/tracer_driver/aer_ccn_act/ice_nucl.F90 index e5432f6bc9..3747407cab 100644 --- a/src/atmos_shared/tracer_driver/aer_ccn_act/ice_nucl.F90 +++ b/src/atmos_shared/tracer_driver/aer_ccn_act/ice_nucl.F90 @@ -29,8 +29,8 @@ MODULE ice_nucl_mod !------------------------------------------------------------------------ !----version number------------------------------------------------------ -Character(len=128) :: Version = '$Id: ice_nucl.F90,v 19.0 2012/01/06 20:31:40 fms Exp $' -Character(len=128) :: Tagname = '$Name: siena_201207 $' +Character(len=128) :: Version = '$Id: ice_nucl.F90,v 20.0 2013/12/13 23:24:20 fms Exp $' +Character(len=128) :: Tagname = '$Name: tikal $' !------------------------------------------------------------------------ !--namelist-------------------------------------------------------------- @@ -50,6 +50,9 @@ MODULE ice_nucl_mod logical :: do_ice_nucl_ss_wpdf = & .false. ! use seasalt particles for ! homogeneous nucleation ? +! ---> h1g +logical :: retain_ice_nucl_bug = .true. +! <--- h1g !------------------------------------------------------------------------ ! note that in-situ nucleation at cold temperatures most likely results ! in small sulfate (homogeneous nucleation). Heterogeneous nucleation, @@ -86,7 +89,7 @@ MODULE ice_nucl_mod limit_immersion_frz, limit_rhil, & do_ice_nucl_ss_wpdf, d_sulf, & d_bc, rh_crit_het, dust_surf, dust_frac_min, & - dust_frac_max, dust_frac, rh_dust_max + dust_frac_max, dust_frac, rh_dust_max, retain_ice_nucl_bug integer, parameter :: npoints = 64 ! # for Gauss-Hermite quadrature real, parameter :: wp2_eps = 0.0001 ! w variance threshold @@ -332,7 +335,7 @@ SUBROUTINE ice_nucl_k (zfull, T1, rhi_in, rhl_in, W1, TotalMass, & !--local variables----- REAL :: tc, rhl_thresh, A, B, C, nsulf, nss, naer, nbc, ndu, & - ndu_l, nbccrit, rhi, rhl, rhid + ndu_l, nbccrit, rhi, rhl, rhid, Sat_max LOGICAL :: do_hom !----------------------------------------------------------------------- @@ -457,7 +460,26 @@ SUBROUTINE ice_nucl_k (zfull, T1, rhi_in, rhl_in, W1, TotalMass, & ! calculate relative humidity threshold for homogeneous nucleation. !------------------------------------------------------------------------ A = 6.e-4 * LOG(W1) + 6.6e-3 - B = 6.e-3 * LOG(W1) + 1.052 +! ---> h1g, 2012-06-29, B=6.e-2 * LOG(W1) + 1.052 from +! (1) Liu, X., and J. E. Penner, 2005: Ice nucleation parameterization +! for global models. Meteor. Z., 14, 499-514. (2005) +! (2) Liu, Xiaohong, Joyce E. Penner, Steven J. Ghan, Minghuai Wang, 2007: +! Inclusion of Ice Microphysics in the NCAR Community Atmospheric +! Model Version 3 (CAM3). J. Climate, 20, 4526-4547. doi: http://dx.doi.org/10.1175/JCLI4264.1 +! (3) M. Salzmann1,*, Y. Ming2, J.-C. Golaz2, P. A. Ginoux2, H. Morrison3, A. Gettelman3, M. Kr¨amer4, +! and L. J. Donner, Two-moment bulk stratiform cloud microphysics +! in the GFDL AM3 GCM: description, evaluation, and sensitivity tests, ACP (2010) +! change from +! B = 6.e-3 * LOG(W1) + 1.052 +! to + if( retain_ice_nucl_bug ) then + B = 6.e-3 * LOG(W1) + 1.052 + else + B = 6.e-2 * LOG(W1) + 1.052 + endif + +! <--- h1g, 2012-06-29 + C = 1.68 * LOG(W1) + 129.35 rhl_thresh = A * Tc**2 + B * Tc + C @@ -567,6 +589,44 @@ SUBROUTINE ice_nucl_k (zfull, T1, rhi_in, rhl_in, W1, TotalMass, & Ni_dust = MIN(MAX(imass(7)/dust_surf, dust_frac_min), & dust_frac_max)*EXP(-0.639 + 0.1296*(100.*(rhid - 1. ))) Ni_dust = MIN (Ni_dust, ndu_l) + + ELSE IF ( dust_opt .EQ. 6 ) THEN + Ni_dust = 1.5e-10* EXP(-0.639 + 0.1296*(100.*(rhid - 1. ))) + +! --->h1g, 2012-06-30 +! calculate maximum super-saturation Sat_max following +! (1) Liu, X., and J. E. Penner, 2005: Ice nucleation parameterization +! for global models. Meteor. Z., 14, 499-514. (2005) + ELSE IF ( dust_opt .EQ. 7 ) THEN + IF ( use_dust_instead_of_bc) THEN + +!------------------------------------------------------------------------- +! dust is activated. units of #/cm^3. Use only dust_frac of the total +! dust for nucleation. +!------------------------------------------------------------------------- + ndu = 1.e-6*(Nfact_du1*imass(8) + Nfact_du2*imass(9) + & + Nfact_du3*imass(10) + Nfact_du4*imass(11) + & + Nfact_du5*imass(12)) + nbc = dust_frac * ndu + ELSE +!------------------------------------------------------------------------- +! black carbon is activated. 1.e-6 is conversion from from m^-3 to cm^-3. +!------------------------------------------------------------------------- + nbc = MIN(imass(6)*1.e-6*6./(rho_bc*pi*d_bc**3)* & + exp(-9./2. * (log(sigma_bc))**2), 1.e10) + ENDIF + nbc = max(nbc, 1.e-10) + call S_max(Sat_max, nbc, w1, tc) + + if( tc < -20.0 ) then + Ni_dust = MIN(MAX(imass(7)/dust_surf, dust_frac_min), & + dust_frac_max)*EXP(-0.639 + 0.1296*(max(100.*(rhid - 1. ), Sat_max))) + else + Ni_dust = MIN(MAX(imass(7)/dust_surf, dust_frac_min), & + dust_frac_max)*EXP(-0.639 + 0.1296*(100.*(rhid - 1. ))) + endif +! <---h1g, 2012-06-30 + endif !------------------------------------------------------------------------- @@ -690,7 +750,37 @@ SUBROUTINE bc_het(Ni, nbc, w1, tc) END SUBROUTINE bc_het +!------------------------------------------------------------------------ + +!######################################################################## + +SUBROUTINE S_max(Sat_max, nbc, w1, tc) +REAL, INTENT (INOUT ) :: Sat_max +REAL, INTENT (IN ) :: nbc, w1, tc +real :: A, B, C, & + a1, a2, a3, & + b1, b2, b3, & + c1, c2, c3 + + a1 = -0.2035*nbc**(-0.8854) + a2 = 0.2725*nbc**(-0.415) + a3 = -0.0069 + + b1 = -24.759*nbc**(-0.8831) + b2 = 29.893*nbc**(-0.4067) + b3 = -0.672 + + c1 = -732.36*nbc**(-0.8712) + c2 = 822.49*nbc**(-0.3951) + c3 = 6.702 + + A = a1*w1*w1 + a2 * w1 +a3 + B = b1*w1*w1 + b2 * w1 +b3 + C = c1*w1*w1 + c2 * w1 +c3 + + Sat_max = A * tc*tc + B * tc + C +END SUBROUTINE S_max !------------------------------------------------------------------------ diff --git a/src/atmos_shared/tracer_driver/atmos_age_tracer.F90 b/src/atmos_shared/tracer_driver/atmos_age_tracer.F90 index 14906fb580..bc754f627e 100644 --- a/src/atmos_shared/tracer_driver/atmos_age_tracer.F90 +++ b/src/atmos_shared/tracer_driver/atmos_age_tracer.F90 @@ -75,7 +75,7 @@ module atmos_age_tracer_mod !---- version number ----- character(len=128) :: version = '$Id: atmos_age_tracer.F90,v 19.0 2012/01/06 20:29:08 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains diff --git a/src/atmos_shared/tracer_driver/atmos_carbon_aerosol.F90 b/src/atmos_shared/tracer_driver/atmos_carbon_aerosol.F90 index 12cbd38b13..5eca2348d2 100644 --- a/src/atmos_shared/tracer_driver/atmos_carbon_aerosol.F90 +++ b/src/atmos_shared/tracer_driver/atmos_carbon_aerosol.F90 @@ -285,8 +285,8 @@ Module atmos_carbon_aerosol_mod logical :: used !---- version number ----- -character(len=128) :: version = '$Id: atmos_carbon_aerosol.F90,v 19.0 2012/01/06 20:29:40 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_carbon_aerosol.F90,v 20.0 2013/12/13 23:23:44 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- type(time_type) :: bcff_time @@ -317,7 +317,7 @@ subroutine atmos_carbon_aerosol_driver(lon, lat, ocn_flx_fraction, & omphob, omphob_dt, & omphil, omphil_dt, & oh_conc,& - model_time, is, ie, js, je ) + diag_time, is, ie, js, je ) !----------------------------------------------------------------------- real, intent(in), dimension(:,:) :: lon, lat @@ -331,7 +331,7 @@ subroutine atmos_carbon_aerosol_driver(lon, lat, ocn_flx_fraction, & real, intent(in), dimension(:,:,:) :: oh_conc real, intent(out), dimension(:,:,:) :: bcphob_dt,bcphil_dt real, intent(out), dimension(:,:,:) :: omphob_dt,omphil_dt -type(time_type), intent(in) :: model_time +type(time_type), intent(in) :: diag_time integer, intent(in) :: is, ie, js, je !----------------------------------------------------------------------- @@ -793,7 +793,7 @@ subroutine atmos_carbon_aerosol_driver(lon, lat, ocn_flx_fraction, & bcphil_emis(:,:,k) end do - used = send_data ( id_bc_emis_col, bc_emis, model_time, & + used = send_data ( id_bc_emis_col, bc_emis, diag_time, & is_in=is,js_in=js) endif @@ -806,7 +806,7 @@ subroutine atmos_carbon_aerosol_driver(lon, lat, ocn_flx_fraction, & omphil_emis(:,:,k) end do - used = send_data ( id_om_emis_col, om_emis, model_time, & + used = send_data ( id_om_emis_col, om_emis, diag_time, & is_in=is,js_in=js) endif @@ -821,7 +821,7 @@ subroutine atmos_carbon_aerosol_driver(lon, lat, ocn_flx_fraction, & bc_emis(:,:) = bc_emis(:,:) + pwt(:,:,k)*& (bcphob_emis(:,:,k) + bcphil_emis(:,:,k)) end do - used = send_data ( id_bc_emis_colv2, bc_emis, model_time, & + used = send_data ( id_bc_emis_colv2, bc_emis, diag_time, & is_in=is,js_in=js) endif @@ -833,90 +833,90 @@ subroutine atmos_carbon_aerosol_driver(lon, lat, ocn_flx_fraction, & om_emis(:,:) = om_emis(:,:) + pwt(:,:,k)* & (omphob_emis(:,:,k) + omphil_emis(:,:,k)) end do - used = send_data ( id_om_emis_colv2, om_emis, model_time, & + used = send_data ( id_om_emis_colv2, om_emis, diag_time, & is_in=is,js_in=js) endif !----------------------------------------------------------------- if (id_bcphob_emis > 0) then - used = send_data ( id_bcphob_emis, bcphob_emis, model_time, & + used = send_data ( id_bcphob_emis, bcphob_emis, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_bcphil_emis > 0) then - used = send_data ( id_bcphil_emis, bcphil_emis, model_time, & + used = send_data ( id_bcphil_emis, bcphil_emis, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_omphob_emis > 0) then - used = send_data ( id_omphob_emis, omphob_emis, model_time, & + used = send_data ( id_omphob_emis, omphob_emis, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_omphil_emis > 0) then - used = send_data ( id_omphil_emis, omphil_emis, model_time, & + used = send_data ( id_omphil_emis, omphil_emis, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_bcphob_sink > 0) then - used = send_data ( id_bcphob_sink, bcphob_sink, model_time, & + used = send_data ( id_bcphob_sink, bcphob_sink, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_omphob_sink > 0) then - used = send_data ( id_omphob_sink, omphob_sink, model_time, & + used = send_data ( id_omphob_sink, omphob_sink, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_bcemisbf > 0) then - used = send_data ( id_bcemisbf, bcemisbf, model_time, & + used = send_data ( id_bcemisbf, bcemisbf, diag_time, & is_in=is,js_in=js) endif if (id_emisbb > 0) then - used = send_data ( id_emisbb, emisob, model_time, & + used = send_data ( id_emisbb, emisob, diag_time, & is_in=is,js_in=js) endif if (id_omemisbb_col > 0) then - used = send_data ( id_omemisbb_col, omemisob_2d, model_time, & + used = send_data ( id_omemisbb_col, omemisob_2d, diag_time, & is_in=is,js_in=js) endif if (id_bcemisbb > 0) then - used = send_data ( id_bcemisbb, bcemisob, model_time, & + used = send_data ( id_bcemisbb, bcemisob, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_bcemissh > 0) then - used = send_data ( id_bcemissh, bcemissh, model_time, & + used = send_data ( id_bcemissh, bcemissh, diag_time, & is_in=is,js_in=js) endif if (id_bcemisff > 0) then - used = send_data ( id_bcemisff, bcemisff, model_time, & + used = send_data ( id_bcemisff, bcemisff, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_bcemisav > 0) then - used = send_data ( id_bcemisav, bcemisav*bc_aircraft_EI, model_time, & + used = send_data ( id_bcemisav, bcemisav*bc_aircraft_EI, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_omemisbf > 0) then - used = send_data ( id_omemisbf, omemisbf, model_time, & + used = send_data ( id_omemisbf, omemisbf, diag_time, & is_in=is,js_in=js) endif if (id_omemisbb > 0) then - used = send_data ( id_omemisbb, omemisob, model_time, & + used = send_data ( id_omemisbb, omemisob, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_omemissh > 0) then - used = send_data ( id_omemissh, omemissh, model_time, & + used = send_data ( id_omemissh, omemissh, diag_time, & is_in=is,js_in=js) endif if (id_omemisff > 0) then - used = send_data ( id_omemisff, omemisff, model_time, & + used = send_data ( id_omemisff, omemisff, diag_time, & is_in=is,js_in=js,ks_in=1) endif if (id_omemisbg > 0) then - used = send_data ( id_omemisbg, omemisbg, model_time, & + used = send_data ( id_omemisbg, omemisbg, diag_time, & is_in=is,js_in=js) endif if (id_omemisoc > 0) then - used = send_data ( id_omemisoc, omemisocean, model_time, & + used = send_data ( id_omemisoc, omemisocean, diag_time, & is_in=is,js_in=js) endif if (id_bc_tau > 0) then - used = send_data ( id_bc_tau, bc_tau, model_time, & + used = send_data ( id_bc_tau, bc_tau, diag_time, & is_in=is,js_in=js,ks_in=1) endif ! diff --git a/src/atmos_shared/tracer_driver/atmos_ch3i.F90 b/src/atmos_shared/tracer_driver/atmos_ch3i.F90 index 2bbd24c2d2..7d094b123e 100644 --- a/src/atmos_shared/tracer_driver/atmos_ch3i.F90 +++ b/src/atmos_shared/tracer_driver/atmos_ch3i.F90 @@ -63,8 +63,8 @@ module atmos_ch3i_mod character(len=7), parameter :: module_name = 'tracers' !---- version number ----- -character(len=128) :: version = '$Id: atmos_ch3i.F90,v 19.0 2012/01/06 20:29:42 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_ch3i.F90,v 20.0 2013/12/13 23:23:47 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. contains @@ -265,7 +265,7 @@ subroutine atmos_ch3i( lon, lat, land, pwt, ch3i, ch3i_dt, & else emis_source(:,:,kd) = emis(:,:)/pwt(:,:,kd) * emis_cons end if - used = send_data(id_emissions,emis,Time,is_in=is,js_in=js) + used = send_data(id_emissions,emis,Time_next,is_in=is,js_in=js) end if !----------------------------------------------------------------------- @@ -290,8 +290,8 @@ subroutine atmos_ch3i( lon, lat, land, pwt, ch3i, ch3i_dt, & end do ch3i_loss(:,:,:) = ( j_ch3i(:,:,:) + k_ch3i_oh(:,:,:)*conc_oh(:,:,:) ) & * ch3i(:,:,:) ! VMR/s -used = send_data( id_loss, ch3i_loss, Time, is_in=is, js_in=js ) -used = send_data( id_j_ch3i, j_ch3i, Time, is_in=is, js_in=js ) +used = send_data( id_loss, ch3i_loss, Time_next, is_in=is, js_in=js ) +used = send_data( id_j_ch3i, j_ch3i, Time_next, is_in=is, js_in=js ) ch3i_dt(:,:,:) = emis_source(:,:,:) - ch3i_loss(:,:,:) diff --git a/src/atmos_shared/tracer_driver/atmos_co2.F90 b/src/atmos_shared/tracer_driver/atmos_co2.F90 index 33f05827a0..496eb83d47 100644 --- a/src/atmos_shared/tracer_driver/atmos_co2.F90 +++ b/src/atmos_shared/tracer_driver/atmos_co2.F90 @@ -137,10 +137,10 @@ module atmos_co2_mod ! ! -subroutine atmos_co2_sourcesink(is, ie, js, je, Time, dt, pwt, co2, sphum, co2_restore) +subroutine atmos_co2_sourcesink(is, ie, js, je, Time, Time_next, dt, pwt, co2, sphum, co2_restore) integer, intent(in) :: is, ie, js, je - type (time_type), intent(in) :: Time + type (time_type), intent(in) :: Time, Time_next real, intent(in) :: dt real, intent(in), dimension(:,:,:) :: pwt ! kg/m2 real, intent(in), dimension(:,:,:) :: co2 ! moist mmr @@ -199,7 +199,7 @@ subroutine atmos_co2_sourcesink(is, ie, js, je, Time, dt, pwt, co2, sphum, co2_r ! restoring diagnostic in moles co2/m2/sec ! pwt is moist air, so no need to divide by 1-sphum here if (id_co2restore > 0) sent = send_data (id_co2restore, co2_restore * & - pwt / (WTMCO2*1.e-3), Time, is_in=is,js_in=js) + pwt / (WTMCO2*1.e-3), Time_next, is_in=is,js_in=js) endif !else @@ -208,7 +208,7 @@ subroutine atmos_co2_sourcesink(is, ie, js, je, Time, dt, pwt, co2, sphum, co2_r endif !! add pwt as a diagnostic -if (id_pwt > 0) sent = send_data (id_pwt, pwt, Time, is_in=is,js_in=js) +if (id_pwt > 0) sent = send_data (id_pwt, pwt, Time_next, is_in=is,js_in=js) end subroutine atmos_co2_sourcesink @@ -322,10 +322,10 @@ end subroutine atmos_co2_rad ! ! -subroutine atmos_co2_emissions(is, ie, js, je, Time, dt, pwt, co2, sphum, co2_emiss_dt, kbot) +subroutine atmos_co2_emissions(is, ie, js, je, Time, Time_next, dt, pwt, co2, sphum, co2_emiss_dt, kbot) integer, intent(in) :: is, ie, js, je - type (time_type), intent(in) :: Time + type (time_type), intent(in) :: Time, Time_next real, intent(in) :: dt real, intent(in), dimension(:,:,:) :: pwt ! kg/m2 real, intent(in), dimension(:,:,:) :: co2 ! moist mmr @@ -375,7 +375,7 @@ subroutine atmos_co2_emissions(is, ie, js, je, Time, dt, pwt, co2, sphum, co2_em call error_mesg (trim(error_header), ' data override needed for co2 emission ', FATAL) endif - if (id_co2_emiss_orig > 0) sent = send_data (id_co2_emiss_orig, co2_emis2d, Time, is_in=is,js_in=js) + if (id_co2_emiss_orig > 0) sent = send_data (id_co2_emiss_orig, co2_emis2d, Time_next, is_in=is,js_in=js) ! lowest model layer do j=1,jd @@ -388,7 +388,7 @@ subroutine atmos_co2_emissions(is, ie, js, je, Time, dt, pwt, co2, sphum, co2_em ! co2 mol emission diagnostic in moles CO2/m2/sec if (id_co2_mol_emiss > 0) sent = send_data (id_co2_mol_emiss, & - co2_emiss_dt(:,:,kd)*pwt(:,:,kd)/(WTMCO2*1.e-3), Time, is_in=is,js_in=js) + co2_emiss_dt(:,:,kd)*pwt(:,:,kd)/(WTMCO2*1.e-3), Time_next, is_in=is,js_in=js) endif diff --git a/src/atmos_shared/tracer_driver/atmos_convection_tracer.F90 b/src/atmos_shared/tracer_driver/atmos_convection_tracer.F90 index bb4f6b8e13..5066c6b2ac 100644 --- a/src/atmos_shared/tracer_driver/atmos_convection_tracer.F90 +++ b/src/atmos_shared/tracer_driver/atmos_convection_tracer.F90 @@ -70,7 +70,7 @@ module atmos_convection_tracer_mod !---- version number ----- character(len=128) :: version = '$Id: atmos_convection_tracer.F90,v 19.0 2012/01/06 20:30:16 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains diff --git a/src/atmos_shared/tracer_driver/atmos_dust.F90 b/src/atmos_shared/tracer_driver/atmos_dust.F90 index 30d3491159..6691e4b25f 100644 --- a/src/atmos_shared/tracer_driver/atmos_dust.F90 +++ b/src/atmos_shared/tracer_driver/atmos_dust.F90 @@ -80,8 +80,8 @@ module atmos_dust_mod namelist /dust_nml/ dust_source_filename, dust_source_name, uthresh, coef_emis !---- version number ----- -character(len=128) :: version = '$Id: atmos_dust.F90,v 19.0 2012/01/06 20:30:48 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_dust.F90,v 20.0 2013/12/13 23:23:54 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains @@ -95,7 +95,7 @@ module atmos_dust_mod subroutine atmos_dust_sourcesink (i_DU,ra,rb,dustref,dustden, & lon, lat, frac_land, pwt, & zhalf, pfull, w10m, t, rh, & - dust, dust_dt, dust_emis, dust_setl, Time, is,ie,js,je,kbot) + dust, dust_dt, dust_emis, dust_setl, Time, Time_next, is,ie,js,je,kbot) !----------------------------------------------------------------------- integer, intent(in) :: i_DU @@ -110,7 +110,7 @@ subroutine atmos_dust_sourcesink (i_DU,ra,rb,dustref,dustden, & real, intent(in), dimension(:,:,:) :: pwt, dust real, intent(in), dimension(:,:,:) :: zhalf, pfull, t, rh real, intent(out), dimension(:,:,:) :: dust_dt - type(time_type), intent(in) :: Time + type(time_type), intent(in) :: Time, Time_next integer, intent(in), dimension(:,:), optional :: kbot integer, intent(in) :: is, ie, js, je !----------------------------------------------------------------------- @@ -156,7 +156,7 @@ subroutine atmos_dust_sourcesink (i_DU,ra,rb,dustref,dustden, & trim(dust_source_name(1)), is, js) ! Send the dust source data to the diag_manager for output. if (id_dust_source > 0 ) & - used = send_data ( id_dust_source, source , Time ) + used = send_data ( id_dust_source, source , Time_next ) where ( frac_land.gt.0.1 .and. w10m .gt. u_ts_2d ) dust_emis = CH * frac_s(i_DU)*source * frac_land & @@ -166,7 +166,7 @@ subroutine atmos_dust_sourcesink (i_DU,ra,rb,dustref,dustden, & ! Send the emission data to the diag_manager for output. if (id_dust_emis(i_DU) > 0 ) then - used = send_data ( id_dust_emis(i_DU), dust_emis, Time, & + used = send_data ( id_dust_emis(i_DU), dust_emis, Time_next, & is_in=is,js_in=js ) endif @@ -211,7 +211,7 @@ subroutine atmos_dust_sourcesink (i_DU,ra,rb,dustref,dustden, & ! Send the settling data to the diag_manager for output. if (id_dust_setl(i_DU) > 0 ) then - used = send_data ( id_dust_setl(i_DU), dust_setl, Time, & + used = send_data ( id_dust_setl(i_DU), dust_setl, Time_next, & is_in=is,js_in=js ) endif diff --git a/src/atmos_shared/tracer_driver/atmos_radon.F90 b/src/atmos_shared/tracer_driver/atmos_radon.F90 index 1faef265f7..784e41e67b 100644 --- a/src/atmos_shared/tracer_driver/atmos_radon.F90 +++ b/src/atmos_shared/tracer_driver/atmos_radon.F90 @@ -68,7 +68,7 @@ module atmos_radon_mod !---- version number ----- character(len=128) :: version = '$Id: atmos_radon.F90,v 19.0 2012/01/06 20:30:50 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains diff --git a/src/atmos_shared/tracer_driver/atmos_sea_salt.F90 b/src/atmos_shared/tracer_driver/atmos_sea_salt.F90 index 9fe857d686..86a40f5875 100644 --- a/src/atmos_shared/tracer_driver/atmos_sea_salt.F90 +++ b/src/atmos_shared/tracer_driver/atmos_sea_salt.F90 @@ -38,8 +38,8 @@ module atmos_sea_salt_mod public atmos_sea_salt_sourcesink, atmos_sea_salt_init, atmos_sea_salt_end !---- version number ----- -character(len=128) :: version = '$Id: atmos_sea_salt.F90,v 19.0 2012/01/06 20:31:22 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_sea_salt.F90,v 20.0 2013/12/13 23:23:59 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- @@ -117,7 +117,8 @@ subroutine atmos_sea_salt_sourcesink (i_SS,ra,rb,ssaltref,ssaltden, & lon, lat, ocn_flx_fraction, pwt, & zhalf, pfull, w10m, t, rh, & seasalt, seasalt_dt, dt, SS_setl, & - SS_emis, Time, is,ie,js,je, kbot) + SS_emis, Time, Time_next, & + is,ie,js,je, kbot) !----------------------------------------------------------------------- integer, intent(in) :: i_SS @@ -134,7 +135,7 @@ subroutine atmos_sea_salt_sourcesink (i_SS,ra,rb,ssaltref,ssaltden, & real, intent(in), dimension(:,:,:) :: zhalf, pfull, t, rh real, intent(out), dimension(:,:,:) :: seasalt_dt integer, intent(in) :: is, ie, js, je - type(time_type), intent(in) :: Time + type(time_type), intent(in) :: Time, Time_next integer, intent(in), dimension(:,:), optional :: kbot !----------------------------------------------------------------------- @@ -252,11 +253,11 @@ subroutine atmos_sea_salt_sourcesink (i_SS,ra,rb,ssaltref,ssaltden, & ! Send the emission data to the diag_manager for output. if (id_SS_emis(i_SS) > 0 ) then - used = send_data ( id_SS_emis(i_SS), SS_emis, Time, & + used = send_data ( id_SS_emis(i_SS), SS_emis, Time_next, & is_in=is,js_in=js ) endif if (id_ocn_flx_fraction > 0) then - used = send_data ( id_ocn_flx_fraction, ocn_flx_fraction, Time, & + used = send_data ( id_ocn_flx_fraction, ocn_flx_fraction, Time_next, & is_in=is,js_in=js ) endif @@ -325,7 +326,7 @@ subroutine atmos_sea_salt_sourcesink (i_SS,ra,rb,ssaltref,ssaltden, & ! Send the settling data to the diag_manager for output. if (id_SS_setl(i_SS) > 0 ) then - used = send_data ( id_SS_setl(i_SS), SS_setl, Time, & + used = send_data ( id_SS_setl(i_SS), SS_setl, Time_next, & is_in=is,js_in=js ) endif diff --git a/src/atmos_shared/tracer_driver/atmos_soa.F90 b/src/atmos_shared/tracer_driver/atmos_soa.F90 index 2bf08122b8..a292ff5cd2 100644 --- a/src/atmos_shared/tracer_driver/atmos_soa.F90 +++ b/src/atmos_shared/tracer_driver/atmos_soa.F90 @@ -76,8 +76,8 @@ module atmos_soa_mod logical :: used !---- version number ----- -character(len=128) :: version = '$Id: atmos_soa.F90,v 19.0 2012/01/06 20:31:24 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_soa.F90,v 20.0 2013/12/13 23:24:02 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains @@ -230,7 +230,7 @@ end subroutine atmos_SOA_end !----------------------------------------------------------------------- SUBROUTINE atmos_SOA_chem(pwt,temp,pfull, phalf, dt, & jday,hour,minute,second,lat,lon, & - SOA, SOA_dt, Time,is,ie,js,je,kbot) + SOA, SOA_dt, Time,Time_next,is,ie,js,je,kbot) ! **************************************************************************** real, intent(in), dimension(:,:,:) :: pwt @@ -240,7 +240,7 @@ SUBROUTINE atmos_SOA_chem(pwt,temp,pfull, phalf, dt, & real, intent(in), dimension(:,:) :: lat, lon ! [radian] real, intent(in), dimension(:,:,:) :: SOA real, intent(out), dimension(:,:,:) :: SOA_dt - type(time_type), intent(in) :: Time + type(time_type), intent(in) :: Time, Time_next integer, intent(in), dimension(:,:), optional :: kbot integer, intent(in) :: is,ie,js,je ! Working vectors @@ -327,7 +327,7 @@ SUBROUTINE atmos_SOA_chem(pwt,temp,pfull, phalf, dt, & if (id_SOA_chem > 0) then used = send_data ( id_SOA_chem, & - SOA_chem, Time,is_in=is,js_in=js,ks_in=1) + SOA_chem, Time_next,is_in=is,js_in=js,ks_in=1) endif ! column production of SOA @@ -340,7 +340,7 @@ SUBROUTINE atmos_SOA_chem(pwt,temp,pfull, phalf, dt, & if (id_SOA_chem_col > 0) then used = send_data ( id_SOA_chem_col, & - SOA_prod, Time,is_in=is,js_in=js) + SOA_prod, Time_next,is_in=is,js_in=js) endif diff --git a/src/atmos_shared/tracer_driver/atmos_sulfate.F90 b/src/atmos_shared/tracer_driver/atmos_sulfate.F90 index a0f2937250..9024173efa 100644 --- a/src/atmos_shared/tracer_driver/atmos_sulfate.F90 +++ b/src/atmos_shared/tracer_driver/atmos_sulfate.F90 @@ -265,8 +265,8 @@ module atmos_sulfate_mod logical :: used !---- version number ----- -character(len=128) :: version = '$Id: atmos_sulfate.F90,v 19.0 2012/01/06 20:31:26 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_sulfate.F90,v 20.0 2013/12/13 23:24:05 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains @@ -1212,7 +1212,7 @@ end subroutine atmos_sulfate_end ! (nlon, nlat, nlev, ntime) ! subroutine atmos_DMS_emission (lon, lat, area, ocn_flx_fraction, t_surf_rad, w10m, & - pwt, DMS_dt, Time, is,ie,js,je,kbot) + pwt, DMS_dt, Time, Time_next, is,ie,js,je,kbot) ! real, intent(in), dimension(:,:) :: lon, lat real, intent(in), dimension(:,:) :: ocn_flx_fraction @@ -1221,7 +1221,7 @@ subroutine atmos_DMS_emission (lon, lat, area, ocn_flx_fraction, t_surf_rad, w10 real, intent(in), dimension(:,:) :: area real, intent(in), dimension(:,:,:) :: pwt real, intent(out), dimension(:,:,:) :: DMS_dt - type(time_type), intent(in) :: Time + type(time_type), intent(in) :: Time, Time_next integer, intent(in) :: is, ie, js, je integer, intent(in), dimension(:,:), optional :: kbot !----------------------------------------------------------------------- @@ -1240,7 +1240,7 @@ subroutine atmos_DMS_emission (lon, lat, area, ocn_flx_fraction, t_surf_rad, w10 trim(gocart_emission_name(1)), is, js) ! --- Send the DMS data to the diag_manager for output. if (id_DMSo > 0 ) & - used = send_data ( id_DMSo, DMSo, Time, is_in=is, js_in=js ) + used = send_data ( id_DMSo, DMSo, Time_next, is_in=is, js_in=js ) ! **************************************************************************** ! * If ocn_flx_fraction > critical_sea_fraction: DMS_emis = seawaterDMS * transfer velocity * ocn_flx_fraction @@ -1330,11 +1330,11 @@ subroutine atmos_DMS_emission (lon, lat, area, ocn_flx_fraction, t_surf_rad, w10 ! DIAGNOSTICS: DMS surface emission in kg/m2/s !-------------------------------------------------------------------- if (id_DMS_emis > 0) then - used = send_data ( id_DMS_emis, dms_emis*WTM_S/WTM_DMS, Time, & + used = send_data ( id_DMS_emis, dms_emis*WTM_S/WTM_DMS, Time_next, & is_in=is,js_in=js ) endif if (id_DMS_emis_cmip > 0) then - used = send_data ( id_DMS_emis_cmip, dms_emis, Time, & + used = send_data ( id_DMS_emis_cmip, dms_emis, Time_next, & is_in=is,js_in=js ) endif @@ -1368,7 +1368,7 @@ end subroutine atmos_DMS_emission ! (nlon, nlat, nlev, ntime) ! subroutine atmos_SOx_emission (lon, lat, area, frac_land, & - z_pbl, zhalf, phalf, pwt, SO2_dt, SO4_dt, model_time, is,ie,js,je,kbot) + z_pbl, zhalf, phalf, pwt, SO2_dt, SO4_dt, model_time, diag_time, is,ie,js,je,kbot) ! ! This subroutine calculates the tendencies of SO2 and SO4 due to ! their emissions. @@ -1384,7 +1384,7 @@ subroutine atmos_SOx_emission (lon, lat, area, frac_land, & real, intent(in), dimension(:,:,:) :: zhalf, phalf real, intent(in), dimension(:,:,:) :: pwt real, intent(out), dimension(:,:,:) :: SO2_dt, SO4_dt - type(time_type), intent(in) :: model_time + type(time_type), intent(in) :: model_time,diag_time integer, intent(in) :: is, ie, js, je integer, intent(in), dimension(:,:), optional :: kbot !----------------------------------------------------------------------- @@ -1766,55 +1766,55 @@ subroutine atmos_SOx_emission (lon, lat, area, frac_land, & !-------------------------------------------------------------------- if (id_so2_emis > 0) then used = send_data ( id_so2_emis, so2_emis*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js,ks_in=1) + diag_time, is_in=is,js_in=js,ks_in=1) endif if (id_so2_aircraft > 0) then used = send_data ( id_so2_aircraft, & so2_aircraft*so2_aircraft_EI*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_cont_volc > 0) then used = send_data ( id_so2_cont_volc, so2_emis_cont_volc*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_expl_volc > 0) then used = send_data ( id_so2_expl_volc, so2_emis_expl_volc*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_biobur > 0) then used = send_data ( id_so2_biobur, so2_emis_biobur*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js,ks_in=1) + diag_time, is_in=is,js_in=js,ks_in=1) endif if (id_so2_ship > 0) then used = send_data ( id_so2_ship, so2_emis_ship*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_road > 0) then used = send_data ( id_so2_road, so2_emis_road*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_domestic > 0) then used = send_data ( id_so2_domestic, so2_emis_domestic*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_industry > 0) then used = send_data ( id_so2_industry, so2_emis_industry*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_power > 0) then used = send_data ( id_so2_power, so2_emis_power*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_off_road > 0) then used = send_data ( id_so2_Off_road, so2_emis_off_road*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so2_ff > 0) then used = send_data ( id_so2_ff, so2_emis_ff*WTM_S/WTM_so2, & - model_time, is_in=is,js_in=js, ks_in=1) + diag_time, is_in=is,js_in=js, ks_in=1) endif if (id_so4_emis > 0) then - used = send_data ( id_so4_emis, so4_emis*WTM_S/WTM_so4, model_time, & + used = send_data ( id_so4_emis, so4_emis*WTM_S/WTM_so4, diag_time, & is_in=is,js_in=js,ks_in=1) endif @@ -1824,9 +1824,9 @@ end subroutine atmos_SOx_emission !####################################################################### subroutine atmos_SOx_chem(pwt,temp,pfull, phalf, dt, lwc, & jday,hour,minute,second,lat,lon, & - SO2, SO4, DMS, MSA, H2O2, & + SO2, SO4, DMS, MSA, H2O2, oh_vmr, & SO2_dt, SO4_dt, DMS_dt, MSA_dt, H2O2_dt, & - model_time,is,ie,js,je,kbot) + model_time,diag_time,is,ie,js,je,kbot) ! real, intent(in) :: dt integer, intent(in) :: jday, hour,minute,second @@ -1835,9 +1835,10 @@ subroutine atmos_SOx_chem(pwt,temp,pfull, phalf, dt, lwc, & real, intent(in), dimension(:,:,:) :: lwc real, intent(in), dimension(:,:,:) :: temp, pfull, phalf real, intent(in), dimension(:,:,:) :: SO2, SO4, DMS, MSA, H2O2 + real, intent(inout), dimension(:,:,:) :: oh_vmr real, intent(out),dimension(:,:,:) :: SO2_dt,SO4_dt,DMS_dt,MSA_dt,H2O2_dt - type(time_type), intent(in) :: model_time + type(time_type), intent(in) :: model_time,diag_time integer, intent(in), dimension(:,:), optional :: kbot integer, intent(in) :: is,ie,js,je ! Working vectors @@ -2003,6 +2004,7 @@ subroutine atmos_SOx_chem(pwt,temp,pfull, phalf, dt, lwc, & xno3 = max(0. , NO3_conc(i,j,k) *fac_NO3(i,j)) xo3 = max(small_value, O3_mmr(i,j,k)) oh_diurnal(i,j,k)=xoh + oh_vmr(i,j,k)=xoh/xhnm no3_diurnal(i,j,k)=xno3 ho2_diurnal(i,j,k)=xho2 jh2o2_diurnal(i,j,k)=xjh2o2 @@ -2197,65 +2199,65 @@ subroutine atmos_SOx_chem(pwt,temp,pfull, phalf, dt, lwc, & end do if ( id_NO3 > 0) then used = send_data ( id_NO3, NO3_diurnal, & - model_time,is_in=is,js_in=js,ks_in=1) + diag_time,is_in=is,js_in=js,ks_in=1) endif if ( id_OH > 0) then used = send_data ( id_OH, OH_diurnal, & - model_time, is_in=is, js_in=js,ks_in=1 ) + diag_time, is_in=is, js_in=js,ks_in=1 ) endif if ( id_HO2 > 0) then used = send_data ( id_HO2, HO2_diurnal, & - model_time, is_in=is, js_in=js,ks_in=1 ) + diag_time, is_in=is, js_in=js,ks_in=1 ) endif if ( id_jH2O2 > 0) then used = send_data ( id_jH2O2, jH2O2_diurnal, & - model_time, is_in=is, js_in=js,ks_in=1 ) + diag_time, is_in=is, js_in=js,ks_in=1 ) endif if (id_ph > 0) then used = send_data ( id_ph, ph, & - model_time,is_in=is,js_in=js,ks_in=1) + diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_o3 > 0) then used = send_data ( id_o3, o3_mmr, & - model_time,is_in=is,js_in=js,ks_in=1) + diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_SO2_chem > 0) then used = send_data ( id_SO2_chem, & - SO2_dt*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + SO2_dt*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_SO4_chem > 0) then used = send_data ( id_SO4_chem, & - SO4_dt*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + SO4_dt*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_SO4_oh_prod > 0) then used = send_data ( id_SO4_oh_prod, & - SO4_oh_prod*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + SO4_oh_prod*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_SO4_o3_prod > 0) then used = send_data ( id_SO4_o3_prod, & - SO4_o3_prod*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + SO4_o3_prod*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_SO4_h2o2_prod > 0) then used = send_data ( id_SO4_h2o2_prod, & - SO4_h2o2_prod*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + SO4_h2o2_prod*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_DMS_chem > 0) then used = send_data ( id_DMS_chem, & - DMS_dt*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + DMS_dt*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_MSA_chem > 0) then used = send_data ( id_MSA_chem, & - MSA_dt*pwt*WTM_S/WTMAIR, model_time,is_in=is,js_in=js,ks_in=1) + MSA_dt*pwt*WTM_S/WTMAIR, diag_time,is_in=is,js_in=js,ks_in=1) endif if (id_H2O2_chem > 0) then used = send_data ( id_H2O2_chem, & - H2O2_dt*pwt, model_time,is_in=is,js_in=js,ks_in=1) + H2O2_dt*pwt, diag_time,is_in=is,js_in=js,ks_in=1) endif end subroutine atmos_SOx_chem diff --git a/src/atmos_shared/tracer_driver/atmos_sulfur_hex.F90 b/src/atmos_shared/tracer_driver/atmos_sulfur_hex.F90 index 4a3f5e95f6..b577424dc6 100644 --- a/src/atmos_shared/tracer_driver/atmos_sulfur_hex.F90 +++ b/src/atmos_shared/tracer_driver/atmos_sulfur_hex.F90 @@ -104,7 +104,7 @@ module atmos_sulfur_hex_mod !---- version number ----- character(len=128) :: version = '$Id: atmos_sulfur_hex.F90,v 19.0 2012/01/06 20:31:28 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains diff --git a/src/atmos_shared/tracer_driver/atmos_tracer_driver.F90 b/src/atmos_shared/tracer_driver/atmos_tracer_driver.F90 index af1a345fdf..56b1a58bd0 100644 --- a/src/atmos_shared/tracer_driver/atmos_tracer_driver.F90 +++ b/src/atmos_shared/tracer_driver/atmos_tracer_driver.F90 @@ -111,7 +111,8 @@ module atmos_tracer_driver_mod use tracer_manager_mod, only : get_tracer_index, & get_number_tracers, & get_tracer_names, & - get_tracer_indices + get_tracer_indices, & + adjust_positive_def use field_manager_mod, only : MODEL_ATMOS use atmos_tracer_utilities_mod, only : & dry_deposition, & @@ -306,8 +307,8 @@ module atmos_tracer_driver_mod type(time_type) :: Time !---- version number ----- -character(len=128) :: version = '$Id: atmos_tracer_driver.F90,v 19.0 2012/01/06 20:31:30 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_tracer_driver.F90,v 20.0 2013/12/13 23:24:10 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains @@ -503,7 +504,10 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & ! For tracers other than specific humdity, cloud amount, ice water and & ! liquid water fill eventual negative values !------------------------------------------------------------------------ - if (n /= nqq .and. n/=nqa .and. n/=nqi .and. n/=nql) then +! does tracer need to be adjusted to remain positive definite? +! if (n /= nqq .and. n/=nqa .and. n/=nqi .and. n/=nql) then + if ( adjust_positive_def(MODEL_ATMOS,n) ) then +! do j=1,jd do k=1,kd temp(:,k) = tracer(:,j,k,n) @@ -526,7 +530,9 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & else tracer(:,:,:,n)=r(:,:,:,n) end if - if (n /= nqq .and. n/=nqa .and. n/=nqi .and. n/=nql) then +! does tracer need to be adjusted to remain positive definite? +! if (n /= nqq .and. n/=nqa .and. n/=nqi .and. n/=nql) then + if ( adjust_positive_def(MODEL_ATMOS,n) ) then do j=1,jd do k=1,kd temp(:,k) = tracer(:,j,k,n) @@ -560,7 +566,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & call get_w10m(z_full(:,:,kd) - z_half(:,:,kd+1), & u(:,:,kd), v(:,:,kd), & rough_mom, u_star, b_star, q_star, & - w10m_ocean, w10m_land, Time, is, js) + w10m_ocean, w10m_land, Time_next, is, js) !----------------------------------------------------------------------- !------Cloud liquid water content !----------------------------------------------------------------------- @@ -615,11 +621,11 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & !------------------------------------------------------------------------ ! output land fraction information, if desired. !------------------------------------------------------------------------ - used = send_data ( id_landfr, frland, Time, is_in =is,js_in=js) - used = send_data ( id_seaicefr, frice, Time, is_in =is,js_in=js) -! used = send_data ( id_snowfr, frsnow, Time, is_in =is,js_in=js) -! used = send_data ( id_vegnfr, vegn_cover, Time, is_in =is,js_in=js) -! used = send_data ( id_vegnlai, vegn_lai, Time, is_in =is,js_in=js) + used = send_data ( id_landfr, frland, Time_next, is_in =is,js_in=js) + used = send_data ( id_seaicefr, frice, Time_next, is_in =is,js_in=js) +! used = send_data ( id_snowfr, frsnow, Time_next, is_in =is,js_in=js) +! used = send_data ( id_vegnfr, vegn_cover, Time_next, is_in =is,js_in=js) +! used = send_data ( id_vegnlai, vegn_lai, Time_next, is_in =is,js_in=js) !------------------------------------------------------------------------ ! For tracers other than specific humdity, cloud amount, ice water and & @@ -632,7 +638,8 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & pwt(:,:,kd), pfull(:,:,kd), & z_half(:,:,kd)-z_half(:,:,kd+1), u_star, & (land > 0.5), dsinku(:,:,n), & - tracer(:,:,kd,n), Time, lon, half_day, & + tracer(:,:,kd,n), Time, Time_next, & + lon, half_day, & drydep_data(n))!, frland, frice, frsnow, & ! vegn_cover, vegn_lai, & ! b_star, z_pbl, rough_mom) @@ -643,17 +650,17 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & if (id_om_ddep > 0) then used = send_data (id_om_ddep, & pwt(:,:,kd)*(dsinku(:,:,nomphilic) + dsinku(:,:,nomphobic)), & - Time, is_in=is, js_in=js) + Time_next, is_in=is, js_in=js) endif if (id_bc_ddep > 0) then used = send_data (id_bc_ddep, & pwt(:,:,kd)*(dsinku(:,:,nbcphilic) + dsinku(:,:,nbcphobic)), & - Time, is_in=is, js_in=js) + Time_next, is_in=is, js_in=js) endif if (id_nh4_ddep_cmip > 0) then used = send_data (id_nh4_ddep_cmip, & 0.018*1.0e03*pwt(:,:,kd)*(dsinku(:,:,nNH4NO3) + dsinku(:,:,nNH4))/WTMAIR, & - Time, is_in=is, js_in=js) + Time_next, is_in=is, js_in=js) endif !---------------------------------------------------------------------- @@ -667,7 +674,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & end do used = send_data (id_nh4_col, & 0.018*1.0e03*suma(:,:)/WTMAIR, & - Time, is_in=is, js_in=js) + Time_next, is_in=is, js_in=js) endif if(id_nh4no3_col > 0) then suma = 0. @@ -676,7 +683,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & end do used = send_data (id_nh4no3_col, & 0.062*1.0e03*suma(:,:)/WTMAIR, & - Time, is_in=is, js_in=js) + Time_next, is_in=is, js_in=js) endif !---------------------------------------------------------------------- @@ -686,43 +693,43 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & used = send_data (id_nh4_cmip, & 0.018*1.0e03* (tracer(:,:,:,nNH4NO3) + & tracer(:,:,:,nNH4)) /WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if (id_nh4_cmipv2 > 0) then used = send_data (id_nh4_cmipv2, & 0.018*1.0e03*rho(:,:,:)* (tracer(:,:,:,nNH4NO3) + & tracer(:,:,:,nNH4)) /WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if(id_nh4no3_cmip > 0) then used = send_data (id_nh4no3_cmip, & 0.062*1.0e03*tracer(:,:,:,nNH4NO3)/WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if(id_nh4no3_cmipv2 > 0) then used = send_data (id_nh4no3_cmipv2, & 0.062*1.0e03*rho(:,:,:)*tracer(:,:,:,nNH4NO3)/WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if(id_so2_cmip > 0) then used = send_data (id_so2_cmip, & 0.064*1.0e03*tracer(:,:,:,nSO2_cmip)/WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if(id_so2_cmipv2 > 0) then used = send_data (id_so2_cmipv2, & 0.064*1.0e03*rho(:,:,:)*tracer(:,:,:,nSO2_cmip)/WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if(id_dms_cmip > 0) then used = send_data (id_dms_cmip, & 0.062*1.0e03*tracer(:,:,:,nDMS_cmip)/WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif if(id_dms_cmipv2 > 0) then used = send_data (id_dms_cmipv2, & 0.062*1.0e03*rho(:,:,:)*tracer(:,:,:,nDMS_cmip)/WTMAIR, & - Time, is_in=is, js_in=js, ks_in=1) + Time_next, is_in=is, js_in=js, ks_in=1) endif !------------------------------------------------------------------------ @@ -880,7 +887,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & tracer(:,:,:,nomphobic), rtndomphob, & tracer(:,:,:,nomphilic), rtndomphil, & tracer(:,:,:,noh), & - Time,is,ie,js,je) + Time_next,is,ie,js,je) rdt(:,:,:,nbcphobic)=rdt(:,:,:,nbcphobic)+rtndbcphob(:,:,:) rdt(:,:,:,nbcphilic)=rdt(:,:,:,nbcphilic)+rtndbcphil(:,:,:) rdt(:,:,:,nomphobic)=rdt(:,:,:,nomphobic)+rtndomphob(:,:,:) @@ -899,7 +906,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & lon,lat,land,pwt, & z_half, pfull, w10m_land, t, rh, & tracer(:,:,:,ndust1), rtnd, dust_emis(:,:,1), & - dust_settl(:,:,1), Time, & + dust_settl(:,:,1), Time, Time_next, & is,ie,js,je, kbot) rdt(:,:,:,ndust1)=rdt(:,:,:,ndust1)+rtnd(:,:,:) endif @@ -912,7 +919,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & lon,lat,land,pwt, & z_half, pfull, w10m_land, t, rh, & tracer(:,:,:,ndust2), rtnd, dust_emis(:,:,2), & - dust_settl(:,:,2), Time, & + dust_settl(:,:,2), Time, Time_next, & is,ie,js,je, kbot) rdt(:,:,:,ndust2)=rdt(:,:,:,ndust2)+rtnd(:,:,:) endif @@ -925,7 +932,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & lon,lat,land,pwt, & z_half, pfull, w10m_land, t, rh, & tracer(:,:,:,ndust3), rtnd, dust_emis(:,:,3), & - dust_settl(:,:,3), Time, & + dust_settl(:,:,3), Time, Time_next, & is,ie,js,je, kbot) rdt(:,:,:,ndust3)=rdt(:,:,:,ndust3)+rtnd(:,:,:) endif @@ -938,7 +945,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & lon,lat,land,pwt, & z_half, pfull, w10m_land, t, rh, & tracer(:,:,:,ndust4), rtnd, dust_emis(:,:,4), & - dust_settl(:,:,4), Time, & + dust_settl(:,:,4), Time, Time_next, & is,ie,js,je, kbot) rdt(:,:,:,ndust4)=rdt(:,:,:,ndust4)+rtnd(:,:,:) endif @@ -951,7 +958,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & lon,lat,land,pwt, & z_half, pfull, w10m_land, t, rh, & tracer(:,:,:,ndust5), rtnd, dust_emis(:,:,5), & - dust_settl(:,:,5), Time, & + dust_settl(:,:,5), Time, Time_next, & is,ie,js,je, kbot) rdt(:,:,:,ndust5)=rdt(:,:,:,ndust5)+rtnd(:,:,:) endif @@ -962,13 +969,13 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & used = send_data (id_dust_ddep, all_dust_settl(:,:) + & pwt(:,:,kd)*(dsinku(:,:,ndust1) + dsinku(:,:,ndust2) + & dsinku(:,:,ndust3) + dsinku(:,:,ndust4) + & - dsinku(:,:,ndust5)), Time, is_in=is, js_in=js) + dsinku(:,:,ndust5)), Time_next, is_in=is, js_in=js) endif if (id_dust_emis > 0) then used = send_data (id_dust_emis, & dust_emis(:,:,1) + dust_emis(:,:,2) + & dust_emis(:,:,3) + dust_emis(:,:,4) + & - dust_emis(:,:,5), Time, is_in=is, js_in=js) + dust_emis(:,:,5), Time_next, is_in=is, js_in=js) endif call mpp_clock_end (dust_clock) @@ -986,7 +993,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & z_half, pfull, w10m_ocean, t, rh, & tracer(:,:,:,nseasalt1), rtnd, dt, & ssalt_settl(:,:,1), ssalt_emis(:,:,1), & - Time,is,ie,js,je, kbot) + Time,Time_next,is,ie,js,je, kbot) rdt(:,:,:,nseasalt1)=rdt(:,:,:,nseasalt1)+rtnd(:,:,:) endif if (nseasalt2 > 0) then @@ -999,7 +1006,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & z_half, pfull, w10m_ocean, t, rh, & tracer(:,:,:,nseasalt2), rtnd, dt, & ssalt_settl(:,:,2), ssalt_emis(:,:,2), & - Time,is,ie,js,je, kbot) + Time,Time_next,is,ie,js,je, kbot) rdt(:,:,:,nseasalt2)=rdt(:,:,:,nseasalt2)+rtnd(:,:,:) endif if (nseasalt3 > 0) then @@ -1012,7 +1019,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & z_half, pfull, w10m_ocean, t, rh, & tracer(:,:,:,nseasalt3), rtnd, dt, & ssalt_settl(:,:,3), ssalt_emis(:,:,3), & - Time,is,ie,js,je, kbot) + Time,Time_next,is,ie,js,je, kbot) rdt(:,:,:,nseasalt3)=rdt(:,:,:,nseasalt3)+rtnd(:,:,:) endif if (nseasalt4 > 0) then @@ -1025,7 +1032,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & z_half, pfull, w10m_ocean, t, rh, & tracer(:,:,:,nseasalt4), rtnd, dt, & ssalt_settl(:,:,4), ssalt_emis(:,:,4), & - Time,is,ie,js,je, kbot) + Time,Time_next,is,ie,js,je, kbot) rdt(:,:,:,nseasalt4)=rdt(:,:,:,nseasalt4)+rtnd(:,:,:) endif if (nseasalt5 > 0) then @@ -1038,7 +1045,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & z_half, pfull, w10m_ocean, t, rh, & tracer(:,:,:,nseasalt5), rtnd, dt, & ssalt_settl(:,:,5), ssalt_emis(:,:,5), & - Time,is,ie,js,je, kbot) + Time,Time_next,is,ie,js,je, kbot) rdt(:,:,:,nseasalt5)=rdt(:,:,:,nseasalt5)+rtnd(:,:,:) endif if (id_ssalt_ddep > 0) then @@ -1048,13 +1055,13 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & used = send_data (id_ssalt_ddep, all_salt_settl(:,:) + & pwt(:,:,kd)*(dsinku(:,:,nseasalt1) + dsinku(:,:,nseasalt2) + & dsinku(:,:,nseasalt3) + dsinku(:,:,nseasalt4) + & - dsinku(:,:,nseasalt5)), Time, is_in=is, js_in=js) + dsinku(:,:,nseasalt5)), Time_next, is_in=is, js_in=js) endif if (id_ssalt_emis > 0) then used = send_data (id_ssalt_emis, & ssalt_emis(:,:,1) + ssalt_emis(:,:,2) + & ssalt_emis(:,:,3) + ssalt_emis(:,:,4) + & - ssalt_emis(:,:,5), Time, is_in=is, js_in=js) + ssalt_emis(:,:,5), Time_next, is_in=is, js_in=js) endif call mpp_clock_end (seasalt_clock) @@ -1071,19 +1078,20 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & call mpp_clock_begin (sulfur_clock) call atmos_DMS_emission(lon, lat, area, ocn_flx_fraction, t_surf_rad, & - w10m_ocean, pwt, rtnddms, Time, is,ie,js,je,kbot) + w10m_ocean, pwt, rtnddms, Time, Time_next, is,ie,js,je,kbot) rdt(:,:,kd,nDMS) = rdt(:,:,kd,nDMS) + rtnddms(:,:,kd) call atmos_SOx_emission(lon, lat, area, land, & z_pbl, z_half, phalf, pwt, rtndso2, rtndso4, & - Time, is,ie,js,je,kbot) + Time, Time_next, is,ie,js,je,kbot) rdt(:,:,:,nSO2) = rdt(:,:,:,nSO2) + rtndso2(:,:,:) rdt(:,:,:,nSO4) = rdt(:,:,:,nSO4) + rtndso4(:,:,:) call atmos_SOx_chem( pwt, t, pfull, phalf, dt, lwc, & jday,hour,minute,second,lat,lon, & tracer(:,:,:,nSO2), tracer(:,:,:,nSO4), tracer(:,:,:,nDMS), & tracer(:,:,:,nMSA), tracer(:,:,:,nH2O2), & + tracer(:,:,:,noh), & rtndso2, rtndso4, rtnddms, rtndmsa, rtndh2o2, & - Time,is,ie,js,je,kbot) + Time,Time_next, is,ie,js,je,kbot) rdt(:,:,:,nSO2) = rdt(:,:,:,nSO2) + rtndso2(:,:,:) rdt(:,:,:,nSO4) = rdt(:,:,:,nSO4) + rtndso4(:,:,:) rdt(:,:,:,nDMS) = rdt(:,:,:,nDMS) + rtnddms(:,:,:) @@ -1102,7 +1110,7 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & call mpp_clock_begin (SOA_clock) call atmos_SOA_chem(pwt,t,pfull,phalf,dt, & jday,hour,minute,second,lat,lon, & - tracer(:,:,:,nSOA),rtnd, Time,is,ie,js,je,kbot ) + tracer(:,:,:,nSOA),rtnd, Time,Time_next,is,ie,js,je,kbot ) rdt(:,:,:,nSOA)=rdt(:,:,:,nSOA)+rtnd(:,:,:) call mpp_clock_end (SOA_clock) @@ -1143,11 +1151,11 @@ subroutine atmos_tracer_driver (is, ie, js, je, Time, lon, lat, & if (nco2 > ntp ) call error_mesg ('Tracer_driver', & 'Number of tracers < number for co2', FATAL) call mpp_clock_begin (co2_clock) - call atmos_co2_emissions (is, ie, js, je, Time, dt, pwt, tracer(:,:,:,nco2), & + call atmos_co2_emissions (is, ie, js, je, Time, Time_next, dt, pwt, tracer(:,:,:,nco2), & tracer(:,:,:,nsphum), rtndco2_emis, kbot) rdt(:,:,:,nco2)=rdt(:,:,:,nco2)+rtndco2_emis(:,:,:) - call atmos_co2_sourcesink (is, ie, js, je, Time, dt, pwt, tracer(:,:,:,nco2), & + call atmos_co2_sourcesink (is, ie, js, je, Time, Time_next, dt, pwt, tracer(:,:,:,nco2), & tracer(:,:,:,nsphum), rtndco2) rdt(:,:,:,nco2)=rdt(:,:,:,nco2)+rtndco2(:,:,:) call mpp_clock_end (co2_clock) diff --git a/src/atmos_shared/tracer_driver/atmos_tracer_utilities.F90 b/src/atmos_shared/tracer_driver/atmos_tracer_utilities.F90 index d0b7427458..8baf3d156f 100644 --- a/src/atmos_shared/tracer_driver/atmos_tracer_utilities.F90 +++ b/src/atmos_shared/tracer_driver/atmos_tracer_utilities.F90 @@ -72,8 +72,8 @@ module atmos_tracer_utilities_mod sjl_fillz !---- version number ----- -character(len=128) :: version = '$Id: atmos_tracer_utilities.F90,v 19.0 2012/01/06 20:31:32 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: atmos_tracer_utilities.F90,v 20.0 2013/12/13 23:24:13 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. @@ -457,7 +457,7 @@ end subroutine write_namelist_values !-! dummy interface. -! Arguments: -! timestamp (optional, intent(in)) : A character string that represents the model time, -! used for writing restart. timestamp will append to -! the any restart file name as a prefix. -! -! -subroutine topo_drag_restart(timestamp) - character(len=*), intent(in), optional :: timestamp - -end subroutine topo_drag_restart -!subroutine dry_deposition( n, is, js, u, v, T, pwt, pfull, dz, & u_star, landmask, dsinku, tracer, Time, & - lon, half_day, drydep_data) + Time_next, lon, half_day, drydep_data) ! When formulation of dry deposition is resolved perhaps use the following? ! landfr, seaice_cn, snow_area, & ! vegn_cover, vegn_lai, & @@ -567,7 +567,7 @@ subroutine dry_deposition( n, is, js, u, v, T, pwt, pfull, dz, & !real, intent(in), dimension(:,:) :: landfr, z_pbl, b_star, rough_mom !real, intent(in), dimension(:,:) :: seaice_cn, snow_area, vegn_cover, & ! vegn_lai -type(time_type), intent(in) :: Time +type(time_type), intent(in) :: Time, Time_next type(interpolate_type),intent(inout) :: drydep_data real, intent(out), dimension(:,:) :: dsinku @@ -791,7 +791,7 @@ subroutine dry_deposition( n, is, js, u, v, T, pwt, pfull, dz, & case default diag_scale = 1. end select - used = send_data ( id_tracer_ddep(n), dsinku*pwt/diag_scale, Time, & + used = send_data ( id_tracer_ddep(n), dsinku*pwt/diag_scale, Time_next, & is_in =is,js_in=js) endif if (id_tracer_ddep_cmip(n) > 0 ) then @@ -808,11 +808,11 @@ subroutine dry_deposition( n, is, js, u, v, T, pwt, pfull, dz, & case default diag_scale = 1. end select - used = send_data ( id_tracer_ddep_cmip(n), dsinku*pwt/diag_scale,Time, & + used = send_data ( id_tracer_ddep_cmip(n), dsinku*pwt/diag_scale,Time_next, & is_in =is,js_in=js) endif if (id_tracer_dvel(n) > 0 ) then - used = send_data ( id_tracer_dvel(n), drydep_vel, Time, & + used = send_data ( id_tracer_dvel(n), drydep_vel, Time_next, & is_in =is,js_in=js) end if end subroutine dry_deposition @@ -1955,12 +1955,12 @@ end subroutine GET_RH ! ###################################################################### ! subroutine get_w10m(z_full, u, v, rough_mom,u_star, b_star, q_star, & - w10m_ocean, w10m_land, Time, is,js) + w10m_ocean, w10m_land, Time_next, is,js) real, intent(in), dimension(:,:) :: z_full, u, v real, intent(in), dimension(:,:) :: rough_mom real, intent(in), dimension(:,:) :: u_star, b_star, q_star -type(time_type), intent(in) :: Time +type(time_type), intent(in) :: Time_next integer, intent(in) :: is,js logical :: used @@ -1990,12 +1990,12 @@ subroutine get_w10m(z_full, u, v, rough_mom,u_star, b_star, q_star, & ! Send the scaling factor if (id_delm > 0 ) then - used = send_data ( id_delm, del_m, Time, is_in=is,js_in=js ) + used = send_data ( id_delm, del_m, Time_next, is_in=is,js_in=js ) endif ! Send the 10m wind speed data to the diag_manager for output. if (id_w10m > 0 ) then - used = send_data ( id_w10m, w10m_land, Time, is_in=is,js_in=js ) + used = send_data ( id_w10m, w10m_land, Time_next, is_in=is,js_in=js ) endif end subroutine get_w10m diff --git a/src/atmos_shared/tracer_driver/stratchem/strat_chem_driver.F90 b/src/atmos_shared/tracer_driver/stratchem/strat_chem_driver.F90 index ffe375de77..8ebea8e236 100644 --- a/src/atmos_shared/tracer_driver/stratchem/strat_chem_driver.F90 +++ b/src/atmos_shared/tracer_driver/stratchem/strat_chem_driver.F90 @@ -23,7 +23,7 @@ module strat_chem_driver_mod !----------- ****** VERSION NUMBER ******* --------------------------- character(len=128) :: version = '$Id: strat_chem_driver.F90,v 19.0 2012/01/06 20:32:12 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. !------- interfaces -------- diff --git a/src/atmos_shared/tracer_driver/tropchem/m_tracname.F90 b/src/atmos_shared/tracer_driver/tropchem/m_tracname.F90 index 1011fe1f52..3f56b60d44 100644 --- a/src/atmos_shared/tracer_driver/tropchem/m_tracname.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/m_tracname.F90 @@ -11,7 +11,7 @@ module m_tracname_mod implicit none character(len=128), parameter :: version = '$Id: m_tracname.F90,v 19.0 2012/01/06 20:32:14 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. save diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_chem_utls.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_chem_utls.F90 index bbf488a915..1dc2433702 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_chem_utls.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_chem_utls.F90 @@ -13,7 +13,7 @@ module mo_chem_utls_mod logical :: do_ox character(len=128), parameter :: version = '$Id: mo_chem_utls.F90,v 19.0 2012/01/06 20:32:46 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_chemdr.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_chemdr.F90 index 1841ab6ae4..9d70b55123 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_chemdr.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_chemdr.F90 @@ -9,7 +9,7 @@ module mo_chemdr_mod ! save character(len=128), parameter :: version = '$Id: mo_chemdr.F90,v 19.0 2012/01/06 20:33:18 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_chemini.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_chemini.F90 index ef6839af10..3ea460663e 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_chemini.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_chemini.F90 @@ -6,7 +6,7 @@ module mo_chemini_mod public :: chemini character(len=128), parameter :: version = '$Id: mo_chemini.F90,v 19.0 2012/01/06 20:33:20 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_exp_slv.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_exp_slv.F90 index ca4b6534e5..8b635d178e 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_exp_slv.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_exp_slv.F90 @@ -21,7 +21,7 @@ module MO_EXP_SOL_MOD logical :: class_hist_loss = .false. character(len=128), parameter :: version = '$Id: mo_exp_slv.F90,v 19.0 2012/01/06 20:33:52 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_fastjx.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_fastjx.F90 index b4081374e6..c1b819a170 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_fastjx.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_fastjx.F90 @@ -261,8 +261,8 @@ module MO_FASTJX_MOD !----------------------------------------------------------------------- ! version number and tagname. !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: mo_fastjx.F90,v 19.0 2012/01/06 20:33:53 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: mo_fastjx.F90,v 20.0 2013/12/13 23:24:59 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' ! include 'parm_CTM.f' for fast-JX code v5.3+ (prather 6/05) ! @@ -705,6 +705,7 @@ subroutine fastjx_photo( U0, SOLF, phalf1, zhalf1, pfull1, tfull, & !----------------------------------------------------------------------- ZPJ(:,:) = 0.d0 FFF(:,:) = 0.d0 + FREFI = 0.d0 FREFL = 0.d0 FREFS = 0.d0 @@ -916,7 +917,7 @@ subroutine fastjx_photo( U0, SOLF, phalf1, zhalf1, pfull1, tfull, & !---set surface reflectance RFLECT = srf_alb !SA(ILNG,JLAT) - RFL(:) = max(0.d0,min(1.d0,RFLECT)) + RFL(:) = max(0.0,min(1.0,RFLECT)) !----------------------------------------------------------------------- !---Loop over all wavelength bins to calc mean actinic flux AVGF(L) !----------------------------------------------------------------------- @@ -1863,7 +1864,7 @@ subroutine JRATET(PPJ,TTJ,FFF, VALJL) do J = 4,NJVAL if (TQQ(2,J) .gt. TQQ(1,J)) then - TFACT = max(0.d0,min(1.d0,(TT-TQQ(1,J))/(TQQ(2,J)-TQQ(1,J)))) + TFACT = max(0.0,min(1.0,(TT-TQQ(1,J))/(TQQ(2,J)-TQQ(1,J)))) else TFACT = 0.d0 endif @@ -1899,7 +1900,7 @@ subroutine JRATET(PPJ,TTJ,FFF, VALJL) !---IV=NJVAL-1 = Xsect (total abs) for Acetone - pre-calc Temp interp fa IV = NJVAL-1 TFACA = (TT-TQQ(1,IV))/(TQQ(2,IV)-TQQ(1,IV)) - TFACA = max(0.d0, min(1.d0, TFACA)) + TFACA = max(0.0, min(1.0, TFACA)) !---IV=NJVAL = Q2 for Acetone=>(2), specifically designed for quadratic !--- but force to Q2=0 by 210K IV = NJVAL @@ -1907,10 +1908,10 @@ subroutine JRATET(PPJ,TTJ,FFF, VALJL) if (TT .lt. TQQ(1,IV)) then TFAC0 = (TT - 210.d0)/(TQQ(1,IV)-210.d0) endif - TFAC0 = max(0.d0, min(1.d0, TFAC0)) + TFAC0 = max(0.0, min(1.0, TFAC0)) !---IV=NJVAL+1 = Q1A for Acetone => (1), allow full range of T = 200K-30 IV = NJVAL+1 - TT200 = min(300.d0, max(200.d0, TT)) + TT200 = min(300.0, max(200.0, TT)) TFAC1 = (TT200-TQQ(1,IV))/(TQQ(2,IV)-TQQ(1,IV)) !---IV=NJVAL+2 = Q1B for Acetone => (1) IV = NJVAL+2 @@ -2590,7 +2591,7 @@ subroutine SPHERE2(GMU,RAD,ZHL,ZZHT,AMF2,L1_) do II = J-1,1,-1 DIFF = RZ2(II+1)*sqrt(1.0d0-XMU1**2)-RZ2(II) ! filter - if (II.eq.1) DIFF = max(DIFF,0.d0) + if (II.eq.1) DIFF = max(DIFF,0.0) ! Tangent height below current level - beam passes through twice if (DIFF .lt. 0.0d0) then XMU2 = sqrt(1.0d0 - (1.0d0-XMU1**2)/RQ2(II)) diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_fphoto.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_fphoto.F90 index 519be20ee6..6234ca966b 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_fphoto.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_fphoto.F90 @@ -24,7 +24,7 @@ module MO_FPHOTO_MOD public :: fprate_init, fphoto character(len=128) :: version = '$Id: mo_fphoto.F90,v 19.0 2012/01/06 20:33:54 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' integer :: fastjx_clock integer, parameter :: jdim = JVN_ ! number of fastjx species 62 diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_hook.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_hook.F90 index 2254869f80..1b404868b5 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_hook.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_hook.F90 @@ -26,7 +26,7 @@ module MOZ_HOOK_MOD real :: lat25 character(len=128), parameter :: version = '$Id: mo_hook.F90,v 19.0 2012/01/06 20:33:56 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_imp_slv.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_imp_slv.F90 index 4be6b26cc1..a6ef1022ef 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_imp_slv.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_imp_slv.F90 @@ -46,8 +46,8 @@ module mo_imp_sol_mod type(hst_pl), private, allocatable :: imp_hst_loss(:) logical, private, allocatable :: factor(:) -character(len=128), parameter :: version = '$Id: mo_imp_slv.F90,v 17.0.4.1.2.1.2.1.4.1.2.1 2012/02/01 13:40:55 z1l Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: version = '$Id: mo_imp_slv.F90,v 20.0 2013/12/13 23:25:05 fms Exp $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains @@ -85,13 +85,13 @@ subroutine imp_slv_init( verbose_in, retain_cm3_bugs ) factor(:) = .true. eps(:) = rel_err - if (retain_cm3_bugs) then - ox_ndx = get_spc_ndx( 'OX' ) - else - ox_ndx = get_spc_ndx ('O3') + if (retain_cm3_bugs) then + ox_ndx = get_spc_ndx( 'OX' ) + else + ox_ndx = get_spc_ndx ('O3') + endif o1d_ndx = get_spc_ndx('O1D') h2o_ndx = get_spc_ndx('H2O') - endif if( ox_ndx > 0 ) then eps(ox_ndx) = high_rel_err else diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_jpl.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_jpl.F90 index 1a010e5d1a..45d44783eb 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_jpl.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_jpl.F90 @@ -2,7 +2,7 @@ module MO_JPL_MOD implicit none character(len=128), parameter :: version = '$Id: mo_jpl.F90,v 13.0 2006/03/28 21:16:17 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_photo.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_photo.F90 index be9f4379c1..d5621cd3c1 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_photo.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_photo.F90 @@ -88,7 +88,7 @@ module MO_PHOTO_MOD real :: o3_column_top, jno_scale_factor character(len=128), parameter :: version = '$Id: mo_photo.F90,v 19.0 2012/01/06 20:34:00 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. integer :: photo_clock diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_read_sim_chm.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_read_sim_chm.F90 index e2f593ae65..f163c36be6 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_read_sim_chm.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_read_sim_chm.F90 @@ -6,7 +6,7 @@ module MO_READ_SIM_CHM_MOD implicit none character(len=128), parameter :: version = '$Id: mo_read_sim_chm.F90,v 19.0 2012/01/06 20:34:02 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_rodas_slv.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_rodas_slv.F90 index 43bc2dceca..92e2a86632 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_rodas_slv.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_rodas_slv.F90 @@ -18,7 +18,7 @@ module mo_rodas_sol_mod real :: err_wghts(max(1,clscnt5)) character(len=128), parameter :: version = '$Id: mo_rodas_slv.F90,v 19.0 2012/01/06 20:34:04 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_setinv.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_setinv.F90 index f95c2b971a..42f6d3ec75 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_setinv.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_setinv.F90 @@ -2,7 +2,7 @@ module MO_SETINV_MOD implicit none character(len=128), parameter :: version = '$Id: mo_setinv.F90,v 19.0 2012/01/06 20:34:06 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_setsox.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_setsox.F90 index b3b1841ca4..6093207cf0 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_setsox.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_setsox.F90 @@ -2,7 +2,7 @@ module MO_SETSOX_MOD implicit none character(len=128), parameter :: version = '$Id: mo_setsox.F90,v 19.0 2012/01/06 20:34:08 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. CONTAINS diff --git a/src/atmos_shared/tracer_driver/tropchem/mo_usrrxt.F90 b/src/atmos_shared/tracer_driver/tropchem/mo_usrrxt.F90 index b16eb29980..0835acdf7d 100644 --- a/src/atmos_shared/tracer_driver/tropchem/mo_usrrxt.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/mo_usrrxt.F90 @@ -24,7 +24,7 @@ module mo_usrrxt_mod real, parameter :: d378 = 1. - d622 character(len=128), parameter :: version = '$Id: mo_usrrxt.F90,v 19.0 2012/01/06 20:34:10 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/moz.mat.F90 b/src/atmos_shared/tracer_driver/tropchem/moz.mat.F90 index fe063e804b..ef108a857d 100644 --- a/src/atmos_shared/tracer_driver/tropchem/moz.mat.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/moz.mat.F90 @@ -2,7 +2,7 @@ module MO_EXP_PROD_LOSS_MOD implicit none character(len=128), parameter :: version = '$Id: moz.mat.F90,v 19.0 2012/01/06 20:34:12 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/moz.mods.F90 b/src/atmos_shared/tracer_driver/tropchem/moz.mods.F90 index 457b846ace..aeebdae1a8 100644 --- a/src/atmos_shared/tracer_driver/tropchem/moz.mods.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/moz.mods.F90 @@ -7,7 +7,7 @@ module mo_grid_mod save character(len=128), parameter :: version = '$Id: moz.mods.F90,v 19.0 2012/01/06 20:34:14 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. integer, parameter :: & diff --git a/src/atmos_shared/tracer_driver/tropchem/moz.subs.F90 b/src/atmos_shared/tracer_driver/tropchem/moz.subs.F90 index da716d86ed..9299aae7d8 100644 --- a/src/atmos_shared/tracer_driver/tropchem/moz.subs.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/moz.subs.F90 @@ -5,7 +5,7 @@ module mo_setrxt_mod public :: setrxt character(len=128), parameter :: version = '$Id: moz.subs.F90,v 19.0 2012/01/06 20:34:16 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. contains diff --git a/src/atmos_shared/tracer_driver/tropchem/strat_chem_utilities.F90 b/src/atmos_shared/tracer_driver/tropchem/strat_chem_utilities.F90 index 39dc1ef0eb..e494c9874b 100644 --- a/src/atmos_shared/tracer_driver/tropchem/strat_chem_utilities.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/strat_chem_utilities.F90 @@ -265,6 +265,7 @@ subroutine strat_chem_dcly_dt(Time, phalf, is, js, age, cly, bry, dclydt, dbrydt type(time_type) :: cfc_Time, cfc_base_Time !--lwh real, dimension(size(age,1),size(age,2),nspecies_tropc) :: cfc +character(len=256) :: err_msg call get_date( Time, iyear, imon, iday, ihour, imin, isec ) @@ -345,7 +346,11 @@ subroutine strat_chem_dcly_dt(Time, phalf, is, js, age, cly, bry, dclydt, dbrydt else if (cfc_Time > tropc_Time(ntime_tropc)) then cfc_Time = tropc_Time(ntime_tropc) end if - call time_interp( cfc_Time, tropc_Time(:), dt1, it1, it2 ) + call time_interp( cfc_Time, tropc_Time(:), dt1, it1, it2, err_msg=err_msg ) + if(err_msg /= '') then + call error_mesg('strat_chem_dcly_dt', trim(err_msg) , FATAL) + endif + cfc(i,j,:) = tropc(it1,:)*(1-dt1) + tropc(it2,:)*dt1 !--lwh @@ -1274,7 +1279,7 @@ subroutine strat_chem_get_extra_h2o( h2o, age, ch4, Time, extra_h2o ) integer :: i, k, il, kl, index1, index2 real :: frac, ch4_trop, min_h2o type(time_type) :: time_trop - +character(len=256) :: err_msg il = size(h2o,1) kl = size(h2o,2) @@ -1287,7 +1292,10 @@ subroutine strat_chem_get_extra_h2o( h2o, age, ch4, Time, extra_h2o ) else time_trop = increment_time( Time, -NINT(age(i,k)/tfact), 0) end if - call time_interp( time_trop, ch4_time(:), frac, index1, index2 ) + call time_interp( time_trop, ch4_time(:), frac, index1, index2, err_msg=err_msg ) + if(err_msg /= '') then + call error_mesg('strat_chem_get_extra_h2o', trim(err_msg) , FATAL) + endif ch4_trop = ch4_value(index1) + frac*(ch4_value(index2)-ch4_value(index1)) min_h2o = 2. * MAX( 0., ch4_trop - ch4(i,k) ) if (age(i,k) > 0.1) then diff --git a/src/atmos_shared/tracer_driver/tropchem/tropchem_driver.F90 b/src/atmos_shared/tracer_driver/tropchem/tropchem_driver.F90 index 9213e9e156..a3f5def9f9 100644 --- a/src/atmos_shared/tracer_driver/tropchem/tropchem_driver.F90 +++ b/src/atmos_shared/tracer_driver/tropchem/tropchem_driver.F90 @@ -313,8 +313,8 @@ module tropchem_driver_mod !---- version number --------------------------------------------------- -character(len=128), parameter :: version = '$Id: tropchem_driver.F90,v 19.0 2012/01/06 20:34:20 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: version = '$Id: tropchem_driver.F90,v 20.0 2013/12/13 23:25:19 fms Exp $' +character(len=128), parameter :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- contains @@ -522,35 +522,36 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, ! ... read in the surface emissions, using interpolator !----------------------------------------------------------------------- if (has_emis(n)) then - call read_2D_emis_data( inter_emis(n), emis, Time, & + call read_2D_emis_data( inter_emis(n), emis, Time, Time_next, & emis_field_names(n)%field_names, & diurnal_emis(n), coszen, half_day, lon, & is, js, id_emis(n) ) if (tracnam(n) == 'NO') then emisz(:,:,n) = emis(:,:) if (id_no_emis_cmip > 0) then - used = send_data(id_no_emis_cmip,emis*1.0e04*0.030/AVOGNO,Time, & + used = send_data(id_no_emis_cmip,emis*1.0e04*0.030/AVOGNO, & + Time_next, & is_in=is,js_in=js) endif endif if (tracnam(n) == 'CO') then emisz(:,:,n) = emis(:,:) if (id_co_emis_cmip > 0) then - used = send_data(id_co_emis_cmip,emis*1.0e04*0.028/AVOGNO,Time, & + used = send_data(id_co_emis_cmip,emis*1.0e04*0.028/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif if (tracnam(n) == 'SO2') then emisz(:,:,n) = emis(:,:) if (id_so2_emis_cmip > 0) then - used = send_data(id_so2_emis_cmip,emis*1.0e04*0.064/AVOGNO,Time, & + used = send_data(id_so2_emis_cmip,emis*1.0e04*0.064/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif if (tracnam(n) == 'NH3') then emisz(:,:,n) = emis(:,:) if (id_nh3_emis_cmip > 0) then - used = send_data(id_nh3_emis_cmip,emis*1.0e04*0.017/AVOGNO,Time, & + used = send_data(id_nh3_emis_cmip,emis*1.0e04*0.017/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif @@ -571,7 +572,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, ! ... read in the 3-D emissions, using interpolator !----------------------------------------------------------------------- if (has_emis3d(n)) then - call read_3D_emis_data( inter_emis3d(n), emis3d, Time, phalf, & + call read_3D_emis_data( inter_emis3d(n), emis3d, Time, Time_next,phalf, & emis3d_field_names(n)%field_names, & diurnal_emis3d(n), coszen, half_day, lon, & is, js, id_emis3d(n) ) @@ -610,7 +611,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, flux_sw_down_vis = flux_sw_down_vis_dir+flux_sw_down_vis_dif - call calc_xactive_isop ( n, Time, lon, lat, oro, pwtsfc, is, js, & + call calc_xactive_isop ( n, Time, Time_next, lon, lat, oro, pwtsfc, is, js, & area, land, tsfcair, flux_sw_down_vis, & coszen, emis, id_gamma_lai_age=id_glaiage, & id_gamma_temp=id_gtemp, id_gamma_light=id_glight, & @@ -633,7 +634,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, end if end if case ('DMS') - call calc_xactive_emis( n, Time, lon, lat, pwt, is, ie, js, je, & + call calc_xactive_emis( n, Time, Time_next,lon, lat, pwt, is, ie, js, je, & area, land, ocn_flx_fraction,tsurf, w10m, xactive_emis, & kbot=kbot, id_emis_diag=id_xactive_emis(n) ) if (has_xactive_emis(n)) then @@ -653,7 +654,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, call interpolator( inter_aircraft_emis(n), Time, phalf, & airc_emis(:,:,:,n), trim(airc_names(n)),is,js) if(id_airc(n) > 0)& - used = send_data(id_airc(n),airc_emis(:,:,:,n),Time, is_in=is, js_in=js) + used = send_data(id_airc(n),airc_emis(:,:,:,n),Time_next, is_in=is, js_in=js) if (tracnam(n) == 'CO') then do k=1, size(emis3d,3) @@ -680,25 +681,25 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, end if if (tracnam(n) == 'NO') then if (id_no_emis_cmip2 > 0) then - used = send_data(id_no_emis_cmip2,emisz(:,:,n)*1.0e04*0.030/AVOGNO,Time, & + used = send_data(id_no_emis_cmip2,emisz(:,:,n)*1.0e04*0.030/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif if (tracnam(n) == 'CO') then if (id_co_emis_cmip2 > 0) then - used = send_data(id_co_emis_cmip2,emisz(:,:,n)*1.0e04*0.028/AVOGNO,Time, & + used = send_data(id_co_emis_cmip2,emisz(:,:,n)*1.0e04*0.028/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif if (tracnam(n) == 'SO2') then if (id_so2_emis_cmip2 > 0) then - used = send_data(id_so2_emis_cmip2,emisz(:,:,n)*1.0e04*0.064/AVOGNO,Time, & + used = send_data(id_so2_emis_cmip2,emisz(:,:,n)*1.0e04*0.064/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif if (tracnam(n) == 'NH3') then if (id_nh3_emis_cmip2 > 0) then - used = send_data(id_nh3_emis_cmip2,emisz(:,:,n)*1.0e04*0.017/AVOGNO,Time, & + used = send_data(id_nh3_emis_cmip2,emisz(:,:,n)*1.0e04*0.017/AVOGNO,Time_next, & is_in=is,js_in=js) endif endif @@ -719,7 +720,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, ! ... read in the sulfate aerosol concentrations !----------------------------------------------------------------------- call interpolator(sulfate, Time, phalf, sulfate_data, 'sulfate', is,js) - used = send_data(id_sul, sulfate_data, Time, is_in=is, js_in=js) + used = send_data(id_sul, sulfate_data, Time_next, is_in=is, js_in=js) ! call mpp_clock_begin(clock_id) @@ -920,10 +921,10 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, !----------------------------------------------------------------------- do n = 1,pcnstm1 if(id_prod(n)>0) then - used = send_data(id_prod(n),prod(:,:,:,n),Time,is_in=is,js_in=js) + used = send_data(id_prod(n),prod(:,:,:,n),Time_next,is_in=is,js_in=js) end if if(id_loss(n)>0) then - used = send_data(id_loss(n),loss(:,:,:,n),Time,is_in=is,js_in=js) + used = send_data(id_loss(n),loss(:,:,:,n),Time_next,is_in=is,js_in=js) end if if (n == sphum_ndx) then @@ -968,7 +969,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, ! ... output diagnostic tendency !----------------------------------------------------------------------- if(id_chem_tend(n)>0) then - used = send_data( id_chem_tend(n), tend_tmp(:,:,:), Time, is_in=is,js_in=js) + used = send_data( id_chem_tend(n), tend_tmp(:,:,:), Time_next, is_in=is,js_in=js) end if !----------------------------------------------------------------------- @@ -977,7 +978,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, if(has_ubc(n)) then call interpolator(ub(n), Time, phalf, r_ub(:,:,:,n), trim(ub_names(n)), is, js) if(id_ub(n)>0) then - used = send_data(id_ub(n), r_ub(:,:,:,n), Time, is_in=is, js_in=js) + used = send_data(id_ub(n), r_ub(:,:,:,n), Time_next, is_in=is, js_in=js) end if where (pfull(:,:,:) < ub_pres) chem_dt(:,:,:,indices(n)) = (r_ub(:,:,:,n) - r(:,:,:,indices(n))) / relaxed_dt @@ -996,7 +997,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, call time_interp( lbc_Time, lb(n)%gas_time(:), frac, index1, index2 ) r_lb(n) = lb(n)%gas_value(index1) + frac*( lb(n)%gas_value(index2) - lb(n)%gas_value(index1) ) if(id_lb(n)>0) then - used = send_data(id_lb(n), r_lb(n), Time) + used = send_data(id_lb(n), r_lb(n), Time_next) end if where (pfull(:,:,:) > lb_pres) chem_dt(:,:,:,indices(n)) = (r_lb(n) - r(:,:,:,indices(n))) / relaxed_dt_lbc @@ -1008,16 +1009,16 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, ! ...send ox budget(jmao,1/1/2011) !----------------------------------------------------------------------- if(id_prodox>0) then - used = send_data(id_prodox, prodox(:,:,:), Time, is_in=is, js_in=js) + used = send_data(id_prodox, prodox(:,:,:), Time_next, is_in=is, js_in=js) end if if(id_lossox>0) then - used = send_data(id_lossox, lossox(:,:,:), Time, is_in=is, js_in=js) + used = send_data(id_lossox, lossox(:,:,:), Time_next, is_in=is, js_in=js) end if !----------------------------------------------------------------------- ! ... surface concentration diagnostics !----------------------------------------------------------------------- if ( o3_ndx>0 ) then - used = send_data(id_srf_o3, r_temp(:,:,size(r_temp,3),o3_ndx), Time, is_in=is, js_in=js) + used = send_data(id_srf_o3, r_temp(:,:,size(r_temp,3),o3_ndx), Time_next, is_in=is, js_in=js) end if @@ -1074,7 +1075,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, ! ... Cly chemical tendency diagnostic !----------------------------------------------------------------------- if (id_dclydt_chem>0) then - used = send_data(id_dclydt_chem, (cly(:,:,:)-cly0(:,:,:))/dt, Time, is_in=is, js_in=js) + used = send_data(id_dclydt_chem, (cly(:,:,:)-cly0(:,:,:))/dt, Time_next, is_in=is, js_in=js) end if !----------------------------------------------------------------------- @@ -1201,11 +1202,11 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, end if if (cl_ndx>0) then chem_dt(:,:,:,indices(cl_ndx)) = chem_dt(:,:,:,indices(cl_ndx)) + dclydt(:,:,:) - used = send_data(id_dclydt, dclydt, Time, is_in=is, js_in=js) + used = send_data(id_dclydt, dclydt, Time_next, is_in=is, js_in=js) end if if (br_ndx>0) then chem_dt(:,:,:,indices(br_ndx)) = chem_dt(:,:,:,indices(br_ndx)) + dbrydt(:,:,:) - used = send_data(id_dbrydt, dbrydt, Time, is_in=is, js_in=js) + used = send_data(id_dbrydt, dbrydt, Time_next, is_in=is, js_in=js) end if !----------------------------------------------------------------------- @@ -1228,7 +1229,7 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, !----------------------------------------------------------------------- do n = 1,phtcnt if(id_jval(n)>0) then - used = send_data(id_jval(n),jvals(:,:,:,n),Time,is_in=is,js_in=js) + used = send_data(id_jval(n),jvals(:,:,:,n),Time_next,is_in=is,js_in=js) end if end do @@ -1237,26 +1238,26 @@ subroutine tropchem_driver( lon, lat, land, ocn_flx_fraction, pwt, r, chem_dt, !----------------------------------------------------------------------- do n = 1,gascnt if(id_rate_const(n)>0) then - used = send_data(id_rate_const(n),rate_constants(:,:,:,n),Time,is_in=is,js_in=js) + used = send_data(id_rate_const(n),rate_constants(:,:,:,n),Time_next,is_in=is,js_in=js) end if end do !----------------------------------------------------------------------- ! ... Output diagnostics !----------------------------------------------------------------------- - used = send_data(id_volc_aer, strat_aerosol, Time, is_in=is, js_in=js) - used = send_data(id_psc_sat, psc_vmr_save(:,:,:,1), Time, is_in=is, js_in=js) - used = send_data(id_psc_nat, psc_vmr_save(:,:,:,2), Time, is_in=is, js_in=js) - used = send_data(id_psc_ice, psc_vmr_save(:,:,:,3), Time, is_in=is, js_in=js) + used = send_data(id_volc_aer, strat_aerosol, Time_next, is_in=is, js_in=js) + used = send_data(id_psc_sat, psc_vmr_save(:,:,:,1), Time_next, is_in=is, js_in=js) + used = send_data(id_psc_nat, psc_vmr_save(:,:,:,2), Time_next, is_in=is, js_in=js) + used = send_data(id_psc_ice, psc_vmr_save(:,:,:,3), Time_next, is_in=is, js_in=js) if (id_h2o_chem>0) then if (sphum_ndx>0) then - used = send_data(id_h2o_chem, r_temp(:,:,:,sphum_ndx), Time, is_in=is, js_in=js) + used = send_data(id_h2o_chem, r_temp(:,:,:,sphum_ndx), Time_next, is_in=is, js_in=js) else - used = send_data(id_h2o_chem, q(:,:,:)*WTMAIR/WTMH2O, Time, is_in=is, js_in=js) + used = send_data(id_h2o_chem, q(:,:,:)*WTMAIR/WTMH2O, Time_next, is_in=is, js_in=js) end if end if - used = send_data(id_coszen, coszen_local(:,:), Time, is_in=is, js_in=js) - used = send_data(id_imp_slv_nonconv,imp_slv_nonconv(:,:,:),Time,is_in=is,js_in=js) + used = send_data(id_coszen, coszen_local(:,:), Time_next, is_in=is, js_in=js) + used = send_data(id_imp_slv_nonconv,imp_slv_nonconv(:,:,:),Time_next,is_in=is,js_in=js) !----------------------------------------------------------------------- ! ... convert H2O VMR tendency to specific humidity tendency @@ -2098,14 +2099,14 @@ end subroutine tropchem_driver_end ! is, js, id_emis_diag ) ! -subroutine read_2D_emis_data( emis_type, emis, Time, & +subroutine read_2D_emis_data( emis_type, emis, Time, Time_next, & field_names, & Ldiurnal, coszen, half_day, lon, & is, js, id_emis_diag ) type(interpolate_type),intent(inout) :: emis_type real, dimension(:,:),intent(out) :: emis - type(time_type),intent(in) :: Time + type(time_type),intent(in) :: Time, Time_next character(len=*),dimension(:), intent(in) :: field_names logical, intent(in) :: Ldiurnal real, dimension(:,:), intent(in) :: coszen, half_day, lon @@ -2154,7 +2155,7 @@ subroutine read_2D_emis_data( emis_type, emis, Time, & if (present(id_emis_diag)) then if (id_emis_diag > 0) then - used = send_data(id_emis_diag,emis,Time,is_in=is,js_in=js) + used = send_data(id_emis_diag,emis,Time_next,is_in=is,js_in=js) end if end if end subroutine read_2D_emis_data @@ -2176,7 +2177,7 @@ end subroutine read_2D_emis_data ! is, js, id_emis_diag ) ! -subroutine read_3D_emis_data( emis_type, emis, Time, phalf, & +subroutine read_3D_emis_data( emis_type, emis, Time, Time_next, phalf, & field_names, & Ldiurnal, coszen, half_day, lon, & is, js, id_emis_diag ) @@ -2184,7 +2185,7 @@ subroutine read_3D_emis_data( emis_type, emis, Time, phalf, & type(interpolate_type),intent(inout) :: emis_type real, dimension(:,:,:),intent(in) :: phalf real, dimension(:,:,:),intent(out) :: emis - type(time_type),intent(in) :: Time + type(time_type),intent(in) :: Time, Time_next character(len=*),dimension(:), intent(in) :: field_names logical, intent(in) :: Ldiurnal real, dimension(:,:), intent(in) :: coszen, half_day, lon @@ -2232,7 +2233,7 @@ subroutine read_3D_emis_data( emis_type, emis, Time, phalf, & if (present(id_emis_diag)) then if (id_emis_diag > 0) then - used = send_data(id_emis_diag,emis,Time,is_in=is,js_in=js) + used = send_data(id_emis_diag,emis,Time_next,is_in=is,js_in=js) end if end if end subroutine read_3D_emis_data @@ -2251,12 +2252,12 @@ end subroutine read_3D_emis_data ! call calc_xactive_emis( index, emis, Time, is, js, id_emis_diag ) ! -subroutine calc_xactive_emis( index, Time, lon, lat, pwt, is, ie, js, je, & +subroutine calc_xactive_emis( index, Time, Time_next, lon, lat, pwt, is, ie, js, je, & area, land, ocn_flx_fraction, tsurf, w10m, emis, & kbot, id_emis_diag ) integer,intent(in) :: index - type(time_type),intent(in) :: Time + type(time_type),intent(in) :: Time, Time_next real, intent(in), dimension(:,:) :: lon, lat real, intent(in), dimension(:,:,:) :: pwt integer, intent(in) :: is, ie, js, je @@ -2274,7 +2275,7 @@ subroutine calc_xactive_emis( index, Time, lon, lat, pwt, is, ie, js, je, & if (index == dms_ndx) then call atmos_DMS_emission( lon, lat, area, ocn_flx_fraction, tsurf, w10m, pwt, & - emis, Time, is, ie, js, je, kbot ) + emis, Time, Time_next, is, ie, js, je, kbot ) else call error_mesg ('calc_xactive_emis', & 'Interactive emissions not defined for species: '//trim(tracnam(index)), FATAL) @@ -2282,7 +2283,7 @@ subroutine calc_xactive_emis( index, Time, lon, lat, pwt, is, ie, js, je, & if (present(id_emis_diag)) then if (id_emis_diag > 0) then - used = send_data( id_emis_diag, emis, Time, is_in=is, js_in=js) + used = send_data( id_emis_diag, emis, Time_next, is_in=is, js_in=js) end if end if end subroutine calc_xactive_emis @@ -2803,14 +2804,14 @@ end subroutine isop_xactive_init ! id_tsfcair, id_fsdvd, id_climtas, id_climfsds, id_emis_diag ) ! -subroutine calc_xactive_isop( index, Time, lon, lat, oro, pwtsfc, is, js, & +subroutine calc_xactive_isop( index, Time, Time_next,lon, lat, oro, pwtsfc, is, js, & area, land, tsfcair, flux_sw_down_vis, & coszen, emis, id_gamma_lai_age, & id_gamma_temp, id_gamma_light, id_tsfcair, & id_fsdvd, id_climtas, id_climfsds, id_emis_diag ) integer,intent(in) :: index - type(time_type),intent(in) :: Time + type(time_type),intent(in) :: Time, Time_next real, intent(in), dimension(:,:) :: lon, lat real, intent(in), dimension(:,:) :: pwtsfc integer, intent(in) :: is, js @@ -2872,44 +2873,44 @@ subroutine calc_xactive_isop( index, Time, lon, lat, oro, pwtsfc, is, js, & !accumulate isoprene emissions in diagnostic - units should be molec/cm2/s if (present(id_emis_diag)) then if (id_emis_diag > 0) then - used = send_data( id_emis_diag, emis, Time, is_in=is, js_in=js) + used = send_data( id_emis_diag, emis, Time_next, is_in=is, js_in=js) end if end if ! also store sw visible direct at surface and surface air temperature diagnostics if (present(id_fsdvd)) then if (id_fsdvd > 0) then - used = send_data( id_fsdvd, flux_sw_down_vis, Time, is_in=is, js_in=js) + used = send_data( id_fsdvd, flux_sw_down_vis, Time_next, is_in=is, js_in=js) end if end if if (present(id_tsfcair)) then if (id_tsfcair > 0) then - used = send_data( id_tsfcair, tsfcair, Time, is_in=is, js_in=js) + used = send_data( id_tsfcair, tsfcair, Time_next, is_in=is, js_in=js) end if end if if (present(id_gamma_light)) then if (id_gamma_light > 0) then - used = send_data( id_gamma_light, diag_gamma_light(is:ie,js:je), Time, is_in=is, js_in=js) + used = send_data( id_gamma_light, diag_gamma_light(is:ie,js:je), Time_next, is_in=is, js_in=js) end if end if if (present(id_gamma_temp)) then if (id_gamma_temp > 0) then - used = send_data( id_gamma_temp, diag_gamma_temp(is:ie,js:je), Time, is_in=is, js_in=js) + used = send_data( id_gamma_temp, diag_gamma_temp(is:ie,js:je), Time_next, is_in=is, js_in=js) end if end if if (present(id_climtas)) then if (id_climtas > 0) then - used = send_data( id_climtas, diag_climtas(is:ie,js:je), Time, is_in=is, js_in=js) + used = send_data( id_climtas, diag_climtas(is:ie,js:je), Time_next, is_in=is, js_in=js) end if end if if (present(id_climfsds)) then if (id_climfsds > 0) then - used = send_data( id_climfsds, diag_climfsds(is:ie,js:je), Time, is_in=is, js_in=js) + used = send_data( id_climfsds, diag_climfsds(is:ie,js:je), Time_next, is_in=is, js_in=js) end if end if @@ -2921,7 +2922,7 @@ subroutine calc_xactive_isop( index, Time, lon, lat, oro, pwtsfc, is, js, & ! print*, 'id_gamma_lai_age = ', id_gamma_lai_age ! print*, 'sum(diag_gamma_lai_age', sum(diag_gamma_lai_age(:,:)) ! end if - used = send_data( id_gamma_lai_age, diag_gamma_lai_age(is:ie,js:je), Time, is_in=is, js_in=js) + used = send_data( id_gamma_lai_age, diag_gamma_lai_age(is:ie,js:je), Time_next, is_in=is, js_in=js) end if end if diff --git a/src/atmos_shared/vert_advection/vert_advection.F90 b/src/atmos_shared/vert_advection/vert_advection.F90 index 1778e1e923..35288f100b 100644 --- a/src/atmos_shared/vert_advection/vert_advection.F90 +++ b/src/atmos_shared/vert_advection/vert_advection.F90 @@ -26,7 +26,7 @@ module vert_advection_mod integer, parameter, public :: OUTFLOW_BOUNDARY=2 character(len=128), parameter :: version = '$Id: vert_advection.F90,v 17.0 2009/07/21 03:00:04 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. diff --git a/src/atmos_spectral/driver/coupled/atmosphere.F90 b/src/atmos_spectral/driver/coupled/atmosphere.F90 index be31306546..04bdcd8b76 100644 --- a/src/atmos_spectral/driver/coupled/atmosphere.F90 +++ b/src/atmos_spectral/driver/coupled/atmosphere.F90 @@ -40,7 +40,7 @@ module atmosphere_mod '$Id: atmosphere.F90,v 17.0 2009/07/21 03:00:28 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' public :: atmosphere_init, atmosphere_down, atmosphere_up, atmosphere_end, atmosphere_domain public :: atmosphere_resolution, atmosphere_boundary, get_bottom_mass, get_bottom_wind, get_atmosphere_axes diff --git a/src/atmos_spectral/driver/coupled/mcm_mca_lsc.F90 b/src/atmos_spectral/driver/coupled/mcm_mca_lsc.F90 index 356f3e21ba..8f5f4be450 100644 --- a/src/atmos_spectral/driver/coupled/mcm_mca_lsc.F90 +++ b/src/atmos_spectral/driver/coupled/mcm_mca_lsc.F90 @@ -44,7 +44,7 @@ module mcm_mca_lsc_mod '$Id: mcm_mca_lsc.F90,v 11.0 2004/09/28 19:28:56 fms Exp $' character(len=128) :: tagname = & - '$Name: siena_201207 $' + '$Name: tikal $' real,allocatable,dimension(:) :: qmh,q,dqph,dq,tauran,tausno diff --git a/src/atmos_spectral/driver/coupled/mcm_moist_processes.F90 b/src/atmos_spectral/driver/coupled/mcm_moist_processes.F90 index 2e20efd642..10d4f1f99d 100644 --- a/src/atmos_spectral/driver/coupled/mcm_moist_processes.F90 +++ b/src/atmos_spectral/driver/coupled/mcm_moist_processes.F90 @@ -58,7 +58,7 @@ module mcm_moist_processes_mod !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: mcm_moist_processes.F90,v 10.0 2003/10/24 22:00:58 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- !-------------------- namelist data (private) -------------------------- diff --git a/src/atmos_spectral/driver/coupled/spectral_physics.F90 b/src/atmos_spectral/driver/coupled/spectral_physics.F90 index 1f9ebdd9ba..93c14dc9cd 100644 --- a/src/atmos_spectral/driver/coupled/spectral_physics.F90 +++ b/src/atmos_spectral/driver/coupled/spectral_physics.F90 @@ -39,7 +39,7 @@ module spectral_physics_mod '$Id: spectral_physics.F90,v 13.0 2006/03/28 21:17:25 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' integer, parameter :: num_time_levels=2 diff --git a/src/atmos_spectral/driver/solo/atmosphere.F90 b/src/atmos_spectral/driver/solo/atmosphere.F90 index 4386e4812e..5f66046cd8 100644 --- a/src/atmos_spectral/driver/solo/atmosphere.F90 +++ b/src/atmos_spectral/driver/solo/atmosphere.F90 @@ -1,3 +1,24 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! !! +!! GNU General Public License !! +!! !! +!! This file is part of the Flexible Modeling System (FMS). !! +!! !! +!! FMS is free software; you can redistribute it and/or modify it !! +!! under the terms of the GNU General Public License as published by !! +!! the Free Software Foundation, either version 3 of the License, or !! +!! (at your option) any later version. !! +!! !! +!! FMS is distributed in the hope that it will be useful, !! +!! but WITHOUT ANY WARRANTY; without even the implied warranty of !! +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! +!! GNU General Public License for more details. !! +!! !! +!! You should have received a copy of the GNU General Public License !! +!! along with FMS. if not, see: http://www.gnu.org/licenses/gpl.txt !! +!! !! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + module atmosphere_mod use fms_mod, only: set_domain, write_version_number, field_size, file_exist, & @@ -9,8 +30,7 @@ module atmosphere_mod get_deg_lon, get_deg_lat, get_grid_boundaries, grid_domain, & spectral_domain, get_grid_domain, get_lon_max, get_lat_max, atmosphere_domain -use time_manager_mod, only: time_type, set_time, get_time, & - operator( + ), operator( - ), operator( < ) +use time_manager_mod, only: time_type, get_time, operator( + ) use press_and_geopot_mod, only: compute_pressures_and_heights @@ -20,21 +40,25 @@ module atmosphere_mod use tracer_type_mod, only: tracer_type -use hs_forcing_mod, only: hs_forcing_init, hs_forcing - use field_manager_mod, only: MODEL_ATMOS use tracer_manager_mod, only: get_number_tracers +#ifdef IDEALIZED_MOIST_MODEL + use idealized_moist_phys_mod, only: idealized_moist_phys_init , idealized_moist_phys , idealized_moist_phys_end +#else + use hs_forcing_mod, only: hs_forcing_init, hs_forcing +#endif + implicit none private !================================================================================================================================= character(len=128) :: version= & -'$Id: atmosphere.F90,v 19.0 2012/01/06 20:35:29 fms Exp $' +'$Id: atmosphere.F90,v 20.0 2013/12/13 23:25:37 fms Exp $' character(len=128) :: tagname= & -'$Name: siena_201207 $' +'$Name: tikal $' character(len=10), parameter :: mod_name='atmosphere' !================================================================================================================================= @@ -47,8 +71,8 @@ module atmosphere_mod integer :: is, ie, js, je, num_levels, num_tracers, nhum logical :: dry_model -real, allocatable, dimension(:,:,:) :: p_half, p_full -real, allocatable, dimension(:,:,:) :: z_half, z_full +real, allocatable, dimension(:,:,:,:) :: p_half, p_full +real, allocatable, dimension(:,:,:,:) :: z_half, z_full type(tracer_type), allocatable, dimension(:) :: tracer_attributes real, allocatable, dimension(:,:,:,:,:) :: grid_tracers @@ -67,14 +91,11 @@ module atmosphere_mod integer :: previous, current, future logical :: module_is_initialized =.false. -character(len=4) :: ch_tmp1, ch_tmp2 integer :: dt_integer real :: dt_real type(time_type) :: Time_step -integer, dimension(4) :: axis_id - !================================================================================================================================= contains !================================================================================================================================= @@ -104,10 +125,10 @@ subroutine atmosphere_init(Time_init, Time, Time_step_in) call get_grid_domain(is, ie, js, je) call get_num_levels(num_levels) -allocate (p_half (is:ie, js:je, num_levels+1)) -allocate (z_half (is:ie, js:je, num_levels+1)) -allocate (p_full (is:ie, js:je, num_levels)) -allocate (z_full (is:ie, js:je, num_levels)) +allocate (p_half (is:ie, js:je, num_levels+1, num_time_levels)) +allocate (z_half (is:ie, js:je, num_levels+1, num_time_levels)) +allocate (p_full (is:ie, js:je, num_levels, num_time_levels)) +allocate (z_full (is:ie, js:je, num_levels, num_time_levels)) allocate (wg_full (is:ie, js:je, num_levels)) allocate (psg (is:ie, js:je, num_time_levels)) allocate (ug (is:ie, js:je, num_levels, num_time_levels)) @@ -171,10 +192,17 @@ subroutine atmosphere_init(Time_init, Time, Time_step_in) endif !-------------------------------------------------------------------------------------------------------------------------------- if(dry_model) then - call compute_pressures_and_heights(tg(:,:,:,current), psg(:,:,current), surf_geopotential, z_full, z_half, p_full, p_half) + call compute_pressures_and_heights(tg(:,:,:,current), psg(:,:,current), surf_geopotential, & + z_full(:,:,:,current), z_half(:,:,:,current), p_full(:,:,:,current), p_half(:,:,:,current)) + call compute_pressures_and_heights(tg(:,:,:,previous), psg(:,:,previous), surf_geopotential, & + z_full(:,:,:,previous), z_half(:,:,:,previous), p_full(:,:,:,previous), p_half(:,:,:,previous)) else - call compute_pressures_and_heights(tg(:,:,:,current), psg(:,:,current), surf_geopotential, z_full, z_half, p_full, p_half, & - grid_tracers(:,:,:,current,nhum)) + call compute_pressures_and_heights(tg(:,:,:,current), psg(:,:,current), surf_geopotential, & + z_full(:,:,:,current), z_half(:,:,:,current), p_full(:,:,:,current), p_half(:,:,:,current), & + grid_tracers(:,:,:,current,nhum)) + call compute_pressures_and_heights(tg(:,:,:,previous), psg(:,:,previous), surf_geopotential, & + z_full(:,:,:,previous), z_half(:,:,:,previous), p_full(:,:,:,previous), p_half(:,:,:,previous), & + grid_tracers(:,:,:,previous,nhum)) endif call get_deg_lon(deg_lon) @@ -197,7 +225,11 @@ subroutine atmosphere_init(Time_init, Time, Time_step_in) rad_latb_2d(:,j) = rad_latb(j) enddo -call hs_forcing_init(get_axis_id(), Time, rad_lonb_2d, rad_latb_2d) +#ifdef IDEALIZED_MOIST_MODEL + call idealized_moist_phys_init(Time, Time_step, nhum, rad_lat_2d, rad_lonb_2d, rad_latb_2d, tg(:,:,num_levels,current)) +#else + call hs_forcing_init(get_axis_id(), Time, rad_lonb_2d, rad_latb_2d) +#endif module_is_initialized = .true. @@ -230,14 +262,19 @@ subroutine atmosphere(Time) Time_next = Time + Time_step -call hs_forcing(1, ie-is+1, 1, je-js+1, delta_t, Time_next, rad_lon_2d, rad_lat_2d, & - p_half(:,:,: ), p_full(:,:,: ), & +#ifdef IDEALIZED_MOIST_MODEL + call idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, tg, grid_tracers, & + previous, current, dt_ug, dt_vg, dt_tg, dt_tracers) +#else + call hs_forcing(1, ie-is+1, 1, je-js+1, delta_t, Time_next, rad_lon_2d, rad_lat_2d, & + p_half(:,:,:,current ), p_full(:,:,:,current ), & ug(:,:,:,previous), vg(:,:,:,previous ), & tg(:,:,:,previous), grid_tracers(:,:,:,previous,:), & ug(:,:,:,previous), vg(:,:,:,previous ), & tg(:,:,:,previous), grid_tracers(:,:,:,previous,:), & dt_ug(:,:,: ), dt_vg(:,:,: ), & dt_tg(:,:,: ), dt_tracers(:,:,:,:)) +#endif if(previous == current) then future = num_time_levels + 1 - current @@ -247,14 +284,17 @@ subroutine atmosphere(Time) call spectral_dynamics(Time, psg(:,:,future), ug(:,:,:,future), vg(:,:,:,future), & tg(:,:,:,future), tracer_attributes, grid_tracers(:,:,:,:,:), future, & - dt_psg, dt_ug, dt_vg, dt_tg, dt_tracers, wg_full, p_full, p_half, z_full) + dt_psg, dt_ug, dt_vg, dt_tg, dt_tracers, wg_full, & + p_full(:,:,:,current), p_half(:,:,:,current), z_full(:,:,:,current)) call complete_robert_filter(tracer_attributes) if(dry_model) then - call compute_pressures_and_heights(tg(:,:,:,future), psg(:,:,future), surf_geopotential, z_full, z_half, p_full, p_half) + call compute_pressures_and_heights(tg(:,:,:,future), psg(:,:,future), surf_geopotential, & + z_full(:,:,:,future), z_half(:,:,:,future), p_full(:,:,:,future), p_half(:,:,:,future)) else - call compute_pressures_and_heights(tg(:,:,:,future), psg(:,:,future), surf_geopotential, z_full, z_half, p_full, p_half, & + call compute_pressures_and_heights(tg(:,:,:,future), psg(:,:,future), surf_geopotential, & + z_full(:,:,:,future), z_half(:,:,:,future), p_full(:,:,:,future), p_half(:,:,:,future), & grid_tracers(:,:,:,future,nhum)) endif @@ -277,9 +317,7 @@ subroutine atmosphere_end file='RESTART/atmosphere.res' call nullify_domain() -!call write_data(trim(file), 'previous', previous) ! No interface exists to write a scalar -!call write_data(trim(file), 'current', current) ! No interface exists to write a scalar -call write_data(trim(file), 'time_pointers', (/real(previous),real(current)/)) ! getaround for no interface to write a scalar +call write_data(trim(file), 'time_pointers', (/real(previous),real(current)/)) do nt=1,num_time_levels call write_data(trim(file), 'ug', ug(:,:,:,nt), grid_domain) call write_data(trim(file), 'vg', vg(:,:,:,nt), grid_domain) @@ -297,6 +335,9 @@ subroutine atmosphere_end deallocate (deg_lon, rad_lon_2d, deg_lat, rad_lat_2d) call set_domain(grid_domain) +#ifdef IDEALIZED_MOIST_MODEL +call idealized_moist_phys_end +#endif call spectral_dynamics_end(tracer_attributes) deallocate(tracer_attributes) diff --git a/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 b/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 new file mode 100644 index 0000000000..bca75d17e6 --- /dev/null +++ b/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 @@ -0,0 +1,576 @@ +module idealized_moist_phys_mod + +#ifdef INTERNAL_FILE_NML + use mpp_mod, only: input_nml_file +#else + use fms_mod, only: open_namelist_file, close_file +#endif + +use fms_mod, only: write_version_number, file_exist, close_file, stdlog, error_mesg, FATAL + +use constants_mod, only: grav + +use time_manager_mod, only: time_type, get_time, operator( + ) + +use vert_turb_driver_mod, only: vert_turb_driver_init, vert_turb_driver, vert_turb_driver_end + +use vert_diff_mod, only: vert_diff_init, gcm_vert_diff_down, gcm_vert_diff_up, vert_diff_end, surf_diff_type + +use two_stream_gray_rad_mod, only: two_stream_gray_rad_init, two_stream_gray_rad_down, two_stream_gray_rad_up, two_stream_gray_rad_end + +use mixed_layer_mod, only: mixed_layer_init, mixed_layer, mixed_layer_end + +use lscale_cond_mod, only: lscale_cond_init, lscale_cond, lscale_cond_end + +use qe_moist_convection_mod, only: qe_moist_convection_init, qe_moist_convection, qe_moist_convection_end + +use diag_manager_mod, only: register_diag_field, send_data + +use transforms_mod, only: get_grid_domain + +use spectral_dynamics_mod, only: get_axis_id, get_num_levels, get_surf_geopotential + +use surface_flux_mod, only: surface_flux + +implicit none +private +!================================================================================================================================= + +character(len=128) :: version= & +'$Id: idealized_moist_phys.F90,v 20.0 2013/12/13 23:25:39 fms Exp $' + +character(len=128) :: tagname= & +'$Name: tikal $' +character(len=10), parameter :: mod_name='atmosphere' + +!================================================================================================================================= + +public :: idealized_moist_phys_init , idealized_moist_phys , idealized_moist_phys_end + +logical :: module_is_initialized =.false. +logical :: turb = .false. +logical :: do_virtual = .false. ! whether virtual temp used in gcm_vert_diff +logical :: lwet_convection = .false. +logical :: two_stream = .true. +logical :: mixed_layer_bc = .false. +real :: roughness_heat = 0.05 +real :: roughness_moist = 0.05 +real :: roughness_mom = 0.05 + +namelist / idealized_moist_phys_nml / turb, lwet_convection, roughness_heat, two_stream, mixed_layer_bc, & + roughness_moist, roughness_mom, do_virtual + +real, allocatable, dimension(:,:) :: & + z_surf, & ! surface height + t_surf, & ! surface temperature + q_surf, & ! surface moisture + u_surf, & ! surface U wind + v_surf, & ! surface V wind + rough_mom, & ! momentum roughness length for surface_flux + rough_heat, & ! heat roughness length for surface_flux + rough_moist, & ! moisture roughness length for surface_flux + gust, & ! gustiness constant + z_pbl, & ! gustiness constant + flux_t, & ! surface sensible heat flux + flux_q, & ! surface moisture flux + flux_r, & ! surface radiation flux + flux_u, & ! surface flux of zonal mom. + flux_v, & ! surface flux of meridional mom. + drag_m, & ! momentum drag coefficient + drag_t, & ! heat drag coefficient + drag_q, & ! moisture drag coefficient + w_atm, & ! wind speed + ustar, & ! friction velocity + bstar, & ! buoyancy scale + qstar, & ! moisture scale + dhdt_surf, & ! d(sensible heat flux)/d(surface temp) + dedt_surf, & ! d(latent heat flux)/d(surface temp)??? + dedq_surf, & ! d(latent heat flux)/d(surface moisture)??? + drdt_surf, & ! d(upward longwave)/d(surface temp) + dhdt_atm, & ! d(sensible heat flux)/d(atmos.temp) + dedq_atm, & ! d(latent heat flux)/d(atmospheric mixing rat.) + dtaudv_atm, & ! d(stress component)/d(atmos wind) + dtaudu_atm, & ! d(stress component)/d(atmos wind) + fracland, & ! fraction of land in gridbox + rough ! roughness for vert_turb_driver + + +real, allocatable, dimension(:,:,:) :: & + diff_m, & ! momentum diffusion coeff. + diff_t, & ! temperature diffusion coeff. + tdtlw, & ! place holder. appears in calling arguments of vert_turb_driver but not used unless do_edt=.true. -- pjp + diss_heat, & ! heat dissipated by vertical diffusion + non_diff_dt_ug, & ! zonal wind tendency except from vertical diffusion + non_diff_dt_vg, & ! merid. wind tendency except from vertical diffusion + non_diff_dt_tg, & ! temperature tendency except from vertical diffusion + non_diff_dt_qg, & ! moisture tendency except from vertical diffusion + conv_dt_tg, & ! temperature tendency from convection + conv_dt_qg, & ! moisture tendency from convection + cond_dt_tg, & ! temperature tendency from condensation + cond_dt_qg ! moisture tendency from condensation + + +logical, allocatable, dimension(:,:) :: & + avail, & ! generate surf. flux (all true) + land, & ! land points (all false) + coldT, & ! should precipitation be snow at this point + convect ! place holder. appears in calling arguments of vert_turb_driver but not used unless do_entrain=.true. -- pjp + +real, allocatable, dimension(:,:) :: & + klzbs, & ! stored level of zero buoyancy values + cape, & ! convectively available potential energy + cin, & ! convective inhibition (this and the above are before the adjustment) + invtau_q_relaxation, & ! temperature relaxation time scale + invtau_t_relaxation, & ! humidity relaxation time scale + rain, & ! + snow + +real, allocatable, dimension(:,:,:) :: & + t_ref, & ! relaxation temperature for bettsmiller scheme + q_ref ! relaxation moisture for bettsmiller scheme + +real, allocatable, dimension(:,:) :: & + net_surf_sw_down, & ! net sw flux at surface + surf_lw_down ! downward lw flux at surface + +integer :: & + id_diff_dt_ug, & ! zonal wind tendency from vertical diffusion + id_diff_dt_vg, & ! merid. wind tendency from vertical diffusion + id_diff_dt_tg, & ! temperature tendency from vertical diffusion + id_diff_dt_qg, & ! moisture tendency from vertical diffusion + id_conv_rain, & ! rain from convection + id_cond_rain, & ! rain from condensation + id_conv_dt_tg, & ! temperature tendency from convection + id_conv_dt_qg, & ! temperature tendency from convection + id_cond_dt_tg, & ! temperature tendency from convection + id_cond_dt_qg ! temperature tendency from convection + +integer, allocatable, dimension(:,:) :: convflag ! indicates which qe convection subroutines are used +real, allocatable, dimension(:,:) :: rad_lat + +type(surf_diff_type) :: Tri_surf ! used by gcm_vert_diff + +logical :: used, doing_edt, doing_entrain +integer, dimension(4) :: axes +integer :: is, ie, js, je, num_levels, nsphum, dt_integer +real :: dt_real +type(time_type) :: Time_step + +!================================================================================================================================= +contains +!================================================================================================================================= + +subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lat_2d, rad_lonb_2d, rad_latb_2d, t_surf_init) +type(time_type), intent(in) :: Time, Time_step_in +integer, intent(in) :: nhum +real, intent(in), dimension(:,:) :: rad_lat_2d, rad_lonb_2d, rad_latb_2d, t_surf_init + +integer :: io, nml_unit, stdlog_unit, seconds, days + +if(module_is_initialized) return + +call write_version_number(version, tagname) + +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=idealized_moist_phys_nml, iostat=io) +#else + if ( file_exist('input.nml') ) then + nml_unit = open_namelist_file() + read (nml_unit, idealized_moist_phys_nml, iostat=io) + call close_file(nml_unit) + endif +#endif +stdlog_unit = stdlog() +write(stdlog_unit, idealized_moist_phys_nml) + +nsphum = nhum +Time_step = Time_step_in +call get_time(Time_step, seconds, days) +dt_integer = 86400*days + seconds +dt_real = float(dt_integer) + +call get_grid_domain(is, ie, js, je) +call get_num_levels(num_levels) + +allocate(rad_lat (is:ie, js:je)); rad_lat = rad_lat_2d +allocate(z_surf (is:ie, js:je)) +allocate(t_surf (is:ie, js:je)) +allocate(q_surf (is:ie, js:je)); q_surf = 0.0 +allocate(u_surf (is:ie, js:je)); u_surf = 0.0 +allocate(v_surf (is:ie, js:je)); v_surf = 0.0 +allocate(rough_mom (is:ie, js:je)); rough_mom = roughness_mom +allocate(rough_heat (is:ie, js:je)); rough_heat = roughness_heat +allocate(rough_moist (is:ie, js:je)); rough_moist = roughness_moist +allocate(gust (is:ie, js:je)); gust = 1.0 +allocate(z_pbl (is:ie, js:je)) +allocate(flux_t (is:ie, js:je)) +allocate(flux_q (is:ie, js:je)) +allocate(flux_r (is:ie, js:je)) +allocate(flux_u (is:ie, js:je)) +allocate(flux_v (is:ie, js:je)) +allocate(drag_m (is:ie, js:je)) +allocate(drag_t (is:ie, js:je)) +allocate(drag_q (is:ie, js:je)) +allocate(w_atm (is:ie, js:je)) +allocate(ustar (is:ie, js:je)) +allocate(bstar (is:ie, js:je)) +allocate(qstar (is:ie, js:je)) +allocate(dhdt_surf (is:ie, js:je)) +allocate(dedt_surf (is:ie, js:je)) +allocate(dedq_surf (is:ie, js:je)) +allocate(drdt_surf (is:ie, js:je)) +allocate(dhdt_atm (is:ie, js:je)) +allocate(dedq_atm (is:ie, js:je)) +allocate(dtaudv_atm (is:ie, js:je)) +allocate(dtaudu_atm (is:ie, js:je)) +allocate(land (is:ie, js:je)); land = .false. +allocate(avail (is:ie, js:je)); avail = .true. +allocate(fracland (is:ie, js:je)); fracland = 0.0 +allocate(rough (is:ie, js:je)) +allocate(diff_t (is:ie, js:je, num_levels)) +allocate(diff_m (is:ie, js:je, num_levels)) +allocate(diss_heat (is:ie, js:je, num_levels)) +allocate(tdtlw (is:ie, js:je, num_levels)); tdtlw = 0.0 + +allocate(non_diff_dt_ug (is:ie, js:je, num_levels)) +allocate(non_diff_dt_vg (is:ie, js:je, num_levels)) +allocate(non_diff_dt_tg (is:ie, js:je, num_levels)) +allocate(non_diff_dt_qg (is:ie, js:je, num_levels)) + +allocate(net_surf_sw_down (is:ie, js:je)) +allocate(surf_lw_down (is:ie, js:je)) +allocate(conv_dt_tg (is:ie, js:je, num_levels)) +allocate(conv_dt_qg (is:ie, js:je, num_levels)) +allocate(cond_dt_tg (is:ie, js:je, num_levels)) +allocate(cond_dt_qg (is:ie, js:je, num_levels)) + +allocate(coldT (is:ie, js:je)); coldT = .false. +allocate(klzbs (is:ie, js:je)) +allocate(cape (is:ie, js:je)) +allocate(cin (is:ie, js:je)) +allocate(invtau_q_relaxation (is:ie, js:je)) +allocate(invtau_t_relaxation (is:ie, js:je)) +allocate(rain (is:ie, js:je)); rain = 0.0 +allocate(snow (is:ie, js:je)); snow = 0.0 +allocate(convflag (is:ie, js:je)) +allocate(convect (is:ie, js:je)); convect = .false. + +allocate(t_ref (is:ie, js:je, num_levels)); t_ref = 0.0 +allocate(q_ref (is:ie, js:je, num_levels)); q_ref = 0.0 + +call get_surf_geopotential(z_surf) +z_surf = z_surf/grav + +if(mixed_layer_bc) then + ! need an initial condition for the mixed layer temperature + ! may be overwritten by restart file + ! choose an unstable initial condition to allow moisture + ! to quickly enter the atmosphere avoiding problems with the convection scheme + t_surf = t_surf_init + 1.0 + call mixed_layer_init(is, ie, js, je, num_levels, t_surf, get_axis_id(), Time) ! t_surf is intent(inout) +endif + +if(turb) then +! need to call vert_diff_init even if using gcm_vert_diff (rather than +! gcm_vert_diff_down) because the variable sphum is not initialized +! otherwise in the vert_diff module + call vert_diff_init (Tri_surf, ie-is+1, je-js+1, num_levels, .true., do_virtual) +end if + +call lscale_cond_init() + +axes = get_axis_id() + +id_cond_dt_qg = register_diag_field(mod_name, 'dt_qg_condensation', & + axes(1:3), Time, 'Moisture tendency from condensation','kg/kg/s') +id_cond_dt_tg = register_diag_field(mod_name, 'dt_tg_condensation', & + axes(1:3), Time, 'Temperature tendency from condensation','K/s') +id_cond_rain = register_diag_field(mod_name, 'condensation_rain', & + axes(1:2), Time, 'Rain from condensation','kg/m/m/s') + +if(lwet_convection) then + call qe_moist_convection_init() + id_conv_dt_qg = register_diag_field(mod_name, 'dt_qg_convection', & + axes(1:3), Time, 'Moisture tendency from convection','kg/kg/s') + id_conv_dt_tg = register_diag_field(mod_name, 'dt_tg_convection', & + axes(1:3), Time, 'Temperature tendency from convection','K/s') + id_conv_rain = register_diag_field(mod_name, 'convection_rain', & + axes(1:2), Time, 'Rain from convection','kg/m/m/s') +endif + +if(two_stream) call two_stream_gray_rad_init(is, ie, js, je, num_levels, get_axis_id(), Time) + +if(turb) then + call vert_turb_driver_init (rad_lonb_2d, rad_latb_2d, ie-is+1,je-js+1, & + num_levels,get_axis_id(),Time, doing_edt, doing_entrain) + + axes = get_axis_id() + id_diff_dt_ug = register_diag_field(mod_name, 'dt_ug_diffusion', & + axes(1:3), Time, 'zonal wind tendency from diffusion','m/s^2') + id_diff_dt_vg = register_diag_field(mod_name, 'dt_vg_diffusion', & + axes(1:3), Time, 'meridional wind tendency from diffusion','m/s^2') + id_diff_dt_tg = register_diag_field(mod_name, 'dt_tg_diffusion', & + axes(1:3), Time, 'temperature diffusion tendency','T/s') + id_diff_dt_qg = register_diag_field(mod_name, 'dt_qg_diffusion', & + axes(1:3), Time, 'moisture diffusion tendency','T/s') +endif + +end subroutine idealized_moist_phys_init +!================================================================================================================================= +subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, tg, grid_tracers, & + previous, current, dt_ug, dt_vg, dt_tg, dt_tracers) + +type(time_type), intent(in) :: Time +real, dimension(:,:,:,:), intent(in) :: p_half, p_full, z_half, z_full, ug, vg, tg +real, dimension(:,:,:,:,:), intent(in) :: grid_tracers +integer, intent(in) :: previous, current +real, dimension(:,:,:), intent(inout) :: dt_ug, dt_vg, dt_tg +real, dimension(:,:,:,:), intent(inout) :: dt_tracers + +real :: delta_t +real, dimension(size(ug,1), size(ug,2), size(ug,3)) :: tg_tmp, qg_tmp + +if(current == previous) then + delta_t = dt_real +else + delta_t = 2*dt_real +endif + +if (lwet_convection) then + rain = 0.0; snow = 0.0 + call qe_moist_convection ( delta_t, tg(:,:,:,previous), & + grid_tracers(:,:,:,previous,nsphum), p_full(:,:,:,previous), & + p_half(:,:,:,previous), coldT, & + rain, snow, & + conv_dt_tg, conv_dt_qg, & + q_ref, convflag, & + klzbs, cape, & + cin, invtau_q_relaxation, & + invtau_t_relaxation, t_ref) + + tg_tmp = conv_dt_tg + tg(:,:,:,previous) + qg_tmp = conv_dt_qg + grid_tracers(:,:,:,previous,nsphum) +! note the delta's are returned rather than the time derivatives + + conv_dt_tg = conv_dt_tg/delta_t + conv_dt_qg = conv_dt_qg/delta_t + rain = rain/delta_t + + dt_tg = dt_tg + conv_dt_tg + dt_tracers(:,:,:,nsphum) = dt_tracers(:,:,:,nsphum) + conv_dt_qg + + if(id_conv_dt_qg > 0) used = send_data(id_conv_dt_qg, conv_dt_qg, Time) + if(id_conv_dt_tg > 0) used = send_data(id_conv_dt_tg, conv_dt_tg, Time) + if(id_conv_rain > 0) used = send_data(id_conv_rain, rain, Time) + +else + + tg_tmp = tg(:,:,:,previous) + qg_tmp = grid_tracers(:,:,:,previous,nsphum) + +endif + +rain = 0.0 +call lscale_cond ( tg_tmp, qg_tmp, & + p_full(:,:,:,previous), p_half(:,:,:,previous), & + coldT, rain, & + snow, cond_dt_tg, & + cond_dt_qg ) + +cond_dt_tg = cond_dt_tg/delta_t +cond_dt_qg = cond_dt_qg/delta_t +rain = rain/delta_t + +dt_tg = dt_tg + cond_dt_tg +dt_tracers(:,:,:,nsphum) = dt_tracers(:,:,:,nsphum) + cond_dt_qg + +if(id_cond_dt_qg > 0) used = send_data(id_cond_dt_qg, cond_dt_qg, Time) +if(id_cond_dt_tg > 0) used = send_data(id_cond_dt_tg, cond_dt_tg, Time) +if(id_cond_rain > 0) used = send_data(id_cond_rain, rain, Time) + +! Begin the radiation calculation by computing downward fluxes. +! This part of the calculation does not depend on the surface temperature. + +if(two_stream) then + call two_stream_gray_rad_down(is, js, Time, & + rad_lat(:,:), & + p_half(:,:,:,current), & + tg(:,:,:,previous), & + net_surf_sw_down(:,:), & + surf_lw_down(:,:)) +end if + +if(.not.mixed_layer_bc) then + +!!$! infinite heat capacity +! t_surf = surface_temperature_forced(rad_lat) +!!$! no heat capacity: +!!$ t_surf = tg(:,:,num_levels,previous) + +!!$! surface temperature has same potential temp. as lowest layer: +!!$ t_surf = surface_temperature(tg(:,:,:,previous), p_full(:,:,:,current), p_half(:,:,:,current)) +end if + +call surface_flux( & + tg(:,:,num_levels,previous), & + grid_tracers(:,:,num_levels,previous,nsphum), & + ug(:,:,num_levels,previous), & + vg(:,:,num_levels,previous), & + p_full(:,:,num_levels,current), & + z_full(:,:,num_levels,current)-z_surf(:,:), & + p_half(:,:,num_levels+1,current), & + t_surf(:,:), & + t_surf(:,:), & + q_surf(:,:), & ! is intent(inout) + u_surf(:,:), & + v_surf(:,:), & + rough_mom(:,:), & + rough_heat(:,:), & + rough_moist(:,:), & + rough_mom(:,:), & ! using rough_mom in place of rough_scale -- pjp + gust(:,:), & + flux_t(:,:), & ! is intent(out) + flux_q(:,:), & ! is intent(out) + flux_r(:,:), & ! is intent(out) + flux_u(:,:), & ! is intent(out) + flux_v(:,:), & ! is intent(out) + drag_m(:,:), & ! is intent(out) + drag_t(:,:), & ! is intent(out) + drag_q(:,:), & ! is intent(out) + w_atm(:,:), & ! is intent(out) + ustar(:,:), & ! is intent(out) + bstar(:,:), & ! is intent(out) + qstar(:,:), & ! is intent(out) + dhdt_surf(:,:), & ! is intent(out) + dedt_surf(:,:), & ! is intent(out) + dedq_surf(:,:), & ! is intent(out) + drdt_surf(:,:), & ! is intent(out) + dhdt_atm(:,:), & ! is intent(out) + dedq_atm(:,:), & ! is intent(out) + dtaudu_atm(:,:), & ! is intent(out) + dtaudv_atm(:,:), & ! is intent(out) + delta_t, & + land(:,:), & + .not.land(:,:), & + avail(:,:) ) + +! Now complete the radiation calculation by computing the upward and net fluxes. + +if(two_stream) then + call two_stream_gray_rad_up(is, js, Time, & + rad_lat(:,:), & + p_half(:,:,:,current), & + t_surf(:,:), & + tg(:,:,:,previous), & + dt_tg(:,:,:)) +end if + +if(turb) then + + call vert_turb_driver( 1, 1, & + Time, Time+Time_step, & + delta_t, tdtlw(:,:,:), fracland(:,:), & + p_half(:,:,:,current), p_full(:,:,:,current), & + z_half(:,:,:,current), z_full(:,:,:,current), & + ustar(:,:), bstar(:,:), & + qstar(:,:), rough(:,:), & + rad_lat(:,:), convect(:,:), & + ug(:,:,:,current ), vg(:,:,:,current ), & + tg(:,:,:,current ), & + grid_tracers(:,:,:,current,nsphum), grid_tracers(:,:,:,current,:), & + ug(:,:,:,previous), & + vg(:,:,:,previous), tg(:,:,:,previous), & + grid_tracers(:,:,:,previous,nsphum), grid_tracers(:,:,:,previous,:), & + dt_ug(:,:,:), dt_vg(:,:,:), & + dt_tg(:,:,:), dt_tracers(:,:,:,nsphum), & + dt_tracers(:,:,:,:), diff_t(:,:,:), & + diff_m(:,:,:), gust(:,:), & + z_pbl(:,:) ) +! +!! Don't zero these derivatives as the surface flux depends implicitly +!! on the lowest level values +!! However it should be noted that these derivatives do not take into +!! account the change in the Monin-Obukhov coefficients, and so are not +!! very accurate. +! +!!$ dtaudv_atm = 0.0 +!!$ dhdt_atm = 0.0 +!!$ dedq_atm = 0.0 + + if(.not.mixed_layer_bc) then + call error_mesg('atmosphere','no diffusion implentation for non-mixed layer b.c.',FATAL) + endif + + +! We must use gcm_vert_diff_down and _up rather than gcm_vert_diff as the surface flux +! depends implicitly on the surface values + +! +! Don't want to do time splitting for the implicit diffusion step in case +! of compensation of the tendencies +! + non_diff_dt_ug = dt_ug + non_diff_dt_vg = dt_vg + non_diff_dt_tg = dt_tg + non_diff_dt_qg = dt_tracers(:,:,:,nsphum) + + call gcm_vert_diff_down (1, 1, & + delta_t, ug(:,:,:,previous), & + vg(:,:,:,previous), tg(:,:,:,previous), & + grid_tracers(:,:,:,previous,nsphum), & + grid_tracers(:,:,:,previous,:), diff_m(:,:,:), & + diff_t(:,:,:), p_half(:,:,:,current), & + p_full(:,:,:,current), z_full(:,:,:,current), & + flux_u(:,:), flux_v(:,:), & + dtaudu_atm(:,:), dtaudv_atm(:,:), & + dt_ug(:,:,:), dt_vg(:,:,:), & + dt_tg(:,:,:), dt_tracers(:,:,:,nsphum), & + dt_tracers(:,:,:,:), diss_heat(:,:,:), & + Tri_surf) +! +! update surface temperature +! + call mixed_layer( & + Time, & + t_surf(:,:), & ! t_surf is intent(inout) + flux_t(:,:), & + flux_q(:,:), & + flux_r(:,:), & + dt_real, & + net_surf_sw_down(:,:), & + surf_lw_down(:,:), & + Tri_surf, & ! Tri_surf is intent(inout) + dhdt_surf(:,:), & + dedt_surf(:,:), & + dedq_surf(:,:), & + drdt_surf(:,:), & + dhdt_atm(:,:), & + dedq_atm(:,:)) + + + call gcm_vert_diff_up (1, 1, delta_t, Tri_surf, dt_tg(:,:,:), dt_tracers(:,:,:,nsphum), dt_tracers(:,:,:,:)) + + if(id_diff_dt_ug > 0) used = send_data(id_diff_dt_ug, dt_ug - non_diff_dt_ug, Time) + if(id_diff_dt_vg > 0) used = send_data(id_diff_dt_vg, dt_vg - non_diff_dt_vg, Time) + if(id_diff_dt_tg > 0) used = send_data(id_diff_dt_tg, dt_tg - non_diff_dt_tg, Time) + if(id_diff_dt_qg > 0) used = send_data(id_diff_dt_qg, dt_tracers(:,:,:,nsphum) - non_diff_dt_qg, Time) + +endif ! if(turb) then + +end subroutine idealized_moist_phys +!================================================================================================================================= +subroutine idealized_moist_phys_end + +if(two_stream) call two_stream_gray_rad_end +if(lwet_convection) call qe_moist_convection_end +if(turb) then + call vert_diff_end + call vert_turb_driver_end +endif +call lscale_cond_end +if(mixed_layer_bc) call mixed_layer_end(t_surf) + +end subroutine idealized_moist_phys_end +!================================================================================================================================= + +end module idealized_moist_phys_mod diff --git a/src/atmos_spectral/driver/solo/mixed_layer.F90 b/src/atmos_spectral/driver/solo/mixed_layer.F90 new file mode 100644 index 0000000000..301f1509c5 --- /dev/null +++ b/src/atmos_spectral/driver/solo/mixed_layer.F90 @@ -0,0 +1,349 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! !! +!! GNU General Public License !! +!! !! +!! This file is part of the Flexible Modeling System (FMS). !! +!! !! +!! FMS is free software; you can redistribute it and/or modify it !! +!! under the terms of the GNU General Public License as published by !! +!! the Free Software Foundation, either version 3 of the License, or !! +!! (at your option) any later version. !! +!! !! +!! FMS is distributed in the hope that it will be useful, !! +!! but WITHOUT ANY WARRANTY; without even the implied warranty of !! +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! +!! GNU General Public License for more details. !! +!! !! +!! You should have received a copy of the GNU General Public License !! +!! along with FMS. if not, see: http://www.gnu.org/licenses/gpl.txt !! +!! !! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +module mixed_layer_mod + +! +! Implementation of mixed layer boundary condition +! + +use fms_mod, only: set_domain, write_version_number, & + mpp_pe, mpp_root_pe, error_mesg, FATAL, WARNING + +use fms_mod, only: stdlog, check_nml_error, close_file,& + open_namelist_file, stdout, file_exist, & + read_data, write_data, open_file, & + nullify_domain, lowercase + +use field_manager_mod, only: MODEL_ATMOS + +use tracer_manager_mod, only: get_tracer_names, get_number_tracers + +use constants_mod, only: HLV, PI, RHO_CP, CP_AIR + +use diag_manager_mod, only: register_diag_field, send_data + +use time_manager_mod, only: time_type + +use transforms_mod, only: get_deg_lat, grid_domain + +use vert_diff_mod, only: surf_diff_type + +implicit none +private +!================================================================================================================================= + +character(len=128) :: version= & +'$Id: mixed_layer.F90,v 20.0 2013/12/13 23:25:40 fms Exp $' + +character(len=128) :: tagname= & +'$Name: tikal $' +character(len=128), parameter :: mod_name='mixed_layer' + +!================================================================================================================================= + +public :: mixed_layer_init, mixed_layer, mixed_layer_end + +!================================================================================================================================= + +logical :: evaporation = .true. +real :: qflux_amp = 0.0 +real :: qflux_width = 16.0 ! width of qflux region in degrees +real :: depth = 40.0 +logical :: load_qflux = .false. + + +namelist/mixed_layer_nml/ evaporation, qflux_amp, depth, qflux_width, load_qflux + +!================================================================================================================================= + + +logical :: module_is_initialized =.false. +logical :: used + +integer :: iter, nhum +integer, dimension(4) :: axes +integer :: & + id_t_surf, & ! surface temperature + id_flux_lhe, & ! latent heat flux at surface + id_flux_oceanq, & ! oceanic Q flux + id_flux_t ! sensible heat flux at surface + +real, allocatable, dimension(:,:) :: & + ocean_qflux, & ! Q-flux + rad_lat_2d ! latitude in radians + +real, allocatable, dimension(:) :: deg_lat + +real, allocatable, dimension(:,:) :: & + gamma_t, & ! Used to calculate the implicit + gamma_q, & ! correction to the diffusion in + fn_t, & ! the lowest layer + fn_q, & ! + en_t, & ! + en_q, & ! + alpha_t, & ! + alpha_q, & ! + alpha_lw, & ! + beta_t, & ! + beta_q, & ! + beta_lw, & ! + t_surf_dependence, & ! + corrected_flux, & ! + eff_heat_capacity, & ! Effective heat capacity + delta_t_surf ! Increment in surface temperature + +real inv_cp_air + +!================================================================================================================================= +contains +!================================================================================================================================= + +subroutine mixed_layer_init(is, ie, js, je, num_levels, t_surf, axes, Time) + +type(time_type), intent(in) :: Time +real, intent(out), dimension(:,:) :: t_surf +integer, intent(in), dimension(4) :: axes +integer, intent(in) :: is, ie, js, je, num_levels + +integer :: j +real :: rad_qwidth +integer:: ierr, io, unit, num_tr, n +character(32) :: tr_name + +if(module_is_initialized) return + +call write_version_number(version, tagname) + +unit = open_namelist_file () +ierr=1 +do while (ierr /= 0) + read (unit, nml=mixed_layer_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'mixed_layer_nml') +enddo +10 call close_file (unit) + +if ( mpp_pe() == mpp_root_pe() ) write (stdlog(), nml=mixed_layer_nml) + +call get_number_tracers (MODEL_ATMOS, num_prog=num_tr) +do n = 1,num_tr + call get_tracer_names( MODEL_ATMOS, n, tr_name ) + if(lowercase(tr_name)=='sphum') then + nhum = n + endif +enddo + +allocate(rad_lat_2d (is:ie, js:je)) +allocate(ocean_qflux (is:ie, js:je)) +allocate(deg_lat (js:je)) +allocate(gamma_t (is:ie, js:je)) +allocate(gamma_q (is:ie, js:je)) +allocate(en_t (is:ie, js:je)) +allocate(en_q (is:ie, js:je)) +allocate(fn_t (is:ie, js:je)) +allocate(fn_q (is:ie, js:je)) +allocate(alpha_t (is:ie, js:je)) +allocate(alpha_q (is:ie, js:je)) +allocate(alpha_lw (is:ie, js:je)) +allocate(beta_t (is:ie, js:je)) +allocate(beta_q (is:ie, js:je)) +allocate(beta_lw (is:ie, js:je)) +allocate(delta_t_surf (is:ie, js:je)) +allocate(eff_heat_capacity (is:ie, js:je)) +allocate(corrected_flux (is:ie, js:je)) +allocate(t_surf_dependence (is:ie, js:je)) +! +!see if restart file exists for the surface temperature +! +if (file_exist('INPUT/mixed_layer.res.nc')) then + + call nullify_domain() + call read_data(trim('INPUT/mixed_layer.res'), 't_surf', t_surf, grid_domain) + +else if (file_exist('INPUT/swamp.res')) then + unit = open_file (file='INPUT/swamp.res', & + form='native', action='read') + call read_data (unit, t_surf) + call close_file (unit) + call error_mesg('mixed_layer','mixed_layer restart file not found, using swamp restart file', WARNING) +else + call error_mesg('mixed_layer','mixed_layer restart file not found', WARNING) +endif + +id_t_surf = register_diag_field(mod_name, 't_surf', & + axes(1:2), Time, 'surface temperature','K') +id_flux_t = register_diag_field(mod_name, 'flux_t', & + axes(1:2), Time, 'sensible heat flux up at surface','watts/m2') +id_flux_lhe = register_diag_field(mod_name, 'flux_lhe', & + axes(1:2), Time, 'latent heat flux up at surface','watts/m2') +id_flux_oceanq = register_diag_field(mod_name, 'flux_oceanq', & + axes(1:2), Time, 'oceanic Q-flux','watts/m2') + +! latitude will be needed for oceanic q flux +call get_deg_lat(deg_lat) +do j=js,je + rad_lat_2d(:,j) = deg_lat(j)*PI/180. +enddo + +! calculate ocean Q flux +rad_qwidth = qflux_width*PI/180. +ocean_qflux = qflux_amp*(1-2.*rad_lat_2d**2/rad_qwidth**2) * & + exp(- ((rad_lat_2d)**2/(rad_qwidth)**2)) + +! load Q flux +if (load_qflux) then + call read_data('INPUT/ocean_qflux.nc', 'ocean_qflux', ocean_qflux) +endif + +inv_cp_air = 1.0 / CP_AIR + +module_is_initialized = .true. + +return +end subroutine mixed_layer_init + +!================================================================================================================================= + +subroutine mixed_layer ( & + Time, & + t_surf, & + flux_t, & + flux_q, & + flux_r, & + dt, & + net_surf_sw_down, & + surf_lw_down, & + Tri_surf, & + dhdt_surf, & + dedt_surf, & + dedq_surf, & + drdt_surf, & + dhdt_atm, & + dedq_atm) + +! ---- arguments ----------------------------------------------------------- +type(time_type), intent(in) :: Time +real, intent(in), dimension(:,:) :: & + net_surf_sw_down, surf_lw_down +real, intent(in), dimension(:,:) :: & + flux_t, flux_q, flux_r +real, intent(inout), dimension(:,:) :: t_surf +real, intent(in), dimension(:,:) :: & + dhdt_surf, dedt_surf, dedq_surf, & + drdt_surf, dhdt_atm, dedq_atm +real, intent(in) :: dt +type(surf_diff_type), intent(inout) :: Tri_surf + +if(.not.module_is_initialized) then + call error_mesg('mixed_layer','mixed_layer module is not initialized',FATAL) +endif + +! Need to calculate the implicit changes to the lowest level delta_q and delta_t +! - see the discussion in vert_diff.tech.ps + +! Care is needed to differentiate between the sensible heat flux and the +! diffusive flux of temperature + +gamma_t = 1.0 / (1.0 - Tri_surf%dtmass * (Tri_surf%dflux_t + dhdt_atm * inv_cp_air)) +gamma_q = 1.0 / (1.0 - Tri_surf%dtmass * (Tri_surf%dflux_tr(:,:,nhum) + dedq_atm)) + +fn_t = gamma_t * (Tri_surf%delta_t + Tri_surf%dtmass * flux_t * inv_cp_air) +fn_q = gamma_q * (Tri_surf%delta_tr(:,:,nhum) + Tri_surf%dtmass * flux_q) + +en_t = gamma_t * Tri_surf%dtmass * dhdt_surf * inv_cp_air +en_q = gamma_q * Tri_surf%dtmass * dedt_surf + +! +! Note flux_sw doesn't depend on surface or lowest layer values +! Note drdt_atm is not used - should be fixed +! +alpha_t = flux_t * inv_cp_air + dhdt_atm * inv_cp_air * fn_t +alpha_q = flux_q + dedq_atm * fn_q +alpha_lw = flux_r + +beta_t = dhdt_surf * inv_cp_air + dhdt_atm * inv_cp_air * en_t +beta_q = dedt_surf + dedq_atm * en_q +beta_lw = drdt_surf + +! +! Implement mixed layer surface boundary condition +! +corrected_flux = - net_surf_sw_down - surf_lw_down + alpha_t * CP_AIR + alpha_lw + ocean_qflux +t_surf_dependence = beta_t * CP_AIR + beta_lw + + +if (evaporation) then + corrected_flux = corrected_flux + alpha_q * HLV + t_surf_dependence = t_surf_dependence + beta_q * HLV +endif + +! +! Now update the mixed layer surface temperature using an implicit step +! +eff_heat_capacity = depth * RHO_CP + t_surf_dependence * dt + +if (any(eff_heat_capacity .eq. 0.0)) then + write(*,*) 'mixed_layer: error', eff_heat_capacity + call error_mesg('mixed_layer', 'Avoiding division by zero',fatal) +end if + +delta_t_surf = - corrected_flux * dt / eff_heat_capacity + +t_surf = t_surf + delta_t_surf + +! +! Finally calculate the increments for the lowest atmospheric layer +! +Tri_surf%delta_t = fn_t + en_t * delta_t_surf +Tri_surf%delta_tr(:,:,nhum) = fn_q + en_q * delta_t_surf + + +! +! Note: +! When using an implicit step there is not a clearly defined flux for a given timestep +! +if(id_t_surf > 0) used = send_data(id_t_surf, t_surf, Time) +if(id_flux_t > 0) used = send_data(id_flux_t, flux_t, Time) +if(id_flux_lhe > 0) used = send_data(id_flux_lhe, HLV * flux_q, Time) +if(id_flux_oceanq > 0) used = send_data(id_flux_oceanq, ocean_qflux, Time) + +end subroutine mixed_layer + +!================================================================================================================================= + +subroutine mixed_layer_end(t_surf) + +real, intent(inout), dimension(:,:) :: t_surf +integer:: unit + +if(.not.module_is_initialized) return + +! write a restart file for the surface temperature +call nullify_domain() +call write_data(trim('RESTART/mixed_layer.res'), 't_surf', t_surf, grid_domain) + +module_is_initialized = .false. + +end subroutine mixed_layer_end + +!================================================================================================================================= + +end module mixed_layer_mod diff --git a/src/atmos_spectral/init/ic_from_external_file.F90 b/src/atmos_spectral/init/ic_from_external_file.F90 index f5a3a8f29f..72e83b3a0f 100644 --- a/src/atmos_spectral/init/ic_from_external_file.F90 +++ b/src/atmos_spectral/init/ic_from_external_file.F90 @@ -26,7 +26,7 @@ module ic_from_external_file_mod '$Id: ic_from_external_file.F90,v 19.0 2012/01/06 20:35:31 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' public :: ic_from_external_file diff --git a/src/atmos_spectral/init/jablonowski_2006.F90 b/src/atmos_spectral/init/jablonowski_2006.F90 index 13488c81aa..51d3a16854 100644 --- a/src/atmos_spectral/init/jablonowski_2006.F90 +++ b/src/atmos_spectral/init/jablonowski_2006.F90 @@ -37,7 +37,7 @@ module jablonowski_2006_mod '$Id: jablonowski_2006.F90,v 19.0 2012/01/06 20:35:33 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' public :: jablonowski_2006 diff --git a/src/atmos_spectral/init/polvani_2004.F90 b/src/atmos_spectral/init/polvani_2004.F90 index e9d4ff92d4..66f4b08478 100644 --- a/src/atmos_spectral/init/polvani_2004.F90 +++ b/src/atmos_spectral/init/polvani_2004.F90 @@ -34,7 +34,7 @@ module polvani_2004_mod '$Id: polvani_2004.F90,v 19.0 2012/01/06 20:35:35 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' public :: polvani_2004 diff --git a/src/atmos_spectral/init/polvani_2007.F90 b/src/atmos_spectral/init/polvani_2007.F90 index 626e90149e..6e30c7d52e 100644 --- a/src/atmos_spectral/init/polvani_2007.F90 +++ b/src/atmos_spectral/init/polvani_2007.F90 @@ -42,7 +42,7 @@ module polvani_2007_mod private character(len=128), parameter :: version='$Id: polvani_2007.F90,v 19.0 2012/01/06 20:35:37 fms Exp $' -character(len=128), parameter :: tagname='$Name: siena_201207 $' +character(len=128), parameter :: tagname='$Name: tikal $' public :: polvani_2007, polvani_2007_tracer_init, get_polvani_2007_tracers diff --git a/src/atmos_spectral/init/spectral_init_cond.F90 b/src/atmos_spectral/init/spectral_init_cond.F90 index fe32e898a3..9867f55359 100644 --- a/src/atmos_spectral/init/spectral_init_cond.F90 +++ b/src/atmos_spectral/init/spectral_init_cond.F90 @@ -40,7 +40,7 @@ module spectral_init_cond_mod '$Id: spectral_init_cond.F90,v 19.0 2012/01/06 20:35:39 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' public :: spectral_init_cond diff --git a/src/atmos_spectral/init/spectral_initialize_fields.F90 b/src/atmos_spectral/init/spectral_initialize_fields.F90 index be7ff4baa9..3809af95f0 100644 --- a/src/atmos_spectral/init/spectral_initialize_fields.F90 +++ b/src/atmos_spectral/init/spectral_initialize_fields.F90 @@ -16,7 +16,7 @@ module spectral_initialize_fields_mod '$Id: spectral_initialize_fields.F90,v 17.0 2009/07/21 03:00:42 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' contains diff --git a/src/atmos_spectral/init/topog_regularization.F90 b/src/atmos_spectral/init/topog_regularization.F90 index 1441eff2e3..635f887c0a 100644 --- a/src/atmos_spectral/init/topog_regularization.F90 +++ b/src/atmos_spectral/init/topog_regularization.F90 @@ -29,7 +29,7 @@ module topog_regularization_mod '$Id: topog_regularization.F90,v 13.0 2006/03/28 21:17:37 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' public :: compute_lambda, regularize diff --git a/src/atmos_spectral/init/vert_coordinate.F90 b/src/atmos_spectral/init/vert_coordinate.F90 index 1adee87180..ca939ad411 100644 --- a/src/atmos_spectral/init/vert_coordinate.F90 +++ b/src/atmos_spectral/init/vert_coordinate.F90 @@ -52,7 +52,7 @@ module vert_coordinate_mod '$Id: vert_coordinate.F90,v 19.0 2012/01/06 20:35:42 fms Exp $' character(len=128), parameter :: tagname = & -'$Name: siena_201207 $' +'$Name: tikal $' character(len=8) :: ch_tmp logical :: entry_to_logfile_done = .false. diff --git a/src/atmos_spectral/model/every_step_diagnostics.F90 b/src/atmos_spectral/model/every_step_diagnostics.F90 index 5e7571133e..98c058fc5f 100644 --- a/src/atmos_spectral/model/every_step_diagnostics.F90 +++ b/src/atmos_spectral/model/every_step_diagnostics.F90 @@ -24,7 +24,7 @@ module every_step_diagnostics_mod !=============================================================================================== character(len=128), parameter :: version = '$Id: every_step_diagnostics.F90,v 13.0 2006/03/28 21:17:44 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' integer :: id_ps, id_u, id_v, id_t, num_levels, num_tracers integer, allocatable, dimension(:) :: id_tr diff --git a/src/atmos_spectral/model/fv_advection.F90 b/src/atmos_spectral/model/fv_advection.F90 index bd1649643b..bbad7cf530 100644 --- a/src/atmos_spectral/model/fv_advection.F90 +++ b/src/atmos_spectral/model/fv_advection.F90 @@ -11,7 +11,7 @@ module fv_advection_mod private character(len=128), parameter :: version = '$Id: fv_advection.F90,v 13.0 2006/03/28 21:17:47 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' type(domain2D), save, public :: advection_domain diff --git a/src/atmos_spectral/model/global_integral.F90 b/src/atmos_spectral/model/global_integral.F90 index 1c8ea01c74..5a27af3fee 100644 --- a/src/atmos_spectral/model/global_integral.F90 +++ b/src/atmos_spectral/model/global_integral.F90 @@ -19,7 +19,7 @@ module global_integral_mod real :: global_sum_of_wts logical :: entry_to_logfile_done=.false. character(len=128), parameter :: version = '$Id: global_integral.F90,v 13.0 2006/03/28 21:17:51 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' contains diff --git a/src/atmos_spectral/model/implicit.F90 b/src/atmos_spectral/model/implicit.F90 index c70ad556fb..0723dd7c36 100644 --- a/src/atmos_spectral/model/implicit.F90 +++ b/src/atmos_spectral/model/implicit.F90 @@ -30,7 +30,7 @@ module implicit_mod logical :: module_is_initialized = .false. character(len=128), parameter :: version = '$Id: implicit.F90,v 13.0 2006/03/28 21:17:54 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' real, allocatable, dimension(:) :: ref_temperature_implicit real, allocatable, dimension(:) :: ref_ln_p_half, ref_ln_p_full, del_ln_p_half, del_ln_p_full diff --git a/src/atmos_spectral/model/leapfrog.F90 b/src/atmos_spectral/model/leapfrog.F90 index e00fde911f..af41595e5d 100644 --- a/src/atmos_spectral/model/leapfrog.F90 +++ b/src/atmos_spectral/model/leapfrog.F90 @@ -24,7 +24,7 @@ module leapfrog_mod end interface character(len=128), parameter :: version = '$Id leapfrog.f90 $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' public :: leapfrog, leapfrog_2level_A, leapfrog_2level_B diff --git a/src/atmos_spectral/model/matrix_invert.F90 b/src/atmos_spectral/model/matrix_invert.F90 index d163a566c2..6380c0e06e 100644 --- a/src/atmos_spectral/model/matrix_invert.F90 +++ b/src/atmos_spectral/model/matrix_invert.F90 @@ -9,7 +9,7 @@ module matrix_invert_mod integer, private :: maxmag character(len=128), parameter :: version = '$Id matrix_invert.f90 $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: entry_to_logfile_done = .false. contains diff --git a/src/atmos_spectral/model/press_and_geopot.F90 b/src/atmos_spectral/model/press_and_geopot.F90 index 3f2049f8f7..c1ab36748c 100644 --- a/src/atmos_spectral/model/press_and_geopot.F90 +++ b/src/atmos_spectral/model/press_and_geopot.F90 @@ -46,7 +46,7 @@ module press_and_geopot_mod !=============================================================================================== character(len=128), parameter :: version = '$Id: press_and_geopot.F90,v 17.0 2009/07/21 03:00:50 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' !=============================================================================================== diff --git a/src/atmos_spectral/model/spectral_damping.F90 b/src/atmos_spectral/model/spectral_damping.F90 index f0a9dab7b2..812e322e5a 100644 --- a/src/atmos_spectral/model/spectral_damping.F90 +++ b/src/atmos_spectral/model/spectral_damping.F90 @@ -19,7 +19,7 @@ module spectral_damping_mod integer :: ms, me, ns, ne, num_levels character(len=128), parameter :: version = '$Id: spectral_damping.F90,v 17.0 2009/07/21 03:00:53 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' public :: spectral_damping_init, spectral_damping_end, compute_spectral_damping public :: compute_spectral_damping_vor, compute_spectral_damping_div diff --git a/src/atmos_spectral/model/spectral_dynamics.F90 b/src/atmos_spectral/model/spectral_dynamics.F90 index bcacd4985e..042353ac00 100644 --- a/src/atmos_spectral/model/spectral_dynamics.F90 +++ b/src/atmos_spectral/model/spectral_dynamics.F90 @@ -78,7 +78,7 @@ module spectral_dynamics_mod !=============================================================================================== character(len=128), parameter :: version = '$Id: spectral_dynamics.F90,v 19.0 2012/01/06 20:35:46 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' !=============================================================================================== ! variables needed for diagnostics diff --git a/src/atmos_spectral/model/tracer_type.F90 b/src/atmos_spectral/model/tracer_type.F90 index 0e18543b4f..558747edc9 100644 --- a/src/atmos_spectral/model/tracer_type.F90 +++ b/src/atmos_spectral/model/tracer_type.F90 @@ -7,7 +7,7 @@ module tracer_type_mod public :: tracer_type_version, tracer_type_tagname character(len=128) :: tracer_type_version = '$Id: tracer_type.F90,v 11.0 2004/09/28 19:30:05 fms Exp $' -character(len=128) :: tracer_type_tagname = '$Name: siena_201207 $' +character(len=128) :: tracer_type_tagname = '$Name: tikal $' type tracer_type character(len=32) :: name, numerical_representation, advect_horiz, advect_vert, hole_filling diff --git a/src/atmos_spectral/model/water_borrowing.F90 b/src/atmos_spectral/model/water_borrowing.F90 index 9752417e8c..ff0b12f2a1 100644 --- a/src/atmos_spectral/model/water_borrowing.F90 +++ b/src/atmos_spectral/model/water_borrowing.F90 @@ -10,7 +10,7 @@ module water_borrowing_mod public :: water_borrowing character(len=128), parameter :: version = '$Id: water_borrowing.F90,v 10.0 2003/10/24 22:01:01 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: entry_to_logfile_done = .false. contains diff --git a/src/atmos_spectral/tools/gauss_and_legendre.F90 b/src/atmos_spectral/tools/gauss_and_legendre.F90 index 180630425d..db155d2c7b 100644 --- a/src/atmos_spectral/tools/gauss_and_legendre.F90 +++ b/src/atmos_spectral/tools/gauss_and_legendre.F90 @@ -14,7 +14,7 @@ module gauss_and_legendre_mod private character(len=128), parameter :: version = '$Id: gauss_and_legendre.F90,v 10.0 2003/10/24 22:01:02 fms Exp $' -character(len=128), parameter :: tagname ='$Name: siena_201207 $' +character(len=128), parameter :: tagname ='$Name: tikal $' logical :: entry_to_logfile_done=.false. diff --git a/src/atmos_spectral/tools/grid_fourier.F90 b/src/atmos_spectral/tools/grid_fourier.F90 index bdf4fd6bdc..113bae9b41 100644 --- a/src/atmos_spectral/tools/grid_fourier.F90 +++ b/src/atmos_spectral/tools/grid_fourier.F90 @@ -17,7 +17,7 @@ module grid_fourier_mod private character(len=128), parameter :: version = '$Id: grid_fourier.F90,v 11.0 2004/09/28 19:30:50 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' public :: grid_fourier_init, grid_fourier_end, trans_grid_to_fourier, trans_fourier_to_grid public :: get_lon_max, get_longitude_origin, get_deg_lon diff --git a/src/atmos_spectral/tools/spec_mpp.F90 b/src/atmos_spectral/tools/spec_mpp.F90 index 01cefe617f..feaed9acfe 100644 --- a/src/atmos_spectral/tools/spec_mpp.F90 +++ b/src/atmos_spectral/tools/spec_mpp.F90 @@ -13,7 +13,7 @@ module spec_mpp_mod private character(len=128), private :: version = '$Id: spec_mpp.F90,v 14.0 2007/03/15 22:12:44 fms Exp $' - character(len=128), private :: tagname = '$Name: siena_201207 $' + character(len=128), private :: tagname = '$Name: tikal $' type(domain2D), save, public :: grid_domain, spectral_domain, global_spectral_domain logical, private :: module_is_initialized=.FALSE. integer, private :: pe, npes diff --git a/src/atmos_spectral/tools/spherical.F90 b/src/atmos_spectral/tools/spherical.F90 index 89571bfebe..caeebb889a 100644 --- a/src/atmos_spectral/tools/spherical.F90 +++ b/src/atmos_spectral/tools/spherical.F90 @@ -26,7 +26,7 @@ module spherical_mod private character(len=128), parameter :: version = '$Id: spherical.F90,v 13.0 2006/03/28 21:18:30 fms Exp $' -character(len=128), parameter :: tagname ='$Name: siena_201207 $' +character(len=128), parameter :: tagname ='$Name: tikal $' interface compute_lon_deriv_cos module procedure compute_lon_deriv_cos_2d, & diff --git a/src/atmos_spectral/tools/spherical_fourier.F90 b/src/atmos_spectral/tools/spherical_fourier.F90 index ea2b0e5cbe..4c0506bbdb 100644 --- a/src/atmos_spectral/tools/spherical_fourier.F90 +++ b/src/atmos_spectral/tools/spherical_fourier.F90 @@ -40,7 +40,7 @@ module spherical_fourier_mod private character(len=128), parameter :: version = '$Id: spherical_fourier.F90,v 13.0 2006/03/28 21:18:33 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' interface trans_spherical_to_fourier module procedure trans_spherical_to_fourier_3d, & diff --git a/src/atmos_spectral/tools/transforms.F90 b/src/atmos_spectral/tools/transforms.F90 index 5e8f87450f..68defe3786 100644 --- a/src/atmos_spectral/tools/transforms.F90 +++ b/src/atmos_spectral/tools/transforms.F90 @@ -104,7 +104,7 @@ module transforms_mod '$Id: transforms.F90,v 19.0 2012/01/06 20:36:20 fms Exp $' character(len=128), parameter :: tagname=& -'$Name: siena_201207 $' +'$Name: tikal $' ! --------------------------------------------------- diff --git a/src/coupler/coupler_main.F90 b/src/coupler/coupler_main.F90 index 6830323ce1..7e74ab94f5 100644 --- a/src/coupler/coupler_main.F90 +++ b/src/coupler/coupler_main.F90 @@ -228,8 +228,8 @@ program coupler_main !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: coupler_main.F90,v 19.0.4.2.4.1.4.1 2012/05/15 17:57:31 z1l Exp $' - character(len=128) :: tag = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: coupler_main.F90,v 20.0 2013/12/13 23:27:07 fms Exp $' + character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- !---- model defined-types ---- @@ -392,6 +392,9 @@ program coupler_main newClock8, newClock9, newClock10, newClock11, newClock12, newClock13, newClock14, newClocka, & newClockb, newClockc, newClockd, newClocke, newClockf, newClockg, newClockh + integer :: id_atmos_model_init, id_land_model_init, id_ice_model_init + integer :: id_ocean_model_init, id_flux_exchange_init + character(len=80) :: text character(len=48), parameter :: mod_name = 'coupler_main_mod' @@ -417,8 +420,6 @@ program coupler_main call mpp_init() !these clocks are on the global pelist initClock = mpp_clock_id( 'Initialization' ) - mainClock = mpp_clock_id( 'Main loop' ) - termClock = mpp_clock_id( 'Termination' ) call mpp_clock_begin(initClock) call fms_init @@ -720,7 +721,7 @@ program coupler_main if( Atm%pe )then call atmos_model_restart(Atm, timestamp) call land_model_restart(timestamp) - call ice_model_restart(timestamp) + call ice_model_restart(Ice, timestamp) endif if( Ocean%is_ocean_pe) then call ocean_model_restart(Ocean_state, timestamp) @@ -953,8 +954,8 @@ subroutine coupler_init if( atmos_npes+ocean_npes.NE.npes ) & call mpp_error( FATAL, 'coupler_init: atmos_npes+ocean_npes must equal npes for concurrent coupling.' ) else !serial timestepping - if( atmos_npes.EQ.0 )atmos_npes = npes - if( ocean_npes.EQ.0 )ocean_npes = npes + if( (atmos_npes.EQ.0) .and. (do_atmos .or. do_land .or. do_ice) ) atmos_npes = npes + if( (ocean_npes.EQ.0) .and. (do_ocean) ) ocean_npes = npes if( max(atmos_npes,ocean_npes).EQ.npes )then !overlapping pelists ! do nothing else !disjoint pelists @@ -968,7 +969,6 @@ subroutine coupler_init if(land_npes > atmos_npes) call mpp_error(FATAL, 'coupler_init: land_npes > atmos_npes') if(ice_npes > atmos_npes) call mpp_error(FATAL, 'coupler_init: ice_npes > atmos_npes') - allocate( Atm%pelist (atmos_npes) ) allocate( Ocean%pelist(ocean_npes) ) allocate( Land%pelist (land_npes) ) @@ -1008,16 +1008,45 @@ subroutine coupler_init ! call set_cpu_affinity( base_cpu + omp_get_thread_num() ) ! !$OMP END PARALLEL end if + + !--- initialization clock + if( Atm%pe )then + call mpp_set_current_pelist(Atm%pelist) + id_atmos_model_init = mpp_clock_id( ' Init: atmos_model_init ' ) + endif + if( Land%pe )then + call mpp_set_current_pelist(Land%pelist) + id_land_model_init = mpp_clock_id( ' Init: land_model_init ' ) + endif + if( Ice%pe )then + call mpp_set_current_pelist(Ice%pelist) + id_ice_model_init = mpp_clock_id( ' Init: ice_model_init ' ) + endif + if( Ocean%is_ocean_pe )then + call mpp_set_current_pelist(Ocean%pelist) + id_ocean_model_init = mpp_clock_id( ' Init: ocean_model_init ' ) + endif + call mpp_set_current_pelist(ensemble_pelist(ensemble_id,:)) + id_flux_exchange_init = mpp_clock_id( ' Init: flux_exchange_init' ) + call mpp_set_current_pelist() + mainClock = mpp_clock_id( 'Main loop' ) + termClock = mpp_clock_id( 'Termination' ) !Write out messages on root PEs if(mpp_pe().EQ.mpp_root_pe() )then write( text,'(a,2i6,a,i2.2)' )'Atmos PE range: ', Atm%pelist(1) , Atm%pelist(atmos_npes) ,& ' ens_', ensemble_id call mpp_error( NOTE, 'coupler_init: '//trim(text) ) - write( text,'(a,2i6,a,i2.2)' )'Ocean PE range: ', Ocean%pelist(1), Ocean%pelist(ocean_npes), & - ' ens_', ensemble_id - call mpp_error( NOTE, 'coupler_init: '//trim(text) ) + if (ocean_npes .gt. 0) then ! only if ocean is active (cjg) + write( text,'(a,2i6,a,i2.2)' )'Ocean PE range: ', Ocean%pelist(1), Ocean%pelist(ocean_npes), & + ' ens_', ensemble_id + call mpp_error( NOTE, 'coupler_init: '//trim(text) ) + else + write( text,'(a,i2.2)' )'Ocean PE range is not set (do_ocean=.false. and concurrent=.false.) for ens_', & + ensemble_id + call mpp_error( NOTE, 'coupler_init: '//trim(text) ) + end if write( text,'(a,2i6,a,i2.2)' )'Land PE range: ', Land%pelist(1) , Land%pelist(land_npes) ,& ' ens_', ensemble_id call mpp_error( NOTE, 'coupler_init: '//trim(text) ) @@ -1233,7 +1262,10 @@ subroutine coupler_init write(errunit,*) 'Starting to initialize atmospheric model at '& //trim(walldate)//' '//trim(walltime) endif + + call mpp_clock_begin(id_atmos_model_init) call atmos_model_init( Atm, Time_init, Time, Time_step_atmos ) + call mpp_clock_end(id_atmos_model_init) if( mpp_pe().EQ.mpp_root_pe() ) then call DATE_AND_TIME(walldate, walltime, wallzone, wallvalues) write(errunit,*) 'Finished initializing atmospheric model at '& @@ -1250,8 +1282,10 @@ subroutine coupler_init write(errunit,*) 'Starting to initialize land model at '& //trim(walldate)//' '//trim(walltime) endif + call mpp_clock_begin(id_land_model_init) call land_model_init( Atmos_land_boundary, Land, Time_init, Time, & Time_step_atmos, Time_step_cpld ) + call mpp_clock_end(id_land_model_init) if( mpp_pe().EQ.mpp_root_pe() ) then call DATE_AND_TIME(walldate, walltime, wallzone, wallvalues) write(errunit,*) 'Finished initializing land model at '& @@ -1268,7 +1302,9 @@ subroutine coupler_init write(errunit,*) 'Starting to initialize ice model at '& //trim(walldate)//' '//trim(walltime) endif + call mpp_clock_begin(id_ice_model_init) call ice_model_init( Ice, Time_init, Time, Time_step_atmos, Time_step_cpld ) + call mpp_clock_end(id_ice_model_init) if( mpp_pe().EQ.mpp_root_pe() ) then call DATE_AND_TIME(walldate, walltime, wallzone, wallvalues) write(errunit,*) 'Finished initializing ice model at '& @@ -1285,7 +1321,9 @@ subroutine coupler_init write(errunit,*) 'Starting to initialize ocean model at '& //trim(walldate)//' '//trim(walltime) endif + call mpp_clock_begin(id_ocean_model_init) call ocean_model_init( Ocean, Ocean_state, Time_init, Time ) + call mpp_clock_end(id_ocean_model_init) if( mpp_pe().EQ.mpp_root_pe() ) then call DATE_AND_TIME(walldate, walltime, wallzone, wallvalues) write(errunit,*) 'Finished initializing ocean model at '& @@ -1320,10 +1358,14 @@ subroutine coupler_init write(errunit,*) 'Starting to initialize flux_exchange at '& //trim(walldate)//' '//trim(walltime) endif + call mpp_clock_begin(id_flux_exchange_init) call flux_exchange_init ( Time, Atm, Land, Ice, Ocean, Ocean_state,& atmos_ice_boundary, land_ice_atmos_boundary, & land_ice_boundary, ice_ocean_boundary, ocean_ice_boundary, & dt_atmos=dt_atmos, dt_cpld=dt_cpld) + call mpp_set_current_pelist(ensemble_pelist(ensemble_id,:)) + call mpp_clock_end(id_flux_exchange_init) + call mpp_set_current_pelist() if( mpp_pe().EQ.mpp_root_pe() ) then call DATE_AND_TIME(walldate, walltime, wallzone, wallvalues) write(errunit,*) 'Finsihed initializing flux_exchange at '& diff --git a/src/coupler/coupler_main.html b/src/coupler/coupler_main.html deleted file mode 100644 index b3647780e3..0000000000 --- a/src/coupler/coupler_main.html +++ /dev/null @@ -1,396 +0,0 @@ - - - - NAME="wscale" @@ -2373,11 +2415,12 @@ end subroutine ddmix ! ! ! -subroutine blmix_kpp(Thickness, diff_cbt, visc_cbu) +subroutine blmix_kpp(Thickness, diff_cbt, visc_cbu, do_wave) type(ocean_thickness_type), intent(in) :: Thickness real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt real, dimension(isd:,jsd:,:) , intent(inout) :: visc_cbu + logical, intent(in) :: do_wave real, dimension(isd:ied,jsd:jed) :: zt_kl_dummy @@ -2401,7 +2444,7 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbu) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy(:,:) = 0.0 - call wscale (iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale (iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) do j=jsc,jec do i = isc,iec @@ -2472,7 +2515,7 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbu) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy(:,:) = 0.0 - call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) !----------------------------------------------------------------------- ! compute the dimensionless shape functions at the interfaces @@ -2508,10 +2551,16 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbu) !----------------------------------------------------------------------- ! nonlocal transport term = ghats *Program coupler_main - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST - ~ ERROR MESSAGES -
-Program coupler_main
- - - - - -
-OVERVIEW
- -- A main program that couples component models for atmosphere, ocean, land, - and sea ice on independent grids. -
- - - -- This version couples model components representing atmosphere, ocean, land - and sea ice on independent grids. Each model component is represented by a - data type giving the instantaneous model state. - - The component models are coupled to allow implicit vertical diffusion of - heat and moisture at the interfaces of the atmosphere, land, and ice models. - As a result, the atmosphere, land, and ice models all use the same time step. - The atmospheric model has been separated into down and up calls that - correspond to the down and up sweeps of the standard tridiagonal elimination. - - The ocean interface uses explicit mixing. Fluxes to and from the ocean must - be passed through the ice model. This includes atmospheric fluxes as well as - fluxes from the land to the ocean (runoff). - - This program contains the model's main time loop. Each iteration of the - main time loop is one coupled (slow) time step. Within this slow time step - loop is a fast time step loop, using the atmospheric time step, where the - tridiagonal vertical diffusion equations are solved. Exchange between sea - ice and ocean occurs once every slow timestep. - --MAIN PROGRAM EXAMPLE - -------------------- - - DO slow time steps (ocean) - - call flux_ocean_to_ice - - call ICE_SLOW_UP - - DO fast time steps (atmos) - - call flux_calculation - - call ATMOS_DOWN - - call flux_down_from_atmos - - call LAND_FAST - - call ICE_FAST - - call flux_up_to_atmos - - call ATMOS_UP - - END DO - - call ICE_SLOW_DN - - call flux_ice_to_ocean - - call OCEAN - - END DO- -
- - -
-MODULES USED
- --- - - -constants_mod-
time_manager_mod
fms_mod
fms_io_mod
diag_manager_mod
field_manager_mod
tracer_manager_mod
coupler_types_mod
data_override_mod
atmos_model_mod
land_model_mod
ice_model_mod
ocean_model_mod
flux_exchange_mod
atmos_tracer_driver_mod
mpp_mod
mpp_io_mod
mpp_domains_mod
memutils_mod
ensemble_manager_mod
-PUBLIC INTERFACE
----
- - -
-PUBLIC ROUTINES
- -- - - - -
-NAMELIST
- --&coupler_nml --
-
----
-- -current_date -
-- The date that the current integration starts with. -
-
-[integer, dimension(6), default: 0] -- -force_date_from_namelist -
-- Flag that determines whether the namelist variable current_date should - override the date in the restart file INPUT/coupler.res. If the restart - file does not exist then force_date_from_namelist has not effect, the value of current_date - will be used. -
-
-[logical, default: .false.] -- -calendar -
-- The calendar type used by the current integration. Valid values are consistent - with the time_manager module: 'julian', 'noleap', or 'thirty_day'. The value - 'no_calendar' can not be used because the time_manager's date function are used. - All values must be lowercase. -
-
-[character(maxlen=17), default: ''] -- -months -
-- The number of months that the current integration will be run for. -
-
-[integer, default: 0] -- -days -
-- The number of days that the current integration will be run for. -
-
-[integer, default: 0] -- -hours -
-- The number of hours that the current integration will be run for. -
-
-[integer, default: 0] -- -minutes -
-- The number of minutes that the current integration will be run for. -
-
-[integer, default: 0] -- -seconds -
-- The number of seconds that the current integration will be run for. -
-
-[integer, default: 0] -- -dt_atmos -
-- Atmospheric model time step in seconds, including the fast coupling with - land and sea ice. -
-
-[integer, default: 0] -- -dt_cpld -
-- Time step in seconds for coupling between ocean and atmospheric models: - must be an integral multiple of dt_atmos and dt_ocean. This is the "slow" timestep. -
-
-[integer, default: 0] -- -do_atmos, do_ocean, do_ice, do_land, do_flux -
-- If true (default), that particular model component (atmos, etc.) is run. - If false, the execution of that component is skipped. This is used when - ALL the output fields sent by that component to the coupler have been - overridden using the data_override feature. For advanced users only: - if you're not sure, you should leave these values at TRUE. -
-
-[logical] -- -concurrent -
-- If true, the ocean executes concurrently with the atmosphere-land-ocean - on a separate set of PEs. - If false (default), the execution is serial: call atmos... followed by - call ocean... - If using concurrent execution, you must set one of - atmos_npes and ocean_npes, see below. -
-
-[logical] -- -atmos_npes, ocean_npes -
-- If concurrent is set to true, we use these to set the list of PEs on which - each component runs. - At least one of them must be set to a number between 0 and NPES. - If exactly one of these two is set non-zero, the other is set to the - remainder from NPES. - If both are set non-zero they must add up to NPES. -
-
-[integer] -- -atmos_nthreads, ocean_nthreads -
-- We set here the number of OpenMP threads to use - separately for each component (default 1) -
-
-[integer] -- -use_lag_fluxes -
-- If true, then mom4 is forced with SBCs from one coupling timestep ago - If false, then mom4 is forced with most recent SBCs. - For a leapfrog MOM coupling with dt_cpld=dt_ocean, lag fluxes - can be shown to be stable and current fluxes to be unconditionally unstable. - For dt_cpld>dt_ocean there is probably sufficient damping. - use_lag_fluxes is set to TRUE by default. -
-
-[logical] -- -restart_interval -
-- The time interval that write out intermediate restart file. The format is (yr,mo,day,hr,min,sec). - When restart_interval is all zero, no intermediate restart file will be written out. -
-
-[integer, dimension(6), default: 0] -
- - - - -
-ERROR MESSAGES
- --- - --
-- -FATAL error during execution of program coupler_main -
-- -no namelist value for current_date -
-- - A namelist value for current_date must be given if no restart file for - coupler_main (INPUT/coupler.res) is found. -
-- -FATAL error during execution of program coupler_main -
-- -invalid namelist value for calendar -
-- - The value of calendar must be 'julian', 'noleap', or 'thirty_day'. - See the namelist documentation. -
-- -FATAL error during execution of program coupler_main -
-- -no namelist value for calendar -
-- - If no restart file is present, then a namelist value for calendar - must be specified. -
-- -FATAL error during execution of program coupler_main -
-- -initial time is greater than current time -
-- - If a restart file is present, then the namelist value for either - current_date or start_date was incorrectly set. -
-- -FATAL error during execution of program coupler_main -
-- -run length must be multiple of ocean time step -
-- - There must be an even number of ocean time steps for the requested run length. -
-- -WARNING error during execution of program coupler_main -
-- -final time does not match expected ending time -
-- - This error should probably not occur because of checks done at initialization time. -
-
-
-NOTES
- -- --1.If no value is set for current_date, start_date, or calendar (or default value - specified) then the value from restart file "INPUT/coupler.res" will be used. - If neither a namelist value or restart file value exist the program will fail. - 2.The actual run length will be the sum of months, days, hours, minutes, and - seconds. A run length of zero is not a valid option. - 3.The run length must be an intergal multiple of the coupling timestep dt_cpld.- -
- -
--top -- - diff --git a/src/coupler/flux_exchange.F90 b/src/coupler/flux_exchange.F90 index 76842b9d41..4fc900738e 100644 --- a/src/coupler/flux_exchange.F90 +++ b/src/coupler/flux_exchange.F90 @@ -16,11 +16,10 @@ module flux_exchange_mod ! 675 Mass Ave, Cambridge, MA 02139, USA. ! or see: http://www.gnu.org/licenses/gpl.html !----------------------------------------------------------------------- -!Bruce Wyman -!V. Balaji -!Sergey Malyshev +!Bruce Wyman +!V. Balaji +!Sergey Malyshev -!! ! The flux_exchange module provides interfaces to couple the following component @@ -262,8 +261,8 @@ module flux_exchange_mod flux_ocean_from_ice_stocks !----------------------------------------------------------------------- - character(len=128) :: version = '$Id$' - character(len=128) :: tag = '$Name$' + character(len=128) :: version = '$Id: flux_exchange.F90,v 20.0 2013/12/13 23:27:41 fms Exp $' + character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- !---- exchange grid maps ----- @@ -1019,24 +1018,24 @@ subroutine flux_exchange_init ( Time, Atm, Land, Ice, Ocean, Ocean_state,& !AMIP ocean needs no input fields !choice of fields will eventually be done at runtime !via field_manager - allocate( ice_ocean_boundary%u_flux (is:ie,js:je) ) - allocate( ice_ocean_boundary%v_flux (is:ie,js:je) ) - allocate( ice_ocean_boundary%t_flux (is:ie,js:je) ) - allocate( ice_ocean_boundary%q_flux (is:ie,js:je) ) - allocate( ice_ocean_boundary%salt_flux(is:ie,js:je) ) - allocate( ice_ocean_boundary%lw_flux (is:ie,js:je) ) - allocate( ice_ocean_boundary%sw_flux_vis_dir (is:ie,js:je) ) - allocate( ice_ocean_boundary%sw_flux_vis_dif (is:ie,js:je) ) - allocate( ice_ocean_boundary%sw_flux_nir_dir (is:ie,js:je) ) - allocate( ice_ocean_boundary%sw_flux_nir_dif (is:ie,js:je) ) - allocate( ice_ocean_boundary%lprec (is:ie,js:je) ) - allocate( ice_ocean_boundary%fprec (is:ie,js:je) ) - allocate( ice_ocean_boundary%runoff (is:ie,js:je) ) - allocate( ice_ocean_boundary%calving (is:ie,js:je) ) - allocate( ice_ocean_boundary%runoff_hflx (is:ie,js:je) ) - allocate( ice_ocean_boundary%calving_hflx (is:ie,js:je) ) - allocate( ice_ocean_boundary%p (is:ie,js:je) ) - allocate( ice_ocean_boundary%mi (is:ie,js:je) ) + allocate( ice_ocean_boundary%u_flux (is:ie,js:je) ) ; ice_ocean_boundary%u_flux = 0.0 + allocate( ice_ocean_boundary%v_flux (is:ie,js:je) ) ; ice_ocean_boundary%v_flux = 0.0 + allocate( ice_ocean_boundary%t_flux (is:ie,js:je) ) ; ice_ocean_boundary%t_flux = 0.0 + allocate( ice_ocean_boundary%q_flux (is:ie,js:je) ) ; ice_ocean_boundary%q_flux = 0.0 + allocate( ice_ocean_boundary%salt_flux(is:ie,js:je) ) ; ice_ocean_boundary%salt_flux = 0.0 + allocate( ice_ocean_boundary%lw_flux (is:ie,js:je) ) ; ice_ocean_boundary%lw_flux = 0.0 + allocate( ice_ocean_boundary%sw_flux_vis_dir (is:ie,js:je) ) ; ice_ocean_boundary%sw_flux_vis_dir = 0.0 + allocate( ice_ocean_boundary%sw_flux_vis_dif (is:ie,js:je) ) ; ice_ocean_boundary%sw_flux_vis_dif = 0.0 + allocate( ice_ocean_boundary%sw_flux_nir_dir (is:ie,js:je) ) ; ice_ocean_boundary%sw_flux_nir_dir = 0.0 + allocate( ice_ocean_boundary%sw_flux_nir_dif (is:ie,js:je) ) ; ice_ocean_boundary%sw_flux_nir_dif = 0.0 + allocate( ice_ocean_boundary%lprec (is:ie,js:je) ) ; ice_ocean_boundary%lprec = 0.0 + allocate( ice_ocean_boundary%fprec (is:ie,js:je) ) ; ice_ocean_boundary%fprec = 0.0 + allocate( ice_ocean_boundary%runoff (is:ie,js:je) ) ; ice_ocean_boundary%runoff = 0.0 + allocate( ice_ocean_boundary%calving (is:ie,js:je) ) ; ice_ocean_boundary%calving = 0.0 + allocate( ice_ocean_boundary%runoff_hflx (is:ie,js:je) ) ; ice_ocean_boundary%runoff_hflx = 0.0 + allocate( ice_ocean_boundary%calving_hflx (is:ie,js:je) ) ; ice_ocean_boundary%calving_hflx = 0.0 + allocate( ice_ocean_boundary%p (is:ie,js:je) ) ; ice_ocean_boundary%p = 0.0 + allocate( ice_ocean_boundary%mi (is:ie,js:je) ) ; ice_ocean_boundary%mi = 0.0 ! ! allocate fields for extra tracers diff --git a/src/coupler/flux_exchange.html b/src/coupler/flux_exchange.html deleted file mode 100644 index 20ff0b6b61..0000000000 --- a/src/coupler/flux_exchange.html +++ /dev/null @@ -1,1356 +0,0 @@ - - - - Module flux_exchange_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST - ~ DIAGNOSTIC FIELDS - ~ ERROR MESSAGES -
-Module flux_exchange_mod
- - --Contact: Bruce Wyman , - V. Balaji , - Sergey Malyshev -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- The flux_exchange module provides interfaces to couple the following component - models: atmosphere, ocean, land, and ice. All interpolation between physically - distinct model grids is handled by the exchange grid (xgrid_mod) with the - interpolated quantities being conserved. -
- - - -- --1.This version of flux_exchange_mod allows the definition of physically independent - grids for atmosphere, land and sea ice. Ice and ocean must share the same physical - grid (though the domain decomposition on parallel systems may be different). - Grid information is input through the grid_spec file (URL). The masked region of the - land grid and ice/ocean grid must "tile" each other. The masked region of the ice grid - and ocean grid must be identical. - - ATMOSPHERE |----|----|----|----|----|----|----|----| - - LAND |---|---|---|---|xxx|xxx|xxx|xxx|xxx|xxx| - - ICE |xxx|xxx|xxx|xxx|---|---|---|---|---|---| - - OCEAN |xxx|xxx|xxx|xxx|---|---|---|---|---|---| - - where |xxx| = masked grid point - - - The atmosphere, land, and ice grids exchange information using the exchange grid xmap_sfc. - - The land and ice grids exchange runoff data using the exchange grid xmap_runoff. - - Transfer of data between the ice bottom and ocean does not require an exchange - grid as the grids are physically identical. The flux routines will automatically - detect and redistribute data if their domain decompositions are different. - - To get information from the atmosphere to the ocean it must pass through the - ice model, first by interpolating from the atmospheric grid to the ice grid, - and then transferring from the ice grid to the ocean grid. - 2.Each component model must have a public defined data type containing specific - boundary fields. A list of these quantities is located in the NOTES of this document. - - 3.The surface flux of sensible heat and surface evaporation can be implicit functions - of surface temperature. As a consequence, the parts of the land and sea-ice models - that update the surface temperature must be called on the atmospheric time step - - 4.The surface fluxes of all other tracers and of momentum are assumed to be explicit - functions of all surface parameters - - 5.While no explicit reference is made within this module to the implicit treatment - of vertical diffusion in the atmosphere and in the land or sea-ice models, the - module is designed to allow for simultaneous implicit time integration on both - sides of the surface interface. - - 6.Due to #5, the diffusion part of the land and ice models must be called on the - atmospheric time step. -7. Any field passed from one component to another may be "faked" to a - constant value, or to data acquired from a file, using the - data_override feature of FMS. The fields to override are runtime - configurable, using the text file <tt>data_table</tt> for input. - See the data_override_mod documentation for more details. - - We DO NOT RECOMMEND exercising the data override capabilities of - the FMS coupler until the user has acquired considerable - sophistication in running FMS. - - Here is a listing of the override capabilities of the flux_exchange - module: - - FROM the atmosphere boundary TO the exchange grid (in sfc_boundary_layer): - - t_bot, q_bot, z_bot, p_bot, u_bot, v_bot, p_surf, slp, gust - - FROM the ice boundary TO the exchange grid (in sfc_boundary_layer): - - t_surf, rough_mom, rough_heat, rough_moist, albedo, u_surf, v_surf - - FROM the land boundary TO the exchange grid (in sfc_boundary_layer): - - t_surf, t_ca, q_ca, rough_mom, rough_heat, albedo - - FROM the exchange grid TO land_ice_atmos_boundary (in - sfc_boundary_layer): - - t, albedo, land_frac, dt_t, dt_q, u_flux, v_flux, dtaudu, dtaudv, - u_star, b_star, rough_mom - - FROM the atmosphere boundary TO the exchange grid (in - flux_down_from_atmos): - - flux_sw, flux_lw, lprec, fprec, coszen, dtmass, delta_t, - delta_q, dflux_t, dflux_q - - FROM the exchange grid TO the land boundary (in - flux_down_from_atmos): - - t_flux, q_flux, lw_flux, sw_flux, lprec, fprec, dhdt, dedt, dedq, - drdt, drag_q, p_surf - - FROM the exchange grid TO the ice boundary (in flux_down_from_atmos): - - u_flux, v_flux, t_flux, q_flux, lw_flux, lw_flux_dn, sw_flux, - sw_flux_dn, lprec, fprec, dhdt, dedt, drdt, coszen, p - - FROM the land boundary TO the ice boundary (in flux_land_to_ice): - - runoff, calving - - FROM the ice boundary TO the ocean boundary (in flux_ice_to_ocean): - - u_flux, v_flux, t_flux, q_flux, salt_flux, lw_flux, sw_flux, - lprec, fprec, runoff, calving, p - - FROM the ocean boundary TO the ice boundary (in flux_ocean_to_ice): - - u, v, t, s, frazil, sea_level - - FROM the ice boundary TO the atmosphere boundary (in flux_up_to_atmos): - - t_surf - - FROM the land boundary TO the atmosphere boundary (in - flux_up_to_atmos): - - t_ca, t_surf, q_ca - - See NOTES below for an explanation of the field names.- -
- - -
-OTHER MODULES USED
- --- - - -mpp_mod-
mpp_domains_mod
mpp_io_mod
atmos_model_mod
ocean_model_mod
ice_model_mod
land_model_mod
surface_flux_mod
monin_obukhov_mod
xgrid_mod
diag_integral_mod
diag_manager_mod
time_manager_mod
sat_vapor_pres_mod
constants_mod
fms_mod
data_override_mod
coupler_types_mod
atmos_ocean_fluxes_mod
atmos_tracer_driver_mod
field_manager_mod
tracer_manager_mod
stock_constants_mod
scm_forc_mod
-PUBLIC INTERFACE
----
-- -flux_exchange_init:
-- - Initialization routine. -
-- -sfc_boundary_layer:
-- - Computes explicit fluxes as well as derivatives that will be used to compute an implicit flux correction. -
-- -flux_down_from_atmos:
-- - Returns fluxes and derivatives corrected for the implicit treatment of atmospheric - diffusive fluxes, as well as the increments in the temperature and specific humidity - of the lowest atmospheric layer due to all explicit processes as well as the diffusive - fluxes through the top of this layer. -
-- -flux_land_to_ice:
-- - Conservative transfer of water and snow discharge from the land model to sea ice/ocean model. -
-- -flux_ice_to_ocean:
-- - Takes the ice model state (fluxes at the bottom of the ice) and interpolates it to the ocean model grid. -
-- -flux_ocean_to_ice:
-- - Takes the ocean model state and interpolates it onto the bottom of the ice. -
-- -flux_check_stocks:
-- - Check stock values. -
-- -flux_init_stocks:
-- - Initialize stock values. -
-- -generate_sfc_xgrid:
-- - Optimizes the exchange grids by eliminating land and ice partitions with no data. -
-- -flux_up_to_atmos:
-- - Corrects the fluxes for consistency with the new surface temperatures in land - and ice models. -
-- -flux_ice_to_ocean_stocks:
-- - Updates Ice and Ocean stocks. -
-- -flux_ocean_from_ice_stocks:
-- - Updates Ocean stocks due to input that the Ocean model gets. -
-
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-flux_exchange_init
--call flux_exchange_init ( Time, Atm, Land, Ice, Ocean, & atmos_ice_boundary, land_ice_atmos_boundary, & land_ice_boundary, ice_ocean_boundary, ocean_ice_boundary, & dt_atmos, dt_cpld )--
-- -DESCRIPTION -
-- - Initializes the interpolation routines,diagnostics and boundary data -
-
-
-- -INPUT -
-- -
--
-- -Time - current time - -
[time_type]- -Atm - A derived data type to specify atmosphere boundary data. - -
[atmos_data_type]- -Land - A derived data type to specify land boundary data. - -
[land_data_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]- -Ocean - A derived data type to specify ocean boundary data. - -
[ocean_public_type]- -dt_atmos - Atmos time step in secs. - -
[integer]- -dt_cpld - Coupled time step in secs. - -
[integer]
-- -INPUT/OUTPUT -
-- -
--
-- -atmos_ice_boundary - A derived data type to specify properties and fluxes passed from atmosphere to ice. - -
[atmos_ice_boundary_type]- -land_ice_atmos_boundary - A derived data type to specify properties and fluxes passed from exchange grid to - the atmosphere, land and ice. - -
[land_ice_atmos_boundary_type]- -land_ice_boundary - A derived data type to specify properties and fluxes passed from land to ice. - -
[land_ice_boundary_type]- -ice_ocean_boundary - A derived data type to specify properties and fluxes passed from ice to ocean. - -
[ice_ocean_boundary_type]- -ocean_ice_boundary - A derived data type to specify properties and fluxes passed from ocean to ice. - -
[ocean_ice_boundary_type]
-- - -
-sfc_boundary_layer
--call sfc_boundary_layer ( dt, Time, Atm, Land, Ice, Boundary )--
-- -DESCRIPTION -
-- - -
-The following quantities in the land_ice_atmos_boundary_type are computed: - - - t_surf_atm = surface temperature (used for radiation) (K) - albedo_atm = surface albedo (used for radiation) (nondimensional) - rough_mom_atm = surface roughness for momentum (m) - land_frac_atm = fractional area of land beneath an atmospheric - grid box - dtaudu_atm, dtaudv_atm = derivatives of wind stress w.r.t. the - lowest level wind speed (Pa/(m/s)) - flux_u_atm = zonal wind stress (Pa) - flux_v_atm = meridional wind stress (Pa) - u_star_atm = friction velocity (m/s) - b_star_atm = buoyancy scale (m2/s) - - (u_star and b_star are defined so that u_star**2 = magnitude - of surface stress divided by density of air at the surface, - and u_star*b_star = buoyancy flux at the surface)- -
-
-- -INPUT -
-- -
--
-- -dt - time step. - -
[real]- -Time - current time - -
[time_type]
-- -INPUT/OUTPUT -
-- -
--
-- -Atm - A derived data type to specify atmosphere boundary data. - -
[atmos_data_type]- -Land - A derived data type to specify land boundary data. - -
[land_data_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]- -Boundary - A derived data type to specify properties and fluxes passed from exchange grid to - the atmosphere, land and ice. - -
[land_ice_atmos_boundary_type]
-- - -
-flux_down_from_atmos
--call flux_down_from_atmos (Time, Atm, Land, Ice, & Atmos_boundary, Land_boundary, Ice_boundary )--
-- -DESCRIPTION -
-- - -
-The following elements from Atmos_boundary are used as input: - - flux_u_atm = zonal wind stress (Pa) - flux_v_atm = meridional wind stress (Pa) - - - The following elements of Land_boundary are output: - - flux_t_land = sensible heat flux (W/m2) - flux_q_land = specific humidity flux (Kg/(m2 s) - flux_lw_land = net longwave flux (W/m2), uncorrected for - changes in surface temperature - flux_sw_land = net shortwave flux (W/m2) - dhdt_land = derivative of sensible heat flux w.r.t. - surface temperature (on land model grid) (W/(m2 K) - dedt_land = derivative of specific humidity flux w.r.t. - surface temperature (on land model grid) (Kg/(m2 s K) - drdt_land = derivative of upward longwave flux w.r.t. - surface temperature (on land model grid) (W/(m2 K) - lprec_land = liquid precipitation, mass for one time step - (Kg/m2) - fprec_land = frozen precipitation, mass for one time step - (Kg/m2) - - - The following elements of Ice_boundary are output: - - flux_u_ice = zonal wind stress (Pa) - flux_v_ice = meridional wind stress (Pa) - coszen_ice = cosine of the zenith angle- -
-
-- -INPUT -
-- -
--
-- -Time - current time - -
[time_type]- -Land - A derived data type to specify land boundary data. - -
[land_data_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]- -Atmos_boundary - A derived data type to specify properties and fluxes passed from exchange grid to - the atmosphere, land and ice. - -
[land_ice_atmos_boundary_type]
-- -INPUT/OUTPUT -
-- -
--
-- -Atm - A derived data type to specify atmosphere boundary data. - -
[atmos_data_type]- -Land_boundary - A derived data type to specify properties and fluxes passed from atmosphere to land. - -
[atmos_land_boundary_type]- -Ice_boundary - A derived data type to specify properties and fluxes passed from atmosphere to ice. - -
[atmos_ice_boundary_type]
-- - -
-flux_land_to_ice
--call flux_land_to_ice (Time, Land, Ice, Land_Ice_Boundary )--
-- -DESCRIPTION -
-- - -
-The following elements are transferred from the Land to the Land_ice_boundary: - - discharge --> runoff (kg/m2) - discharge_snow --> calving (kg/m2)- -
-
-- -INPUT -
-- -
--
-- -Time - current time - -
[time_type]- -Land - A derived data type to specify land boundary data. - -
[land_data_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]
-- -INPUT/OUTPUT -
-- -
--
-- -Land_Ice_Boundary - A derived data type to specify properties and fluxes passed from land to ice. - -
[land_ice_boundary_type]
-- - -
-flux_ice_to_ocean
--call flux_ice_to_ocean ( Time, Ice, Ocean, Ice_Ocean_Boundary )--
-- -DESCRIPTION -
-- - -
-The following quantities are transferred from the Ice to the ice_ocean_boundary_type: - - flux_u = zonal wind stress (Pa) - flux_v = meridional wind stress (Pa) - flux_t = sensible heat flux (W/m2) - flux_q = specific humidity flux (Kg/m2/s) - flux_salt = salt flux (Kg/m2/s) - flux_sw = net (down-up) shortwave flux (W/m2) - flux_lw = net (down-up) longwave flux (W/m2) - lprec = mass of liquid precipitation since last - time step (Kg/m2) - fprec = mass of frozen precipitation since last - time step (Kg/m2) - runoff = mass (?) of runoff since last time step - (Kg/m2) - p_surf = surface pressure (Pa)- -
-
-- -INPUT -
-- -
--
-- -Time - current time - -
[time_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]- -Ocean - A derived data type to specify ocean boundary data. - -
[ocean_public_type]
-- -INPUT/OUTPUT -
-- -
--
-- -Ice_Ocean_Boundary - A derived data type to specify properties and fluxes passed from ice to ocean. - -
[ice_ocean_boundary_type]
-- - -
-flux_ocean_to_ice
--call flux_ocean_to_ice ( Time, Ocean, Ice, Ocean_Ice_Boundary)--
-- -DESCRIPTION -
-- - -
-The following quantities are transferred from the Ocean to the ocean_ice_boundary_type: - - t_surf = surface temperature (deg K) - frazil = frazil (???) - u_surf = zonal ocean current/ice motion (m/s) - v_surf = meridional ocean current/ice motion (m/s- -
-
-- -INPUT -
-- -
--
-- -Time - current time - -
[time_type]- -Ocean - A derived data type to specify ocean boundary data. - -
[ocean_public_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]
-- -INPUT/OUTPUT -
-- -
--
-- -Ocean_Ice_Boundary - A derived data type to specify properties and fluxes passed from ocean to ice. - -
[ocean_ice_boundary_type]
-- - -
-flux_check_stocks
--
-- -DESCRIPTION -
-- - Will print out any difference between the integrated flux (in time - and space) feeding into a component, and the stock stored in that - component. -
-
-
-- - -
-flux_init_stocks
--
-- -DESCRIPTION -
-- - This will call the various component stock_pe routines to store the - the initial stock values. -
-
-
-- - -
-generate_sfc_xgrid
--call generate_sfc_xgrid ( Land, Ice )--
-- -DESCRIPTION -
-- - Optimizes the exchange grids by eliminating land and ice partitions with no data. -
-
-
-- -INPUT -
-- -
--
-- -Land - A derived data type to specify land boundary data. - -
[land_data_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]
-- - -
-flux_up_to_atmos
--call flux_up_to_atmos ( Time, Land, Ice, Land_Ice_Atmos_Boundary, Land_boundary, Ice_boundary )--
-- -DESCRIPTION -
-- - Corrects the fluxes for consistency with the new surface temperatures in land - and ice models. Final increments for temperature and specific humidity in the - lowest atmospheric layer are computed and returned to the atmospheric model - so that it can finalize the increments in the rest of the atmosphere. -
-The following elements of the land_ice_atmos_boundary_type are computed: - dt_t = temperature change at the lowest - atmospheric level (deg k) - dt_q = specific humidity change at the lowest - atmospheric level (kg/kg)- -
-
-- -INPUT -
-- -
--
-- -Time - Current time. - -
[time_type]
-- -INPUT/OUTPUT -
-- -
--
-- -Land - A derived data type to specify land boundary data. - -
[land_data_type]- -Ice - A derived data type to specify ice boundary data. - -
[ice_data_type]- -Land_Ice_Atmos_Boundary - A derived data type to specify properties and fluxes passed from exchange grid to - the atmosphere, land and ice. - -
[land_ice_atmos_boundary_type]
-- - -
-flux_ice_to_ocean_stocks
--call flux_ice_to_ocean_stocks ( Ice )--
-- -DESCRIPTION -
-- - Integrate the fluxes over the surface and in time. -
-
-
-- -INPUT -
-- -
--
-- -Time - A derived data type to specify ice boundary data. - -
[ice_data_type]
-- - -
-flux_ocean_from_ice_stocks
--call flux_ocean_from_ice_stocks (ocean_state,Ocean,Ice_Ocean_boundary)--
-- -DESCRIPTION -
-- - This subroutine updates the stocks of Ocean by the amount of input that the Ocean gets from Ice component. - Unlike subroutine flux_ice_to_ocean_stocks() that uses Ice%fluxes to update the stocks due to the amount of output from Ice - this subroutine uses Ice_Ocean_boundary%fluxes to calculate the amount of input to the Ocean. These fluxes are the ones - that Ocean model uses internally to calculate its budgets. Hence there should be no difference between this input and what - Ocean model internal diagnostics uses. - This bypasses the possible mismatch in cell areas between Ice and Ocean in diagnosing the stocks of Ocean - and should report a conserving Ocean component regardless of the glitches in fluxes. - - The use of this subroutine in conjunction with subroutine flux_ice_to_ocean_stocks() will also allow to directly - diagnose the amount "stocks lost in exchange" between Ice and Ocean - -
-
-
-
-NAMELIST
- --&flux_exchange_nml --
-
----
-- -z_ref_heat -
-- eference height (meters) for temperature and relative humidity - diagnostics (t_ref,rh_ref,del_h,del_q) -
-
-[real, default: 2.0] -- -z_ref_mom -
-- reference height (meters) for momentum diagnostics (u_ref,v_ref,del_m) -
-
-[real, default: 10.0] -- -ex_u_star_smooth_bug -
-- By default, the global exchange grid u_star will not be interpolated from - atmospheric grid, this is different from Jakarta behavior and will - change answers. So to perserve Jakarta behavior and reproduce answers - explicitly set this namelist variable to .true. in input.nml. - Talk to mw, ens for details. -
-
-[logical, default: false] -- -do_runoff -
-- Turns on/off the land runoff interpolation to the ocean. -
-
-[logical, default: .TRUE.] -
- - - -
-DIAGNOSTIC FIELDS
-Diagnostic fields may be output to a netcdf file by - specifying the module name identifier and the desired field names (given below) in - file diag_table. See the documentation for diag_manager.- - - - -Diagnostic fields for module name identifier: -----
-- -- field name-
----------
land_mask -wind -drag_moist -drag_heat -drag_mom -rough_moist -rough_heat -rough_mom -u_star -b_star -q_star -t_atm -u_atm -v_atm -q_atm -p_atm -z_atm -gust -rh_ref -t_ref -u_ref -v_ref -del_h -del_m -del_q -tau_x -tau_y -ice_mask -t_surf -t_ca -q_surf -shflx -evap -lwflx -- -field description (units)-
-------------------------
fractional amount of land (none) -wind speed for flux calculations (m/s) -drag coeff for moisture (none) -drag coeff for heat (none) -drag coeff for momentum (none) -surface roughness for moisture (m) -surface roughness for heat (m) -surface roughness for momentum (m) -friction velocity (m/s) -buoyancy scale (m/s) -moisture scale (kg water/kg air) -temperature at btm level (deg_k) -u wind component at btm level (m/s) -v wind component at btm level (m/s) -specific humidity at btm level (kg/kg) -pressure at btm level (pa) -height of btm level (m) -gust scale (m/s) -relative humidity at ref height (percent) -temperature at ref height (deg_k) -zonal wind component at ref height (m/s) -meridional wind component at ref height (m/s) -ref height interp factor for heat (none) -ref height interp factor for momentum (none) -ref height interp factor for moisture (none) -zonal wind stress (pa) -meridional wind stress (pa) -fractional amount of sea ice (none) -surface temperature (deg_k) -canopy air temperature (deg_k) -surface specific humidity (kg/kg) -sensible heat flux (w/m2) -evaporation rate (kg/m2/s) -net (down-up) longwave flux (w/m2) -
-ERROR MESSAGES
- --- - --
-- -FATAL in flux_exchange_init -
-- -grid_spec.nc incompatible with atmosphere resolution -
-- - The atmosphere grid size from file grid_spec.nc is not compatible with the atmosphere - resolution from atmosphere model. -
-- -FATAL in flux_exchange_init -
-- -grid_spec.nc incompatible with atmosphere longitudes (see xba.dat and yba.dat) -
-- - longitude from file grid_spec.nc ( from field yba ) is different from the longitude from atmosphere model. -
-- -FATAL in flux_exchange_init -
-- -grid_spec.nc incompatible with atmosphere longitudes (see xba.dat and yba.dat) -
-- - longitude from file grid_spec.nc ( from field xba ) is different from the longitude from atmosphere model. -
-- -FATAL in flux_exchange_init -
-- -grid_spec.nc incompatible with atmosphere latitudes (see grid_spec.nc) -
-- - latgitude from file grid_spec.nc is different from the latitude from atmosphere model. -
-- -FATAL in sfc_boundary_layer -
-- -must call flux_exchange_init first -
-- - flux_exchange_init has not been called before calling sfc_boundary_layer. -
-- -FATAL in flux_ocean_to_ice -
-- -Ocean_Ice_Boundary%xtype must be DIRECT or REDIST. -
-- - The value of variable xtype of ice_ocean_boundary_type data must be DIRECT or REDIST. -
-
-
-NOTES
- -- --MAIN PROGRAM EXAMPLE - -------------------- - - DO slow time steps (ocean) - - call flux_ocean_to_ice - - call ICE_SLOW_UP - - - DO fast time steps (atmos) - - call sfc_boundary_layer - - call ATMOS_DOWN - - call flux_down_from_atmos - - call LAND_FAST - - call ICE_FAST - - call flux_up_to_atmos - - call ATMOS_UP - - END DO - - call ICE_SLOW_DN - - call flux_ice_to_ocean - - call OCEAN - - END DO - - LAND_FAST and ICE_FAST must update the surface temperature - - ======================================================================= - - REQUIRED VARIABLES IN DEFINED DATA TYPES FOR COMPONENT MODELS - -------------------------------------------------------------- - - type (atmos_boundary_data_type) :: Atm - type (surf_diff_type) :: Atm%Surf_Diff - - real, dimension(:) - - Atm%lon_bnd longitude axis grid box boundaries in radians - must be monotonic - Atm%lat_bnd latitude axis grid box boundaries in radians - must be monotonic - - real, dimension(:,:) - - Atm%t_bot temperature at lowest model level - Atm%q_bot specific humidity at lowest model level - Atm%z_bot height above the surface for the lowest model level (m) - Atm%p_bot pressure at lowest model level (pa) - Atm%u_bot zonal wind component at lowest model level (m/s) - Atm%v_bot meridional wind component at lowest model level (m/s) - Atm%p_surf surface pressure (pa) - Atm%slp sea level pressure (pa) - Atm%gust gustiness factor (m/s) - Atm%flux_sw net shortwave flux at the surface - Atm%flux_lw downward longwave flux at the surface - Atm%lprec liquid precipitation (kg/m2) - Atm%fprec water equivalent frozen precipitation (kg/m2) - Atm%coszen cosine of the zenith angle - - (the following five fields are gathered into a data type for convenience in passing - this information through the different levels of the atmospheric model -- - these fields are rlated to the simultaneous implicit time steps in the - atmosphere and surface models -- they are described more fully in - flux_exchange.tech.ps and - in the documntation for vert_diff_mod - - - Atm%Surf_Diff%dtmass = dt/mass where dt = atmospheric time step ((i+1) = (i-1) for leapfrog) (s) - mass = mass per unit area of lowest atmosphehic layer (Kg/m2)) - Atm%Surf_Diff%delta_t increment ((i+1) = (i-1) for leapfrog) in temperature of - lowest atmospheric layer (K) - Atm%Surf_Diff%delta_q increment ((i+1) = (i-1) for leapfrog) in specific humidity of - lowest atmospheric layer (nondimensional -- Kg/Kg) - Atm%Surf_Diff%dflux_t derivative of implicit part of downward temperature flux at top of lowest - atmospheric layer with respect to temperature - of lowest atmospheric layer (Kg/(m2 s)) - Atm%Surf_Diff%dflux_q derivative of implicit part of downward moisture flux at top of lowest - atmospheric layer with respect to specific humidity of - of lowest atmospheric layer (Kg/(m2 s)) - - - integer, dimension(4) - - Atm%axes Axis identifiers returned by diag_axis_init for the - atmospheric model axes: X, Y, Z_full, Z_half. - - ----------------------------------------------- - - type (land_boundary_data_type) :: Land - - real, dimension(:) - - Land%lon_bnd longitude axis grid box boundaries in radians - must be monotonic - Land%lat_bnd latitude axis grid box boundaries in radians - must be monotonic - - logical, dimension(:,:,:) - - Land%mask land/sea mask (true for land) - Land%glacier glacier mask (true for glacier) - - real, dimension(:,:,:) - - Land%tile_size fractional area of each tile (partition) - - Land%t_surf surface temperature (deg k) - Land%albedo surface albedo (fraction) - Land%rough_mom surface roughness for momentum (m) - Land%rough_heat surface roughness for heat/moisture (m) - Land%stomatal stomatal resistance - Land%snow snow depth (water equivalent) (kg/m2) - Land%water water depth of the uppermost bucket (kg/m2) - Land%max_water maximum water depth allowed in the uppermost bucket (kg/m2) - - ----------------------------------------------- - - - type (ice_boundary_data_type) :: Ice - - real, dimension(:) - - Ice%lon_bnd longitude axis grid box boundaries for temperature points - in radians (must be monotonic) - Ice%lat_bnd latitude axis grid box boundaries for temperature points - in radians (must be monotonic) - Ice%lon_bnd_uv longitude axis grid box boundaries for momentum points - in radians (must be monotonic) - Ice%lat_bnd_uv latitude axis grid box boundaries for momentum points - in radians (must be monotonic) - - logical, dimension(:,:,:) - - Ice%mask ocean/land mask for temperature points - (true for ocean, with or without ice) - Ice%mask_uv ocean/land mask for momentum points - (true for ocean, with or without ice) - Ice%ice_mask optional ice mask (true for ice) - - real, dimension(:,:,:) - - Ice%part_size fractional area of each partition of a temperature grid box - Ice%part_size_uv fractional area of each partition of a momentum grid box - - the following fields are located on the ice top grid - - Ice%t_surf surface temperature (deg k) - Ice%albedo surface albedo (fraction) - Ice%rough_mom surface roughness for momentum (m) - Ice%rough_heat surface roughness for heat/moisture (m) - Ice%u_surf zonal (ocean/ice) current at the surface (m/s) - Ice%v_surf meridional (ocean/ice) current at the surface (m/s) - - the following fields are located on the ice bottom grid - - Ice%flux_u zonal wind stress (Pa) - Ice%flux_v meridional wind stress (Pa) - Ice%flux_t sensible heat flux (w/m2) - Ice%flux_q specific humidity flux (kg/m2/s) - Ice%flux_sw net (down-up) shortwave flux (w/m2) - Ice%flux_lw net (down-up) longwave flux (w/m2) - Ice%lprec mass of liquid precipitation since last time step (Kg/m2) - Ice%fprec mass of frozen precipitation since last time step (Kg/m2) - Ice%runoff mass of runoff water since last time step (Kg/m2) - - ----------------------------------------------- - - type (ocean_boundary_data_type) :: Ocean - - real, dimension(:) - - Ocean%Data%lon_bnd longitude axis grid box boundaries for temperature - points on the ocean DATA GRID (radians) - Ocean%Data%lat_bnd latitude axis grid box boundaries for temperature - points on the ocean DATA GRID (radians) - Ocean%Data%lon_bnd_uv longitude axis grid box boundaries for momentum - points on the ocean DATA GRID (radians) - Ocean%Data%lat_bnd_uv latitude axis grid box boundaries for momentum - points on the ocean DATA GRID (radians) - - Ocean%Ocean%lon_bnd longitude axis grid box boundaries for temperature - points on the ocean MODEL GRID (radians) - Ocean%Ocean%lat_bnd latitude axis grid box boundaries for temperature - points on the ocean MODEL GRID (radians) - Ocean%Ocean%lon_bnd_uv longitude axis grid box boundaries for momentum - points on the ocean MODEL GRID (radians) - Ocean%Ocean%lat_bnd_uv latitude axis grid box boundaries for momentum - points on the ocean MODEL GRID (radians) - - Note: The data values in all longitude and latitude grid box boundary - array must be monotonic. - - logical, dimension(:,:) - - Ocean%Data%mask ocean/land mask for temperature points on the ocean - DATA GRID (true for ocean) - Ocean%Data%mask_uv ocean/land mask for momentum points on the ocean - DATA GRID (true for ocean) - - Ocean%Ocean%mask ocean/land mask for temperature points on the ocean - MODEL GRID (true for ocean) - Ocean%Ocean%mask_uv ocean/land mask for momentum points on the ocean - MODEL GRID (true for ocean) - - real, dimension(:,:) - - Ocean%t_surf_data surface temperature on the ocean DATA GRID (deg k) - - Ocean%t_surf surface temperature on the ocean MODEL GRID (deg k) - Ocean%u_surf zonal ocean current at the surface on the ocean - MODEL GRID (m/s) - Ocean%v_surf meridional ocean current at the surface on the - ocean MODEL GRID (m/s) - Ocean%frazil frazil at temperature points on the ocean MODEL GRID- -
- -
--top -- - diff --git a/src/coupler/surface_flux.F90 b/src/coupler/surface_flux.F90 index 33aff01d50..1f78542001 100644 --- a/src/coupler/surface_flux.F90 +++ b/src/coupler/surface_flux.F90 @@ -1,31 +1,27 @@ -! ============================================================================ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! !! +!! GNU General Public License !! +!! !! +!! This file is part of the Flexible Modeling System (FMS). !! +!! !! +!! FMS is free software; you can redistribute it and/or modify it !! +!! under the terms of the GNU General Public License as published by !! +!! the Free Software Foundation, either version 3 of the License, or !! +!! (at your option) any later version. !! +!! !! +!! FMS is distributed in the hope that it will be useful, !! +!! but WITHOUT ANY WARRANTY; without even the implied warranty of !! +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! +!! GNU General Public License for more details. !! +!! !! +!! You should have received a copy of the GNU General Public License !! +!! along with FMS. if not, see: http://www.gnu.org/licenses/gpl.txt !! +!! !! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + module surface_flux_mod -!----------------------------------------------------------------------- -! GNU General Public License -! -! This program is free software; you can redistribute it and/or modify it and -! are expected to follow the terms of the GNU General Public License -! as published by the Free Software Foundation; either version 2 of -! the License, or (at your option) any later version. -! -! MOM is distributed in the hope that it will be useful, but WITHOUT -! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -! License for more details. -! -! For the full text of the GNU General Public License, -! write to: Free Software Foundation, Inc., -! 675 Mass Ave, Cambridge, MA 02139, USA. -! or see: http://www.gnu.org/licenses/gpl.html -!----------------------------------------------------------------------- ! -!Steve Klein -!Isaac Held -!Bruce Wyman - -!V. Balaji -!Sergey Malyshev -!Elena Shevliakova +!GFDL ! ! !@@ -191,14 +187,14 @@ module surface_flux_mod interface surface_flux ! module procedure surface_flux_0d module procedure surface_flux_1d -! module procedure surface_flux_2d + module procedure surface_flux_2d end interface ! !----------------------------------------------------------------------- -character(len=*), parameter :: version = '$Id: surface_flux.F90,v 19.0 2012/01/06 20:36:33 fms Exp $' -character(len=*), parameter :: tagname = '$Name: siena_201207 $' +character(len=*), parameter :: version = '$Id: surface_flux.F90,v 20.0 2013/12/13 23:27:45 fms Exp $' +character(len=*), parameter :: tagname = '$Name: tikal $' logical :: do_init = .true. @@ -726,6 +722,7 @@ subroutine surface_flux_init ! read namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, surface_flux_nml, iostat=io) + ierr = check_nml_error(io,'surface_flux_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file () @@ -754,8 +751,8 @@ end subroutine surface_flux_init !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! ! Over-ocean fluxes following Large and Yeager (used in NCAR models) ! -! Original code: Michael.Winton -! Update Jul2007: Stephen.Griffies (ch and ce exchange coeff bugfix) +! Original code: GFDL.Climate.Model.Info +! Update Jul2007: GFDL.Climate.Model.Info (ch and ce exchange coeff bugfix) !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! ! subroutine ncar_ocean_fluxes (u_del, t, ts, q, qs, z, avail, & diff --git a/src/coupler/surface_flux.html b/src/coupler/surface_flux.html deleted file mode 100644 index 47111e4f49..0000000000 --- a/src/coupler/surface_flux.html +++ /dev/null @@ -1,458 +0,0 @@ - - - - Module surface_flux_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module surface_flux_mod
- - --Contact: Steve Klein , - Isaac Held , - Bruce Wyman -- - -
-Reviewers: V. Balaji , - Sergey Malyshev , - Elena Shevliakova -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Driver program for the calculation of fluxes on the exchange grids. -
- - - -- - --
- - -
-OTHER MODULES USED
- --- - - -fms_mod-
monin_obukhov_mod
sat_vapor_pres_mod
constants_mod
mpp_mod
-PUBLIC INTERFACE
----
-- -surface_flux:
-- - For the calculation of fluxes on the exchange grids. -
-
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-surface_flux
--
-- -- -subroutine surface_flux ( & - t_atm, q_atm_in, u_atm, v_atm, p_atm, z_atm, & - p_surf, t_surf, t_ca, q_surf, & - u_surf, v_surf, & - rough_mom, rough_heat, rough_moist, rough_scale, gust, & - flux_t, flux_q, flux_r, flux_u, flux_v, & - cd_m, cd_t, cd_q, & - w_atm, u_star, b_star, q_star, & - dhdt_surf, dedt_surf, dedq_surf, drdt_surf, & - dhdt_atm, dedq_atm, dtaudu_atm, dtaudv_atm, & - dt, land, seawater, avail )-
--
-- -DESCRIPTION -
-- - For the calculation of fluxes on the exchange grids. -
-
-
-- -INPUT -
-- -
--
-- -t_atm - Air temp lowest atmospheric level. - -
[real, dimension(:)]- -q_atm - Mixing ratio at lowest atmospheric level (kg/kg). - -
[real, dimension(:)]- -u_atm - Zonal wind velocity at lowest atmospheric level. - -
[real, dimension(:)]- -v_atm - Meridional wind velocity at lowest atmospheric level. - -
[real, dimension(:)]- -p_atm - Pressure lowest atmospheric level. - -
[real, dimension(:)]- -z_atm - Height lowest atmospheric level. - -
[real, dimension(:)]- -p_surf - Pressure at the earth's surface - -
[real, dimension(:)]- -t_surf - Temp at the earth's surface - -
[real, dimension(:)]- -t_ca - Air temp at the canopy - -
[real, dimension(:)]- -u_surf - Zonal wind velocity at earth surface. - -
[real, dimension(:)]- -v_surf - Meridional wind velocity at earth surface. - -
[real, dimension(:)]- -rough_mom - Momentum roughness length - -
[real, dimension(:)]- -rough_heat - Heat roughness length - -
[real, dimension(:)]- -rough_moist - <Moisture roughness length - -
[real, dimension(:)]- -rough_scale - Scale factor used to topographic roughness calculation - -
[real, dimension(:)]- -gust - Gustiness factor - -
[real, dimension(:)]- -land - Indicates where land exists (true if exchange cell is on land). - -
[logical, dimension(:)]- -seawater - Indicates where liquid ocean water exists - (true if exchange cell is on liquid ocean water). - -
[logical, dimension(:)]- -avail - True where the exchange cell is active. - -
[logical, dimension(:)]
-- -OUTPUT -
-- -
--
-- -q_surf - Mixing ratio at earth surface (kg/kg). - -
[real, dimension(:)]- -flux_t - Sensible heat flux - -
[real, dimension(:)]- -flux_q - Evaporative water flux - -
[real, dimension(:)]- -flux_r - Radiative energy flux - -
[real, dimension(:)]- -flux_u - Zonal momentum flux - -
[real, dimension(:)]- -flux_v - Meridional momentum flux - -
[real, dimension(:)]- -cd_m - Momentum exchange coefficient - -
[real, dimension(:)]- -cd_t - Heat exchange coefficient - -
[real, dimension(:)]- -cd_q - Moisture exchange coefficient - -
[real, dimension(:)]- -w_atm - Absolute wind at the lowest atmospheric level - -
[real, dimension(:)]- -u_star - Turbulent velocity scale - -
[real, dimension(:)]- -b_star - Turbulent buoyant scale - -
[real, dimension(:)]- -q_star - Turbulent moisture scale - -
[real, dimension(:)]- -dhdt_surf - Sensible heat flux temperature sensitivity - -
[real, dimension(:)]- -dedt_surf - Moisture flux temperature sensitivity - -
[real, dimension(:)]- -dedq_surf - Moisture flux humidity sensitivity - -
[real, dimension(:)]- -drdt_surf - Radiative energy flux temperature sensitivity - -
[real, dimension(:)]- -dhdt_atm - Derivative of sensible heat flux over temp at the lowest atmos level. - -
[real, dimension(:)]- -dedq_atm - Derivative of water vapor flux over temp at the lowest atmos level. - -
[real, dimension(:)]- -dtaudu_atm - Derivative of zonal wind stress w.r.t the lowest level zonal - wind speed of the atmos - -
[real, dimension(:)]- -dtaudv_atm - Derivative of meridional wind stress w.r.t the lowest level meridional - wind speed of the atmos - -
[real, dimension(:)]- -dt - Time step (it is not used presently) - -
[real]
-
-NAMELIST
- --&surface_flux_nml --
-
----
-- -no_neg_q -
-- If q_atm_in (specific humidity) is negative (because of numerical truncation), - then override with 0. -
-
-[logical, default: .false.] -- -use_virtual_temp -
-- If true, use virtual potential temp to calculate the stability of the surface layer. - if false, use potential temp. -
-
-[logical, default: .true.] -- -alt_gustiness -
-- An alternative formulation for gustiness calculation. - A minimum bound on the wind speed used influx calculations, with the bound - equal to gust_const -
-
-[logical, default: .false.] -- -old_dtaudv -
-- The derivative of surface wind stress w.r.t. the zonal wind and - meridional wind are approximated by the same tendency. -
-
-[logical, default: .false.] -- -use_mixing_ratio -
-- An option to provide capability to run the Manabe Climate form of the - surface flux (coded for legacy purposes). -
-
-[logical, default: .false.] -- -gust_const -
-- Constant for alternative gustiness calculation. -
-
-[, default: 1.0] -- -gust_min -
-- Minimum gustiness used when alt_gustiness = false. -
-
-[, default: 0.0] -- -ncar_ocean_flux -
-- Use NCAR climate model turbulent flux calculation described by - Large and Yeager, NCAR Technical Document, 2004 -
-
-[logical, default: .false.] -- -ncar_ocean_flux_orig -
-- Use NCAR climate model turbulent flux calculation described by - Large and Yeager, NCAR Technical Document, 2004, using the original - GFDL implementation, which contains a bug in the specification of - the exchange coefficient for the sensible heat. This option is available - for legacy purposes, and is not recommended for new experiments. -
-
-[logical, default: .false.] -- -raoult_sat_vap -
-- Reduce saturation vapor pressures to account for seawater salinity. -
-
-[logical, default: .false.] -
- - - - -
--top -- - diff --git a/src/ice_param/ice_albedo.F90 b/src/ice_param/ice_albedo.F90 index af7d920855..d0a457ba94 100644 --- a/src/ice_param/ice_albedo.F90 +++ b/src/ice_param/ice_albedo.F90 @@ -30,7 +30,7 @@ module ice_albedo_mod !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: ice_albedo.F90,v 19.0 2012/01/06 20:36:39 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !======================================================================= diff --git a/src/ice_param/ocean_albedo.F90 b/src/ice_param/ocean_albedo.F90 index 13be6073e7..6d1b059bae 100644 --- a/src/ice_param/ocean_albedo.F90 +++ b/src/ice_param/ocean_albedo.F90 @@ -27,7 +27,7 @@ module ocean_albedo_mod !----------------------------------------------------------------------- character(len=256) :: version = '$Id: ocean_albedo.F90,v 19.0 2012/01/06 20:37:11 fms Exp $' -character(len=256) :: tagname = '$Name: siena_201207 $' +character(len=256) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- real :: const_alb = 0.10 diff --git a/src/ice_param/ocean_rough.F90 b/src/ice_param/ocean_rough.F90 index d894586599..4c7e3c16b1 100644 --- a/src/ice_param/ocean_rough.F90 +++ b/src/ice_param/ocean_rough.F90 @@ -21,7 +21,7 @@ module ocean_rough_mod !----------------------------------------------------------------------- character(len=256) :: version = '$Id: ocean_rough.F90,v 19.0 2012/01/06 20:37:13 fms Exp $' -character(len=256) :: tagname = '$Name: siena_201207 $' +character(len=256) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- !----- namelist ----- diff --git a/src/ice_sis/ice_bergs.F90 b/src/ice_sis/ice_bergs.F90 index 81fd18522e..3852f60d72 100644 --- a/src/ice_sis/ice_bergs.F90 +++ b/src/ice_sis/ice_bergs.F90 @@ -6,14 +6,16 @@ module ice_bergs use fms_mod, only: stdlog, stderr, error_mesg, FATAL, WARNING use fms_mod, only: write_version_number, read_data, write_data, file_exist use mosaic_mod, only: get_mosaic_ntiles, get_mosaic_ncontacts -use mpp_mod, only: mpp_pe, mpp_root_pe, mpp_sum, mpp_min, mpp_max, NULL_PE -use mpp_mod, only: mpp_send, mpp_recv, mpp_sync_self, mpp_chksum +use mpp_mod, only: mpp_npes, mpp_pe, mpp_root_pe, mpp_sum, mpp_min, mpp_max, NULL_PE +use mpp_mod, only: mpp_send, mpp_recv, mpp_sync_self, mpp_chksum, input_nml_file use mpp_mod, only: mpp_clock_begin, mpp_clock_end, mpp_clock_id use mpp_mod, only: CLOCK_COMPONENT, CLOCK_SUBCOMPONENT, CLOCK_LOOP use mpp_mod, only: COMM_TAG_1, COMM_TAG_2, COMM_TAG_3, COMM_TAG_4 use mpp_mod, only: COMM_TAG_5, COMM_TAG_6, COMM_TAG_7, COMM_TAG_8 use mpp_mod, only: COMM_TAG_9, COMM_TAG_10 +use mpp_mod, only: mpp_gather use fms_mod, only: clock_flag_default +use fms_io_mod, only: get_instance_filename use mpp_domains_mod, only: domain2D, mpp_update_domains, mpp_define_domains use mpp_parameter_mod, only: SCALAR_PAIR, CGRID_NE, BGRID_NE, CORNER, AGRID use mpp_domains_mod, only: mpp_get_compute_domain, mpp_get_data_domain @@ -161,8 +163,9 @@ module ice_bergs end type icebergs ! Global constants -character(len=*), parameter :: version = '$Id: ice_bergs.F90,v 19.0.2.2.2.2 2012/05/24 18:54:50 Zhi.Liang Exp $' -character(len=*), parameter :: tagname = '$Name: siena_201207 $' +character(len=*), parameter :: version = '$Id: ice_bergs.F90,v 20.0 2013/12/13 23:28:21 fms Exp $' +character(len=*), parameter :: tagname = '$Name: tikal $' + integer, parameter :: nclasses=10 ! Number of ice bergs classes integer, parameter :: file_format_major_version=0 integer, parameter :: file_format_minor_version=1 @@ -192,6 +195,7 @@ module ice_bergs logical :: use_roundoff_fix=.true. ! Use a "fix" for the round-off discrepancy between is_point_in_cell() and pos_within_cell() logical :: old_bug_rotated_weights=.false. ! Skip the rotation of off-center weights for rotated halo updates logical :: make_calving_reproduce=.false. ! Make the calving.res.nc file reproduce across pe count changes. +character(len=10) :: restart_input_dir = 'INPUT/' logical :: folded_north_on_pe = .false. @@ -2538,6 +2542,7 @@ subroutine icebergs_init(bergs, & logical :: passive_mode=.false. ! Add weight of icebergs + bits to ocean logical :: time_average_weight=.false. ! Time average the weight on the ocean logical :: fix_restart_dates=.true. ! After a restart, check that bergs were created before the current model date +logical :: reproduce_siena=.false. !To reproduce siena answers which change across PE layout change set to .true. real :: speed_limit=0. ! CFL speed limit for a berg real, dimension(nclasses) :: initial_mass=(/8.8e7, 4.1e8, 3.3e9, 1.8e10, 3.8e10, 7.5e10, 1.2e11, 2.2e11, 3.9e11, 7.4e11/) ! Mass thresholds between iceberg classes (kg) real, dimension(nclasses) :: distribution=(/0.24, 0.12, 0.15, 0.18, 0.12, 0.07, 0.03, 0.03, 0.03, 0.02/) ! Fraction of calving to apply to this class (non-dim) @@ -2548,7 +2553,7 @@ subroutine icebergs_init(bergs, & rho_bergs, LoW_ratio, debug, really_debug, use_operator_splitting, bergy_bit_erosion_fraction, & parallel_reprod, use_slow_find, sicn_shift, add_weight_to_ocean, passive_mode, ignore_ij_restart, & time_average_weight, generate_test_icebergs, speed_limit, fix_restart_dates, use_roundoff_fix, & - old_bug_rotated_weights, make_calving_reproduce + old_bug_rotated_weights, make_calving_reproduce, restart_input_dir, reproduce_siena ! Local variables integer :: ierr, iunit, i, j, id_class, axes3d(3), is,ie,js,je type(icebergs_gridded), pointer :: grd @@ -2562,10 +2567,14 @@ subroutine icebergs_init(bergs, & ! Read namelist parameters !write(stderrunit,*) 'diamonds: reading namelist' +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=icebergs_nml, iostat=ierr) +#else iunit = open_namelist_file() read (iunit, icebergs_nml,iostat=ierr) - ierr = check_nml_error(ierr, 'icebergs_nml') - call close_file(iunit) + call close_file (iunit) +#endif + ierr = check_nml_error(ierr,'icebergs_nml') if (really_debug) debug=.true. ! One implies the other... @@ -2573,6 +2582,15 @@ subroutine icebergs_init(bergs, & call write_version_number(version, tagname) write (stdlogunit, icebergs_nml) + if( reproduce_siena ) then + if( mpp_pe() == mpp_root_pe() ) then + call error_mesg("ice_bergs: You have overridden the default value of reproduce_siena " // & + "and set it to .true. in icebergs_nml. This is a temporary workaround to " // & + "allow for consistency in continuing experiments.", "Please use the default " //& + "value (.false.) as this option will be removed in a future release. ", WARNING) + endif + endif + ! Allocate overall structure !write(stderrunit,*) 'diamonds: allocating bergs' allocate(bergs) @@ -2713,6 +2731,7 @@ subroutine icebergs_init(bergs, & enddo; enddo ! Sanitize lon for the tile (need continuous longitudes within one tile) + if(reproduce_siena) then j=grd%jsc; do i=grd%isc+1,grd%ied minl=grd%lon(i-1,j)-180. grd%lon(i,j)=modulo(grd%lon(i,j)-minl,360.)+minl @@ -2729,7 +2748,28 @@ subroutine icebergs_init(bergs, & minl=grd%lon(i,j+1)-180. grd%lon(i,j)=modulo(grd%lon(i,j)-minl,360.)+minl enddo; enddo - + else !The fix to reproduce across PE layout change, from AJA + j=grd%jsc; do i=grd%isc+1,grd%ied + minl=grd%lon(i-1,j)-180. + if (abs(grd%lon(i,j)-(modulo(grd%lon(i,j)-minl,360.)+minl))>180.) & + grd%lon(i,j)=modulo(grd%lon(i,j)-minl,360.)+minl + enddo + j=grd%jsc; do i=grd%isc-1,grd%isd,-1 + minl=grd%lon(i+1,j)-180. + if (abs(grd%lon(i,j)-(modulo(grd%lon(i,j)-minl,360.)+minl))>180.) & + grd%lon(i,j)=modulo(grd%lon(i,j)-minl,360.)+minl + enddo + do j=grd%jsc+1,grd%jed; do i=grd%isd,grd%ied + minl=grd%lon(i,j-1)-180. + if (abs(grd%lon(i,j)-(modulo(grd%lon(i,j)-minl,360.)+minl))>180.) & + grd%lon(i,j)=modulo(grd%lon(i,j)-minl,360.)+minl + enddo; enddo + do j=grd%jsc-1,grd%jsd,-1; do i=grd%isd,grd%ied + minl=grd%lon(i,j+1)-180. + if (abs(grd%lon(i,j)-(modulo(grd%lon(i,j)-minl,360.)+minl))>180.) & + grd%lon(i,j)=modulo(grd%lon(i,j)-minl,360.)+minl + enddo; enddo + endif ! lonc, latc used for searches do j=grd%jsd+1,grd%jed; do i=grd%isd+1,grd%ied grd%lonc(i,j)=0.25*( (grd%lon(i,j)+grd%lon(i-1,j-1)) & @@ -2865,6 +2905,8 @@ subroutine icebergs_init(bergs, & if (debug) then call grd_chksum2(grd, grd%lon, 'init lon') call grd_chksum2(grd, grd%lat, 'init lat') + call grd_chksum2(grd, grd%lonc, 'init lonc') + call grd_chksum2(grd, grd%latc, 'init latc') call grd_chksum2(grd, grd%area, 'init area') call grd_chksum2(grd, grd%msk, 'init msk') call grd_chksum2(grd, grd%cos, 'init cos') @@ -2883,14 +2925,15 @@ subroutine read_restart_bergs(bergs,Time) type(icebergs), pointer :: bergs type(time_type), intent(in) :: Time ! Local variables +integer, dimension(:), allocatable :: found_restart_int integer :: k, ierr, ncid, dimid, nbergs_in_file integer :: lonid, latid, uvelid, vvelid, ineid, jneid integer :: massid, thicknessid, widthid, lengthid integer :: start_lonid, start_latid, start_yearid, start_dayid, start_massid integer :: scaling_id, mass_of_bits_id, heat_density_id -logical :: lres, found_restart, multiPErestart=.false. +logical :: lres, found_restart, multiPErestart real :: lon0, lon1, lat0, lat1 -character(len=30) :: filename +character(len=33) :: filename, filename_base type(icebergs_gridded), pointer :: grd type(iceberg) :: localberg ! NOT a pointer but an actual local variable integer :: stderrunit @@ -2903,26 +2946,32 @@ subroutine read_restart_bergs(bergs,Time) ! Find a restart file multiPErestart=.false. - do - filename='INPUT/icebergs.res.nc'; inquire(file=filename,exist=found_restart) - if (found_restart) exit - write(filename(1:27),'("INPUT/icebergs.res.nc.",I4.4)') mpp_pe() - inquire(file=filename,exist=found_restart) - if (found_restart) multiPErestart=.true. - if (found_restart) exit - write(filename(1:21),'("icebergs.res.nc.",I4.4)') mpp_pe() - inquire(file=filename,exist=found_restart) - if (found_restart) multiPErestart=.true. - if (found_restart) exit - filename='icebergs.res.nc'; inquire(file=filename,exist=found_restart) - if (found_restart) exit - if (verbose.and.mpp_pe()==mpp_root_pe()) write(*,'(a)') 'diamonds, read_restart_bergs: no restart file found' -! return ! leave s/r if no restart found - multiPErestart=.true. ! This is to force sanity checking in a mulit-PE mode if no file was found on this PE - exit - enddo - - if (found_restart) then ! only do the following if a file was found + + ! Zero out nbergs_in_file + nbergs_in_file = 0 + + filename_base=trim(restart_input_dir)//'icebergs.res.nc' + + found_restart = find_restart_file(filename_base, filename, multiPErestart) + + ! Check if no restart found on any pe + allocate(found_restart_int(mpp_npes())) + if (found_restart .eqv. .true.) then + k=1 + else + k=0 + endif + call mpp_gather((/k/),found_restart_int) + if (sum(found_restart_int)==0.and.mpp_pe()==mpp_root_pe())& + & write(*,'(a)') 'diamonds, read_restart_bergs: no restart file found' + deallocate(found_restart_int) + + if (.not.found_restart) then + + multiPErestart=.true. ! This is to force sanity checking in a mulit-PE mode if no file was found on this PE + + elseif (found_restart) then ! if (.not.found_restart) + ! only do the following if a file was found if (verbose.and.mpp_pe()==mpp_root_pe()) write(*,'(2a)') 'diamonds, read_restart_bergs: found restart file = ',filename @@ -3021,7 +3070,7 @@ subroutine read_restart_bergs(bergs,Time) else ! if no restart file was read on this PE nbergs_in_file=0 - endif ! if (found_restart) + endif ! if (.not.found_restart) ! Sanity check k=count_bergs(bergs) @@ -3113,7 +3162,7 @@ subroutine read_restart_calving(bergs) type(icebergs), pointer :: bergs ! Local variables integer :: k,i,j -character(len=30) :: filename +character(len=37) :: filename, actual_filename type(icebergs_gridded), pointer :: grd real, allocatable, dimension(:,:) :: randnum type(randomNumberStream) :: rns @@ -3122,7 +3171,7 @@ subroutine read_restart_calving(bergs) grd=>bergs%grd ! Read stored ice - filename='INPUT/calving.res.nc' + filename=trim(restart_input_dir)//'calving.res.nc' if (file_exist(filename)) then if (verbose.and.mpp_pe().eq.mpp_root_pe()) write(*,'(2a)') & 'diamonds, read_restart_calving: reading ',filename @@ -4585,7 +4634,7 @@ subroutine write_restart(bergs) integer :: massid, thicknessid, lengthid, widthid integer :: start_lonid, start_latid, start_yearid, start_dayid, start_massid integer :: scaling_id, mass_of_bits_id, heat_density_id -character(len=28) :: filename +character(len=35) :: filename type(iceberg), pointer :: this integer :: stderrunit @@ -4595,7 +4644,8 @@ subroutine write_restart(bergs) ! Only create a restart file for this PE if we have anything to say if (associated(bergs%first)) then - write(filename(1:28),'("RESTART/icebergs.res.nc.",I4.4)') mpp_pe() + call get_instance_filename("RESTART/icebergs.res.nc", filename) + write(filename,'(A,".",I4.4)') trim(filename), mpp_pe() if (verbose) write(*,'(2a)') 'diamonds, write_restart: creating ',filename iret = nf_create(filename, NF_CLOBBER, ncid) @@ -4736,14 +4786,21 @@ subroutine write_trajectory(trajectory) integer :: uoid, void, uiid, viid, uaid, vaid, sshxid, sshyid, sstid integer :: cnid, hiid integer :: mid, did, wid, lid, mbid, hdid -character(len=30) :: filename +character(len=37) :: filename +character(len=7) :: pe_name type(xyt), pointer :: this, next integer :: stderrunit ! Get the stderr unit number stderrunit=stderr() - - write(filename(1:30),'("iceberg_trajectories.nc.",I4.4)') mpp_pe() + + call get_instance_filename("iceberg_trajectories.nc", filename) + if (mpp_npes()>10000) then + write(pe_name,'(a,i6.6)' )'.', mpp_pe() + else + write(pe_name,'(a,i4.4)' )'.', mpp_pe() + endif + filename=trim(filename)//trim(pe_name) if (debug) write(stderrunit,*) 'diamonds, write_trajectory: creating ',filename iret = nf_create(filename, NF_CLOBBER, ncid) @@ -5373,4 +5430,40 @@ end function berg_chksum ! ############################################################################## +logical function find_restart_file(filename, actual_file, multiPErestart) + character(len=*), intent(in) :: filename + character(len=*), intent(out) :: actual_file + logical, intent(out) :: multiPErestart + + character(len=6) :: pe_name + + find_restart_file = .false. + + ! If running as ensemble, add the ensemble id string to the filename + call get_instance_filename(filename, actual_file) + + ! Prefer combined restart files. + inquire(file=actual_file,exist=find_restart_file) + if (find_restart_file) return + + ! Uncombined restart + if (mpp_npes()>10000) then + write(pe_name,'(a,i6.6)' )'.', mpp_pe() + else + write(pe_name,'(a,i4.4)' )'.', mpp_pe() + endif + actual_file=trim(actual_file)//trim(pe_name) + inquire(file=actual_file,exist=find_restart_file) + if (find_restart_file) then + multiPErestart=.true. + return + endif + + ! No file found, Reset all return parameters + find_restart_file=.false. + actual_file = '' + multiPErestart=.false. + +end function find_restart_file + end module diff --git a/src/ice_sis/ice_dyn.F90 b/src/ice_sis/ice_dyn.F90 index c471913672..29be62861d 100644 --- a/src/ice_sis/ice_dyn.F90 +++ b/src/ice_sis/ice_dyn.F90 @@ -5,12 +5,13 @@ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! module ice_dyn_mod - use mpp_domains_mod, only: mpp_update_domains + use mpp_domains_mod, only: mpp_update_domains, BGRID_NE use constants_mod, only: grav, pi use ice_grid_mod, only: Domain, isc, iec, im, jsc, jec, isd, ied, jsd, jed, jm use ice_grid_mod, only: dtw, dte, dts, dtn, dxt, dxv, dyt, dyv, cor, wett, wetv use ice_grid_mod, only: t_on_uv, t_to_uv, dTdx, dTdy, dt_evp, evp_sub_steps use ice_grid_mod, only: dydx, dxdy + use ice_grid_mod, only: reproduce_siena_201303 use ice_thm_mod, only: DI, DS, DW implicit none @@ -199,7 +200,11 @@ subroutine ice_dynamics(ci, hs, hi, ui, vi, sig11, sig22, sig12, uo, vo, & do l=1,evp_sub_steps ! ! calculate strain tensor for viscosities and forcing elastic eqn. - call mpp_update_domains(ui, vi, Domain) + if(reproduce_siena_201303) then + call mpp_update_domains(ui, vi, Domain) + else + call mpp_update_domains(ui, vi, Domain, gridtype=BGRID_NE) + endif !rab call mpp_update_domains(vi, Domain) ! call set_strn(ui, vi, strn11, strn22, strn12) diff --git a/src/ice_sis/ice_grid.F90 b/src/ice_sis/ice_grid.F90 index ea26751e84..511e2d5e56 100644 --- a/src/ice_sis/ice_grid.F90 +++ b/src/ice_sis/ice_grid.F90 @@ -12,6 +12,7 @@ module ice_grid_mod use mpp_domains_mod, only: mpp_define_io_domain, mpp_copy_domain, mpp_get_global_domain use mpp_domains_mod, only: mpp_set_global_domain, mpp_set_data_domain, mpp_set_compute_domain use mpp_domains_mod, only: mpp_deallocate_domain, mpp_get_pelist, mpp_get_compute_domains + use mpp_domains_mod, only: SCALAR_PAIR, CGRID_NE, BGRID_NE use fms_mod, only: error_mesg, FATAL, field_exist, field_size, read_data use fms_mod, only: get_global_att_value, stderr use mosaic_mod, only: get_mosaic_ntiles, get_mosaic_ncontacts @@ -31,6 +32,7 @@ module ice_grid_mod public :: ice_line, vel_t_to_uv, cut_check, latitude, slab_ice_advect public :: dxdy, dydx, ice_grid_end public :: tripolar_grid, x_cyclic, dt_adv + public :: reproduce_siena_201303 type(domain2D), save :: Domain @@ -65,6 +67,8 @@ module ice_grid_mod real :: dt_adv = 0.0 ! advection timestep (sec) integer :: comm_pe ! pe to be communicated with + logical :: reproduce_siena_201303 = .TRUE. + contains !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! ! ice_avg - take area weighted average over ice partiions ! @@ -605,8 +609,12 @@ subroutine set_ice_grid(ice_domain, dt_slow, dyn_sub_steps_in, & end do end do - call mpp_update_domains(dte, Domain) - call mpp_update_domains(dtn, Domain) + if(reproduce_siena_201303) then + call mpp_update_domains(dte, Domain) + call mpp_update_domains(dtn, Domain) + else + call mpp_update_domains(dte, dtn, Domain, gridtype=CGRID_NE, flags = SCALAR_PAIR) + endif call mpp_update_domains(cos_rot, Domain) call mpp_update_domains(sin_rot, Domain) @@ -633,8 +641,12 @@ subroutine set_ice_grid(ice_domain, dt_slow, dyn_sub_steps_in, & dxv(isc:iec,jsc:jec) = t_on_uv(dxt) dyv(isc:iec,jsc:jec) = t_on_uv(dyt) - call mpp_update_domains(dxv, Domain ) - call mpp_update_domains(dyv, Domain ) + if(reproduce_siena_201303) then + call mpp_update_domains(dxv, Domain ) + call mpp_update_domains(dyv, Domain ) + else + call mpp_update_domains(dxv, dyv, Domain, gridtype=BGRID_NE, flags=SCALAR_PAIR ) + endif !--- dxdy and dydx to be used by ice_dyn_mod. dydx = dTdx(dyt) @@ -838,8 +850,12 @@ subroutine slab_ice_advect(ui, vi, trc, stop_lim) enddo enddo - call mpp_update_domains(ue, Domain) - call mpp_update_domains(vn, Domain) + if(reproduce_siena_201303) then + call mpp_update_domains(ue, Domain) + call mpp_update_domains(vn, Domain) + else + call mpp_update_domains(ue, vn, Domain, gridtype=CGRID_NE) + endif do l=1,adv_sub_steps do j = jsd, jec diff --git a/src/ice_sis/ice_model.F90 b/src/ice_sis/ice_model.F90 index 07ec4a146f..30a35a5fb9 100644 --- a/src/ice_sis/ice_model.F90 +++ b/src/ice_sis/ice_model.F90 @@ -30,7 +30,7 @@ module ice_model_mod use mpp_mod, only: mpp_clock_begin, mpp_clock_end - use mpp_domains_mod, only: mpp_update_domains, BGRID_NE + use mpp_domains_mod, only: mpp_update_domains, BGRID_NE, CGRID_NE use fms_mod, only: error_mesg use diag_manager_mod, only: send_data use time_manager_mod, only: time_type, operator(+), get_date, get_time @@ -78,6 +78,7 @@ module ice_model_mod use ice_grid_mod, only: geo_lon, geo_lat, cell_area, sin_rot, cos_rot, latitude use ice_spec_mod, only: get_sea_surface use ice_grid_mod, only: dte, dtn, dxv, dyv, dxt, dyt, dt_adv, wett + use ice_grid_mod, only: reproduce_siena_201303 ! ! the following two modules are the work horses of the sea ice model ! @@ -373,8 +374,19 @@ subroutine avg_top_quantities ( Ice ) call mpp_update_domains(Ice % flux_u_top, Ice % flux_v_top, Domain ) do k=1,km call vel_t_to_uv( -Ice%flux_u_top(:,:,k),-Ice%flux_v_top(:,:,k), & - Ice%flux_u_top(isc:iec,jsc:jec,k), Ice%flux_v_top(isc:iec,jsc:jec,k) ) + Ice%flux_u_top_bgrid(isc:iec,jsc:jec,k), Ice%flux_v_top_bgrid(isc:iec,jsc:jec,k) ) end do + else + if(reproduce_siena_201303) then + Ice%flux_u_top_bgrid(isc:iec,jsc:jec,:) = Ice%flux_u_top(isc:iec,jsc:jec,:) + Ice%flux_v_top_bgrid(isc:iec,jsc:jec,:) = Ice%flux_v_top(isc:iec,jsc:jec,:) + else + call mpp_update_domains(Ice % flux_u_top, Ice % flux_v_top, Domain ) + do k=1,km + call vel_t_to_uv( Ice%flux_u_top(:,:,k),Ice%flux_v_top(:,:,k), & + Ice%flux_u_top_bgrid(isc:iec,jsc:jec,k), Ice%flux_v_top_bgrid(isc:iec,jsc:jec,k) ) + end do + endif endif do k = 1, km @@ -448,8 +460,8 @@ subroutine ice_top_to_ice_bottom (Ice, part_size, part_size_uv) real, dimension (:,:,:), intent(in) :: part_size, part_size_uv integer :: m, n - Ice % flux_u = all_avg( Ice % flux_u_top(isc:iec,jsc:jec,:) , part_size_uv ) - Ice % flux_v = all_avg( Ice % flux_v_top(isc:iec,jsc:jec,:) , part_size_uv ) + Ice % flux_u = all_avg( Ice % flux_u_top_bgrid(isc:iec,jsc:jec,:) , part_size_uv ) + Ice % flux_v = all_avg( Ice % flux_v_top_bgrid(isc:iec,jsc:jec,:) , part_size_uv ) Ice % flux_t = all_avg( Ice % flux_t_top , part_size ) Ice % flux_q = all_avg( Ice % flux_q_top , part_size ) Ice % flux_sw_nir_dir = all_avg( Ice % flux_sw_nir_dir_top, part_size ) @@ -667,7 +679,11 @@ subroutine ice_bottom_to_ice_top (Ice, t_surf_ice_bot, u_surf_ice_bot, v_surf_ic enddo enddo - call mpp_update_domains(Ice%u_ocn, Ice%v_ocn, Domain) + if(reproduce_siena_201303) then + call mpp_update_domains(Ice%u_ocn, Ice%v_ocn, Domain) + else + call mpp_update_domains(Ice%u_ocn, Ice%v_ocn, Domain, gridtype=BGRID_NE) + endif ! put ocean and ice velocities into Ice%u_surf/v_surf on t-cells call uv_to_t(Ice%u_ocn, Ice%u_surf(:,:,1)) @@ -1047,19 +1063,31 @@ subroutine update_ice_model_slow (Ice, runoff, calving, & tmp2 = ice_avg(Ice%h_ice,Ice%part_size) call mpp_clock_begin(iceClocka) - call ice_dynamics(1-Ice%part_size(:,:,1), tmp1, tmp2, Ice%u_ice, Ice%v_ice, & - Ice%sig11, Ice%sig22, Ice%sig12, Ice%u_ocn, Ice%v_ocn, & - ice_avg(Ice%flux_u_top(isc:iec,jsc:jec,:),Ice%part_size(isc:iec,jsc:jec,:) ), & - ice_avg(Ice%flux_v_top(isc:iec,jsc:jec,:),Ice%part_size(isc:iec,jsc:jec,:) ), & - Ice%sea_lev, fx_wat, fy_wat, fx_ice, fy_ice, fx_cor, fy_cor) + if(reproduce_siena_201303) then + call ice_dynamics(1-Ice%part_size(:,:,1), tmp1, tmp2, Ice%u_ice, Ice%v_ice, & + Ice%sig11, Ice%sig22, Ice%sig12, Ice%u_ocn, Ice%v_ocn, & + ice_avg(Ice%flux_u_top_bgrid(isc:iec,jsc:jec,:),Ice%part_size(isc:iec,jsc:jec,:) ), & + ice_avg(Ice%flux_v_top_bgrid(isc:iec,jsc:jec,:),Ice%part_size(isc:iec,jsc:jec,:) ), & + Ice%sea_lev, fx_wat, fy_wat, fx_ice, fy_ice, fx_cor, fy_cor) + else + call ice_dynamics(1-Ice%part_size(:,:,1), tmp1, tmp2, Ice%u_ice, Ice%v_ice, & + Ice%sig11, Ice%sig22, Ice%sig12, Ice%u_ocn, Ice%v_ocn, & + ice_avg(Ice%flux_u_top_bgrid(isc:iec,jsc:jec,:),Ice%part_size_uv(isc:iec,jsc:jec,:) ), & + ice_avg(Ice%flux_v_top_bgrid(isc:iec,jsc:jec,:),Ice%part_size_uv(isc:iec,jsc:jec,:) ), & + Ice%sea_lev, fx_wat, fy_wat, fx_ice, fy_ice, fx_cor, fy_cor) + endif call mpp_clock_end(iceClocka) call mpp_clock_begin(iceClockb) - call mpp_update_domains(Ice%u_ice, Ice%v_ice, Domain) - if(tripolar_grid) then - call cut_check('u_ice', Ice%u_ice) ! these calls fix round off differences - call cut_check('v_ice', Ice%v_ice) ! in northernmost velocities over the fold + if(reproduce_siena_201303) then call mpp_update_domains(Ice%u_ice, Ice%v_ice, Domain) + if(tripolar_grid) then + call cut_check('u_ice', Ice%u_ice) ! these calls fix round off differences + call cut_check('v_ice', Ice%v_ice) ! in northernmost velocities over the fold + call mpp_update_domains(Ice%u_ice, Ice%v_ice, Domain) + endif + else + call mpp_update_domains(Ice%u_ice, Ice%v_ice, Domain, gridtype=BGRID_NE) endif call mpp_clock_end(iceClockb) @@ -1068,9 +1096,9 @@ subroutine update_ice_model_slow (Ice, runoff, calving, & ! Dynamics diagnostics ! if (id_fax>0) & - sent = send_data(id_fax, all_avg(Ice%flux_u_top(isc:iec,jsc:jec,:),Ice%part_size_uv), Ice%Time) + sent = send_data(id_fax, all_avg(Ice%flux_u_top_bgrid(isc:iec,jsc:jec,:),Ice%part_size_uv), Ice%Time) if (id_fay>0) & - sent = send_data(id_fay, all_avg(Ice%flux_v_top(isc:iec,jsc:jec,:),Ice%part_size_uv), Ice%Time) + sent = send_data(id_fay, all_avg(Ice%flux_v_top_bgrid(isc:iec,jsc:jec,:),Ice%part_size_uv), Ice%Time) if (id_fix>0) sent = send_data(id_fix, fx_ice, Ice%Time) if (id_fiy>0) sent = send_data(id_fiy, fy_ice, Ice%Time) if (id_fcx>0) sent = send_data(id_fcx, fx_cor, Ice%Time) @@ -1097,8 +1125,8 @@ subroutine update_ice_model_slow (Ice, runoff, calving, & do k=2,km do j = jsc, jec do i = isc, iec - Ice%flux_u_top(i,j,k) = fx_wat(i,j) ! stress of ice on ocean - Ice%flux_v_top(i,j,k) = fy_wat(i,j) ! + Ice%flux_u_top_bgrid(i,j,k) = fx_wat(i,j) ! stress of ice on ocean + Ice%flux_v_top_bgrid(i,j,k) = fy_wat(i,j) ! enddo enddo end do @@ -1658,7 +1686,12 @@ subroutine transport (Ice) enddo enddo endif - call mpp_update_domains(uc, vc, Domain) + + if(reproduce_siena_201303) then + call mpp_update_domains(uc, vc, Domain) + else + call mpp_update_domains(uc, vc, Domain, gridtype=CGRID_NE) + endif uf = 0.0; vf = 0.0 do k=2,km diff --git a/src/ice_sis/ice_spec.F90 b/src/ice_sis/ice_spec.F90 index b93403ffc8..3914543531 100644 --- a/src/ice_sis/ice_spec.F90 +++ b/src/ice_sis/ice_spec.F90 @@ -4,7 +4,8 @@ module ice_spec_mod use fms_mod, only: open_namelist_file, check_nml_error, close_file, & - stdlog, mpp_pe, mpp_root_pe, write_version_number + stdlog, stdout, mpp_pe, mpp_root_pe, write_version_number +use mpp_mod, only: input_nml_file use time_manager_mod, only: time_type, get_date, set_date use data_override_mod,only: data_override @@ -15,8 +16,8 @@ module ice_spec_mod private public :: get_sea_surface -character(len=128), parameter :: version = '$Id: ice_spec.F90,v 17.0 2009/07/21 03:01:45 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: version = '$Id: ice_spec.F90,v 20.0 2013/12/13 23:28:29 fms Exp $' +character(len=128), parameter :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. @@ -54,18 +55,25 @@ subroutine get_sea_surface(Time, ts, cn, iceh) integer :: ierr, io, unit type(time_type) :: Spec_Time integer :: tod(3),dum +integer :: stdoutunit,stdlogunit + +stdoutunit=stdout() +stdlogunit=stdlog() if(.not.module_is_initialized) then - unit = open_namelist_file() - ierr=1 - do while (ierr /= 0) - read(unit, nml=ice_spec_nml, iostat=io, end=20) - ierr = check_nml_error (io, 'ice_spec_nml') - enddo -20 call close_file (unit) +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=ice_spec_nml, iostat=io) +#else + unit = open_namelist_file() + read (unit, ice_spec_nml,iostat=io) + call close_file (unit) +#endif + ierr = check_nml_error(io,'ice_spec_nml') + write (stdoutunit,'(/)') + write (stdoutunit, ice_spec_nml) + write (stdlogunit, ice_spec_nml) + call write_version_number(version, tagname) - unit = stdlog() - if(mpp_pe() == mpp_root_pe()) write (unit, nml=ice_spec_nml) module_is_initialized = .true. endif diff --git a/src/ice_sis/ice_type.F90 b/src/ice_sis/ice_type.F90 index 445ffbf200..b1abee5f2b 100644 --- a/src/ice_sis/ice_type.F90 +++ b/src/ice_sis/ice_type.F90 @@ -5,9 +5,9 @@ module ice_type_mod use mpp_mod, only: mpp_pe, mpp_root_pe, mpp_sum, mpp_clock_id, CLOCK_COMPONENT, & - CLOCK_LOOP, CLOCK_ROUTINE, stdout - use mpp_domains_mod, only: domain2D, mpp_update_domains - use fms_mod, only: file_exist, open_namelist_file, check_nml_error, & + CLOCK_LOOP, CLOCK_ROUTINE, stdout,input_nml_file + use mpp_domains_mod, only: domain2D, mpp_update_domains, CORNER, BGRID_NE + use fms_mod, only: file_exist, open_namelist_file, check_nml_error, write_version_number,& read_data, close_file, field_exist, & stderr, stdlog, error_mesg, FATAL, WARNING, NOTE, clock_flag_default use fms_io_mod, only: save_restart, restore_state, query_initialized, & @@ -23,6 +23,7 @@ module ice_type_mod use ice_grid_mod, only: geo_lon, geo_lat, cell_area, sin_rot, cos_rot, wett, xb1d, yb1d use ice_grid_mod, only: geo_lonv_ib, geo_latv_ib use ice_grid_mod, only: x_cyclic, tripolar_grid, dtn, dte, wetv + use ice_grid_mod, only: reproduce_siena_201303 use ice_thm_mod, only: ice_thm_param, DI, DS, e_to_melt use ice_dyn_mod, only: ice_dyn_param use constants_mod, only: LI => hlf ! latent heat of fusion - 334e3 J/(kg-ice) @@ -60,6 +61,9 @@ module ice_type_mod public :: iceClock,iceClock1,iceClock2,iceClock3,iceClock4,iceClock5,iceClock6,iceClock7,iceClock8,iceClock9 public :: iceClocka,iceClockb,iceClockc + character(len=128) :: version = '$Id: ice_type.F90,v 20.0 2013/12/13 23:28:32 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' + !---- id for diagnositics ------------------- integer :: id_xb, id_xt, id_yb, id_yt, id_ct, id_xv, id_yv integer :: id_cn, id_hi, id_hs, id_t1, id_t2, id_ts @@ -152,7 +156,7 @@ module ice_type_mod t_range_melt, cm2_bugs, ks, h_lo_lim, verbose, & do_icebergs, add_diurnal_sw, io_layout, channel_viscosity,& smag_ocn, ssh_gravity, chan_cfl_limit, do_sun_angle_for_alb, & - mask_table + mask_table, reproduce_siena_201303 logical :: do_init = .false. real :: hlim(8) = (/ 0.0, 0.1, 0.3, 0.7, 1.1, 1.5, 2.0, 2.5 /) ! thickness limits 1...num_part-1 @@ -194,6 +198,8 @@ module ice_type_mod real, pointer, dimension(:,:) :: v_ocn =>NULL() real, pointer, dimension(:,:,:) :: flux_u_top =>NULL() real, pointer, dimension(:,:,:) :: flux_v_top =>NULL() + real, pointer, dimension(:,:,:) :: flux_u_top_bgrid =>NULL() + real, pointer, dimension(:,:,:) :: flux_v_top_bgrid =>NULL() real, pointer, dimension(:,:,:) :: flux_t_top =>NULL() real, pointer, dimension(:,:,:) :: flux_q_top =>NULL() real, pointer, dimension(:,:,:) :: flux_lw_top =>NULL() @@ -355,11 +361,19 @@ subroutine ice_model_init (Ice, Time_Init, Time, Time_step_fast, Time_step_slow ! ! read namelist and write to logfile ! +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=ice_model_nml, iostat=io) +#else unit = open_namelist_file() read (unit, ice_model_nml,iostat=io) + call close_file (unit) +#endif + ierr = check_nml_error(io,'ice_model_nml') + write (stdoutunit,'(/)') + write (stdoutunit, ice_model_nml) write (stdlogunit, ice_model_nml) - ierr = check_nml_error(io, 'ice_model_nml') - call close_file(unit) + + call write_version_number( version, tagname ) if (spec_ice) then slab_ice = .true. @@ -426,6 +440,9 @@ subroutine ice_model_init (Ice, Time_Init, Time, Time_step_fast, Time_step_slow Ice % lprec_top (isc:iec, jsc:jec, km) , & Ice % fprec_top (isc:iec, jsc:jec, km) ) + allocate ( Ice % flux_u_top_bgrid (isc:iec, jsc:jec, km) , & + Ice % flux_v_top_bgrid (isc:iec, jsc:jec, km) ) + allocate ( Ice % flux_u (isc:iec, jsc:jec ) , & Ice % flux_v (isc:iec, jsc:jec ) , & Ice % flux_t (isc:iec, jsc:jec ) , & @@ -467,6 +484,8 @@ subroutine ice_model_init (Ice, Time_Init, Time, Time_step_fast, Time_step_slow Ice % swdn =0. Ice % flux_u_top =0. Ice % flux_v_top =0. + Ice % flux_u_top_bgrid=0. + Ice % flux_v_top_bgrid=0. Ice % sea_lev =0. Ice % part_size =0. Ice % u_ocn =0. @@ -482,6 +501,24 @@ subroutine ice_model_init (Ice, Time_Init, Time, Time_step_fast, Time_step_slow Ice % t_ice2 =0. Ice % area = cell_area * 4*PI*RADIUS*RADIUS Ice % mi =0. + Ice % u_surf =0. + Ice % v_surf =0. + Ice % s_surf =0. + Ice % flux_t_top =0. + Ice % flux_q_top =0. + Ice % flux_lw_top =0. + Ice % flux_sw_vis_dir_top =0. + Ice % flux_sw_vis_dif_top =0. + Ice % flux_sw_nir_dir_top =0. + Ice % flux_sw_nir_dif_top =0. + Ice % flux_lh_top =0. + Ice % lprec_top =0. + Ice % fprec_top =0. + Ice % flux_salt =0. + Ice % pen =0. + Ice % trn =0. + Ice % bheat =0. + do j = jsc, jec do i = isc, iec @@ -497,7 +534,11 @@ subroutine ice_model_init (Ice, Time_Init, Time, Time_step_fast, Time_step_slow end if enddo enddo - call mpp_update_domains(Ice%vmask, domain=domain ) + if(reproduce_siena_201303) then + call mpp_update_domains(Ice%vmask, domain=domain ) + else + call mpp_update_domains(Ice%vmask, domain=domain, position=CORNER ) + endif Ice % Time = Time Ice % Time_Init = Time_Init @@ -594,8 +635,12 @@ subroutine ice_model_init (Ice, Time_Init, Time, Time_step_fast, Time_step_slow call mpp_update_domains(Ice%h_ice (:,:,2:km), Domain ) call mpp_update_domains(Ice%t_ice1(:,:,2:km), Domain ) call mpp_update_domains(Ice%t_ice2(:,:,2:km), Domain ) - call mpp_update_domains(Ice%u_ice, Domain ) - call mpp_update_domains(Ice%v_ice, Domain ) + if(reproduce_siena_201303) then + call mpp_update_domains(Ice%u_ice, Domain ) + call mpp_update_domains(Ice%v_ice, Domain ) + else + call mpp_update_domains(Ice%u_ice, Ice%v_ice, Domain, gridtype=BGRID_NE ) + endif call mpp_update_domains(Ice%sig11, Domain ) call mpp_update_domains(Ice%sig22, Domain ) call mpp_update_domains(Ice%sig12, Domain ) @@ -718,6 +763,7 @@ subroutine ice_model_end (Ice) deallocate(Ice % part_size, Ice % part_size_uv, Ice % u_surf, Ice % v_surf ) deallocate(Ice % u_ocn, Ice % v_ocn , Ice % rough_mom, Ice % rough_heat ) deallocate(Ice % rough_moist, Ice % albedo, Ice % flux_u_top, Ice % flux_v_top ) + deallocate(Ice % flux_u_top_bgrid, Ice % flux_v_top_bgrid ) deallocate(Ice % flux_t_top, Ice % flux_q_top, Ice % flux_lw_top ) deallocate(Ice % flux_lh_top, Ice % lprec_top, Ice % fprec_top, Ice % flux_u ) deallocate(Ice % flux_v, Ice % flux_t, Ice % flux_q, Ice % flux_lw ) @@ -746,7 +792,8 @@ end subroutine ice_model_end !! Write out restart files registered through register_restart_file ! - subroutine ice_model_restart(time_stamp) + subroutine ice_model_restart(Ice, time_stamp) + type (ice_data_type), intent(inout), optional :: Ice character(len=*), intent(in), optional :: time_stamp call save_restart(Ice_restart, time_stamp) @@ -983,70 +1030,70 @@ subroutine ice_data_type_chksum(id, timestep, data_type) outunit = stdout() 100 FORMAT(" CHECKSUM::",A32," = ",Z20) write(outunit,*) "BEGIN CHECKSUM(ice_data_type):: ", id, timestep - write(outunit,100) 'ice_data_type%part_size ',mpp_chksum(data_type%part_size ) - write(outunit,100) 'ice_data_type%part_size_uv ',mpp_chksum(data_type%part_size_uv ) - write(outunit,100) 'ice_data_type%albedo ',mpp_chksum(data_type%albedo ) - write(outunit,100) 'ice_data_type%albedo_vis_dir ',mpp_chksum(data_type%albedo_vis_dir ) - write(outunit,100) 'ice_data_type%albedo_nir_dir ',mpp_chksum(data_type%albedo_nir_dir ) - write(outunit,100) 'ice_data_type%albedo_vis_dif ',mpp_chksum(data_type%albedo_vis_dif ) - write(outunit,100) 'ice_data_type%albedo_nir_dif ',mpp_chksum(data_type%albedo_nir_dif ) - write(outunit,100) 'ice_data_type%rough_mom ',mpp_chksum(data_type%rough_mom ) - write(outunit,100) 'ice_data_type%rough_heat ',mpp_chksum(data_type%rough_heat ) - write(outunit,100) 'ice_data_type%rough_moist ',mpp_chksum(data_type%rough_moist ) - write(outunit,100) 'ice_data_type%t_surf ',mpp_chksum(data_type%t_surf ) - write(outunit,100) 'ice_data_type%u_surf ',mpp_chksum(data_type%u_surf ) - write(outunit,100) 'ice_data_type%v_surf ',mpp_chksum(data_type%v_surf ) - write(outunit,100) 'ice_data_type%sea_lev ',mpp_chksum(data_type%sea_lev ) - write(outunit,100) 'ice_data_type%s_surf ',mpp_chksum(data_type%s_surf ) - write(outunit,100) 'ice_data_type%u_ocn ',mpp_chksum(data_type%u_ocn ) - write(outunit,100) 'ice_data_type%v_ocn ',mpp_chksum(data_type%v_ocn ) - write(outunit,100) 'ice_data_type%flux_u_top ',mpp_chksum(data_type%flux_u_top ) - write(outunit,100) 'ice_data_type%flux_v_top ',mpp_chksum(data_type%flux_v_top ) - write(outunit,100) 'ice_data_type%flux_t_top ',mpp_chksum(data_type%flux_t_top ) - write(outunit,100) 'ice_data_type%flux_q_top ',mpp_chksum(data_type%flux_q_top ) - write(outunit,100) 'ice_data_type%flux_lw_top ',mpp_chksum(data_type%flux_lw_top ) - write(outunit,100) 'ice_data_type%flux_sw_vis_dir_top',mpp_chksum(data_type%flux_sw_vis_dir_top) - write(outunit,100) 'ice_data_type%flux_sw_vis_dif_top',mpp_chksum(data_type%flux_sw_vis_dif_top) - write(outunit,100) 'ice_data_type%flux_sw_nir_dir_top',mpp_chksum(data_type%flux_sw_nir_dir_top) - write(outunit,100) 'ice_data_type%flux_sw_nir_dif_top',mpp_chksum(data_type%flux_sw_nir_dif_top) - write(outunit,100) 'ice_data_type%flux_lh_top ',mpp_chksum(data_type%flux_lh_top ) - write(outunit,100) 'ice_data_type%lprec_top ',mpp_chksum(data_type%lprec_top ) - write(outunit,100) 'ice_data_type%fprec_top ',mpp_chksum(data_type%fprec_top ) - write(outunit,100) 'ice_data_type%flux_u ',mpp_chksum(data_type%flux_u ) - write(outunit,100) 'ice_data_type%flux_v ',mpp_chksum(data_type%flux_v ) - write(outunit,100) 'ice_data_type%flux_t ',mpp_chksum(data_type%flux_t ) - write(outunit,100) 'ice_data_type%flux_q ',mpp_chksum(data_type%flux_q ) - write(outunit,100) 'ice_data_type%flux_lw ',mpp_chksum(data_type%flux_lw ) - write(outunit,100) 'ice_data_type%flux_sw_vis_dir ',mpp_chksum(data_type%flux_sw_vis_dir ) - write(outunit,100) 'ice_data_type%flux_sw_vis_dif ',mpp_chksum(data_type%flux_sw_vis_dif ) - write(outunit,100) 'ice_data_type%flux_sw_nir_dir ',mpp_chksum(data_type%flux_sw_nir_dir ) - write(outunit,100) 'ice_data_type%flux_sw_nir_dif ',mpp_chksum(data_type%flux_sw_nir_dif ) - write(outunit,100) 'ice_data_type%flux_lh ',mpp_chksum(data_type%flux_lh ) - write(outunit,100) 'ice_data_type%lprec ',mpp_chksum(data_type%lprec ) - write(outunit,100) 'ice_data_type%fprec ',mpp_chksum(data_type%fprec ) - write(outunit,100) 'ice_data_type%p_surf ',mpp_chksum(data_type%p_surf ) - write(outunit,100) 'ice_data_type%runoff ',mpp_chksum(data_type%runoff ) - write(outunit,100) 'ice_data_type%calving ',mpp_chksum(data_type%calving ) - write(outunit,100) 'ice_data_type%flux_salt ',mpp_chksum(data_type%flux_salt ) - write(outunit,100) 'ice_data_type%lwdn ',mpp_chksum(data_type%lwdn ) - write(outunit,100) 'ice_data_type%swdn ',mpp_chksum(data_type%swdn ) - write(outunit,100) 'ice_data_type%pen ',mpp_chksum(data_type%pen ) - write(outunit,100) 'ice_data_type%trn ',mpp_chksum(data_type%trn ) - write(outunit,100) 'ice_data_type%tmelt ',mpp_chksum(data_type%tmelt ) - write(outunit,100) 'ice_data_type%bmelt ',mpp_chksum(data_type%bmelt ) - write(outunit,100) 'ice_data_type%h_snow ',mpp_chksum(data_type%h_snow ) - write(outunit,100) 'ice_data_type%h_ice ',mpp_chksum(data_type%h_ice ) - write(outunit,100) 'ice_data_type%t_ice1 ',mpp_chksum(data_type%t_ice1 ) - write(outunit,100) 'ice_data_type%t_ice2 ',mpp_chksum(data_type%t_ice2 ) - write(outunit,100) 'ice_data_type%u_ice ',mpp_chksum(data_type%u_ice ) - write(outunit,100) 'ice_data_type%v_ice ',mpp_chksum(data_type%v_ice ) - write(outunit,100) 'ice_data_type%sig11 ',mpp_chksum(data_type%sig11 ) - write(outunit,100) 'ice_data_type%sig22 ',mpp_chksum(data_type%sig22 ) - write(outunit,100) 'ice_data_type%sig12 ',mpp_chksum(data_type%sig12) - write(outunit,100) 'ice_data_type%frazil ',mpp_chksum(data_type%frazil) - write(outunit,100) 'ice_data_type%bheat ',mpp_chksum(data_type%bheat) - write(outunit,100) 'ice_data_type%qflx_lim_ice ',mpp_chksum(data_type%qflx_lim_ice) - write(outunit,100) 'ice_data_type%qflx_res_ice ',mpp_chksum(data_type%qflx_res_ice) + write(outunit,100) 'ice_data_type%part_size ',mpp_chksum(data_type%part_size(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%part_size_uv ',mpp_chksum(data_type%part_size_uv(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%albedo ',mpp_chksum(data_type%albedo(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%albedo_vis_dir ',mpp_chksum(data_type%albedo_vis_dir(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%albedo_nir_dir ',mpp_chksum(data_type%albedo_nir_dir(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%albedo_vis_dif ',mpp_chksum(data_type%albedo_vis_dif(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%albedo_nir_dif ',mpp_chksum(data_type%albedo_nir_dif(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%rough_mom ',mpp_chksum(data_type%rough_mom(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%rough_heat ',mpp_chksum(data_type%rough_heat(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%rough_moist ',mpp_chksum(data_type%rough_moist(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_u ',mpp_chksum(data_type%flux_u(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_v ',mpp_chksum(data_type%flux_v(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_t ',mpp_chksum(data_type%flux_t(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_q ',mpp_chksum(data_type%flux_q(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_lw ',mpp_chksum(data_type%flux_lw(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_sw_vis_dir ',mpp_chksum(data_type%flux_sw_vis_dir(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_sw_vis_dif ',mpp_chksum(data_type%flux_sw_vis_dif(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_sw_nir_dir ',mpp_chksum(data_type%flux_sw_nir_dir(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_sw_nir_dif ',mpp_chksum(data_type%flux_sw_nir_dif(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%lprec ',mpp_chksum(data_type%lprec(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%fprec ',mpp_chksum(data_type%fprec(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%p_surf ',mpp_chksum(data_type%p_surf(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%runoff ',mpp_chksum(data_type%runoff(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%calving ',mpp_chksum(data_type%calving(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_salt ',mpp_chksum(data_type%flux_salt(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%h_snow ',mpp_chksum(data_type%h_snow(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%h_ice ',mpp_chksum(data_type%h_ice(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%t_ice1 ',mpp_chksum(data_type%t_ice1(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%t_ice2 ',mpp_chksum(data_type%t_ice2(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%u_ice ',mpp_chksum(data_type%u_ice(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%v_ice ',mpp_chksum(data_type%v_ice(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%sig11 ',mpp_chksum(data_type%sig11(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%sig22 ',mpp_chksum(data_type%sig22(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%sig12 ',mpp_chksum(data_type%sig12(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%frazil ',mpp_chksum(data_type%frazil(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%qflx_lim_ice ',mpp_chksum(data_type%qflx_lim_ice(isc:iec,jsc:jec)) + write(outunit,100) 'ice_data_type%qflx_res_ice ',mpp_chksum(data_type%qflx_res_ice(isc:iec,jsc:jec)) + write(outunit,*) ' ======The following are not restart variables======' + write(outunit,100) 'ice_data_type%u_surf ',mpp_chksum(data_type%u_surf(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%v_surf ',mpp_chksum(data_type%v_surf(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%sea_lev ',mpp_chksum(data_type%sea_lev(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%s_surf ',mpp_chksum(data_type%s_surf(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%u_ocn ',mpp_chksum(data_type%u_ocn(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%v_ocn ',mpp_chksum(data_type%v_ocn(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%flux_u_top ',mpp_chksum(data_type%flux_u_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_v_top ',mpp_chksum(data_type%flux_v_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_t_top ',mpp_chksum(data_type%flux_t_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_q_top ',mpp_chksum(data_type%flux_q_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_lw_top ',mpp_chksum(data_type%flux_lw_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_sw_vis_dir_top',mpp_chksum(data_type%flux_sw_vis_dir_top(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%flux_sw_vis_dif_top',mpp_chksum(data_type%flux_sw_vis_dif_top(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%flux_sw_nir_dir_top',mpp_chksum(data_type%flux_sw_nir_dir_top(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%flux_sw_nir_dif_top',mpp_chksum(data_type%flux_sw_nir_dif_top(isc:iec,jsc:jec,:)) + write(outunit,100) 'ice_data_type%flux_lh_top ',mpp_chksum(data_type%flux_lh_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%lprec_top ',mpp_chksum(data_type%lprec_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%fprec_top ',mpp_chksum(data_type%fprec_top(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%flux_lh ',mpp_chksum(data_type%flux_lh(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%lwdn ',mpp_chksum(data_type%lwdn(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%swdn ',mpp_chksum(data_type%swdn(isc:iec,jsc:jec) ) + write(outunit,100) 'ice_data_type%pen ',mpp_chksum(data_type%pen(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%trn ',mpp_chksum(data_type%trn(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%tmelt ',mpp_chksum(data_type%tmelt(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%bmelt ',mpp_chksum(data_type%bmelt(isc:iec,jsc:jec,:) ) + write(outunit,100) 'ice_data_type%bheat ',mpp_chksum(data_type%bheat(isc:iec,jsc:jec)) do n = 1, data_type%ocean_fields%num_bcs !{ do m = 1, data_type%ocean_fields%bc(n)%num_fields !{ diff --git a/src/land_lad/land_model.F90 b/src/land_lad/land_model.F90 index 91a15c3fa6..963bad8d96 100644 --- a/src/land_lad/land_model.F90 +++ b/src/land_lad/land_model.F90 @@ -196,7 +196,7 @@ module land_model_mod logical :: module_is_initialized = .FALSE. character(len=*), parameter :: module_name = 'land_mod' character(len=128), parameter :: version = '$Id: land_model.F90,v 19.0 2012/01/06 20:38:57 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' ! ==== local module variables ================================================ diff --git a/src/land_lad/land_types.F90 b/src/land_lad/land_types.F90 index beac018f31..3f82f4614e 100644 --- a/src/land_lad/land_types.F90 +++ b/src/land_lad/land_types.F90 @@ -305,8 +305,8 @@ module land_types_mod ! logical :: module_is_initialized =.FALSE. -character(len=128) :: version = '$Id: land_types.F90,v 19.0.4.1.2.1 2012/05/14 13:12:52 Zhi.Liang Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: land_types.F90,v 20.0 2013/12/13 23:28:40 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' contains ! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/src/land_lad/numerics.F90 b/src/land_lad/numerics.F90 index 15d947307b..92cfb5bf8a 100644 --- a/src/land_lad/numerics.F90 +++ b/src/land_lad/numerics.F90 @@ -65,7 +65,7 @@ module numerics_mod ! module constants character(len=*), parameter :: mod_name = "Numerics_mod" character(len=128) :: version = '$Id: numerics.F90,v 15.0 2007/08/14 04:00:08 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' contains diff --git a/src/land_lad/soil/land_properties.F90 b/src/land_lad/soil/land_properties.F90 index c94dab12a8..5036f6369e 100644 --- a/src/land_lad/soil/land_properties.F90 +++ b/src/land_lad/soil/land_properties.F90 @@ -530,7 +530,7 @@ module land_properties_mod logical :: module_is_initialized =.FALSE. character(len=128) :: version = '$Id: land_properties.F90,v 19.0 2012/01/06 20:39:32 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !---- other module variables and named constants diff --git a/src/land_lad/soil/rivers.F90 b/src/land_lad/soil/rivers.F90 index d3270b229e..7f54e9d4b0 100644 --- a/src/land_lad/soil/rivers.F90 +++ b/src/land_lad/soil/rivers.F90 @@ -178,7 +178,7 @@ module rivers_mod character(len=*), parameter :: mod_name = 'rivers' character(len=*), parameter :: file_name = __FILE__ character(len=128), parameter :: version = '$Id: rivers.F90,v 19.0 2012/01/06 20:39:34 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' !diff --git a/src/land_lad/soil/soil.F90 b/src/land_lad/soil/soil.F90 index 81dc623874..046382f1ad 100644 --- a/src/land_lad/soil/soil.F90 +++ b/src/land_lad/soil/soil.F90 @@ -307,7 +307,7 @@ module soil_mod ! some names, for information only character(len=*), parameter :: module_name = 'soil' character(len=128), parameter :: version = '$Id: soil.F90,v 16.0 2008/07/30 22:30:32 fms Exp $' -character(len=128), parameter :: tagname = '$Name: siena_201207 $' +character(len=128), parameter :: tagname = '$Name: tikal $' ! ---- module constants ------------------------------------------------------ integer, parameter :: max_lev = 50 diff --git a/src/land_lad/vegetation/vegetation.F90 b/src/land_lad/vegetation/vegetation.F90 index c7123970bd..f2667baadb 100644 --- a/src/land_lad/vegetation/vegetation.F90 +++ b/src/land_lad/vegetation/vegetation.F90 @@ -155,7 +155,7 @@ module vegetation_mod logical :: module_is_initialized =.FALSE. character(len=*), private, parameter :: module_name = 'vegetation_mod' character(len=128), private, parameter :: version = '$Id: vegetation.F90,v 15.0 2007/08/14 04:00:20 fms Exp $' -character(len=128), private, parameter :: tagname = '$Name: siena_201207 $' +character(len=128), private, parameter :: tagname = '$Name: tikal $' ! module constants real, parameter :: d622 = rdgas/rvgas diff --git a/src/land_lad2/canopy_air/cana_tile.F90 b/src/land_lad2/canopy_air/cana_tile.F90 index 284a716f36..1aa24fef60 100644 --- a/src/land_lad2/canopy_air/cana_tile.F90 +++ b/src/land_lad2/canopy_air/cana_tile.F90 @@ -40,7 +40,7 @@ module cana_tile_mod ! ==== module constants ====================================================== character(len=*), parameter :: & version = '$Id: cana_tile.F90,v 18.0 2010/03/02 23:36:42 fms Exp $', & - tagname = '$Name: siena_201207 $' + tagname = '$Name: tikal $' ! ==== data types ====================================================== type :: cana_prog_type diff --git a/src/land_lad2/canopy_air/canopy_air.F90 b/src/land_lad2/canopy_air/canopy_air.F90 index c1f6704ee3..8d470c3206 100644 --- a/src/land_lad2/canopy_air/canopy_air.F90 +++ b/src/land_lad2/canopy_air/canopy_air.F90 @@ -1,10 +1,10 @@ ! ============================================================================ ! canopy air ! ============================================================================ -#include "../shared/debug.inc" - module canopy_air_mod +#include "../shared/debug.inc" + #ifdef INTERNAL_FILE_NML use mpp_mod, only: input_nml_file #else @@ -49,8 +49,8 @@ module canopy_air_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & - version = '$Id: canopy_air.F90,v 19.0 2012/01/06 20:40:41 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: canopy_air.F90,v 20.0 2013/12/13 23:29:31 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'canopy_air_mod' ! options for turbulence parameter calculations @@ -62,15 +62,16 @@ module canopy_air_mod real :: init_T_cold = 260. real :: init_q = 0. real :: init_co2 = 350.0e-6 ! ppmv = mol co2/mol of dry air -real :: rav_lit_vi = 0. ! litter resistance to vapor per v_idx character(len=32) :: turbulence_to_use = 'lm3w' ! or lm3v logical :: save_qco2 = .TRUE. logical :: sfc_dir_albedo_bug = .FALSE. ! if true, reverts to buggy behavior ! where direct albedo was mistakenly used for part of sub-canopy diffuse light +logical :: allow_small_z0 = .FALSE. ! to use z0 provided by lake and glac modules +real :: lai_min_turb = 0.0 ! fudge to desensitize Tv to SW/cosz inconsistency namelist /cana_nml/ & init_T, init_T_cold, init_q, init_co2, turbulence_to_use, & - canopy_air_mass, canopy_air_mass_for_tracers, cpw, rav_lit_vi, save_qco2, & - sfc_dir_albedo_bug + canopy_air_mass, canopy_air_mass_for_tracers, cpw, save_qco2, & + sfc_dir_albedo_bug, allow_small_z0, lai_min_turb !---- end of namelist -------------------------------------------------------- logical :: module_is_initialized =.FALSE. @@ -335,7 +336,6 @@ subroutine cana_turbulence (u_star,& real :: Kh_top ! turbulent exchange coefficient on top of the canopy real :: vegn_idx ! total vegetation index = LAI+SAI real :: rah_sca ! ground-SCA resistance - real :: rav_lit ! additional resistance of litter to vapor transport vegn_idx = vegn_lai+vegn_sai ! total vegetation index select case(turbulence_option) @@ -343,7 +343,7 @@ subroutine cana_turbulence (u_star,& if(vegn_cover > 0) then wind = u_star/VONKARM*log((vegn_height-land_d)/land_z0m) ! normalized wind on top of the canopy a = vegn_cover*a_max - con_v_h = (2*vegn_lai*leaf_co*(1-exp(-a/2))/a)*sqrt(wind/vegn_d_leaf) + con_v_h = (2*max(vegn_lai,lai_min_turb)*leaf_co*(1-exp(-a/2))/a)*sqrt(wind/vegn_d_leaf) con_g_h = u_star*a*VONKARM*(1-land_d/vegn_height) & / (exp(a*(1-grnd_z0s/vegn_height)) - exp(a*(1-(land_z0s+land_d)/vegn_height))) else @@ -355,7 +355,7 @@ subroutine cana_turbulence (u_star,& a = a_max wind=u_star/VONKARM*log((height-land_d)/land_z0m) ! normalized wind on top of the canopy - con_v_h = (2*vegn_lai*leaf_co*(1-exp(-a/2))/a)*sqrt(wind/vegn_d_leaf) + con_v_h = (2*max(vegn_lai,lai_min_turb)*leaf_co*(1-exp(-a/2))/a)*sqrt(wind/vegn_d_leaf) if (land_d > 0.06 .and. vegn_idx > 0.25) then Kh_top = VONKARM*u_star*(height-land_d) @@ -367,10 +367,7 @@ subroutine cana_turbulence (u_star,& endif con_g_h = 1.0/rah_sca end select -! not a good parameterization, but just using for sensitivity analyses now. -! ignores differing biomass and litter turnover rates. - rav_lit = rav_lit_vi * vegn_idx - con_g_v = con_g_h/(1.+rav_lit*con_g_h) + con_g_v = con_g_h con_v_v = con_v_h end subroutine @@ -397,8 +394,8 @@ subroutine cana_roughness(lm2, & subs_z0m, subs_z0s, & snow_z0m, snow_z0s, snow_area, & vegn_cover, vegn_height, vegn_lai, vegn_sai, & - land_d, land_z0m, land_z0s ) - logical, intent(in) :: lm2 + land_d, land_z0m, land_z0s, is_lake_or_glac ) + logical, intent(in) :: lm2, is_lake_or_glac real, intent(in) :: & subs_z0m, subs_z0s, snow_z0m, snow_z0s, snow_area, vegn_cover, vegn_height, & vegn_lai, vegn_sai @@ -465,6 +462,12 @@ subroutine cana_roughness(lm2, & endif land_z0s = land_z0m*exp(-2.0) + if (allow_small_z0.and.is_lake_or_glac) then + land_d = 0 + land_z0m = grnd_z0m + land_z0s = grnd_z0s + endif + end select end subroutine cana_roughness @@ -500,7 +503,7 @@ subroutine cana_step_1 ( cana,& ! ---- local vars real :: rho, grnd_q, qsat, DqsatDTg - call check_temp_range(grnd_T,'cana_step_1','grnd_T') + call check_temp_range(grnd_T,'cana_step_1','grnd_T', lnd%time) call qscomp(grnd_T,p_surf,qsat,DqsatDTg) grnd_q = grnd_rh * qsat diff --git a/src/land_lad2/glacier/glac_tile.F90 b/src/land_lad2/glacier/glac_tile.F90 index 937f6fd0f6..b616c863aa 100644 --- a/src/land_lad2/glacier/glac_tile.F90 +++ b/src/land_lad2/glacier/glac_tile.F90 @@ -52,8 +52,8 @@ module glac_tile_mod ! ==== module constants ====================================================== character(len=*), parameter :: & - version = '$Id: glac_tile.F90,v 19.0 2012/01/06 20:40:47 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: glac_tile.F90,v 20.0 2013/12/13 23:29:33 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'glac_tile_mod' integer, parameter :: max_lev = 30 ! max number of levels in glacier @@ -111,6 +111,7 @@ module glac_tile_mod real, pointer :: w_wilt(:) real :: Eg_part_ref real :: z0_scalar + real :: geothermal_heat_flux real, pointer :: heat_capacity_dry(:) real, pointer :: e(:), f(:) @@ -160,6 +161,7 @@ module glac_tile_mod real :: gw_res_time = 60.*86400 ! mean groundwater residence time, ! used when use_single_geo real :: rsa_exp_global = 1.5 +real :: geothermal_heat_flux_constant = 0.0 ! true continental average is ~0.065 W/m2 real, dimension(n_dim_glac_types) :: & dat_w_sat =(/ 1.000 /),& dat_awc_lm2 =(/ 1.000 /),& @@ -197,7 +199,7 @@ module glac_tile_mod use_lm2_awc, use_lad1_glac, & use_single_glac, use_mcm_albedo, & use_single_geo, glac_index_constant, & - gw_res_time, rsa_exp_global, & + gw_res_time, rsa_exp_global, geothermal_heat_flux_constant, & dat_w_sat, dat_awc_lm2, & dat_k_sat_ref, & dat_psi_sat_ref, dat_chb, & @@ -367,6 +369,7 @@ subroutine glacier_data_init_0d(glac) *(2*pi/(3*glac%pars%chb**2*(1+3/glac%pars%chb)*(1+4/glac%pars%chb)))/2 glac%z0_scalar = glac%pars%z0_momentum * exp(-k_over_B) + glac%geothermal_heat_flux = geothermal_heat_flux_constant end subroutine glacier_data_init_0d diff --git a/src/land_lad2/glacier/glacier.F90 b/src/land_lad2/glacier/glacier.F90 index b72f03bab4..611cc9e255 100644 --- a/src/land_lad2/glacier/glacier.F90 +++ b/src/land_lad2/glacier/glacier.F90 @@ -52,8 +52,8 @@ module glacier_mod ! ==== module constants ====================================================== character(len=*), parameter :: & module_name = 'glacier',& - version = '$Id: glacier.F90,v 19.0 2012/01/06 20:40:49 fms Exp $',& - tagname = '$Name: siena_201207 $' + version = '$Id: glacier.F90,v 20.0 2013/12/13 23:29:35 fms Exp $',& + tagname = '$Name: tikal $' ! ==== module variables ====================================================== @@ -364,7 +364,8 @@ subroutine glac_step_1 ( glac, & bbb = 1.0 - aaa(num_l) denom = bbb - dt_e = aaa(num_l)*(glac%prog(num_l)%T - glac%prog(num_l-1)%T) + dt_e = aaa(num_l)*(glac%prog(num_l)%T - glac%prog(num_l-1)%T) & + + glac%geothermal_heat_flux * delta_time / heat_capacity(num_l) glac%e(num_l-1) = -aaa(num_l)/denom glac%f(num_l-1) = dt_e/denom do l = num_l-1, 2, -1 @@ -466,7 +467,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & write(*,*) 'subs_M_imp ', subs_M_imp write(*,*) 'theta_s ', glac%pars%w_sat do l = 1, num_l - write(*,'(i2.2,99(a,g))')l,& + write(*,'(i2.2,99(a,g23.16))')l,& ' T =', glac%prog(l)%T,& ' Th=', (glac%prog(l)%ws+glac%prog(l)%wl)/(dens_h2o*dz(l)),& ' wl=', glac%prog(l)%wl,& @@ -502,7 +503,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & write(*,*) 'fevap=',glac_fevap write(*,*) 'subs_M_imp=',subs_M_imp do l = 1, num_l - write(*,'(i2.2,x,a,g)') l, 'T', glac%prog(l)%T + write(*,'(i2.2,x,a,g23.16)') l, 'T', glac%prog(l)%T enddo endif @@ -527,7 +528,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** glac_step_2 checkpoint 3 ***** ' do l = 1, num_l - write(*,'(i2.2,99(a,g))') l,& + write(*,'(i2.2,99(a,g23.16))') l,& ' T =', glac%prog(l)%T,& ' wl=', glac%prog(l)%wl,& ' ws=', glac%prog(l)%ws @@ -546,7 +547,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** glac_step_2 checkpoint 3.1 ***** ' do l = 1, num_l - write(*,'(i2.2,99(x,a,g))') l, 'vlc', vlc(l),& + write(*,'(i2.2,99(x,a,g23.16))') l, 'vlc', vlc(l),& 'K ', hyd_cond(l) enddo @@ -584,11 +585,11 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** glac_step_2 checkpoint 3.1 ***** ' do l = 1, num_l - write(*,'(i2.2,x,a,99g)') l, 'DThDP,hyd_cond,psi,DKDP', & + write(*,'(i2.2,x,a,99g23.16)') l, 'DThDP,hyd_cond,psi,DKDP', & DThDP(l), hyd_cond(l), psi(l), DKDP(l) enddo do l = 1, num_l-1 - write(*,'(i2.2,x,a,99g)') l, 'K,DKDPm,DKDPp,grad,del_z', & + write(*,'(i2.2,x,a,99g23.16)') l, 'K,DKDPm,DKDPp,grad,del_z', & K(l), DKDPm(l), DKDPp(l), grad(l) enddo endif @@ -602,7 +603,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & fff(l-1) = ddd/bbb if(is_watch_point()) then - write(*,'(a,i,99g)') 'l,a,b, ,d', l,aaa, bbb,ddd + write(*,'(a,i4,99g23.16)') 'l,a,b, ,d', l,aaa, bbb,ddd endif @@ -617,7 +618,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & eee(l-1) = -aaa/(bbb+ccc*eee(l)) fff(l-1) = (ddd-ccc*fff(l))/(bbb+ccc*eee(l)) if(is_watch_point()) then - write(*,'(a,i,99g)') 'l,a,b,c,d', l,aaa, bbb,ccc,ddd + write(*,'(a,i4,99g23.16)') 'l,a,b,c,d', l,aaa, bbb,ccc,ddd endif enddo @@ -639,12 +640,12 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & lrunf_ie = lprec_eff - flow(l)/delta_time if(is_watch_point()) then - write(*,'(a,i,99g)') 'l, b,c,d', l, bbb,ccc,ddd + write(*,'(a,i4,99g23.16)') 'l, b,c,d', l, bbb,ccc,ddd write(*,*) ' ***** glac_step_2 checkpoint 3.2 ***** ' write(*,*) 'ie,sn,bf:', lrunf_ie,lrunf_sn,lrunf_bf do l = 1, num_l-1 - write(*,'(a,i,99g)') 'l,eee(l),fff(l)', l,eee(l), fff(l) + write(*,'(a,i4,99g23.16)') 'l,eee(l),fff(l)', l,eee(l), fff(l) enddo write(*,*) 'DThDP(1)', DThDP(1) write(*,*) 'ddd(1)', ddd @@ -677,7 +678,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & write(*,*) 'psi_sat',glac%pars%psi_sat_ref write(*,*) 'Dpsi_max',Dpsi_max do l = 1, num_l - write(*,'(i2.2,99(a,g))')l,& + write(*,'(i2.2,99(a,g23.16))')l,& ' Th=', (glac%prog(l)%ws+glac%prog(l)%wl)/(dens_h2o*dz(l)),& ' wl=', glac%prog(l)%wl,& ' ws=', glac%prog(l)%ws,& @@ -753,7 +754,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & write(*,*) 'hcap', hcap write(*,*) 'cap_flow', cap_flow do l = 1, num_l - write(*,'(i2.2,99(a,g))')l, ' T', glac%prog(l)%T, ' flow ',flow(l) + write(*,'(i2.2,99(a,g23.16))')l, ' T', glac%prog(l)%T, ' flow ',flow(l) enddo write(*,*) 'delta_time,tau_gw,c0,c1,c2,x', delta_time,tau_gw,c0,& c1,c2,x @@ -781,7 +782,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & write(*,*) 'hcap', hcap write(*,*) 'cap_flow', cap_flow do l = 1, num_l - write(*,'(i2.2,99(a,g))')l, ' T', glac%prog(l)%T + write(*,'(i2.2,99(a,g23.16))')l, ' T', glac%prog(l)%T enddo endif do l = 1, num_l @@ -798,7 +799,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & endif if(is_watch_point()) then - write(*,'(a,i,99g)') 'l,T,wl(1),ws(1),melt:', l,glac%prog(l)%T, glac%prog(l)%wl, & + write(*,'(a,i4,99g23.16)') 'l,T,wl(1),ws(1),melt:', l,glac%prog(l)%T, glac%prog(l)%wl, & glac%prog(l)%ws, melt endif @@ -808,7 +809,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & + (hcap*(glac%prog(l)%T-tfreeze) - hlf*melt) & / ( hcap + (clw-csw)*melt ) if(is_watch_point()) then - write(*,'(a,i,99g)') 'l,T,wl(1),ws(1):', l,glac%prog(l)%T, glac%prog(l)%wl, & + write(*,'(a,i4,99g23.16)') 'l,T,wl(1),ws(1):', l,glac%prog(l)%T, glac%prog(l)%wl, & glac%prog(l)%ws endif @@ -819,7 +820,7 @@ subroutine glac_step_2 ( glac, diag, glac_subl, snow_lprec, snow_hlprec, & write(*,*) 'i,j,k,melt:',& glac_melt*delta_time do l = 1, num_l - write(*,'(i2.2,99(a,g))')l, & + write(*,'(i2.2,99(a,g23.16))')l, & ' T =', glac%prog(l)%T, & ' Th=', (glac%prog(l)%ws+glac%prog(l)%wl)/(dens_h2o*dz(l)),& ' wl=', glac%prog(l)%wl,& @@ -917,45 +918,65 @@ end function glac_tile_exists subroutine glac_temp_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%glac)) ptr=>tile%glac%prog%T + if(associated(tile%glac)) then + n = size(tile%glac%prog) + ptr(1:n) => tile%glac%prog(1:n)%T + endif endif end subroutine glac_temp_ptr subroutine glac_wl_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%glac)) ptr=>tile%glac%prog%wl + if(associated(tile%glac)) then + n = size(tile%glac%prog) + ptr(1:n) => tile%glac%prog(1:n)%wl + endif endif end subroutine glac_wl_ptr subroutine glac_ws_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%glac)) ptr=>tile%glac%prog%ws + if(associated(tile%glac)) then + n = size(tile%glac%prog) + ptr(1:n) => tile%glac%prog(1:n)%ws + endif endif end subroutine glac_ws_ptr subroutine glac_gw_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%glac)) ptr=>tile%glac%prog%groundwater + if(associated(tile%glac)) then + n = size(tile%glac%prog) + ptr(1:n) => tile%glac%prog(1:n)%groundwater + endif endif end subroutine glac_gw_ptr subroutine glac_gwT_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%glac)) ptr=>tile%glac%prog%groundwater_T + if(associated(tile%glac)) then + n = size(tile%glac%prog) + ptr(1:n) => tile%glac%prog(1:n)%groundwater_T + endif endif end subroutine glac_gwT_ptr diff --git a/src/land_lad2/lake/lake.F90 b/src/land_lad2/lake/lake.F90 index 3b12f74b24..4f632e4c33 100644 --- a/src/land_lad2/lake/lake.F90 +++ b/src/land_lad2/lake/lake.F90 @@ -9,8 +9,7 @@ module lake_mod use fms_mod, only: open_namelist_file #endif -use fms_mod, only : error_mesg, file_exist, & - read_data, check_nml_error, & +use fms_mod, only : error_mesg, file_exist, read_data, check_nml_error, & stdlog, write_version_number, close_file, mpp_pe, mpp_root_pe, FATAL, NOTE use time_manager_mod, only: time_type, increment_time, time_type_to_real use diag_manager_mod, only: diag_axis_init, register_diag_field, & @@ -25,12 +24,13 @@ module lake_mod lake_tile_type, lake_pars_type, lake_prog_type, read_lake_data_namelist, & lake_data_radiation, lake_data_diffusion, & lake_data_thermodynamics, & - max_lev, cpw,clw,csw, lake_width_inside_lake, large_lake_sill_width + max_lev, cpw,clw,csw, lake_width_inside_lake, large_lake_sill_width, & + lake_specific_width, n_outlet, outlet_face, outlet_i, outlet_j, outlet_width use land_tile_mod, only : land_tile_type, land_tile_enum_type, & first_elmt, tail_elmt, next_elmt, current_tile, operator(/=) use land_tile_diag_mod, only : register_tiled_static_field, & register_tiled_diag_field, send_tile_data, diag_buff_type, & - send_tile_data_r0d_fptr + send_tile_data_r0d_fptr, add_tiled_static_field_alias use land_data_mod, only : land_state_type, lnd use land_tile_io_mod, only : print_netcdf_error, create_tile_out_file, & read_tile_data_r1d_fptr, write_tile_data_r1d_fptr, sync_nc_files, & @@ -61,8 +61,8 @@ module lake_mod ! ==== module constants ====================================================== character(len=*), parameter, private :: & module_name = 'lake',& - version = '$Id: lake.F90,v 19.0 2012/01/06 20:40:51 fms Exp $',& - tagname = '$Name: siena_201207 $' + version = '$Id: lake.F90,v 20.0 2013/12/13 23:29:37 fms Exp $',& + tagname = '$Name: tikal $' ! ==== module variables ====================================================== @@ -75,16 +75,26 @@ module lake_mod logical :: large_dyn_small_stat = .true. logical :: relayer_in_step_one = .false. logical :: float_ice_to_top = .false. +logical :: wind_penetrates_ice = .false. real :: min_rat = 0.4 logical :: do_stratify = .true. character(len=16):: albedo_to_use = '' ! or 'brdf-params' real :: K_z_large = 1. +real :: K_z_background = 0. +real :: K_z_min = 0. +real :: K_z_factor = 1. +real :: c_drag = 1.2e-3 +real :: lake_depth_max = 1.e10 +real :: lake_depth_min = 1.99 +real :: max_plain_slope = -1.e10 namelist /lake_nml/ init_temp, init_w, & init_groundwater, use_rh_feedback, cpw, clw, csw, & make_all_lakes_wide, large_dyn_small_stat, & relayer_in_step_one, float_ice_to_top, & - min_rat, do_stratify, albedo_to_use, K_z_large + min_rat, do_stratify, albedo_to_use, K_z_large, & + K_z_background, K_z_min, K_z_factor, & + lake_depth_max, lake_depth_min, max_plain_slope !---- end of namelist -------------------------------------------------------- real :: K_z_molec = 1.4e-7 real :: tc_molec = 0.59052 ! dens_h2o*clw*K_z_molec @@ -96,14 +106,14 @@ module lake_mod real :: delta_time integer :: num_l ! # of water layers -real :: zfull (max_lev) ! diag axis, dimensionless layer number -real :: zhalf (max_lev+1) +real, allocatable:: zfull (:) ! diag axis, dimensionless layer number +real, allocatable:: zhalf (:) real :: max_rat ! ---- diagnostic field IDs integer :: id_lwc, id_swc, id_temp, id_ie, id_sn, id_bf, id_hie, id_hsn, id_hbf -integer :: id_evap, id_dz, id_wl, id_ws, id_K_z, id_silld, id_sillw -integer :: id_silld_old, id_sillw_old +integer :: id_evap, id_dz, id_wl, id_ws, id_K_z, id_silld, id_sillw, id_backw +integer :: id_back1 ! ==== end of module variables =============================================== ! ==== NetCDF declarations =================================================== @@ -144,6 +154,7 @@ subroutine read_lake_namelist() endif ! ---- set up vertical discretization + allocate (zhalf(num_l+1), zfull(num_l)) zhalf(1) = 0 do l = 1, num_l; zhalf(l+1) = zhalf(l) + 1. @@ -178,6 +189,7 @@ subroutine lake_init ( id_lon, id_lat ) character(len=256) :: restart_file_name logical :: restart_exists real, allocatable :: buffer(:,:),bufferc(:,:),buffert(:,:) + integer i module_is_initialized = .TRUE. time = lnd%time @@ -196,6 +208,8 @@ subroutine lake_init ( id_lon, id_lat ) call put_to_tiles_r0d_fptr(buffer, lnd%tile_map, lake_whole_area_ptr) call read_data('INPUT/river_data.nc', 'lake_depth_sill', buffer(:,:), lnd%domain) +buffer = min(buffer, lake_depth_max) +buffer = max(buffer, lake_depth_min) call put_to_tiles_r0d_fptr(buffer, lnd%tile_map, lake_depth_sill_ptr) ! lake_tau is just used here as a flag for 'large lakes' @@ -204,8 +218,26 @@ subroutine lake_init ( id_lon, id_lat ) buffer = -1. !where (bufferc.gt.0.5) buffer = lake_width_inside_lake where (bufferc.lt.0.5 .and. buffert.gt.1.) buffer = large_lake_sill_width +if (lake_specific_width) then + do i = 1, n_outlet + if(lnd%face.eq.outlet_face(i).and.lnd%is.le.outlet_i(i).and.lnd%ie.ge.outlet_i(i) & + .and.lnd%js.le.outlet_j(i).and.lnd%je.ge.outlet_j(i)) & + buffer(outlet_i(i),outlet_j(i)) = outlet_width(i) + enddo +endif call put_to_tiles_r0d_fptr(buffer, lnd%tile_map, lake_width_sill_ptr) +buffer = 1.e8 +if (max_plain_slope.gt.0.) & + call read_data('INPUT/river_data.nc', 'max_slope_to_next', buffer(:,:), lnd%domain) +call read_data('INPUT/river_data.nc', 'travel', buffert(:,:), lnd%domain) +bufferc = 0. +where (buffer.lt.max_plain_slope .and. buffert.gt.1.5) bufferc = 1. +call put_to_tiles_r0d_fptr(bufferc, lnd%tile_map, lake_backwater_ptr) +bufferc = 0 +where (buffer.lt.max_plain_slope .and. buffert.lt.1.5) bufferc = 1. +call put_to_tiles_r0d_fptr(bufferc, lnd%tile_map, lake_backwater_1_ptr) + ELSE call read_data('INPUT/river_data.nc', 'whole_lake_area', bufferc(:,:), lnd%domain) @@ -273,13 +305,15 @@ subroutine lake_init ( id_lon, id_lat ) ! ---- static diagnostic section call send_tile_data_r0d_fptr(id_sillw, lnd%tile_map, lake_width_sill_ptr) call send_tile_data_r0d_fptr(id_silld, lnd%tile_map, lake_depth_sill_ptr) - + call send_tile_data_r0d_fptr(id_backw, lnd%tile_map, lake_backwater_ptr) + call send_tile_data_r0d_fptr(id_back1, lnd%tile_map, lake_backwater_1_ptr) end subroutine lake_init ! ============================================================================ subroutine lake_end () + deallocate (zfull, zhalf) module_is_initialized =.FALSE. end subroutine lake_end @@ -391,7 +425,7 @@ subroutine lake_step_1 ( u_star_a, p_surf, latitude, lake, & write(*,*) 'G0 ', lake_G0 write(*,*) 'DGDT ', lake_DGDT do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' dz=', lake%prog(l)%dz,& ' T =', lake%prog(l)%T,& ' wl=', lake%prog(l)%wl,& @@ -415,9 +449,10 @@ subroutine lake_step_1 ( u_star_a, p_surf, latitude, lake, & ! Ignore air humidity in converting atmospheric friction velocity to lake value rho_a = p_surf/(rdgas*lake_T) ! No momentum transfer through ice cover - if (lake%prog(1)%ws.le.0.) then + if (lake%prog(1)%ws.le.0. .or. wind_penetrates_ice) then u_star = u_star_a*sqrt(rho_a/dens_h2o) k_star = 2.79e-5*sqrt(sin(abs(latitude)))*u_star**(-1.84) + k_star = k_star*(c_drag/1.2e-3)**1.84 else u_star = 0. k_star = 1. @@ -467,6 +502,9 @@ subroutine lake_step_1 ( u_star_a, p_surf, latitude, lake, & else ! arbitrary constant for unstable mixing lake%prog(l)%K_z = K_z_large endif + if (lake%pars%depth_sill.gt.2.01) & + lake%prog(l)%K_z = K_z_factor & + * max(lake%prog(l)%K_z + K_z_background, K_z_min) aaa(l+1) = - lake%prog(l)%K_z * delta_time / (dz_alt(l+1)*dz_mid) ccc(l) = - lake%prog(l)%K_z * delta_time / (dz_alt(l )*dz_mid) else @@ -488,7 +526,8 @@ subroutine lake_step_1 ( u_star_a, p_surf, latitude, lake, & bbb = 1.0 - aaa(num_l) denom = bbb - dt_e = aaa(num_l)*(lake%prog(num_l)%T - lake%prog(num_l-1)%T) + dt_e = aaa(num_l)*(lake%prog(num_l)%T - lake%prog(num_l-1)%T) & + + lake%geothermal_heat_flux * delta_time / heat_capacity(num_l) lake%e(num_l-1) = -aaa(num_l)/denom lake%f(num_l-1) = dt_e/denom do l = num_l-1, 2, -1 @@ -523,7 +562,7 @@ subroutine lake_step_1 ( u_star_a, p_surf, latitude, lake, & write(*,*) 'G0 ', lake_G0 write(*,*) 'DGDT ', lake_DGDT do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' dz=', lake%prog(l)%dz,& ' T =', lake%prog(l)%T,& ' wl=', lake%prog(l)%wl,& @@ -580,7 +619,7 @@ subroutine lake_step_2 ( lake, diag, lake_subl, snow_lprec, snow_hlprec, & write(*,*) 'subs_M_imp ', subs_M_imp write(*,*) 'theta_s ', lake%pars%w_sat do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' dz=', lake%prog(l)%dz,& ' T =', lake%prog(l)%T,& ' Th=', (lake%prog(l)%ws & @@ -653,7 +692,7 @@ subroutine lake_step_2 ( lake, diag, lake_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** lake_step_2 checkpoint 3.3 ***** ' do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' wl=', lake%prog(l)%wl,& 'flow=', flow(l) enddo @@ -694,7 +733,7 @@ subroutine lake_step_2 ( lake, diag, lake_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** lake_step_2 checkpoint 5 ***** ' do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' dz=', lake%prog(l)%dz,& ' T =', lake%prog(l)%T,& ' Th=', (lake%prog(l)%ws +lake%prog(l)%wl)/(dens_h2o*lake%prog(l)%dz),& @@ -709,7 +748,7 @@ subroutine lake_step_2 ( lake, diag, lake_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** lake_step_2 checkpoint 6 ***** ' do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' dz=', lake%prog(l)%dz,& ' T =', lake%prog(l)%T,& ' Th=', (lake%prog(l)%ws +lake%prog(l)%wl)/(dens_h2o*lake%prog(l)%dz),& @@ -741,7 +780,7 @@ subroutine lake_step_2 ( lake, diag, lake_subl, snow_lprec, snow_hlprec, & if(is_watch_point()) then write(*,*) ' ***** lake_step_2 checkpoint 7 ***** ' do l = 1, num_l - write(*,*) ' level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' dz=', lake%prog(l)%dz,& ' T =', lake%prog(l)%T,& ' Th=', (lake%prog(l)%ws +lake%prog(l)%wl)/(dens_h2o*lake%prog(l)%dz),& @@ -772,8 +811,6 @@ subroutine lake_step_2 ( lake, diag, lake_subl, snow_lprec, snow_hlprec, & call send_tile_data (id_swc, lake%prog(1:num_l)%ws/lake%prog(1:num_l)%dz, diag ) call send_tile_data (id_K_z, lake%prog(1:num_l)%K_z, diag ) call send_tile_data (id_evap, lake_levap+lake_fevap, diag ) - call send_tile_data (id_silld_old, lake%pars%depth_sill,diag) - call send_tile_data (id_sillw_old, lake%pars%width_sill,diag) end subroutine lake_step_2 @@ -923,7 +960,10 @@ subroutine lake_diag_init ( id_lon, id_lat ) axes(1:2), 'lake width at outflow', 'm', missing_value=-100.0 ) id_silld = register_tiled_static_field ( module_name, 'lake_depth', & axes(1:2), 'lake depth below sill', 'm', missing_value=-100.0 ) - + id_backw = register_tiled_static_field ( module_name, 'backwater', & + axes(1:2), 'backwater flag', '-', missing_value=-100.0 ) + id_back1 = register_tiled_static_field ( module_name, 'backwater_1', & + axes(1:2), 'backwater1 flag', '-', missing_value=-100.0 ) ! define dynamic diagnostic fields id_dz = register_tiled_diag_field ( module_name, 'lake_dz', axes, & Time, 'nominal layer thickness', 'm', missing_value=-100.0 ) @@ -942,11 +982,11 @@ subroutine lake_diag_init ( id_lon, id_lat ) id_evap = register_tiled_diag_field ( module_name, 'lake_evap', axes(1:2), & Time, 'lake evap', 'kg/(m2 s)', missing_value=-100.0 ) - id_silld_old = register_tiled_diag_field (module_name, 'sill_depth', & - axes(1:2), Time, 'obsolete, pls use lake_depth (static)','m', & + call add_tiled_static_field_alias (id_silld, module_name, 'sill_depth', & + axes(1:2), 'obsolete, pls use lake_depth (static)','m', & missing_value=-100.0 ) - id_sillw_old = register_tiled_diag_field (module_name, 'sill_width', & - axes(1:2), Time, 'obsolete, pls use lake_width (static)','m', & + call add_tiled_static_field_alias (id_sillw, module_name, 'sill_width', & + axes(1:2), 'obsolete, pls use lake_width (static)','m', & missing_value=-100.0 ) end subroutine lake_diag_init @@ -967,54 +1007,78 @@ end function lake_tile_exists subroutine lake_dz_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%lake)) ptr=>tile%lake%prog%dz + if(associated(tile%lake)) then + n = size(tile%lake%prog) + ptr(1:n) => tile%lake%prog(1:n)%dz + endif endif end subroutine lake_dz_ptr subroutine lake_temp_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%lake)) ptr=>tile%lake%prog%T + if(associated(tile%lake)) then + n = size(tile%lake%prog) + ptr(1:n) => tile%lake%prog(1:n)%T + endif endif end subroutine lake_temp_ptr subroutine lake_wl_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%lake)) ptr=>tile%lake%prog%wl + if(associated(tile%lake)) then + n = size(tile%lake%prog) + ptr(1:n) => tile%lake%prog(1:n)%wl + endif endif end subroutine lake_wl_ptr subroutine lake_ws_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%lake)) ptr=>tile%lake%prog%ws + if(associated(tile%lake)) then + n = size(tile%lake%prog) + ptr(1:n) => tile%lake%prog(1:n)%ws + endif endif end subroutine lake_ws_ptr subroutine lake_gw_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%lake)) ptr=>tile%lake%prog%groundwater + if(associated(tile%lake)) then + n = size(tile%lake%prog) + ptr(1:n) => tile%lake%prog(1:n)%groundwater + endif endif end subroutine lake_gw_ptr subroutine lake_gwT_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%lake)) ptr=>tile%lake%prog%groundwater_T + if(associated(tile%lake)) then + n = size(tile%lake%prog) + ptr(1:n) => tile%lake%prog(1:n)%groundwater_T + endif endif end subroutine lake_gwT_ptr @@ -1054,6 +1118,24 @@ subroutine lake_width_sill_ptr(tile, ptr) endif end subroutine lake_width_sill_ptr +subroutine lake_backwater_ptr(tile, ptr) + type(land_tile_type), pointer :: tile + real , pointer :: ptr + ptr=>NULL() + if(associated(tile)) then + if(associated(tile%lake)) ptr=>tile%lake%pars%backwater + endif +end subroutine lake_backwater_ptr + +subroutine lake_backwater_1_ptr(tile, ptr) + type(land_tile_type), pointer :: tile + real , pointer :: ptr + ptr=>NULL() + if(associated(tile)) then + if(associated(tile%lake)) ptr=>tile%lake%pars%backwater_1 + endif +end subroutine lake_backwater_1_ptr + end module lake_mod diff --git a/src/land_lad2/lake/lake_tile.F90 b/src/land_lad2/lake/lake_tile.F90 index 813cc77c8e..3604109954 100644 --- a/src/land_lad2/lake/lake_tile.F90 +++ b/src/land_lad2/lake/lake_tile.F90 @@ -57,8 +57,8 @@ module lake_tile_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & - version = '$Id: lake_tile.F90,v 19.0 2012/01/06 20:40:53 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: lake_tile.F90,v 20.0 2013/12/13 23:29:39 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'lake_tile_mod' integer, parameter :: max_lev = 80 @@ -97,10 +97,13 @@ module lake_tile_mod real emis_dry real emis_sat real z0_momentum + real z0_momentum_ice real depth_sill real width_sill real whole_area real connected_to_next + real backwater + real backwater_1 real tau_groundwater real rsa_exp ! riparian source-area exponent end type lake_pars_type @@ -123,6 +126,8 @@ module lake_tile_mod real, pointer :: w_wilt(:) real :: Eg_part_ref real :: z0_scalar + real :: z0_scalar_ice + real :: geothermal_heat_flux real, pointer :: e(:),f(:) real, pointer :: heat_capacity_dry(:) end type lake_tile_type @@ -138,21 +143,23 @@ module lake_tile_mod real :: large_lake_sill_width = 200. real :: min_lake_frac = 0. real :: max_lake_rh = 1. +real :: lake_rh_exp = 1. +real :: dry_lake_depth_frac = 0. real :: k_over_B = 0.25 ! reset to 0 for MCM +real :: k_over_B_ice = 0.25 real :: rate_fc = 0.1/86400 ! 0.1 mm/d drainage rate at FC real :: sfc_heat_factor = 1 -integer, public :: num_l = 18 ! number of lake levels -real :: dz(max_lev) = (/ & - 0.02, 0.04, 0.04, 0.05, 0.05, 0.1, 0.1, 0.2, 0.2, & - 0.2, 0.4, 0.4, 0.4, 0.4, 0.4, 1., 1., 1., & - 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0., & - 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0., & - 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0., & - 0.,0.,0.,0.,0. /) - ! thickness (m) of model layers, - ! from top down +real :: geothermal_heat_flux_constant = 0.0 ! true continental average is ~0.065 W/m2 +integer, public :: num_l = 18 ! number of lake levels +integer, public :: n_outlet = 0 logical :: use_lm2_awc = .false. - integer :: n_map_1st_lake_type = 10 +logical, public :: lake_specific_width = .false. +integer :: n_map_1st_lake_type = 10 + +integer, public :: outlet_face(100) +integer, public :: outlet_i(100) +integer, public :: outlet_j(100) +real, public :: outlet_width(100) ! from analysis of modis data (ignoring temperature dependence): real :: f_iso_ice(NBANDS) = (/ 0.056, 0.131 /) @@ -196,6 +203,7 @@ module lake_tile_mod dat_emis_dry =(/ 0.950 /),& dat_emis_sat =(/ 0.980 /),& dat_z0_momentum =(/ 1.4e-4 /),& + dat_z0_momentum_ice =(/ 1.4e-4 /),& dat_tf_depr =(/ 0.00 /) real, dimension(n_dim_lake_types, NBANDS) :: & dat_refl_dry_dif, dat_refl_dry_dir, & @@ -213,11 +221,13 @@ module lake_tile_mod namelist /lake_data_nml/ lake_width_inside_lake, & large_lake_sill_width, & - min_lake_frac, round_frac_down, max_lake_rh, & + lake_specific_width, n_outlet, outlet_face, outlet_i, outlet_j, outlet_width, & + min_lake_frac, round_frac_down, max_lake_rh, lake_rh_exp, & + dry_lake_depth_frac, & lake_to_use,input_cover_types, tile_names, & - k_over_B, & - rate_fc, sfc_heat_factor, & - num_l, dz, & + k_over_B, k_over_B_ice, & + rate_fc, sfc_heat_factor, geothermal_heat_flux_constant, & + num_l, & use_lm2_awc, n_map_1st_lake_type, & use_single_lake, use_mcm_albedo, & use_single_geo, lake_index_constant, & @@ -229,7 +239,7 @@ module lake_tile_mod dat_refl_dry_dir, dat_refl_sat_dir, & dat_refl_dry_dif, dat_refl_sat_dif, & dat_emis_dry, dat_emis_sat, & - dat_z0_momentum, dat_tf_depr, & + dat_z0_momentum, dat_z0_momentum_ice, dat_tf_depr, & f_iso_ice, f_vol_ice, f_geo_ice, f_iso_liq, f_vol_liq, f_geo_liq @@ -359,6 +369,7 @@ subroutine init_lake_data_0d(lake) lake%pars%emis_dry = dat_emis_dry (k) lake%pars%emis_sat = dat_emis_sat (k) lake%pars%z0_momentum = dat_z0_momentum (k) + lake%pars%z0_momentum_ice = dat_z0_momentum_ice (k) lake%pars%tau_groundwater = 86400.*30. lake%pars%rsa_exp = rsa_exp_global @@ -383,6 +394,8 @@ subroutine init_lake_data_0d(lake) *(2*pi/(3*lake%pars%chb**2*(1+3/lake%pars%chb)*(1+4/lake%pars%chb)))/2 lake%z0_scalar = lake%pars%z0_momentum * exp(-k_over_B) + lake%z0_scalar_ice = lake%pars%z0_momentum_ice * exp(-k_over_B_ice) + lake%geothermal_heat_flux = geothermal_heat_flux_constant end subroutine @@ -455,9 +468,11 @@ subroutine merge_lake_tiles(t1,w1,t2,w2) C2 = sfc_heat_factor*t2%pars%heat_capacity_ref ! calculate heat content at this level for both source tiles HEAT1 = & - (C1*dz(i)+clw*t1%prog(i)%wl+csw*t1%prog(i)%ws) * (t1%prog(i)%T-tfreeze) + 0. +! (C1*dz(i)+clw*t1%prog(i)%wl+csw*t1%prog(i)%ws) * (t1%prog(i)%T-tfreeze) HEAT2 = & - (C2*dz(i)+clw*t2%prog(i)%wl+csw*t2%prog(i)%ws) * (t2%prog(i)%T-tfreeze) + 0. +! (C2*dz(i)+clw*t2%prog(i)%wl+csw*t2%prog(i)%ws) * (t2%prog(i)%T-tfreeze) ! calculate (and assign) combined water mass t2%prog(i)%wl = t1%prog(i)%wl*x1 + t2%prog(i)%wl*x2 t2%prog(i)%ws = t1%prog(i)%ws*x1 + t2%prog(i)%ws*x2 @@ -465,8 +480,9 @@ subroutine merge_lake_tiles(t1,w1,t2,w2) ! ... ! calculate combined temperature, based on total heat content and combined ! heat capacity - t2%prog(i)%T = (HEAT1*x1+HEAT2*x2) / & - (C2*dz(i)+clw*t2%prog(i)%wl+csw*t2%prog(i)%ws) + tfreeze +! t2%prog(i)%T = (HEAT1*x1+HEAT2*x2) / & +! (C2*dz(i)+clw*t2%prog(i)%wl+csw*t2%prog(i)%ws) + tfreeze + t2%prog(i)%T = 0. ! calculate combined groundwater content gw = t1%prog(i)%groundwater*x1 + t2%prog(i)%groundwater*x2 @@ -554,8 +570,13 @@ subroutine lake_data_diffusion ( lake,lake_z0s, lake_z0m ) real, intent(out) :: lake_z0s, lake_z0m ! ---- surface roughness - lake_z0s = lake%z0_scalar - lake_z0m = lake%pars%z0_momentum + if (lake%prog(1)%ws.le.0.) then + lake_z0s = lake%z0_scalar + lake_z0m = lake%pars%z0_momentum + else + lake_z0s = lake%z0_scalar_ice + lake_z0m = lake%pars%z0_momentum_ice + endif end subroutine ! ============================================================================ @@ -570,10 +591,17 @@ subroutine lake_data_thermodynamics ( lake_pars, lake_depth, & ! ---- local vars integer l + real lake_depth_frac, lake_rh_base ! ---------------------------------------------------------------------------- - lake_rh = min(max_lake_rh, max(lake_depth/lake_pars%depth_sill,0.)) + lake_depth_frac = (lake_depth/lake_pars%depth_sill) + lake_rh_base = (lake_depth_frac-dry_lake_depth_frac)/(1.-dry_lake_depth_frac) + if (lake_rh_base.gt.0.) then + lake_rh = min(max_lake_rh, lake_rh_base**lake_rh_exp ) + else + lake_rh = 0. + endif do l = 1, num_l heat_capacity_dry(l) = lake_pars%heat_capacity_ref @@ -608,8 +636,8 @@ function lake_tile_heat (lake) result(heat) ; real heat heat = 0 do i = 1, num_l heat = heat + & - (lake%heat_capacity_dry(i)*dz(i) + clw*lake%prog(i)%wl + csw*lake%prog(i)%ws)& - *(lake%prog(i)%T-tfreeze) + & + (lake%heat_capacity_dry(i)*lake%prog(i)%dz + clw*lake%prog(i)%wl & + + csw*lake%prog(i)%ws)*(lake%prog(i)%T-tfreeze) + & clw*lake%prog(i)%groundwater*(lake%prog(i)%groundwater_T-tfreeze) - & hlf*lake%prog(i)%ws enddo diff --git a/src/land_lad2/land_constants.F90 b/src/land_lad2/land_constants.F90 index 3fce102ab7..c5a010ac3e 100644 --- a/src/land_lad2/land_constants.F90 +++ b/src/land_lad2/land_constants.F90 @@ -27,6 +27,6 @@ module land_constants_mod ! ==== module constants ====================================================== character(len=*), parameter :: & version = '$Id: land_constants.F90,v 17.0 2009/07/21 03:02:18 fms Exp $', & - tagname = '$Name: siena_201207 $' + tagname = '$Name: tikal $' end module diff --git a/src/land_lad2/land_data.F90 b/src/land_lad2/land_data.F90 index c77d3873e9..d86c387f0a 100644 --- a/src/land_lad2/land_data.F90 +++ b/src/land_lad2/land_data.F90 @@ -50,8 +50,8 @@ module land_data_mod ! ---- module constants ------------------------------------------------------ character(len=*), parameter :: & module_name = 'land_data_mod', & - version = '$Id: land_data.F90,v 19.0.6.1 2012/05/15 19:59:57 z1l Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: land_data.F90,v 20.0 2013/12/13 23:29:24 fms Exp $', & + tagname = '$Name: tikal $' ! init_value is used to fill most of the allocated boundary condition arrays. ! It is supposed to be double-precision signaling NaN, to trigger a trap when @@ -168,7 +168,7 @@ module land_data_mod integer, allocatable :: io_pelist(:) ! list of processors in our io_domain ! if io_domain was not defined, then there is just one element in this ! array, and it's equal to current PE - integer :: io_id ! suffix in the distributed files. + integer :: io_id ! suffix in the distributed files. logical :: append_io_id ! if FALSE, io_id is not appended to the file names ! (for the case io_layout = 1,1) end type land_state_type @@ -556,37 +556,14 @@ function max_n_tiles() result(n) end function -!####################################################################### -! -use mpp_mod, only : mpp_pe, mpp_chksum +use mpp_mod, only : mpp_pe, mpp_chksum, mpp_root_pe use mpp_mod, only : input_nml_file use mpp_domains_mod, only : CYCLIC_GLOBAL_DOMAIN, mpp_get_compute_domain @@ -77,8 +77,8 @@ module land_model_mod ! This is the null version ! ==== end of public interfaces ============================================== character(len=*), parameter :: & - version = '$Id: land_model.F90,v 18.0.2.1.2.1.2.1.2.1.2.2.2.1.2.1 2012/05/31 15:56:39 Niki.Zadeh Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: land_model.F90,v 20.0 2013/12/13 23:31:21 fms Exp $', & + tagname = '$Name: tikal $' type :: atmos_land_boundary_type real, dimension(:,:,:), pointer :: & ! (lon, lat, tile) @@ -233,7 +233,7 @@ subroutine land_model_init (cplr2land, land2cplr, time_init, time, dt_fast, dt_s land2cplr%domain = domain npes_per_tile = mpp_npes()/ntiles - face = mpp_pe()/npes_per_tile + 1 + face = (mpp_pe()-mpp_root_pe())/npes_per_tile + 1 allocate(garea(nlon,nlat), gcellarea(nlon,nlat), gfrac(nlon,nlat)) call get_grid_cell_area ('LND',face,gcellarea) call get_grid_comp_area ('LND',face,garea) diff --git a/src/land_param/climap_albedo.F90 b/src/land_param/climap_albedo.F90 index d1c4ad884d..00d62bff15 100644 --- a/src/land_param/climap_albedo.F90 +++ b/src/land_param/climap_albedo.F90 @@ -28,7 +28,7 @@ module climap_albedo_mod !--------------------- version number ---------------------------------- character(len=128) :: version = '$Id: climap_albedo.F90,v 15.0 2007/08/14 04:00:26 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' logical :: do_init = .true. !======================================================================= diff --git a/src/mom5/drivers/mom_oasis3_interface.html b/src/mom5/drivers/mom_oasis3_interface.html deleted file mode 100644 index eb02877942..0000000000 --- a/src/mom5/drivers/mom_oasis3_interface.html +++ /dev/null @@ -1,162 +0,0 @@ - - - --! -! - -!####################################################################### -!-! Print checksums of the various fields in the atmos_land_boundary_type. -! - -!-! Routine to print checksums of the various fields in the atmos_land_boundary_type. -! - -! -! call atm_lnd_bnd_type_chksum(id, timestep, albt) -! - -!-! Derived-type variable that contains fields in the atmos_land_boundary_type. -! -! -! -! Label to differentiate where this routine in being called from. -! -! -!-! An integer to indicate which timestep this routine is being called for. -! -! -subroutine atm_lnd_bnd_type_chksum(id, timestep, albt) - character(len=*), intent(in) :: id - integer , intent(in) :: timestep +! =========================================================================== +! Prints checksums of the various fields in the atmos_land_boundary_type. +subroutine atm_lnd_bnd_type_chksum(id, timestep, albt) + character(len=*), intent(in) :: id ! Label to differentiate where this + ! routine is being called from. + integer , intent(in) :: timestep ! An integer to indicate which + ! timestep this routine is being called for. type(atmos_land_boundary_type), intent(in) :: albt integer :: n, outunit @@ -627,42 +604,14 @@ subroutine atm_lnd_bnd_type_chksum(id, timestep, albt) end subroutine atm_lnd_bnd_type_chksum -!-! -! - - end module land_data_mod diff --git a/src/land_lad2/land_model.F90 b/src/land_lad2/land_model.F90 index af0ba211fc..ddc4cd8bad 100644 --- a/src/land_lad2/land_model.F90 +++ b/src/land_lad2/land_model.F90 @@ -16,7 +16,7 @@ module land_model_mod #endif use mpp_mod, only : mpp_max, mpp_sum -use fms_mod, only : write_version_number, error_mesg, FATAL, NOTE, mpp_pe, & +use fms_mod, only : write_version_number, error_mesg, FATAL, WARNING, NOTE, mpp_pe, & mpp_root_pe, file_exist, check_nml_error, close_file, & stdlog, stderr, mpp_clock_id, mpp_clock_begin, mpp_clock_end, string, & stdout, CLOCK_FLAG_DEFAULT, CLOCK_COMPONENT, CLOCK_ROUTINE @@ -36,7 +36,8 @@ module land_model_mod use lake_mod, only : read_lake_namelist, lake_init, lake_end, lake_get_sfc_temp, & lake_radiation, lake_diffusion, lake_step_1, lake_step_2, save_lake_restart use soil_mod, only : read_soil_namelist, soil_init, soil_end, soil_get_sfc_temp, & - soil_radiation, soil_diffusion, soil_step_1, soil_step_2, save_soil_restart + soil_radiation, soil_diffusion, soil_step_1, soil_step_2, soil_step_3, & + save_soil_restart use snow_mod, only : read_snow_namelist, snow_init, snow_end, snow_get_sfc_temp, & snow_radiation, snow_diffusion, snow_get_depth_area, snow_step_1, snow_step_2, & save_snow_restart @@ -63,10 +64,11 @@ module land_model_mod use land_numerics_mod, only : ludcmp, lubksb, nearest, & horiz_remap_type, horiz_remap_new, horiz_remap, horiz_remap_del, & horiz_remap_print +use land_io_mod, only : read_land_io_namelist, input_buf_size use land_tile_mod, only : land_tile_type, land_tile_list_type, & land_tile_enum_type, new_land_tile, insert, nitems, & first_elmt, tail_elmt, next_elmt, current_tile, operator(/=), & - get_elmt_indices, get_tile_tags + get_elmt_indices, get_tile_tags, land_tile_carbon use land_data_mod, only : land_data_type, atmos_land_boundary_type, & land_state_type, land_data_init, land_data_end, lnd, & dealloc_land2cplr, realloc_land2cplr, & @@ -79,6 +81,7 @@ module land_model_mod write_tile_data_i0d_fptr, get_input_restart_name use land_tile_diag_mod, only : tile_diag_init, tile_diag_end, & register_tiled_diag_field, send_tile_data, dump_tile_diag_fields, & + add_tiled_diag_field_alias, & OP_AVERAGE, OP_SUM use land_debug_mod, only : land_debug_init, land_debug_end, set_current_point, & is_watch_point, get_watch_point, check_temp_range, current_face, & @@ -109,8 +112,8 @@ module land_model_mod ! ==== module constants ====================================================== character(len=*), parameter :: & module_name = 'land', & - version = '$Id: land_model.F90,v 19.0 2012/01/06 20:40:09 fms Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: land_model.F90,v 20.0 2013/12/13 23:29:26 fms Exp $', & + tagname = '$Name: tikal $' ! ==== module variables ====================================================== @@ -126,6 +129,7 @@ module land_model_mod real :: clw = 4218. ! specific heat of water (liquid) real :: csw = 2106. ! specific heat of water (ice) real :: min_sum_lake_frac = 1.e-8 +real :: min_frac = 0.0 ! minimum fraction of soil, lake, and glacier that is not discarded on cold start real :: gfrac_tol = 1.e-6 real :: discharge_tol = -1.e20 real :: con_fac_large = 1.e6 @@ -133,6 +137,9 @@ module land_model_mod integer :: num_c = 0 real :: tau_snow_T_adj = -1.0 ! time scale of snow temperature adjustment ! for the snow-free surface (s); negative means no adjustment +logical :: prohibit_negative_canopy_water = .FALSE. ! if true, then in case of negative canopy + ! water the evaporation is fixed and the equations are re-solved. + ! Default retrievs old behavior. character(16) :: nearest_point_search = 'global' ! specifies where to look for ! nearest points for missing data, "global" or "face" logical :: print_remapping = .FALSE. ! if true, full land cover remapping @@ -144,10 +151,10 @@ module land_model_mod use_tfreeze_in_grnd_latent, & use_atmos_T_for_precip_T, & use_atmos_T_for_evap_T, & - cpw, clw, csw, min_sum_lake_frac, & + cpw, clw, csw, min_sum_lake_frac, min_frac, & gfrac_tol, discharge_tol, & con_fac_large, con_fac_small, num_c, & - tau_snow_T_adj, & + tau_snow_T_adj, prohibit_negative_canopy_water, & nearest_point_search, print_remapping, & layout, io_layout ! ---- end of namelist ------------------------------------------------------- @@ -193,7 +200,7 @@ module land_model_mod id_flw, id_flwv, id_flws, id_flwg, & id_sens, id_sensv, id_senss, id_sensg, & ! - id_e_res_1, id_e_res_2, & + id_e_res_1, id_e_res_2, id_cd_m, id_cd_t, & id_cellarea, id_landarea, id_landfrac, id_no_riv, & id_geolon_t, id_geolat_t, & id_frac, id_area, id_ntiles, & @@ -201,7 +208,6 @@ module land_model_mod id_z0m, id_z0s, id_con_g_h, & id_transp, id_wroff, id_sroff, & id_htransp, id_huptake, id_hroff, id_gsnow, id_gequil, & - id_gsnow_old, & id_grnd_flux, & id_soil_water_supply, id_levapg_max, & id_water, id_snow, & @@ -213,7 +219,7 @@ module land_model_mod id_vegn_refl_dir, id_vegn_refl_dif, id_vegn_refl_lw, & id_vegn_tran_dir, id_vegn_tran_dif, id_vegn_tran_lw, & id_vegn_sctr_dir, & - id_subs_refl_dir, id_subs_refl_dif, id_grnd_T + id_subs_refl_dir, id_subs_refl_dif, id_subs_emis, id_grnd_T, id_total_C ! ---- global clock IDs integer :: landClock, landFastClock, landSlowClock @@ -304,6 +310,7 @@ subroutine land_model_init & endif ! [2.2] read sub-model namelists: then need to be read before initialization ! because they can affect the way cover and tiling is initialized on cold start. + call read_land_io_namelist() call read_soil_namelist() call read_vegn_namelist() call read_lake_namelist() @@ -355,8 +362,8 @@ subroutine land_model_init & if ( id_cellarea > 0 ) used = send_data ( id_cellarea, lnd%cellarea, lnd%time ) if ( id_landarea > 0 ) used = send_data ( id_landarea, lnd%area, lnd%time ) if ( id_landfrac > 0 ) used = send_data ( id_landfrac, frac, lnd%time ) - if ( id_geolon_t > 0 ) used = send_data ( id_geolon_t, lnd%lon, lnd%time ) - if ( id_geolat_t > 0 ) used = send_data ( id_geolat_t, lnd%lat, lnd%time ) + if ( id_geolon_t > 0 ) used = send_data ( id_geolon_t, lnd%lon*180.0/PI, lnd%time ) + if ( id_geolat_t > 0 ) used = send_data ( id_geolat_t, lnd%lat*180.0/PI, lnd%time ) ! [7] initialize individual sub-models num_species = num_phys + num_c @@ -494,7 +501,7 @@ subroutine land_model_restart(timestamp) ! [1] count all land tiles and determine the length of tile dimension ! sufficient for the current domain - tile_dim_length = 0 + tile_dim_length = 0 do j = lnd%js, lnd%je do i = lnd%is, lnd%ie k = nitems(lnd%tile_map(i,j)) @@ -504,6 +511,12 @@ subroutine land_model_restart(timestamp) ! [2] calculate the tile dimension length by taking the max across all domains call mpp_max(tile_dim_length) + if (tile_dim_length==0) then + call error_mesg('land_model_restart',& + 'No land points exist (tile_dim_length=0), therefore no land restarts will be saved',& + WARNING) + return + endif ! [3] create tile output file timestamp_='' @@ -552,8 +565,8 @@ subroutine land_cover_cold_start(lnd) glac, soil, lake, vegn ! arrays of fractions for respective sub-models logical, dimension(lnd%ie-lnd%is+1,lnd%je-lnd%js+1) :: & land_mask, valid_data, invalid_data - integer :: i,j,k,face - integer :: i0,j0 + integer :: iwatch,jwatch,kwatch,face + integer :: i,j integer :: ps,pe ! boundaries of PE list for remapping type(horiz_remap_type) :: map @@ -580,21 +593,21 @@ subroutine land_cover_cold_start(lnd) valid_data = land_mask.and.(sum(glac,3)+sum(lake,3)+sum(soil,3)>0) invalid_data = land_mask.and..not.valid_data - call get_watch_point(i,j,k,face) - if (face==lnd%face.and.(lnd%is<=i.and.i<=lnd%ie).and.(lnd%js<=j.and.j<=lnd%je)) then + call get_watch_point(iwatch,jwatch,kwatch,face) + if (face==lnd%face.and.(lnd%is<=iwatch.and.iwatch<=lnd%ie).and.(lnd%js<=jwatch.and.jwatch<=lnd%je)) then write(*,*)'###### land_cover_cold_start: input data #####' - write(*,'(99(a,i4.2,x))')'i=',i,'j=',j,'face=',lnd%face - write(*,'(99(a,g,x))')'lon=',lnd%lon(i,j)*180/PI,'lat=',lnd%lat(i,j)*180/PI + write(*,'(99(a,i4.2,x))')'iwatch=',iwatch,'jwatch=',jwatch,'face=',lnd%face + write(*,'(99(a,g23.16,x))')'lon=',lnd%lon(iwatch,jwatch)*180/PI,'lat=',lnd%lat(iwatch,jwatch)*180/PI ! calculate local compute domain indices; we assume glac,lake,soil,vegn all ! have the same lbounds - i0 = i-lnd%is+lbound(glac,1); j0 = j-lnd%js+lbound(glac,2) + i = iwatch-lnd%is+lbound(glac,1); j = jwatch-lnd%js+lbound(glac,2) __DEBUG2__(lnd%is,lnd%js) - write(*,'(a,99(a,i4.2,x))')'local indices:','i0=',i0,'j0=',j0 - __DEBUG3__(frac(i,j),land_mask(i0,j0),valid_data(i0,j0)) - __DEBUG1__(glac(i0,j0,:)) - __DEBUG1__(lake(i0,j0,:)) - __DEBUG1__(soil(i0,j0,:)) - __DEBUG1__(vegn(i0,j0,:)) + write(*,'(a,99(a,i4.2,x))')'local indices:','i=',i,'j=',j + __DEBUG3__(frac(iwatch,jwatch),land_mask(i,j),valid_data(i,j)) + __DEBUG1__(glac(i,j,:)) + __DEBUG1__(lake(i,j,:)) + __DEBUG1__(soil(i,j,:)) + __DEBUG1__(vegn(i,j,:)) endif if (trim(nearest_point_search)=='global') then @@ -658,7 +671,8 @@ subroutine land_cover_cold_start(lnd) (lnd%tile_map(i+lnd%is-1,j+lnd%js-1),glac(i,j,:),lake(i,j,:),soil(i,j,:),vegn(i,j,:)) if(nitems(lnd%tile_map(i+lnd%is-1,j+lnd%js-1))==0) then call error_mesg('land_cover_cold_start',& - 'No tiles were created for a valid land point', FATAL) + 'No tiles were created for a valid land point at i='& + //trim(string(lnd%is+i-1))//' j='//trim(string(lnd%js+j-1))//' face='//trim(string(lnd%face)), FATAL) endif enddo enddo @@ -677,7 +691,7 @@ subroutine land_cover_cold_start_0d (set,glac0,lake0,soil0,vegn0) real :: glac(size(glac0(:))), lake(size(lake0(:))), & soil(size(soil0(:))), vegn(size(vegn0(:))) type(land_tile_type), pointer :: tile - integer :: i,j + integer :: i,j,k real :: factor ! normalizing factor for the tile areas real :: frac type(land_tile_enum_type) :: first_non_vegn ! position of first non-vegetated tile in the list @@ -698,6 +712,21 @@ subroutine land_cover_cold_start_0d (set,glac0,lake0,soil0,vegn0) lake = lake/factor soil = soil/factor endif + + ! remove soil/glac/lake fractions that are too small + if (min_frac>0) then + where (glac-! Print checksums of the various fields in the land_data_type. -! - -!-! Routine to print checksums of the various fields in the land_data_type. -! - -! -! call land_data_type_chksum(id, timestep, land) -! - -!-! Derived-type variable that contains fields in the land_data_type. -! -! -! -! Label to differentiate where this routine in being called from. -! -! -!-! An integer to indicate which timestep this routine is being called for. -! -! +! =========================================================================== +! Prints checksums of the various fields in the land_data_type. subroutine land_data_type_chksum(id, timestep, land) - use fms_mod, only: stdout - use mpp_mod, only: mpp_chksum - - character(len=*), intent(in) :: id - integer , intent(in) :: timestep + character(len=*), intent(in) :: id ! Label to differentiate where this + ! routine in being called from. + integer , intent(in) :: timestep ! An integer to indicate which + ! timestep this routine is being called for. type(land_data_type), intent(in) :: land integer :: n, outunit @@ -692,7 +641,4 @@ subroutine land_data_type_chksum(id, timestep, land) 100 FORMAT("CHECKSUM::",A32," = ",Z20) end subroutine land_data_type_chksum -!0)then + glac = glac/factor + lake = lake/factor + soil = soil/factor + endif + endif + if(is_watch_point()) then write(*,*)'#### land_cover_cold_start_0d input data ####' __DEBUG1__(glac0) @@ -761,9 +790,7 @@ end subroutine land_cover_cold_start_0d subroutine land_cover_warm_start ( restart_file_name, lnd ) character(len=*), intent(in) :: restart_file_name type(land_state_type), intent(inout) :: lnd - - integer, parameter :: INPUT_BUF_SIZE = 1024 - + ! ---- local vars integer, allocatable :: idx(:) ! compressed tile index integer, allocatable :: glac(:), lake(:), soil(:), snow(:), cana(:), vegn(:) ! tile tags @@ -783,7 +810,7 @@ subroutine land_cover_warm_start ( restart_file_name, lnd ) ! allocate the input data __NF_ASRT__(nfu_inq_var(ncid,'frac',id=id_frac,varsize=ntiles,dimids=dimids)) ! allocate input buffers for compression index and the variable - bufsize=min(INPUT_BUF_SIZE,ntiles) + bufsize=min(input_buf_size,ntiles) allocate(idx (bufsize), glac(bufsize), lake(bufsize), soil(bufsize), & snow(bufsize), cana(bufsize), vegn(bufsize), frac(bufsize) ) ! get the name of the fist (and only) dimension of the variable 'frac' -- this @@ -863,13 +890,11 @@ subroutine update_land_model_fast ( cplr2land, land2cplr ) real, allocatable :: runoff_1d(:),runoff_snow_1d(:),runoff_heat_1d(:) integer :: i,j,k ! lon, lat, and tile indices integer :: i_species ! river tracer iterator - integer :: i0, i1 ! indices used to iterate over grid cells efficiently + integer :: i1 ! index used to iterate over grid cells efficiently integer :: is,ie,js,je ! horizontal bounds of the override buffer type(land_tile_enum_type) :: ce, te ! tile enumarator type(land_tile_type), pointer :: tile ! pointer to current tile - integer, parameter :: chunk_size = 10 ! arbitrary constant for now - ! variables for data override real, allocatable :: phot_co2_data(:,:) ! buffer for data logical :: phot_co2_overridden ! flag indicating successful override @@ -894,10 +919,8 @@ subroutine update_land_model_fast ( cplr2land, land2cplr ) runoff = 0 ; runoff_snow = 0 ; runoff_heat = 0 ; runoff_c = 0 ! main tile loop -! do i1 = 0,(ie-is+1)*(je-js+1)-1 -!$OMP parallel do schedule(dynamic) default(shared) private(i0,i1,i,j,k,ce,te,tile,fco2_0,Dfco2Dq,ISa_dn_dir,ISa_dn_dif) - do i0 = 0,(ie-is+1)*(je-js+1)-1,chunk_size - do i1 = i0, min(i0+chunk_size-1,(ie-is+1)*(je-js+1)-1) +!$OMP parallel do schedule(dynamic) default(shared) private(i1,i,j,k,ce,te,tile,fco2_0,Dfco2Dq,ISa_dn_dir,ISa_dn_dif) + do i1 = 0,(ie-is+1)*(je-js+1)-1 i = mod(i1,ie-is+1)+is j = i1/(ie-is+1)+js ! __DEBUG4__(is,js,i-is+lnd%is,j-js+lnd%js) @@ -944,9 +967,10 @@ subroutine update_land_model_fast ( cplr2land, land2cplr ) call send_tile_data(id_Trad, land2cplr%t_surf(i,j,k), tile%diag) call send_tile_data(id_Tca, land2cplr%t_ca(i,j,k), tile%diag) call send_tile_data(id_qca, land2cplr%tr(i,j,k,lnd%isphum), tile%diag) + call send_tile_data(id_cd_m, cplr2land%cd_m(i,j,k), tile%diag) + call send_tile_data(id_cd_t, cplr2land%cd_t(i,j,k), tile%diag) enddo enddo - enddo ! set values of tracer fluxes runoff_c(:,:,1) = runoff_snow @@ -962,17 +986,16 @@ subroutine update_land_model_fast ( cplr2land, land2cplr ) discharge_l = discharge_l/lnd%cellarea do i_species = 1, num_species - discharge_c(:,:,i_species) = & - discharge_c(:,:,i_species)/lnd%cellarea + discharge_c(:,:,i_species) = discharge_c(:,:,i_species)/lnd%cellarea enddo ! pass through to ocean the runoff that was not seen by river module because of land_frac diffs. ! need to multiply by gfrac to spread over whole cell where (missing_rivers) discharge_l = (runoff-runoff_c(:,:,1))*frac do i_species = 1, num_species - where (missing_rivers) discharge_c(:,:,i_species) = & - runoff_c(:,:,i_species)*frac - enddo + where (missing_rivers) & + discharge_c(:,:,i_species) = runoff_c(:,:,i_species)*frac + enddo ! don't send negatives or insignificant values to ocean. put them in the sink instead. ! this code does not seem necessary, and default discharge_tol value should be used. @@ -1022,15 +1045,15 @@ subroutine update_land_model_fast ( cplr2land, land2cplr ) call cana_state( tile%cana, cana_q=cana_q ) cana_VMASS = canopy_air_mass*cana_q cana_HEAT = cana_tile_heat(tile%cana) - ! NEED TO DEFINE CANA_HEAT ************************************************** endif if (associated(tile%vegn)) then call vegn_tile_stock_pe(tile%vegn, vegn_LMASS, vegn_FMASS) vegn_HEAT = vegn_tile_heat(tile%vegn) endif - if(associated(tile%snow)) & + if(associated(tile%snow)) then call snow_tile_stock_pe(tile%snow, snow_LMASS, snow_FMASS) snow_HEAT = snow_tile_heat(tile%snow) + endif if (associated(tile%glac)) then call glac_tile_stock_pe(tile%glac, subs_LMASS, subs_FMASS) subs_HEAT = glac_tile_heat(tile%glac) @@ -1203,7 +1226,8 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & real :: snow_T, snow_rh, snow_liq, snow_ice, snow_subl integer :: ii, jj ! indices for debug output integer :: ierr - logical :: conserve_glacier_mass, snow_active + logical :: conserve_glacier_mass, snow_active, redo_leaf_water + integer :: canopy_water_step real :: subs_z0m, subs_z0s, snow_z0m, snow_z0s, grnd_z0s soil_uptake_T = tfreeze ! just to avoid using un-initialized values @@ -1266,7 +1290,7 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & ! volumetric mixing ratio [mol CO2/mol dry air] cana_co2_mol = cana_co2*mol_air/mol_CO2/(1-cana_q) if (phot_co2_overridden) cana_co2_mol = phot_co2_data - call vegn_step_1 ( tile%vegn, tile%diag, & + call vegn_step_1 ( tile%vegn, tile%soil, tile%diag, & p_surf, & ustar, & drag_q, & @@ -1284,6 +1308,14 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & Et0, DEtDTv, DEtDqc, DEtDwl, DEtDwf, & Eli0, DEliDTv, DEliDqc, DEliDwl, DEliDwf, & Esi0, DEsiDTv, DEsiDqc, DEsiDwl, DEsiDwf ) + if (LM2) then + con_g_h = con_g_h * con_fac_large + if (snow_active) then + con_g_v = con_g_v * con_fac_large + else + con_g_v = con_g_v * con_fac_small + endif + endif else RSv = 0 con_g_h = con_fac_large ; con_g_v = con_fac_large @@ -1329,130 +1361,132 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & ! [X.0] calculate the latent heats of vaporization at appropriate temperatures if (use_tfreeze_in_grnd_latent) then - grnd_latent = hlv + hlf*grnd_subl - else - grnd_latent = hlv + (cpw-clw)*(grnd_T-tfreeze) & - + (hlf + (clw-csw)*(grnd_T-tfreeze)) * grnd_subl - endif + grnd_latent = hlv + hlf*grnd_subl + else + grnd_latent = hlv + (cpw-clw)*(grnd_T-tfreeze) & + + (hlf + (clw-csw)*(grnd_T-tfreeze)) * grnd_subl + endif if (use_atmos_T_for_precip_T) then - precip_T = atmos_T - else - precip_T = cana_T - endif + precip_T = atmos_T + else + precip_T = cana_T + endif if (use_atmos_T_for_evap_T) then - evap_T = atmos_T - else - evap_T = cana_T - endif + evap_T = atmos_T + else + evap_T = cana_T + endif if (use_old_conservation_equations) then - hlv_Tv = hlv - (cpw-clw)*tfreeze + cpw*vegn_T - hls_Tv = hlv + hlf - (cpw-csw)*tfreeze + cpw*vegn_T - hlv_Tu = hlv - (cpw-clw)*tfreeze + cpw*vegn_T - clw*soil_uptake_T - pT = precip_T - cT = cana_T - eT = evap_T - gT = grnd_T - vT = vegn_T - else - hlv_Tv = hlv + cpw*(vegn_T-tfreeze) - hls_Tv = hlf + hlv_Tv - hlv_Tu = hlv_Tv - clw*(soil_uptake_T-tfreeze) - pT = precip_T-tfreeze - cT = cana_T-tfreeze - eT = evap_T-tfreeze - gT = grnd_T-tfreeze - vT = vegn_T-tfreeze - endif - if(is_watch_point()) then - write(*,*)'#### input data for the matrix ####' - __DEBUG1__(delta_time) - __DEBUG4__(vegn_T,vT,vegn_Wl,vegn_Ws) - __DEBUG3__(grnd_T,gT,grnd_rh) - __DEBUG3__(cana_T,cT,cana_q) - __DEBUG2__(evap_T,eT) - __DEBUG2__(vegn_emis_lw,surf_emis_lw) - __DEBUG2__(vegn_emsn,surf_emsn) - __DEBUG4__(precip_l, vegn_drip_l, pT, precip_T) - __DEBUG2__(precip_s, vegn_drip_s) - __DEBUG2__(vegn_ifrac, vegn_lai) - __DEBUG1__(ILa_dn) - __DEBUG2__(ISa_dn_dir(1),ISa_dn_dir(2)) - __DEBUG2__(ISa_dn_dif(1),ISa_dn_dif(2)) - __DEBUG2__(fswg, vegn_fsw) - __DEBUG1__(vegn_hcap) - __DEBUG3__(hlv_Tv, hlv_Tu, hls_Tv) - __DEBUG2__(G0, DGDTg) - __DEBUG2__(Ha0, DHaDTc) - __DEBUG2__(Ea0, DEaDqc) - __DEBUG3__(Hv0, DHvDTv, DHvDTc) - __DEBUG5__(Et0, DEtDTv, DEtDqc, DEtDwl, DEtDwf) - __DEBUG5__(Eli0, DEliDTv, DEliDqc, DEliDwl, DEliDwf) - __DEBUG5__(Esi0, DEsiDTv, DEsiDqc, DEsiDwl, DEsiDwf) - __DEBUG3__(Hg0, DHgDTg, DHgDTc) - __DEBUG3__(Eg0, DEgDTg, DEgDqc) - __DEBUG3__(flwv0, DflwvDTg, DflwvDTv) - __DEBUG3__(flwg0, DflwgDTg, DflwgDTv) - __DEBUG2__(tile%e_res_1,tile%e_res_2) + hlv_Tv = hlv - (cpw-clw)*tfreeze + cpw*vegn_T + hls_Tv = hlv + hlf - (cpw-csw)*tfreeze + cpw*vegn_T + hlv_Tu = hlv - (cpw-clw)*tfreeze + cpw*vegn_T - clw*soil_uptake_T + pT = precip_T + cT = cana_T + eT = evap_T + gT = grnd_T + vT = vegn_T + else + hlv_Tv = hlv + cpw*(vegn_T-tfreeze) + hls_Tv = hlf + hlv_Tv + hlv_Tu = hlv_Tv - clw*(soil_uptake_T-tfreeze) + pT = precip_T-tfreeze + cT = cana_T-tfreeze + eT = evap_T-tfreeze + gT = grnd_T-tfreeze + vT = vegn_T-tfreeze endif + do canopy_water_step = 1,2 + if(is_watch_point()) then + write(*,*)'#### input data for the matrix ####' + __DEBUG1__(delta_time) + __DEBUG4__(vegn_T,vT,vegn_Wl,vegn_Ws) + __DEBUG3__(grnd_T,gT,grnd_rh) + __DEBUG3__(cana_T,cT,cana_q) + __DEBUG2__(evap_T,eT) + __DEBUG2__(vegn_emis_lw,surf_emis_lw) + __DEBUG2__(vegn_emsn,surf_emsn) + __DEBUG4__(precip_l, vegn_drip_l, pT, precip_T) + __DEBUG2__(precip_s, vegn_drip_s) + __DEBUG2__(vegn_ifrac, vegn_lai) + __DEBUG1__(ILa_dn) + __DEBUG2__(ISa_dn_dir(1),ISa_dn_dir(2)) + __DEBUG2__(ISa_dn_dif(1),ISa_dn_dif(2)) + __DEBUG2__(fswg, vegn_fsw) + __DEBUG1__(vegn_hcap) + __DEBUG3__(hlv_Tv, hlv_Tu, hls_Tv) + __DEBUG2__(G0, DGDTg) + __DEBUG2__(Ha0, DHaDTc) + __DEBUG2__(Ea0, DEaDqc) + __DEBUG3__(Hv0, DHvDTv, DHvDTc) + __DEBUG5__(Et0, DEtDTv, DEtDqc, DEtDwl, DEtDwf) + __DEBUG5__(Eli0, DEliDTv, DEliDqc, DEliDwl, DEliDwf) + __DEBUG5__(Esi0, DEsiDTv, DEsiDqc, DEsiDwl, DEsiDwf) + __DEBUG3__(Hg0, DHgDTg, DHgDTc) + __DEBUG3__(Eg0, DEgDTg, DEgDqc) + __DEBUG3__(flwv0, DflwvDTg, DflwvDTv) + __DEBUG3__(flwg0, DflwgDTg, DflwgDTv) + __DEBUG2__(tile%e_res_1,tile%e_res_2) + endif + ! [X.1] form the system of equations for implicit scheme, such that A*X = B1*delta_Tg+B2*delta_psig+B0 ! [X.1.1] equation of canopy air mass balance - A(iqc,iqc) = canopy_air_mass/delta_time-DEtDqc-DEliDqc-DEsiDqc-DEgDqc+DEaDqc - A(iqc,iTc) = 0 - A(iqc,iTv) = -DEtDTv-DEliDTv-DEsiDTv - A(iqc,iwl) = -DEtDwl-DEliDwl-DEsiDwl - A(iqc,iwf) = -DEtDwf-DEliDwf-DEsiDwf - B0(iqc) = Esi0+Eli0+Et0+Eg0-Ea0 - B1(iqc) = DEgDTg - B2(iqc) = DEgDpsig + A(iqc,iqc) = canopy_air_mass/delta_time-DEtDqc-DEliDqc-DEsiDqc-DEgDqc+DEaDqc + A(iqc,iTc) = 0 + A(iqc,iTv) = -DEtDTv-DEliDTv-DEsiDTv + A(iqc,iwl) = -DEtDwl-DEliDwl-DEsiDwl + A(iqc,iwf) = -DEtDwf-DEliDwf-DEsiDwf + B0(iqc) = Esi0+Eli0+Et0+Eg0-Ea0 + B1(iqc) = DEgDTg + B2(iqc) = DEgDpsig ! [X.1.2] equation of canopy air energy balance #ifdef USE_DRY_CANA_MASS - A(iTc,iqc) = canopy_air_mass*cpw*cT/delta_time & + A(iTc,iqc) = canopy_air_mass*cpw*cT/delta_time & #else - A(iTc,iqc) = canopy_air_mass*(cpw-cp_air)*cT/delta_time & + A(iTc,iqc) = canopy_air_mass*(cpw-cp_air)*cT/delta_time & #endif - cpw*vT*(DEtDqc+DEliDqc+DEsiDqc) - cpw*gT*DEgDqc + cpw*eT*DEaDqc #ifdef USE_DRY_CANA_MASS - A(iTc,iTc) = canopy_air_mass*cp_air/delta_time-DHvDTc-DHgDTc+DHaDTc + A(iTc,iTc) = canopy_air_mass*cp_air/delta_time-DHvDTc-DHgDTc+DHaDTc #else - A(iTc,iTc) = canopy_air_mass*(cp_air+cana_q*(cpw-cp_air))/delta_time-DHvDTc-DHgDTc+DHaDTc + A(iTc,iTc) = canopy_air_mass*(cp_air+cana_q*(cpw-cp_air))/delta_time-DHvDTc-DHgDTc+DHaDTc #endif - A(iTc,iTv) = -DHvDTv-cpw*vT*(DEtDTv+DEliDTv+DEsiDTv) - A(iTc,iwl) = -cpw*vT*(DEtDwl+DEliDwl+DEsiDwl) - A(iTc,iwf) = -cpw*vT*(DEtDwf+DEliDwf+DEsiDwf) - B0(iTc) = Hv0 + Hg0 - Ha0 + cpw*(vT*(Et0+Eli0+Esi0)+gT*Eg0-eT*Ea0) - tile%e_res_1 - B1(iTc) = DHgDTg + cpw*gT*DEgDTg - B2(iTc) = cpw*gT*DEgDpsig + A(iTc,iTv) = -DHvDTv-cpw*vT*(DEtDTv+DEliDTv+DEsiDTv) + A(iTc,iwl) = -cpw*vT*(DEtDwl+DEliDwl+DEsiDwl) + A(iTc,iwf) = -cpw*vT*(DEtDwf+DEliDwf+DEsiDwf) + B0(iTc) = Hv0 + Hg0 - Ha0 + cpw*(vT*(Et0+Eli0+Esi0)+gT*Eg0-eT*Ea0) - tile%e_res_1 + B1(iTc) = DHgDTg + cpw*gT*DEgDTg + B2(iTc) = cpw*gT*DEgDpsig ! [X.1.3] equation of canopy energy balance - A(iTv,iqc) = hlv_Tu*DEtDqc + hlv_Tv*DEliDqc + hls_Tv*DEsiDqc - A(iTv,iTc) = DHvDTc - A(iTv,iTv) = vegn_hcap/delta_time-DflwvDTv + DHvDTv + & - hlv_Tu*DEtDTv + hlv_Tv*DEliDTv + hls_Tv*DEsiDTv + clw*vegn_drip_l + csw*vegn_drip_s - A(iTv,iwl) = clw*vT/delta_time + hlv_Tu*DEtDwl + hlv_Tv*DEliDwl + hls_Tv*DEsiDwl - A(iTv,iwf) = csw*vT/delta_time + hlv_Tu*DEtDwf + hlv_Tv*DEliDwf + hls_Tv*DEsiDwf - B0(iTv) = vegn_fsw + flwv0 - Hv0 - hlv_Tu*Et0 - Hlv_Tv*Eli0 - hls_Tv*Esi0 & - + clw*precip_l*vegn_ifrac*pT + csw*precip_s*vegn_ifrac*pT & - - clw*vegn_drip_l*vT - csw*vegn_drip_s*vT - tile%e_res_2 - B1(iTv) = DflwvDTg - B2(iTv) = 0 + A(iTv,iqc) = hlv_Tu*DEtDqc + hlv_Tv*DEliDqc + hls_Tv*DEsiDqc + A(iTv,iTc) = DHvDTc + A(iTv,iTv) = vegn_hcap/delta_time-DflwvDTv + DHvDTv + & + hlv_Tu*DEtDTv + hlv_Tv*DEliDTv + hls_Tv*DEsiDTv + clw*vegn_drip_l + csw*vegn_drip_s + A(iTv,iwl) = clw*vT/delta_time + hlv_Tu*DEtDwl + hlv_Tv*DEliDwl + hls_Tv*DEsiDwl + A(iTv,iwf) = csw*vT/delta_time + hlv_Tu*DEtDwf + hlv_Tv*DEliDwf + hls_Tv*DEsiDwf + B0(iTv) = vegn_fsw + flwv0 - Hv0 - hlv_Tu*Et0 - Hlv_Tv*Eli0 - hls_Tv*Esi0 & + + clw*precip_l*vegn_ifrac*pT + csw*precip_s*vegn_ifrac*pT & + - clw*vegn_drip_l*vT - csw*vegn_drip_s*vT - tile%e_res_2 + B1(iTv) = DflwvDTg + B2(iTv) = 0 ! [X.1.4] equation of intercepted liquid water mass balance - A(iwl,iqc) = DEliDqc - A(iwl,iTc) = 0 - A(iwl,iTv) = DEliDTv - A(iwl,iwl) = 1.0/delta_time + DEliDwl - A(iwl,iwf) = DEliDwf - B0(iwl) = -Eli0 + precip_l*vegn_ifrac - vegn_drip_l - B1(iwl) = 0 - B2(iwl) = 0 + A(iwl,iqc) = DEliDqc + A(iwl,iTc) = 0 + A(iwl,iTv) = DEliDTv + A(iwl,iwl) = 1.0/delta_time + DEliDwl + A(iwl,iwf) = DEliDwf + B0(iwl) = -Eli0 + precip_l*vegn_ifrac - vegn_drip_l + B1(iwl) = 0 + B2(iwl) = 0 ! [X.1.5] equation of intercepted frozen water mass balance - A(iwf,iqc) = DEsiDqc - A(iwf,iTc) = 0 - A(iwf,iTv) = DEsiDTv - A(iwf,iwl) = DEsiDwl - A(iwf,iwf) = 1.0/delta_time + DEsiDwf - B0(iwf) = -Esi0 + precip_s*vegn_ifrac - vegn_drip_s - B1(iwf) = 0 - B2(iwf) = 0 + A(iwf,iqc) = DEsiDqc + A(iwf,iTc) = 0 + A(iwf,iTv) = DEsiDTv + A(iwf,iwl) = DEsiDwl + A(iwf,iwf) = 1.0/delta_time + DEsiDwf + B0(iwf) = -Esi0 + precip_s*vegn_ifrac - vegn_drip_s + B1(iwf) = 0 + B2(iwf) = 0 ! [X.1.6] if LAI becomes zero (and, therefore, all fluxes from vegetation and their ! derivatives must be zero too) we get a degenerate case. Still, the drip may be non-zero ! because some water may remain from before leaf drop, and non-zero energy residual can be @@ -1463,52 +1497,50 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & ! delta_Wl = -vegn_drip_l*delta_time ! delta_Ws = -vegn_drip_s*delta_time ! the residual vegn_Wl and vegn_Ws, if any, are taken care of by the overflow calculations - if(vegn_hcap==0) then - ! vegn_T + delta_Tv = cana_T + delta_Tc - A(iTv,:) = 0 - A(iTv,iTc) = -1 - A(iTv,iTv) = +1 - B0(iTv) = cana_T - vegn_T - B1(iTv) = 0 - ! delta_Wl = -vegn_drip_l*delta_time - A(iwl,:) = 0 - A(iwl,iwl) = 1 - B0(iwl) = -vegn_drip_l*delta_time - B1(iwl) = 0 - ! delta_Ws = -vegn_drip_s*delta_time - A(iwf,:) = 0 - A(iwf,iwf) = 1 - B0(iwf) = -vegn_drip_s*delta_time - B1(iwf) = 0 - endif - - + if(vegn_hcap==0) then + ! vegn_T + delta_Tv = cana_T + delta_Tc + A(iTv,:) = 0 + A(iTv,iTc) = -1 + A(iTv,iTv) = +1 + B0(iTv) = cana_T - vegn_T + B1(iTv) = 0 + ! delta_Wl = -vegn_drip_l*delta_time + A(iwl,:) = 0 + A(iwl,iwl) = 1 + B0(iwl) = -vegn_drip_l*delta_time + B1(iwl) = 0 + ! delta_Ws = -vegn_drip_s*delta_time + A(iwf,:) = 0 + A(iwf,iwf) = 1 + B0(iwf) = -vegn_drip_s*delta_time + B1(iwf) = 0 + endif - if(is_watch_point()) then - write(*,*)'#### A, B0, B1, B2 ####' - do ii = 1, size(A,1) - write(*,'(99g)')(A(ii,jj),jj=1,size(A,2)),B0(ii),B1(ii),B2(ii) - enddo - endif + if(is_watch_point()) then + write(*,*)'#### A, B0, B1, B2 ####' + do ii = 1, size(A,1) + write(*,'(99g23.16)')(A(ii,jj),jj=1,size(A,2)),B0(ii),B1(ii),B2(ii) + enddo + endif - A00 = A - B00 = B0 - B10 = B1 + A00 = A + B00 = B0 + B10 = B1 ! [X.2] solve the system for free terms and delta_Tg and delta_psig terms, getting ! linear equation for delta_Tg and delta_psig - call ludcmp(A,indx, ierr) - if (ierr/=0)& - write(*,*) 'Matrix is singular',i,j,k - call lubksb(A,indx,B0) - call lubksb(A,indx,B1) - call lubksb(A,indx,B2) - - if(is_watch_point()) then - write(*,*)'#### solution: B0, B1, B2 ####' - do ii = 1, size(A,1) - __DEBUG3__(B0(ii),B1(ii),B2(ii)) - enddo + call ludcmp(A,indx, ierr) + if (ierr/=0)& + write(*,*) 'Matrix is singular',i,j,k + call lubksb(A,indx,B0) + call lubksb(A,indx,B1) + call lubksb(A,indx,B2) + + if(is_watch_point()) then + write(*,*)'#### solution: B0, B1, B2 ####' + do ii = 1, size(A,1) + __DEBUG3__(B0(ii),B1(ii),B2(ii)) + enddo !!$ write(*,*)'#### solution check ####' !!$ do ii = 1, size(A,1) !!$ sum0 = 0; sum1 = 0; @@ -1518,79 +1550,96 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & !!$ enddo !!$ write(*,'(99g)')sum0-B00(ii),sum1-B10(ii) !!$ enddo - endif + endif ! the result of this solution is a set of expressions for delta_xx in terms ! of delta_Tg and delta_psig: ! delta_xx(i) = B0(i) + B1(i)*delta_Tg + B2(i)*delta_psig. Note that A, B0, B1 and B2 ! are destroyed in the process: A is replaced with LU-decomposition, and ! B0, B1, B2 are replaced with solutions - ! solve the non-linear equation for energy balance at the surface. + ! solve the non-linear equation for energy balance at the surface. - call land_surface_energy_balance( & - grnd_T, grnd_liq, grnd_ice, grnd_latent, grnd_Tf, grnd_E_min, & - grnd_E_max, fswg, & - flwg0 + b0(iTv)*DflwgDTv, DflwgDTg + b1(iTv)*DflwgDTv, b2(iTv)*DflwgDTv, & - Hg0 + b0(iTc)*DHgDTc, DHgDTg + b1(iTc)*DHgDTc, b2(iTc)*DHgDTc, & - Eg0 + b0(iqc)*DEgDqc, DEgDTg + b1(iqc)*DEgDqc, DEgDpsig + b2(iqc)*DEgDqc, & - G0, DGDTg, & - ! output - delta_Tg, delta_psig, Mg_imp ) + call land_surface_energy_balance( & + grnd_T, grnd_liq, grnd_ice, grnd_latent, grnd_Tf, grnd_E_min, & + grnd_E_max, fswg, & + flwg0 + b0(iTv)*DflwgDTv, DflwgDTg + b1(iTv)*DflwgDTv, b2(iTv)*DflwgDTv, & + Hg0 + b0(iTc)*DHgDTc, DHgDTg + b1(iTc)*DHgDTc, b2(iTc)*DHgDTc, & + Eg0 + b0(iqc)*DEgDqc, DEgDTg + b1(iqc)*DEgDqc, DEgDpsig + b2(iqc)*DEgDqc, & + G0, DGDTg, & + ! output + delta_Tg, delta_psig, Mg_imp ) ! [X.5] calculate final value of other tendencies - delta_qc = B0(iqc) + B1(iqc)*delta_Tg + B2(iqc)*delta_psig - delta_Tc = B0(iTc) + B1(iTc)*delta_Tg + B2(iTc)*delta_psig - delta_Tv = B0(iTv) + B1(iTv)*delta_Tg + B2(iTv)*delta_psig - delta_wl = B0(iwl) + B1(iwl)*delta_Tg + B2(iwl)*delta_psig - delta_ws = B0(iwf) + B1(iwf)*delta_Tg + B2(iwf)*delta_psig + delta_qc = B0(iqc) + B1(iqc)*delta_Tg + B2(iqc)*delta_psig + delta_Tc = B0(iTc) + B1(iTc)*delta_Tg + B2(iTc)*delta_psig + delta_Tv = B0(iTv) + B1(iTv)*delta_Tg + B2(iTv)*delta_psig + delta_wl = B0(iwl) + B1(iwl)*delta_Tg + B2(iwl)*delta_psig + delta_ws = B0(iwf) + B1(iwf)*delta_Tg + B2(iwf)*delta_psig ! [X.6] calculate updated values of energy balance components used in further ! calculations - flwg = flwg0 + DflwgDTg*delta_Tg + DflwgDTv*delta_Tv - evapg = Eg0 + DEgDTg*delta_Tg + DEgDpsig*delta_psig + DEgDqc*delta_qc - sensg = Hg0 + DHgDTg*delta_Tg + DHgDTc*delta_Tc - grnd_flux = G0 + DGDTg*delta_Tg - vegn_sens = Hv0 + DHvDTv*delta_Tv + DHvDTc*delta_Tc - vegn_levap = Eli0 + DEliDTv*delta_Tv + DEliDqc*delta_qc + DEliDwl*delta_wl + DEliDwf*delta_ws - vegn_fevap = Esi0 + DEsiDTv*delta_Tv + DEsiDqc*delta_qc + DEsiDwl*delta_wl + DEsiDwf*delta_ws - vegn_uptk = Et0 + DEtDTv*delta_Tv + DEtDqc*delta_qc + DEtDwl*delta_wl + DEtDwf*delta_ws - vegn_flw = flwv0 + DflwvDTv*delta_Tv + DflwvDTg*delta_Tg - land_evap = Ea0 + DEaDqc*delta_qc - land_sens = Ha0 + DHaDTc*delta_Tc + flwg = flwg0 + DflwgDTg*delta_Tg + DflwgDTv*delta_Tv + evapg = Eg0 + DEgDTg*delta_Tg + DEgDpsig*delta_psig + DEgDqc*delta_qc + sensg = Hg0 + DHgDTg*delta_Tg + DHgDTc*delta_Tc + grnd_flux = G0 + DGDTg*delta_Tg + vegn_sens = Hv0 + DHvDTv*delta_Tv + DHvDTc*delta_Tc + vegn_levap = Eli0 + DEliDTv*delta_Tv + DEliDqc*delta_qc + DEliDwl*delta_wl + DEliDwf*delta_ws + vegn_fevap = Esi0 + DEsiDTv*delta_Tv + DEsiDqc*delta_qc + DEsiDwl*delta_wl + DEsiDwf*delta_ws + vegn_uptk = Et0 + DEtDTv*delta_Tv + DEtDqc*delta_qc + DEtDwl*delta_wl + DEtDwf*delta_ws + vegn_flw = flwv0 + DflwvDTv*delta_Tv + DflwvDTg*delta_Tg + land_evap = Ea0 + DEaDqc*delta_qc + land_sens = Ha0 + DHaDTc*delta_Tc ! [X.7] calculate energy residuals due to cross-product of time tendencies #ifdef USE_DRY_CANA_MASS - tile%e_res_1 = canopy_air_mass*cpw*delta_qc*delta_Tc/delta_time + tile%e_res_1 = canopy_air_mass*cpw*delta_qc*delta_Tc/delta_time #else - tile%e_res_1 = canopy_air_mass*(cpw-cp_air)*delta_qc*delta_Tc/delta_time + tile%e_res_1 = canopy_air_mass*(cpw-cp_air)*delta_qc*delta_Tc/delta_time #endif - tile%e_res_2 = delta_Tv*(clw*delta_Wl+csw*delta_Ws)/delta_time + tile%e_res_2 = delta_Tv*(clw*delta_Wl+csw*delta_Ws)/delta_time ! calculate the final value upward long-wave radiation flux from the land, to be ! returned to the flux exchange. - tile%lwup = ILa_dn - vegn_flw - flwg - - if(is_watch_point())then - write(*,*)'#### ground balance' - __DEBUG2__(fswg,flwg) - __DEBUG2__(sensg,evapg*grnd_latent) - __DEBUG1__(grnd_flux) - __DEBUG1__(Mg_imp) - write(*,*)'#### implicit time steps' - __DEBUG3__(delta_Tg, grnd_T, grnd_T+delta_Tg ) - __DEBUG1__(delta_psig ) - __DEBUG3__(delta_qc, cana_q, cana_q+delta_qc ) - __DEBUG3__(delta_Tc, cana_T, cana_T+delta_Tc ) - __DEBUG3__(delta_Tv, vegn_T, vegn_T+delta_Tv ) - __DEBUG3__(delta_wl, vegn_Wl, vegn_Wl+delta_wl) - __DEBUG3__(delta_ws, vegn_Ws, vegn_Ws+delta_ws) - __DEBUG2__(tile%e_res_1, tile%e_res_2) - write(*,*)'#### resulting fluxes' - __DEBUG4__(flwg, evapg, sensg, grnd_flux) - __DEBUG3__(vegn_levap,vegn_fevap,vegn_uptk) - __DEBUG2__(vegn_sens,vegn_flw) - __DEBUG1__(Ea0+DEaDqc*delta_qc) - __DEBUG2__(tile%cana%prog%q,cana_q) - endif + tile%lwup = ILa_dn - vegn_flw - flwg + + if(is_watch_point())then + write(*,*)'#### ground balance' + __DEBUG2__(fswg,flwg) + __DEBUG2__(sensg,evapg*grnd_latent) + __DEBUG1__(grnd_flux) + __DEBUG1__(Mg_imp) + write(*,*)'#### implicit time steps' + __DEBUG3__(delta_Tg, grnd_T, grnd_T+delta_Tg ) + __DEBUG1__(delta_psig ) + __DEBUG3__(delta_qc, cana_q, cana_q+delta_qc ) + __DEBUG3__(delta_Tc, cana_T, cana_T+delta_Tc ) + __DEBUG3__(delta_Tv, vegn_T, vegn_T+delta_Tv ) + __DEBUG3__(delta_wl, vegn_Wl, vegn_Wl+delta_wl) + __DEBUG3__(delta_ws, vegn_Ws, vegn_Ws+delta_ws) + __DEBUG2__(tile%e_res_1, tile%e_res_2) + write(*,*)'#### resulting fluxes' + __DEBUG4__(flwg, evapg, sensg, grnd_flux) + __DEBUG3__(vegn_levap,vegn_fevap,vegn_uptk) + __DEBUG2__(vegn_sens,vegn_flw) + __DEBUG1__(Ea0+DEaDqc*delta_qc) + __DEBUG2__(tile%cana%prog%q,cana_q) + endif + if (.not.prohibit_negative_canopy_water) exit ! do no corrections + redo_leaf_water = .FALSE. + if (vegn_Wl+delta_wl<0) then + redo_leaf_water = .TRUE. + Eli0 = vegn_Wl/delta_time + precip_l*vegn_ifrac - vegn_drip_l + DEliDTv = 0.0; DEliDqc = 0.0 + DEliDwl = 0.0; DEliDwf = 0.0 + endif + if (vegn_Ws+delta_ws<0) then + redo_leaf_water = .TRUE. + Esi0 = vegn_Ws/delta_time + precip_s*vegn_ifrac - vegn_drip_s + DEsiDTv = 0.0; DEsiDqc = 0.0 + DEsiDwl = 0.0; DEsiDwf = 0.0 + endif + if (.not.redo_leaf_water) exit ! from loop + enddo ! canopy_water_step + call cana_step_2 ( tile%cana, delta_Tc, delta_qc ) if(associated(tile%vegn)) then @@ -1683,14 +1732,14 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & ! TEMP FIX: MAIN PROG SHOULD NOT TOUCH CONTENTS OF PROG VARS. ****** ! ALSO, DIAGNOSTICS IN COMPONENT MODULES SHOULD _FOLLOW_ THIS ADJUSTMENT****** - IF (LM2) THEN - tile%snow%prog%T = subs_Ttop + if (LM2) then + tile%snow%T = subs_Ttop subs_G2 = 0. - ELSE - if (sum(tile%snow%prog(:)%ws)>0)then + else + if (sum(tile%snow%ws(:))>0)then new_T = (subs_Ctop*subs_Ttop +snow_Cbot*snow_Tbot) & / (subs_Ctop+snow_Cbot) - tile%snow%prog(size(tile%snow%prog))%T = new_T + tile%snow%T(size(tile%snow%T)) = new_T if(associated(tile%glac)) tile%glac%prog(1)%T = new_T if(associated(tile%lake)) tile%lake%prog(1)%T = new_T if(associated(tile%soil)) tile%soil%prog(1)%T = new_T @@ -1699,7 +1748,7 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & if(tau_snow_T_adj>=0) then delta_T_snow = subs_Ctop*(subs_Ttop-snow_avrg_T)/& (subs_Ctop*tau_snow_T_adj/delta_time+subs_Ctop+snow_C) - tile%snow%prog(:)%T = snow_avrg_T + delta_T_snow + tile%snow%T(:) = snow_avrg_T + delta_T_snow new_T = subs_Ttop-snow_C/subs_Ctop*delta_T_snow if(associated(tile%glac)) tile%glac%prog(1)%T = new_T @@ -1710,13 +1759,15 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & subs_G2 = 0. endif endif - ENDIF + endif vegn_fco2 = 0 if (associated(tile%vegn)) then ! do the calculations that require updated land surface prognostic variables call vegn_step_3 (tile%vegn, tile%soil, tile%cana%prog%T, precip_l+precip_s, & vegn_fco2, tile%diag) + ! if vegn is present, then soil must be too + call soil_step_3(tile%soil, tile%diag) endif ! update co2 concentration in the canopy air. It would be more consistent to do that ! in the same place and fashion as the rest of prognostic variables: that is, have the @@ -1824,7 +1875,6 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & call send_tile_data(id_hroff, snow_hlrunf+subs_hlrunf+snow_hfrunf, & tile%diag) call send_tile_data(id_gsnow, subs_G, tile%diag) - call send_tile_data(id_gsnow_old, subs_G, tile%diag) call send_tile_data(id_gequil, subs_G2, tile%diag) call send_tile_data(id_grnd_flux, grnd_flux, tile%diag) call send_tile_data(id_soil_water_supply, soil_water_supply, tile%diag) @@ -1839,7 +1889,10 @@ subroutine update_land_model_fast_0d(tile, i,j,k, land2cplr, & call send_tile_data(id_swup_dir, ISa_dn_dir*tile%land_refl_dir, tile%diag) call send_tile_data(id_swup_dif, ISa_dn_dif*tile%land_refl_dif, tile%diag) call send_tile_data(id_lwdn, ILa_dn, tile%diag) + call send_tile_data(id_subs_emis,surf_emis_lw, tile%diag) + if (id_total_C > 0) & + call send_tile_data(id_total_C, land_tile_carbon(tile), tile%diag) end subroutine update_land_model_fast_0d @@ -2092,7 +2145,7 @@ subroutine update_land_bc_fast (tile, i,j,k, land2cplr, is_init) ', face='//trim(string(face))//')',FATAL) endif - call snow_radiation ( tile%snow%prog(1)%T, cosz, snow_refl_dir, snow_refl_dif, snow_refl_lw, snow_emis) + call snow_radiation ( tile%snow%T(1), cosz, snow_refl_dir, snow_refl_dif, snow_refl_lw, snow_emis) call snow_get_depth_area ( tile%snow, snow_depth, snow_area ) call snow_diffusion ( tile%snow, snow_z0s, snow_z0m ) @@ -2166,7 +2219,8 @@ subroutine update_land_bc_fast (tile, i,j,k, land2cplr, is_init) subs_z0m, subs_z0s, & snow_z0m, snow_z0s, snow_area, & vegn_cover, vegn_height, vegn_lai, vegn_sai, & - tile%land_d, tile%land_z0m, tile%land_z0s) + tile%land_d, tile%land_z0m, tile%land_z0s, & + associated(tile%lake).or.associated(tile%glac)) if(is_watch_point()) then write(*,*) '#### update_land_bc_fast ### checkpoint 2 ####' @@ -2254,7 +2308,7 @@ subroutine update_land_bc_fast (tile, i,j,k, land2cplr, is_init) call send_tile_data(id_grnd_T, grnd_T, tile%diag) ! --- debug section - call check_temp_range(land2cplr%t_ca(i,j,k),'update_land_bc_fast','T_ca') + call check_temp_range(land2cplr%t_ca(i,j,k),'update_land_bc_fast','T_ca',lnd%time) end subroutine update_land_bc_fast @@ -2675,6 +2729,10 @@ subroutine land_diag_init(clonb, clatb, clon, clat, time, domain, & 'net lw rad to snow', 'W/m2', missing_value=-1.0e+20 ) id_flwg = register_tiled_diag_field ( module_name, 'flwg', axes, time, & 'net lw rad to ground', 'W/m2', missing_value=-1.0e+20 ) + id_cd_m = register_tiled_diag_field ( module_name, 'cd_m', axes, time, & + 'drag coefficient for momentum', missing_value=-1e20) + id_cd_t = register_tiled_diag_field ( module_name, 'cd_t', axes, time, & + 'drag coefficient for heat and tracers', missing_value=-1e20) id_sens = register_tiled_diag_field ( module_name, 'sens', axes, time, & 'sens heat flux from land', 'W/m2', missing_value=-1.0e+20 ) id_sensv = register_tiled_diag_field ( module_name, 'sensv', axes, time, & @@ -2714,7 +2772,7 @@ subroutine land_diag_init(clonb, clatb, clon, clat, time, domain, & 'sensible heat of runoff', 'W/m2', missing_value=-1.0e+20 ) id_gsnow = register_tiled_diag_field ( module_name, 'gsnow', axes, time, & 'sens heat into ground from snow', 'W/m2', missing_value=-1.0e+20 ) - id_gsnow_old=register_tiled_diag_field ( module_name, 'gflux', axes, time, & + call add_tiled_diag_field_alias ( id_gsnow, module_name, 'gflux', axes, time, & 'obsolete, please use "gsnow" instead', 'W/m2', missing_value=-1.0e+20 ) id_gequil = register_tiled_diag_field ( module_name, 'gequil', axes, time, & 'snow-subs equilibration flux', 'W/m2', missing_value=-1.0e+20 ) @@ -2785,8 +2843,13 @@ subroutine land_diag_init(clonb, clatb, clon, clat, time, domain, & id_subs_refl_dif = register_tiled_diag_field(module_name, 'subs_refl_dif', & (/id_lon, id_lat, id_band/), time, & 'substrate reflectivity for diffuse light',missing_value=-1.0) + id_subs_emis = register_tiled_diag_field(module_name, 'subs_emis', & + (/id_lon, id_lat/), time, & + 'substrate emissivity for long-wave radiation',missing_value=-1.0) id_grnd_T = register_tiled_diag_field ( module_name, 'Tgrnd', axes, time, & 'ground surface temperature', 'degK', missing_value=-1.0 ) + id_total_C = register_tiled_diag_field ( module_name, 'Ctot', axes, time, & + 'total land carbon', 'kg C/m2', missing_value=-1.0 ) end subroutine land_diag_init ! the code below defines the accessor routines that are used to access fields of the diff --git a/src/land_lad2/land_tile.F90 b/src/land_lad2/land_tile.F90 index 007ab385dd..ec220f3ecf 100644 --- a/src/land_lad2/land_tile.F90 +++ b/src/land_lad2/land_tile.F90 @@ -14,7 +14,7 @@ module land_tile_mod use soil_tile_mod, only : & soil_tile_type, new_soil_tile, delete_soil_tile, soil_is_selected, & soil_tiles_can_be_merged, merge_soil_tiles, get_soil_tile_tag, & - soil_tile_stock_pe, soil_tile_heat + soil_tile_stock_pe, soil_tile_carbon, soil_tile_heat use cana_tile_mod, only : & cana_tile_type, new_cana_tile, delete_cana_tile, cana_is_selected, & cana_tiles_can_be_merged, merge_cana_tiles, get_cana_tile_tag, & @@ -105,8 +105,8 @@ module land_tile_mod ! ==== module constants ====================================================== character(len=*), parameter :: & - version = '$Id: land_tile.F90,v 17.0 2009/07/21 03:02:24 fms Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: land_tile.F90,v 20.0 2013/12/13 23:29:28 fms Exp $', & + tagname = '$Name: tikal $' ! ==== data types ============================================================ ! land_tile_type describes the structure of the land model tile; basically @@ -351,6 +351,8 @@ function land_tile_carbon(tile) result(carbon) ; real carbon carbon = carbon + cana_tile_carbon(tile%cana) if (associated(tile%vegn)) & carbon = carbon + vegn_tile_carbon(tile%vegn) + if (associated(tile%soil)) & + carbon = carbon + soil_tile_carbon(tile%soil) end function diff --git a/src/land_lad2/river/river.F90 b/src/land_lad2/river/river.F90 index 9a118824e1..be75f90270 100644 --- a/src/land_lad2/river/river.F90 +++ b/src/land_lad2/river/river.F90 @@ -47,19 +47,20 @@ module river_mod #endif use mpp_mod, only : CLOCK_SUBCOMPONENT, CLOCK_ROUTINE - use mpp_mod, only : mpp_error, mpp_chksum, FATAL, WARNING, stdlog, mpp_npes + use mpp_mod, only : mpp_error, mpp_chksum, FATAL, WARNING, NOTE, stdlog, mpp_npes use mpp_mod, only : mpp_pe, stdout, mpp_chksum, mpp_max use mpp_mod, only : mpp_clock_id, mpp_clock_begin, mpp_clock_end, MPP_CLOCK_DETAILED use mpp_domains_mod, only : domain2d, mpp_get_compute_domain, mpp_get_global_domain use mpp_domains_mod, only : mpp_get_data_domain, mpp_update_domains, mpp_get_ntile_count - use fms_mod, only : write_version_number, check_nml_error + use fms_mod, only : write_version_number, check_nml_error, string use fms_mod, only : close_file, file_exist, field_size, read_data, write_data, lowercase use fms_mod, only : field_exist, CLOCK_FLAG_DEFAULT - use fms_io_mod, only : get_mosaic_tile_file + use fms_io_mod, only : get_mosaic_tile_file, get_instance_filename use diag_manager_mod, only : diag_axis_init, register_diag_field, register_static_field, send_data use time_manager_mod, only : time_type, increment_time, get_time - use river_type_mod, only : river_type, Leo_Mad_trios - use river_physics_mod, only : river_physics_step, river_physics_init + use river_type_mod, only : river_type, Leo_Mad_trios, NO_RIVER_FLAG + use river_physics_mod, only : river_physics_step, river_physics_init, river_impedes_lake, & + river_impedes_large_lake use constants_mod, only : PI, RADIAN, tfreeze, DENS_H2O, hlf use stock_constants_mod, only : ISTOCK_WATER, ISTOCK_HEAT use land_tile_mod, only : land_tile_type, land_tile_enum_type, & @@ -72,8 +73,8 @@ module river_mod private !--- version information --------------------------------------------- - character(len=128) :: version = '$Id: river.F90,v 19.0 2012/01/06 20:40:55 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: river.F90,v 20.0 2013/12/13 23:29:41 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--- public interface ------------------------------------------------ public :: river_init, river_end, river_type, update_river, river_stock_pe @@ -105,7 +106,10 @@ module river_mod real :: channel_tau = 86400*365.25*10 ! channel geometry reflects average flow over O(10 y) logical :: lake_area_bug = .FALSE. ! if set to true, reverts to buggy (quebec) ! behavior, where by mistake cell area was used instead of land area to - ! compute the area of lakes. + ! compute the area of lakes. + logical :: stop_on_mask_mismatch = .TRUE. ! if set to false, then the data mismatches (mmismatch + ! of land and river masks, and discharges in pouints where there is no ocean) are reported, + ! but don't cause the abort of the program. namelist /river_nml/ dt_slow, diag_freq, debug_river, do_age, & Somin, outflowmean_min, num_c, rt_c_name, rt_t_ref, & rt_vf_ref, rt_q10, rt_kinv, rt_source_conc_file, & @@ -113,7 +117,7 @@ module river_mod rt_source_flux_name, ave_DHG_exp, ave_AAS_exp, & ave_DHG_coef, do_rivers, sinuosity, channel_tau, & land_area_called_cellarea, all_big_outlet_ctn0, & - lake_area_bug + lake_area_bug, stop_on_mask_mismatch character(len=128) :: river_src_file = 'INPUT/river_data.nc' character(len=128) :: river_Omean_file = 'INPUT/river_Omean.nc' @@ -123,7 +127,7 @@ module river_mod integer :: isd, ied, jsd, jed ! data domain decomposition integer :: nlon, nlat ! size of computational river grid integer :: num_lake_lev - integer :: id_outflowmean + integer :: id_outflowmean, id_lake_depth_sill integer :: id_dx, id_basin, id_So, id_depth, id_width, id_vel integer :: id_LWSr, id_FWSr, id_HSr, id_meltr integer :: i_species @@ -160,7 +164,6 @@ module river_mod character(len=5), allocatable, dimension(:) :: conc_units integer :: num_fast_calls integer :: slow_step = 0 ! record number of slow time step run. - real :: D2R type(domain2d), save :: domain type(river_type) , save :: River @@ -186,7 +189,7 @@ subroutine river_init( land_lon, land_lat, time, dt_fast, land_domain, & integer, intent(in) :: id_lon, id_lat ! IDs of diagnostic axes logical, intent(out):: river_land_mask(:,:) ! land mask seen by rivers - integer :: unit, outunit, io_status, ierr + integer :: unit, io_status, ierr integer :: sec, day, i, j integer :: nxc, nyc character(len=128) :: filename @@ -195,7 +198,6 @@ subroutine river_init( land_lon, land_lat, time, dt_fast, land_domain, & type(Leo_Mad_trios) :: DHG_coef ! downstream equation coefficients type(Leo_Mad_trios) :: AAS_exp ! at-a-station equation exponents - D2R = PI/180. riverclock = mpp_clock_id('update_river' , CLOCK_FLAG_DEFAULT, CLOCK_SUBCOMPONENT) slowclock = mpp_clock_id('update_river_slow' , CLOCK_FLAG_DEFAULT, CLOCK_ROUTINE) bndslowclock = mpp_clock_id('update_river_bnd_slow', CLOCK_FLAG_DEFAULT, CLOCK_ROUTINE) @@ -368,17 +370,24 @@ subroutine river_init( land_lon, land_lat, time, dt_fast, land_domain, & call river_diag_init (id_lon, id_lat) !--- read restart file - call get_mosaic_tile_file('INPUT/river.res.nc', filename, .false., domain) + call get_instance_filename('INPUT/river.res.nc', filename) + call get_mosaic_tile_file(trim(filename), filename, .false., domain) - outunit=stdout() if(file_exist(trim(filename),domain) ) then + call mpp_error(NOTE, 'river_init : Read restart files '//trim(filename)) call read_data(filename,'storage', River%storage, domain) call read_data(filename,'storage_c', River%storage_c, domain) call read_data(filename,'discharge2ocean', discharge2ocean_next, domain) call read_data(filename,'discharge2ocean_c',discharge2ocean_next_c, domain) call read_data(filename,'Omean', River%outflowmean, domain) - write(outunit,*) 'Read restart files INPUT/river.res.nc' + if (field_exist(filename,'depth',domain)) then + ! call mpp_error(WARNING, 'river_init : Reading field "depth" from '//trim(filename)) + call read_data(filename,'depth', River%depth, domain) + else + ! call mpp_error(WARNING, 'river_init : "depth" is not present in '//trim(filename)) + endif else + call mpp_error(NOTE, 'river_init : cold start, set data to 0') River%storage = 0.0 River%storage_c = 0.0 discharge2ocean_next = 0.0 @@ -388,7 +397,6 @@ subroutine river_init( land_lon, land_lat, time, dt_fast, land_domain, & else River%outflowmean = CONST_OMEAN end if - write(outunit,*) 'cold restart, set data to 0 ' endif River%stordis_c = River%dt_slow * discharge2ocean_next_c/DENS_H2O River%stordis = River%dt_slow *(discharge2ocean_next + & @@ -482,7 +490,8 @@ subroutine update_river_slow(runoff, runoff_c) real, dimension(isd:ied,jsd:jed,num_lake_lev) :: & lake_wl, lake_ws real, dimension(isc:iec,jsc:jec) :: & - lake_depth_sill, lake_width_sill, & + lake_depth_sill, lake_width_sill, lake_backwater, & + lake_backwater_1, & lake_whole_area, & rivr_LMASS, & ! mass of liquid water in rivers in cell rivr_FMASS, & ! mass of ice in rivers in cell @@ -534,7 +543,9 @@ subroutine update_river_slow(runoff, runoff_c) lake_width_sill = 0 lake_whole_area = 0 lake_conn = 0 - ce = first_elmt(lnd%tile_map, is=isc, js=jsc) + lake_backwater = 0 + lake_backwater_1 = 0 + ce = first_elmt(lnd%tile_map, is=isc, js=jsc) te = tail_elmt (lnd%tile_map) do while(ce /= te) call get_elmt_indices(ce,i,j,k) @@ -558,6 +569,8 @@ subroutine update_river_slow(runoff, runoff_c) lake_width_sill(i,j) = tile%lake%pars%width_sill lake_whole_area(i,j) = tile%lake%pars%whole_area lake_conn (i,j) = tile%lake%pars%connected_to_next + lake_backwater(i,j) = tile%lake%pars%backwater + lake_backwater_1(i,j) = tile%lake%pars%backwater_1 enddo call mpp_update_domains (lake_sfc_A, domain) @@ -567,16 +580,40 @@ subroutine update_river_slow(runoff, runoff_c) call mpp_update_domains (lake_conn, domain) do i=isc,iec do j=jsc,jec - i_next = River%i_tocell(i,j) - j_next = River%j_tocell(i,j) - if (lake_conn(i,j).gt.0.5 ) then - if (lake_conn(i_next,j_next).gt.0.5 .or. all_big_outlet_ctn0) then - lake_depth_sill(i,j) = lake_sfc_bot(i_next,j_next) & - +(lake_wl(i_next,j_next,1)+lake_ws(i_next,j_next,1))/DENS_H2O - endif + if (River%i_tocell(i,j) /= NO_RIVER_FLAG) then + i_next = River%i_tocell(i,j) + j_next = River%j_tocell(i,j) + else + ! to avoid indices out of bounds in the lake_sfc_A check + i_next = i; j_next=j + endif + + if (lake_backwater(i,j).gt.0.5 .and. lake_sfc_A(i,j).gt.0. .and. & + lake_sfc_A(i_next,j_next).gt.0. ) then + ! because of river backwater, lake in this cell relaxes toward level of + ! lake in next cell downstream. (river depth is still simple function + ! of discharge though.) + lake_depth_sill(i,j) = lake_sfc_bot(i_next,j_next) & + +(lake_wl(i_next,j_next,1)+lake_ws(i_next,j_next,1))/DENS_H2O + elseif (lake_backwater_1(i,j).gt.0.5) then + ! to determine depth of backwater, lake at coastal cell has base level + ! set to river depth in same cell + lake_depth_sill(i,j) = lake_depth_sill(i,j) + River%depth(i,j) + elseif (lake_conn(i,j).gt.0.5 ) then + ! for all but furthest dowstream cell of a multi-cell lake, + ! relax toward level in next cell (same lake) downstream + if (lake_conn(i_next,j_next).gt.0.5 .or. all_big_outlet_ctn0) then + lake_depth_sill(i,j) = lake_sfc_bot(i_next,j_next) & + +(lake_wl(i_next,j_next,1)+lake_ws(i_next,j_next,1))/DENS_H2O endif - enddo + elseif (river_impedes_lake) then + if (lake_width_sill(i,j).lt.0..or.river_impedes_large_lake) then + ! lake level in cell relaxes toward river level in cell + lake_depth_sill(i,j) = lake_depth_sill(i,j) + River%depth(i,j) + endif + endif enddo + enddo ! leftovers from horizontal mixing option, now gone !call mpp_update_domains (lake_T, domain) @@ -660,7 +697,7 @@ subroutine update_river_slow(runoff, runoff_c) rivr_MELT = rivr_MELT / lnd%area used = send_data (id_meltr, rivr_MELT, River%time, mask=lnd%area>0) end if - if(mod(slow_step, diag_freq) == 0) call river_diag() + if(mod(slow_step, diag_freq) == 0) call river_diag(lake_depth_sill) call mpp_clock_end(diagclock) end subroutine update_river_slow @@ -749,10 +786,10 @@ subroutine save_river_restart(timestamp) call write_data(filename,'discharge2ocean' ,discharge2ocean_next (isc:iec,jsc:jec), domain) call write_data(filename,'discharge2ocean_c',discharge2ocean_next_c(isc:iec,jsc:jec,:), domain) call write_data(filename,'Omean', River%outflowmean, domain) + call write_data(filename,'depth', River%depth, domain) end subroutine save_river_restart - - + !##################################################################### subroutine get_river_data(land_lon, land_lat, land_frac) real, intent(in) :: land_lon(isc:,jsc:) ! geographical lontitude of cell center @@ -760,8 +797,8 @@ subroutine get_river_data(land_lon, land_lat, land_frac) real, intent(in) :: land_frac(isc:,jsc:) ! land area fraction of land grid. integer :: ni, nj, i, j, siz(4), ntiles - real, dimension(:,:), allocatable :: xt, yt, frac, lake_frac, tmp - integer :: start(4), nread(4) + real, dimension(:,:), allocatable :: xt, yt, frac, glon, glat, lake_frac + integer :: nerrors ! number of errors detected during initialization ntiles = mpp_get_ntile_count(domain) @@ -771,32 +808,23 @@ subroutine get_river_data(land_lon, land_lat, land_frac) if(ni .NE. River%nlon .OR. nj .NE. River%nlat) call mpp_error(FATAL, & "river_mod: size mismatch between river grid and land grid") + allocate(glon(ni,nj), glat(ni, nj)) allocate(xt(isc:iec, jsc:jec), yt(isc:iec, jsc:jec), frac(isc:iec, jsc:jec) ) allocate(lake_frac(isc:iec, jsc:jec)) + if (ntiles == 1) then + call read_data(river_src_file, 'x', glon, no_domain=.true.) + call read_data(river_src_file, 'y', glat, no_domain=.true.) + endif call read_data(river_src_file, 'x', xt, domain) call read_data(river_src_file, 'y', yt, domain) call read_data(river_src_file, 'land_frac', frac, domain) call read_data(river_src_file, 'lake_frac', lake_frac, domain) !--- the following will be changed when the river data sets is finalized. -!!$ xt = xt*D2R; -!!$ yt = yt*D2R; xt = land_lon yt = land_lat !--- transform to radians, since land model grid use radians and compare with land grid. - -!!$ do j = jsc, jec -!!$ do i = isc, iec -!!$ if(abs(xt(i,j) - land_lon(i,j)) > epsln) call mpp_error(FATAL, & -!!$ "river_mod: longitude mismatch between river grid and land grid") -!!$ if(abs(yt(i,j) - land_lat(i,j)) > epsln) call mpp_error(FATAL, & -!!$ "river_mod: latitude mismatch between river grid and land grid") -!!$ if(abs(frac(i,j) - land_frac(i,j)) > epsln) call mpp_error(FATAL, & -!!$ "river_mod: area fraction mismatch between river grid and land grid") -!!$ end do -!!$ end do - allocate(River%lon_1d (1:ni ) ) allocate(River%lat_1d (1:nj ) ) allocate(River%lon (isc:iec, jsc:jec) ) @@ -842,22 +870,13 @@ subroutine get_river_data(land_lon, land_lat, land_frac) allocate(River%source_flux(isc:iec, jsc:jec,num_species-num_c+1:num_species)) if(ntiles == 1) then ! lat-lon grid, use actual grid location - start = 1; nread = 1 - nread(1) = ni - allocate(tmp(ni,1)) - call read_data(river_src_file, 'x', tmp, start, nread, no_domain=.TRUE.) - River%lon_1d = tmp(:,1) - deallocate(tmp) - start = 1; nread = 1 - nread(2) = nj - allocate(tmp(1,nj)) - call read_data(river_src_file, 'y', tmp, start, nread, no_domain=.TRUE.) - River%lat_1d = tmp(1,:) - deallocate(tmp) + River%lon_1d(:) = glon(:,1) + River%lat_1d(:) = glat(1,:) else ! cubic grid, use index. River%lon_1d(:) = (/ (i, i=1,River%nlon) /) River%lat_1d(:) = (/ (i, i=1,River%nlat) /) end if + deallocate(glon, glat) River%lon(:,:) = land_lon(:,:) River%lat(:,:) = land_lat(:,:) @@ -888,6 +907,36 @@ subroutine get_river_data(land_lon, land_lat, land_frac) where (River%tocell(:,:).eq. 32) River%tocell(:,:)=6 where (River%tocell(:,:).eq. 64) River%tocell(:,:)=7 where (River%tocell(:,:).eq.128) River%tocell(:,:)=8 + + nerrors = 0 + do j = jsc, jec + do i = isc, iec +!!$ if(abs(xt(i,j) - land_lon(i,j)) > epsln) call mpp_error(FATAL, & +!!$ "get_river_data: longitude mismatch between river grid and land grid") +!!$ if(abs(yt(i,j) - land_lat(i,j)) > epsln) call mpp_error(FATAL, & +!!$ "get_river_data: latitude mismatch between river grid and land grid") +!!$ if(abs(frac(i,j) - land_frac(i,j)) > epsln) call mpp_error(FATAL, & +!!$ "get_river_data: area fraction mismatch between river grid and land grid") + + ! check that river and land masks match + if ((frac(i,j)>0).neqv.(land_frac(i,j)>0)) then + call mpp_error(WARNING,'get_river_data: land and river masks do not match at '//& + trim(coordinates(i,j))) + nerrors = nerrors+1 + endif + + ! check that the rivers do not discarge in the middle of the continents + if ((River%tocell(i,j)==0).and.(land_frac(i,j)>1.0-epsln)) then + call mpp_error(WARNING, & + 'get_river_data: river discharges into a land point '& + //trim(coordinates(i,j))//' where there is no ocean') + nerrors = nerrors+1 + endif + end do + end do + + if (nerrors>0.and.stop_on_mask_mismatch) call mpp_error(FATAL,& + 'get_river_data: river/land mask-related mismatch detected during river data initialization') call read_data(river_src_file, 'basin', River%basinid, domain) where (River%basinid >0) @@ -981,6 +1030,8 @@ subroutine river_diag_init(id_lon, id_lat) missing_value=missing ) enddo + id_lake_depth_sill= register_diag_field ( mod_name, 'rv_dsill', (/id_lon, id_lat/), & + River%Time, 'effective lake sill depth', 'm', missing_value=missing ) id_outflowmean = register_diag_field ( mod_name, 'rv_Qavg', (/id_lon, id_lat/), & River%Time, 'long-time average vol. flow', 'm3/s', missing_value=missing ) id_depth = register_diag_field ( mod_name, 'rv_depth', (/id_lon, id_lat/), & @@ -1080,7 +1131,8 @@ end subroutine river_diag_init !##################################################################### - subroutine river_diag + subroutine river_diag(lake_depth_sill) + real, dimension(isc:iec,jsc:jec), intent(in) :: lake_depth_sill logical :: used ! logical for send_data real diag_factor (isc:iec,jsc:jec) real diag_factor_2(isc:iec,jsc:jec) @@ -1169,6 +1221,8 @@ subroutine river_diag diag_factor*River%disc2o(isc:iec,jsc:jec,i_species), River%Time) enddo + if (id_lake_depth_sill > 0) used = send_data (id_lake_depth_sill, & + lake_depth_sill, River%Time, mask=River%mask ) if (id_outflowmean > 0) used = send_data (id_outflowmean, & River%outflowmean(isc:iec,jsc:jec), River%Time, mask=River%mask ) if (id_width > 0) used = send_data (id_width, & @@ -1237,6 +1291,12 @@ subroutine river_stock_pe(index, value) end subroutine river_stock_pe !##################################################################### +! returns string indicating the coordiantes of the point i,j +function coordinates(i,j) result(s); character(128) :: s + integer, intent(in) :: i,j + s ='('//trim(string(i))//','//trim(string(j))//')' + if (lnd%nfaces>1) s=trim(s)//' on cubic sphere face '//string(lnd%face) +end function coordinates end module river_mod diff --git a/src/land_lad2/river/river_physics.F90 b/src/land_lad2/river/river_physics.F90 index c1167e1c9b..72d64ec4c7 100644 --- a/src/land_lad2/river/river_physics.F90 +++ b/src/land_lad2/river/river_physics.F90 @@ -34,11 +34,11 @@ module river_physics_mod use fms_mod, only : stdlog, write_version_number use fms_mod, only : close_file, check_nml_error, file_exist use diag_manager_mod,only : register_diag_field, send_data - use river_type_mod, only : river_type, Leo_Mad_trios + use river_type_mod, only : river_type, Leo_Mad_trios, NO_RIVER_FLAG use lake_mod, only : large_dyn_small_stat use lake_tile_mod, only : num_l use constants_mod, only : tfreeze, hlf, DENS_H2O - use land_debug_mod, only : set_current_point, is_watch_point + use land_debug_mod, only : set_current_point, is_watch_cell implicit none private @@ -46,13 +46,13 @@ module river_physics_mod real :: missing = -1.e8 !--- version information --------------------------------------------- - character(len=128) :: version = '$Id: river_physics.F90,v 19.0.4.2 2012/05/14 19:11:07 Zhi.Liang Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: river_physics.F90,v 20.0 2013/12/13 23:29:43 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' ! ---- public interfaces ----------------------------------------------------- - public :: river_physics_init, river_physics_step + public :: river_physics_init, river_physics_step, river_impedes_lake, river_impedes_large_lake !---------------------------------------------------------------------- real :: clw = 4218. @@ -72,12 +72,20 @@ module river_physics_mod ! behavior, where the discharge points with zero land fraction were ! missed, resulting in water non-conservation real :: ice_frac_factor = 0. + logical :: prohibit_cold_ice_outflow = .TRUE. ! default retrieves old behavior, + ! to activate bugfix, set it to FALSE + logical :: lockstep = .false. ! set to true to recognize that lake level falls + ! in lockstep with river when integrating river storage + logical :: river_impedes_lake = .false. + logical :: river_impedes_large_lake = .true. namelist /river_physics_nml/ algor, lake_outflow_frac_ceiling, & lake_sfc_w_min, storage_threshold_for_melt, & storage_threshold_for_diag, & ice_frac_from_sfc, ice_frac_factor, & - use_lake_area_bug, zero_frac_bug + use_lake_area_bug, zero_frac_bug, & + prohibit_cold_ice_outflow, lockstep, & + river_impedes_lake, river_impedes_large_lake integer, parameter, dimension(8) :: di=(/1,1,0,-1,-1,-1,0,1/) integer, parameter, dimension(8) :: dj=(/0,-1,-1,-1,0,1,1,1/) @@ -158,6 +166,7 @@ subroutine river_physics_init(River, domain, id_lon, id_lat ) !--- set up the halo update call setup_halo_update(River, domain) + River%i_tocell = NO_RIVER_FLAG; River%j_tocell = NO_RIVER_FLAG do j = jsc, jec do i = isc, iec if(River%tocell(i,j) > 0) then @@ -202,7 +211,7 @@ subroutine river_physics_step(River, cur_travel, & lake_T ! ---- local vars ---------------------------------------------------------- integer :: i, j, to_i, to_j, i_species, lev - real :: Q0, dQ_dV, avail, out_frac, qmelt + real :: Q0, dQ_dV, dh_dQ, avail, out_frac, qmelt real :: liq_to_flow, ice_to_flow, liq_this_lev, ice_this_lev real :: lake_area, h, ql, qs, qh, qt, h0, t_scale real :: influx @@ -245,11 +254,21 @@ subroutine river_physics_step(River, cur_travel, & else ! non-terminal all-land cell (possible lake), or terminal coastal cell (possible lake) if (lake_area.gt.0.) then + if (is_watch_cell()) then + write(*,*) 'lake_wl(1):', lake_wl(i,j,1) + write(*,*) 'lake_ws(1):', lake_ws(i,j,1) + write(*,*) 'lake_T (1):', lake_T (i,j,1) + endif h = (clw*lake_wl(i,j,1)+csw*lake_ws(i,j,1))*(lake_T(i,j,1)-tfreeze) lake_wl(i,j,1) = lake_wl(i,j,1) + (influx-influx_c(1))/lake_area lake_ws(i,j,1) = lake_ws(i,j,1) + influx_c(1) /lake_area lake_T (i,j,1) = tfreeze + & (h+influx_c(2)/lake_area)/(clw*lake_wl(i,j,1)+csw*lake_ws(i,j,1)) + if (is_watch_cell()) then + write(*,*) 'lake_wl(1):', lake_wl(i,j,1) + write(*,*) 'lake_ws(1):', lake_ws(i,j,1) + write(*,*) 'lake_T (1):', lake_T (i,j,1) + endif ! LAKE_SFC_C(I,J,:) = LAKE_SFC_C(I,J,:) + INFLUX_C / LAKE_AREA h0 = lake_sfc_bot(i,j) + (lake_wl(i,j,1)+lake_ws(i,j,1))/DENS_H2O & -lake_depth_sill(i,j) @@ -258,14 +277,18 @@ subroutine river_physics_step(River, cur_travel, & ! now reduce it to amount that discharges this time step if (qt.gt.0.) then IF (large_dyn_small_stat) THEN + if (is_watch_cell()) write(*,*) 'qt[1]/A', qt/lake_area if (lake_width_sill(i,j) .gt. 0.) then t_scale = lake_whole_area(i,j)/(0.9*lake_width_sill(i,j)*sqrt(h0)) qt = qt * (1. - (1.+River%dt_slow/t_scale)**(-2) ) if (.not.use_lake_area_bug) qt = qt * lake_whole_area(i,j)/lake_area endif + if (is_watch_cell()) write(*,*) 'qt[2]/A', qt/lake_area qt = min(qt, lake_outflow_frac_ceiling * lake_area & * max(0.,(lake_wl(i,j,1)+lake_ws(i,j,1)))) + if (is_watch_cell()) write(*,*) 'qt[3]/A', qt/lake_area qt = min(qt, (lake_wl(i,j,1)+lake_ws(i,j,1)-lake_sfc_w_min)*lake_area ) + if (is_watch_cell()) write(*,*) 'qt[4]/A', qt/lake_area ELSE t_scale = lake_whole_area(i,j)/(0.9*lake_width_sill(i,j)*sqrt(h0)) qt = qt * (1. - (1.+River%dt_slow/t_scale)**(-2) ) @@ -291,13 +314,13 @@ subroutine river_physics_step(River, cur_travel, & liq_to_flow = ql ice_to_flow = qs qh = 0. - if (is_watch_point()) & + if (is_watch_cell()) & write(*,*) 'ql/A,qs/A,A',ql/lake_area,qs/lake_area,lake_area do lev = 1, num_lake_lev - if (is_watch_point()) & - write(*,*) 'wl(1),ws(1),wl(l),ws(l):',& - lake_wl(i,j,1),lake_ws(i,j,1),& - lake_wl(i,j,lev),lake_ws(i,j,lev) + if (is_watch_cell() .and. lev.le.10) & + write(*,'(a,i3,99(x,a,g23.16))')'l=',lev,& + 'wl(1)=',lake_wl(i,j,1),'ws(1)=',lake_ws(i,j,1), & + 'wl(l)=',lake_wl(i,j,lev),'ws(l)=',lake_ws(i,j,lev) liq_this_lev = max(0.,min(liq_to_flow, lake_area*lake_wl(i,j,lev))) ice_this_lev = max(0.,min(ice_to_flow, lake_area*lake_ws(i,j,lev))) lake_wl(i,j,lev) = lake_wl(i,j,lev) - liq_this_lev/lake_area @@ -315,17 +338,22 @@ subroutine river_physics_step(River, cur_travel, & lake_T (i,j,lev) = tfreeze + & (h +(liq_this_lev/lake_area)*csw*(lake_T(i,j,1)-tfreeze)) & /(clw*lake_wl(i,j,lev)+csw*lake_ws(i,j,lev)) - endif - if (is_watch_point()) & - write(*,*) 'wl(1),ws(1),wl(l),ws(l):',& - lake_wl(i,j,1),lake_ws(i,j,1),& - lake_wl(i,j,lev),lake_ws(i,j,lev) + endif + if (is_watch_cell() .and. lev.le.10) & + write(*,'(a,i3,99(x,a,g23.16))')'l=',lev,& + 'wl(1)=',lake_wl(i,j,1),'ws(1)=',lake_ws(i,j,1), & + 'wl(l)=',lake_wl(i,j,lev),'ws(l)=',lake_ws(i,j,lev) if (liq_to_flow.eq.0..and.ice_to_flow.eq.0.) exit enddo River%lake_outflow (i,j) = qt River%lake_outflow_c(i,j,1) = qs River%lake_outflow_c(i,j,2) = qh endif + if (is_watch_cell()) then + write(*,*) 'lake_wl(1):', lake_wl(i,j,1) + write(*,*) 'lake_ws(1):', lake_ws(i,j,1) + write(*,*) 'lake_T (1):', lake_T (i,j,1) + endif else River%lake_outflow (i,j ) = influx River%lake_outflow_c(i,j,1) = influx_c(1) @@ -347,9 +375,20 @@ subroutine river_physics_step(River, cur_travel, & Q0=River%o_coef(i,j)*River%storage(i,j)**River%o_exp dQ_dV=River%o_exp*Q0/River%storage(i,j) endif - River%storage(i,j) = River%storage(i,j) + River%dt_slow * & + if (.not.river_impedes_lake.or..not.lockstep) then + River%storage(i,j) = River%storage(i,j) + River%dt_slow * & (River%lake_outflow(i,j)/(DENS_H2O*River%dt_slow)-Q0) & /(1.+River%dt_slow*dQ_dV) + else + if (River%storage(i,j) .le. 0.) then + dh_dQ = 0. + else + dh_dQ = River%d_coef(i,j)*River%d_exp*Q0**(River%d_exp-1) + endif + River%storage(i,j) = River%storage(i,j) + River%dt_slow * & + (River%lake_outflow(i,j)/(DENS_H2O*River%dt_slow)-Q0) & + /(1.+dQ_dV*(River%dt_slow+lake_whole_area(i,j)*dh_dQ)) + endif else if (algor.eq.'nonlin') then ! assume all inflow at start of step if (avail .gt. 0.) then River%storage(i,j) = (avail**(1.-River%o_exp) & @@ -380,7 +419,16 @@ subroutine river_physics_step(River, cur_travel, & if (avail .gt. 0.) out_frac = River%outflow(i,j)/avail River%outflow_c(i,j,:) = out_frac * (River%storage_c(i,j,:) & +River%lake_outflow_c(i,j,:)/DENS_H2O) - River%outflow_c(i,j,:) = max(River%outflow_c(i,j,:), 0.) + ! 2011/05/13 PCM: fix ice outflow temperature bug + if (prohibit_cold_ice_outflow) then + River%outflow_c(i,j,:) = max(River%outflow_c(i,j,:), 0.) + else + River%outflow_c(i,j,1) = max(River%outflow_c(i,j,1), 0.) + if(River%num_phys+1 <= River%num_species) then + River%outflow_c(i,j,River%num_phys+1:River%num_species) = & + max(River%outflow_c(i,j,River%num_phys+1:River%num_species), 0.) + endif + endif River%outflow_c(i,j,1) = min(River%outflow_c(i,j,1), River%outflow(i,j)) River%storage_c(i,j,:) = River%storage_c(i,j,:) & + River%lake_outflow_c(i,j,:)/DENS_H2O & diff --git a/src/land_lad2/river/river_type.F90 b/src/land_lad2/river/river_type.F90 index 38212520ef..262d65e890 100644 --- a/src/land_lad2/river/river_type.F90 +++ b/src/land_lad2/river/river_type.F90 @@ -26,11 +26,12 @@ module river_type_mod private !--- version information --------------------------------------------- - character(len=128) :: version = '$Id: river_type.F90,v 18.0 2010/03/02 23:37:04 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: river_type.F90,v 20.0 2013/12/13 23:29:45 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--- public interface ------------------------------------------------ public :: river_type, Leo_Mad_trios + integer, public, parameter :: NO_RIVER_FLAG = -9999 !--- public data type ------------------------------------------------ diff --git a/src/land_lad2/shared/debug.inc b/src/land_lad2/shared/debug.inc index 72d1c26c23..3c5cce0939 100644 --- a/src/land_lad2/shared/debug.inc +++ b/src/land_lad2/shared/debug.inc @@ -1,8 +1,10 @@ ! -*-f90-*- -! $Id: debug.inc,v 17.0 2009/07/21 03:02:31 fms Exp $ +! $Id: debug.inc,v 20.0 2013/12/13 23:29:47 fms Exp $ -#define __DEBUG1__(x) write(*,'(a12,99g)')#x,x -#define __DEBUG2__(x1,x2) write(*,'(99(a12,g))')#x1,x1,#x2,x2 -#define __DEBUG3__(x1,x2,x3) write(*,'(99(a12,g))')#x1,x1,#x2,x2,#x3,x3 -#define __DEBUG4__(x1,x2,x3,x4) write(*,'(99(a12,g))')#x1,x1,#x2,x2,#x3,x3,#x4,x4 -#define __DEBUG5__(x1,x2,x3,x4,x5) write(*,'(99(a12,g))')#x1,x1,#x2,x2,#x3,x3,#x4,x4,#x5,x5 +use land_debug_mod, only : dpri + +#define __DEBUG1__(x) call dpri(#x,x);write(*,*) +#define __DEBUG2__(x1,x2) call dpri(#x1,x1);call dpri(#x2,x2);write(*,*) +#define __DEBUG3__(x1,x2,x3) call dpri(#x1,x1);call dpri(#x2,x2);call dpri(#x3,x3);write(*,*) +#define __DEBUG4__(x1,x2,x3,x4) call dpri(#x1,x1);call dpri(#x2,x2);call dpri(#x3,x3);call dpri(#x4,x4);write(*,*) +#define __DEBUG5__(x1,x2,x3,x4,x5) call dpri(#x1,x1);call dpri(#x2,x2);call dpri(#x3,x3);call dpri(#x4,x4);call dpri(#x5,x5);write(*,*) diff --git a/src/land_lad2/shared/land_debug.F90 b/src/land_lad2/shared/land_debug.F90 index 6fb9b76d88..4cf1cb8d07 100644 --- a/src/land_lad2/shared/land_debug.F90 +++ b/src/land_lad2/shared/land_debug.F90 @@ -7,14 +7,12 @@ module land_debug_mod #endif use fms_mod, only: & - error_mesg, file_exist, check_nml_error, stdlog, & - write_version_number, close_file, mpp_pe, mpp_npes, mpp_root_pe, FATAL, NOTE + error_mesg, file_exist, check_nml_error, stdlog, write_version_number, & + close_file, mpp_pe, mpp_npes, mpp_root_pe, string, FATAL, WARNING, NOTE use time_manager_mod, only : & - get_date + time_type, get_date use grid_mod, only: & get_grid_ntiles -use land_data_mod, only : & - lnd ! NOTE TO SELF: the "!$" sentinels are not comments: they are compiled if OpenMP ! support is turned on @@ -35,22 +33,44 @@ module land_debug_mod public :: get_watch_point public :: check_temp_range +public :: check_var_range +public :: check_conservation + +public :: dpri + +interface dpri + module procedure debug_printout_r0d + module procedure debug_printout_i0d + module procedure debug_printout_l0d + module procedure debug_printout_r1d +end interface dpri + ! ==== module constants ====================================================== character(len=*), parameter, private :: & module_name = 'land_debug',& - version = '$Id: land_debug.F90,v 19.0 2012/01/06 20:41:29 fms Exp $',& - tagname = '$Name: siena_201207 $' + version = '$Id: land_debug.F90,v 20.0 2013/12/13 23:29:49 fms Exp $',& + tagname = '$Name: tikal $' ! ==== module variables ====================================================== integer, allocatable :: current_debug_level(:) integer :: mosaic_tile = 0 integer, allocatable :: curr_i(:), curr_j(:), curr_k(:) +character(128) :: fixed_format !---- namelist --------------------------------------------------------------- -integer :: watch_point(4)=(/0,0,0,1/) ! coordinates of the point of interest, i,j,tile,mosaic_tile +integer :: watch_point(4)=(/0,0,0,1/) ! coordinates of the point of interest, + ! i,j,tile,mosaic_tile real :: temp_lo = 120.0 ! lower limit of "reasonable" temperature range, deg K real :: temp_hi = 373.0 ! upper limit of "reasonable" temperature range, deg K -namelist/land_debug_nml/ watch_point, temp_lo, temp_hi +logical :: print_hex_debug = .FALSE. ! if TRUE, hex representation of debug + ! values is also printed +integer :: label_len = 12 ! minimum length of text labels for debug output +logical :: trim_labels = .FALSE. ! if TRUE, the length of text labels in debug + ! printout is never allowed to exceed label_len, resulting in + ! trimming of the labels. Set it to TRUE to match earlier debug + ! printout +namelist/land_debug_nml/ watch_point, temp_lo, temp_hi, & + print_hex_debug, label_len, trim_labels contains @@ -92,6 +112,10 @@ subroutine land_debug_init() allocate(curr_i(max_threads),curr_j(max_threads),curr_k(max_threads)) allocate(current_debug_level(max_threads)) current_debug_level(:) = 0 + + ! construct the format string for output + fixed_format = '(a'//trim(string(label_len))//',99g23.16)' + end subroutine land_debug_init ! ============================================================================ @@ -190,28 +214,137 @@ end subroutine get_watch_point ! ============================================================================ ! checks if the temperature within reasonable range, and prints a message ! if it isn't -subroutine check_temp_range(temp, tag, varname) +subroutine check_temp_range(temp, tag, varname, time) real, intent(in) :: temp ! temperature to check character(*), intent(in) :: tag ! tag to print character(*), intent(in) :: varname ! name of the variable for printout + type(time_type), intent(in) :: time ! current time + + call check_var_range(temp,temp_lo,temp_hi,tag,varname,time) +end subroutine + +! ============================================================================ +! checks if the value is within specified range, and prints a message +! if it isn't +subroutine check_var_range(value, lo, hi, tag, varname, time, severity) + real, intent(in) :: value ! value to check + real, intent(in) :: lo,hi ! lower and upper bounds of acceptable range + character(*), intent(in) :: tag ! tag to print + character(*), intent(in) :: varname ! name of the variable for printout + type(time_type), intent(in) :: time ! current time + integer, intent(in), optional :: severity ! severity of the non-conservation error: + ! Can be WARNING, FATAL, or negative. Negative means check is not done. ! ---- local vars integer :: y,mo,d,h,m,s ! components of date integer :: thread + character(512) :: message + integer :: severity_ + + severity_=WARNING + if (present(severity)) severity_=severity + if (severity_<0) return - if(temp_lo 0) then + ifld0 = id0-BASE_TILED_FIELD_ID + if (ifld0<1.or.ifld0>n_fields) & + call error_mesg(module_name, 'incorrect index ifld0 '//string(ifld0)//& + ' in definition of tiled diag field alias "'//& + trim(module_name)//'/'//trim(field_name)//'"', FATAL) + id1 = reg_field(static, module_name, field_name, init_time, axes, long_name, & + units, missing_value, range, op=op, offset=fields(ifld0)%offset) + if (id1>0) then + ifld1 = id1-BASE_TILED_FIELD_ID + ! check that sizes of the fields are identical + if (fields(ifld0)%size/=fields(ifld1)%size) & + call error_mesg(module_name, 'sizes of diag field "'// & + trim(fields(ifld0)%module)//'/'//trim(fields(ifld0)%name)// & + '" and its alias "'//trim(module_name)//'/'//trim(field_name)//& + '" are not the same', FATAL) + ! check that "static" status of the fields is the same + if(fields(ifld0)%static.and..not.fields(ifld1)%static) & + call error_mesg(module_name, & + 'attempt to register non-static alias"'// & + trim(module_name)//'/'//trim(field_name)// & + '" of static field "'// & + trim(fields(ifld0)%module)//'/'//trim(fields(ifld0)%name)//'"',& + FATAL) + if(.not.fields(ifld0)%static.and.fields(ifld1)%static) & + call error_mesg(module_name, & + 'attempt to register static alias"'// & + trim(module_name)//'/'//trim(field_name)// & + '" of non-static field "'// & + trim(fields(ifld0)%module)//'/'//trim(fields(ifld0)%name)//'"',& + FATAL) + + ! copy alias field from the original into the alias, to preserve the chain + fields(ifld1)%alias = fields(ifld0)%alias + ! update alias field in the head of alias chain + fields(ifld0)%alias = ifld1 + endif + else + ! the "main" field has not been registered, so simply redister the alias + ! as a diag field + id0 = reg_field(static, module_name, field_name, init_time, axes, long_name, & + units, missing_value, range, op=op) + endif +end subroutine + ! ============================================================================ ! provides unified interface for registering a diagnostic field with full set ! of selectors function reg_field(static, module_name, field_name, init_time, axes, & - long_name, units, missing_value, range, require, op) result(id) + long_name, units, missing_value, range, require, op, offset) result(id) integer :: id @@ -195,6 +305,7 @@ function reg_field(static, module_name, field_name, init_time, axes, & real, intent(in), optional :: range(2) logical, intent(in), optional :: require integer, intent(in), optional :: op + integer, intent(in), optional :: offset ! ---- local vars integer, pointer :: diag_ids(:) ! ids returned by FMS diag manager for each selector @@ -205,11 +316,9 @@ function reg_field(static, module_name, field_name, init_time, axes, & type(tile_selector_type) :: sel ! ---- global vars: n_fields, fields, current_offset -- all used and updated -#ifdef USE_LOG_DIAG_FIELD_INFO ! log diagnostic field information call log_diag_field_info ( module_name, trim(field_name), axes, long_name, units,& missing_value, range, dynamic=.not.static ) -#endif ! go through all possible selectors and try to register a diagnostic field ! with the name derived from field name and selector; if any of the ! registrations succeeds, return a tiled field id, otherwise return 0. @@ -245,7 +354,11 @@ function reg_field(static, module_name, field_name, init_time, axes, & ! set the array of FMS diagnostic field IDs for each selector fields(id)%ids => diag_ids ! set the field offset in the diagnostic buffers - fields(id)%offset = current_offset + if (present(offset)) then + fields(id)%offset = offset + else + fields(id)%offset = current_offset + endif ! calculate field size per tile and increment current offset to ! reserve space in per-tile buffers. We assume that the first two axes ! are horizontal coordinates, so their size is not taken into account @@ -253,7 +366,10 @@ function reg_field(static, module_name, field_name, init_time, axes, & do i = 3, size(axes(:)) fields(id)%size = fields(id)%size * get_axis_length(axes(i)) enddo - current_offset = current_offset + fields(id)%size + ! if offset is present in the list of the arguments, it means that we don't + ! want to increase the current_offset -- this is an alias field + if (.not.present(offset)) & + current_offset = current_offset + fields(id)%size ! store the code of the requested tile aggregation operation if(present(op)) then fields(id)%op = op @@ -266,6 +382,7 @@ function reg_field(static, module_name, field_name, init_time, axes, & fields(id)%n_sends = 0 ! store the name of the field -- for now, only to be able to see what it is ! in the debugger + fields(id)%module=module_name fields(id)%name=field_name ! increment the field id by some (large) number to distinguish it from the ! IDs of regular FMS diagnostic fields @@ -312,19 +429,11 @@ function reg_field_set(static, sel, module_name, field_name, axes, init_time, & ! try registering diagnostic field with FMS diagnostic manager. if (static) then id = register_static_field ( module_name, fname, & -#ifdef USE_LOG_DIAG_FIELD_INFO axes, lname, units, missing_value, range, require, do_not_log=.TRUE. ) -#else - axes, lname, units, missing_value, range, require ) -#endif else id = register_diag_field ( module_name, fname, & axes, init_time, lname, units, missing_value, range, & -#ifdef USE_LOG_DIAG_FIELD_INFO mask_variant=.true., do_not_log=.TRUE. ) -#else - mask_variant=.true. ) -#endif endif end function @@ -354,6 +463,11 @@ subroutine send_tile_data_0d(id, x, buffer) ! increment sent data counter fields(i)%n_sends = fields(i)%n_sends + 1 + ! increment sent data counter in all aliases + do while(fields(i)%alias>0) + i=fields(i)%alias + fields(i)%n_sends = fields(i)%n_sends + 1 + enddo end subroutine ! ============================================================================ @@ -379,6 +493,11 @@ subroutine send_tile_data_1d(id, x, buffer) ! increment sent data counter fields(i)%n_sends = fields(i)%n_sends + 1 + ! increment sent data counter in all aliases + do while(fields(i)%alias>0) + i=fields(i)%alias + fields(i)%n_sends = fields(i)%n_sends + 1 + enddo end subroutine ! NOTE: 2-d fields can be handled similarly to 1-d with reshape diff --git a/src/land_lad2/shared/land_tile_diag_buff.F90 b/src/land_lad2/shared/land_tile_diag_buff.F90 index 66104ac952..19487498b8 100644 --- a/src/land_lad2/shared/land_tile_diag_buff.F90 +++ b/src/land_lad2/shared/land_tile_diag_buff.F90 @@ -22,7 +22,7 @@ module tile_diag_buff_mod integer, parameter :: MIN_DIAG_BUFF_SIZE = 1 character(len=*), parameter :: & version = '$Id: land_tile_diag_buff.F90,v 17.0 2009/07/21 03:02:39 fms Exp $', & - tagname = '$Name: siena_201207 $' + tagname = '$Name: tikal $' contains ! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- diff --git a/src/land_lad2/shared/land_tile_diag_sel.F90 b/src/land_lad2/shared/land_tile_diag_sel.F90 index 91c7f733d6..b5f227ff35 100644 --- a/src/land_lad2/shared/land_tile_diag_sel.F90 +++ b/src/land_lad2/shared/land_tile_diag_sel.F90 @@ -25,7 +25,7 @@ module land_tile_selectors_mod character(len=*), parameter :: & module_name = 'land_tile_selectors_mod', & version = '$Id: land_tile_diag_sel.F90,v 18.0 2010/03/02 23:37:10 fms Exp $', & - tagname = '$Name: siena_201207 $' + tagname = '$Name: tikal $' integer, parameter :: SEL_LEN = 16 ! max length of the selector name integer, parameter :: SEL_LONG_NAME_LEN = 128 ! max name of the selector long name diff --git a/src/land_lad2/shared/land_tile_io.F90 b/src/land_lad2/shared/land_tile_io.F90 index d38a5cda5b..0d559f713f 100644 --- a/src/land_lad2/shared/land_tile_io.F90 +++ b/src/land_lad2/shared/land_tile_io.F90 @@ -10,7 +10,7 @@ module land_tile_io_mod use nf_utils_mod, only : nfu_inq_dim, nfu_inq_var, nfu_def_dim, nfu_def_var, & nfu_get_var, nfu_put_att -use land_io_mod, only : print_netcdf_error, read_field +use land_io_mod, only : print_netcdf_error, read_field, input_buf_size use land_tile_mod, only : land_tile_type, land_tile_list_type, land_tile_enum_type, & first_elmt, tail_elmt, next_elmt, current_tile, operator(/=), & get_elmt_indices @@ -60,21 +60,21 @@ module land_tile_io_mod ! ==== module constants ====================================================== character(len=*), parameter :: & module_name = 'land_tile_io_mod', & - version = '$Id: land_tile_io.F90,v 19.0.6.2 2012/05/14 19:16:06 Zhi.Liang Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: land_tile_io.F90,v 20.0 2013/12/13 23:29:59 fms Exp $', & + tagname = '$Name: tikal $' ! name of the "compressed" dimension (and dimension variable) in the output ! netcdf files -- that is, the dimensions written out using compression by ! gathering, as described in CF conventions. See subroutines write_tile_data, ! read_tile_data, read_unpack_tile_data, write_cohort_data character(len=*), parameter :: tile_index_name = 'tile_index' -integer, parameter :: INPUT_BUF_SIZE=1024 ! size of the input buffer for tile input ! ==== NetCDF declarations =================================================== include 'netcdf.inc' #define __NF_ASRT__(x) call print_netcdf_error((x),module_name,__LINE__) + contains ! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ! ============================================================================= @@ -141,6 +141,8 @@ subroutine create_tile_out_file_idx(ncid, name, glon, glat, tidx, tile_dim_lengt integer, allocatable :: tidx2(:) ! array of tile indices from all PEs in io_domain integer :: p ! io_domain PE iterator integer :: k ! current index in tidx2 array for receive operation + integer :: i + integer :: iret ! form the full name of the file call get_instance_filename(trim(name), full_name) @@ -190,7 +192,8 @@ subroutine create_tile_out_file_idx(ncid, name, glon, glat, tidx, tile_dim_lengt __NF_ASRT__(nfu_def_dim(ncid,'lon' ,glon(:) ,'longitude','degrees_east')) __NF_ASRT__(nfu_def_dim(ncid,'lat' ,glat(:) ,'latitude','degrees_north')) - __NF_ASRT__(nfu_def_dim(ncid,'tile',tile_dim_length)) + iret=nfu_def_dim(ncid,'tile',(/(p,p=1,tile_dim_length)/),'tile number within grid cell') + __NF_ASRT__(iret) ! the size of tile dimension really does not matter for the output, but it does ! matter for uncompressing utility, since it uses it as a size of the array to ! unpack to @@ -359,7 +362,7 @@ end subroutine fptr __NF_ASRT__(nfu_inq_dim(ncid,dimids(1),idxname)) __NF_ASRT__(nfu_inq_var(ncid,idxname,id=idxid)) ! allocate input buffers for compression index and the variable - bufsize = min(INPUT_BUF_SIZE,dimlen(1)) + bufsize = min(input_buf_size,dimlen(1)) allocate(idx(bufsize),x1d(bufsize)) ! read the input buffer-by-buffer do j = 1,dimlen(1),bufsize @@ -368,7 +371,7 @@ end subroutine fptr ! read the data __NF_ASRT__(nf_get_vara_int(ncid,varid,(/j/),(/min(bufsize,dimlen(1)-j+1)/),x1d)) ! distribute the data over the tiles - do i = 1, min(INPUT_BUF_SIZE,dimlen(1)-j+1) + do i = 1, min(input_buf_size,dimlen(1)-j+1) call get_tile_by_idx(idx(i),lnd%nlon,lnd%nlat,lnd%tile_map,& lnd%is,lnd%js, tileptr) call fptr(tileptr, ptr) @@ -415,7 +418,7 @@ end subroutine fptr __NF_ASRT__(nfu_inq_dim(ncid,dimids(1),idxname)) __NF_ASRT__(nfu_inq_var(ncid,idxname,id=idxid)) ! allocate input buffers for compression index and the variable - bufsize=min(INPUT_BUF_SIZE,dimlen(1)) + bufsize=min(input_buf_size,dimlen(1)) allocate(idx(bufsize),x1d(bufsize)) ! read the input buffer-by-buffer do j = 1,dimlen(1),bufsize @@ -471,7 +474,7 @@ end subroutine fptr __NF_ASRT__(nfu_inq_dim(ncid,dimids(1),idxname)) __NF_ASRT__(nfu_inq_var(ncid,idxname,id=idxid)) ! allocate input buffers for compression index and the variable - bufsize=min(INPUT_BUF_SIZE,dimlen(1)) + bufsize=min(input_buf_size,dimlen(1)) allocate(idx(bufsize),x1d(bufsize*dimlen(2))) ! read the input buffer-by-buffer do j = 1,dimlen(1),bufsize @@ -531,7 +534,7 @@ end subroutine fptr __NF_ASRT__(nfu_inq_dim(ncid,dimids(1),idxname)) __NF_ASRT__(nfu_inq_var(ncid,idxname,id=idxid)) ! allocate input buffers for compression index and the variable - bufsize=min(INPUT_BUF_SIZE,dimlen(1)) + bufsize=min(input_buf_size,dimlen(1)) allocate(idx(bufsize),x1d(bufsize)) ! read the input buffer-by-buffer do j = 1,dimlen(1),bufsize diff --git a/src/land_lad2/shared/land_utils.F90 b/src/land_lad2/shared/land_utils.F90 index 7816a3744f..1048cbaffb 100644 --- a/src/land_lad2/shared/land_utils.F90 +++ b/src/land_lad2/shared/land_utils.F90 @@ -13,7 +13,7 @@ module land_utils_mod ! ==== module constants ====================================================== character(len=*), parameter :: & version = '$Id: land_utils.F90,v 17.0 2009/07/21 03:02:46 fms Exp $', & - tagname = '$Name: siena_201207 $' + tagname = '$Name: tikal $' contains diff --git a/src/land_lad2/shared/nf_utils/nf_utils.F90 b/src/land_lad2/shared/nf_utils/nf_utils.F90 index 473ae5e5de..852f7fab3d 100644 --- a/src/land_lad2/shared/nf_utils/nf_utils.F90 +++ b/src/land_lad2/shared/nf_utils/nf_utils.F90 @@ -25,6 +25,6 @@ module nf_utils_mod ! ==== module constants ====================================================== character(len=*), parameter :: & version = '$Id: nf_utils.F90,v 17.0 2009/07/21 03:02:54 fms Exp $', & - tagname = '$Name: siena_201207 $' + tagname = '$Name: tikal $' end module nf_utils_mod diff --git a/src/land_lad2/shared/nf_utils/nfc.F90 b/src/land_lad2/shared/nf_utils/nfc.F90 index db6135d3bd..9a9ede8239 100644 --- a/src/land_lad2/shared/nf_utils/nfc.F90 +++ b/src/land_lad2/shared/nf_utils/nfc.F90 @@ -33,8 +33,8 @@ module nfc_mod #undef __INTERFACE_SECTION__ ! ---- module constants ------------------------------------------------------ character(len=*), parameter :: & - version = '$Id: nfc.F90,v 17.0 2009/07/21 03:02:50 fms Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: nfc.F90,v 20.0 2013/12/13 23:30:40 fms Exp $', & + tagname = '$Name: tikal $' ! ---- private type - used to hold dimension/packing information during unpacking ! (see get_compressed_var_i_r8) @@ -160,6 +160,7 @@ function inq_compressed_var_i(ncid, vid, name, xtype, ndims, dimids, dimlens, & integer :: nd0, dids0(NF_MAX_VAR_DIMS),dlens0(NF_MAX_VAR_DIMS) integer :: nd1, dids1(NF_MAX_VAR_DIMS),dlens1(NF_MAX_VAR_DIMS) integer :: i,n,unlimdim,vsize,rsize + logical :: compressed iret = nfu_inq_var(ncid, vid, name, xtype, nd0, dids0, dlens0, natts, & is_dim, has_records, varsize, recsize, nrec) @@ -167,8 +168,11 @@ function inq_compressed_var_i(ncid, vid, name, xtype, ndims, dimids, dimlens, & nd1=1 if(present(is_compressed)) is_compressed=.false. do i = 1, nd0 - if(nfu_inq_compressed_dim(ncid,dids0(i),& - ndims=n,dimids=dids1(nd1:),dimlens=dlens1(nd1:))==NF_NOERR) then + __NF_TRY__(nfu_inq_dim(ncid,dids0(i),is_compressed=compressed),iret,7) + if (compressed) then + iret = nfu_inq_compressed_dim(ncid,dids0(i),& + ndims=n,dimids=dids1(nd1:),dimlens=dlens1(nd1:)) + if (iret/=NF_NOERR) goto 7 nd1 = nd1+n if(present(is_compressed)) is_compressed=.true. else diff --git a/src/land_lad2/shared/nf_utils/nfu.F90 b/src/land_lad2/shared/nf_utils/nfu.F90 index 880adfeab8..297a3cf441 100644 --- a/src/land_lad2/shared/nf_utils/nfu.F90 +++ b/src/land_lad2/shared/nf_utils/nfu.F90 @@ -65,8 +65,8 @@ module nfu_mod ! ---- module constants ------------------------------------------------------ character(len=*), parameter :: & module_name = 'nf_utils_mod', & - version = '$Id: nfu.F90,v 17.0 2009/07/21 03:02:52 fms Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: nfu.F90,v 20.0 2013/12/13 23:30:42 fms Exp $', & + tagname = '$Name: tikal $' ! ---- module types ---------------------------------------------------------- type nfu_validtype @@ -87,36 +87,54 @@ module nfu_mod #define __BODY_SECTION__ ! ============================================================================ -function inq_dim_n(ncid, name, len, dimid) result (iret) +function inq_dim_n(ncid, name, len, dimid, is_compressed) result (iret) integer :: iret integer, intent(in) :: ncid character(*),intent(in) :: name integer, intent(out), optional :: len integer, intent(out), optional :: dimid + logical, intent(out), optional :: is_compressed - integer :: id + integer :: id,varid,attlen __NF_TRY__(nf_inq_dimid(ncid,name, id),iret,7) if(present(dimid))dimid = id if(present(len)) & iret = nf_inq_dimlen(ncid,id,len) + if (present(is_compressed)) then + is_compressed = .FALSE. + if (nf_inq_varid(ncid,name,varid)==NF_NOERR) then + is_compressed=(nf_inq_attlen(ncid,varid,'compress',attlen)==NF_NOERR) + endif + endif 7 return end function ! ============================================================================ -function inq_dim_i(ncid, id, name, len) result (iret) +function inq_dim_i(ncid, id, name, len, is_compressed) result (iret) integer :: iret integer, intent(in) :: ncid integer, intent(in) :: id character(*), intent(out), optional :: name integer , intent(out), optional :: len + logical , intent(out), optional :: is_compressed + + character(len=NF_MAX_NAME) :: dname + integer :: varid,attlen + __NF_TRY__(nf_inq_dimname(ncid,id,dname),iret,7) if(present(name)) then - __NF_TRY__(nf_inq_dimname(ncid,id,name),iret,7) + name=dname endif if(present(len)) then __NF_TRY__(nf_inq_dimlen(ncid,id,len),iret,7) end if + if (present(is_compressed)) then + is_compressed = .FALSE. + if (nf_inq_varid(ncid,dname,varid)==NF_NOERR) then + is_compressed=(nf_inq_attlen(ncid,varid,'compress',attlen)==NF_NOERR) + endif + endif 7 return end function @@ -707,13 +725,13 @@ function nfu_validtype2ascii(v) result (string) type(nfu_validtype), intent(in) :: v if(v%hasmin.and.v%hasmax) then - write(string,'("[",g,",",g,"]")') v%min, v%max + write(string,'("[",g23.16,",",g23.16,"]")') v%min, v%max else if (v%hasmin) then - write(string,'("[",g,")")') v%min + write(string,'("[",g23.16,")")') v%min else if (v%hasmax) then - write(string,'("(",g,"]")') v%max + write(string,'("(",g23.16,"]")') v%max else - write(string,'("/=",g)') v%min + write(string,'("/=",g23.16)') v%min endif end function diff --git a/src/land_lad2/shared/sphum.F90 b/src/land_lad2/shared/sphum.F90 index 17a95f2696..bf13eb62cf 100644 --- a/src/land_lad2/shared/sphum.F90 +++ b/src/land_lad2/shared/sphum.F90 @@ -10,8 +10,8 @@ module sphum_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & - version = '$Id: sphum.F90,v 15.0 2007/08/14 18:48:28 fms Exp $', & - tagname = '$Name: siena_201207 $' ,& + version = '$Id: sphum.F90,v 20.0 2013/12/13 23:30:34 fms Exp $', & + tagname = '$Name: tikal $' ,& module_name = 'vegn' real, parameter :: d622 = rdgas/rvgas real, parameter :: d378 = 1.0-d622 @@ -30,7 +30,7 @@ subroutine qscomp(T, p, qsat, DqsatDT ) if(120.0 null() ! table cells +end type + +! ---- generic procedure interface +interface add_row + module procedure add_row_real, add_row_integer + module procedure add_row_logical, add_row_character +end interface add_row + +contains + + +! ============================================================================== +! deallocats all table data and resets the counters +subroutine dealloc(t) + type(table_printer_type), intent(inout) :: t + + if (associated(t%table)) deallocate(t%table) + t%table => null() ; t%nr = 0 ; t%nc = 0 +end subroutine + + +! ============================================================================== +! sets the column headers and resets the table data +subroutine init_with_headers(t,names) + type(table_printer_type), intent(inout) :: t + character(*), intent(in) :: names(:) + + call dealloc(t) + t%nc = size(names) + call realloc_table(t) + t%table(1:,0) = names(:) +end subroutine + + +! ============================================================================== +! increases a number of row storage. Private procedure. +subroutine realloc_table(t) + type(table_printer_type), intent(inout) :: t + + character(32), pointer :: ptr(:,:) + integer :: i,j,n + + ! reallocate data + n = 0 ; if (associated(t%table)) n = ubound(t%table,2) + if (t%nr >= n) then + allocate(ptr(0:t%nc,0:t%nr+N_ROWS_INCREMENT)) + forall (i=lbound(ptr,1):ubound(ptr,1), j=lbound(ptr,2):ubound(ptr,2)) ptr(i,j) = '' + if (associated(t%table)) then + ptr(:,0:t%nr) = t%table(:,0:t%nr) + deallocate(t%table) + endif + t%table => ptr + endif +end subroutine + + +! ============================================================================== +! adds a row of real numbers to the table +subroutine add_row_real(t, name, data, format) + type(table_printer_type), intent(inout) :: t + character(*), intent(in) :: name ! name of the row + real , intent(in) :: data(:) ! table data + character(*), intent(in), optional :: format + + character(32) :: fcell + integer :: i + + call realloc_table(t) + + fcell = DEFAULT_FORMAT; if (present(format)) fcell=format + t%nr = t%nr + 1 + t%table(0,t%nr) = name + do i = 1, min(t%nc,size(data)) + write(t%table(i,t%nr),fcell) data(i) + t%table(i,t%nr) = adjustl(t%table(i,t%nr)) + enddo +end subroutine add_row_real + + +! ============================================================================== +! adds a row of integer numbers to the table +subroutine add_row_integer(t, name, data, format) + type(table_printer_type), intent(inout) :: t + character(*), intent(in) :: name ! name of the row + integer , intent(in) :: data(:) ! table data + character(*), intent(in), optional :: format + + character(32) :: fcell + integer :: i + + call realloc_table(t) + + fcell = DEFAULT_FORMAT; if (present(format)) fcell=format + t%nr = t%nr + 1 + t%table(0,t%nr) = name + do i = 1, min(t%nc,size(data)) + write(t%table(i,t%nr),fcell) data(i) + t%table(i,t%nr) = adjustl(t%table(i,t%nr)) + enddo +end subroutine add_row_integer + + +! ============================================================================== +! adds a row of logical values to the table +subroutine add_row_logical(t, name, data, format) + type(table_printer_type), intent(inout) :: t + character(*), intent(in) :: name ! name of the row + logical , intent(in) :: data(:) ! table data + character(*), intent(in), optional :: format + + character(32) :: fcell + integer :: i + + call realloc_table(t) + + fcell = DEFAULT_FORMAT; if (present(format)) fcell=format + t%nr = t%nr + 1 + t%table(0,t%nr) = name + do i = 1, min(t%nc,size(data)) + write(t%table(i,t%nr),fcell) data(i) + t%table(i,t%nr) = adjustl(t%table(i,t%nr)) + enddo +end subroutine add_row_logical + + +! ============================================================================== +! adds a row of character names +subroutine add_row_character(t, name, data) + type(table_printer_type), intent(inout) :: t + character(*), intent(in) :: name ! name of the row + character(*), intent(in) :: data(:) ! row data + + integer :: i + + call realloc_table(t) + t%nr = t%nr + 1 + t%table(0,t%nr) = name + do i = 1, min(t%nc,size(data)) + t%table(i,t%nr) = adjustl(data(i)) + enddo +end subroutine add_row_character + +! ============================================================================= +! prints the table +subroutine print(t,unit,max_width,cell_width,head_width,transposed) + type(table_printer_type), intent(in) :: t + integer, intent(in), optional :: unit ! unit number for i/o + integer, intent(in), optional :: max_width ! maximum width of the cell + integer, intent(in), optional :: cell_width ! width of each cell + integer, intent(in), optional :: head_width ! width of the row header + logical, intent(in), optional :: transposed ! if true, the table is transposed + + integer :: unit_ + integer :: max_width_, head_width_, cell_width_ + logical :: transposed_ + integer :: cells_per_line, k + + unit_ = 6 ; if (present(unit))unit_ = unit + cell_width_ = DEFAULT_CELL_WIDTH ; if (present(cell_width)) cell_width_ = cell_width + head_width_ = cell_width_ ; if (present(head_width)) head_width_ = head_width + max_width_ = DEFAULT_TABLE_WIDTH ; if (present(max_width)) max_width_ = max_width + transposed_ = .FALSE. ; if (present(transposed)) transposed_ = transposed + + ! calculate max number of cells per line + cells_per_line = (max_width_-head_width_)/(cell_width_+1) + + if (transposed_) then + do k = 1, t%nr, cells_per_line + call print_table_section(transpose(t%table),& + k,min(t%nr,k+cells_per_line-1),1,t%nc,& + unit_,cell_width_,head_width_) + enddo + else + do k = 1, t%nc, cells_per_line + call print_table_section(t%table,& + k,min(t%nc,k+cells_per_line-1),1,t%nr,& + unit_,cell_width_,head_width_) + enddo + endif + +end subroutine print + +! ============================================================================= +subroutine print_table_section(table,is,ie,js,je,unit,cell_width,head_width) + character(*) :: table(0:,0:) + integer, intent(in) :: is,ie,js,je ! boundaries of the chunk + integer, intent(in) :: unit ! unit number for i/o + integer, intent(in) :: cell_width ! width of each cell + integer, intent(in) :: head_width ! width of the row header + + integer :: i,j,k + integer :: cells_per_line + character(128) :: fhead,fcell,ftop,fmid,fbot! format strings + character(32) :: l, cell + character :: toprule,midrule,botrule,fieldsep + + ! TODO: make all 4 things below optional arguments + toprule = '=' + midrule = '-' + botrule = '=' + fieldsep = ' ' + + ! create formats for the cells, and for the row headers + write(l,*)cell_width; fcell = '(a'//trim(adjustl(l))//')' + write(l,*)head_width; fhead = '(a'//trim(adjustl(l))//')' + + ! create formats for table separator + write(l,*)head_width+(cell_width+1)*(ie-is+1) + l = adjustl(l) + ftop = "("//trim(l)//"('"//toprule//"'))" + fmid = "("//trim(l)//"('"//midrule//"'))" + fbot = "("//trim(l)//"('"//botrule//"'))" + + ! print table header + write(unit,ftop) ! top-ruler + write(unit,fhead,advance='no')'' + do i = is,ie + write(unit,'(a1)',advance='no') fieldsep + write(unit,fcell,advance='no') table(i,0) + enddo + write(unit,*) ! go to the next line + write(unit,fmid) ! mid-ruler + ! print table data + do j = js,je + write(unit,fhead,advance='no')table(0,j) + do i = is,ie + write(unit,'(a1)',advance='no') fieldsep + if (trim(table(i,j))=='' ) then + cell = '----' + else if (len_trim(table(i,j))>cell_width) then + cell = repeat('*',cell_width) + else + cell = table(i,j) + endif + write(unit,fcell,advance='no') cell + enddo + write(unit,*) ! go to the next line + enddo + write(unit,fbot) ! bottom-ruler + +end subroutine print_table_section + +end module + +! ############################################################################ +#if 0 +program test + use table_printer_mod + + type(table_printer_type) :: t + + call init_with_headers(t,(/'a','b','c','d','e'/)) + call add_row(t,'test1',(/1.0,2.0,3.0,4.0,5.0/)) + call add_row(t,'test2',(/3.5,4.444444,5.6666666e33,1.0,1.0/),format='(e12.4)') + call add_row(t,'test3',(/4.444444,5.6666666e33,77777.0,2.0,2.0/)) + call add_row(t,'test I',(/11,12,13,14,15/)) + call add_row(t,'test L',(/.TRUE.,.FALSE.,.TRUE.,.TRUE.,.FALSE./)) + call add_row(t,'test Char',(/'a1','b2','c3','d4','e5'/)) + call print(t) + write(*,*) + call print(t,max_width=70) + write(*,*) + call print(t,unit=33,max_width=80,head_width=10) + call print(t,unit=33,max_width=80,head_width=10,transposed=.TRUE.) + write(*,*) + call print(t,head_width=10,cell_width=5) + write(*,*) + call print(t,cell_width=10) + write(*,*) + call print(t,cell_width=10,transposed=.TRUE.) + + call init_with_headers(t,(/' x','y ','z ','xx','yy','zz'/)) + call add_row(t,'test10',(/1.0,2.0,3.0,4.0,5.0,6.0/)) + call add_row(t,'test11',(/1.0,2.0,3.0,4.0,5.0/)) + call print(t,head_width=10) + call print(t,head_width=10,transposed=.TRUE.) + call dealloc(t) + +end program +#endif \ No newline at end of file diff --git a/src/land_lad2/snow/snow.F90 b/src/land_lad2/snow/snow.F90 index d928459321..e3dd93f76d 100644 --- a/src/land_lad2/snow/snow.F90 +++ b/src/land_lad2/snow/snow.F90 @@ -16,7 +16,7 @@ module snow_mod use land_constants_mod, only : NBANDS use snow_tile_mod, only : & - snow_tile_type, snow_prog_type, read_snow_data_namelist, & + snow_tile_type, read_snow_data_namelist, & snow_data_thermodynamics, snow_data_area, snow_data_radiation, snow_data_diffusion, & snow_data_hydraulics, max_lev, cpw, clw, csw @@ -51,8 +51,8 @@ module snow_mod ! ==== module variables ====================================================== character(len=*), parameter, private :: & module_name = 'snow_mod' ,& - version = '$Id: snow.F90,v 19.0 2012/01/06 20:42:42 fms Exp $' ,& - tagname = '$Name: siena_201207 $' + version = '$Id: snow.F90,v 20.0 2013/12/13 23:30:44 fms Exp $' ,& + tagname = '$Name: tikal $' ! ==== module variables ====================================================== @@ -143,7 +143,7 @@ subroutine snow_init ( id_lon, id_lat ) integer, intent(in) :: id_lat ! ID of land latitude (Y) axis ! ---- local vars ---------------------------------------------------------- - integer :: unit ! unit for various i/o + integer :: unit,k ! unit for various i/o type(land_tile_enum_type) :: te,ce ! tail and current tile list elements type(land_tile_type), pointer :: tile ! pointer to current tile character(len=256) :: restart_file_name @@ -175,10 +175,11 @@ subroutine snow_init ( id_lon, id_lat ) ce=next_elmt(ce) ! advance position to the next tile if (.not.associated(tile%snow)) cycle - - tile%snow%prog(1:num_l)%wl = init_pack_wl * dz(1:num_l) - tile%snow%prog(1:num_l)%ws = init_pack_wl * dz(1:num_l) - tile%snow%prog(1:num_l)%T = init_temp + do k = 1,num_l + tile%snow%wl(k) = init_pack_wl * dz(k) + tile%snow%ws(k) = init_pack_ws * dz(k) + tile%snow%T(k) = init_temp + enddo enddo endif @@ -239,7 +240,7 @@ subroutine snow_get_sfc_temp(snow, snow_T) type(snow_tile_type), intent(in) :: snow real, intent(out) :: snow_T - snow_T = snow%prog(1)%T + snow_T = snow%T(1) end subroutine @@ -252,7 +253,7 @@ subroutine snow_get_depth_area(snow, snow_depth, snow_area) snow_depth= 0.0 do l = 1, num_l - snow_depth = snow_depth + snow%prog(l)%ws + snow_depth = snow_depth + snow%ws(l) enddo snow_depth = snow_depth / snow_density call snow_data_area (snow_depth, snow_area ) @@ -309,24 +310,24 @@ subroutine snow_step_1 ( snow, snow_G_Z, snow_G_TZ, & ! ---------------------------------------------------------------------------- snow_T = tfreeze - snow_T = snow%prog(1)%T + snow_T = snow%T(1) call snow_data_thermodynamics ( snow_rh, thermal_cond ) snow_depth= 0.0 do l = 1, num_l - snow_depth = snow_depth + snow%prog(l)%ws + snow_depth = snow_depth + snow%ws(l) enddo snow_depth = snow_depth / snow_density call snow_data_area (snow_depth, snow_area ) ! ---- only liquid in the top snow layer is available to freeze implicitly - snow_liq = snow%prog(1)%wl + snow_liq = snow%wl(1) ! ---- snow in any layer can be melted implicitly - snow_ice = sum(snow%prog(:)%ws) + snow_ice = sum(snow%ws(:)) ! ---- fractionate evaporation/sublimation according to sfc phase ratios -! where (max(snow%prog(1)%ws,0.)+max(snow%prog(1)%wl,0.)>0) -! snow_subl = max(snow%prog(1)%ws,0.) & -! /(max(snow%prog(1)%ws,0.)+max(snow%prog(1)%wl,0.)) +! where (max(snow%ws(1),0.)+max(snow%wl(1),0.)>0) +! snow_subl = max(snow%ws(1),0.) & +! /(max(snow%ws(1),0.)+max(snow%wl(1),0.)) ! elsewhere ! snow_subl = 0 ! endwhere @@ -349,7 +350,7 @@ subroutine snow_step_1 ( snow, snow_G_Z, snow_G_TZ, & else do l = 1, num_l heat_capacity(l) = mc_fict*dz(l) + & - clw*snow%prog(l)%wl + csw*snow%prog(l)%ws + clw*snow%wl(l) + csw*snow%ws(l) enddo endif @@ -364,7 +365,7 @@ subroutine snow_step_1 ( snow, snow_G_Z, snow_G_TZ, & bbb = 1.0 - aaa(num_l) + delta_time*snow_G_TZ/heat_capacity(num_l) denom = bbb - dt_e = aaa(num_l)*(snow%prog(num_l)%T - snow%prog(num_l-1)%T) & + dt_e = aaa(num_l)*(snow%T(num_l) - snow%T(num_l-1)) & - delta_time*snow_G_Z/heat_capacity(num_l) snow%e(num_l-1) = -aaa(num_l)/denom snow%f(num_l-1) = dt_e/denom @@ -372,14 +373,14 @@ subroutine snow_step_1 ( snow, snow_G_Z, snow_G_TZ, & do l = num_l-1, 2, -1 bbb = 1.0 - aaa(l) - ccc(l) denom = bbb + ccc(l)*snow%e(l) - dt_e = - ( ccc(l)*(snow%prog(l+1)%T - snow%prog(l)%T ) & - -aaa(l)*(snow%prog(l)%T - snow%prog(l-1)%T) ) + dt_e = - ( ccc(l)*(snow%T(l+1) - snow%T(l) ) & + -aaa(l)*(snow%T(l) - snow%T(l-1)) ) snow%e(l-1) = -aaa(l)/denom snow%f(l-1) = (dt_e - ccc(l)*snow%f(l))/denom enddo denom = delta_time/heat_capacity(1) - snow_G0 = ccc(1)*(snow%prog(2)%T- snow%prog(1)%T & + snow_G0 = ccc(1)*(snow%T(2)- snow%T(1) & + snow%f(1)) / denom snow_DGDT = (1 - ccc(1)*(1-snow%e(1))) / denom endif @@ -454,12 +455,14 @@ subroutine snow_step_2 ( snow, snow_subl, & evapg_lm2, vegn_fprec_lm2, & snow_LMASS, snow_FMASS, snow_HEAT integer :: l, l_old - type(snow_prog_type) :: new_prog(num_l) + real :: new_ws(num_l) + real :: new_wl(num_l) + real :: new_T(num_l) ! -------------------------------------------------------------------------- depth= 0. do l = 1, num_l - depth = depth + snow%prog(l)%ws + depth = depth + snow%ws(l) enddo depth = depth / snow_density @@ -481,20 +484,20 @@ subroutine snow_step_2 ( snow, snow_subl, & write(*,*) 'depth ', depth do l = 1, num_l - write(*,'(i2,3(x,a,g))') l,& - ' wl=', snow%prog(l)%wl,& - ' ws=', snow%prog(l)%ws,& - ' T =', snow%prog(l)%T + write(*,'(i2,3(x,a,g23.16))') l,& + ' wl=', snow%wl(l),& + ' ws=', snow%ws(l),& + ' T =', snow%T(l) enddo endif snow_LMASS = 0; snow_FMASS = 0; snow_HEAT = 0 do l = 1, num_l; - snow_LMASS = snow_LMASS + snow%prog(l)%wl - snow_FMASS = snow_FMASS + snow%prog(l)%ws + snow_LMASS = snow_LMASS + snow%wl(l) + snow_FMASS = snow_FMASS + snow%ws(l) snow_HEAT = snow_HEAT + & - (mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws) & - * (snow%prog(l)%T-tfreeze) + (mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l)) & + * (snow%T(l)-tfreeze) enddo if(is_watch_point()) then @@ -547,13 +550,13 @@ subroutine snow_step_2 ( snow, snow_subl, & ! ---- load surface temp change and perform back substitution -------------- if (depth>0) then del_t(1) = DTg - snow%prog(1)%T = snow%prog(1)%T + del_t(1) + snow%T(1) = snow%T(1) + del_t(1) endif if ( num_l > 1) then do l = 1, num_l-1 if (depth>0) then del_t(l+1) = snow%e(l) * del_t(l) + snow%f(l) - snow%prog(l+1)%T = snow%prog(l+1)%T + del_t(l+1) + snow%T(l+1) = snow%T(l+1) + del_t(l+1) endif enddo endif @@ -566,17 +569,17 @@ subroutine snow_step_2 ( snow, snow_subl, & if(is_watch_point()) then write(*,*) ' ***** snow_step_2 checkpoint 2 ***** ' do l = 1, num_l - write(*,'(i2,a,g)') l,' T =', snow%prog(l)%T + write(*,'(i2,a,g23.16)') l,' T =', snow%T(l) enddo endif snow_LMASS = 0; snow_FMASS = 0; snow_HEAT = 0 do l = 1, num_l - snow_LMASS = snow_LMASS + snow%prog(l)%wl - snow_FMASS = snow_FMASS + snow%prog(l)%ws + snow_LMASS = snow_LMASS + snow%wl(l) + snow_FMASS = snow_FMASS + snow%ws(l) snow_HEAT = snow_HEAT + & - (mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws) & - * (snow%prog(l)%T-tfreeze) + (mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l)) & + * (snow%T(l)-tfreeze) enddo if(is_watch_point()) then @@ -588,35 +591,35 @@ subroutine snow_step_2 ( snow, snow_subl, & ! ---- evaporation and sublimation ----------------------------------------- if (depth>0) then - snow%prog(1)%wl = snow%prog(1)%wl - snow_levap*delta_time - snow%prog(1)%ws = snow%prog(1)%ws - snow_fevap*delta_time - cap0 = mc_fict*dz(1) + clw*snow%prog(1)%wl + csw*snow%prog(1)%ws + snow%wl(1) = snow%wl(1) - snow_levap*delta_time + snow%ws(1) = snow%ws(1) - snow_fevap*delta_time + cap0 = mc_fict*dz(1) + clw*snow%wl(1) + csw*snow%ws(1) ! T adjustment for nonlinear terms (del_T)*(del_W) dheat = delta_time*(clw*snow_levap+csw*snow_fevap)*del_T(1) ! take out extra heat not claimed in advance for evaporation if (use_tfreeze_in_grnd_latent) dheat = dheat & - delta_time*((cpw-clw)*snow_levap+(cpw-csw)*snow_fevap) & - *(snow%prog(1)%T-del_T(1)-tfreeze) - snow%prog(1)%T = snow%prog(1)%T + dheat/cap0 + *(snow%T(1)-del_T(1)-tfreeze) + snow%T(1) = snow%T(1) + dheat/cap0 endif if(is_watch_point()) then write(*,*) ' ***** snow_step_2 checkpoint 2.5 ***** ' do l = 1, num_l - write(*,'(i2,3(a,g))')l,& - ' wl=', snow%prog(l)%wl,& - ' ws=', snow%prog(l)%ws,& - ' T =', snow%prog(l)%T + write(*,'(i2,3(a,g23.16))')l,& + ' wl=', snow%wl(l),& + ' ws=', snow%ws(l),& + ' T =', snow%T(l) enddo endif snow_LMASS = 0; snow_FMASS = 0; snow_HEAT = 0 do l = 1, num_l - snow_LMASS = snow_LMASS + snow%prog(l)%wl - snow_FMASS = snow_FMASS + snow%prog(l)%ws + snow_LMASS = snow_LMASS + snow%wl(l) + snow_FMASS = snow_FMASS + snow%ws(l) snow_HEAT = snow_HEAT + & - (mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws) & - * (snow%prog(l)%T-tfreeze) + (mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l)) & + * (snow%T(l)-tfreeze) enddo if(is_watch_point()) then @@ -636,7 +639,7 @@ subroutine snow_step_2 ( snow, snow_subl, & subs_M_imp = Mg_imp do l = 1, num_l if (depth>0 .and. subs_M_imp.gt.0) then - M_layer(l) = min( subs_M_imp, max(0.,snow%prog(l)%ws) ) + M_layer(l) = min( subs_M_imp, max(0.,snow%ws(l)) ) subs_M_imp = subs_M_imp - M_layer(l) endif enddo @@ -646,10 +649,10 @@ subroutine snow_step_2 ( snow, snow_subl, & endif do l = 1, num_l if (depth>0) then - cap0 = mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws - snow%prog(l)%wl = snow%prog(l)%wl + M_layer(l) - snow%prog(l)%ws = snow%prog(l)%ws - M_layer(l) - snow%prog(l)%T = tfreeze + (cap0*(snow%prog(l)%T-tfreeze) ) & + cap0 = mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l) + snow%wl(l) = snow%wl(l) + M_layer(l) + snow%ws(l) = snow%ws(l) - M_layer(l) + snow%T(l) = tfreeze + (cap0*(snow%T(l)-tfreeze) ) & / ( cap0 + (clw-csw)*M_layer(l) ) endif enddo @@ -657,20 +660,20 @@ subroutine snow_step_2 ( snow, snow_subl, & if(is_watch_point()) then write(*,*) ' ***** snow_step_2 checkpoint 3 ***** ' do l = 1, num_l - write(*,'(i2,3(a,g))') l,& - ' wl=', snow%prog(l)%wl,& - ' ws=', snow%prog(l)%ws,& - ' T=', snow%prog(l)%T + write(*,'(i2,3(a,g23.16))') l,& + ' wl=', snow%wl(l),& + ' ws=', snow%ws(l),& + ' T=', snow%T(l) enddo endif snow_LMASS = 0; snow_FMASS = 0; snow_HEAT = 0 do l = 1, num_l - snow_LMASS = snow_LMASS + snow%prog(l)%wl - snow_FMASS = snow_FMASS + snow%prog(l)%ws + snow_LMASS = snow_LMASS + snow%wl(l) + snow_FMASS = snow_FMASS + snow%ws(l) snow_HEAT = snow_HEAT + & - (mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws) & - * (snow%prog(l)%T-tfreeze) + (mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l)) & + * (snow%T(l)-tfreeze) enddo if(is_watch_point()) then @@ -681,7 +684,7 @@ subroutine snow_step_2 ( snow, snow_subl, & endif ! ---------------------------------------------------------------------------- -! call snow_data_hydraulics (pars, snow%prog%wl, psi, hyd_cond ) +! call snow_data_hydraulics (pars, snow%wl, psi, hyd_cond ) ! ---- remainder of mass fluxes and associated sensible heat fluxes ---------- liq_rate = vegn_lprec @@ -696,59 +699,58 @@ subroutine snow_step_2 ( snow, snow_subl, & do l = 1, num_l if(depth>0 .or. vegn_fprec_lm2>0) then ! ---- mix inflow with existing snow and water --------------------------- - cap0 = mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws + cap0 = mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l) dW_l = liq_rate*delta_time dW_s = sno_rate*delta_time dcap = clw*dW_l + csw*dW_s - snow%prog(l)%ws = snow%prog(l)%ws + dW_s - snow%prog(l)%wl = snow%prog(l)%wl + dW_l - snow%prog(l)%T = tfreeze & - + (cap0*(snow%prog(l)%T-tfreeze) & - + (hsno_rate+hliq_rate)*delta_time) /(cap0 + dcap) + snow%ws(l) = snow%ws(l) + dW_s + snow%wl(l) = snow%wl(l) + dW_l + snow%T(l) = tfreeze + (cap0*(snow%T(l)-tfreeze) & + + (hsno_rate+hliq_rate)*delta_time) /(cap0 + dcap) endif if(is_watch_point()) then write(*,*) ' ***** snow_step_2 checkpoint 4a ***** ' - write(*,'(i2,3(a,g))') l,& - ' wl=', snow%prog(l)%wl,& - ' ws=', snow%prog(l)%ws,& - ' T=', snow%prog(l)%T + write(*,'(i2,3(a,g23.16))') l,& + ' wl=', snow%wl(l),& + ' ws=', snow%ws(l),& + ' T=', snow%T(l) endif if (depth>0 .or. vegn_fprec_lm2>0) then ! ---- compute explicit melt/freeze -------------------------------------- melt_per_deg = (cap0+dcap)/hlf - if (snow%prog(l)%ws>0 .and. snow%prog(l)%T>tfreeze) then - melt = min(snow%prog(l)%ws, (snow%prog(l)%T-tfreeze)*melt_per_deg) - elseif (snow%prog(l)%wl>0 .and. snow%prog(l)%T 0 .and. snow%T(l)>tfreeze) then + melt = min(snow%ws(l), (snow%T(l)-tfreeze)*melt_per_deg) + elseif (snow%wl(l)>0 .and. snow%T(l) snow_frunf) then + if (sum_sno + snow%ws(l) > snow_frunf) then snow_transfer = snow_frunf - sum_sno else - snow_transfer = snow%prog(l)%ws + snow_transfer = snow%ws(l) endif - if (snow%prog(l)%ws > 0) then - frac = snow_transfer / snow%prog(l)%ws + if (snow%ws(l) > 0) then + frac = snow_transfer / snow%ws(l) else frac = 1. endif sum_sno = sum_sno + snow_transfer - snow_lrunf = snow_lrunf + frac*snow%prog(l)%wl - snow_hlrunf = snow_hlrunf + clw*frac*snow%prog(l)%wl*(snow%prog(l)%T-tfreeze) - snow_hfrunf = snow_hfrunf + csw*frac*snow%prog(l)%ws*(snow%prog(l)%T-tfreeze) - snow%prog(l)%ws = (1-frac)*snow%prog(l)%ws - snow%prog(l)%wl = (1-frac)*snow%prog(l)%wl + snow_lrunf = snow_lrunf + frac*snow%wl(l) + snow_hlrunf = snow_hlrunf + clw*frac*snow%wl(l)*(snow%T(l)-tfreeze) + snow_hfrunf = snow_hfrunf + csw*frac*snow%ws(l)*(snow%T(l)-tfreeze) + snow%ws(l) = (1-frac)*snow%ws(l) + snow%wl(l) = (1-frac)*snow%wl(l) enddo endif snow_lrunf = snow_lrunf / delta_time @@ -838,20 +840,20 @@ subroutine snow_step_2 ( snow, snow_subl, & write(*,*) ' ***** snow_step_2 checkpoint 5 ***** ' write(*,*) 'fict_heat ', fict_heat do l = 1, num_l - write(*,'(i2,3(a,g))')l,& - ' wl=', snow%prog(l)%wl,& - ' ws=', snow%prog(l)%ws,& - ' T =', snow%prog(l)%T + write(*,'(i2,3(a,g23.16))')l,& + ' wl=', snow%wl(l),& + ' ws=', snow%ws(l),& + ' T =', snow%T(l) enddo endif snow_LMASS = 0; snow_FMASS = 0; snow_HEAT = 0 do l = 1, num_l - snow_LMASS = snow_LMASS + snow%prog(l)%wl - snow_FMASS = snow_FMASS + snow%prog(l)%ws + snow_LMASS = snow_LMASS + snow%wl(l) + snow_FMASS = snow_FMASS + snow%ws(l) snow_HEAT = snow_HEAT + & - (mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws) & - * (snow%prog(l)%T-tfreeze) + (mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l)) & + * (snow%T(l)-tfreeze) enddo if(is_watch_point()) then @@ -862,48 +864,48 @@ subroutine snow_step_2 ( snow, snow_subl, & endif depth= 0. - new_prog%ws=0 - new_prog%wl=0 - new_prog%T=0 + new_ws=0 + new_wl=0 + new_T=0 do l = 1, num_l - depth = depth + snow%prog(l)%ws + depth = depth + snow%ws(l) enddo depth = depth / snow_density !************************** fudge to avoid T=NaN from too-small mass ** ! if(depth*snow_density < min_snow_mass .and. depth>0.) then ! depth = 0 -! snow%prog%ws = 0 -! snow%prog%wl = 0 +! snow%ws = 0 +! snow%wl = 0 ! endif ! ---- re-layer the snowpack ------------------------------------------------ do l = 1, num_l if (depth > 0) then - new_prog(l)%ws = snow_mass*dz(l) + new_ws(l) = snow_mass*dz(l) sum_sno = 0 sum_liq = 0 sum_heat = 0 endif do l_old = 1, num_l if (depth > 0) then - if (sum_sno + snow%prog(l_old)%ws > new_prog(l)%ws) then - snow_transfer = new_prog(l)%ws - sum_sno + if (sum_sno + snow%ws(l_old) > new_ws(l)) then + snow_transfer = new_ws(l) - sum_sno else - snow_transfer = snow%prog(l_old)%ws + snow_transfer = snow%ws(l_old) endif - if (snow%prog(l_old)%ws .ne. 0.) then - frac = snow_transfer / snow%prog(l_old)%ws + if (snow%ws(l_old) .ne. 0.) then + frac = snow_transfer / snow%ws(l_old) else frac = 1 endif sum_sno = sum_sno + snow_transfer - sum_liq = sum_liq + frac* snow%prog(l_old)%wl + sum_liq = sum_liq + frac* snow%wl(l_old) sum_heat = sum_heat + frac*& - (clw*snow%prog(l_old)%wl + csw*snow%prog(l_old)%ws)& - *snow%prog(l_old)%T - snow%prog(l_old)%ws = (1.-frac)*snow%prog(l_old)%ws - snow%prog(l_old)%wl = (1.-frac)*snow%prog(l_old)%wl + (clw*snow%wl(l_old) + csw*snow%ws(l_old))& + *snow%T(l_old) + snow%ws(l_old) = (1.-frac)*snow%ws(l_old) + snow%wl(l_old) = (1.-frac)*snow%wl(l_old) if(is_watch_point()) then write(*,*) 'l=',l, ' l_old=',l_old,snow_transfer,frac,& sum_sno,sum_liq, sum_heat @@ -912,9 +914,8 @@ subroutine snow_step_2 ( snow, snow_subl, & enddo if (depth > 0) then - new_prog(l)%wl = sum_liq - new_prog(l)%T = sum_heat & - / (clw*new_prog(l)%wl + csw*new_prog(l)%ws) + new_wl(l) = sum_liq + new_T(l) = sum_heat / (clw*new_wl(l) + csw*new_ws(l)) endif enddo @@ -923,25 +924,28 @@ subroutine snow_step_2 ( snow, snow_subl, & write(*,*) 'depth ', depth write(*,*) 'fict_heat ', fict_heat do l = 1, num_l - write(*,'(i2,3(a,g))')l,& - ' new_wl=', new_prog(l)%wl,& - ' new_ws=', new_prog(l)%ws,& - ' new_T =', new_prog(l)%T + write(*,'(i2,3(a,g23.16))')l,& + ' new_wl=', new_wl(l),& + ' new_ws=', new_ws(l),& + ' new_T =', new_T(l) enddo endif ! add back fictional mass/heat do l = 1, num_l if (depth > 0) & - new_prog(l)%T = ( & - (clw*new_prog(l)%wl + csw*new_prog(l)%ws)*new_prog(l)%T & + new_T(l) = ( & + (clw*new_wl(l) + csw*new_ws(l))*new_T(l) & + mc_fict*dz(l)*fict_heat ) & - / (clw*new_prog(l)%wl + csw*new_prog(l)%ws + dz(l)*mc_fict) + / (clw*new_wl(l) + csw*new_ws(l) + dz(l)*mc_fict) enddo do l = 1, num_l -!! where (mask .and. snow_mass > 0) snow%prog(l) = new_prog(l) - if (depth > 0) snow%prog(l) = new_prog(l) + if (depth > 0) then + snow%ws(l) = new_ws(l) + snow%wl(l) = new_wl(l) + snow%T(l) = new_T(l) + endif enddo if(is_watch_point()) then @@ -950,10 +954,10 @@ subroutine snow_step_2 ( snow, snow_subl, & write(*,*) 'snow_lprec', snow_lprec write(*,*) 'depth ', depth do l = 1, num_l - write(*,'(i2,3(a,g))')l,& - ' wl=', snow%prog(l)%wl,& - ' ws=', snow%prog(l)%ws,& - ' T =', snow%prog(l)%T + write(*,'(i2,3(a,g23.16))')l,& + ' wl=', snow%wl(l),& + ' ws=', snow%ws(l),& + ' T =', snow%T(l) enddo endif @@ -961,17 +965,17 @@ subroutine snow_step_2 ( snow, snow_subl, & snow_FMASS = 0 snow_HEAT = 0 do l = 1, num_l - snow_LMASS = snow_LMASS + snow%prog(l)%wl - snow_FMASS = snow_FMASS + snow%prog(l)%ws + snow_LMASS = snow_LMASS + snow%wl(l) + snow_FMASS = snow_FMASS + snow%ws(l) snow_HEAT = snow_HEAT + & - (mc_fict*dz(l) + clw*snow%prog(l)%wl + csw*snow%prog(l)%ws) & - * (snow%prog(l)%T-tfreeze) + (mc_fict*dz(l) + clw*snow%wl(l) + csw*snow%ws(l)) & + * (snow%T(l)-tfreeze) enddo - snow_Tbot = snow%prog(num_l)%T + snow_Tbot = snow%T(num_l) snow_Cbot = mc_fict*dz(num_l) & - + clw*snow%prog(num_l)%wl + csw*snow%prog(num_l)%ws + + clw*snow%wl(num_l) + csw*snow%ws(num_l) snow_C = sum(mc_fict*dz(1:num_l) & - + clw*snow%prog(1:num_l)%wl + csw*snow%prog(1:num_l)%ws) + + clw*snow%wl(1:num_l) + csw*snow%ws(1:num_l)) snow_avrg_T = snow_HEAT/snow_C+tfreeze if(is_watch_point()) then @@ -1001,27 +1005,39 @@ end function snow_tile_exists subroutine snow_temp_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%snow)) ptr=>tile%snow%prog%T + if(associated(tile%snow)) then + n = size(tile%snow%T) + ptr(1:n) => tile%snow%T(1:n) + endif endif end subroutine snow_temp_ptr subroutine snow_wl_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%snow)) ptr=>tile%snow%prog%wl + if(associated(tile%snow)) then + n = size(tile%snow%wl) + ptr(1:n) => tile%snow%wl(1:n) + endif endif end subroutine snow_wl_ptr subroutine snow_ws_ptr(tile, ptr) type(land_tile_type), pointer :: tile real , pointer :: ptr(:) + integer :: n ptr=>NULL() if(associated(tile)) then - if(associated(tile%snow)) ptr=>tile%snow%prog%ws + if(associated(tile%snow)) then + n = size(tile%snow%ws) + ptr(1:n) => tile%snow%ws(1:n) + endif endif end subroutine snow_ws_ptr diff --git a/src/land_lad2/snow/snow_tile.F90 b/src/land_lad2/snow/snow_tile.F90 index 394fe6b2fd..bd1f42ba1c 100644 --- a/src/land_lad2/snow/snow_tile.F90 +++ b/src/land_lad2/snow/snow_tile.F90 @@ -21,7 +21,6 @@ module snow_tile_mod private ! ==== public interfaces ===================================================== -public :: snow_prog_type public :: snow_tile_type public :: new_snow_tile, delete_snow_tile @@ -51,8 +50,8 @@ module snow_tile_mod ! ==== module constants ====================================================== character(len=*), parameter :: & module_name = 'snow_tile_mod' ,& - version = '$Id: snow_tile.F90,v 19.0 2012/01/06 20:42:44 fms Exp $' ,& - tagname = '$Name: siena_201207 $' + version = '$Id: snow_tile.F90,v 20.0 2013/12/13 23:30:46 fms Exp $' ,& + tagname = '$Name: tikal $' integer, parameter :: max_lev = 10 real , parameter :: t_range = 10.0 ! degK @@ -71,16 +70,12 @@ module snow_tile_mod real :: g2_geo = 0.041840 ! ==== types ================================================================= -type :: snow_prog_type - real wl - real ws - real T -end type snow_prog_type - type :: snow_tile_type integer :: tag ! kind of the tile - type(snow_prog_type), pointer :: prog(:) + real, pointer :: wl(:) + real, pointer :: ws(:) + real, pointer :: T(:) real, pointer :: e(:), f(:) end type snow_tile_type @@ -185,7 +180,9 @@ function snow_tile_ctor(tag) result(ptr) allocate(ptr) ptr%tag = 0 ; if(present(tag)) ptr%tag = tag ! allocate storage for tile data - allocate(ptr%prog(num_l)) + allocate(ptr%ws(num_l)) + allocate(ptr%wl(num_l)) + allocate(ptr%T(num_l)) allocate(ptr%e(num_l)) allocate(ptr%f(num_l)) @@ -200,11 +197,15 @@ function snow_tile_copy_ctor(snow) result(ptr) ! copy all non-pointer members ptr = snow ! allocate storage for tile data - allocate(ptr%prog(num_l)) + allocate(ptr%ws(num_l)) + allocate(ptr%wl(num_l)) + allocate(ptr%T(num_l)) allocate(ptr%e(num_l)) allocate(ptr%f(num_l)) ! copy all pointer members - ptr%prog(:) = snow%prog(:) + ptr%ws(:) = snow%ws(:) + ptr%wl(:) = snow%wl(:) + ptr%T(:) = snow%T(:) ptr%e(:) = snow%e(:) ptr%f(:) = snow%f(:) end function snow_tile_copy_ctor @@ -213,7 +214,9 @@ end function snow_tile_copy_ctor subroutine delete_snow_tile(snow) type(snow_tile_type), pointer :: snow - deallocate(snow%prog) + deallocate(snow%ws) + deallocate(snow%wl) + deallocate(snow%T) deallocate(snow%e) deallocate(snow%f) deallocate(snow) @@ -243,15 +246,15 @@ subroutine merge_snow_tiles(snow1, w1, snow2, w2) x2 = 1-x1 do i = 1, num_l - HEAT1 = (mc_fict*dz(i)+clw*snow1%prog(i)%wl+csw*snow1%prog(i)%ws)*(snow1%prog(i)%T-tfreeze) - HEAT2 = (mc_fict*dz(i)+clw*snow2%prog(i)%wl+csw*snow2%prog(i)%ws)*(snow2%prog(i)%T-tfreeze) - snow2%prog(i)%wl = snow1%prog(i)%wl*x1 + snow2%prog(i)%wl*x2 - snow2%prog(i)%ws = snow1%prog(i)%ws*x1 + snow2%prog(i)%ws*x2 - if (snow2%prog(i)%wl/=0.or.snow2%prog(i)%ws/=0) then - snow2%prog(i)%T = (HEAT1*x1+HEAT2*x2)/& - (mc_fict*dz(i)+clw*snow2%prog(i)%wl+csw*snow2%prog(i)%ws)+tfreeze + HEAT1 = (mc_fict*dz(i)+clw*snow1%wl(i)+csw*snow1%ws(i))*(snow1%T(i)-tfreeze) + HEAT2 = (mc_fict*dz(i)+clw*snow2%wl(i)+csw*snow2%ws(i))*(snow2%T(i)-tfreeze) + snow2%wl(i) = snow1%wl(i)*x1 + snow2%wl(i)*x2 + snow2%ws(i) = snow1%ws(i)*x1 + snow2%ws(i)*x2 + if (snow2%wl(i)/=0.or.snow2%ws(i)/=0) then + snow2%T(i) = (HEAT1*x1+HEAT2*x2)/& + (mc_fict*dz(i)+clw*snow2%wl(i)+csw*snow2%ws(i))+tfreeze else - snow2%prog(i)%T = snow1%prog(i)%T*x1 + snow2%prog(i)%T*x2 + snow2%T(i) = snow1%T(i)*x1 + snow2%T(i)*x2 endif enddo end subroutine @@ -378,9 +381,9 @@ subroutine snow_tile_stock_pe (snow, twd_liq, twd_sol ) twd_liq = 0. twd_sol = 0. - do n=1, size(snow%prog) - twd_liq = twd_liq + snow%prog(n)%wl - twd_sol = twd_sol + snow%prog(n)%ws + do n=1, size(snow%wl) + twd_liq = twd_liq + snow%wl(n) + twd_sol = twd_sol + snow%ws(n) enddo end subroutine snow_tile_stock_pe @@ -394,9 +397,9 @@ function snow_tile_heat (snow) result(heat) ; real heat heat = 0 do i = 1,num_l - heat = heat - snow%prog(i)%ws*hlf & - + (mc_fict*dz(i) + clw*snow%prog(i)%wl + csw*snow%prog(i)%ws) & - * (snow%prog(i)%T-tfreeze) + heat = heat - snow%ws(i)*hlf & + + (mc_fict*dz(i) + clw*snow%wl(i) + csw*snow%ws(i)) & + * (snow%T(i)-tfreeze) enddo end function diff --git a/src/land_lad2/soil/soil.F90 b/src/land_lad2/soil/soil.F90 index f97623e5fe..9a2ffc903e 100644 --- a/src/land_lad2/soil/soil.F90 +++ b/src/land_lad2/soil/soil.F90 @@ -13,21 +13,26 @@ module soil_mod use fms_mod, only: error_mesg, file_exist, check_nml_error, & stdlog, write_version_number, close_file, mpp_pe, mpp_root_pe, FATAL, NOTE -use mpp_io_mod, only: mpp_open, MPP_RDONLY use time_manager_mod, only: time_type, increment_time, time_type_to_real use diag_manager_mod, only: diag_axis_init -use constants_mod, only: tfreeze, hlv, hlf, dens_h2o, PI -use horiz_interp_mod, only: horiz_interp +use constants_mod, only: tfreeze, hlv, hlf, dens_h2o use land_constants_mod, only : NBANDS, BAND_VIS, BAND_NIR -use soil_tile_mod, only : & +use soil_tile_mod, only : GW_LM2, GW_LINEAR, GW_HILL_AR5, GW_HILL, GW_TILED, & soil_tile_type, soil_pars_type, soil_prog_type, read_soil_data_namelist, & soil_data_radiation, soil_data_diffusion, soil_data_thermodynamics, & - soil_data_hydraulics, soil_data_gw_hydraulics, & ! soil_data_gw_tables, & - soil_data_vwc_sat, & - max_lev, psi_wilt, cpw, clw, csw, g_iso, g_vol, g_geo, g_RT, & - num_storage_pts, num_zeta_s_pts, gw_zeta_s, gw_flux_table, gw_area_table, & - gw_scale_length, gw_scale_relief, gw_scale_soil_depth + soil_data_hydraulic_properties, soil_data_psi_for_rh, & + soil_data_gw_hydraulics, soil_data_gw_hydraulics_ar5, & + soil_data_vwc_for_init_only, & + soil_data_init_derive_subsurf_pars, & + soil_data_init_derive_subsurf_pars_ar5,& + max_lev, psi_wilt, cpw, clw, csw, g_iso, g_vol, g_geo, g_RT, aspect,& + num_storage_pts, gw_zeta_s, gw_flux_table, gw_area_table, & + gw_scale_length, gw_scale_relief, gw_scale_soil_depth, & + slope_exp, & + num_zeta_pts, num_tau_pts, & + log_rho_table, log_zeta_s, log_tau, gw_scale_perm, & + z_ref, k_macro_constant, use_tau_fix use land_tile_mod, only : land_tile_type, land_tile_enum_type, & first_elmt, tail_elmt, next_elmt, current_tile, get_elmt_indices, & @@ -36,15 +41,16 @@ module soil_mod use land_tile_diag_mod, only : diag_buff_type, & register_tiled_static_field, register_tiled_diag_field, & send_tile_data, send_tile_data_r0d_fptr, send_tile_data_r1d_fptr, & - send_tile_data_i0d_fptr -use land_data_mod, only : land_state_type, lnd + send_tile_data_i0d_fptr, & + add_tiled_diag_field_alias, add_tiled_static_field_alias +use land_data_mod, only : land_state_type, lnd use land_io_mod, only : read_field use land_tile_io_mod, only : create_tile_out_file, write_tile_data_r0d_fptr,& - write_tile_data_r1d_fptr,read_tile_data_r0d_fptr, read_tile_data_r1d_fptr,& + write_tile_data_r1d_fptr, read_tile_data_r0d_fptr, read_tile_data_r1d_fptr,& print_netcdf_error, get_input_restart_name, sync_nc_files use nf_utils_mod, only : nfu_def_dim, nfu_put_att, nfu_inq_var use vegn_tile_mod, only : vegn_tile_type, vegn_uptake_profile, vegn_root_properties -use land_debug_mod, only : is_watch_point, get_current_point +use land_debug_mod, only : is_watch_point, get_current_point, check_var_range use uptake_mod, only : UPTAKE_LINEAR, UPTAKE_DARCY2D, UPTAKE_DARCY2D_LIN, & uptake_init, & darcy2d_uptake, darcy2d_uptake_solver, & @@ -63,6 +69,7 @@ module soil_mod public :: soil_diffusion public :: soil_step_1 public :: soil_step_2 +public :: soil_step_3 ! =====end of public interfaces ============================================== @@ -70,8 +77,8 @@ module soil_mod ! ==== module constants ====================================================== character(len=*), parameter, private :: & module_name = 'soil',& - version = '$Id: soil.F90,v 17.0.2.2.2.2 2011/12/16 19:01:57 pjp Exp $',& - tagname = '$Name: siena_201207 $' + version = '$Id: soil.F90,v 20.0 2013/12/13 23:30:48 fms Exp $',& + tagname = '$Name: tikal $' ! ==== module variables ====================================================== @@ -81,6 +88,8 @@ module soil_mod logical :: use_E_max = .true. ! theoretical effiltration capacity flag real :: init_temp = 288. ! cold-start soil T real :: init_w = 150. ! cold-start w(l)/dz(l) +real :: init_wtdep = -1. ! positive value activates hydrostatic IC, + ! overriding init_w real :: init_groundwater = 0. ! cold-start gw storage real :: lrunf_ie_min = -1.0e-4 ! trigger for clip and runoff real :: lrunf_ie_tol = 1.e-12 @@ -88,33 +97,52 @@ module soil_mod character(len=24) :: uptake_to_use = 'linear' ! or 'darcy2d', or 'darcy2d-linearized' logical :: uptake_oneway = .false. ! if true, roots can't loose water to soil logical :: uptake_from_sat = .true. ! if false, the uptake from saturated soil is prohibited -logical :: unconditional_sweep = .false. logical :: allow_negative_rie = .false. logical :: baseflow_where_frozen = .false. logical :: write_when_flagged = .false. logical :: bypass_richards_when_stiff = .true. logical :: corrected_lm2_gw = .true. +logical :: use_stiff_bug = .false. +logical :: fix_z_bot = .false. +logical :: update_psi = .false. +logical :: consistent_d_trans = .false. +logical :: fix_interp = .false. +logical :: use_new_dq = .false. +logical :: use_fringe = .false. +logical :: push_down_sfc_excess = .true. +logical :: lrunf_from_div = .true. real :: active_layer_drainage_acceleration = 0. +real :: hlf_factor = 1. +real :: gw_flux_max = 1.e10 +real :: log_rho_max = 100. +real :: aquifer_heat_cap = 0. ! in equivalent liquid water amount, kg/m2 +logical :: write_soil_carbon_restart = .FALSE. ! indicates whether to write + ! information for soil carbon acceleration namelist /soil_nml/ lm2, use_E_min, use_E_max, & init_temp, & - init_w, & + init_w, init_wtdep, & init_groundwater, lrunf_ie_min, lrunf_ie_tol, & cpw, clw, csw, & albedo_to_use, & uptake_to_use, uptake_oneway, uptake_from_sat, & - unconditional_sweep, allow_negative_rie, & + allow_negative_rie, & baseflow_where_frozen, & write_when_flagged, & bypass_richards_when_stiff, corrected_lm2_gw, & - active_layer_drainage_acceleration + use_stiff_bug, fix_z_bot, update_psi, & + consistent_d_trans, fix_interp, use_new_dq, use_fringe, & + push_down_sfc_excess, lrunf_from_div, & + active_layer_drainage_acceleration, hlf_factor, & + gw_flux_max, log_rho_max, aquifer_heat_cap, & + write_soil_carbon_restart !---- end of namelist -------------------------------------------------------- logical :: module_is_initialized =.FALSE. logical :: use_brdf = .false. type(time_type) :: time real :: delta_time -logical :: use_single_geo, use_geohydrology +logical :: use_single_geo integer :: num_l ! # of water layers real :: dz (max_lev) ! thicknesses of layers real :: zfull (max_lev) @@ -122,21 +150,25 @@ module soil_mod real :: Eg_min integer :: uptake_option = -1 +integer :: gw_option = -1 ! ---- diagnostic field IDs -integer :: id_lwc, id_swc, id_psi, id_temp, & - id_ie, id_sn, id_bf, id_nu, id_hie, id_hsn, id_hbf, id_hnu, & +integer :: id_fast_soil_C, id_slow_soil_C, id_fsc, id_ssc, & + id_lwc, id_swc, id_psi, id_temp, & + id_ie, id_sn, id_bf, id_if, id_al, id_nu, id_sc, & + id_hie, id_hsn, id_hbf, id_hif, id_hal, id_hnu, id_hsc, & id_heat_cap, id_thermal_cond, id_type, id_tau_gw, id_slope_l, & id_slope_Z, id_zeta_bar, id_e_depth, id_vwc_sat, id_vwc_fc, & - id_vwc_wilt, id_K_sat, id_w_fc, & + id_vwc_wilt, id_K_sat, id_K_gw, id_w_fc, & id_refl_dry_dif, id_refl_dry_dir, id_refl_sat_dif, id_refl_sat_dir, & id_f_iso_dry, id_f_vol_dry, id_f_geo_dry, & id_f_iso_sat, id_f_vol_sat, id_f_geo_sat, & - id_evap, id_uptk_n_iter, id_uptk, id_uptk_residual, id_excess, & - id_psi_bot, id_sat_frac, id_stor_frac, id_sat_depth, & - id_uptk_old, id_psi_bot_old, id_sat_frac_old, id_stor_frac_old, & - id_sat_depth_old, id_slope_Z_old, id_e_depth_old, & - id_vwc_wilt_old, id_vwc_fc_old, id_vwc_sat_old, id_K_sat_old + id_evap, id_uptk_n_iter, id_uptk, id_psi_x0, id_uptk_residual, & + id_excess, id_deficit, id_deficit_2, id_deficit_3, id_zeta, id_tau, & + id_psi_bot, id_sat_frac, id_stor_frac, id_sat_depth, id_sat_dept2, & + id_cf_1, id_cf_3, id_wt_1, id_wt_2, id_wt_2a, id_wt_3, id_wt2_3, & + id_div_bf, id_div_if, id_div_al, & + id_z_cap, id_active_layer ! ==== end of module variables =============================================== @@ -154,7 +186,7 @@ subroutine read_soil_namelist() integer :: ierr ! error code, returned by i/o routines integer :: l - call read_soil_data_namelist(num_l,dz,use_single_geo,use_geohydrology) + call read_soil_data_namelist(num_l,dz,use_single_geo,gw_option) call write_version_number(version, tagname) #ifdef INTERNAL_FILE_NML @@ -184,7 +216,7 @@ subroutine read_soil_namelist() zfull(l) = 0.5*(zhalf(l+1) + zhalf(l)) enddo - ! ---- convert symbolic names of the uptake options into numeric IDs to speed up + ! ---- convert symbolic names of options into numeric IDs to speed up ! the selection during run-time if (trim(uptake_to_use)=='linear') then uptake_option = UPTAKE_LINEAR @@ -216,15 +248,15 @@ subroutine soil_init ( id_lon, id_lat, id_band ) integer, intent(in) :: id_band ! ID of spectral band axis ! ---- local vars - integer :: unit ! unit for various i/o + integer :: unit, unit1 ! unit numbers for various i/o type(land_tile_enum_type) :: te,ce ! tail and current tile list elements type(land_tile_type), pointer :: tile ! pointer to current tile real, allocatable :: gw_param(:,:), gw_param2(:,:), albedo(:,:,:) ! input data buffers for respective variables real, allocatable :: f_iso(:,:,:), f_vol(:,:,:), f_geo(:,:,:), refl_dif(:,:,:) - integer :: i, code, m - real :: zeta_s, frac - character(len=256) :: restart_file_name + integer :: i + real :: psi(num_l), mwc(num_l) + character(len=256) :: restart_file_name logical :: restart_exists module_is_initialized = .TRUE. @@ -233,113 +265,63 @@ subroutine soil_init ( id_lon, id_lat, id_band ) call uptake_init(num_l,dz,zfull) - ! -------- initialize soil state -------- - te = tail_elmt (lnd%tile_map) - ce = first_elmt(lnd%tile_map) - do while(ce /= te) - tile=>current_tile(ce) ! get pointer to current tile - ce=next_elmt(ce) ! advance position to the next tile - - if (.not.associated(tile%soil)) cycle - - if (init_temp.ge.tile%soil%pars%tfreeze) then - tile%soil%prog(1:num_l)%wl = init_w*dz(1:num_l) - tile%soil%prog(1:num_l)%ws = 0 - else - tile%soil%prog(1:num_l)%wl = 0 - tile%soil%prog(1:num_l)%ws = init_w*dz(1:num_l) - endif - tile%soil%prog%T = init_temp - tile%soil%prog%groundwater = init_groundwater - tile%soil%prog%groundwater_T = init_temp - - tile%soil%uptake_T = init_temp - enddo - - call get_input_restart_name('INPUT/soil.res.nc',restart_exists,restart_file_name) - if (restart_exists) then - call error_mesg('soil_init',& - 'reading NetCDF restart "'//trim(restart_file_name)//'"',& - NOTE) - __NF_ASRT__(nf_open(restart_file_name,NF_NOWRITE,unit)) - call read_tile_data_r1d_fptr(unit, 'temp' , soil_T_ptr ) - call read_tile_data_r1d_fptr(unit, 'wl' , soil_wl_ptr ) - call read_tile_data_r1d_fptr(unit, 'ws' , soil_ws_ptr ) - call read_tile_data_r1d_fptr(unit, 'groundwater' , soil_groundwater_ptr ) - call read_tile_data_r1d_fptr(unit, 'groundwater_T', soil_groundwater_T_ptr) - if(nfu_inq_var(unit, 'uptake_T')==NF_NOERR) & - call read_tile_data_r0d_fptr(unit, 'uptake_T', soil_uptake_T_ptr) - - __NF_ASRT__(nf_close(unit)) - else - call error_mesg('soil_init',& - 'cold-starting soil',& - NOTE) - endif - - ! initialize soil model diagnostic fields + ! -------- initialize soil model diagnostic fields call soil_diag_init ( id_lon, id_lat, id_band ) - ! read groundwater parameters, if requested + ! -------- read spatially distributed fields for groundwater parameters, if requested if (.not.use_single_geo) then - if (.not.use_geohydrology) then - allocate(gw_param(lnd%is:lnd%ie,lnd%js:lnd%je)) - call read_field( 'INPUT/groundwater_residence.nc','tau', & - lnd%lon, lnd%lat, gw_param, interp='bilinear' ) - call put_to_tiles_r0d_fptr( gw_param, lnd%tile_map, soil_tau_groundwater_ptr ) - deallocate(gw_param) + select case (gw_option) + case (GW_LINEAR,GW_LM2) + allocate(gw_param(lnd%is:lnd%ie,lnd%js:lnd%je)) + call read_field( 'INPUT/groundwater_residence.nc','tau', lnd%lon, lnd%lat, & + gw_param, interp='bilinear' ) + call put_to_tiles_r0d_fptr( gw_param, lnd%tile_map, soil_tau_groundwater_ptr ) + deallocate(gw_param) + case (GW_HILL, GW_HILL_AR5) + allocate(gw_param (lnd%is:lnd%ie,lnd%js:lnd%je)) + allocate(gw_param2(lnd%is:lnd%ie,lnd%js:lnd%je)) + call read_field( 'INPUT/geohydrology.nc','hillslope_length', lnd%lon, lnd%lat, & + gw_param, interp='bilinear' ) + call put_to_tiles_r0d_fptr( gw_param*gw_scale_length, lnd%tile_map, soil_hillslope_length_ptr ) + call read_field( 'INPUT/geohydrology.nc','slope', lnd%lon, lnd%lat, & + gw_param2, interp='bilinear' ) + gw_param = gw_param*gw_param2 + call put_to_tiles_r0d_fptr( gw_param*gw_scale_relief, lnd%tile_map, soil_hillslope_relief_ptr ) + call read_field( 'INPUT/geohydrology.nc','hillslope_zeta_bar', & + lnd%lon, lnd%lat, gw_param, interp='bilinear' ) + call put_to_tiles_r0d_fptr( gw_param, lnd%tile_map, soil_hillslope_zeta_bar_ptr ) + call read_field( 'INPUT/geohydrology.nc','soil_e_depth', & + lnd%lon, lnd%lat, gw_param, interp='bilinear' ) + if (slope_exp.gt.0.01) then + call put_to_tiles_r0d_fptr( gw_param*gw_scale_soil_depth*(0.08/gw_param2)**slope_exp, & + lnd%tile_map, soil_soil_e_depth_ptr ) else - allocate(gw_param (lnd%is:lnd%ie,lnd%js:lnd%je)) - allocate(gw_param2(lnd%is:lnd%ie,lnd%js:lnd%je)) - call read_field( 'INPUT/geohydrology.nc','hillslope_length', & - lnd%lon, lnd%lat, gw_param, interp='bilinear' ) - call put_to_tiles_r0d_fptr( gw_param*gw_scale_length, lnd%tile_map, soil_hillslope_length_ptr ) - call read_field( 'INPUT/geohydrology.nc','slope', & - lnd%lon, lnd%lat, gw_param2, interp='bilinear' ) - gw_param = gw_param*gw_param2 - call put_to_tiles_r0d_fptr( gw_param*gw_scale_relief, lnd%tile_map, soil_hillslope_relief_ptr ) - call read_field( 'INPUT/geohydrology.nc','hillslope_zeta_bar', & - lnd%lon, lnd%lat, gw_param, interp='bilinear' ) - call put_to_tiles_r0d_fptr( gw_param, lnd%tile_map, soil_hillslope_zeta_bar_ptr ) - call read_field( 'INPUT/geohydrology.nc','soil_e_depth', & - lnd%lon, lnd%lat, gw_param, interp='bilinear' ) - call put_to_tiles_r0d_fptr( gw_param*gw_scale_soil_depth, lnd%tile_map, soil_soil_e_depth_ptr ) - deallocate(gw_param, gw_param2) - te = tail_elmt (lnd%tile_map) - ce = first_elmt(lnd%tile_map) - do while(ce /= te) + call put_to_tiles_r0d_fptr( gw_param*gw_scale_soil_depth, lnd%tile_map, soil_soil_e_depth_ptr ) + endif + if (gw_option /= GW_HILL_AR5) then + call read_field( 'INPUT/geohydrology.nc','perm', lnd%lon, lnd%lat, & + gw_param, interp='bilinear' ) + call put_to_tiles_r0d_fptr(9.8e9*gw_scale_perm*gw_param, lnd%tile_map, & + soil_k_sat_gw_ptr ) + endif + deallocate(gw_param, gw_param2) + te = tail_elmt (lnd%tile_map) + ce = first_elmt(lnd%tile_map) + do while(ce /= te) tile=>current_tile(ce) ! get pointer to current tile ce=next_elmt(ce) ! advance position to the next tile if (.not.associated(tile%soil)) cycle - if (tile%soil%pars%hillslope_relief.le.0.) & - tile%soil%pars%hillslope_relief = & - tile%soil%pars%soil_e_depth / gw_zeta_s(num_zeta_s_pts) - zeta_s = tile%soil%pars%soil_e_depth / tile%soil%pars%hillslope_relief - zeta_s = max(zeta_s, gw_zeta_s(1)) - zeta_s = min(zeta_s, gw_zeta_s(num_zeta_s_pts)) - m = num_zeta_s_pts / 2 - code = 0 - do while (code.eq.0) - if (zeta_s .lt. gw_zeta_s(m)) then - m = m - 1 - else if (zeta_s .gt. gw_zeta_s(m+1)) then - m = m + 1 - else - code = 1 - endif - enddo - frac = (zeta_s - gw_zeta_s(m)) / (gw_zeta_s(m+1) - gw_zeta_s(m)) - do i = 1, num_storage_pts - tile%soil%pars%gw_flux_norm(i) = gw_flux_table(i,m) & - + frac*(gw_flux_table(i,m+1)-gw_flux_table(i,m)) - tile%soil%pars%gw_area_norm(i) = gw_area_table(i,m) & - + frac*(gw_area_table(i,m+1)-gw_area_table(i,m)) - enddo - enddo - endif - endif + select case (gw_option) + case (GW_HILL) + call soil_data_init_derive_subsurf_pars(tile%soil) + case (GW_HILL_AR5) + call soil_data_init_derive_subsurf_pars_ar5(tile%soil) + end select + enddo + end select ! gw_option + endif ! single geo - ! set dry soil albedo values, if requested + ! -------- set dry soil albedo values, if requested if (trim(albedo_to_use)=='albedo-map') then allocate(albedo(lnd%is:lnd%ie,lnd%js:lnd%je,NBANDS)) call read_field( 'INPUT/soil_albedo.nc','SOIL_ALBEDO_VIS',& @@ -359,10 +341,6 @@ subroutine soil_init ( id_lon, id_lat, id_band ) allocate( f_vol(lnd%is:lnd%ie,lnd%js:lnd%je,NBANDS)) allocate( f_geo(lnd%is:lnd%ie,lnd%js:lnd%je,NBANDS)) allocate(refl_dif(lnd%is:lnd%ie,lnd%js:lnd%je,NBANDS)) -! *********************** ????????? ************* -! sergey-- these are hig-res maps. is 'bilinear' the best option to use? i simply -! copied it from the albedo-map option. -! *********************** ????????? ************* call read_field( 'INPUT/soil_brdf.nc','f_iso_vis',& lnd%lon, lnd%lat, f_iso(:,:,BAND_VIS),'bilinear') call read_field( 'INPUT/soil_brdf.nc','f_vol_vis',& @@ -392,20 +370,96 @@ subroutine soil_init ( id_lon, id_lat, id_band ) else call error_mesg('soil_init',& 'option albedo_to_use="'// trim(albedo_to_use)//& - '" is invalid, use "albedo-map", "brdf-maps", or nothing ("")',& + '" is invalid, use "albedo-map", "brdf-maps", or empty line ("")',& FATAL) endif + ! -------- initialize soil state -------- + te = tail_elmt (lnd%tile_map) + ce = first_elmt(lnd%tile_map) + do while(ce /= te) + tile=>current_tile(ce) ! get pointer to current tile + ce=next_elmt(ce) ! advance position to the next tile + if (.not.associated(tile%soil)) cycle + if (init_wtdep .gt. 0.) then + psi = zfull - init_wtdep + call soil_data_vwc_for_init_only(tile%soil, psi, mwc) + mwc = mwc * dens_h2o + else if (init_w .ge. 0.) then + mwc = init_w + else ! negative init_w is to be intrepreted as prescribed saturation + mwc = -init_w*tile%soil%pars%vwc_sat*dens_h2o + endif + if (init_temp.ge.tile%soil%pars%tfreeze) then + tile%soil%prog%wl = mwc*dz(1:num_l) + tile%soil%prog%ws = 0 + else + tile%soil%prog%wl = 0 + tile%soil%prog%ws = mwc*dz(1:num_l) + endif + tile%soil%prog%T = init_temp + tile%soil%prog%groundwater = init_groundwater + tile%soil%prog%groundwater_T = init_temp + tile%soil%uptake_T = init_temp + enddo + + call get_input_restart_name('INPUT/soil.res.nc',restart_exists,restart_file_name) + if (restart_exists) then + call error_mesg('soil_init',& + 'reading NetCDF restart "'//trim(restart_file_name)//'"',& + NOTE) + __NF_ASRT__(nf_open(restart_file_name,NF_NOWRITE,unit)) + call read_tile_data_r1d_fptr(unit, 'temp' , soil_T_ptr ) + call read_tile_data_r1d_fptr(unit, 'wl' , soil_wl_ptr ) + call read_tile_data_r1d_fptr(unit, 'ws' , soil_ws_ptr ) + call read_tile_data_r1d_fptr(unit, 'groundwater' , soil_groundwater_ptr ) + call read_tile_data_r1d_fptr(unit, 'groundwater_T', soil_groundwater_T_ptr) + if(nfu_inq_var(unit, 'uptake_T')==NF_NOERR) & + call read_tile_data_r0d_fptr(unit, 'uptake_T', soil_uptake_T_ptr) + if(nfu_inq_var(unit, 'fsc')==NF_NOERR) then + call read_tile_data_r1d_fptr(unit,'fsc',soil_fast_soil_C_ptr) + call read_tile_data_r1d_fptr(unit,'ssc',soil_slow_soil_C_ptr) + else + ! try to read fsc and ssc from vegetation restart + call get_input_restart_name('INPUT/vegn2.res.nc',restart_exists,restart_file_name) + if (restart_exists) then + __NF_ASRT__(nf_open(restart_file_name,NF_NOWRITE,unit1)) + ! read old (scalar) fsc and ssc into the first element of the fast_soil_C + ! and slow_soil_C arrays + call read_tile_data_r1d_fptr(unit1,'fsc',soil_fast_soil_C_ptr,1) + call read_tile_data_r1d_fptr(unit1,'ssc',soil_slow_soil_C_ptr,1) + endif + endif + + __NF_ASRT__(nf_close(unit)) + else + call error_mesg('soil_init', 'cold-starting soil', NOTE) + endif + + ! read soil carbon restart, if present + call get_input_restart_name('INPUT/soil_carbon.res.nc',restart_exists,restart_file_name) + if (restart_exists) then + __NF_ASRT__(nf_open(restart_file_name,NF_NOWRITE,unit)) + call error_mesg('veg_data_init','reading soil_carbon restart',NOTE) + call read_tile_data_r1d_fptr(unit,'asoil_in',soil_asoil_in_ptr) + call read_tile_data_r1d_fptr(unit,'fsc_in',soil_fsc_in_ptr) + call read_tile_data_r1d_fptr(unit,'ssc_in',soil_ssc_in_ptr) + __NF_ASRT__(nf_close(unit)) + endif + ! ---- static diagnostic section call send_tile_data_r0d_fptr(id_tau_gw, lnd%tile_map, soil_tau_groundwater_ptr) call send_tile_data_r0d_fptr(id_slope_l, lnd%tile_map, soil_hillslope_length_ptr) call send_tile_data_r0d_fptr(id_slope_Z, lnd%tile_map, soil_hillslope_relief_ptr) call send_tile_data_r0d_fptr(id_zeta_bar, lnd%tile_map, soil_hillslope_zeta_bar_ptr) call send_tile_data_r0d_fptr(id_e_depth, lnd%tile_map, soil_soil_e_depth_ptr) + call send_tile_data_r0d_fptr(id_zeta, lnd%tile_map, soil_zeta_ptr) + call send_tile_data_r0d_fptr(id_tau, lnd%tile_map, soil_tau_ptr) call send_tile_data_r0d_fptr(id_vwc_wilt, lnd%tile_map, soil_vwc_wilt_ptr) call send_tile_data_r0d_fptr(id_vwc_fc, lnd%tile_map, soil_vwc_fc_ptr) call send_tile_data_r0d_fptr(id_vwc_sat, lnd%tile_map, soil_vwc_sat_ptr) call send_tile_data_r0d_fptr(id_K_sat, lnd%tile_map, soil_k_sat_ref_ptr) + call send_tile_data_r0d_fptr(id_K_gw, lnd%tile_map, soil_k_sat_gw_ptr) call send_tile_data_r1d_fptr(id_w_fc, lnd%tile_map, soil_w_fc_ptr) call send_tile_data_r1d_fptr(id_refl_dry_dir, lnd%tile_map, soil_refl_dry_dir_ptr) call send_tile_data_r1d_fptr(id_refl_dry_dif, lnd%tile_map, soil_refl_dry_dif_ptr) @@ -418,14 +472,6 @@ subroutine soil_init ( id_lon, id_lat, id_band ) call send_tile_data_r1d_fptr(id_f_vol_sat, lnd%tile_map, soil_f_vol_sat_ptr) call send_tile_data_r1d_fptr(id_f_geo_sat, lnd%tile_map, soil_f_geo_sat_ptr) call send_tile_data_i0d_fptr(id_type, lnd%tile_map, soil_tag_ptr) - - call send_tile_data_r0d_fptr(id_slope_Z_old, lnd%tile_map, soil_hillslope_relief_ptr) - call send_tile_data_r0d_fptr(id_e_depth_old, lnd%tile_map, soil_soil_e_depth_ptr) - call send_tile_data_r0d_fptr(id_vwc_wilt_old, lnd%tile_map, soil_vwc_wilt_ptr) - call send_tile_data_r0d_fptr(id_vwc_fc_old, lnd%tile_map, soil_vwc_fc_ptr) - call send_tile_data_r0d_fptr(id_vwc_sat_old, lnd%tile_map, soil_vwc_sat_ptr) - call send_tile_data_r0d_fptr(id_K_sat_old, lnd%tile_map, soil_k_sat_ref_ptr) - end subroutine soil_init @@ -450,6 +496,14 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) axes = (/ id_lon, id_lat, id_zfull /) ! define diagnostic fields + id_fast_soil_C = register_tiled_diag_field ( module_name, 'fast_soil_C', axes, & + Time, 'fast soil carbon', 'kg C/m3', missing_value=-100.0 ) + id_slow_soil_C = register_tiled_diag_field ( module_name, 'slow_soil_C', axes, & + Time, 'slow soil carbon', 'kg C/m3', missing_value=-100.0 ) + id_fsc = register_tiled_diag_field ( module_name, 'fsc', axes(1:2), & + Time, 'total fast soil carbon', 'kg C/m2', missing_value=-100.0 ) + id_ssc = register_tiled_diag_field ( module_name, 'ssc', axes(1:2), & + Time, 'total slow soil carbon', 'kg C/m2', missing_value=-100.0 ) id_lwc = register_tiled_diag_field ( module_name, 'soil_liq', axes, & Time, 'bulk density of liquid water', 'kg/m3', missing_value=-100.0 ) id_swc = register_tiled_diag_field ( module_name, 'soil_ice', axes, & @@ -464,16 +518,28 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) Time, 'satn runf', 'kg/(m2 s)', missing_value=-100.0 ) id_bf = register_tiled_diag_field ( module_name, 'soil_rbf', axes(1:2), & Time, 'baseflow', 'kg/(m2 s)', missing_value=-100.0 ) + id_if = register_tiled_diag_field ( module_name, 'soil_rif', axes(1:2), & + Time, 'interflow', 'kg/(m2 s)', missing_value=-100.0 ) + id_al = register_tiled_diag_field ( module_name, 'soil_ral', axes(1:2), & + Time, 'active layer flow', 'kg/(m2 s)', missing_value=-100.0 ) id_nu = register_tiled_diag_field ( module_name, 'soil_rnu', axes(1:2), & Time, 'numerical runoff', 'kg/(m2 s)', missing_value=-100.0 ) + id_sc = register_tiled_diag_field ( module_name, 'soil_rsc', axes(1:2), & + Time, 'lm2 groundwater runoff', 'kg/(m2 s)', missing_value=-100.0 ) id_hie = register_tiled_diag_field ( module_name, 'soil_hie', axes(1:2), & Time, 'heat ie runf', 'W/m2', missing_value=-100.0 ) id_hsn = register_tiled_diag_field ( module_name, 'soil_hsn', axes(1:2), & Time, 'heat sn runf', 'W/m2', missing_value=-100.0 ) id_hbf = register_tiled_diag_field ( module_name, 'soil_hbf', axes(1:2), & Time, 'heat bf runf', 'W/m2', missing_value=-100.0 ) + id_hif = register_tiled_diag_field ( module_name, 'soil_hif', axes(1:2), & + Time, 'heat if runf', 'W/m2', missing_value=-100.0 ) + id_hal = register_tiled_diag_field ( module_name, 'soil_hal', axes(1:2), & + Time, 'heat al runf', 'W/m2', missing_value=-100.0 ) id_hnu = register_tiled_diag_field ( module_name, 'soil_hnu', axes(1:2), & Time, 'heat nu runoff', 'W/m2', missing_value=-100.0 ) + id_hsc = register_tiled_diag_field ( module_name, 'soil_hsc', axes(1:2), & + Time, 'heat sc runoff', 'W/m2', missing_value=-100.0 ) id_evap = register_tiled_diag_field ( module_name, 'soil_evap', axes(1:2), & Time, 'soil evap', 'kg/(m2 s)', missing_value=-100.0 ) id_excess = register_tiled_diag_field ( module_name, 'sfc_excess', axes(1:2), & @@ -483,6 +549,14 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) Time, 'number of iterations for soil uptake', missing_value=-100.0 ) id_uptk = register_tiled_diag_field ( module_name, 'soil_uptk', axes, & Time, 'uptake of water by roots', 'kg/(m2 s)', missing_value=-100.0 ) + id_psi_x0 = register_tiled_diag_field ( module_name, 'soil_psix0', axes(1:2), & + Time, 'xylem potential at z=0', 'm', missing_value=-100.0 ) + id_deficit = register_tiled_diag_field ( module_name, 'soil_def', axes(1:2), & + Time, 'groundwater storage deficit', '-', missing_value=-100.0 ) + id_deficit_2 = register_tiled_diag_field ( module_name, 'soil_def2', axes(1:2), & + Time, 'groundwater storage deficit2', '-', missing_value=-100.0 ) + id_deficit_3 = register_tiled_diag_field ( module_name, 'soil_def3', axes(1:2), & + Time, 'groundwater storage deficit3', '-', missing_value=-100.0 ) id_psi_bot = register_tiled_diag_field ( module_name, 'soil_psi_n', axes(1:2), & Time, 'psi at bottom of soil column', 'm', missing_value=-100.0 ) id_sat_frac = register_tiled_diag_field ( module_name, 'soil_fsat', axes(1:2), & @@ -491,25 +565,35 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) Time, 'groundwater storage frac above base elev', '-', missing_value=-100.0 ) id_sat_depth = register_tiled_diag_field ( module_name, 'soil_wtdep', axes(1:2), & Time, 'depth below sfc to saturated soil', 'm', missing_value=-100.0 ) - - ! ---- the following fields are for compatibility with older diag tables - id_uptk_old = register_tiled_diag_field ( module_name, 'uptake', axes, & - Time, 'uptake of water by roots (obsolete, use "soil_uptk" instead)', & - 'kg/(m2 s)', missing_value=-100.0 ) - id_psi_bot_old = register_tiled_diag_field ( module_name, 'psi_bot', axes(1:2), & - Time, 'psi at bottom of soil column (obsolete, use "soil_psi_n" instead)', & - 'm', missing_value=-100.0 ) - id_sat_frac_old = register_tiled_diag_field ( module_name, 'sat_frac', axes(1:2), & - Time, 'fraction of soil area saturated at surface (obsolete, use "soil_fsat" instead)',& - '-', missing_value=-100.0 ) - id_stor_frac_old = register_tiled_diag_field ( module_name, 'stor_frac', axes(1:2), & - Time, 'groundwater storage frac above base elev (obsolete, use "soil_fgw" instead)',& - '-', missing_value=-100.0 ) - id_sat_depth_old = register_tiled_diag_field ( module_name, 'sat_depth', axes(1:2), & - Time, 'depth below sfc to saturated soil (obsolete, use "soil_wtdep" instead)', & - 'm', missing_value=-100.0 ) - ! ---- end of compatibility section - + id_sat_dept2 = register_tiled_diag_field ( module_name, 'soil_wtdp2', axes(1:2), & + Time, 'alt depth below sfc to saturated soil', 'm', missing_value=-100.0 ) + id_z_cap = register_tiled_diag_field ( module_name, 'soil_zcap', axes(1:2), & + Time, 'depth below sfc to capillary fringe', 'm', missing_value=-100.0 ) + + id_div_bf = register_tiled_diag_field ( module_name, 'soil_dvbf', axes, & + Time, 'baseflow by layer', 'kg/(m2 s)', missing_value=-100.0 ) + id_div_if = register_tiled_diag_field ( module_name, 'soil_dvif', axes, & + Time, 'interflow by layer', 'kg/(m2 s)', missing_value=-100.0 ) + id_div_al = register_tiled_diag_field ( module_name, 'soil_dval', axes, & + Time, 'active-layer flow by layer', 'kg/(m2 s)', missing_value=-100.0 ) + + id_cf_1 = register_tiled_diag_field ( module_name, 'soil_cf_1', axes(1:2), & + Time, 'soil_cf_1', 'm', missing_value=-100.0 ) + id_cf_3 = register_tiled_diag_field ( module_name, 'soil_cf_3', axes(1:2), & + Time, 'soil_cf_1', 'm', missing_value=-100.0 ) + id_wt_1 = register_tiled_diag_field ( module_name, 'soil_wt_1', axes(1:2), & + Time, 'soil_wt_1', 'm', missing_value=-100.0 ) + id_wt_2 = register_tiled_diag_field ( module_name, 'soil_wt_2', axes(1:2), & + Time, 'soil_wt_2', 'm', missing_value=-100.0 ) + id_wt_2a = register_tiled_diag_field ( module_name, 'soil_wt_2a', axes(1:2), & + Time, 'soil_wt_2a', 'm', missing_value=-100.0 ) + id_wt_3 = register_tiled_diag_field ( module_name, 'soil_wt_3', axes(1:2), & + Time, 'soil_wt_3', 'm', missing_value=-100.0 ) + id_wt2_3 = register_tiled_diag_field ( module_name, 'soil_wt2_3', axes(1:2), & + Time, 'soil_wt2_3', 'm', missing_value=-100.0 ) + + id_active_layer = register_tiled_diag_field ( module_name, 'soil_alt', axes(1:2), & + Time, 'active-layer thickness', 'm', missing_value=-100.0 ) id_heat_cap = register_tiled_diag_field ( module_name, 'soil_heat_cap', & axes, Time, 'heat capacity of dry soil','J/(m3 K)', missing_value=-100.0 ) id_thermal_cond = register_tiled_diag_field ( module_name, 'soil_tcon', & @@ -527,6 +611,10 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) axes(1:2), 'hillslope zeta bar', '-', missing_value=-100.0 ) id_e_depth = register_tiled_static_field ( module_name, 'soil_depth', & axes(1:2), 'soil e-folding depth', 'm', missing_value=-100.0 ) + id_zeta = register_tiled_static_field ( module_name, 'soil_zeta', & + axes(1:2), 'soil depth/topo relief', '-', missing_value=-100.0 ) + id_tau = register_tiled_static_field ( module_name, 'soil_tau', & + axes(1:2), 'gw transmissivity/soil transmissivity', '-', missing_value=-100.0 ) id_vwc_wilt = register_tiled_static_field ( module_name, 'soil_wilt', & axes(1:2), 'wilting water content', '-', missing_value=-100.0 ) id_vwc_fc = register_tiled_static_field ( module_name, 'soil_fc', & @@ -535,6 +623,8 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) axes(1:2), 'soil porosity', '-', missing_value=-100.0 ) id_K_sat = register_tiled_static_field ( module_name, 'soil_Ksat', & axes(1:2), 'soil sat. hydraulic conductivity', 'kg /(m2 s)', missing_value=-100.0 ) + id_K_gw = register_tiled_static_field ( module_name, 'soil_K_gw', & + axes(1:2), 'deep hydraulic conductivity', 'kg /(m2 s)', missing_value=-100.0 ) id_w_fc = register_tiled_static_field ( module_name, 'w_fc', & axes, 'soil field capacity', missing_value=-1.0 ) id_refl_dry_dir = register_tiled_static_field ( module_name, 'refl_dry_dir', & @@ -569,22 +659,22 @@ subroutine soil_diag_init ( id_lon, id_lat, id_band ) missing_value=-1.0 ) ! the following fields are for compatibility with older diag tables only - id_slope_Z_old = register_tiled_static_field ( module_name, 'slope_Z', & + call add_tiled_static_field_alias ( id_slope_Z, module_name, 'slope_Z', & axes(1:2), 'hillslope relief (obsolete, use "soil_rlief" instead)',& 'm', missing_value=-100.0 ) - id_e_depth_old = register_tiled_static_field ( module_name, 'e_depth', & + call add_tiled_static_field_alias ( id_e_depth, module_name, 'e_depth', & axes(1:2), 'soil e-folding depth (obsolete, use "soil_depth" instead)', & 'm', missing_value=-100.0 ) - id_vwc_wilt_old = register_tiled_static_field ( module_name, 'vwc_wilt', & + call add_tiled_static_field_alias ( id_vwc_wilt, module_name, 'vwc_wilt', & axes(1:2), 'wilting water content (obsolete, use "soil_wilt" instead)', & '-', missing_value=-100.0 ) - id_vwc_fc_old = register_tiled_static_field ( module_name, 'vwc_fc', & + call add_tiled_static_field_alias ( id_vwc_fc, module_name, 'vwc_fc', & axes(1:2), 'field capacity (obsolete, use "soil_fc" instead)', & '-', missing_value=-100.0 ) - id_vwc_sat_old = register_tiled_static_field ( module_name, 'vwc_sat', & + call add_tiled_static_field_alias ( id_vwc_sat, module_name, 'vwc_sat', & axes(1:2), 'soil porosity (obsolete, use "soil_sat")', & '-', missing_value=-100.0 ) - id_K_sat_old = register_tiled_static_field ( module_name, 'K_sat', & + call add_tiled_static_field_alias ( id_K_sat, module_name, 'K_sat', & axes(1:2), 'soil sat. hydraulic conductivity (obsolte, use "soil_Ksat" instead)', & 'kg /(m2 s)', missing_value=-100.0 ) @@ -625,10 +715,29 @@ subroutine save_soil_restart (tile_dim_length, timestamp) call write_tile_data_r1d_fptr(unit,'groundwater' ,soil_groundwater_ptr ,'zfull') call write_tile_data_r1d_fptr(unit,'groundwater_T',soil_groundwater_T_ptr ,'zfull') call write_tile_data_r0d_fptr(unit,'uptake_T', soil_uptake_T_ptr, 'temperature of transpiring water', 'degrees_K') + call write_tile_data_r1d_fptr(unit,'fsc', soil_fast_soil_C_ptr,'zfull','fast soil carbon', 'kg C/m2') + call write_tile_data_r1d_fptr(unit,'ssc', soil_slow_soil_C_ptr,'zfull','slow soil carbon', 'kg C/m2') ! close file __NF_ASRT__(nf_close(unit)) + if (write_soil_carbon_restart) then + call create_tile_out_file(unit,'RESTART/'//trim(timestamp)//'soil_carbon.res.nc', & + lnd%coord_glon, lnd%coord_glat, soil_tile_exists, tile_dim_length ) + ! in addition, define vertical coordinate + if (mpp_pe()==lnd%io_pelist(1)) then + __NF_ASRT__(nfu_def_dim(unit,'zfull',zfull(1:num_l),'full level','m')) + __NF_ASRT__(nfu_put_att(unit,'zfull','positive','down')) + endif + call sync_nc_files(unit) + + call write_tile_data_r1d_fptr(unit,'asoil_in',soil_asoil_in_ptr,'zfull','aerobic activity modifier', 'unitless') + call write_tile_data_r1d_fptr(unit,'fsc_in',soil_fsc_in_ptr,'zfull','fast soil carbon input', 'kg C/m2') + call write_tile_data_r1d_fptr(unit,'ssc_in',soil_ssc_in_ptr,'zfull','slow soil carbon input', 'kg C/m2') + __NF_ASRT__(nf_close(unit)) + endif + + end subroutine save_soil_restart @@ -651,12 +760,10 @@ subroutine soil_radiation ( soil, cosz, & call soil_data_radiation ( soil, cosz, use_brdf, soil_refl_dir, soil_refl_dif, soil_emis ) soil_refl_lw = 1 - soil_emis - if(any(soil_refl_dif<0).or.any(soil_refl_dif>1).or.& - any(soil_refl_dir<0).or.any(soil_refl_dir>1)) then - write(*,*)'soil_refl is out of range' - write(*,*)'soil_refl_dif=',soil_refl_dif - write(*,*)'soil_refl_dir=',soil_refl_dir - endif + call check_var_range(soil_refl_dir(BAND_VIS), 0.0, 1.0, 'soil_radiation', 'soil_refl_dir(VIS)', lnd%time, FATAL) + call check_var_range(soil_refl_dir(BAND_NIR), 0.0, 1.0, 'soil_radiation', 'soil_refl_dir(NIR)', lnd%time, FATAL) + call check_var_range(soil_refl_dif(BAND_VIS), 0.0, 1.0, 'soil_radiation', 'soil_refl_dif(VIS)', lnd%time, FATAL) + call check_var_range(soil_refl_dif(BAND_NIR), 0.0, 1.0, 'soil_radiation', 'soil_refl_dif(NIR)', lnd%time, FATAL) end subroutine soil_radiation @@ -692,11 +799,9 @@ subroutine soil_data_beta ( soil, vegn, soil_beta, soil_water_supply, & uptake_frac_max, & ! root distribution vegn_uptake_term, & vlc, vsc, & ! volumetric fractions of water and ice in the layer - DThDP, hyd_cond, DKDP, soil_w_fc, & ! soil hydraulic parameters (not used) VRL, & ! vertical distribution of volumetric root length, m/m3 u, du ! uptake and its derivative (the latter is not used) - real :: DPsi_min, DPsi_max, tau_gw, psi_for_rh - real :: gw_length, gw_relief, gw_zeta_bar, gw_e_depth, K_sat ! soil hydraulic parameters (not used) + real :: psi_for_rh real :: K_r, r_r ! root properties real :: z ! soil depth @@ -724,13 +829,8 @@ subroutine soil_data_beta ( soil, vegn, soil_beta, soil_water_supply, & enddo if (lm2) soil%uptake_frac = uptake_frac_max - ! calculate soil hydraulic properties, in particular psi_for_rh -- we don't use - ! anything else in this subroutine. this moved out of 'case' because - ! we need psi unconditionally now for soil_rh - - call soil_data_hydraulics ( soil, vlc, vsc, & - soil%psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max, tau_gw, & - psi_for_rh, soil_w_fc ) + ! calculate relative humidity at soil surface + call soil_data_psi_for_rh ( soil, vlc, vsc, soil%psi, psi_for_rh ) soil_rh = exp(psi_for_rh*g_RT) soil_rh_psi = g_RT*soil_rh @@ -846,7 +946,8 @@ subroutine soil_step_1 ( soil, vegn, diag, & bbb = 1.0 - aaa(num_l) denom = bbb - dt_e = aaa(num_l)*(soil%prog(num_l)%T - soil%prog(num_l-1)%T) + dt_e = aaa(num_l)*(soil%prog(num_l)%T - soil%prog(num_l-1)%T) & + + soil%geothermal_heat_flux * delta_time / heat_capacity(num_l) soil%e(num_l-1) = -aaa(num_l)/denom soil%f(num_l-1) = dt_e/denom do l = num_l-1, 2, -1 @@ -916,27 +1017,26 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, soil_lrunf, soil_hlrunf, soil_Ttop, soil_Ctop ! ---- local vars ---------------------------------------------------------- - real, dimension(num_l) :: del_t, eee, fff, & - psi, DThDP, hyd_cond, DKDP, K, DKDPm, DKDPp, grad, & - vlc, vsc, dW_l, u_minus, u_plus, DPsi, soil_w_fc, soil_vwc_sat + real, dimension(num_l) :: del_t, psi, DThDP, hyd_cond, DKDP, & + vlc, vsc, dW_l, DPsi real, dimension(num_l+1) :: flow, infilt - real, dimension(num_l ) :: div, dq, div_active - real :: & + real, dimension(num_l ) :: div, div_bf, div_if, div_al, dq, div_active + real :: & lprec_eff, hlprec_eff, tflow, hcap,cap_flow, dheat, & - melt_per_deg, melt, adj, & - liq_to_extract, ice_to_extract, heat_of_extract, & - liq_to_extract_here, ice_to_extract_here, & - lrunf_sn,lrunf_ie,lrunf_bf,lrunf_nu, hlrunf_sn,hlrunf_ie,hlrunf_bf,hlrunf_nu, & - Qout, DQoutDP, tau_gw, gw_length, gw_relief, gw_zeta_bar, gw_e_depth, K_sat, & - c0, c1, c2, x, aaa, bbb, ccc, ddd, xxx, sat_frac, z_sat, & - gw_flux, storage_frac, depth_to_saturation, & - Dpsi_min, Dpsi_max, psi_for_rh, & - liq_frac, excess_wat, excess_liq, excess_ice, h1, h2, summax, & - space_avail, liq_placed, ice_placed, excess_t, dW_l_internal, w_to_move_up - logical :: stiff, flag - real, dimension(num_l-1) :: del_z - integer :: n_iter, l, ipt, jpt, kpt, fpt, l_internal, l_max_active_layer - real :: jj,dpsi_alt + melt_per_deg, melt, & + lrunf_sn,lrunf_ie,lrunf_bf,lrunf_if,lrunf_al,lrunf_nu,lrunf_sc, d_GW, & + hlrunf_sn,hlrunf_ie,hlrunf_bf,hlrunf_if,hlrunf_al,hlrunf_nu,hlrunf_sc, & + c0, c1, c2, Dpsi_min, Dpsi_max, & + sat_area_frac, sat_thick, sum_trans, & + gw_flux, depth_to_wt, depth_to_wt2_3, depth_to_wt_apparent, & + depth_to_gw_flow_3, deficit, z_bot, & + active_layer_thickness, depth_to_cf, d_psi, d_psi_s, psi_star, & + depth_to_cf_1, depth_to_cf_3, & + depth_to_wt_1, depth_to_wt_2, depth_to_wt_2a, depth_to_wt_3, & + storage_2, deficit_2, deficit_3 + logical :: stiff + real :: zimh, ziph, dTr_g(num_l), dTr_s(num_l) + integer :: n_iter, l, l_max_active_layer real :: & VRL(num_l), & ! volumetric root length, m/m3 K_r, & ! root membrame permeability, kg/(m3 s) @@ -946,11 +1046,13 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, uptake_pos, & ! sum of the positive uptake, kg/(m2 s) uptake_T_new, & ! updated average temperature of uptaken water, deg K uptake_T_corr,& ! correction for uptake temperature, deg K - Tu ! temperature of water taken up from (or added to) a layer, deg K - - jj = 1. - flag = .false. + Tu, & ! temperature of water taken up from (or added to) a layer, deg K + psi_x0 ! water potential inside roots (in xylem) at zero depth, m + + ! -------------------------------------------------------------------------- + + !......................................................................... if(is_watch_point()) then write(*,*) ' ##### soil_step_2 checkpoint 1 #####' write(*,*) 'mask ', .true. @@ -960,48 +1062,51 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, write(*,*) 'subs_M_imp ', subs_M_imp write(*,*) 'theta_s ', soil%pars%vwc_sat do l = 1, num_l - write(*,'(a,i2.2,100(2x,a,g))') 'level=', l,& + write(*,'(a,i2.2,100(2x,a,g23.16))') 'level=', l,& ' T =', soil%prog(l)%T,& ' Th=', (soil%prog(l)%ws+soil%prog(l)%wl)/(dens_h2o*dz(l)),& ' wl=', soil%prog(l)%wl,& ' ws=', soil%prog(l)%ws,& ' gw=', soil%prog(l)%groundwater enddo - endif + endif + !......................................................................... - ! ---- record fluxes --------- + ! ---- record fluxes ----------------------------------------------------- soil_levap = subs_evap*(1-soil_subl) soil_fevap = subs_evap* soil_subl soil_melt = subs_M_imp / delta_time - ! ---- load surface temp change and perform back substitution -------------- + ! ---- load surface temp change and perform back substitution ------------ del_t(1) = subs_DT soil%prog(1)%T = soil%prog(1)%T + del_t(1) if ( num_l > 1) then do l = 1, num_l-1 del_t(l+1) = soil%e(l) * del_t(l) + soil%f(l) soil%prog(l+1)%T = soil%prog(l+1)%T + del_t(l+1) - end do - end if + enddo + endif + !......................................................................... if(is_watch_point()) then write(*,*) ' ##### soil_step_2 checkpoint 2 #####' do l = 1, num_l - write(*,'(a,i2.2,100(2x,a,g))') 'level=',l, 'T=', soil%prog(l)%T, & + write(*,'(a,i2.2,100(2x,a,g23.16))') 'level=',l, 'T=', soil%prog(l)%T, & 'del_t=', del_t(l), 'e=', soil%e(l), 'f=', soil%f(l) - enddo - endif + enddo + endif + !......................................................................... - ! ---- extract evap from soil and do implicit melt -------------------- - IF(LM2) THEN - do l = 1, num_l - soil%prog(l)%wl = soil%prog(l)%wl & + ! ---- extract evap from soil, adjusting T, and do implicit melt --------- + IF (LM2) THEN ! (extract surface E--is there any?--uniformly from bucket) + do l = 1, num_l + soil%prog(l)%wl = soil%prog(l)%wl & - soil%uptake_frac(l)*soil_levap*delta_time - enddo - ELSE - soil%prog(1)%wl = soil%prog(1)%wl - soil_levap*delta_time - soil%prog(1)%ws = soil%prog(1)%ws - soil_fevap*delta_time - ENDIF + enddo + ELSE + soil%prog(1)%wl = soil%prog(1)%wl - soil_levap*delta_time + soil%prog(1)%ws = soil%prog(1)%ws - soil_fevap*delta_time + ENDIF hcap = soil%heat_capacity_dry(1)*dz(1) & + clw*soil%prog(1)%wl + csw*soil%prog(1)%ws ! T adjustment for nonlinear terms (del_T)*(del_W) @@ -1016,12 +1121,13 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, soil%prog(1)%T = tfreeze + (hcap*(soil%prog(1)%T-tfreeze) ) & / ( hcap + (clw-csw)*subs_M_imp ) - ! calculate actual vertical distribution of uptake + ! ---- calculate actual uptake and update its T -------------------------- select case(uptake_option) case ( UPTAKE_LINEAR ) uptake_T_corr = 0 n_iter = 0 uptake = soil%uptake_frac*vegn_uptk + soil%psi_x0 = 0. case ( UPTAKE_DARCY2D, UPTAKE_DARCY2D_LIN ) ! for Darcy-flow uptake, find the root water potential to satify actual ! transpiration by the vegetation @@ -1029,11 +1135,12 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, if ( uptake_option==UPTAKE_DARCY2D ) then call darcy2d_uptake_solver ( soil, vegn_uptk, VRL, K_r, r_r, & - uptake_oneway, uptake_from_sat, uptake, n_iter) + uptake_oneway, uptake_from_sat, uptake, psi_x0, n_iter) else call darcy2d_uptake_solver_lin ( soil, vegn_uptk, VRL, K_r, r_r, & - uptake_oneway, uptake_from_sat, uptake, n_iter ) + uptake_oneway, uptake_from_sat, uptake, psi_x0, n_iter ) endif + soil%psi_x0 = psi_x0 uptake_pos = sum(uptake(:),mask=uptake(:)>0) if (uptake_pos > 0) then @@ -1055,54 +1162,507 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, call error_mesg('soil_step_2', 'invalid soil uptake option', FATAL) end select + !......................................................................... if (is_watch_point())then - write(*,*) ' ##### soil_step_2 checkpoint 2.1 #####' - __DEBUG2__(vegn_uptk,sum(uptake)) - do l = 1,num_l - write(*,'(a,i2.2,100(2x,a,g))')'level=',l, & + write(*,*) ' ##### soil_step_2 checkpoint 2.1 #####' + __DEBUG2__(vegn_uptk,sum(uptake)) + do l = 1,num_l + write(*,'(a,i2.2,100(2x,a,g23.16))')'level=',l, & 'uptake=',uptake(l),'dwl=',-uptake(l)*delta_time,& 'wl=',soil%prog(l)%wl,'new wl=',soil%prog(l)%wl - uptake(l)*delta_time - enddo - endif + enddo + endif + !......................................................................... call send_tile_data(id_uptk_n_iter, real(n_iter), diag) call send_tile_data(id_uptk, uptake, diag) - call send_tile_data(id_uptk_old, uptake, diag) + call send_tile_data(id_psi_x0, psi_x0, diag) - ! update temperature and water content of soil due to root uptake processes + ! ---- perform the uptake ------------------------------------------------ do l = 1, num_l - ! calculate the temperature of water that is taken from the layer (or added - ! to the layer), including energy balance correction - if (uptake(l) > 0) then + ! calculate the temperature of water that is taken from the layer (or added + ! to the layer), including energy balance correction + if (uptake(l) > 0) then Tu = soil%prog(l)%T + uptake_T_corr - else + else Tu = soil%uptake_T + uptake_T_corr - endif - ! heat capacity of the layer - hcap = soil%heat_capacity_dry(l)*dz(l) & + endif + hcap = soil%heat_capacity_dry(l)*dz(l) & + clw*soil%prog(l)%wl + csw*soil%prog(l)%ws - - soil%prog(l)%T = soil%prog(l)%T - & + soil%prog(l)%T = soil%prog(l)%T - & uptake(l)*delta_time*clw*( Tu-soil%prog(l)%T ) / & ( hcap - uptake(l)*delta_time*clw ) - soil%prog(l)%wl = soil%prog(l)%wl - uptake(l)*delta_time - enddo + soil%prog(l)%wl = soil%prog(l)%wl - uptake(l)*delta_time + enddo + !......................................................................... if(is_watch_point()) then - write(*,*) ' ##### soil_step_2 checkpoint 3 #####' - do l = 1, num_l - write(*,'(a,i2.2,100(2x,a,g))') ' level=', l,& + write(*,*) ' ##### soil_step_2 checkpoint 3 #####' + do l = 1, num_l + write(*,'(a,i2.2,100(2x,a,g23.16))') ' level=', l,& ' T =', soil%prog(l)%T,& ' Th=', (soil%prog(l)%ws+soil%prog(l)%wl)/(dens_h2o*dz(l)),& ' wl=', soil%prog(l)%wl,& ' ws=', soil%prog(l)%ws + enddo + endif + !......................................................................... + + ! ---- push down any excess surface water, with heat --------------------- + IF (PUSH_DOWN_SFC_EXCESS) THEN + CALL SOIL_PUSH_DOWN_EXCESS ( soil, diag, lrunf_nu, hlrunf_nu ) + ELSE + lrunf_nu=0; hlrunf_nu=0 + ENDIF + + ! ---- fetch soil hydraulic properties ----------------------------------- + do l = 1, num_l + vlc(l) = max(0., soil%prog(l)%wl / (dens_h2o*dz(l))) + vsc(l) = max(0., soil%prog(l)%ws / (dens_h2o*dz(l))) + enddo + call soil_data_hydraulic_properties (soil, vlc, vsc, & + psi, DThDP, hyd_cond, DKDP, Dpsi_min, Dpsi_max ) + + ! ---- compute various measures of water table depth --------------------- + sat_thick = 0. + do l=num_l,1,-1 + if(vsc(l)+vlc(l).le.soil%pars%vwc_sat) exit + sat_thick = sat_thick + dz(l) + enddo + depth_to_cf_1 = zhalf(num_l+1) - sat_thick + depth_to_wt_1 = depth_to_cf_1 - soil%pars%psi_sat_ref/soil%alpha(max(l,1)) + + depth_to_wt_2 = zfull(num_l)-psi(num_l) + + depth_to_wt_2a = 0. + do l=1,num_l + if (soil%prog(l)%wl+soil%prog(l)%ws .lt. & + soil%pars%vwc_sat*dens_h2o*dz(l)) then + depth_to_wt_2a = depth_to_wt_2a + dz(l) + if (l.eq.num_l) depth_to_wt_2a = -1. + else + exit + endif + enddo + storage_2 = 1 - depth_to_wt_2 & + /(soil%pars%hillslope_zeta_bar*soil%pars%hillslope_relief) + storage_2 = min( max( 0., storage_2 ) , 1.) + deficit_2 = 1 - storage_2 + + if (vsc(num_l).gt.0.) then ! permafrost + depth_to_wt2_3 = 0. + depth_to_cf_3 = 0. + depth_to_wt_3 = 0. + else ! liquid water at depth + depth_to_cf_3 = 0. + if (use_fringe) then + do l = num_l, 1, -1 + if ( l.eq.num_l .and. psi(l).le.soil%pars%psi_sat_ref/soil%alpha(l) ) then + depth_to_cf_3 = zfull(l) + soil%pars%psi_sat_ref/soil%alpha(l) - psi(l) + exit + else if (psi(l).le.soil%pars%psi_sat_ref/soil%alpha(l) ) then + d_psi = psi(l+1) - psi(l) + d_psi_s = (soil%pars%psi_sat_ref/soil%alpha(l+1)) & + -(soil%pars%psi_sat_ref/soil%alpha(l)) + psi_star = (psi(l)*d_psi_s - & + d_psi*(soil%pars%psi_sat_ref/soil%alpha(l)))& + / (d_psi_s - d_psi) + depth_to_cf_3 = zfull(l) + (zfull(l+1)-zfull(l)) & + * (psi_star-psi(l)) / d_psi + exit + else if (l.eq.1) then + d_psi = psi(l+1) - psi(l) + d_psi_s = (soil%pars%psi_sat_ref/soil%alpha(l+1)) & + -(soil%pars%psi_sat_ref/soil%alpha(l)) + psi_star = (psi(l)*d_psi_s - & + d_psi*(soil%pars%psi_sat_ref/soil%alpha(l)))& + / (d_psi_s - d_psi) + depth_to_cf_3 = zfull(l) + (zfull(l+1)-zfull(l)) & + * (psi_star-psi(l)) / d_psi + depth_to_cf_3 = max(0.,depth_to_cf_3) + endif + enddo + endif + depth_to_wt_3 = max(0., zhalf(num_l+1)-(psi(num_l)+dz(num_l)/2.)) + depth_to_wt2_3 = depth_to_wt_3 + endif + + if (use_fringe) then + depth_to_gw_flow_3 = depth_to_cf_3 + else + depth_to_gw_flow_3 = depth_to_wt_3 + endif + deficit_3 = depth_to_gw_flow_3 & + /(soil%pars%hillslope_zeta_bar*soil%pars%hillslope_relief) + + ! ---- get saturated area and column flow divergences -------------------- + SELECT CASE(gw_option) + + CASE(GW_LM2) + + div_bf=0; div_if=0; div_al=0; sat_area_frac = 0 + + CASE(GW_LINEAR) + + IF (CORRECTED_LM2_GW) THEN + do l = 1, num_l + if (vlc(l) .ge. soil%pars%vwc_sat .and. vsc(l).le.0.) & + div_bf(l) = 0.15*dens_h2o*dz(l)/soil%pars%tau_groundwater + enddo + ELSE + do l = 1, num_l + if ((vsc(l)+vlc(l)) .ge. soil%pars%vwc_sat) & + div_bf(l) = 0.15*dens_h2o*dz(l)*(vlc(l)/(vsc(l)+vlc(l))) & + /soil%pars%tau_groundwater + enddo + ENDIF + div_if = 0 + div_al = 0 + sat_thick = zhalf(num_l+1) - depth_to_cf_1 + sat_area_frac = min((sat_thick/zhalf(num_l+1))**soil%pars%rsa_exp,1.) + + CASE(GW_HILL_AR5) + + call soil_data_gw_hydraulics_ar5(soil, storage_2, & + gw_flux, sat_area_frac) + dq = 0. + sat_thick = 0. + do l=num_l,1,-1 + if(psi(l).le.0.) exit + if (vsc(l).le.0.) dq(l) = dz(l) + sat_thick = sat_thick + dz(l) + enddo + div_bf = 0. + if (sat_thick.gt.0.) div_bf = (dq/sat_thick)*gw_flux + + div_active = 0. + l_max_active_layer = 0 + do l=1,num_l + if(vsc(l).gt.0.) exit + l_max_active_layer = l + enddo + if (l_max_active_layer.lt.num_l .and. l_max_active_layer.gt.0) then + do l = 1, l_max_active_layer + if(vlc(l).gt.0) & + div_active(l) = hyd_cond(l) * soil%pars%hillslope_relief*dz(l) & + / (soil%pars%hillslope_length*soil%pars%hillslope_length) + enddo + endif + + div_al = 0 + where (div_bf.eq.0.) div_al = div_active*active_layer_drainage_acceleration + div_if = 0 + + CASE(GW_HILL) + + if (vsc(num_l).gt.0.) then ! permafrost + sat_area_frac = 0. + div_bf = 0. + div_if = 0. + else ! liquid water at depth + call soil_data_gw_hydraulics(soil, deficit_3, & + gw_flux, sat_area_frac) + gw_flux = min(gw_flux, gw_flux_max) + dTr_g = 0. + dTr_s = 0. + dTr_g(num_l) = 1. + l = num_l + ziph = sum(dz) + zimh = ziph - dz(num_l) + if (depth_to_gw_flow_3 .lt. zimh) then + dTR_g(l) = dz(l) + dTr_s(l) = (exp(-zimh/soil%pars%soil_e_depth)) + do l = num_l-1, 1, -1 + if (vsc(l).gt.0.) exit + ziph = zimh + zimh = ziph - dz(l) + if (depth_to_gw_flow_3 .lt. zimh) then + dTR_g(l) = dz(l) + dTr_s(l) = exp(-zimh/soil%pars%soil_e_depth)-exp(-ziph/soil%pars%soil_e_depth) + else if (depth_to_gw_flow_3 .lt. ziph) then + dTR_g(l) =(ziph-depth_to_gw_flow_3) + dTr_s(l) = exp(-depth_to_gw_flow_3/soil%pars%soil_e_depth)-exp(-ziph/soil%pars%soil_e_depth) + else + exit + endif + enddo + endif + sum_trans = sum(dTr_g) + if (sum_trans.ne.0.) then + dTR_g = dTR_g / sum_trans + dTR_g = dTR_g * soil%pars%k_sat_gw*aspect*soil%pars%hillslope_length + endif + dTR_s = dTR_s * (soil%pars%k_sat_sfc+k_macro_constant)*soil%pars%soil_e_depth + sum_trans = sum(dTR_g) + sum(dTr_s) + if (sum_trans.ne.0.) then + div_bf = gw_flux * dTR_g /sum_trans + div_if = gw_flux * dTR_s /sum_trans + else + div_bf = 0. + div_if = 0. + endif + endif + + div_al = 0 + l_max_active_layer = 0 ! "active layer" either over permafrost or perched + do l=1,num_l + if(vsc(l).gt.0.) exit + l_max_active_layer = l + enddo + if (l_max_active_layer.lt.num_l .and. l_max_active_layer.gt.0) then + do l = 1, l_max_active_layer + div_al(l) = hyd_cond(l) * soil%pars%hillslope_relief*dz(l) & + / (soil%pars%hillslope_length*soil%pars%hillslope_length) + enddo + endif + + END SELECT + + div = div_bf + div_if + div_al + lrunf_bf = sum(div_bf) + lrunf_if = sum(div_if) + lrunf_al = sum(div_al) + + if (snow_lprec.ne.0.) then + lrunf_sn = sat_area_frac * snow_lprec + hlrunf_sn = lrunf_sn*snow_hlprec/snow_lprec + else + lrunf_sn = 0. + hlrunf_sn = 0. + endif + hlrunf_ie=0 + lprec_eff = snow_lprec - lrunf_sn + hlprec_eff = snow_hlprec - hlrunf_sn + + if(is_watch_point()) then + do l = 1, num_l + write(*,'(a,1x,i2.2,100(2x,g23.16))')'div_ac,div_bf,div_if,div_al,div', & + l,div_active(l),div_bf(l),div_if(l),div_al(l),div(l) + enddo + do l = 1, num_l + write(*,'(a,1x,i2.2,100(2x,g23.16))')'vsc,psi,dz',l,vsc(l),psi(l),dz(l) + enddo + write(*,*)'lrunf_bf',lrunf_bf + write(*,*)'tau_gw',soil%pars%tau_groundwater + write(*,*)'dens_h2o',dens_h2o + endif + + ! ---- soil-water flow ---------------------------------------------------- + IF (LM2) THEN + flow(1) = 0 + do l = 1, num_l + infilt(l) = soil%uptake_frac(l)*lprec_eff *delta_time + flow(l+1) = max(0., soil%prog(l)%wl + flow(l) & + + infilt(l) - soil%w_fc(l)*dz(l)*dens_h2o) + dW_l(l) = flow(l) - flow(l+1) + infilt(l) + soil%prog(l)%wl = soil%prog(l)%wl + dW_l(l) + enddo + do l = 1, num_l + flow(l) = flow(l) + infilt(l) + enddo + dW_l=0 + dpsi=0 + c0 = delta_time/soil%pars%tau_groundwater + c1 = exp(-c0) + c2 = (1-c1)/c0 + l = 1 + d_GW = c1 * soil%prog(l)%groundwater + c2 * flow(num_l+1) & + - soil%prog(l)%groundwater + soil%prog(l)%groundwater = soil%prog(l)%groundwater + d_GW + lrunf_sc = (1-c1)*soil%prog(l)%groundwater/delta_time & + + (1-c2)*flow(num_l+1)/delta_time + lrunf_ie=0 + ELSE + lrunf_sc = 0 + d_GW = 0 + stiff = all(DThDP.eq.0) + IF(stiff .AND. BYPASS_RICHARDS_WHEN_STIFF) THEN + flow = 0. + dW_l = 0. + div = 0; div_bf=0; div_if=0; div_al=0 + lrunf_bf = 0; lrunf_if = 0; lrunf_al = 0 + lrunf_ie = lprec_eff + hlrunf_ie = hlprec_eff + if (use_stiff_bug) then + psi=-zfull + else + psi=zfull + endif + dpsi=0. + ELSE + CALL RICHARDS(soil, psi, DThDP, hyd_cond, DKDP, div, & + lprec_eff, Dpsi_min, Dpsi_max, stiff, & + dPsi, dW_l, flow, lrunf_ie) + ENDIF + ENDIF + + ! ---- heat advection by water flow --------------------------------------- + if (snow_lprec.ne.0.) then + tflow = tfreeze + snow_hlprec/(clw*snow_lprec) + else + tflow = tfreeze + endif + + if(is_watch_point()) then + write(*,*) ' ***** soil_step_2 checkpoint 3.4 ***** ' + write(*,*) ' tfreeze', tfreeze + write(*,*) ' tflow ', tflow + write(*,*) ' snow_hlprec', snow_hlprec + endif + + call advection(soil, flow, dW_l, tflow, d_GW, snow_lprec, snow_hlprec) + + if (lprec_eff.ne.0. .and. flow(1).ge.0. ) then + hlrunf_ie = lrunf_ie*hlprec_eff/lprec_eff + else if (flow(1).lt.0. ) then + hlrunf_ie = hlprec_eff - (flow(1)/delta_time)*clw & + *(soil%prog(1)%T-tfreeze) + else + hlrunf_ie = 0. + endif + + hlrunf_bf = clw*sum(div_bf*(soil%prog%T-tfreeze)) + hlrunf_if = clw*sum(div_if*(soil%prog%T-tfreeze)) + hlrunf_al = clw*sum(div_al*(soil%prog%T-tfreeze)) + hlrunf_sc = clw*lrunf_sc *(soil%prog(1)%groundwater_T-tfreeze) + if (lrunf_from_div) then + soil_lrunf = lrunf_sn + lrunf_ie + sum(div) + lrunf_nu + lrunf_sc + soil_hlrunf = hlrunf_sn + hlrunf_ie + clw*sum(div*(soil%prog%T-tfreeze)) & + + hlrunf_nu + hlrunf_sc + else + soil_lrunf = lrunf_sn + lrunf_ie + lrunf_bf + lrunf_if & + + lrunf_al + lrunf_nu + lrunf_sc + soil_hlrunf = hlrunf_sn + hlrunf_ie + hlrunf_bf + hlrunf_if & + + hlrunf_al + hlrunf_nu + hlrunf_sc + endif + + do l = 1, num_l + ! ---- compute explicit melt/freeze -------------------------------------- + hcap = soil%heat_capacity_dry(l)*dz(l) & + + clw*soil%prog(l)%wl + csw*soil%prog(l)%ws + melt_per_deg = hcap/(hlf_factor*hlf) + if (soil%prog(l)%ws>0 .and. soil%prog(l)%T>soil%pars%tfreeze) then + melt = min(soil%prog(l)%ws, (soil%prog(l)%T-soil%pars%tfreeze)*melt_per_deg) + else if (soil%prog(l)%wl>0 .and. soil%prog(l)%T 0) then - space_avail = dens_h2o*dz(l)*soil_vwc_sat(l) & + space_avail = dens_h2o*dz(l)*soil%pars%vwc_sat & - (soil%prog(l)%wl + soil%prog(l)%ws) liq_placed = max(min(space_avail, excess_liq), 0.) ice_placed = max(min(space_avail-liq_placed, excess_ice), 0.) @@ -1155,155 +1714,41 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, lrunf_nu = (excess_liq+excess_ice) / delta_time hlrunf_nu = ( excess_liq*clw*(excess_T-tfreeze) & + excess_ice*csw*(excess_T-tfreeze) & - - hlf*excess_ice ) / delta_time + - hlf_factor*hlf*excess_ice ) / delta_time if(is_watch_point()) then write(*,*) ' ##### soil_step_2 checkpoint 3.01 #####' write(*,*) ' lrunf_nu',lrunf_nu write(*,*) 'hlrunf_nu',hlrunf_nu do l = 1, num_l - write(*,'(x,a,x,i2.2,100(x,a,g))') ' level=', l,& + write(*,'(x,a,x,i2.2,100(x,a,g23.16))') ' level=', l,& ' T =', soil%prog(l)%T,& ' Th=', (soil%prog(l)%ws +soil%prog(l)%wl)/(dens_h2o*dz(l)),& ' wl=', soil%prog(l)%wl,& ' ws=', soil%prog(l)%ws enddo endif +end subroutine soil_push_down_excess - ! ---- fetch soil hydraulic properties ------------------------------------- - vlc=0;vsc=0 - do l = 1, num_l - vlc(l) = max(0., soil%prog(l)%wl / (dens_h2o*dz(l))) - vsc(l) = max(0., soil%prog(l)%ws / (dens_h2o*dz(l))) - enddo - call soil_data_hydraulics (soil, vlc, vsc, & - psi, DThDP, hyd_cond, DKDP, Dpsi_min, Dpsi_max, tau_gw, & - psi_for_rh, soil_w_fc ) - - IF (lm2) THEN ! ******************************** - - if(is_watch_point()) then - write(*,*) ' ##### soil_step_2 checkpoint 3.1 #####' - do l = 1, num_l - write(*,'(x,a,x,i2.2,100(x,a,g))')'level=', l, 'vlc', vlc(l), 'K ', hyd_cond(l) - enddo - endif - ! ---- remainder of mass fluxes and associated sensible heat fluxes -------- - flow=1 - flow(1) = 0 - do l = 1, num_l - infilt(l) = soil%uptake_frac(l)*snow_lprec *delta_time - flow(l+1) = max(0., soil%prog(l)%wl + flow(l) & - + infilt(l) - soil_w_fc(l)*dz(l)*dens_h2o) - dW_l(l) = flow(l) - flow(l+1) + infilt(l) - soil%prog(l)%wl = soil%prog(l)%wl + dW_l(l) - enddo - do l = 1, num_l - flow(l) = flow(l) + infilt(l) - enddo - dW_l=0 - dpsi=0 - lrunf_bf = lrunf_bf + flow(num_l)/delta_time - ELSE ! ******************************** - IF (.NOT.USE_GEOHYDROLOGY) THEN - div = 0. - IF (CORRECTED_LM2_GW) THEN - do l = 1, num_l - if (vlc(l) .ge. soil_vwc_sat(l) .and. vsc(l).le.0.) & - div(l) = 0.15*dens_h2o*dz(l)/tau_gw - enddo - ELSE - do l = 1, num_l - if ((vsc(l)+vlc(l)) .ge. soil_vwc_sat(l)) & - div(l) = 0.15*dens_h2o*dz(l)*(vlc(l)/(vsc(l)+vlc(l)))/tau_gw - enddo - ENDIF - z_sat = 0. - do l=num_l,1,-1 - if(vsc(l)+vlc(l).le.soil_vwc_sat(l)) exit - z_sat = z_sat + dz(l) - enddo - sat_frac = min((z_sat/zhalf(num_l+1))**soil%pars%rsa_exp,1.) - ELSE - call soil_data_gw_hydraulics(soil, zfull(num_l), psi(num_l), & - gw_flux, sat_frac, storage_frac, depth_to_saturation) - dq = 0. - z_sat = 0. - l = num_l - div_active = 0. - IF (BASEFLOW_WHERE_FROZEN) THEN - do l=num_l,1,-1 - if(psi(l).le.0.) exit - dq(l) = dz(l)*vlc(l)/(vlc(l)+vsc(l)) - z_sat = z_sat + dz(l) - enddo - ELSE - do l=num_l,1,-1 - if(psi(l).le.0.) exit - if (vsc(l).le.0.) dq(l) = dz(l) - z_sat = z_sat + dz(l) - enddo - ! IF (DRAIN_ACTIVE_LAYER) THEN - l_max_active_layer = 0 - do l=1,num_l - if(vsc(l).gt.0.) exit - l_max_active_layer = l - enddo - if (l_max_active_layer.lt.num_l .and. l_max_active_layer.gt.0) then - do l = 1, l_max_active_layer - if(vlc(l).gt.0) & - div_active(l) = hyd_cond(l) * soil%pars%hillslope_relief*dz(l) & - / (soil%pars%hillslope_length*soil%pars%hillslope_length) - enddo - endif - ! ENDIF - ENDIF - div = 0. - if (z_sat.gt.0.) div = (dq / z_sat) * gw_flux - where (div.eq.0.) div = div_active*active_layer_drainage_acceleration - call send_tile_data(id_psi_bot, psi(num_l), diag) - call send_tile_data(id_psi_bot_old, psi(num_l), diag) - call send_tile_data(id_sat_frac, sat_frac, diag) - call send_tile_data(id_sat_frac_old, sat_frac, diag) - call send_tile_data(id_stor_frac, storage_frac, diag) - call send_tile_data(id_stor_frac_old, storage_frac, diag) - if (depth_to_saturation .ge. -0.5) call send_tile_data(id_sat_depth, depth_to_saturation, diag) - if (depth_to_saturation .ge. -0.5) call send_tile_data(id_sat_depth_old, depth_to_saturation, diag) - ENDIF - lrunf_bf = lrunf_bf + sum(div) - if (snow_lprec.ne.0.) then - lrunf_sn = sat_frac * snow_lprec - hlrunf_sn = lrunf_sn*snow_hlprec/snow_lprec - else - lrunf_sn = 0. - hlrunf_sn = 0. - endif +! ============================================================================ + subroutine RICHARDS(soil, psi, DThDP, hyd_cond, DKDP, div, & + lprec_eff, Dpsi_min, Dpsi_max, stiff, & + dPsi, dW_l, flow, lrunf_ie) + type(soil_tile_type), intent(inout) :: soil + real, intent(in), dimension(num_l) :: psi, DThDP, hyd_cond, DKDP, div + real, intent(in) :: lprec_eff, Dpsi_min, Dpsi_max + logical, intent(in) :: stiff + real, intent(out), dimension(num_l) :: dPsi, dW_l + real, intent(out), dimension(num_l+1) :: flow + real, intent(out) :: lrunf_ie + ! ---- local vars ---------------------------------------------------------- + integer l, ipt, jpt, kpt, fpt, l_internal + real, dimension(num_l-1) :: del_z, K, DKDPm, DKDPp, grad, eee, fff + real aaa, bbb, ccc, ddd, xxx, dpsi_alt, dW_l_internal, w_to_move_up, adj + logical flag - if(is_watch_point()) then - do l = 1, num_l - write(*,'(a,1x,i2.2,100(2x,g))')'div,vsc,psi,dz',l,div(l),vsc(l),psi(l),dz(l) - enddo - write(*,*)'lrunf_bf',lrunf_bf - write(*,*)'tau_gw',tau_gw - write(*,*)'dens_h2o',dens_h2o - endif - ! ---- soil-water flow ---------------------------------------------------- - flow = 0 - stiff = all(DThDP.eq.0) - lprec_eff = snow_lprec - lrunf_sn - hlprec_eff = snow_hlprec - hlrunf_sn -IF(stiff .AND. BYPASS_RICHARDS_WHEN_STIFF) THEN ! BYPASS_RICHARDS_WHEN_STIFF -flow = 0. -div = 0. -dW_l = 0. -lrunf_ie = lprec_eff -hlrunf_ie = hlprec_eff -lrunf_bf = 0. -hlrunf_bf =0. -psi=-zfull -dpsi=0. -ELSE ! BYPASS_RICHARDS_WHEN_STIFF + flag = .false. flow(1) = delta_time*lprec_eff do l = 1, num_l-1 del_z(l) = zfull(l+1)-zfull(l) @@ -1313,20 +1758,20 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, ! K(l) = hyd_cond(l) ! DKDPm(l) = DKDP(l) ! DKDPp(l) = 0 - grad(l) = jj*(psi(l+1)-psi(l))/del_z(l) - 1 + grad(l) = (psi(l+1)-psi(l))/del_z(l) - 1 enddo if(is_watch_point()) then write(*,*) '##### soil_step_2 checkpoint 3.1 #####' do l = 1, num_l - write(*,'(x,a,x,i2.2,x,a,100(x,g))') 'level=', l, 'DThDP,hyd_cond,psi,DKDP', & + write(*,'(x,a,x,i2.2,x,a,100(x,g23.16))') 'level=', l, 'DThDP,hyd_cond,psi,DKDP', & DThDP(l),& hyd_cond(l),& psi(l),& DKDP(l) enddo do l = 1, num_l-1 - write(*,'(a,i2.2,1x,a,100(2x,g))') 'interface=', l, 'K,DKDPm,DKDPp,grad,del_z', & + write(*,'(a,i2.2,1x,a,100(2x,g23.16))') 'interface=', l, 'K,DKDPm,DKDPp,grad,del_z', & K(l),& DKDPm(l),& DKDPp(l),& @@ -1337,9 +1782,9 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, l = num_l xxx = dens_h2o*dz(l)*DThDP(l)/delta_time - aaa = - ( jj* K(l-1)/del_z(l-1) - DKDPm(l-1)*grad(l-1)) + aaa = - ( K(l-1)/del_z(l-1) - DKDPm(l-1)*grad(l-1)) ! where (stiff) - bbb = xxx - (- jj*K(l-1)/del_z(l-1) - DKDPp(l-1)*grad(l-1) ) + bbb = xxx - (-K(l-1)/del_z(l-1) - DKDPp(l-1)*grad(l-1) ) ddd = - K(l-1) *grad(l-1) - div(l) ! elsewhere ! Qout = hyd_cond(l) ! gravity drainage @@ -1347,13 +1792,13 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, ! Qout = 0. ! no drainage ! DQoutDP = 0. ! no drainage ! where (psi(l).gt.0.) ! linear baseflow from gw -! Qout = 0.15*psi(l)/tau_gw -! DQoutDP = 0.15/tau_gw +! Qout = 0.15*psi(l)/soil%pars%tau_groundwater +! DQoutDP = 0.15/soil%pars%tau_groundwater ! elsewhere ! Qout = 0. ! DQoutDP = 0. ! endwhere -! bbb = xxx - (- jj*K(l-1)/del_z(l-1) - DKDPp(l-1)*grad(l-1)& +! bbb = xxx - (-K(l-1)/del_z(l-1) - DKDPp(l-1)*grad(l-1)& ! -DQoutDP ) ! ddd = -Qout - K(l-1) *grad(l-1) ! endwhere @@ -1361,39 +1806,59 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, fff(l-1) = ddd/bbb if(is_watch_point()) then - write(*,'(a,i2.2,100(2x,g))') 'l,a,b, ,d', l,aaa, bbb,ddd + write(*,'(a,i2.2,100(2x,g23.16))') 'l,a,b, ,d', l,aaa, bbb,ddd endif do l = num_l-1, 2, -1 xxx = dens_h2o*dz(l)*DThDP(l)/delta_time - aaa = - ( jj*K(l-1)/del_z(l-1) - DKDPm(l-1)*grad(l-1)) - bbb = xxx-( -jj*K(l-1)/del_z(l-1) - DKDPp(l-1)*grad(l-1)& - -jj*K(l )/del_z(l ) + DKDPm(l )*grad(l )) - ccc = - ( jj*K(l )/del_z(l ) + DKDPp(l )*grad(l )) + aaa = - ( K(l-1)/del_z(l-1) - DKDPm(l-1)*grad(l-1)) + bbb = xxx-( -K(l-1)/del_z(l-1) - DKDPp(l-1)*grad(l-1)& + -K(l )/del_z(l ) + DKDPm(l )*grad(l )) + ccc = - ( K(l )/del_z(l ) + DKDPp(l )*grad(l )) ddd = K(l)*grad(l) - K(l-1)*grad(l-1) & - div(l) eee(l-1) = -aaa/(bbb+ccc*eee(l)) fff(l-1) = (ddd-ccc*fff(l))/(bbb+ccc*eee(l)) if(is_watch_point()) then - write(*,'(a,i2.2,100(2x,g))') 'l,a,b,c,d', l,aaa, bbb,ccc,ddd + write(*,'(a,i2.2,100(2x,g23.16))') 'l,a,b,c,d', l,aaa, bbb,ccc,ddd endif enddo l = 1 xxx = dens_h2o*dz(l)*DThDP(l)/delta_time - bbb = xxx - ( -jj*K(l )/del_z(l ) + DKDPm(l )*grad(l )) - ccc = - ( jj*K(l )/del_z(l ) + DKDPp(l )*grad(l )) + bbb = xxx - ( -K(l )/del_z(l ) + DKDPm(l )*grad(l )) + ccc = - ( K(l )/del_z(l ) + DKDPp(l )*grad(l )) ddd = flow(1)/delta_time + K(l) *grad(l) & - div(l) IF (bbb+ccc*eee(l) .NE. 0.) THEN dPsi(l) = (ddd-ccc*fff(l))/(bbb+ccc*eee(l)) + if(is_watch_point()) then + write(*,*) 'bbb+ccc*eee(l) .NE. 0.' + write(*,*) 'bbb', bbb + write(*,*) 'ccc', ccc + write(*,*) 'ddd', ddd + write(*,*) 'eee(l)', eee(l) + write(*,*) 'fff(l)', fff(l) + write(*,*) 'dPsi(l)', dPsi(l) + write(*,*) 'stiff', stiff + write(*,*) 'dPsi(l)', dPsi(l) + write(*,*) 'Dpsi_min', Dpsi_min + write(*,*) 'Dpsi_max', Dpsi_max + endif if (.not.stiff .and. dPsi(l).gt.Dpsi_min .and. dPsi(l).lt.Dpsi_max) then lrunf_ie = 0. else if (stiff) then dPsi(l) = - psi(l) else + if (dPsi(l).lt.Dpsi_min) then + flag = .true. + call get_current_point(ipt,jpt,kpt,fpt) + write(*,*) 'note 1: at point ',ipt,jpt,kpt,fpt,'computed dPsi(1) too negative' + write(*,*) 'note 1: at point ',ipt,jpt,kpt,fpt,'dPsi(1)=',dPsi(l) + write(*,*) 'note 1: at point ',ipt,jpt,kpt,fpt,'dPsi_min =',dPsi_min + endif dPsi(l) = min (dPsi(l), Dpsi_max) dPsi(l) = max (dPsi(l), Dpsi_min) endif @@ -1413,6 +1878,19 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, endif endif ELSE + if(is_watch_point()) then + write(*,*) 'bbb+ccc*eee(l) .EQ. 0.' + write(*,*) 'bbb', bbb + write(*,*) 'ccc', ccc + write(*,*) 'ddd', ddd + write(*,*) 'eee(l)', eee(l) + write(*,*) 'fff(l)', fff(l) + write(*,*) 'dPsi(l)', dPsi(l) + write(*,*) 'stiff', stiff + write(*,*) 'dPsi(l)', dPsi(l) + write(*,*) 'Dpsi_min', Dpsi_min + write(*,*) 'Dpsi_max', Dpsi_max + endif if (stiff) then dPsi(l) = - psi(l) else @@ -1438,11 +1916,11 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, ENDIF if(is_watch_point().or.(flag.and.write_when_flagged)) then - write(*,'(a,i2.2,100(2x,g))') 'l, b,c,d', l, bbb,ccc,ddd + write(*,'(a,i2.2,100(2x,g23.16))') 'l, b,c,d', l, bbb,ccc,ddd write(*,*) ' ##### soil_step_2 checkpoint 3.2 #####' - write(*,*) 'ie,sn,bf:', lrunf_ie,lrunf_sn,lrunf_bf + write(*,*) 'ie:', lrunf_ie do l = 1, num_l-1 - write(*,'(a,i2.2,100(2x,g))') 'l,eee(l),fff(l)',l,eee(l),fff(l) + write(*,'(a,i2.2,100(2x,g23.16))') 'l,eee(l),fff(l)',l,eee(l),fff(l) enddo write(*,*) 'DThDP(1)', DThDP(1) write(*,*) 'K(1)', K(1) @@ -1464,7 +1942,7 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, do l = 1, num_l-1 flow(l+1) = delta_time*( & -K(l)*(grad(l)& - +jj*(DPsi(l+1)-DPsi(l))/ del_z(l)) & + +(DPsi(l+1)-DPsi(l))/ del_z(l)) & -grad(l)*(DKDPp(l)*Dpsi(l+1)+ & DKDPm(l)*Dpsi(l) ) ) dW_l(l) = flow(l) - flow(l+1) - div(l)*delta_time @@ -1484,7 +1962,7 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, if(is_watch_point().or.(flag.and.write_when_flagged)) then write(*,*) ' ##### soil_step_2 checkpoint 3.21 #####' do l = 1, num_l - write(*,'(i2.2,100(2x,a,g))') l,& + write(*,'(i2.2,100(2x,a,g23.16))') l,& ' dW_l=', dW_l(l),& ' flow=', flow(l),& ' div=', div(l) @@ -1510,7 +1988,7 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, if(is_watch_point().or.(flag.and.write_when_flagged)) then write(*,*) ' ##### soil_step_2 checkpoint 3.22 #####' do l = 1, num_l - write(*,'(i2.2,100(2x,a,g))') l,& + write(*,'(i2.2,100(2x,a,g23.16))') l,& ' dW_l=', dW_l(l),& ' flow=', flow(l),& ' div=', div(l) @@ -1524,13 +2002,13 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, write(*,*) 'note: at point ',ipt,jpt,kpt,fpt,' clip triggered by lrunf_ie=',lrunf_ie do l = num_l, 1, -1 adj = max(dW_l(l)+soil%prog(l)%ws+soil%prog(l)%wl & - - soil_vwc_sat(l)*dz(l)*dens_h2o, 0. ) + - soil%pars%vwc_sat*dz(l)*dens_h2o, 0. ) if(is_watch_point()) then write(*,*) '3.22 l=', l,& ' soil_prog%wl=',soil%prog(l)%wl, & ' soil_prog%ws=',soil%prog(l)%ws , & - ' soil_vwc_sat=', soil_vwc_sat(l), & + ' soil%pars%vwc_sat=', soil%pars%vwc_sat, & ' dz=', dz(l), & ' adj=', adj endif @@ -1546,28 +2024,6 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, enddo lrunf_ie = lprec_eff - flow(1)/delta_time - ELSE IF (UNCONDITIONAL_SWEEP) THEN - ! Sweep and fill upward any liquid supersaturation - ! USE OF THIS EXPERIMENTAL CODE IS NOT RECOMMENDED. - ! CONFLICTS WITH COMP.NE.0 !!! - excess_liq = 0. - do l = num_l, 1, -1 - adj = dW_l(l)+soil%prog(l)%ws+soil%prog(l)%wl & - - soil_vwc_sat(l)*dz(l)*dens_h2o - if (adj.gt.0.) then ! collect excess liquid - adj = min(adj, max(0.,soil%prog(l)%wl)) - dW_l(l) = dW_l(l) - adj - excess_liq = excess_liq + adj - else if (adj.lt.0.) then ! deposit collected liquid - if (excess_liq.gt.0.) then - adj = min(-adj, excess_liq) - dW_l(l) = dW_l(l) + adj - excess_liq = excess_liq - adj - endif - endif - flow(l) = flow(l+1) + dW_l(l) + div(l)*delta_time - enddo - lrunf_ie = lprec_eff - flow(1)/delta_time ENDIF do l = 1, num_l @@ -1579,7 +2035,7 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, write(*,*) 'psi_sat',soil%pars%psi_sat_ref write(*,*) 'Dpsi_max',Dpsi_max do l = 1, num_l - write(*,'(i2.2,100(2x,a,g))') l, & + write(*,'(i2.2,100(2x,a,g23.16))') l, & 'Th=', (soil%prog(l)%ws +soil%prog(l)%wl)/(dens_h2o*dz(l)), & 'wl=', soil%prog(l)%wl, & 'ws=', soil%prog(l)%ws, & @@ -1589,23 +2045,24 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, enddo endif -ENDIF ! BYPASS_RICHARDS_WHEN_STIFF - ENDIF ! ************************************ - - if (snow_lprec.ne.0.) then - tflow = tfreeze + snow_hlprec/(clw*snow_lprec) - else - tflow = tfreeze - endif - - if(is_watch_point()) then - write(*,*) ' ***** soil_step_2 checkpoint 3.4 ***** ' - write(*,*) ' tfreeze', tfreeze - write(*,*) ' tflow ', tflow - write(*,*) ' snow_hlprec', snow_hlprec - endif - +end subroutine richards +! ============================================================================ + subroutine advection(soil, flow, dW_l, tflow, d_GW, snow_lprec, snow_hlprec) + type(soil_tile_type), intent(inout) :: soil + real, intent(in), dimension(:) :: flow + real, intent(in), dimension(:) :: dW_l + real, intent(in) :: & + tflow, & + d_GW, & + snow_lprec, & + snow_hlprec + ! ---- local vars ---------------------------------------------------------- + real, dimension(num_l) :: u_minus, u_plus, del_t + real, dimension(num_l-1) :: eee, fff + real hcap, aaa, bbb, ccc + integer l + ! Upstream weighting of advection. Preserving u_plus here for now. u_minus = 1. where (flow.lt.0.) u_minus = 0. @@ -1654,132 +2111,16 @@ subroutine soil_step_2 ( soil, vegn, diag, soil_subl, snow_lprec, snow_hlprec, do l = 1, num_l-1 del_t(l+1) = eee(l)*del_t(l) + fff(l) soil%prog(l+1)%T = soil%prog(l+1)%T + del_t(l+1) - enddo - - tflow = soil%prog(num_l)%T - -! do l = 1, num_l -! where (mask) -! hcap = soil%heat_capacity_dry(l)*dz(l) & -! + clw*(soil%prog(l)%wl-dW_l(l)) + csw*soil%prog(l)%ws -! cap_flow = clw*flow(l) -! soil%prog(l)%T = (hcap*soil%prog(l)%T + cap_flow*tflow) & -! /(hcap + cap_flow ) -! tflow = soil%prog(l)%T -! endwhere -! enddo - - if(is_watch_point()) then - write(*,*) ' ***** soil_step_2 checkpoint 3.5 ***** ' - write(*,*) 'hcap', hcap -! write(*,*) 'cap_flow', cap_flow - do l = 1, num_l - write(*,*) 'level=', l, ' T', soil%prog(l)%T - enddo - endif - - ! ---- groundwater --------------------------------------------------------- - ! THIS T AVERAGING IS WRONG, BECAUSE IT NEGLECTS THE MEDIUM *** - ! ALSO, FREEZE-THAW IS NEEDED! - ! PROBABLY THIS SECTION WILL BE DELETED ANYWAY, WITH GW TREATED ABOVE. - IF (lm2) THEN - do l = 1, 1 !TEMPORARY LAYER THING !!!!*** - if (soil%prog(l)%groundwater + flow(num_l+1) .ne. 0.) then ! TEMP FIX - soil%prog(l)%groundwater_T = & - + (soil%prog(l)%groundwater*soil%prog(l)%groundwater_T & - + flow(num_l+1)*tflow) & - /(soil%prog(l)%groundwater + flow(num_l+1)) - endif - c0 = delta_time/tau_gw - c1 = exp(-c0) - c2 = (1-c1)/c0 - x = (1-c1)*soil%prog(l)%groundwater/delta_time & - + (1-c2)*flow(num_l+1)/delta_time - soil%prog(l)%groundwater = c1 * soil%prog(l)%groundwater & - + c2 * flow(num_l+1) - soil_lrunf = x - soil_hlrunf = x*clw*(soil%prog(l)%groundwater_T-tfreeze) enddo - ELSE - if (lprec_eff.ne.0. .and. flow(1).ge.0. ) then - hlrunf_ie = lrunf_ie*hlprec_eff/lprec_eff - else if (flow(1).lt.0. ) then - hlrunf_ie = hlprec_eff - (flow(1)/delta_time)*clw & - *(soil%prog(1)%T-tfreeze) - else - hlrunf_ie = 0. - endif - hlrunf_bf = hlrunf_bf + clw*sum(div*(soil%prog%T-tfreeze)) - - - soil_lrunf = lrunf_sn + lrunf_ie + lrunf_bf + lrunf_nu - soil_hlrunf = hlrunf_sn + hlrunf_ie + hlrunf_bf + hlrunf_nu - ENDIF - - do l = 1, num_l - ! ---- compute explicit melt/freeze -------------------------------------- - hcap = soil%heat_capacity_dry(l)*dz(l) & - + clw*soil%prog(l)%wl + csw*soil%prog(l)%ws - melt_per_deg = hcap/hlf - if (soil%prog(l)%ws>0 .and. soil%prog(l)%T>soil%pars%tfreeze) then - melt = min(soil%prog(l)%ws, (soil%prog(l)%T-soil%pars%tfreeze)*melt_per_deg) - else if (soil%prog(l)%wl>0 .and. soil%prog(l)%T NULL() ! fast soil carbon pool, (kg C/m2), per layer + real, pointer :: slow_soil_C(:) => NULL() ! slow soil carbon pool, (kg C/m2), per layer + ! values for the diagnostic of carbon budget and soil carbon acceleration + real, pointer :: asoil_in(:) => NULL() + real, pointer :: fsc_in(:) => NULL() + real, pointer :: ssc_in(:) => NULL() end type soil_tile_type ! ==== module data =========================================================== +integer :: gw_option + real, public :: & cpw = 1952.0, & ! specific heat of water vapor at constant pressure clw = 4218.0, & ! specific heat of water (liquid) csw = 2106.0 ! specific heat of water (ice) !---- namelist --------------------------------------------------------------- +real :: psi_wilt = -150.0 ! matric head at wilting real :: comp = 0.001 ! m^-1, dThdPsi at saturation real :: k_over_B = 2 ! reset to 0 for MCM real :: rate_fc = 0.1/86400 ! 0.1 mm/d drainage rate at FC @@ -175,28 +212,45 @@ module soil_tile_mod real :: z_sub_layer_min = 0.0 real :: z_sub_layer_max = 0.0 real :: freeze_factor = 1.0 +real :: aspect = 1.0 +real :: zeta_mult = 1.0 ! multiplier for root depth scale in stress index integer :: num_l = 18 ! number of soil levels real :: dz(max_lev) = (/ & 0.02, 0.04, 0.04, 0.05, 0.05, 0.1, 0.1, 0.2, 0.2, & 0.2, 0.4, 0.4, 0.4, 0.4, 0.4, 1., 1., 1., & - 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0. /) + 0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,& + 0.,0.,0.,0.,0.,0.,0.,0.,0.,0. /) ! thickness (m) of model layers, ! from top down logical :: use_lm2_awc = .false. logical :: lm2 = .false. -logical :: use_experimental_smc = .false. logical :: use_alt_psi_for_rh = .false. +logical :: use_tau_fix = .false. +logical :: use_sat_fix = .false. +logical :: use_comp_for_ic = .false. ! ---- remainder are used only for cold start --------- -character(len=16):: soil_to_use = 'single-tile' +character(32):: soil_to_use = 'single-tile' ! 'multi-tile' for multiple soil types per grid cell, a tile per type ! 'single-tile' for geographically varying soil with single type per ! model grid cell [default] ! 'uniform' for global constant soil, e.g., to reproduce MCM +character(32) :: geohydrology_to_use = 'hill_ar5' + ! 'lm2' for lm2 hydrology -- must be consistent with lm2 flag + ! 'linear' + ! 'hill' -- for hillslope geohydrology + ! 'hill_ar5' -- hillslope geohydrology reproducing AR5 simulations logical :: use_mcm_albedo = .false. ! .true. for CLIMAP albedo inputs logical :: use_single_geo = .false. ! .true. for global gw res time, ! e.g., to recover MCM -logical :: use_geohydrology = .false. ! .true. for analytic hillslope soln +logical :: use_alpha = .false. ! for vertical change in soil properties integer :: soil_index_constant = 9 ! index of global constant soil, ! used when use_single_soil real :: gw_res_time = 60.*86400 ! mean groundwater residence time, @@ -205,6 +259,13 @@ module soil_tile_mod real :: gw_scale_length = 1.0 real :: gw_scale_relief = 1.0 real :: gw_scale_soil_depth = 1.0 +real :: slope_exp = 0.0 +real :: gw_scale_perm = 1.0 +real :: k_macro_constant = 0.0 +real :: log_rho_max = 2.0 +real :: z_ref = 0.0 ! depth where [psi/k]_sat = [psi/k]_sat_ref +real :: geothermal_heat_flux_constant = 0.0 ! true continental average is ~0.065 W/m2 +real :: Dpsi_min_const = -1.e16 real, dimension(n_dim_soil_types) :: & dat_w_sat=& @@ -276,18 +337,23 @@ module soil_tile_mod tile_names=& (/'c ','m ','f ','cm ','cf ','mf ','cmf ','peat','mcm ' /) -namelist /soil_data_nml/ & +namelist /soil_data_nml/ psi_wilt, & soil_to_use, tile_names, input_cover_types, & comp, k_over_B, & rate_fc, sfc_heat_factor, z_sfc_layer, & sub_layer_tc_fac, z_sub_layer_min, z_sub_layer_max, freeze_factor, & - num_l, dz, & - use_lm2_awc, lm2, use_experimental_smc, use_alt_psi_for_rh, & - use_mcm_albedo, & - use_single_geo, use_geohydrology, & + aspect, zeta_mult, num_l, dz, & + use_lm2_awc, lm2, use_alt_psi_for_rh, & + use_tau_fix, use_sat_fix, use_comp_for_ic, use_mcm_albedo, & + use_single_geo, geohydrology_to_use, & + use_alpha, & soil_index_constant, & gw_res_time, rsa_exp_global, & gw_scale_length, gw_scale_relief, gw_scale_soil_depth, & + slope_exp, & + gw_scale_perm, z_ref, geothermal_heat_flux_constant, & + Dpsi_min_const, & + k_macro_constant, log_rho_max, & dat_w_sat, dat_awc_lm2, & dat_k_sat_ref, & dat_psi_sat_ref, dat_chb, & @@ -304,10 +370,14 @@ module soil_tile_mod real :: gw_hillslope_relief = 100. real :: gw_hillslope_zeta_bar = 0.5 real :: gw_soil_e_depth = 4. -real, dimension(num_storage_pts, num_zeta_s_pts) :: & - gw_flux_table, gw_area_table - -real, dimension(num_zeta_s_pts ) :: gw_zeta_s = & +real :: gw_perm = 3.e-14 ! nominal permeability, m^2 +real :: gw_flux_table(26,31), gw_area_table(26,31) +real, allocatable :: log_rho_table(:,:,:) +real, allocatable :: log_deficit_list(:) +real, allocatable :: log_zeta_s(:) +real, allocatable :: log_tau(:) + +real, dimension(31 ) :: gw_zeta_s = & (/ 1.0000000e-5, 1.5848932e-5, 2.5118864e-5, 3.9810717e-5, 6.3095737e-5, & 1.0000000e-4, 1.5848932e-4, 2.5118864e-4, 3.9810717e-4, 6.3095737e-4, & 1.0000000e-3, 1.5848932e-3, 2.5118864e-3, 3.9810717e-3, 6.3095737e-3, & @@ -316,19 +386,19 @@ module soil_tile_mod 1.0000000e+0, 1.5848932e+0, 2.5118864e+0, 3.9810717e+0, 6.3095737e+0, & 1.0000000e+1 /) -real, dimension(num_storage_pts) :: gw_storage_norm = & +real, dimension(26) :: gw_storage_norm = & (/ 0., 0.04000, 0.08000, 0.12000, 0.16000, 0.20000, & 0.24000, 0.28000, 0.32000, 0.36000, 0.40000, 0.44000, & 0.48000, 0.52000, 0.56000, 0.60000, 0.64000, 0.68000, & 0.72000, 0.76000, 0.80000, 0.84000, 0.88000, 0.92000, & 0.96000, 1.00000 /) -real, dimension(num_storage_pts) :: gw_flux_norm_zeta_s_04 = & +real, dimension(26) :: gw_flux_norm_zeta_s_04 = & (/ 0.0e000, 7.04e-6, 1.14e-5, 1.85e-5, 3.01e-5, 4.89e-5, & 6.95e-5, 8.10e-5, 9.26e-5, 1.42e-4, 2.93e-4, 6.14e-4, & 1.25e-3, 2.47e-3, 4.76e-3, 8.98e-3, 1.66e-2, 3.02e-2, & 5.41e-2, 9.56e-2, 1.67e-1, 2.88e-1, 4.92e-1, 8.36e-1, & 1.53e+0, 1.00e+1 /) -real, dimension(num_storage_pts) :: gw_area_norm_zeta_s_04 = & +real, dimension(26) :: gw_area_norm_zeta_s_04 = & (/ 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, & 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, & 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, & @@ -336,21 +406,25 @@ module soil_tile_mod 3.48e-1, 1.00000 /) integer :: num_sfc_layers, sub_layer_min, sub_layer_max +integer :: num_storage_pts, num_zeta_pts, num_tau_pts + +real :: zfull (max_lev) +real :: zhalf (max_lev+1) contains ! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ! ============================================================================ subroutine read_soil_data_namelist(soil_num_l, soil_dz, soil_single_geo, & - soil_geohydrology ) + soil_gw_option ) integer, intent(out) :: soil_num_l real, intent(out) :: soil_dz(:) logical, intent(out) :: soil_single_geo - logical, intent(out) :: soil_geohydrology + integer, intent(out) :: soil_gw_option ! ---- local vars integer :: unit ! unit for namelist i/o integer :: io ! i/o status for the namelist integer :: ierr ! error code, returned by i/o routines - integer :: i + integer :: i, rcode, ncid, varid, dimids(3) real :: z call write_version_number(version, tagname) @@ -385,7 +459,11 @@ subroutine read_soil_data_namelist(soil_num_l, soil_dz, soil_single_geo, & sub_layer_min = 0 sub_layer_max = 0 + zhalf(1) = 0 do i = 1, num_l + zhalf(i+1) = zhalf(i) + dz(i) + zfull(i) = 0.5*(zhalf(i+1) + zhalf(i)) + if (z < z_sub_layer_min+1.e-4) sub_layer_min = i z = z + dz(i) if (z < z_sfc_layer+1.e-4) num_sfc_layers = i @@ -394,18 +472,64 @@ subroutine read_soil_data_namelist(soil_num_l, soil_dz, soil_single_geo, & !!$ write (*,*) 'min/max index of layers whose thermal cond is scaled:',sub_layer_min,sub_layer_max - if (use_geohydrology.and..not.use_single_geo) then - call read_data('INPUT/geohydrology_table.nc', 'gw_flux_norm', & - gw_flux_table, no_domain=.true.) - call read_data('INPUT/geohydrology_table.nc', 'gw_area_norm', & - gw_area_table, no_domain=.true.) - endif + if (trim(geohydrology_to_use)=='lm2') then + gw_option = GW_LM2 + else if (trim(geohydrology_to_use)=='linear') then + gw_option = GW_LINEAR + else if (trim(geohydrology_to_use)=='hill_ar5') then + gw_option = GW_HILL_AR5 + else if (trim(geohydrology_to_use)=='hill') then + gw_option = GW_HILL + else + call error_mesg('read_soil_data_namelist',& + 'option geohydrology_to_use="'//trim(geohydrology_to_use)//'" is invalid, use '// & + ' "lm2", "linear", "hill", or "hill_ar5"', & + FATAL) + endif + + if ((gw_option==GW_LM2).neqv.lm2) then + call error_mesg('read_soil_data_namelist',& + 'geohydrlogy/LM2 option conflict: geohydrology_to_use must be consistent with the LM2 flag', & + FATAL) + endif + + if (gw_option==GW_HILL_AR5.and..not.use_single_geo) then + num_storage_pts = 26 + call read_data('INPUT/geohydrology_table.nc', 'gw_flux_norm', & + gw_flux_table, no_domain=.true.) + call read_data('INPUT/geohydrology_table.nc', 'gw_area_norm', & + gw_area_table, no_domain=.true.) + else if (gw_option==GW_HILL.or.gw_option==GW_HILL_AR5) then + __NF_ASRT__(nf_open('INPUT/geohydrology_table.nc',NF_NOWRITE,ncid)) + __NF_ASRT__(nf_inq_varid(ncid,'log_rho',varid)) + __NF_ASRT__(nf_inq_vardimid(ncid,varid,dimids)) + __NF_ASRT__(nf_inq_dimlen(ncid,dimids(1),num_storage_pts)) + __NF_ASRT__(nf_inq_dimlen(ncid,dimids(2),num_tau_pts)) + __NF_ASRT__(nf_inq_dimlen(ncid,dimids(3),num_zeta_pts)) + __NF_ASRT__(nf_close(ncid)) + + allocate (log_rho_table(num_storage_pts, & + num_tau_pts, num_zeta_pts)) + allocate (log_deficit_list(num_storage_pts)) + allocate (log_tau(num_tau_pts)) + allocate (log_zeta_s(num_zeta_pts)) + + call read_data('INPUT/geohydrology_table.nc', 'log_rho', & + log_rho_table, no_domain=.true.) + call read_data('INPUT/geohydrology_table.nc', 'log_deficit', & + log_deficit_list, no_domain=.true.) + call read_data('INPUT/geohydrology_table.nc', 'log_tau', & + log_tau, no_domain=.true.) + call read_data('INPUT/geohydrology_table.nc', 'log_zeta_s', & + log_zeta_s, no_domain=.true.) + endif + ! set up output arguments soil_num_l = num_l soil_dz = dz soil_single_geo = use_single_geo - soil_geohydrology = use_geohydrology + soil_gw_option = gw_option end subroutine @@ -421,11 +545,21 @@ function soil_tile_ctor(tag) result(ptr) allocate( ptr%prog(num_l)) allocate( ptr%w_fc (num_l), & ptr%w_wilt (num_l), & + ptr%d_trans (num_l), & + ptr%alpha (num_l), & + ptr%k_macro (num_l), & ptr%uptake_frac (num_l), & ptr%heat_capacity_dry (num_l), & ptr%e (num_l), & ptr%f (num_l), & - ptr%psi (num_l) ) + ptr%psi (num_l), & + ptr%gw_flux_norm (num_storage_pts), & + ptr%gw_area_norm (num_storage_pts), & + ptr%fast_soil_C (num_l), & + ptr%slow_soil_C (num_l), & + ptr%fsc_in (num_l), & + ptr%ssc_in (num_l), & + ptr%asoil_in (num_l) ) call soil_data_init_0d(ptr) end function soil_tile_ctor @@ -441,21 +575,41 @@ function soil_tile_copy_ctor(soil) result(ptr) allocate( ptr%prog(num_l)) allocate( ptr%w_fc (num_l), & ptr%w_wilt (num_l), & + ptr%d_trans (num_l), & + ptr%alpha (num_l), & + ptr%k_macro (num_l), & ptr%uptake_frac (num_l), & ptr%heat_capacity_dry (num_l), & ptr%e (num_l), & ptr%f (num_l), & - ptr%psi (num_l) ) + ptr%psi (num_l), & + ptr%gw_flux_norm (num_storage_pts), & + ptr%gw_area_norm (num_storage_pts), & + ptr%fast_soil_C (num_l), & + ptr%slow_soil_C (num_l), & + ptr%fsc_in (num_l), & + ptr%ssc_in (num_l), & + ptr%asoil_in (num_l) ) ! copy all pointer members ptr%prog(:) = soil%prog(:) ptr%w_fc(:) = soil%w_fc(:) ptr%w_wilt(:) = soil%w_wilt(:) + ptr%d_trans(:) = soil%d_trans(:) + ptr%alpha(:) = soil%alpha(:) + ptr%k_macro(:) = soil%k_macro(:) ptr%uptake_frac(:) = soil%uptake_frac(:) ptr%uptake_T = soil%uptake_T ptr%heat_capacity_dry(:) = soil%heat_capacity_dry(:) ptr%e(:) = soil%e(:) ptr%f(:) = soil%f(:) ptr%psi(:) = soil%psi(:) + ptr%gw_flux_norm(:) = soil%gw_flux_norm(:) + ptr%gw_area_norm(:) = soil%gw_area_norm(:) + ptr%fast_soil_C(:) = soil%fast_soil_C(:) + ptr%slow_soil_C(:) = soil%slow_soil_C(:) + ptr%fsc_in(:) = soil%fsc_in(:) + ptr%ssc_in(:) = soil%ssc_in(:) + ptr%asoil_in(:) = soil%asoil_in(:) end function soil_tile_copy_ctor @@ -464,8 +618,12 @@ subroutine delete_soil_tile(ptr) type(soil_tile_type), pointer :: ptr deallocate(ptr%prog) - deallocate(ptr%w_fc, ptr%w_wilt, ptr%uptake_frac,& - ptr%heat_capacity_dry, ptr%e, ptr%f, ptr%psi) + deallocate(ptr%w_fc, ptr%w_wilt, ptr%d_trans, ptr%alpha, ptr%k_macro, & + ptr%uptake_frac,& + ptr%heat_capacity_dry, ptr%e, ptr%f, ptr%psi, & + ptr%gw_flux_norm, ptr%gw_area_norm, & + ptr%fast_soil_C, ptr%slow_soil_C, & + ptr%fsc_in, ptr%ssc_in, ptr%asoil_in ) deallocate(ptr) end subroutine delete_soil_tile @@ -476,15 +634,17 @@ subroutine soil_data_init_0d(soil) ! real tau_groundwater ! real rsa_exp ! riparian source-area exponent - integer :: k + integer :: k, i, l, code, m_zeta, m_tau + real alpha_inf_sq, alpha_sfc_sq + real :: single_log_zeta_s, single_log_tau, frac_zeta, frac_tau + k = soil%tag - soil%pars%vwc_sat = dat_w_sat (k) + soil%pars%vwc_sat = dat_w_sat (k) soil%pars%awc_lm2 = dat_awc_lm2 (k) soil%pars%k_sat_ref = dat_k_sat_ref (k) soil%pars%psi_sat_ref = dat_psi_sat_ref (k) soil%pars%chb = dat_chb (k) - soil%pars%alpha = 1 soil%pars%heat_capacity_dry = dat_heat_capacity_dry(k) soil%pars%thermal_cond_dry = dat_thermal_cond_dry (k) soil%pars%thermal_cond_sat = dat_thermal_cond_sat (k) @@ -499,16 +659,38 @@ subroutine soil_data_init_0d(soil) soil%pars%emis_sat = dat_emis_sat (k) soil%pars%z0_momentum = dat_z0_momentum (k) soil%pars%tfreeze = tfreeze - dat_tf_depr(k) - soil%pars%rsa_exp = rsa_exp_global soil%pars%tau_groundwater = gw_res_time soil%pars%hillslope_length = gw_hillslope_length*gw_scale_length - soil%pars%hillslope_relief = gw_hillslope_relief*gw_scale_relief soil%pars%hillslope_zeta_bar= gw_hillslope_zeta_bar + soil%pars%hillslope_relief = gw_hillslope_relief*gw_scale_relief soil%pars%soil_e_depth = gw_soil_e_depth*gw_scale_soil_depth + soil%pars%k_sat_gw = gw_perm*gw_scale_perm*9.8e9 ! m^2 to kg/(m2 s) soil%pars%storage_index = 1 - soil%pars%gw_flux_norm = gw_flux_norm_zeta_s_04 - soil%pars%gw_area_norm = gw_area_norm_zeta_s_04 + soil%alpha = 1.0 + soil%fast_soil_C(:) = 0.0 + soil%slow_soil_C(:) = 0.0 + soil%asoil_in(:) = 0.0 + soil%fsc_in(:) = 0.0 + soil%ssc_in(:) = 0.0 + do l = 1, num_l + soil%k_macro(l) = k_macro_constant & + * exp(zfull(l)/soil%pars%soil_e_depth) + enddo + + select case(gw_option) + case(GW_HILL_AR5) + if (use_single_geo) then + soil%gw_flux_norm = gw_flux_norm_zeta_s_04 + soil%gw_area_norm = gw_area_norm_zeta_s_04 + endif + soil%pars%zeta = soil%pars%soil_e_depth / soil%pars%hillslope_relief + case(GW_HILL) + if (use_single_geo) & + call soil_data_init_derive_subsurf_pars ( soil ) + case default + ! do nothing + end select ! ---- derived constant soil parameters ! w_fc (field capacity) set to w at which hydraulic conductivity equals @@ -519,9 +701,9 @@ subroutine soil_data_init_0d(soil) soil%w_fc (:) = 0.15 + soil%pars%awc_lm2 else soil%w_wilt(:) = soil%pars%vwc_sat & - *(soil%pars%psi_sat_ref/(psi_wilt*soil%pars%alpha))**(1/soil%pars%chb) + *(soil%pars%psi_sat_ref/(psi_wilt*soil%alpha(:)))**(1/soil%pars%chb) soil%w_fc (:) = soil%pars%vwc_sat & - *(rate_fc/(soil%pars%k_sat_ref*soil%pars%alpha**2))**(1/(3+2*soil%pars%chb)) + *(rate_fc/(soil%pars%k_sat_ref*soil%alpha(:)**2))**(1/(3+2*soil%pars%chb)) endif soil%pars%vwc_wilt = soil%w_wilt(1) @@ -529,14 +711,125 @@ subroutine soil_data_init_0d(soil) soil%pars%vlc_min = soil%pars%vwc_sat*K_rel_min**(1/(3+2*soil%pars%chb)) - ! below made use of phi_e from parlange via entekhabi - soil%Eg_part_ref = (-4*soil%w_fc(1)**2*soil%pars%k_sat_ref*soil%pars%psi_sat_ref*soil%pars%chb & - /(pi*soil%pars%vwc_sat)) * (soil%w_fc(1)/soil%pars%vwc_sat)**(2+soil%pars%chb) & - *(2*pi/(3*soil%pars%chb**2*(1+3/soil%pars%chb)*(1+4/soil%pars%chb)))/2 - soil%z0_scalar = soil%pars%z0_momentum * exp(-k_over_B) + + soil%geothermal_heat_flux = geothermal_heat_flux_constant -end subroutine +end subroutine soil_data_init_0d + +! ============================================================================ +subroutine soil_data_init_derive_subsurf_pars ( soil ) + type(soil_tile_type), intent(inout) :: soil + integer i, l, code, m_zeta, m_tau + real :: alpha_inf_sq, alpha_sfc_sq + real :: single_log_zeta_s, single_log_tau, frac_zeta, frac_tau + + if (use_alpha) then + soil%pars%k_sat_sfc = (soil%pars%k_sat_ref-soil%pars%k_sat_gw) & + * exp(z_ref/soil%pars%soil_e_depth) + soil%pars%k_sat_gw + alpha_inf_sq = soil%pars%k_sat_gw / soil%pars%k_sat_ref + alpha_sfc_sq = soil%pars%k_sat_sfc / soil%pars%k_sat_ref + do l = 1, num_l + soil%alpha(l) = sqrt(alpha_inf_sq+(alpha_sfc_sq-alpha_inf_sq) & + *exp(-zfull(l)/soil%pars%soil_e_depth)) + enddo + else + soil%pars%k_sat_sfc = soil%pars%k_sat_ref + soil%alpha = 1.0 + endif + + soil%pars%tau = & + (soil%pars%k_sat_gw*aspect*soil%pars%hillslope_length) & + / ((soil%pars%k_sat_sfc+k_macro_constant)*soil%pars%soil_e_depth) + + soil%d_trans(1) = 1. + do l = 1, num_l-1 + soil%d_trans(l+1) = exp(-zhalf(l+1)/soil%pars%soil_e_depth) + soil%d_trans(l) = soil%d_trans(l) - soil%d_trans(l+1) + enddo + soil%d_trans = soil%d_trans & + * (soil%pars%k_sat_sfc + k_macro_constant ) & + * soil%pars%soil_e_depth + soil%d_trans(num_l) = soil%d_trans(num_l) & + + soil%pars%k_sat_gw*aspect*soil%pars%hillslope_length + + if (soil%pars%hillslope_relief.le.0.) soil%pars%hillslope_relief = 1.e-10 + soil%pars%zeta = soil%pars%soil_e_depth & + / soil%pars%hillslope_relief + single_log_zeta_s = log10(soil%pars%zeta) + single_log_zeta_s = max(single_log_zeta_s, log_zeta_s(1)) + single_log_zeta_s = min(single_log_zeta_s, log_zeta_s(num_zeta_pts)) + m_zeta = num_zeta_pts / 2 + code = 0 + do while (code.eq.0) + if (single_log_zeta_s .lt. log_zeta_s(m_zeta)) then + m_zeta = m_zeta - 1 + else if (single_log_zeta_s .gt. log_zeta_s(m_zeta+1)) then + m_zeta = m_zeta + 1 + else + code = 1 + endif + enddo + frac_zeta = (single_log_zeta_s - log_zeta_s(m_zeta)) & + / (log_zeta_s(m_zeta+1) - log_zeta_s(m_zeta)) + single_log_tau = log10( soil%pars%tau ) + single_log_tau = max(single_log_tau, log_tau(1)) + single_log_tau = min(single_log_tau, log_tau(num_tau_pts)) + m_tau = num_tau_pts / 2 + code = 0 + do while (code.eq.0) + if (single_log_tau .lt. log_tau(m_tau)) then + m_tau = m_tau - 1 + else if (single_log_tau .gt. log_tau(m_tau+1)) then + m_tau = m_tau + 1 + else + code = 1 + endif + enddo + frac_tau = (single_log_tau - log_tau(m_tau)) & + / (log_tau(m_tau+1) - log_tau(m_tau)) + do i = 1, num_storage_pts + soil%gw_flux_norm(i) = min ( log_rho_max, & + (1.-frac_zeta)*(1.-frac_tau)*log_rho_table(i , m_tau , m_zeta ) & + + ( frac_zeta)*(1.-frac_tau)*log_rho_table(i , m_tau , m_zeta+1) & + + (1.-frac_zeta)*( frac_tau)*log_rho_table(i , m_tau+1, m_zeta ) & + + ( frac_zeta)*( frac_tau)*log_rho_table(i , m_tau+1, m_zeta+1) ) + enddo + +end subroutine soil_data_init_derive_subsurf_pars + +! ============================================================================ +subroutine soil_data_init_derive_subsurf_pars_ar5 ( soil ) + type(soil_tile_type), intent(inout) :: soil + integer i, code, m_zeta + real :: frac_zeta + if (soil%pars%hillslope_relief.le.0.) & + soil%pars%hillslope_relief = & + soil%pars%soil_e_depth / 10.**log_zeta_s(num_zeta_pts) + soil%pars%zeta = soil%pars%soil_e_depth & + / soil%pars%hillslope_relief + soil%pars%zeta = max(soil%pars%zeta, gw_zeta_s(1)) + soil%pars%zeta = min(soil%pars%zeta, gw_zeta_s(31)) + m_zeta = 31 / 2 + code = 0 + do while (code.eq.0) + if (soil%pars%zeta .lt. gw_zeta_s(m_zeta)) then + m_zeta = m_zeta - 1 + else if (soil%pars%zeta .gt. gw_zeta_s(m_zeta+1)) then + m_zeta = m_zeta + 1 + else + code = 1 + endif + enddo + frac_zeta = (soil%pars%zeta - gw_zeta_s(m_zeta)) & + / (gw_zeta_s(m_zeta+1) - gw_zeta_s(m_zeta)) + do i = 1, num_storage_pts + soil%gw_flux_norm(i) = gw_flux_table(i,m_zeta) & + + frac_zeta*(gw_flux_table(i,m_zeta+1)-gw_flux_table(i,m_zeta)) + soil%gw_area_norm(i) = gw_area_table(i,m_zeta) & + + frac_zeta*(gw_area_table(i,m_zeta+1)-gw_area_table(i,m_zeta)) + enddo +end subroutine soil_data_init_derive_subsurf_pars_ar5 ! ============================================================================ function soil_cover_cold_start(land_mask, lonb, latb) result (soil_frac) @@ -608,8 +901,15 @@ subroutine merge_soil_tiles(s1,w1,s2,w2) s1%prog(i)%groundwater_T*x1 + s2%prog(i)%groundwater_T*x2 endif s2%prog(i)%groundwater = gw + enddo - s2%uptake_T = s1%uptake_T*x1 + s2%uptake_T*x2 + s2%uptake_T = s1%uptake_T*x1 + s2%uptake_T*x2 + ! merge soil carbon + s2%fast_soil_C(:) = s1%fast_soil_C(:)*x1 + s2%fast_soil_C(:)*x2 + s2%slow_soil_C(:) = s1%slow_soil_C(:)*x1 + s2%slow_soil_C(:)*x2 + s2%asoil_in(:) = s1%asoil_in(:)*x1 + s2%asoil_in(:)*x2 + s2%fsc_in(:) = s1%fsc_in(:)*x1 + s2%fsc_in(:)*x2 + s2%ssc_in(:) = s1%ssc_in(:)*x1 + s2%ssc_in(:)*x2 end subroutine ! ============================================================================= @@ -642,16 +942,14 @@ function soil_ave_temp(soil, depth) result (A) ; real :: A real :: w ! averaging weight real :: N ! normalizing factor for averaging - real :: z ! current depth, m integer :: k - A = 0 ; N = 0 ; z = 0 + A = 0 ; N = 0 do k = 1, num_l - w = dz(k) * exp(-(z+dz(k)/2)/depth) + w = dz(k) * exp(-zfull(k)/depth) A = A + soil%prog(k)%T * w N = N + w - z = z + dz(k) - if (z.gt.depth) exit + if (zhalf(k+1).gt.depth) exit enddo A = A/N end function soil_ave_temp @@ -659,46 +957,77 @@ end function soil_ave_temp ! ============================================================================ ! compute average soil moisture with a given depth scale -function soil_ave_theta(soil, depth) result (A) ; real :: A +function soil_ave_theta0(soil, zeta) result (A) ; real :: A type(soil_tile_type), intent(in) :: soil - real, intent(in) :: depth ! averaging depth - + real, intent(in) :: zeta ! root depth scale + real :: zeta2 ! adjusted length scale for soil-water-stress real :: w ! averaging weight real :: N ! normalizing factor for averaging - real :: z ! current depth, m integer :: k - A = 0 ; N = 0 ; z = 0 + A = 0 ; N = 0 + zeta2 = zeta*zeta_mult do k = 1, num_l - w = dz(k) * exp(-(z+dz(k)/2)/depth) + w = exp(-zhalf(k)/zeta2)-exp(-zhalf(k+1)/zeta2) A = A + max(soil%prog(k)%wl/(dens_h2o*dz(k))-soil%w_wilt(k),0.0)/& (soil%w_fc(k)-soil%w_wilt(k)) * w N = N + w - z = z + dz(k) enddo A = A/N -end function soil_ave_theta +end function soil_ave_theta0 + + +! ============================================================================ function soil_ave_theta1(soil, depth) result (A) ; real :: A type(soil_tile_type), intent(in) :: soil real, intent(in) :: depth ! averaging depth real :: w ! averaging weight real :: N ! normalizing factor for averaging - real :: z ! current depth, m integer :: k - A = 0 ; N = 0 ; z = 0 + A = 0 ; N = 0 do k = 1, num_l - w = dz(k) * exp(-(z+dz(k)/2)/depth) + w = dz(k) * exp(-zfull(k)/depth) A = A +min(max(soil%prog(k)%wl/(dens_h2o*dz(k)),0.0)/& (soil%pars%vwc_sat),1.0) * w N = N + w - z = z + dz(k) - if (z.gt.depth) exit + if (zhalf(k+1).gt.depth) exit enddo A = A/N end function soil_ave_theta1 + +! ============================================================================ +! returns array of soil moisture +function soil_theta(soil) result (theta1) + type(soil_tile_type), intent(in) :: soil + real :: theta1(num_l) + + theta1(:) = min(max(soil%prog(:)%wl/(dens_h2o*dz(:)),0.0)/(soil%pars%vwc_sat),1.0) +end function soil_theta + + +! ============================================================================ +function soil_psi_stress(soil, zeta) result (A) ; real :: A + type(soil_tile_type), intent(in) :: soil + real, intent(in) :: zeta ! root-mass depth scale + real :: zeta2 ! adjusted length scale for soil-water-stress + real :: w ! averaging weight + real :: N ! normalizing factor for averaging + integer :: k + + A = 0 ; N = 0 + zeta2 = zeta*zeta_mult + do k = 1, num_l + w = exp(-zhalf(k)/zeta2)-exp(-zhalf(k+1)/zeta2) + A = A + w * soil%psi(k)/psi_wilt + N = N + w + enddo + A = A/N + +end function soil_psi_stress + ! ============================================================================ ! compute bare-soil albedo, bare-soil emissivity, bare-soil roughness ! for scalar transport, and beta function @@ -758,10 +1087,9 @@ subroutine soil_data_thermodynamics ( soil, vlc, vsc, & integer l ! assign some index of water availability for snow-free soil -! soil_E_max = soil%Eg_part_ref / ( max(small, soil%w_fc(1) - vlc(1)) ) ! NEEDS T adj - soil_E_max = (soil%pars%k_sat_ref*soil%pars%alpha**2) & - * (-soil%pars%psi_sat_ref/soil%pars%alpha) & + soil_E_max = (soil%pars%k_sat_ref*soil%alpha(1)**2) & + * (-soil%pars%psi_sat_ref/soil%alpha(1)) & * ((4.+soil%pars%chb)*vlc(1)/ & ((3.+soil%pars%chb)*soil%pars%vwc_sat))**(3.+soil%pars%chb) & / ((1.+3./soil%pars%chb)*dz(1)) @@ -802,20 +1130,63 @@ subroutine soil_data_thermodynamics ( soil, vlc, vsc, & end subroutine soil_data_thermodynamics +! ============================================================================ +! compute soil hydraulic properties: wrapper to get all parameters for +! richards equation for full column. note that psi_for_rh is not passed. +subroutine soil_data_hydraulic_properties (soil, vlc, vsc, & + psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max ) + type(soil_tile_type), intent(in) :: soil + real, intent(in), dimension(:) :: vlc, vsc + real, intent(out), dimension(:) :: & + psi, DThDP, hyd_cond, DKDP + real, intent(out) :: & + DPsi_min, DPsi_max + ! ---- local vars ---------------------------------------------------------- + real :: psi_for_rh + + call soil_data_hydraulics (soil, vlc, vsc, & + psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max, & + psi_for_rh ) + +end subroutine soil_data_hydraulic_properties + + +! ============================================================================ +! wrapper to compute psi and the potentially different psi used for surface +! relative humidity computation. +! use of this wrapper allows us to avoid passing all the other properties +! back to soil module. (they're computed anyway.) +subroutine soil_data_psi_for_rh (soil, vlc, vsc, psi, psi_for_rh ) + type(soil_tile_type), intent(in) :: soil + real, intent(in), dimension(:) :: vlc, vsc + real, intent(out), dimension(:) :: psi + real, intent(out) :: psi_for_rh + ! ---- local vars ---------------------------------------------------------- + real, dimension(num_l) :: DThDP, hyd_cond, DKDP + real :: DPsi_min, DPsi_max + + call soil_data_hydraulics (soil, vlc, vsc, & + psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max, & + psi_for_rh ) + +end subroutine soil_data_psi_for_rh + + ! ============================================================================ ! compute soil hydraulic properties. subroutine soil_data_hydraulics (soil, vlc, vsc, & - psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max, tau_gw, & - psi_for_rh, soil_w_fc ) + psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max, & + psi_for_rh ) type(soil_tile_type), intent(in) :: soil real, intent(in), dimension(:) :: vlc, vsc real, intent(out), dimension(:) :: & - psi, DThDP, hyd_cond, DKDP, soil_w_fc + psi, DThDP, hyd_cond, DKDP real, intent(out) :: & - DPsi_min, DPsi_max, tau_gw, psi_for_rh + DPsi_min, DPsi_max, psi_for_rh ! ---- local vars ---------------------------------------------------------- integer l real :: vlc_loc, vlc_k, psi_k, sigma, B, por, psi_s, k_sat, alt_psi_for_rh + real :: alpha_sq, f_psi logical flag ! ---- T-dependence of hydraulic properties -------------------------------- @@ -823,66 +1194,63 @@ subroutine soil_data_hydraulics (soil, vlc, vsc, & ! psi_sat = soil%pars%psi_sat0 ! * exp(c*(psi-psi0)), where c~+/-(?)0.0068 ! better approach would be to adopt air entrapment model ! or at least to scale against surface tension model - - ! ---- water and ice dependence of hydraulic properties -------------------- ! ---- (T-dependence can be added later) hyd_cond=1;DThDP=1;psi=1 - IF (.NOT.USE_EXPERIMENTAL_SMC) THEN + DKDP=0 flag = .false. - do l = 1, num_l - hyd_cond(l) = (soil%pars%k_sat_ref*soil%pars%alpha**2)* & - ! * mu(T)/mu(t_ref), where mu is dynamic viscosity + do l = 1, size(vlc) + alpha_sq = soil%alpha(l)**2 + hyd_cond(l) = (soil%pars%k_sat_ref*alpha_sq)* & (vlc(l)/soil%pars%vwc_sat)**(3+2*soil%pars%chb) - if (hyd_cond(l).lt.1.e-12*soil%pars%k_sat_ref) then - vlc_loc = soil%pars%vwc_sat*(1.e-12)**(1./(3+2*soil%pars%chb)) - hyd_cond(l) = 1.e-12*soil%pars%k_sat_ref - if (l.eq.1) flag = .true. - if (vsc(l).eq.0.) then - DThDP (l) = -vlc_loc & - *(vlc_loc /soil%pars%vwc_sat)**soil%pars%chb & - /(soil%pars%psi_sat_ref*soil%pars%chb) - psi (l) = (soil%pars%psi_sat_ref/soil%pars%alpha) & - *(soil%pars%vwc_sat/vlc_loc )**soil%pars%chb & - + (vlc(l)-vlc_loc )/DThDP (l) - DKDP (l) = 0. - if (l.eq.1.and.vlc(1).gt.0.) then - alt_psi_for_rh = & - (soil%pars%psi_sat_ref/soil%pars%alpha) & - *(soil%pars%vwc_sat/vlc(1) )**soil%pars%chb - else if (l.eq.1.and.vlc(1).le.0.) then - alt_psi_for_rh = -1.e10 + if (hyd_cond(l).lt.1.e-12*soil%pars%k_sat_ref*alpha_sq) then + vlc_loc = soil%pars%vwc_sat*(1.e-12)**(1./(3+2*soil%pars%chb)) + hyd_cond(l) = 1.e-12*soil%pars%k_sat_ref*alpha_sq + if (l.eq.1) flag = .true. + if (vsc(l).eq.0.) then + DThDP (l) = -vlc_loc & + *(vlc_loc/soil%pars%vwc_sat)**soil%pars%chb & + /(soil%pars%psi_sat_ref*soil%pars%chb/soil%alpha(l)) + psi (l) = (soil%pars%psi_sat_ref/soil%alpha(l)) & + *(soil%pars%vwc_sat/vlc_loc)**soil%pars%chb & + + (vlc(l)-vlc_loc)/DThDP (l) + if (l.eq.1.and.vlc(1).gt.0.) then + alt_psi_for_rh = & + (soil%pars%psi_sat_ref/soil%alpha(l)) & + *(soil%pars%vwc_sat/vlc(1) )**soil%pars%chb + else if (l.eq.1.and.vlc(1).le.0.) then + alt_psi_for_rh = -1.e10 + endif + else + psi (l) = ((soil%pars%psi_sat_ref/soil%alpha(l)) / 2.2) & + *(soil%pars%vwc_sat/vlc_loc )**soil%pars%chb + DThDP (l) = 0. + if (l.eq.1) alt_psi_for_rh = -1.e10 endif else - psi (l) = ((soil%pars%psi_sat_ref/soil%pars%alpha) / 2.2) & - *(soil%pars%vwc_sat/vlc_loc )**soil%pars%chb - DKDP (l) = 0. - DThDP (l) = 0. - if (l.eq.1) alt_psi_for_rh = -1.e10 - endif - else - if (vsc(l).eq.0.) then - if (vlc(l).le.soil%pars%vwc_sat) then - psi (l) = (soil%pars%psi_sat_ref/soil%pars%alpha) & - *(soil%pars%vwc_sat/vlc(l))**soil%pars%chb - DKDP (l) = -(2+3/soil%pars%chb)*hyd_cond(l) & + if (vsc(l).eq.0.) then + if (vlc(l).le.soil%pars%vwc_sat) then + psi (l) = (soil%pars%psi_sat_ref/soil%alpha(l)) & + *(soil%pars%vwc_sat/vlc(l))**soil%pars%chb + DKDP (l) = -(2+3/soil%pars%chb)*hyd_cond(l) & /psi(l) - DThDP (l) = -vlc(l)/(psi(l)*soil%pars%chb) - else - psi(l) = soil%pars%psi_sat_ref & - + (vlc(l)-soil%pars%vwc_sat)/comp - DThDP(l) = comp - hyd_cond(l) = soil%pars%k_sat_ref - DKDP(l) = 0. - endif - else - psi (l) = ((soil%pars%psi_sat_ref/soil%pars%alpha) / 2.2) & - *(soil%pars%vwc_sat/vlc(l))**soil%pars%chb - DKDP (l) = 0. - DThDP (l) = 0. + DThDP (l) = -vlc(l)/(psi(l)*soil%pars%chb) + else + psi(l) = soil%pars%psi_sat_ref/soil%alpha(l) & + + (vlc(l)-soil%pars%vwc_sat)/comp + f_psi = min(max(1.-psi(l)/soil%pars%psi_sat_ref/soil%alpha(l),0.),1.) + DThDP(l) = comp + hyd_cond(l) = soil%pars%k_sat_ref*alpha_sq & + + f_psi * soil%k_macro(l) + endif + else + psi (l) = ((soil%pars%psi_sat_ref/soil%alpha(l)) / 2.2) & + *(soil%pars%vwc_sat/vlc(l))**soil%pars%chb + DThDP (l) = 0. + endif endif - endif - enddo + enddo + if (use_alt_psi_for_rh .and. flag) then psi_for_rh = alt_psi_for_rh else @@ -890,13 +1258,42 @@ subroutine soil_data_hydraulics (soil, vlc, vsc, & endif if (DThDP(1).ne.0.) then - DPsi_min = -vlc(1) /DThDP(1) - DPsi_max = (soil%pars%vwc_sat-vlc(1))/DThDP(1) - else - Dpsi_min = -1.e16 - DPsi_max = -psi(1) - endif - ELSE + DPsi_min = -vlc(1) /DThDP(1) + DPsi_max = (soil%pars%vwc_sat-vlc(1))/DThDP(1) + else + Dpsi_min = Dpsi_min_const + DPsi_max = -psi(1) + endif + +end subroutine soil_data_hydraulics + +! ============================================================================ +! compute soil hydraulic properties (undeveloped code) +subroutine soil_data_hydraulics_EXPERIMENTAL (soil, vlc, vsc, & + psi, DThDP, hyd_cond, DKDP, DPsi_min, DPsi_max, & + psi_for_rh ) + type(soil_tile_type), intent(in) :: soil + real, intent(in), dimension(:) :: vlc, vsc + real, intent(out), dimension(:) :: & + psi, DThDP, hyd_cond, DKDP + real, intent(out) :: & + DPsi_min, DPsi_max, psi_for_rh + ! ---- local vars ---------------------------------------------------------- + integer l + real :: vlc_loc, vlc_k, psi_k, sigma, B, por, psi_s, k_sat, alt_psi_for_rh + real :: alpha_sq, f_psi + logical flag + + ! ---- T-dependence of hydraulic properties -------------------------------- + ! k_sat = soil%pars%k_sat0 ! * mu(t0)/mu(t), where mu is dynamic viscosity + ! psi_sat = soil%pars%psi_sat0 ! * exp(c*(psi-psi0)), where c~+/-(?)0.0068 + ! better approach would be to adopt air entrapment model + ! or at least to scale against surface tension model + + + ! ---- water and ice dependence of hydraulic properties -------------------- + ! ---- (T-dependence can be added later) + hyd_cond=1;DThDP=1;psi=1 B = soil%pars%chb por = soil%pars%vwc_sat vlc_k = soil%pars%vlc_min @@ -925,33 +1322,22 @@ subroutine soil_data_hydraulics (soil, vlc, vsc, & if (vsc(1).gt.0.) DPsi_min = (vlc_k-vlc(1)) /DThDP(1) DPsi_max = (por-vsc(1)-vlc(1))/DThDP(1) psi_for_rh = psi(1) - ENDIF - - soil_w_fc = soil%w_fc - tau_gw = soil%pars%tau_groundwater - -end subroutine soil_data_hydraulics +end subroutine soil_data_hydraulics_EXPERIMENTAL ! ============================================================================ -subroutine soil_data_gw_hydraulics(soil, z_bot, psi_bot, gw_flux, sat_frac, & - storage_normalized, depth_to_saturation) +subroutine soil_data_gw_hydraulics_ar5(soil, storage_normalized, & + gw_flux, sat_frac ) type(soil_tile_type), intent(inout) :: soil - real, intent(in) :: z_bot - real, intent(in) :: psi_bot + real, intent(in) :: storage_normalized real, intent(out) :: gw_flux real, intent(out) :: sat_frac - real, intent(out) :: storage_normalized - real, intent(out) :: depth_to_saturation integer :: code, m real :: recharge_normalized, frac ! storage_normalized is the fraction of soil above drainage base elevation ! that is below the water table - storage_normalized = 1 - (z_bot-psi_bot) & - /(soil%pars%hillslope_zeta_bar*soil%pars%hillslope_relief) - storage_normalized = min( max( 0., storage_normalized ) , 1.) code = 0 m = soil%pars%storage_index do while (code.eq.0) @@ -964,44 +1350,126 @@ subroutine soil_data_gw_hydraulics(soil, z_bot, psi_bot, gw_flux, sat_frac, & endif enddo if (m.lt.1.or.m.gt.num_storage_pts-1) then - write(*,*) '!!! *** m=',m, ' is outside the table in soil_data_gw_hydraulics *** !!!' + write(*,*) '!!! *** m=',m, ' is outside the table in soil_data_gw_hydraulics_ar5 *** !!!' write(*,*) 'num_storage_pts=',num_storage_pts write(*,*) 'storage_normalized=',storage_normalized write(*,*) 'interval bounds:',gw_storage_norm(m),gw_storage_norm(m+1) endif frac = (storage_normalized-gw_storage_norm(m)) & /(gw_storage_norm(m+1)-gw_storage_norm(m)) - sat_frac = soil%pars%gw_area_norm(m) & - + frac*(soil%pars%gw_area_norm(m+1)-soil%pars%gw_area_norm(m)) - recharge_normalized = soil%pars%gw_flux_norm(m) & - + frac*(soil%pars%gw_flux_norm(m+1)-soil%pars%gw_flux_norm(m)) + sat_frac = soil%gw_area_norm(m) & + + frac*(soil%gw_area_norm(m+1)-soil%gw_area_norm(m)) + recharge_normalized = soil%gw_flux_norm(m) & + + frac*(soil%gw_flux_norm(m+1)-soil%gw_flux_norm(m)) gw_flux = recharge_normalized * soil%pars%k_sat_ref * soil%pars%soil_e_depth & * soil%pars%hillslope_relief & / (soil%pars%hillslope_length * soil%pars%hillslope_length) soil%pars%storage_index = m - ! depth_to_saturation, along with sat_frac, is potentially useful for - ! bgc analysis... - depth_to_saturation = 0. - do m=1,num_l - if (soil%prog(m)%wl+soil%prog(m)%ws .lt. soil%pars%vwc_sat*dens_h2o*dz(m)) then - depth_to_saturation = depth_to_saturation + dz(m) - if (m.eq.num_l) depth_to_saturation = -1. +end subroutine soil_data_gw_hydraulics_ar5 + +! ============================================================================ +subroutine soil_data_gw_hydraulics(soil, deficit_normalized, & + gw_flux, sat_frac ) + type(soil_tile_type), intent(inout) :: soil + real, intent(in) :: deficit_normalized + real, intent(out) :: gw_flux + real, intent(out) :: sat_frac + + integer :: code, m + real :: recharge_normalized, frac, log_deficit_normalized + + ! deficit_normalized is the fraction of soil above drainage base elevation + ! that is NOT saturated/contributing to horizontal flow + + IF (deficit_normalized .LE. 0.) THEN + m = 0 + ELSE IF (deficit_normalized .GE. 1.) THEN + m = num_storage_pts + ELSE + log_deficit_normalized = log10(deficit_normalized) + code = 0 + m = soil%pars%storage_index + do while (code.eq.0.and.m.gt.0.and.m.lt.num_storage_pts) + if (log_deficit_normalized .lt. log_deficit_list(m)) then + m = m - 1 + else if (log_deficit_normalized .gt. log_deficit_list(m+1)) then + m = m + 1 + else + code = 1 + endif + enddo + ENDIF + + IF (m.eq.0) THEN + recharge_normalized = 10.**soil%gw_flux_norm(1) + ELSE IF (m.lt.num_storage_pts) then + frac = (log_deficit_normalized-log_deficit_list(m)) & + /(log_deficit_list(m+1)-log_deficit_list(m)) + recharge_normalized = 10.**(soil%gw_flux_norm(m) & + + frac*(soil%gw_flux_norm(m+1)-soil%gw_flux_norm(m))) + ELSE + recharge_normalized = 0. + ENDIF + + if (use_tau_fix) then + gw_flux = recharge_normalized * & + ((soil%pars%k_sat_sfc+k_macro_constant) * soil%pars%soil_e_depth + & + soil%pars%k_sat_gw*aspect*soil%pars%hillslope_length) & + * soil%pars%hillslope_relief & + / (soil%pars%hillslope_length * soil%pars%hillslope_length) else - exit + gw_flux = recharge_normalized * & + ((soil%pars%k_sat_sfc+k_macro_constant) * soil%pars%soil_e_depth) & + * soil%pars%hillslope_relief & + / (soil%pars%hillslope_length * soil%pars%hillslope_length) endif - enddo + + if (recharge_normalized.gt.1.) then + sat_frac = 1. - 1./recharge_normalized + else + sat_frac = 0. + endif + if (use_sat_fix) then + if (recharge_normalized.gt.1.+soil%pars%tau) then + sat_frac = 1. - (1.+soil%pars%tau)/recharge_normalized + else + sat_frac = 0. + endif + endif + + soil%pars%storage_index = min(max(1,m),num_storage_pts-1) + +! if(is_watch_point()) then +! write(*,*) 'm ', m +! write(*,*) 'code ',code +! write(*,*) 'num_storage_pts', num_storage_pts +! write(*,*) 'frac ', frac +! write(*,*) 'recharge_normalized', recharge_normalized +! write(*,*) 'deficit_normalized ', deficit_normalized +! write(*,*) 'log_deficit_normalized',log_deficit_normalized +! write(*,*) 'gw_flux ',gw_flux +! write(*,*) 'm,log_deficit_list,gw_flux_norm' +! do m=1,num_storage_pts +! write(*,*) m, log_deficit_list(m),soil%gw_flux_norm(m) +! enddo +! endif + end subroutine soil_data_gw_hydraulics ! ============================================================================ -subroutine soil_data_vwc_sat (soil, soil_vwc_sat ) - type(soil_tile_type), intent(in) :: soil - real, intent(out) :: soil_vwc_sat(:) - - soil_vwc_sat(1:num_l) = soil%pars%vwc_sat - -end subroutine soil_data_vwc_sat +subroutine soil_data_vwc_for_init_only (soil, psi, vwc) + type(soil_tile_type), intent(in) :: soil + real, intent(in) :: psi(:) + real, intent(out):: vwc(:) + vwc = soil%pars%vwc_sat* & + ((soil%pars%psi_sat_ref/soil%alpha)/min(psi,(soil%pars%psi_sat_ref/soil%alpha))) & + ** (1./ soil%pars%chb) + if (use_comp_for_ic) then + vwc = vwc + comp*max(psi-soil%pars%psi_sat_ref/soil%alpha,0.) + endif +end subroutine soil_data_vwc_for_init_only ! ============================================================================ subroutine soil_tile_stock_pe (soil, twd_liq, twd_sol ) @@ -1036,4 +1504,12 @@ function soil_tile_heat (soil) result(heat) ; real heat enddo end function +! ============================================================================ +! returns soil tile carbon content, kg C/m2 +function soil_tile_carbon (soil); real soil_tile_carbon + type(soil_tile_type), intent(in) :: soil + + soil_tile_carbon = sum(soil%fast_soil_C(:))+sum(soil%slow_soil_C(:)) +end function + end module soil_tile_mod diff --git a/src/land_lad2/soil/uptake.F90 b/src/land_lad2/soil/uptake.F90 index e3c1eaeb2f..f92dcd9105 100644 --- a/src/land_lad2/soil/uptake.F90 +++ b/src/land_lad2/soil/uptake.F90 @@ -27,8 +27,8 @@ module uptake_mod ! ==== module constants ====================================================== character(len=*), parameter, private :: & module_name = 'uptake',& - version = '$Id: uptake.F90,v 17.0 2009/07/21 03:03:04 fms Exp $',& - tagname = '$Name: siena_201207 $' + version = '$Id: uptake.F90,v 20.0 2013/12/13 23:30:52 fms Exp $',& + tagname = '$Name: tikal $' ! values for internal soil uptake option selector integer, parameter :: & @@ -190,10 +190,6 @@ subroutine darcy2d_uptake ( soil, psi_x0, VRL, K_r, r_r, uptake_oneway, & real :: psi_r - ! calculate some hydraulic properties common for all soil layers - psi_sat = soil%pars%psi_sat_ref/soil%pars%alpha - k_sat = soil%pars%k_sat_ref*soil%pars%alpha**2 - if(is_watch_point())then write(*,*)'##### darcy2d_uptake input #####' __DEBUG3__(psi_x0,psi_sat,K_sat) @@ -202,6 +198,8 @@ subroutine darcy2d_uptake ( soil, psi_x0, VRL, K_r, r_r, uptake_oneway, & ! calculate soil water supply and its derivative uptake = 0; duptake = 0 do l = 1, num_l + psi_sat = soil%pars%psi_sat_ref/soil%alpha(l) + k_sat = soil%pars%k_sat_ref*soil%alpha(l)**2 psi_x = psi_x0+zfull(l) psi_soil = soil%psi(l) if (VRL(l) > 0) then @@ -224,7 +222,7 @@ subroutine darcy2d_uptake ( soil, psi_x0, VRL, K_r, r_r, uptake_oneway, & ! from the current soil layer uptake(l) = VRL(l)*dz(l)*u ; duptake(l) = VRL(l)*dz(l)*du if(is_watch_point()) then - write(*,'(a,i2.2,100(2x,a,g))')'level=',l, & + write(*,'(a,i2.2,100(2x,a,g23.16))')'level=',l, & 'VRL=', VRL(l), 'R=', R,& 'psi_x=', psi_x, 'psi_r=', psi_r, 'psi_soil=', psi_soil, & 'U=',u,& @@ -238,7 +236,7 @@ end subroutine darcy2d_uptake ! for Darcy-flow uptake, find the root water potential such to satisfy actual ! uptake by the vegetation. subroutine darcy2d_uptake_solver (soil, vegn_uptk, VRL, K_r, r_r, uptake_oneway, & - uptake_from_sat, uptake, n_iter) + uptake_from_sat, uptake, psi_x0, n_iter) type(soil_tile_type), intent(in) :: soil real, intent(in) :: & vegn_uptk, & ! uptake requested by vegetation, kg/(m2 s) @@ -249,13 +247,15 @@ subroutine darcy2d_uptake_solver (soil, vegn_uptk, VRL, K_r, r_r, uptake_oneway, uptake_oneway, & ! if true, then the roots can only take up water, but ! never loose it to the soil uptake_from_sat ! if false, uptake from saturated soil is prohibited - real, intent(out) :: uptake(:) ! soil water uptake, by layer + real, intent(out) :: & + uptake(:), & ! soil water uptake, by layer + psi_x0 ! water potential inside roots (in xylem) at zero depth, m integer, intent(out) :: n_iter ! # of iterations made, for diagnostics only real :: uptake_tot call uptake_solver_K(soil, vegn_uptk, VRL, K_r, r_r, uptake_oneway, & - uptake_from_sat, uptake, n_iter, darcy2d_uptake) + uptake_from_sat, uptake, psi_x0, n_iter, darcy2d_uptake) ! since the numerical solution is not exact, adjust the vertical profile ! of uptake to ensure that the sum is equal to transpiration exactly @@ -269,7 +269,7 @@ end subroutine darcy2d_uptake_solver ! the uptake vertical profile for given water potential at the surface, returns ! a soulution subroutine uptake_solver_K (soil, vegn_uptk, VRL, K_r, r_r, uptake_oneway, & - uptake_from_sat, uptake, n_iter, uptake_subr) + uptake_from_sat, uptake, psi_x0, n_iter, uptake_subr) type(soil_tile_type), intent(in) :: soil real, intent(in) :: & vegn_uptk, & ! uptake requested by vegetation, kg/(m2 s) @@ -280,7 +280,9 @@ subroutine uptake_solver_K (soil, vegn_uptk, VRL, K_r, r_r, uptake_oneway, & uptake_oneway, & ! if true, then the roots can only take up water, but ! never loose it to the soil uptake_from_sat ! if false, uptake from saturated soil is prohibited - real, intent(out) :: uptake(:) ! vertical distribution of soil uptake + real, intent(out) :: & + uptake(:), & ! vertical distribution of soil uptake + psi_x0 ! water potential inside roots (in xylem) at zero depth, m integer, intent(out) :: n_iter ! # of iterations made, for diagnostics only interface @@ -359,7 +361,10 @@ end subroutine uptake_subr DfDx = sum(duptake) do n_iter = 1, max_iter ! check if we already reached the desired precision - if(abs(f) ), operator(<), operator(<=), operator(/), & @@ -67,8 +67,8 @@ module land_transitions_mod ! ==== module constants ===================================================== character(len=*), parameter :: & - version = '$Id: transitions.F90,v 19.0 2012/01/06 20:43:22 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: transitions.F90,v 20.0 2013/12/13 23:30:55 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'land_transitions_mod', & diag_mod_name = 'landuse' ! selectors for overshoot handling options, for efficiency @@ -465,7 +465,7 @@ subroutine land_transitions_0d(d_list,d_kinds,a_kinds,area) if (.not.associated(ptr%vegn)) cycle write(*,*)'landuse=',ptr%vegn%landuse,' area=',ptr%frac enddo - write(*,'(a,g)')'total area=',atot + write(*,'(a,g23.16)')'total area=',atot endif ! split each donor tile and gather the parts that undergo a @@ -486,17 +486,17 @@ subroutine land_transitions_0d(d_list,d_kinds,a_kinds,area) do while (ts /= te) ptr=>current_tile(ts); ts=next_elmt(ts) if (.not.associated(ptr%vegn)) cycle - write(*,'(2(a,g,2x))')' donor: landuse=',ptr%vegn%landuse,' area=',ptr%frac + write(*,'(2(a,g23.16,2x))')' donor: landuse=',ptr%vegn%landuse,' area=',ptr%frac atot = atot + ptr%frac enddo ts = first_elmt(a_list); te=tail_elmt(a_list) do while (ts /= te) ptr=>current_tile(ts); ts=next_elmt(ts) if (.not.associated(ptr%vegn)) cycle - write(*,'(2(a,g,2x))')'acceptor: landuse=',ptr%vegn%landuse,' area=',ptr%frac + write(*,'(2(a,g23.16,2x))')'acceptor: landuse=',ptr%vegn%landuse,' area=',ptr%frac atot = atot + ptr%frac enddo - write(*,'(a,g)')'total area=',atot + write(*,'(a,g23.16)')'total area=',atot endif ! move all tiles from the donor list to the acceptor list -- this will ensure @@ -535,10 +535,10 @@ subroutine land_transitions_0d(d_list,d_kinds,a_kinds,area) do while (ts /= te) ptr=>current_tile(ts); ts=next_elmt(ts) if (.not.associated(ptr%vegn)) cycle - write(*,'(2(a,g,2x))')'landuse=',ptr%vegn%landuse,' area=',ptr%frac + write(*,'(2(a,g23.16,2x))')'landuse=',ptr%vegn%landuse,' area=',ptr%frac atot = atot + ptr%frac enddo - write(*,'(a,g)')'total area=',atot + write(*,'(a,g23.16)')'total area=',atot endif ! conservation check part 2: calculate grid cell totals in final state, and @@ -808,10 +808,11 @@ end subroutine get_transitions ! tile transition field, calculates total transition during the specified period. ! The transition rate data are assumed to be in fraction of land area per year, ! timestamped at the beginning of the year -subroutine integral_transition(t1, t2, id, frac) +subroutine integral_transition(t1, t2, id, frac, err_msg) type(time_type), intent(in) :: t1,t2 ! time boundaries integer , intent(in) :: id ! id of the field real , intent(out) :: frac(:,:) + character(len=*),intent(out), optional :: err_msg ! ---- local vars integer :: n ! size of time axis @@ -821,7 +822,9 @@ subroutine integral_transition(t1, t2, id, frac) real :: dt ! current time interval, in years real :: sum(size(frac,1),size(frac,2)) integer :: i,j + character(len=256) :: msg + msg = '' ! adjust the integration limits, in case they are out of range n = size(time_in) ts = t1; @@ -831,7 +834,10 @@ subroutine integral_transition(t1, t2, id, frac) if (te time_in(n)) te = time_in(n) - call time_interp(ts, time_in, w, i1,i2) + call time_interp(ts, time_in, w, i1,i2, err_msg=msg) + if(msg /= '') then + if(fms_error_handler('integral_transition','Message from time_interp: '//trim(msg),err_msg)) return + endif __NF_ASRT__(nfu_get_rec(ncid,id,i1,buffer_in)) frac = 0; @@ -848,7 +854,10 @@ subroutine integral_transition(t1, t2, id, frac) if(i2>size(time_in)) exit ! from loop enddo - call time_interp(te,time_in,w,i1,i2) + call time_interp(te,time_in,w,i1,i2, err_msg=msg) + if(msg /= '') then + if(fms_error_handler('integral_transition','Message from time_interp: '//trim(msg),err_msg)) return + endif __NF_ASRT__(nfu_get_rec(ncid,id,i1,buffer_in)) call horiz_interp(interp,buffer_in,frac) dt = (time_in(i2)-time_in(i1))//set_time(0,days_in_year((time_in(i2)+time_in(i1))/2)) @@ -881,7 +890,7 @@ subroutine check_conservation(name, d1, d2, tolerance) if (abs(d1-d2)>tolerance) then call get_current_point(i=curr_i,j=curr_j,face=face) - write(message,'(a,3(x,a,i4), 2(x,a,g))')& + write(message,'(a,3(x,a,i4), 2(x,a,g23.16))')& 'conservation of '//trim(name)//' is violated', & 'at i=',curr_i,'j=',curr_j,'face=',face, & 'value before=', d1, 'after=', d2 diff --git a/src/land_lad2/vegetation/vegetation.F90 b/src/land_lad2/vegetation/vegetation.F90 index d4f855f2cd..932037dad6 100644 --- a/src/land_lad2/vegetation/vegetation.F90 +++ b/src/land_lad2/vegetation/vegetation.F90 @@ -19,8 +19,8 @@ module vegetation_mod use vegn_tile_mod, only: vegn_tile_type, & vegn_seed_demand, vegn_seed_supply, vegn_add_bliving, & cpw, clw, csw -use soil_tile_mod, only: soil_tile_type, soil_ave_temp, soil_ave_theta, & - soil_ave_theta1 +use soil_tile_mod, only: soil_tile_type, soil_ave_temp, & + soil_ave_theta0, soil_ave_theta1, soil_psi_stress use land_constants_mod, only : NBANDS, BAND_VIS, d608, mol_C, mol_CO2, mol_air, & seconds_per_year use land_tile_mod, only : land_tile_type, land_tile_enum_type, & @@ -82,8 +82,8 @@ module vegetation_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & - version = '$Id: vegetation.F90,v 19.0 2012/01/06 20:43:54 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: vegetation.F90,v 20.0 2013/12/13 23:30:58 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'vegn' ! values for internal selector of CO2 option used for photosynthesis integer, parameter :: VEGN_PHOT_CO2_PRESCRIBED = 1 @@ -113,11 +113,11 @@ module vegetation_mod ! 'interactive' : concentration of co2 in canopy air is used real :: co2_for_photosynthesis = 350.0e-6 ! concentration of co2 for photosynthesis ! calculations, mol/mol. Ignored if co2_to_use_for_photosynthesis is not 'prescribed' -logical :: write_soil_carbon_restart = .FALSE. ! indicates whether to write - ! information for soil carbon acceleration +character(32) :: soil_decomp_option = 'use_ave_t_and_theta' ! or 'use_layer_t_and_theta' logical :: do_cohort_dynamics = .TRUE. ! if true, do vegetation growth logical :: do_patch_disturbance = .TRUE. ! logical :: do_phenology = .TRUE. +logical :: xwilt_available = .TRUE. logical :: do_biogeography = .TRUE. logical :: do_seed_transport = .TRUE. real :: min_Wl=-1.0, min_Ws=-1.0 ! threshold values for condensation numerics, kg/m2: @@ -126,16 +126,23 @@ module vegetation_mod ! evaporation in one time step. real :: tau_smooth_ncm = 0.0 ! Time scale for ncm smoothing ! (low-pass filtering), years. 0.0 retrieves previous behavior (no smoothing) +real :: rav_lit_0 = 0.0 ! constant litter resistance to vapor +real :: rav_lit_vi = 0.0 ! litter resistance to vapor per LAI+SAI +real :: rav_lit_fsc = 0.0 ! litter resistance to vapor per fsc +real :: rav_lit_ssc = 0.0 ! litter resistance to vapor per ssc +real :: rav_lit_bwood = 0.0 ! litter resistance to vapor per bwood namelist /vegn_nml/ & lm2, init_Wl, init_Ws, init_Tv, cpw, clw, csw, & init_cohort_bl, init_cohort_blv, init_cohort_br, init_cohort_bsw, & init_cohort_bwood, init_cohort_cmc, & rad_to_use, snow_rad_to_use, photosynthesis_to_use, & co2_to_use_for_photosynthesis, co2_for_photosynthesis, & - write_soil_carbon_restart, & + soil_decomp_option, & do_cohort_dynamics, do_patch_disturbance, do_phenology, & + xwilt_available, & do_biogeography, do_seed_transport, & - min_Wl, min_Ws, tau_smooth_ncm + min_Wl, min_Ws, tau_smooth_ncm, & + rav_lit_0, rav_lit_vi, rav_lit_fsc, rav_lit_ssc, rav_lit_bwood !---- end of namelist -------------------------------------------------------- @@ -149,14 +156,14 @@ module vegetation_mod integer :: id_vegn_type, id_temp, id_wl, id_ws, id_height, id_lai, id_sai, id_leaf_size, & id_root_density, id_root_zeta, id_rs_min, id_leaf_refl, id_leaf_tran,& id_leaf_emis, id_snow_crit, id_stomatal, id_an_op, id_an_cl, & - id_bl, id_blv, id_br, id_bsw, id_bwood, id_species, id_status, & + id_bl, id_blv, id_br, id_bsw, id_bwood, id_btot, id_species, id_status, & id_con_v_h, id_con_v_v, id_fuel, id_harv_pool(N_HARV_POOLS), & id_harv_rate(N_HARV_POOLS), id_t_harv_pool, id_t_harv_rate, & id_csmoke_pool, id_csmoke_rate, id_fsc_in, id_fsc_out, id_ssc_in, & id_ssc_out, id_veg_in, id_veg_out, id_fsc_pool, id_fsc_rate, & id_ssc_pool, id_ssc_rate, id_t_ann, id_t_cold, id_p_ann, id_ncm, & id_lambda, id_afire, id_atfall, id_closs, id_cgain, id_wdgain, id_leaf_age, & - id_phot_co2 + id_phot_co2, id_theph, id_psiph, id_evap_demand ! ==== end of module variables =============================================== ! ==== NetCDF declarations =================================================== @@ -303,15 +310,21 @@ subroutine vegn_init ( id_lon, id_lat, id_band ) if(nfu_inq_var(unit,'landuse')==NF_NOERR) & call read_tile_data_i0d_fptr(unit,'landuse',vegn_landuse_ptr) call read_tile_data_r0d_fptr(unit,'age',vegn_age_ptr) - call read_tile_data_r0d_fptr(unit,'fsc',vegn_fast_soil_C_ptr) - call read_tile_data_r0d_fptr(unit,'ssc',vegn_slow_soil_C_ptr) call read_tile_data_r0d_fptr(unit,'fsc_pool',vegn_fsc_pool_ptr) call read_tile_data_r0d_fptr(unit,'fsc_rate',vegn_fsc_rate_ptr) call read_tile_data_r0d_fptr(unit,'ssc_pool',vegn_ssc_pool_ptr) call read_tile_data_r0d_fptr(unit,'ssc_rate',vegn_ssc_rate_ptr) ! monthly-mean values call read_tile_data_r0d_fptr(unit,'tc_av', vegn_tc_av_ptr) - call read_tile_data_r0d_fptr(unit,'theta_av', vegn_theta_av_ptr) + if(nfu_inq_var(unit,'theta_av_phen')==NF_NOERR) then + call read_tile_data_r0d_fptr(unit,'theta_av_phen', vegn_theta_av_phen_ptr) + call read_tile_data_r0d_fptr(unit,'theta_av_fire', vegn_theta_av_fire_ptr) + call read_tile_data_r0d_fptr(unit,'psist_av', vegn_psist_av_ptr) + else + call read_tile_data_r0d_fptr(unit,'theta_av', vegn_theta_av_phen_ptr) + call read_tile_data_r0d_fptr(unit,'theta_av', vegn_theta_av_fire_ptr) + ! psist_av remains at initial value (equal to 0) + endif call read_tile_data_r0d_fptr(unit,'tsoil_av', vegn_tsoil_av_ptr) call read_tile_data_r0d_fptr(unit,'precip_av', vegn_precip_av_ptr) call read_tile_data_r0d_fptr(unit,'lambda', vegn_lambda_ptr) @@ -402,19 +415,9 @@ subroutine vegn_init ( id_lon, id_lat, id_band ) cohort%species = tile%vegn%tag endif enddo - - call get_input_restart_name('INPUT/soil_carbon.res.nc',restart_1_exists,restart_file_name_1) - if (restart_1_exists) then - __NF_ASRT__(nf_open(restart_file_name_1,NF_NOWRITE,unit)) - call error_mesg('veg_data_init','reading soil_carbon restart',NOTE) - call read_tile_data_r0d_fptr(unit,'asoil_in',vegn_asoil_in_ptr) - call read_tile_data_r0d_fptr(unit,'fsc_in',vegn_fsc_in_ptr) - call read_tile_data_r0d_fptr(unit,'ssc_in',vegn_ssc_in_ptr) - __NF_ASRT__(nf_close(unit)) - endif - + ! initialize carbon integrator - call vegn_dynamics_init ( id_lon, id_lat, lnd%time, delta_time ) + call vegn_dynamics_init ( id_lon, id_lat, lnd%time, delta_time, soil_decomp_option ) ! initialize static vegetation call static_vegn_init () @@ -488,6 +491,9 @@ subroutine vegn_diag_init ( id_lon, id_lat, id_band, time ) (/id_lon,id_lat/), time, missing_value=-1.0 ) id_stomatal = register_tiled_diag_field ( module_name, 'stomatal_cond', & (/id_lon,id_lat/), time, 'vegetation stomatal conductance', missing_value=-1.0 ) + id_evap_demand = register_tiled_diag_field ( module_name, 'evap_demand', & + (/id_lon,id_lat/), time, 'plant evaporative water demand',& + 'kg/(m2 s)', missing_value=-1e20 ) id_an_op = register_tiled_diag_field ( module_name, 'an_op', & (/id_lon,id_lat/), time, 'net photosynthesis with open stomata', & '(mol CO2)(m2 of leaf)^-1 year^-1', missing_value=-1e20 ) @@ -505,6 +511,8 @@ subroutine vegn_diag_init ( id_lon, id_lat, id_band, time ) (/id_lon,id_lat/), time, 'biomass of sapwood', 'kg C/m2', missing_value=-1.0 ) id_bwood = register_tiled_diag_field ( module_name, 'bwood', & (/id_lon,id_lat/), time, 'biomass of heartwood', 'kg C/m2', missing_value=-1.0 ) + id_btot = register_tiled_diag_field ( module_name, 'btot', & + (/id_lon,id_lat/), time, 'total biomass', 'kg C/m2', missing_value=-1.0 ) id_fuel = register_tiled_diag_field ( module_name, 'fuel', & (/id_lon,id_lat/), time, 'mass of fuel', 'kg C/m2', missing_value=-1.0 ) id_lambda = register_tiled_diag_field (module_name, 'lambda',(/id_lon,id_lat/), & @@ -514,7 +522,11 @@ subroutine vegn_diag_init ( id_lon, id_lat, id_band, time ) (/id_lon,id_lat/), time, 'vegetation species number', missing_value=-1.0 ) id_status = register_tiled_diag_field ( module_name, 'status', & (/id_lon,id_lat/), time, 'status of leaves', missing_value=-1.0 ) - id_leaf_age = register_tiled_diag_field ( module_name, 'leaf_age', & + id_theph = register_tiled_diag_field ( module_name, 'theph', & + (/id_lon,id_lat/), time, 'theta for phenology', missing_value=-1.0 ) + id_psiph = register_tiled_diag_field ( module_name, 'psiph', & + (/id_lon,id_lat/), time, 'psi stress for phenology', missing_value=-1.0 ) + id_leaf_age = register_tiled_diag_field ( module_name, 'leaf_age', & (/id_lon,id_lat/), time, 'age of leaves since bud burst', 'days', missing_value=-1.0 )!ens id_con_v_h = register_tiled_diag_field ( module_name, 'con_v_h', (/id_lon,id_lat/), & @@ -684,8 +696,6 @@ subroutine save_vegn_restart(tile_dim_length,timestamp) call write_tile_data_i0d_fptr(unit,'landuse',vegn_landuse_ptr,'vegetation land use type') call write_tile_data_r0d_fptr(unit,'age',vegn_age_ptr,'vegetation age', 'yr') - call write_tile_data_r0d_fptr(unit,'fsc',vegn_fast_soil_C_ptr,'fast soil carbon', 'kg C/m2') - call write_tile_data_r0d_fptr(unit,'ssc',vegn_slow_soil_C_ptr,'slow soil carbon', 'kg C/m2') call write_tile_data_r0d_fptr(unit,'fsc_pool',vegn_fsc_pool_ptr,'intermediate pool for fast soil carbon input', 'kg C/m2') call write_tile_data_r0d_fptr(unit,'fsc_rate',vegn_fsc_rate_ptr,'conversion rate of fsc_pool to fast soil carbon', 'kg C/(m2 yr)') call write_tile_data_r0d_fptr(unit,'ssc_pool',vegn_ssc_pool_ptr,'intermediate pool for slow soil carbon input', 'kg C/m2') @@ -693,7 +703,9 @@ subroutine save_vegn_restart(tile_dim_length,timestamp) ! monthly-mean values call write_tile_data_r0d_fptr(unit,'tc_av', vegn_tc_av_ptr,'average canopy air temperature','degK') - call write_tile_data_r0d_fptr(unit,'theta_av', vegn_theta_av_ptr,'average soil moisture') + call write_tile_data_r0d_fptr(unit,'theta_av_phen', vegn_theta_av_phen_ptr,'average soil moisture for phenology') + call write_tile_data_r0d_fptr(unit,'theta_av_fire', vegn_theta_av_fire_ptr,'average soil moisture for fire') + call write_tile_data_r0d_fptr(unit,'psist_av', vegn_psist_av_ptr,'average soil-water-stress index') call write_tile_data_r0d_fptr(unit,'tsoil_av', vegn_tsoil_av_ptr,'average bulk soil temperature for soil carbon','degK') call write_tile_data_r0d_fptr(unit,'precip_av', vegn_precip_av_ptr,'average total precipitation','kg/(m2 s)') call write_tile_data_r0d_fptr(unit,'lambda', vegn_lambda_ptr,'dryness parameter') @@ -724,16 +736,6 @@ subroutine save_vegn_restart(tile_dim_length,timestamp) __NF_ASRT__(nf_close(unit)) - if (write_soil_carbon_restart) then - call create_tile_out_file(unit,'RESTART/'//trim(timestamp)//'soil_carbon.res.nc', & - lnd%coord_glon, lnd%coord_glat, vegn_tile_exists, tile_dim_length ) - - call write_tile_data_r0d_fptr(unit,'asoil_in',vegn_asoil_in_ptr,'aerobic activity modifier', 'unitless') - call write_tile_data_r0d_fptr(unit,'fsc_in',vegn_fsc_in_ptr,'fast soil carbon input', 'kg C/m2') - call write_tile_data_r0d_fptr(unit,'ssc_in',vegn_ssc_in_ptr,'slow soil carbon input', 'kg C/m2') - __NF_ASRT__(nf_close(unit)) - endif - end subroutine save_vegn_restart @@ -767,7 +769,7 @@ end subroutine vegn_diffusion ! ============================================================================ -subroutine vegn_step_1 ( vegn, diag, & +subroutine vegn_step_1 ( vegn, soil, diag, & p_surf, ustar, drag_q, & SWdn, RSv, precip_l, precip_s, & land_d, land_z0s, land_z0m, grnd_z0s, & @@ -785,6 +787,9 @@ subroutine vegn_step_1 ( vegn, diag, & Eli0, DEliDTv, DEliDqc, DEliDwl, DEliDwf, & ! evaporation of intercepted water Efi0, DEfiDTv, DEfiDqc, DEfiDwl, DEfiDwf ) ! sublimation of intercepted snow type(vegn_tile_type), intent(inout) :: vegn ! vegetation data + type(soil_tile_type), intent(inout) :: soil ! soil data + ! TODO: possibly move calculation of soil-related stuff from calling subroutine to here + ! now since we have soil tiled passed to us type(diag_buff_type), intent(inout) :: diag ! diagnostic buffer real, intent(in) :: & p_surf, & ! surface pressure, N/m2 @@ -823,11 +828,13 @@ subroutine vegn_step_1 ( vegn, diag, & ! derivatives w.r.t. intercepted water masses stomatal_cond, & ! integral stomatal conductance of canopy con_v_h, con_v_v, & ! aerodyn. conductance between canopy and CAS, for heat and vapor + rav_lit, & ! additional resistance of litter to vapor transport total_cond, &! overall conductance from inside stomata to canopy air qvsat, & ! sat. specific humidity at the leaf T DqvsatDTv, & ! derivative of qvsat w.r.t. leaf T rho, & ! density of canopy air phot_co2, & ! co2 mixing ratio for photosynthesis, mol CO2/mol dry air + evap_demand, & ! evaporative water demand, kg/(m2 s) photosynt, & ! photosynthesis photoresp ! photo-respiration type(vegn_cohort_type), pointer :: cohort @@ -851,7 +858,7 @@ subroutine vegn_step_1 ( vegn, diag, & endif ! check the range of input temperature - call check_temp_range(cohort%prog%Tv,'vegn_step_1','cohort%prog%Tv') + call check_temp_range(cohort%prog%Tv,'vegn_step_1','cohort%prog%Tv', lnd%time) ! calculate the fractions of intercepted precipitation vegn_ifrac = cohort%cover @@ -865,6 +872,15 @@ subroutine vegn_step_1 ( vegn, diag, & land_d, land_z0m, land_z0s, grnd_z0s, & con_v_h, con_v_v, con_g_h, con_g_v) + ! take into account additional resistance of litter to the water vapor flux. + ! not a good parameterization, but just using for sensitivity analyses now. + ! ignores differing biomass and litter turnover rates. + rav_lit = rav_lit_0 + rav_lit_vi * (cohort%lai+cohort%sai) & + + rav_lit_fsc * soil%fast_soil_C(1) & + + rav_lit_ssc * soil%slow_soil_C(1) & + + rav_lit_bwood * cohort%bwood + con_g_v = con_g_v/(1.0+rav_lit*con_g_v) + ! calculate the vegetation photosynthesis and associated stomatal conductance if (vegn_phot_co2_option == VEGN_PHOT_CO2_INTERACTIVE) then phot_co2 = cana_co2_mol @@ -874,7 +890,7 @@ subroutine vegn_step_1 ( vegn, diag, & call vegn_photosynthesis ( vegn, & SWdn(BAND_VIS), RSv(BAND_VIS), cana_q, phot_co2, p_surf, drag_q, & soil_beta, soil_water_supply, & - stomatal_cond, photosynt, photoresp ) + evap_demand, stomatal_cond, photosynt, photoresp ) call get_vegn_wet_frac ( cohort, fw, DfwDwl, DfwDwf, fs, DfsDwl, DfsDwf ) ! transpiring fraction and its derivatives @@ -975,6 +991,7 @@ subroutine vegn_step_1 ( vegn, diag, & endif ! ---- diagnostic section + call send_tile_data(id_evap_demand, evap_demand, diag) call send_tile_data(id_stomatal, stomatal_cond, diag) call send_tile_data(id_an_op, cohort%An_op, diag) call send_tile_data(id_an_cl, cohort%An_cl, diag) @@ -1121,7 +1138,7 @@ end subroutine vegn_step_2 ! of prognostic land variables subroutine vegn_step_3(vegn, soil, cana_T, precip, vegn_fco2, diag) type(vegn_tile_type), intent(inout) :: vegn - type(soil_tile_type), intent(in) :: soil + type(soil_tile_type), intent(inout) :: soil real, intent(in) :: cana_T ! canopy temperature, deg K real, intent(in) :: precip ! total (rain+snow) precipitation, kg/(m2 s) real, intent(out) :: vegn_fco2 ! co2 flux from vegetation, kg CO2/(m2 s) @@ -1130,6 +1147,7 @@ subroutine vegn_step_3(vegn, soil, cana_T, precip, vegn_fco2, diag) ! ---- local vars real :: tsoil ! average temperature of soil for soil carbon decomposition, deg K real :: theta ! average soil wetness, unitless + real :: psist ! psi stress index real :: depth_ave! depth for averaging soil moisture based on Jackson function for root distribution real :: percentile = 0.95 @@ -1144,7 +1162,7 @@ subroutine vegn_step_3(vegn, soil, cana_T, precip, vegn_fco2, diag) __DEBUG3__(depth_ave, tsoil, theta) endif - call vegn_carbon_int(vegn, tsoil, theta, diag) + call vegn_carbon_int(vegn, soil, tsoil, theta, diag) ! decrease, if necessary, csmoke spending rate so that csmoke pool ! is never depleted below zero vegn%csmoke_rate = max( 0.0, & @@ -1170,9 +1188,20 @@ subroutine vegn_step_3(vegn, soil, cana_T, precip, vegn_fco2, diag) vegn%tc_av = vegn%tc_av + cana_T vegn%tsoil_av = vegn%tsoil_av + tsoil vegn%precip_av = vegn%precip_av + precip - vegn%theta_av = vegn%theta_av + soil_ave_theta1(soil,depth_ave) + if (xwilt_available) then + theta = soil_ave_theta1(soil,depth_ave) + else + theta = soil_ave_theta0(soil,vegn%cohorts(1)%root_zeta) + endif + vegn%theta_av_phen = vegn%theta_av_phen + theta + vegn%theta_av_fire = vegn%theta_av_fire + soil_ave_theta1(soil,depth_ave) + psist = soil_psi_stress(soil,vegn%cohorts(1)%root_zeta) + vegn%psist_av = vegn%psist_av + psist vegn%n_accum = vegn%n_accum+1 + + call send_tile_data(id_theph, theta, diag) + call send_tile_data(id_psiph, psist, diag) end subroutine vegn_step_3 @@ -1209,7 +1238,9 @@ subroutine update_vegn_slow( ) ! compute averages from accumulated monthly values tile%vegn%tc_av = tile%vegn%tc_av / tile%vegn%n_accum tile%vegn%tsoil_av = tile%vegn%tsoil_av / tile%vegn%n_accum - tile%vegn%theta_av = tile%vegn%theta_av / tile%vegn%n_accum + tile%vegn%theta_av_phen = tile%vegn%theta_av_phen / tile%vegn%n_accum + tile%vegn%theta_av_fire = tile%vegn%theta_av_fire / tile%vegn%n_accum + tile%vegn%psist_av = tile%vegn%psist_av / tile%vegn%n_accum tile%vegn%precip_av = tile%vegn%precip_av / tile%vegn%n_accum ! accumulate annual values tile%vegn%p_ann_acm = tile%vegn%p_ann_acm+tile%vegn%precip_av @@ -1223,9 +1254,9 @@ subroutine update_vegn_slow( ) ! annual averaging if (year1 /= year0) then - ! The ncm smoothing is coded as a low-pass exponential filter. See, for example - ! http://en.wikipedia.org/wiki/Low-pass_filter - weight_ncm = 1/(1+tau_smooth_ncm) + ! The ncm smoothing is coded as a low-pass exponential filter. See, for example + ! http://en.wikipedia.org/wiki/Low-pass_filter + weight_ncm = 1/(1+tau_smooth_ncm) if(tile%vegn%nmn_acm /= 0) then ! calculate annual averages from accumulated values tile%vegn%p_ann = tile%vegn%p_ann_acm/tile%vegn%nmn_acm @@ -1257,16 +1288,16 @@ subroutine update_vegn_slow( ) call send_tile_data(id_closs,sum(tile%vegn%cohorts(1:n)%carbon_loss),tile%diag) call send_tile_data(id_wdgain,sum(tile%vegn%cohorts(1:n)%bwood_gain),tile%diag) call vegn_growth(tile%vegn) - call vegn_nat_mortality(tile%vegn,86400.0) + call vegn_nat_mortality(tile%vegn,tile%soil,86400.0) endif if (month1 /= month0 .and. do_phenology) then - call vegn_phenology (tile%vegn,tile%soil%w_wilt(1)/tile%soil%pars%vwc_sat) + call vegn_phenology (tile%vegn, tile%soil) ! assume that all layers are the same soil type and wilting is vertically homogeneous endif if (year1 /= year0 .and. do_patch_disturbance) then - call vegn_disturbance(tile%vegn, seconds_per_year) + call vegn_disturbance(tile%vegn, tile%soil, seconds_per_year) endif if (year1 /= year0) then @@ -1309,15 +1340,20 @@ subroutine update_vegn_slow( ) call send_tile_data(id_br, sum(tile%vegn%cohorts(1:n)%br), tile%diag) call send_tile_data(id_bsw, sum(tile%vegn%cohorts(1:n)%bsw), tile%diag) call send_tile_data(id_bwood, sum(tile%vegn%cohorts(1:n)%bwood), tile%diag) + call send_tile_data(id_btot, sum(tile%vegn%cohorts(1:n)%bl & + +tile%vegn%cohorts(1:n)%blv & + +tile%vegn%cohorts(1:n)%br & + +tile%vegn%cohorts(1:n)%bsw & + +tile%vegn%cohorts(1:n)%bwood ), tile%diag) call send_tile_data(id_fuel, tile%vegn%fuel, tile%diag) call send_tile_data(id_species, real(tile%vegn%cohorts(1)%species), tile%diag) call send_tile_data(id_status, real(tile%vegn%cohorts(1)%status), tile%diag) call send_tile_data(id_leaf_age,real(tile%vegn%cohorts(1)%leaf_age), tile%diag)!ens ! carbon budget tracking - call send_tile_data(id_fsc_in, tile%vegn%fsc_in, tile%diag) + call send_tile_data(id_fsc_in, sum(tile%soil%fsc_in(:)), tile%diag) call send_tile_data(id_fsc_out, tile%vegn%fsc_out, tile%diag) - call send_tile_data(id_ssc_in, tile%vegn%ssc_in, tile%diag) + call send_tile_data(id_ssc_in, sum(tile%soil%ssc_in(:)), tile%diag) call send_tile_data(id_ssc_out, tile%vegn%ssc_out, tile%diag) call send_tile_data(id_veg_in, tile%vegn%veg_in, tile%diag) call send_tile_data(id_veg_out, tile%vegn%veg_out, tile%diag) @@ -1328,7 +1364,9 @@ subroutine update_vegn_slow( ) tile%vegn%n_accum = 0 tile%vegn%tc_av = 0. tile%vegn%tsoil_av = 0. - tile%vegn%theta_av = 0. + tile%vegn%theta_av_phen = 0. + tile%vegn%theta_av_fire = 0. + tile%vegn%psist_av = 0. tile%vegn%precip_av= 0. endif @@ -1429,17 +1467,14 @@ #define DEFINE_COHORT_COMPONENT_ACCESSOR(xtype,component,x) subroutine cohort_ # DEFINE_VEGN_ACCESSOR_0D(integer,landuse) DEFINE_VEGN_ACCESSOR_0D(real,age) -DEFINE_VEGN_ACCESSOR_0D(real,fast_soil_C) -DEFINE_VEGN_ACCESSOR_0D(real,slow_soil_C) DEFINE_VEGN_ACCESSOR_0D(real,fsc_pool) DEFINE_VEGN_ACCESSOR_0D(real,fsc_rate) DEFINE_VEGN_ACCESSOR_0D(real,ssc_pool) DEFINE_VEGN_ACCESSOR_0D(real,ssc_rate) -DEFINE_VEGN_ACCESSOR_0D(real,asoil_in) -DEFINE_VEGN_ACCESSOR_0D(real,fsc_in) -DEFINE_VEGN_ACCESSOR_0D(real,ssc_in) DEFINE_VEGN_ACCESSOR_0D(real,tc_av) -DEFINE_VEGN_ACCESSOR_0D(real,theta_av) +DEFINE_VEGN_ACCESSOR_0D(real,theta_av_phen) +DEFINE_VEGN_ACCESSOR_0D(real,theta_av_fire) +DEFINE_VEGN_ACCESSOR_0D(real,psist_av) DEFINE_VEGN_ACCESSOR_0D(real,tsoil_av) DEFINE_VEGN_ACCESSOR_0D(real,precip_av) DEFINE_VEGN_ACCESSOR_0D(real,fuel) diff --git a/src/land_lad2/vegetation/vegn_cohort.F90 b/src/land_lad2/vegetation/vegn_cohort.F90 index 3cd2f4d836..d18851d93b 100644 --- a/src/land_lad2/vegetation/vegn_cohort.F90 +++ b/src/land_lad2/vegetation/vegn_cohort.F90 @@ -39,8 +39,8 @@ module vegn_cohort_mod ! ==== module constants ====================================================== character(len=*), parameter :: & - version = '$Id: vegn_cohort.F90,v 19.0 2012/01/06 20:43:56 fms Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: vegn_cohort.F90,v 20.0 2013/12/13 23:31:00 fms Exp $', & + tagname = '$Name: tikal $' ! ==== types ================================================================= type :: vegn_phys_prog_type @@ -91,7 +91,7 @@ module vegn_cohort_mod real :: cover integer :: pt = 0 ! physiology type - integer :: phent = 0 + integer :: phent = 0 ! phenology type real :: b = 0.0 ! total biomass real :: babove = 0.0 ! total above ground biomass diff --git a/src/land_lad2/vegetation/vegn_cohort_io.F90 b/src/land_lad2/vegetation/vegn_cohort_io.F90 index d97d9dfedb..7352070054 100644 --- a/src/land_lad2/vegetation/vegn_cohort_io.F90 +++ b/src/land_lad2/vegetation/vegn_cohort_io.F90 @@ -6,7 +6,7 @@ module cohort_io_mod use nf_utils_mod, only : nfu_inq_dim, nfu_get_var, nfu_put_var, & nfu_get_rec, nfu_put_rec, nfu_def_dim, nfu_def_var, nfu_put_att, & nfu_inq_var -use land_io_mod, only : print_netcdf_error +use land_io_mod, only : print_netcdf_error, input_buf_size use land_tile_mod, only : land_tile_type, land_tile_list_type, & land_tile_enum_type, first_elmt, tail_elmt, next_elmt, get_elmt_indices, & current_tile, operator(/=) @@ -32,14 +32,12 @@ module cohort_io_mod ! ==== module constants ====================================================== character(len=*), parameter :: & module_name = 'cohort_io_mod', & - version = '$Id: vegn_cohort_io.F90,v 19.0.4.2 2012/05/14 19:18:34 Zhi.Liang Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: vegn_cohort_io.F90,v 20.0 2013/12/13 23:31:02 fms Exp $', & + tagname = '$Name: tikal $' ! name of the "compressed" dimension (and dimension variable) in the output ! netcdf files -- that is, the dimensions written out using compression by ! gathering, as described in CF conventions. character(len=*), parameter :: cohort_index_name = 'cohort_index' -integer, parameter :: INPUT_BUF_SIZE = 1024 ! max size of the input buffer for - ! cohort input ! ==== NetCDF declarations =================================================== include 'netcdf.inc' @@ -97,7 +95,7 @@ subroutine read_create_cohorts(ncid) ! read the cohort index __NF_ASRT__(nfu_inq_dim(ncid,cohort_index_name,len=ncohorts)) __NF_ASRT__(nfu_inq_var(ncid,cohort_index_name,id=idxid)) - bufsize = min(INPUT_BUF_SIZE,ncohorts) + bufsize = min(input_buf_size,ncohorts) allocate(idx(bufsize)) do nn = 1, ncohorts, bufsize @@ -226,7 +224,7 @@ subroutine create_cohort_dimension(ncid) enddo ! create cohort dimension in the output file iret = nf_redef(ncid) - __NF_ASRT__(nfu_def_dim(ncid,'cohort',max_cohorts)) + __NF_ASRT__(nfu_def_dim(ncid,'cohort',(/(i,i=1,max_cohorts)/),'cohort number within tile')) ! create cohort index __NF_ASRT__(nfu_def_dim(ncid,cohort_index_name,idx2,'compressed vegetation cohort index')) __NF_ASRT__(nfu_put_att(ncid,cohort_index_name,'compress','cohort tile lat lon')) diff --git a/src/land_lad2/vegetation/vegn_cohort_io.inc b/src/land_lad2/vegetation/vegn_cohort_io.inc index 4803edcb85..56daaa4a6b 100644 --- a/src/land_lad2/vegetation/vegn_cohort_io.inc +++ b/src/land_lad2/vegetation/vegn_cohort_io.inc @@ -1,5 +1,5 @@ ! -*-f90-*- -! $Id: vegn_cohort_io.inc,v 19.0.4.2 2012/05/14 19:18:34 Zhi.Liang Exp $ +! $Id: vegn_cohort_io.inc,v 20.0 2013/12/13 23:31:04 fms Exp $ ! some sanity checks #ifndef F90_TYPE @@ -63,7 +63,7 @@ subroutine READ_0D_FPTR(ncid,name,fptr,rec) __NF_ASRT__(nfu_inq_var(ncid,cohort_index_name,id=idxid)) ! allocate data - bufsize=min(INPUT_BUF_SIZE,ncohorts) + bufsize=min(input_buf_size,ncohorts) allocate(data(bufsize),idx(bufsize)) do n = 1, ncohorts, bufsize diff --git a/src/land_lad2/vegetation/vegn_data.F90 b/src/land_lad2/vegetation/vegn_data.F90 index 45f3307600..0fe0e46436 100644 --- a/src/land_lad2/vegetation/vegn_data.F90 +++ b/src/land_lad2/vegetation/vegn_data.F90 @@ -8,11 +8,12 @@ module vegn_data_mod use fms_mod, only : & write_version_number, file_exist, check_nml_error, & - close_file, stdlog + close_file, stdlog, stdout -use land_constants_mod, only : NBANDS +use land_constants_mod, only : NBANDS, BAND_VIS, BAND_NIR use land_tile_selectors_mod, only : & tile_selector_type, SEL_VEGN, register_tile_selector +use table_printer_mod implicit none private @@ -112,8 +113,8 @@ module vegn_data_mod ! ==== constants ============================================================= character(len=*), parameter :: & - version = '$Id: vegn_data.F90,v 19.0 2012/01/06 20:44:32 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: vegn_data.F90,v 20.0 2013/12/13 23:31:06 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'vegn_data_mod' real, parameter :: TWOTHIRDS = 2.0/3.0 @@ -174,6 +175,9 @@ module vegn_data_mod ! critical temperature for leaf drop, was internal to phenology real :: tc_crit + ! critical soil-water-stress index, used in place of fact_crit_phen and + ! cnst_crit_phen. It is used if and only if it's value is greater than 0 + real :: psi_stress_crit_phen real :: fact_crit_phen, cnst_crit_phen ! wilting factor and offset to ! get critical value for leaf drop -- only one is non-zero at any time real :: fact_crit_fire, cnst_crit_fire ! wilting factor and offset to @@ -343,6 +347,8 @@ module vegn_data_mod ! c4grass c3grass temp-decid tropical evergreen BE BD BN NE ND G D T A real :: tc_crit(0:MSPECIES)= & (/ 283.16, 278.16, 283.16, 283.16, 263.16, 0., 0., 0., 0., 0., 0., 0., 0., 0. /) +real :: psi_stress_crit_phen(0:MSPECIES)= & ! iff > 0, critical soil-water-stress index for leaf drop, overrides water content + (/ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 /) real :: cnst_crit_phen(0:MSPECIES)= & ! constant critical value for leaf drop (/ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 /) real :: fact_crit_phen(0:MSPECIES)= & ! factor for wilting to get critical value for leaf drop @@ -417,8 +423,8 @@ module vegn_data_mod smoke_fraction, agf_bs, K1,K2, fsc_liv, fsc_wood, & tau_drip_l, tau_drip_s, GR_factor, tg_c3_thresh, tg_c4_thresh, & fsc_pool_spending_time, ssc_pool_spending_time, harvest_spending_time, & - l_fract, T_transp_min, & - tc_crit, cnst_crit_phen, fact_crit_phen, cnst_crit_fire, fact_crit_fire, & + l_fract, T_transp_min, tc_crit, psi_stress_crit_phen, & + cnst_crit_phen, fact_crit_phen, cnst_crit_fire, fact_crit_fire, & scnd_biomass_bins, phen_ev1, phen_ev2 @@ -433,6 +439,8 @@ subroutine read_vegn_data_namelist() integer :: io ! i/o status for the namelist integer :: ierr ! error code, returned by i/o routines integer :: i + + type(table_printer_type) :: table call write_version_number(version, tagname) #ifdef INTERNAL_FILE_NML @@ -504,6 +512,7 @@ subroutine read_vegn_data_namelist() spdata%leaf_size = leaf_size spdata%tc_crit = tc_crit + spdata%psi_stress_crit_phen = psi_stress_crit_phen spdata%cnst_crit_phen = cnst_crit_phen spdata%fact_crit_phen = fact_crit_phen spdata%cnst_crit_fire = cnst_crit_fire @@ -539,6 +548,74 @@ subroutine read_vegn_data_namelist() write (unit, nml=vegn_data_nml) + call init_with_headers(table,species_name) + call add_row(table,'Treefall dist. rate', spdata(:)%treefall_disturbance_rate) + call add_row(table,'Mortality kills balive', spdata(:)%mortality_kills_balive) + call add_row(table,'Phisiology Type', spdata(:)%pt) + call add_row(table,'C1', spdata(:)%c1) + call add_row(table,'C2', spdata(:)%c2) + call add_row(table,'C3', spdata(:)%c3) + + call add_row(table,'alpha_leaf', spdata(:)%alpha(CMPT_LEAF)) + call add_row(table,'alpha_root', spdata(:)%alpha(CMPT_ROOT)) + call add_row(table,'alpha_vleaf', spdata(:)%alpha(CMPT_VLEAF)) + call add_row(table,'alpha_sapwood', spdata(:)%alpha(CMPT_SAPWOOD)) + call add_row(table,'alpha_wood', spdata(:)%alpha(CMPT_WOOD)) + call add_row(table,'alpha_repro', spdata(:)%alpha(CMPT_REPRO)) + + call add_row(table,'beta_leaf', spdata(:)%beta(CMPT_LEAF)) + call add_row(table,'beta_root', spdata(:)%beta(CMPT_ROOT)) + call add_row(table,'beta_vleaf', spdata(:)%beta(CMPT_VLEAF)) + call add_row(table,'beta_sapwood', spdata(:)%beta(CMPT_SAPWOOD)) + call add_row(table,'beta_wood', spdata(:)%beta(CMPT_WOOD)) + call add_row(table,'beta_repro', spdata(:)%beta(CMPT_REPRO)) + + call add_row(table,'dfr', spdata(:)%dfr) + + call add_row(table,'srl', spdata(:)%srl) + call add_row(table,'root_r', spdata(:)%root_r) + call add_row(table,'root_perm', spdata(:)%root_perm) + + call add_row(table,'specific_leaf_area', spdata(:)%specific_leaf_area) + call add_row(table,'leaf_size', spdata(:)%leaf_size) + call add_row(table,'leaf_life_span',spdata(:)%leaf_life_span) + + call add_row(table,'alpha_phot', spdata(:)%alpha_phot) + call add_row(table,'m_cond', spdata(:)%m_cond) + call add_row(table,'Vmax', spdata(:)%Vmax) + call add_row(table,'gamma_resp', spdata(:)%gamma_resp) + call add_row(table,'wet_leaf_dreg', spdata(:)%wet_leaf_dreg) + call add_row(table,'leaf_age_onset',spdata(:)%leaf_age_onset) + call add_row(table,'leaf_age_tau', spdata(:)%leaf_age_tau) + + call add_row(table,'leaf_refl_vis', spdata(:)%leaf_refl(BAND_VIS)) + call add_row(table,'leaf_refl_nir', spdata(:)%leaf_refl(BAND_NIR)) + call add_row(table,'leaf_tran_vis', spdata(:)%leaf_tran(BAND_VIS)) + call add_row(table,'leaf_tran_nir', spdata(:)%leaf_tran(BAND_NIR)) + call add_row(table,'leaf_emis', spdata(:)%leaf_emis) + call add_row(table,'ksi', spdata(:)%ksi) + call add_row(table,'phi1', spdata(:)%phi1) + call add_row(table,'phi2', spdata(:)%phi2) + call add_row(table,'mu_bar', spdata(:)%mu_bar) + + call add_row(table,'cmc_lai', spdata(:)%cmc_lai) + call add_row(table,'cmc_pow', spdata(:)%cmc_pow) + call add_row(table,'csc_lai', spdata(:)%csc_lai) + call add_row(table,'csc_pow', spdata(:)%csc_pow) + call add_row(table,'fuel_intensity',spdata(:)%fuel_intensity) + + call add_row(table,'tc_crit', spdata(:)%tc_crit) + call add_row(table,'psi_stress_crit_phen', spdata(:)%psi_stress_crit_phen) + call add_row(table,'fact_crit_phen',spdata(:)%fact_crit_phen) + call add_row(table,'cnst_crit_phen',spdata(:)%cnst_crit_phen) + call add_row(table,'fact_crit_fire',spdata(:)%fact_crit_fire) + call add_row(table,'cnst_crit_fire',spdata(:)%cnst_crit_fire) + + call add_row(table,'smoke_fraction',spdata(:)%smoke_fraction) + + call print(table,stdout()) + call print(table,unit) + end subroutine diff --git a/src/land_lad2/vegetation/vegn_disturbance.F90 b/src/land_lad2/vegetation/vegn_disturbance.F90 index f5a7e11186..275679b42e 100644 --- a/src/land_lad2/vegetation/vegn_disturbance.F90 +++ b/src/land_lad2/vegetation/vegn_disturbance.F90 @@ -6,6 +6,7 @@ module vegn_disturbance_mod use land_constants_mod, only : seconds_per_year use vegn_data_mod, only : spdata, fsc_wood, fsc_liv, agf_bs, LEAF_OFF use vegn_tile_mod, only : vegn_tile_type +use soil_tile_mod, only : soil_tile_type use vegn_cohort_mod, only : vegn_cohort_type, height_from_biomass, lai_from_biomass, & update_biomass_pools @@ -20,14 +21,15 @@ module vegn_disturbance_mod ! ==== module constants ====================================================== character(len=*), parameter :: & - version = '$Id: vegn_disturbance.F90,v 19.0 2012/01/06 20:44:34 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: vegn_disturbance.F90,v 20.0 2013/12/13 23:31:08 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'vegn_disturbance_mod' contains ! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -subroutine vegn_disturbance(vegn, dt) - type(vegn_tile_type), intent(inout) :: vegn +subroutine vegn_disturbance(vegn, soil, dt) + type(vegn_tile_type), intent(inout) :: vegn ! vegetation data + type(soil_tile_type), intent(inout) :: soil ! soil data real, intent(in) :: dt ! time since last disturbance calculations, s @@ -64,25 +66,25 @@ subroutine vegn_disturbance(vegn, dt) ! "dead" biomass : wood + sapwood delta = (cc%bwood+cc%bsw)*fraction_lost; - vegn%slow_soil_C = vegn%slow_soil_C + (1.0-spdata(sp)%smoke_fraction)*delta*(1-fsc_wood); - vegn%fast_soil_C = vegn%fast_soil_C + (1.0-spdata(sp)%smoke_fraction)*delta* fsc_wood; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1.0-spdata(sp)%smoke_fraction)*delta*(1-fsc_wood); + soil%fast_soil_C(1) = soil%fast_soil_C(1) + (1.0-spdata(sp)%smoke_fraction)*delta* fsc_wood; cc%bwood = cc%bwood * (1-fraction_lost); cc%bsw = cc%bsw * (1-fraction_lost); vegn%csmoke_pool = vegn%csmoke_pool + spdata(sp)%smoke_fraction*delta; ! for budget tracking - temporarily not keeping wood and the rest separately,ens - ! vegn%ssc_in+=delta*(1.0-spdata(sp)%smoke_fraction)*(1-fsc_wood); */ - ! vegn%fsc_in+=delta*(1.0-spdata(sp)%smoke_fraction)*fsc_wood; */ + ! soil%ssc_in(1)+=delta*(1.0-spdata(sp)%smoke_fraction)*(1-fsc_wood); */ + ! soil%fsc_in(1)+=delta*(1.0-spdata(sp)%smoke_fraction)*fsc_wood; */ - vegn%ssc_in = vegn%ssc_in+(cc%bwood+cc%bsw)*fraction_lost *(1.0-spdata(sp)%smoke_fraction); - ! vegn%fsc_in+=cc%bsw*fraction_lost *(1.0-spdata(sp)%smoke_fraction); + soil%ssc_in(1) = soil%ssc_in(1)+(cc%bwood+cc%bsw)*fraction_lost *(1.0-spdata(sp)%smoke_fraction); + ! soil%fsc_in(1)+=cc%bsw*fraction_lost *(1.0-spdata(sp)%smoke_fraction); vegn%veg_out = vegn%veg_out+delta; !"alive" biomass: leaves, roots, and virtual pool delta = (cc%bl+cc%blv+cc%br)*fraction_lost; - vegn%fast_soil_C = vegn%fast_soil_C + (1.0-spdata(sp)%smoke_fraction)*delta* fsc_liv ; - vegn%slow_soil_C = vegn%slow_soil_C + (1.0-spdata(sp)%smoke_fraction)*delta*(1- fsc_liv); + soil%fast_soil_C(1) = soil%fast_soil_C(1) + (1.0-spdata(sp)%smoke_fraction)*delta* fsc_liv ; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1.0-spdata(sp)%smoke_fraction)*delta*(1- fsc_liv); cc%bl = cc%bl * (1-fraction_lost); cc%blv = cc%blv * (1-fraction_lost); @@ -91,9 +93,9 @@ subroutine vegn_disturbance(vegn, dt) vegn%csmoke_pool = vegn%csmoke_pool + spdata(sp)%smoke_fraction*delta; ! for budget tracking- temporarily keeping alive separate ens - ! /* vegn%fsc_in+=delta* fsc_liv; */ - ! /* vegn%ssc_in+=delta* (1-fsc_liv); */ - vegn%fsc_in = vegn%fsc_in+delta*(1.0-spdata(sp)%smoke_fraction); + ! /* soil%fsc_in(1)+=delta* fsc_liv; */ + ! /* soil%ssc_in(1)+=delta* (1-fsc_liv); */ + soil%fsc_in(1) = soil%fsc_in(1)+delta*(1.0-spdata(sp)%smoke_fraction); vegn%veg_out = vegn%veg_out+delta; !"living" biomass:leaves, roots and sapwood @@ -102,10 +104,10 @@ subroutine vegn_disturbance(vegn, dt) if(cc%bliving < BMIN) then ! remove vegetaion competely - vegn%fast_soil_C = vegn%fast_soil_C + fsc_liv*cc%bliving+ fsc_wood*cc%bwood; - vegn%slow_soil_C = vegn%slow_soil_C + (1.- fsc_liv)*cc%bliving+ (1-fsc_wood)*cc%bwood; + soil%fast_soil_C(1) = soil%fast_soil_C(1) + fsc_liv*cc%bliving+ fsc_wood*cc%bwood; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1.- fsc_liv)*cc%bliving+ (1-fsc_wood)*cc%bwood; - vegn%fsc_in = vegn%fsc_in + cc%bwood+cc%bliving; + soil%fsc_in(1) = soil%fsc_in(1) + cc%bwood+cc%bliving; vegn%veg_out = vegn%veg_out + cc%bwood+cc%bliving; cc%bliving = 0.; @@ -197,7 +199,7 @@ subroutine update_fuel(vegn, wilt) + wilt*spdata(cc%species)%fact_crit_fire theta_crit = max(0.0,min(1.0, theta_crit)) if((cc%height < fire_height_threashold) & - .and.(vegn%theta_av < theta_crit) & + .and.(vegn%theta_av_fire < theta_crit) & .and.(vegn%tsoil_av > 278.16)) then babove = cc%bl + agf_bs * (cc%bsw + cc%bwood + cc%blv); ! this is fuel available durng the drought months only @@ -209,7 +211,7 @@ subroutine update_fuel(vegn, wilt) ! the last cohort -- currently it doesn't matter since we have just one cohort, ! but something needs to be done about that in the future ignition_rate = 0.; - if ( (vegn%theta_av < theta_crit) & + if ( (vegn%theta_av_fire < theta_crit) & .and. (vegn%tsoil_av>278.16)) ignition_rate = 1.; vegn%lambda = vegn%lambda + ignition_rate; @@ -219,8 +221,9 @@ end subroutine update_fuel ! ============================================================================ -subroutine vegn_nat_mortality(vegn, deltat) - type(vegn_tile_type), intent(inout) :: vegn +subroutine vegn_nat_mortality(vegn, soil, deltat) + type(vegn_tile_type), intent(inout) :: vegn ! vegetation data + type(soil_tile_type), intent(inout) :: soil ! soil data real, intent(in) :: deltat ! time since last mortality calculations, s ! ---- local vars @@ -252,8 +255,8 @@ subroutine vegn_nat_mortality(vegn, deltat) ! "dead" biomass : wood + sapwood delta = bdead*fraction_lost; - vegn%slow_soil_C = vegn%slow_soil_C + (1-fsc_wood)*delta; - vegn%fast_soil_C = vegn%fast_soil_C + fsc_wood *delta; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1-fsc_wood)*delta; + soil%fast_soil_C(1) = soil%fast_soil_C(1) + fsc_wood *delta; cc%bwood = cc%bwood * (1-fraction_lost); cc%bsw = cc%bsw * (1-fraction_lost); @@ -262,23 +265,23 @@ subroutine vegn_nat_mortality(vegn, deltat) ! It doesn't look correct to me: ssc_in should probably include factor ! (1-fsc_wood) and the whole calculations should be moved up in front ! of bwood and bsw modification - ! vegn%fsc_in+= cc%bsw*fraction_lost; - vegn%ssc_in = vegn%ssc_in + (cc%bwood+cc%bsw)*fraction_lost; + ! soil%fsc_in(1)+= cc%bsw*fraction_lost; + soil%ssc_in(1) = soil%ssc_in(1) + (cc%bwood+cc%bsw)*fraction_lost; vegn%veg_out = vegn%veg_out + delta; ! kill the live biomass if mortality is set to affect it if (spdata(cc%species)%mortality_kills_balive) then delta = (cc%bl + cc%blv + cc%br)*fraction_lost - vegn%slow_soil_C = vegn%slow_soil_C + (1-fsc_liv)*delta; - vegn%fast_soil_C = vegn%fast_soil_C + fsc_liv *delta; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1-fsc_liv)*delta; + soil%fast_soil_C(1) = soil%fast_soil_C(1) + fsc_liv *delta; cc%br = cc%br * (1-fraction_lost); cc%bl = cc%bl * (1-fraction_lost); cc%blv = cc%blv * (1-fraction_lost); ! for budget tracking - vegn%ssc_in = vegn%ssc_in + (cc%bwood+cc%bsw)*fraction_lost; + soil%ssc_in(1) = soil%ssc_in(1) + (cc%bwood+cc%bsw)*fraction_lost; vegn%veg_out = vegn%veg_out + delta; endif diff --git a/src/land_lad2/vegetation/vegn_dynamics.F90 b/src/land_lad2/vegetation/vegn_dynamics.F90 index 215ced2133..1050a8eafc 100644 --- a/src/land_lad2/vegetation/vegn_dynamics.F90 +++ b/src/land_lad2/vegetation/vegn_dynamics.F90 @@ -5,7 +5,7 @@ module vegn_dynamics_mod #include "../shared/debug.inc" -use fms_mod, only: write_version_number +use fms_mod, only: write_version_number, error_mesg, FATAL use time_manager_mod, only: time_type use land_constants_mod, only : seconds_per_year, mol_C @@ -16,7 +16,7 @@ module vegn_dynamics_mod fsc_liv, fsc_wood, K1, K2, soil_carbon_depth_scale, C2B, agf_bs, & l_fract use vegn_tile_mod, only: vegn_tile_type -use soil_tile_mod, only: soil_tile_type, soil_ave_temp, soil_ave_theta +use soil_tile_mod, only: soil_tile_type, soil_ave_temp, soil_theta use vegn_cohort_mod, only : vegn_cohort_type, height_from_biomass, lai_from_biomass, & update_biomass_pools, update_bio_living_fraction, update_species @@ -37,35 +37,51 @@ module vegn_dynamics_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & - version = '$Id: vegn_dynamics.F90,v 17.0 2009/07/21 03:03:22 fms Exp $', & - tagname = '$Name: siena_201207 $' ,& + version = '$Id: vegn_dynamics.F90,v 20.0 2013/12/13 23:31:10 fms Exp $', & + tagname = '$Name: tikal $' ,& module_name = 'vegn' + real, parameter :: GROWTH_RESP=0.333 ! fraction of npp lost as growth respiration +integer, parameter :: USE_AVE_T_AND_THETA=1, USE_LAYER_T_AND_THETA=2 ! soil decomposition options ! ==== module data =========================================================== real :: dt_fast_yr ! fast (physical) time step, yr (year is defined as 365 days) +integer :: soil_decomp_to_use=0 ! diagnostic field IDs -integer :: id_npp, id_nep, id_gpp, id_fast_soil_C, id_slow_soil_C, id_rsoil, id_rsoil_fast -integer :: id_resp, id_resl, id_resr, id_resg, id_asoil -integer :: id_soilt, id_theta, id_litter +integer :: id_npp, id_nep, id_gpp, id_fsc, id_ssc, id_rsoil, & + id_rsoil_fast, id_rsoil_slow, id_resp, id_resl, id_resr, id_resg, id_asoil, & + id_soilt, id_theta, id_litter contains ! ============================================================================ -subroutine vegn_dynamics_init(id_lon, id_lat, time, delta_time) +subroutine vegn_dynamics_init(id_lon, id_lat, time, delta_time, soil_decomp_option) integer , intent(in) :: id_lon ! ID of land longitude (X) axis integer , intent(in) :: id_lat ! ID of land latitude (Y) axis type(time_type), intent(in) :: time ! initial time for diagnostic fields real , intent(in) :: delta_time ! fast time step, s + character(*) , intent(in) :: soil_decomp_option call write_version_number(version, tagname) ! set up global variables dt_fast_yr = delta_time/seconds_per_year + ! parse soil decomposition option + select case (soil_decomp_option) + case('use_ave_t_and_theta') + soil_decomp_to_use = USE_AVE_T_AND_THETA + case('use_layer_t_and_theta') + soil_decomp_to_use = USE_LAYER_T_AND_THETA + case default + call error_mesg('vegn_dynamics_init', & + '"'//trim(soil_decomp_option)//'" is an invalid option for soil_decomp_option', FATAL) + end select + + ! register diagnostic fields id_gpp = register_tiled_diag_field ( module_name, 'gpp', & (/id_lon,id_lat/), time, 'gross primary productivity', 'kg C/(m2 year)', & @@ -78,11 +94,13 @@ subroutine vegn_dynamics_init(id_lon, id_lat, time, delta_time) missing_value=-100.0 ) id_litter = register_tiled_diag_field (module_name, 'litter', (/id_lon,id_lat/), & time, 'litter productivity', 'kg C/(m2 year)', missing_value=-100.0) - id_fast_soil_C = register_tiled_diag_field ( module_name, 'fsc', & - (/id_lon,id_lat/), time, 'fast soil carbon', 'kg C/m2', & + ! TODO: remove fsc and ssc from either soil or vegn modules (or at least deprecate + ! one of them) + id_fsc = register_tiled_diag_field ( module_name, 'fsc', & + (/id_lon,id_lat/), time, 'total fast soil carbon', 'kg C/m2', & missing_value=-100.0 ) - id_slow_soil_C = register_tiled_diag_field ( module_name, 'ssc', & - (/id_lon,id_lat/), time, 'slow soil carbon', 'kg C/m2', & + id_ssc = register_tiled_diag_field ( module_name, 'ssc', & + (/id_lon,id_lat/), time, 'total slow soil carbon', 'kg C/m2', & missing_value=-100.0 ) id_resp = register_tiled_diag_field ( module_name, 'resp', (/id_lon,id_lat/), & time, 'respiration', 'kg C/(m2 year)', missing_value=-100.0 ) @@ -96,9 +114,12 @@ subroutine vegn_dynamics_init(id_lon, id_lat, time, delta_time) (/id_lon,id_lat/), time, 'soil respiration', 'kg C/(m2 year)', & missing_value=-100.0 ) id_rsoil_fast = register_tiled_diag_field ( module_name, 'rsoil_fast', & - (/id_lon,id_lat/), time, 'fast soil carbon respiration', 'kg C/(m2 year)', & + (/id_lon,id_lat/), time, 'total fast soil carbon respiration', 'kg C/(m2 year)', & missing_value=-100.0 ) - id_asoil = register_tiled_diag_field ( module_name, 'asoil', & + id_rsoil_slow = register_tiled_diag_field ( module_name, 'rsoil_slow', & + (/id_lon,id_lat/), time, 'total slow soil carbon respiration', 'kg C/(m2 year)', & + missing_value=-100.0 ) + id_asoil = register_tiled_diag_field ( module_name, 'asoil', & (/id_lon,id_lat/), time, 'aerobic activity modifier', & missing_value=-100.0 ) id_soilt = register_tiled_diag_field ( module_name, 'tsoil_av', & @@ -111,14 +132,18 @@ end subroutine vegn_dynamics_init ! ============================================================================ -subroutine vegn_carbon_int(vegn, soilt, theta, diag) +subroutine vegn_carbon_int(vegn, soil, soilt, theta, diag) type(vegn_tile_type), intent(inout) :: vegn + type(soil_tile_type), intent(inout) :: soil real, intent(in) :: soilt ! average temperature of soil for soil carbon decomposition, deg K real, intent(in) :: theta ! average soil wetness, unitless type(diag_buff_type), intent(inout) :: diag + + ! TODO: possibly move soil-related calculations from calling procedure here, + ! now that we have soil passed as an argument type(vegn_cohort_type), pointer :: cc - real :: resp, resl, resr, resg ! respiration terms accumualted for all cohorts + real :: resp, resl, resr, resg ! respiration terms accumulated for all cohorts real :: cgain, closs ! carbon gain and loss accumulated for entire tile real :: md_alive, md_wood; real :: gpp ! gross primary productivity per tile @@ -167,14 +192,14 @@ subroutine vegn_carbon_int(vegn, soilt, theta, diag) cc%carbon_loss = cc%carbon_loss + cc%md; ! used in diagnostics only ! add md from leaf and root pools to fast soil carbon - vegn%fast_soil_C = vegn%fast_soil_C + fsc_liv *md_alive + fsc_wood *md_wood; - vegn%slow_soil_C = vegn%slow_soil_C + (1-fsc_liv)*md_alive + (1-fsc_wood)*md_wood; + soil%fast_soil_C(1) = soil%fast_soil_C(1) + fsc_liv *md_alive + fsc_wood *md_wood; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1-fsc_liv)*md_alive + (1-fsc_wood)*md_wood; ! for budget tracking -!/* cp->fsc_in+= data->fsc_liv*md_alive+data->fsc_wood*md_wood; */ -!/* cp->ssc_in+= (1.- data->fsc_liv)*md_alive+(1-data->fsc_wood)*md_wood; */ - vegn%fsc_in = vegn%fsc_in + 1*md_alive+0*md_wood; - vegn%ssc_in = vegn%ssc_in + (1.- 1)*md_alive+(1-0)*md_wood; +!/* cp->fsc_in(1)+= data->fsc_liv*md_alive+data->fsc_wood*md_wood; */ +!/* cp->ssc_in(1)+= (1.- data->fsc_liv)*md_alive+(1-data->fsc_wood)*md_wood; */ + soil%fsc_in(1) = soil%fsc_in(1) + 1*md_alive+0*md_wood; + soil%ssc_in(1) = soil%ssc_in(1) + (1.- 1)*md_alive+(1-0)*md_wood; vegn%veg_in = vegn%veg_in + cc%npp*dt_fast_yr; vegn%veg_out = vegn%veg_out + md_alive+md_wood; @@ -200,12 +225,12 @@ subroutine vegn_carbon_int(vegn, soilt, theta, diag) enddo ! update soil carbon - call Dsdt(vegn, diag, soilt, theta) + call Dsdt(vegn, soil, diag, soilt, theta) ! NEP is equal to NNP minus soil respiration vegn%nep = vegn%npp - vegn%rh - call update_soil_pools(vegn) + call update_soil_pools(vegn, soil) vegn%age = vegn%age + dt_fast_yr; @@ -271,41 +296,53 @@ end subroutine vegn_growth ! ============================================================================ -subroutine Dsdt(vegn, diag, soilt, theta) +subroutine Dsdt(vegn, soil, diag, soilt, theta) type(vegn_tile_type), intent(inout) :: vegn + type(soil_tile_type), intent(inout) :: soil type(diag_buff_type), intent(inout) :: diag - real , intent(in) :: soilt ! soil temperature, deg K - real , intent(in) :: theta + real , intent(in) :: soilt ! average soil temperature, deg K + real , intent(in) :: theta ! average soil moisture - real :: fast_C_loss - real :: slow_C_loss - real :: A ! decomp rate reduction due to moisture and temperature + real :: fast_C_loss(size(soil%fast_soil_C)) + real :: slow_C_loss(size(soil%slow_soil_C)) + real :: A (size(soil%slow_soil_C)) ! decomp rate reduction due to moisture and temperature - A=A_function(soilt,theta); + select case (soil_decomp_to_use) + case(USE_AVE_T_AND_THETA) + A(:) = A_function(soilt, theta) + case(USE_LAYER_T_AND_THETA) + A(:) = A_function(soil%prog(:)%T, soil_theta(soil)) + case default + call error_mesg('Dsdt','The value of soil_decomp_to_use is invalid. This should never happen. See developer.',FATAL) + end select - fast_C_loss = vegn%fast_soil_C*A*K1*dt_fast_yr; - slow_C_loss = vegn%slow_soil_C*A*K2*dt_fast_yr; + fast_C_loss = soil%fast_soil_C(:)*A*K1*dt_fast_yr; + slow_C_loss = soil%slow_soil_C(:)*A*K2*dt_fast_yr; - vegn%fast_soil_C = vegn%fast_soil_C - fast_C_loss; - vegn%slow_soil_C = vegn%slow_soil_C - slow_C_loss; + soil%fast_soil_C = soil%fast_soil_C - fast_C_loss; + soil%slow_soil_C = soil%slow_soil_C - slow_C_loss; ! for budget check - vegn%fsc_out = vegn%fsc_out + fast_C_loss; - vegn%ssc_out = vegn%ssc_out + slow_C_loss; + vegn%fsc_out = vegn%fsc_out + sum(fast_C_loss(:)); + vegn%ssc_out = vegn%ssc_out + sum(slow_C_loss(:)); ! loss of C to atmosphere and leaching - vegn%rh = (fast_C_loss+slow_C_loss)/dt_fast_yr; - ! vegn%rh_fast = fast_C_loss/dt_fast_yr; + vegn%rh = sum(fast_C_loss(:)+slow_C_loss(:))/dt_fast_yr; ! accumulate decomposition rate reduction for the soil carbon restart output - vegn%asoil_in = vegn%asoil_in + A + soil%asoil_in(:) = soil%asoil_in(:) + A(:) + ! TODO: arithmetic averaging of A doesn't seem correct; we need to invent something better, + ! e.g. weight it with the carbon loss, or something like that ! ---- diagnostic section - call send_tile_data(id_fast_soil_C, vegn%fast_soil_C, diag) - call send_tile_data(id_slow_soil_C, vegn%slow_soil_C, diag) - call send_tile_data(id_rsoil_fast, fast_C_loss/dt_fast_yr, diag) + if (id_fsc>0) call send_tile_data(id_fsc, sum(soil%fast_soil_C(:)), diag) + if (id_ssc>0) call send_tile_data(id_ssc, sum(soil%slow_soil_C(:)), diag) + if (id_rsoil_fast>0) call send_tile_data(id_rsoil_fast, sum(fast_C_loss(:))/dt_fast_yr, diag) + if (id_rsoil_slow>0) call send_tile_data(id_rsoil_slow, sum(slow_C_loss(:))/dt_fast_yr, diag) call send_tile_data(id_rsoil, vegn%rh, diag) - call send_tile_data(id_asoil, A, diag) + ! TODO: arithmetic averaging of A doesn't seem correct; we need to invent something better, + ! e.g. weight it with the carbon loss, or something like that + if (id_asoil>0) call send_tile_data(id_asoil, sum(A(:))/size(A(:)), diag) end subroutine Dsdt @@ -314,7 +351,7 @@ end subroutine Dsdt ! The combined reduction in decomposition rate as a funciton of TEMP and MOIST ! Based on CENTURY Parton et al 1993 GBC 7(4):785-809 and Bolker's copy of ! CENTURY code -function A_function(soilt, theta) result(A) +elemental function A_function(soilt, theta) result(A) real :: A ! return value, resulting reduction in decomposition rate real, intent(in) :: soilt ! effective temperature for soil carbon decomposition real, intent(in) :: theta @@ -437,16 +474,21 @@ end subroutine vegn_daily_npp ! ============================================================================= -subroutine vegn_phenology(vegn, wilt) +subroutine vegn_phenology(vegn, soil) type(vegn_tile_type), intent(inout) :: vegn - real, intent(in) :: wilt ! ratio of wilting to saturated water content + type(soil_tile_type), intent(inout) :: soil + ! TODO: possibly move soil-related calculations from calling procedure here, + ! now that we have soil passed as an argument ! ---- local vars type(vegn_cohort_type), pointer :: cc real :: leaf_litter,root_litter; real :: theta_crit; ! critical ratio of average soil water to sat. water + real :: psi_stress_crit ! critical soil-water-stress index + real :: wilt ! ratio of wilting to saturated water content integer :: i + wilt = soil%w_wilt(1)/soil%pars%vwc_sat vegn%litter = 0 do i = 1,vegn%n_cohorts @@ -454,7 +496,8 @@ subroutine vegn_phenology(vegn, wilt) if(is_watch_point())then write(*,*)'####### vegn_phenology #######' - __DEBUG4__(vegn%theta_av, wilt, spdata(cc%species)%cnst_crit_phen, spdata(cc%species)%fact_crit_phen) + __DEBUG4__(vegn%theta_av_phen, wilt, spdata(cc%species)%cnst_crit_phen, spdata(cc%species)%fact_crit_phen) + __DEBUG2__(vegn%psist_av, spdata(cc%species)%psi_stress_crit_phen) __DEBUG1__(cc%species) __DEBUG2__(vegn%tc_av,spdata(cc%species)%tc_crit) endif @@ -470,8 +513,10 @@ subroutine vegn_phenology(vegn, wilt) theta_crit = spdata(cc%species)%cnst_crit_phen & + wilt*spdata(cc%species)%fact_crit_phen theta_crit = max(0.0,min(1.0, theta_crit)) - if ( (vegn%theta_av < theta_crit) & - .or.(vegn%tc_av < spdata(cc%species)%tc_crit) ) then + psi_stress_crit = spdata(cc%species)%psi_stress_crit_phen + if ( (psi_stress_crit <= 0. .and. vegn%theta_av_phen < theta_crit) & + .or. (psi_stress_crit > 0. .and. vegn%psist_av > psi_stress_crit) & + .or. (vegn%tc_av < spdata(cc%species)%tc_crit) ) then cc%status = LEAF_OFF; ! set status to indicate leaf drop cc%leaf_age = 0; @@ -481,12 +526,12 @@ subroutine vegn_phenology(vegn, wilt) ! add to patch litter flux terms vegn%litter = vegn%litter + leaf_litter + root_litter; - vegn%fast_soil_C = vegn%fast_soil_C + fsc_liv *(leaf_litter+root_litter); - vegn%slow_soil_C = vegn%slow_soil_C + (1-fsc_liv)*(leaf_litter+root_litter); + soil%fast_soil_C(1) = soil%fast_soil_C(1) + fsc_liv *(leaf_litter+root_litter); + soil%slow_soil_C(1) = soil%slow_soil_C(1) + (1-fsc_liv)*(leaf_litter+root_litter); - ! vegn%fsc_in+=data->fsc_liv*(leaf_litter+root_litter); - ! vegn%ssc_in+=(1.0-data->fsc_liv)*(leaf_litter+root_litter); - vegn%fsc_in = vegn%fsc_in + leaf_litter+root_litter; + ! soil%fsc_in(1)+=data->fsc_liv*(leaf_litter+root_litter); + ! soil%ssc_in(1)+=(1.0-data->fsc_liv)*(leaf_litter+root_litter); + soil%fsc_in(1) = soil%fsc_in(1) + leaf_litter+root_litter; vegn%veg_out = vegn%veg_out + leaf_litter+root_litter; cc%blv = cc%blv + l_fract*(cc%bl+cc%br); @@ -525,8 +570,9 @@ subroutine vegn_biogeography(vegn) ! ============================================================================= -subroutine update_soil_pools(vegn) +subroutine update_soil_pools(vegn, soil) type(vegn_tile_type), intent(inout) :: vegn + type(soil_tile_type), intent(inout) :: soil ! ---- local vars real :: delta; @@ -536,16 +582,16 @@ subroutine update_soil_pools(vegn) ! depleted, never increased vegn%fsc_rate = MAX( 0.0, MIN(vegn%fsc_rate, vegn%fsc_pool/dt_fast_yr)); delta = vegn%fsc_rate*dt_fast_yr; - vegn%fast_soil_C = vegn%fast_soil_C + delta; - vegn%fsc_pool = vegn%fsc_pool - delta; + soil%fast_soil_C(1) = soil%fast_soil_C(1) + delta; + vegn%fsc_pool = vegn%fsc_pool - delta; ! update ssc input rate so that intermediate ssc pool is never ! depleted below zero; on the other hand the pool can be only ! depleted, never increased vegn%ssc_rate = MAX(0.0, MIN(vegn%ssc_rate, vegn%ssc_pool/dt_fast_yr)); delta = vegn%ssc_rate*dt_fast_yr; - vegn%slow_soil_C = vegn%slow_soil_C + delta; - vegn%ssc_pool = vegn%ssc_pool - delta; + soil%slow_soil_C(1) = soil%slow_soil_C(1) + delta; + vegn%ssc_pool = vegn%ssc_pool - delta; end subroutine update_soil_pools diff --git a/src/land_lad2/vegetation/vegn_harvesting.F90 b/src/land_lad2/vegetation/vegn_harvesting.F90 index 9d4c084a5f..a5893c32df 100644 --- a/src/land_lad2/vegetation/vegn_harvesting.F90 +++ b/src/land_lad2/vegetation/vegn_harvesting.F90 @@ -37,8 +37,8 @@ module vegn_harvesting_mod ! ==== module constants ===================================================== character(len=*), parameter :: & - version = '$Id: vegn_harvesting.F90,v 19.0 2012/01/06 20:44:36 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: vegn_harvesting.F90,v 20.0 2013/12/13 23:31:12 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'vegn_harvesting_mod' real, parameter :: ONETHIRD = 1.0/3.0 @@ -50,12 +50,14 @@ module vegn_harvesting_mod real :: grazing_residue = 0.1 ! fraction of the grazed biomass transferred into soil pools real :: frac_wood_wasted_harv = 0.25 ! fraction of wood wasted while harvesting real :: frac_wood_wasted_clear = 0.25 ! fraction of wood wasted while clearing land for pastures or crops +logical :: waste_below_ground_wood = .TRUE. ! If true, all the wood below ground (1-agf_bs fraction of bwood + ! and bsw) is wasted. Old behavior assumed this to be FALSE. real :: frac_wood_fast = ONETHIRD ! fraction of wood consumed fast real :: frac_wood_med = ONETHIRD ! fraction of wood consumed with medium speed real :: frac_wood_slow = ONETHIRD ! fraction of wood consumed slowly real :: crop_seed_density = 0.1 ! biomass of seeds left after crop harvesting, kg/m2 namelist/harvesting_nml/ do_harvesting, grazing_intensity, grazing_residue, & - frac_wood_wasted_harv, frac_wood_wasted_clear, & + frac_wood_wasted_harv, frac_wood_wasted_clear, waste_below_ground_wood, & frac_wood_fast, frac_wood_med, frac_wood_slow, & crop_seed_density @@ -238,6 +240,11 @@ subroutine vegn_cut_forest(vegn, new_landuse) else frac_wood_wasted = frac_wood_wasted_clear endif + ! take into accont that all wood below ground is wasted; also the fraction + ! of waste calculated above is lost from the above-ground part of the wood + if (waste_below_ground_wood) then + frac_wood_wasted = (1-agf_bs) + agf_bs*frac_wood_wasted + endif ! update biomass pools for each cohort according to harvested fraction do i = 1, vegn%n_cohorts diff --git a/src/land_lad2/vegetation/vegn_photosynthesis.F90 b/src/land_lad2/vegetation/vegn_photosynthesis.F90 index e76e481340..b6ad56e82d 100644 --- a/src/land_lad2/vegetation/vegn_photosynthesis.F90 +++ b/src/land_lad2/vegetation/vegn_photosynthesis.F90 @@ -22,8 +22,8 @@ module vegn_photosynthesis_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & - version = '$Id: vegn_photosynthesis.F90,v 17.0 2009/07/21 03:03:26 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: vegn_photosynthesis.F90,v 20.0 2013/12/13 23:31:14 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'vegn_photosynthesis' ! values for internal vegetation photosynthesis option selector integer, parameter :: VEGN_PHOT_SIMPLE = 1 ! zero photosynthesis @@ -62,8 +62,8 @@ end subroutine vegn_photosynthesis_init ! compute stomatal conductance, photosynthesis and respiration subroutine vegn_photosynthesis ( vegn, & PAR_dn, PAR_net, cana_q, cana_co2, p_surf, drag_q, & - soil_beta, soil_water_supply,& - stomatal_cond, psyn, resp ) + soil_beta, soil_water_supply, & + evap_demand, stomatal_cond, psyn, resp ) type(vegn_tile_type), intent(in) :: vegn real, intent(in) :: PAR_dn ! downward PAR at the top of the canopy, W/m2 real, intent(in) :: PAR_net ! net PAR absorbed by the canopy, W/m2 @@ -74,6 +74,7 @@ subroutine vegn_photosynthesis ( vegn, & real, intent(in) :: soil_beta real, intent(in) :: soil_water_supply ! max supply of water to roots per unit ! active root biomass per second, kg/(m2 s) + real, intent(out) :: evap_demand ! evaporative water demand, kg/(m2 s) real, intent(out) :: stomatal_cond ! stomatal conductance, m/s(?) real, intent(out) :: psyn ! net photosynthesis, mol C/(m2 s) real, intent(out) :: resp ! leaf respiration, mol C/(m2 s) @@ -85,7 +86,8 @@ subroutine vegn_photosynthesis ( vegn, & ! ---- local vars type(vegn_cohort_type), pointer :: cohort integer :: sp ! shorthand for vegetation species - real :: water_supply ! water supply per m2 of leaves + real :: water_supply ! water supply, mol H2O per m2 of leaves per second + real :: Ed ! evaporative demand, mol H2O per m2 of leaves per second real :: fw, fs ! wet and snow-covered fraction of leaves ! get the pointer to the first (and, currently, the only) cohort @@ -100,6 +102,7 @@ subroutine vegn_photosynthesis ( vegn, & cohort%An_cl = 0 psyn = 0 resp = 0 + evap_demand = 0 case(VEGN_PHOT_LEUNING) if(cohort%lai > 0) then @@ -110,8 +113,8 @@ subroutine vegn_photosynthesis ( vegn, & call get_vegn_wet_frac (cohort, fw=fw, fs=fs) call gs_Leuning(PAR_dn, PAR_net, cohort%prog%Tv, cana_q, cohort%lai, & - cohort%leaf_age, p_surf, water_supply, sp, cana_co2, & - cohort%extinct, fs+fw, stomatal_cond, psyn, resp, cohort%pt) + cohort%leaf_age, p_surf, water_supply, sp, cohort%pt, cana_co2, & + cohort%extinct, fs+fw, stomatal_cond, psyn, resp, Ed) ! store the calculated photosythesis and fotorespiration for future use ! in carbon_int cohort%An_op = psyn * seconds_per_year @@ -121,6 +124,9 @@ subroutine vegn_photosynthesis ( vegn, & stomatal_cond = stomatal_cond*cohort%lai psyn = psyn *cohort%lai resp = resp *cohort%lai + ! convert evaporative demand from mol H2O/(m2_of_leaf s) to + ! kg/(m2_of_land s) + evap_demand = Ed*mol_h2o *cohort%lai else ! no leaves means no photosynthesis and no stomatal conductance either cohort%An_op = 0 @@ -128,6 +134,7 @@ subroutine vegn_photosynthesis ( vegn, & stomatal_cond = 0 psyn = 0 resp = 0 + evap_demand = 0 endif case default @@ -140,9 +147,9 @@ end subroutine vegn_photosynthesis ! ============================================================================ subroutine gs_Leuning(rad_top, rad_net, tl, ea, lai, leaf_age, & - p_surf, ws, pft, ca, & + p_surf, ws, pft, pt, ca, & kappa, leaf_wet, & - gs, apot, acl, pt) + gs, apot, acl, Ed) real, intent(in) :: rad_top ! PAR dn on top of the canopy, w/m2 real, intent(in) :: rad_net ! PAR net on top of the canopy, w/m2 real, intent(in) :: tl ! leaf temperature, degK @@ -150,8 +157,9 @@ subroutine gs_Leuning(rad_top, rad_net, tl, ea, lai, leaf_age, & real, intent(in) :: lai ! leaf area index real, intent(in) :: leaf_age ! age of leaf since budburst (deciduos), days real, intent(in) :: p_surf ! surface pressure, Pa - real, intent(in) :: ws ! water supply, mol H20/(m2 of leaf s) + real, intent(in) :: ws ! water supply, mol H2O/(m2 of leaf s) integer, intent(in) :: pft ! species + integer, intent(in) :: pt ! physiology type (C3 or C4) real, intent(in) :: ca ! concentartion of CO2 in the canopy air space, mol CO2/mol dry air real, intent(in) :: kappa! canopy extinction coefficient (move inside f(pft)) real, intent(in) :: leaf_wet ! fraction of leaf that's wet or snow-covered @@ -160,7 +168,7 @@ subroutine gs_Leuning(rad_top, rad_net, tl, ea, lai, leaf_age, & real, intent(out) :: gs ! stomatal conductance, m/s real, intent(out) :: apot ! net photosynthesis, mol C/(m2 s) real, intent(out) :: acl ! leaf respiration, mol C/(m2 s) - integer, intent(in) :: pt ! physiology type (C3 or C4) + real, intent(out) :: Ed ! evaporative demand, mol H2O/(m2 s) ! ---- local vars ! photosynthesis @@ -198,7 +206,7 @@ subroutine gs_Leuning(rad_top, rad_net, tl, ea, lai, leaf_age, & real :: w_scale; real, parameter :: p_sea = 1.0e5 ! sea level pressure, Pa ! soil water stress - real :: Ed,an_w,gs_w; + real :: an_w,gs_w; if (is_watch_point()) then write(*,*) '####### gs_leuning input #######' diff --git a/src/land_lad2/vegetation/vegn_radiation.F90 b/src/land_lad2/vegetation/vegn_radiation.F90 index fd24dc6c17..121cf283b2 100644 --- a/src/land_lad2/vegetation/vegn_radiation.F90 +++ b/src/land_lad2/vegetation/vegn_radiation.F90 @@ -22,7 +22,7 @@ module vegn_radiation_mod ! ==== module constants ====================================================== character(len=*), private, parameter :: & version = '$Id: vegn_radiation.F90,v 17.0 2009/07/21 03:03:28 fms Exp $', & - tagname = '$Name: siena_201207 $' ,& + tagname = '$Name: tikal $' ,& module_name = 'vegn_radiation' ! values for internal vegetation radiation option selector integer, parameter :: VEGN_RAD_BIGLEAF = 1 ! "big-leaf" radiation diff --git a/src/land_lad2/vegetation/vegn_static_override.F90 b/src/land_lad2/vegetation/vegn_static_override.F90 index 16d3ed68bf..e34883703c 100644 --- a/src/land_lad2/vegetation/vegn_static_override.F90 +++ b/src/land_lad2/vegetation/vegn_static_override.F90 @@ -14,7 +14,7 @@ module static_vegn_mod use fms_mod, only : write_version_number, error_mesg, FATAL, NOTE, & mpp_pe, file_exist, close_file, check_nml_error, stdlog, & - mpp_root_pe, get_mosaic_tile_file + mpp_root_pe, get_mosaic_tile_file, fms_error_handler use time_interp_mod, only : time_interp use diag_manager_mod, only : get_base_date @@ -47,8 +47,8 @@ module static_vegn_mod ! ==== module constants ===================================================== character(len=*), parameter :: & module_name = 'static_vegn_mod', & - version = '$Id: vegn_static_override.F90,v 19.0 2012/01/06 20:44:38 fms Exp $', & - tagname = '$Name: siena_201207 $' + version = '$Id: vegn_static_override.F90,v 20.0 2013/12/13 23:31:17 fms Exp $', & + tagname = '$Name: tikal $' ! ==== module data ========================================================== logical :: module_is_initialized = .FALSE. @@ -72,7 +72,7 @@ module static_vegn_mod logical :: fill_land_mask = .FALSE. ! if true, all the vegetation points on the ! map are filled with the information from static vegetation data, using ! nearest point remap; otherwise only the points that overlap with valid - ! static vegetation data are overriden. + ! static vegetation data are overridden. logical :: write_static_veg = .FALSE. ! if true, the state of vegetation is saved ! periodically for future use as static vegetation input character(16) :: static_veg_freq = 'daily' ! or 'monthly', or 'annual' @@ -146,7 +146,7 @@ subroutine static_vegn_init() real, allocatable :: in_lon(:)! longitude coordinates in input file real, allocatable :: in_lat(:)! latitude coordinates in input file logical, allocatable :: mask(:,:)! mask of valid points in input data - integer, allocatable :: data(:,:,:,:) ! temprary array used to calculate the mask of + integer, allocatable :: data(:,:,:,:) ! temporary array used to calculate the mask of ! valid input data logical :: has_records ! true if input variable has records integer :: tile_dim_length ! length of tile dimension in output files @@ -186,10 +186,14 @@ subroutine static_vegn_init() call error_mesg('static_vegn_init','Reading global static vegetation file "'& //trim(input_file)//'"', NOTE) input_is_multiface = .FALSE. + actual_input_file = input_file endif ! READ TIME AXIS DATA - __NF_ASRT__(nf_inq_unlimdim( ncid, unlimdim )) + if(nf_inq_unlimdim( ncid, unlimdim )/=NF_NOERR) then + call error_mesg('static_vegn_init',& + 'Input file "'//trim(actual_input_file)//'" lacks record dimension.', FATAL) + endif __NF_ASRT__(nf_inq_dimname ( ncid, unlimdim, dimname )) __NF_ASRT__(nf_inq_varid ( ncid, dimname, timeid )) __NF_ASRT__(nf_inq_dimlen( ncid, unlimdim, timelen )) @@ -198,7 +202,10 @@ subroutine static_vegn_init() ! GET UNITS OF THE TIME units = ' ' - __NF_ASRT__(nf_get_att_text(ncid, timeid,'units',units)) + if (nf_get_att_text(ncid, timeid,'units',units)/=NF_NOERR) then + call error_mesg('static_vegn_init',& + 'Cannot read time units from file "'//trim(actual_input_file)//'"', FATAL) + endif ! GET CALENDAR OF THE DATA calendar = ' ' @@ -218,6 +225,11 @@ subroutine static_vegn_init() ! READ HORIZONTAL COORDINATES iret = nfu_inq_compressed_var(ncid,'species',ndims=ndims,dimids=dimids,dimlens=dimlens,& has_records=has_records) + if (iret/=NF_NOERR) then + call error_mesg('static_vegn_init',& + 'Cannot read compression information from file "'//trim(actual_input_file)//& + '": check that all dimensions listed in "compress" attributes are present in the file.', FATAL) + endif __NF_ASRT__(iret) allocate(in_lon(dimlens(1)),in_lat(dimlens(2))) __NF_ASRT__(nfu_get_dim(ncid,dimids(1),in_lon)) ! get longitude @@ -229,13 +241,17 @@ subroutine static_vegn_init() allocate(map_j(lnd%is:lnd%ie,lnd%js:lnd%je)) allocate(mask(size(in_lon),size(in_lat))) + map_i = -1 + map_j = -1 + mask = .false. + if(fill_land_mask) then ! CALCULATE THE DIMENSIONS OF THE BUFFER FOR THE INPUT DATA if (has_records) ndims=ndims-1 do i = ndims+1,4 dimlens(i) = 1 enddo - ! READ THE FIRST RECORD AND CALCULTE THE MASK OF THE VALID INPUT DATA + ! READ THE FIRST RECORD AND CALCULATE THE MASK OF THE VALID INPUT DATA allocate(data(dimlens(1),dimlens(2),dimlens(3),dimlens(4))) ! lon lat tile cohort data(:,:,:,:) = -1 @@ -278,7 +294,7 @@ subroutine static_vegn_init() if(write_static_veg) then ! create output file for static vegetation - ! count all land tiles and determine the lenght of tile dimension + ! count all land tiles and determine the length of tile dimension ! sufficient for the current domain tile_dim_length = 0 do j = lnd%js, lnd%je @@ -328,30 +344,31 @@ subroutine static_vegn_end() end subroutine static_vegn_end ! =========================================================================== -subroutine read_static_vegn (time) +subroutine read_static_vegn (time, err_msg) type(time_type), intent(in) :: time + character(len=*), intent(out), optional :: err_msg ! ---- local vars integer :: index1, index2 ! result of time interpolation (only index1 is used) real :: weight ! another result of time interp, not used - character(len=256) :: err_msg + character(len=256) :: msg if(.not.use_static_veg)return; + msg = '' ! time_interp to find out the index of the current time interval if (timeline == 'loop') then - err_msg = '' call time_interp(time, ts, te, time_line, weight, index1, index2, & - correct_leap_year_inconsistency=.true.) - if(err_msg /= '') then - call error_mesg('subroutine read_static_vegn',trim(err_msg), FATAL) - endif + correct_leap_year_inconsistency=.true., err_msg=msg) else if (timeline == 'normal') then - call time_interp(time, time_line, weight, index1, index2) + call time_interp(time, time_line, weight, index1, index2, err_msg=msg) else call error_mesg(module_name,'timeline option "'//trim(timeline)// & '" is incorrect, use "normal" or "loop"', FATAL) endif + if(msg /= '') then + if(fms_error_handler('read_static_vegn','Message from time_interp: '//trim(msg),err_msg)) return + endif ! read the data into cohort variables call read_remap_cohort_data_i0d_fptr(ncid, 'species' , cohort_species_ptr , map_i, map_j, index1) diff --git a/src/land_lad2/vegetation/vegn_tile.F90 b/src/land_lad2/vegetation/vegn_tile.F90 index 5e0b056a93..ad4167fb00 100644 --- a/src/land_lad2/vegetation/vegn_tile.F90 +++ b/src/land_lad2/vegetation/vegn_tile.F90 @@ -62,8 +62,8 @@ module vegn_tile_mod ! ==== module constants ====================================================== character(len=*), parameter :: & - version = '$Id: vegn_tile.F90,v 19.0 2012/01/06 20:44:40 fms Exp $', & - tagname = '$Name: siena_201207 $', & + version = '$Id: vegn_tile.F90,v 20.0 2013/12/13 23:31:19 fms Exp $', & + tagname = '$Name: tikal $', & module_name = 'vegn_tile_mod' ! ==== types ================================================================= @@ -74,38 +74,36 @@ module vegn_tile_mod integer :: n_cohorts = 0 type(vegn_cohort_type), pointer :: cohorts(:)=>NULL() - real :: age=0 ! tile age - - real :: fast_soil_C=0 ! fast soil carbon pool, (kg C/m2) - real :: slow_soil_C=0 ! slow soil carbon pool, (kg C/m2) + real :: age=0.0 ! tile age ! fields for smoothing out the contribution of the spike-type processes (e.g. ! harvesting) to the soil carbon pools over some period of time - real :: fsc_pool=0, fsc_rate=0 ! for fast soil carbon - real :: ssc_pool=0, ssc_rate=0 ! for slow soil carbon + real :: fsc_pool=0.0, fsc_rate=0.0 ! for fast soil carbon + real :: ssc_pool=0.0, ssc_rate=0.0 ! for slow soil carbon - real :: csmoke_pool=0 ! carbon lost through fires, kg C/m2 - real :: csmoke_rate=0 ! rate of release of the above to atmosphere, kg C/(m2 yr) + real :: csmoke_pool=0.0 ! carbon lost through fires, kg C/m2 + real :: csmoke_rate=0.0 ! rate of release of the above to atmosphere, kg C/(m2 yr) - real :: harv_pool(N_HARV_POOLS) = 0. ! pools of harvested carbon, kg C/m2 - real :: harv_rate(N_HARV_POOLS) = 0. ! rates of spending (release to the atmosphere), kg C/(m2 yr) + real :: harv_pool(N_HARV_POOLS) = 0.0 ! pools of harvested carbon, kg C/m2 + real :: harv_rate(N_HARV_POOLS) = 0.0 ! rates of spending (release to the atmosphere), kg C/(m2 yr) ! values for the diagnostic of carbon budget and soil carbon acceleration - real :: asoil_in=0 - real :: ssc_in=0, ssc_out=0 - real :: fsc_in=0, fsc_out=0 - real :: veg_in=0, veg_out=0 + real :: ssc_out=0.0 + real :: fsc_out=0.0 + real :: veg_in=0.0, veg_out=0.0 real :: disturbance_rate(0:1) = 0 ! 1/year - real :: lambda = 0. ! cumulative drought months per year - real :: fuel = 0. ! fuel over dry months - real :: litter = 0. ! litter flux + real :: lambda = 0.0 ! cumulative drought months per year + real :: fuel = 0.0 ! fuel over dry months + real :: litter = 0.0 ! litter flux ! monthly accumulated/averaged values - real :: theta_av = 0. ! relative soil_moisture availability not soil moisture - real :: tsoil_av = 0. ! bulk soil temperature - real :: tc_av = 0. ! leaf temperature - real :: precip_av= 0. ! precipitation + real :: theta_av_phen = 0.0 ! relative soil_moisture availability not soil moisture + real :: theta_av_fire = 0.0 + real :: psist_av = 0.0 ! soil water stress index + real :: tsoil_av = 0.0 ! bulk soil temperature + real :: tc_av = 0.0 ! leaf temperature + real :: precip_av= 0.0 ! precipitation ! accumulation counters for long-term averages (monthly and annual). Having ! these counters in the tile is a bit stupid, since the values are the same for @@ -114,21 +112,21 @@ module vegn_tile_mod integer :: n_accum = 0 ! number of accumulated values for monthly averages integer :: nmn_acm = 0 ! number of accumulated values for annual averages ! annual-mean values - real :: t_ann = 0. ! annual mean T, degK - real :: t_cold = 0. ! average temperature of the coldest month, degK - real :: p_ann = 0. ! annual mean precip - real :: ncm = 0. ! number of cold months + real :: t_ann = 0.0 ! annual mean T, degK + real :: t_cold = 0.0 ! average temperature of the coldest month, degK + real :: p_ann = 0.0 ! annual mean precip + real :: ncm = 0.0 ! number of cold months ! annual accumulated values - real :: t_ann_acm = 0. ! accumulated annual temperature for t_ann - real :: t_cold_acm = 0. ! temperature of the coldest month in current year - real :: p_ann_acm = 0. ! accumulated annual precipitation for p_ann - real :: ncm_acm = 0. ! accumulated number of cold months + real :: t_ann_acm = 0.0 ! accumulated annual temperature for t_ann + real :: t_cold_acm = 0.0 ! temperature of the coldest month in current year + real :: p_ann_acm = 0.0 ! accumulated annual precipitation for p_ann + real :: ncm_acm = 0.0 ! accumulated number of cold months ! it's probably possible to get rid of the fields below - real :: npp=0 ! net primary productivity - real :: nep=0 ! net ecosystem productivity - real :: rh=0 ! soil carbon lost to the atmosphere + real :: npp=0.0 ! net primary productivity + real :: nep=0.0 ! net ecosystem productivity + real :: rh=0.0 ! soil carbon lost to the atmosphere real :: total_biomass ! real :: area_disturbed_by_treefall real :: area_disturbed_by_fire @@ -183,7 +181,7 @@ function vegn_tiles_can_be_merged(vegn1,vegn2) result(response) integer :: i, i1, i2 if (vegn1%landuse /= vegn2%landuse) then - response = .false. ! different land use tiles can't be merged + response = .false. ! different land use types can't be merged else if (vegn1%landuse == LU_SCND) then ! secondary vegetation tiles ! get tile wood biomasses b1 = get_vegn_tile_bwood(vegn1) @@ -259,9 +257,6 @@ subroutine merge_vegn_tiles(t1,w1,t2,w2) __MERGE__(age); - __MERGE__(fast_soil_C) - __MERGE__(slow_soil_C) - __MERGE__(fsc_pool); __MERGE__(fsc_rate) __MERGE__(ssc_pool); __MERGE__(ssc_rate) @@ -272,9 +267,8 @@ subroutine merge_vegn_tiles(t1,w1,t2,w2) __MERGE__(harv_rate) ! do we need to merge these? - __MERGE__(asoil_in) - __MERGE__(ssc_in); __MERGE__(ssc_out) - __MERGE__(fsc_in); __MERGE__(fsc_out) + __MERGE__(ssc_out) + __MERGE__(fsc_out) __MERGE__(veg_in); __MERGE__(veg_out) ! or these? @@ -284,7 +278,9 @@ subroutine merge_vegn_tiles(t1,w1,t2,w2) __MERGE__(litter) ! litter flux ! monthly accumulated/averaged values - __MERGE__(theta_av) ! relative soil_moisture availability not soil moisture + __MERGE__(theta_av_phen) ! relative soil_moisture availability not soil moisture + __MERGE__(theta_av_fire) + __MERGE__(psist_av) ! water potential divided by permanent wilting potential __MERGE__(tsoil_av) ! bulk soil temperature __MERGE__(tc_av) ! leaf temperature __MERGE__(precip_av) ! precipitation diff --git a/src/land_null/land_model.F90 b/src/land_null/land_model.F90 index f785553916..41971877ad 100644 --- a/src/land_null/land_model.F90 +++ b/src/land_null/land_model.F90 @@ -36,7 +36,7 @@ module land_model_mod ! This is the null version ! Module mom_oasis3_interface_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module mom_oasis3_interface_mod
- - --Contact: Dave Bi (for OASIS3 hooks) -, - Russ Fiedler (for OASIS3 hooks) - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Interface to OASIS3/PRISM2-5 coupling. -
- - - -- Interface to the OASIS3 - This module serves as a hook between PRISM2-5/OASIS3 and mom4p1 - Only serial coupling has been tested at this stage (Oct 2009) although there are - hints for the user for implementing different strategies. - - Standard mom surface quantities In Ocean_Ice_Boundary and Ocean_sfc may be passed - - The namelist ocean_oasis3_interface_nml contains the quantities to be passed to and from the ocean --
- - -
-OTHER MODULES USED
- --- - - -mod_prism_proto-
mod_prism_def_partition_proto
mod_prism_put_proto
mod_prism_get_proto
mod_comprism_proto
fms_mod
mpp_domains_mod
mpp_mod
ocean_types_mod
time_manager_mod
constants_mod
-PUBLIC INTERFACE
----
- - -
-PUBLIC ROUTINES
- -- - - - -
-NAMELIST
- --&mom_oasis3_interface_nml --
-
----
-- -num_fields_in -
-- The number of fields to be passed to mom from external sources -
-
-[integer, default: 0] -- -num_fields_out -
-- The number of fields to be passed from mom to external progams -
-
-[integer, default: 0] -- -fields_in -
-- The fields to be passed to mom from external progams. Currently - valid names correspond to variables in the Ice_ocean_boundary structure. - These names must agree with names in the OASIS namcouple file - WARNING! Note truncation of names of ssw flux components and salt_flx. -
-
-[character(maxlen=8), default: ''] -- -fields_out -
-- The fields to be passed from mom to external progams. Currently - valid names correspond to variables in the Ocean_sfc structure. - These names must agree with the 'interpolated' names in the OASIS namcouple file -
-
-[character(maxlen=8), default: ''] -- -send_before_ocean_update -
-- TRUE if coupling strategy requires we send data to coupler BEFORE updating the ocean -
-
-[logical, default: .FALSE.] -- -send_after_ocean_update -
-- TRUE if coupling strategy requires we send data to coupler AFTER updating the ocean -
-
-[logical, default: .FALSE.] -
- - - - -
--top -- - diff --git a/src/mom5/drivers/ocean_solo.F90 b/src/mom5/drivers/ocean_solo.F90 index fbc00d8011..ad705beaef 100644 --- a/src/mom5/drivers/ocean_solo.F90 +++ b/src/mom5/drivers/ocean_solo.F90 @@ -1,3 +1,4 @@ +#ifndef USE_ESMF_LIB program main ! !Matt Harrison @@ -682,12 +683,9 @@ end subroutine external_coupler_mpi_exit #endif end program main - - - - - - +#else +#include "ocean_solo_nuopc.inc" +#endif diff --git a/src/mom5/drivers/ocean_solo.html b/src/mom5/drivers/ocean_solo.html deleted file mode 100644 index e64bae68d4..0000000000 --- a/src/mom5/drivers/ocean_solo.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - Program main - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Program main
- - --Contact: Matt Harrison -, - Dave Bi (for OASIS3 hooks) - -- - -
-Reviewers: Niki Zadeh (for OASIS3 hooks) -, - V. Balaji -, - Stephen Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Driver for ocean-only simulations and prototype setup for OASIS3 driver. -
- - - -- Driver for the ocean-only simulations. Similar to the FMS coupler, but - allows one to run the ocean model without compiling other models. - Much simpler than the full FMS coupler. - - This driver also provides the prototype hooks for using MOM with OASIS3, - with this code surrounded by the cpp-preprocessor option "ifdef OASIS3". - The couping of MOM to OASIS3 has not been tested at GFDL. Rather, - CSIRO in Australia uses MOM with OASIS3, with Dave.Bi@csiro.au the primary - contact for questions regarding MOM and OASIS3. --
- - -
-MODULES USED
- --- - - -constants_mod-
data_override_mod
diag_manager_mod
field_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_io_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_model_mod
ocean_types_mod
mom_oasis3_interface_mod
mom_oasis_interface_mod
-PUBLIC INTERFACE
----
- - -
-PUBLIC ROUTINES
- -- - - - -
-NAMELIST
- --&ocean_solo_nml --
-
----
-- -date_init -
-- The date that the current integration starts with. If the restart file - ocean_solo.res is present, date_init will be taken from there. -
-
-[integer, dimension(6), default: 0] -- -calendar -
-- The calendar type used by the current integration. Valid values are consistent - with the time_manager module: 'julian', 'gregorian', 'noleap', or 'thirty_day'. - The value 'no_calendar' can not be used because the time_manager's date - function are used. - -
-
-[character(maxlen=17), default: ''] -- -months -
-- The number of months that the current integration will be run for. -
-
-[integer, default: 0] -- -days -
-- The number of days that the current integration will be run for. -
-
-[integer, default: 0] -- -hours -
-- The number of hours that the current integration will be run for. -
-
-[integer, default: 0] -- -minutes -
-- The number of minutes that the current integration will be run for. -
-
-[integer, default: 0] -- -seconds -
-- The number of seconds that the current integration will be run for. -
-
-[integer, default: 0] -- -dt_cpld -
-- Time step in seconds for coupling between ocean and atmospheric models: - must be an integral multiple of dt_ocean. This is the "slow" timestep. - Note that for an ocean_solo model, the coupling to an "atmosphere" is the coupling - to some data files. In this case, dt_cpld represents the time which data is updated. - For example, if data is "daily", then dt_cpld=86400 should be chosen. - If data is fixed, then dt_cpld of any integer of dt_ocean is fine, with - dt_cpld=86400 the default. -
-
-[integer, default: 0] -- -n_mask -
-- number of region to be masked out. Its value should be less than MAX_PES. -
-
-[integer] -- -mask_list(2,MAXPES) -
-- The position of the region to be masked out. mask_list(1,:) is the x-layout position - and mask_list(2,:) is y-layout position. -
-
-[integer, dimension(MAX_MASK_REGION,2)] -- -layout_mask -
-- Processor domain layout for all the component model. layout_mask need to be set when and only - when n_mask is greater than 0 ( some domain region is masked out ). When this namelist is set, - it will overload the layout in each component model. The default value is (0,0). - Currently we require all the component model has the same layout and same grid size. -
-
-[integer, dimension(2)] -- -restart_interval -
-- The time interval that write out intermediate restart file. The format is (yr,mo,day,hr,min,sec). - When restart_interval is all zero, no intermediate restart file will be written out. -
-
-[integer, dimension(6), default: 0] -
- - - - -
--top -- - diff --git a/src/mom5/drivers/ocean_solo_nuopc.inc b/src/mom5/drivers/ocean_solo_nuopc.inc new file mode 100644 index 0000000000..26d016252f --- /dev/null +++ b/src/mom5/drivers/ocean_solo_nuopc.inc @@ -0,0 +1,1779 @@ +!--------------------------------------------------------------- +!------------------ Utilities ---------------------------------- +! +!This is a set of utilities that convert time management data structures +!between ESMF and FMS. +! +!Author: Fei Liu +!Wed Feb 20 09:15:23 MST 2013 +!--------------------------------------------------------------- + +module time_utils_mod + + use fms_mod, only: uppercase + use mpp_mod, only: mpp_error, FATAL + use time_manager_mod, only: time_type, set_time, set_date, get_date + use time_manager_mod, only: GREGORIAN, JULIAN, NOLEAP, THIRTY_DAY_MONTHS, NO_CALENDAR + use time_manager_mod, only: fms_get_calendar_type => get_calendar_type + use ESMF + + implicit none + private + + !-------------------- interface blocks --------------------- + interface fms2esmf_cal + module procedure fms2esmf_cal_c + module procedure fms2esmf_cal_i + end interface fms2esmf_cal + interface esmf2fms_time + module procedure esmf2fms_time_t + module procedure esmf2fms_timestep + end interface esmf2fms_time + + public fms2esmf_cal + public esmf2fms_time + public fms2esmf_time + public string_to_date + + contains + + !-------------------- module code --------------------- + + function fms2esmf_cal_c(calendar) +! ! Return Value: + type(ESMF_CALKIND_FLAG) :: fms2esmf_cal_c +! ! Arguments: + character(len=*), intent(in) :: calendar + + select case( uppercase(trim(calendar)) ) + case( 'GREGORIAN' ) + fms2esmf_cal_c = ESMF_CALKIND_GREGORIAN + case( 'JULIAN' ) + fms2esmf_cal_c = ESMF_CALKIND_JULIAN + case( 'NOLEAP' ) + fms2esmf_cal_c = ESMF_CALKIND_NOLEAP + case( 'THIRTY_DAY' ) + fms2esmf_cal_c = ESMF_CALKIND_360DAY + case( 'NO_CALENDAR' ) + fms2esmf_cal_c = ESMF_CALKIND_NOCALENDAR + case default + call mpp_error(FATAL, & + 'ocean_solo: ocean_solo_nml entry calendar must be one of GREGORIAN|JULIAN|NOLEAP|THIRTY_DAY|NO_CALENDAR.' ) + end select + end function fms2esmf_cal_c + + function fms2esmf_cal_i(calendar) +! ! Return Value: + type(ESMF_CALKIND_FLAG) :: fms2esmf_cal_i +! ! Arguments: + integer, intent(in) :: calendar + + select case(calendar) + case(THIRTY_DAY_MONTHS) + fms2esmf_cal_i = ESMF_CALKIND_360DAY + case(GREGORIAN) + fms2esmf_cal_i = ESMF_CALKIND_GREGORIAN + case(JULIAN) + fms2esmf_cal_i = ESMF_CALKIND_JULIAN + case(NOLEAP) + fms2esmf_cal_i = ESMF_CALKIND_NOLEAP + case(NO_CALENDAR) + fms2esmf_cal_i = ESMF_CALKIND_NOCALENDAR + end select + end function fms2esmf_cal_i + + function esmf2fms_time_t(time) + ! Return Value + type(Time_type) :: esmf2fms_time_t + ! Input Arguments + type(ESMF_Time), intent(in) :: time + ! Local Variables + integer :: yy, mm, dd, h, m, s + type(ESMF_CALKIND_FLAG) :: calkind + + integer :: rc + + call ESMF_TimeGet(time, yy=yy, mm=mm, dd=dd, h=h, m=m, s=s, & + calkindflag=calkind, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + esmf2fms_time_t = Set_date(yy, mm, dd, h, m, s) + + end function esmf2fms_time_t + + function esmf2fms_timestep(timestep) + ! Return Value + type(Time_type) :: esmf2fms_timestep + ! Input Arguments + type(ESMF_TimeInterval), intent(in):: timestep + ! Local Variables + integer :: s + type(ESMF_CALKIND_FLAG) :: calkind + + integer :: rc + + call ESMF_TimeIntervalGet(timestep, s=s, calkindflag=calkind, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + esmf2fms_timestep = set_time(s, 0) + + end function esmf2fms_timestep + + function fms2esmf_time(time, calkind) + ! Return Value + type(ESMF_Time) :: fms2esmf_time + ! Input Arguments + type(Time_type), intent(in) :: time + type(ESMF_CALKIND_FLAG), intent(in), optional :: calkind + ! Local Variables + integer :: yy, mm, d, h, m, s + type(ESMF_CALKIND_FLAG) :: l_calkind + + integer :: rc + + if(present(calkind)) then + l_calkind = calkind + else + l_calkind = fms2esmf_cal(fms_get_calendar_type()) + endif + + call get_date(time, yy, mm, d, h, m, s) + + call ESMF_TimeSet(fms2esmf_time, yy=yy, mm=mm, d=d, h=h, m=m, s=s, & + calkindflag=l_calkind, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end function fms2esmf_time + + function string_to_date(string, rc) + character(len=15), intent(in) :: string + integer, intent(out), optional :: rc + type(time_type) :: string_to_date + + integer :: yr,mon,day,hr,min,sec + + if(present(rc)) rc = ESMF_SUCCESS + + read(string, '(I4.4,I2.2,I2.2,".",I2.2,I2.2,I2.2)') yr, mon, day, hr, min, sec + string_to_date = set_date(yr, mon, day, hr, min, sec) + + end function string_to_date + +end module time_utils_mod + +!--------------- MOM5 Ocean solo model ----------------- +! This is the MOM5 ocean solo model component that's NUOPC compiant. +! The public ocean_solo_SS method sets up all the model services such as +! initialize, run and finalize. +! +! Author: Fei.Liu@gmail.com +! + +module ocean_solo_mod + use constants_mod, only: constants_init + use data_override_mod, only: data_override_init, data_override + use diag_manager_mod, only: diag_manager_init, diag_manager_end + use field_manager_mod, only: field_manager_init + use fms_mod, only: fms_init, fms_end, open_namelist_file, check_nml_error + use fms_mod, only: close_file, file_exist, uppercase + use fms_io_mod, only: fms_io_exit + use mpp_domains_mod, only: domain2d, mpp_get_compute_domain + use mpp_io_mod, only: mpp_open, MPP_RDONLY, MPP_ASCII, MPP_OVERWR, MPP_APPEND, mpp_close, MPP_SINGLE + use mpp_mod, only: input_nml_file, mpp_error, FATAL, NOTE, mpp_pe, mpp_npes, mpp_set_current_pelist + use mpp_mod, only: stdlog, stdout, mpp_root_pe, mpp_clock_id + use mpp_mod, only: mpp_clock_begin, mpp_clock_end, MPP_CLOCK_SYNC + use mpp_mod, only: MPP_CLOCK_DETAILED, CLOCK_COMPONENT, MAXPES + use time_interp_external_mod, only: time_interp_external_init + use time_manager_mod, only: set_calendar_type, time_type, increment_date + use time_manager_mod, only: set_time, set_date, get_time, get_date, month_name + use time_manager_mod, only: GREGORIAN, JULIAN, NOLEAP, THIRTY_DAY_MONTHS, NO_CALENDAR + use time_manager_mod, only: operator( <= ), operator( < ), operator( >= ) + use time_manager_mod, only: operator( + ), operator( - ), operator( / ) + use time_manager_mod, only: operator( * ), operator( /= ), operator( > ) + use time_manager_mod, only: date_to_string + use time_manager_mod, only: fms_get_calendar_type => get_calendar_type + use ocean_model_mod, only: ocean_model_init , update_ocean_model, ocean_model_end + use ocean_model_mod, only: ocean_model_restart, ocean_public_type, ocean_state_type + use ocean_types_mod, only: ice_ocean_boundary_type + + use ESMF + use NUOPC + use NUOPC_Model, only: & + model_routine_SS => routine_SetServices, & + model_label_SetClock => label_SetClock, & + model_label_Advance => label_Advance + + use time_utils_mod + + implicit none + private + public ocean_solo_SS + + type ocean_internalstate_type + type(ocean_public_type), pointer :: ocean_public_type_ptr + type(ocean_state_type), pointer :: ocean_state_type_ptr + type(ice_ocean_boundary_type), pointer :: ice_ocean_boundary_type_ptr + end type + + type ocean_internalstate_wrapper + type(ocean_internalstate_type), pointer :: ptr + end type + + contains + !----------------------------------------------------------------------- + !------------------- Solo Ocean code starts here ----------------------- + !----------------------------------------------------------------------- + + subroutine ocean_solo_SS(gcomp, rc) + + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! the NUOPC model component will register the generic methods + call model_routine_SS(gcomp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! set entry point for methods that require specific implementation + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, & + userRoutine=InitializeP1, phase=1, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, & + userRoutine=InitializeP2, phase=2, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_FINALIZE, & + userRoutine=ocean_solo_finalize, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! attach specializing method(s) + ! No need to change clock settings + !call ESMF_MethodAdd(gcomp, label=model_label_SetClock, & + ! userRoutine=SetClock, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + + call ESMF_MethodAdd(gcomp, label=model_label_Advance, & + userRoutine=ModelAdvance, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + + subroutine InitializeP1(gcomp, importState, exportState, clock, rc) + + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + type(ESMF_VM) :: vm + + type (ocean_public_type), pointer :: Ocean_sfc + type (ocean_state_type), pointer :: Ocean_state => NULL() + type(ice_ocean_boundary_type), pointer :: Ice_ocean_boundary + + ! define some time types + type(time_type) :: Time_init ! initial time for experiment + type(time_type) :: Time_start ! start time for experiment + type(time_type) :: Time_end ! end time for experiment (as determined by dtts) + type(time_type) :: Run_len ! length of experiment + type(time_type) :: Time + type(time_type) :: Time_step_coupled + type(time_type) :: Time_restart_init + type(time_type) :: Time_restart + type(time_type) :: Time_restart_current + + + integer :: num_cpld_calls = 0 + integer :: nc + integer :: calendar_type=-1 + + + integer :: isc,iec,jsc,jec + integer :: unit, io_status, ierr + + integer :: flags=0, override_clock + integer :: nfields + + character(len=256) :: version = '' + character(len=256) :: tag = '' + + character(len=9) :: month + character(ESMF_MAXSTR):: timestamp + + integer :: n, m + + integer :: date_init(6)=0, date(6) + integer :: date_restart(6) + character(len=17) :: calendar = 'julian' + integer :: dt_cpld = 86400 + integer :: years=0, months=0, days=0, hours=0, minutes=0, seconds=0 + integer :: layout_mask(2) = (/0 , 0/) + integer :: n_mask = 0 + integer :: mask_list(2,MAXPES) + integer, parameter :: mp = 2*MAXPES + data ((mask_list(n,m),n=1, 2),m=1,MAXPES) /mp*0/ + integer :: restart_interval(6) = (/0,0,0,0,0,0/) + + namelist /ocean_solo_nml/ date_init, calendar, months, days, hours, minutes, seconds, dt_cpld, & + n_mask, layout_mask, mask_list, restart_interval + + integer :: mpi_comm_mom + integer :: stdoutunit,stdlogunit + logical :: external_initialization + + type(ocean_internalstate_wrapper) :: ocean_internalstate + + rc = ESMF_SUCCESS + + allocate(Ice_ocean_boundary) + !allocate(Ocean_state) ! ocean_model_init allocate this pointer + allocate(Ocean_sfc) + allocate(ocean_internalstate%ptr) + ocean_internalstate%ptr%ice_ocean_boundary_type_ptr => Ice_ocean_boundary + ocean_internalstate%ptr%ocean_public_type_ptr => Ocean_sfc + + ! To start we have a dummy ocean that will not import or export anything. + ! + !! importable field: air_pressure_at_sea_level + !call NUOPC_StateAdvertiseField(importState, & + ! StandardName="air_pressure_at_sea_level", rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + ! + !! importable field: isotropic_shortwave_radiance_in_air + !call NUOPC_StateAdvertiseField(importState, & + ! StandardName="isotropic_shortwave_radiance_in_air", rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + + ! exportable field: sea_surface_temperature + !call NUOPC_StateAdvertiseField(exportState, & + ! StandardName="sea_surface_temperature", rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + + !call external_coupler_mpi_init(mpi_comm_mom, external_initialization) + + call constants_init + + flags = MPP_CLOCK_SYNC + + stdoutunit=stdout();stdlogunit=stdlog() + + ! provide for namelist over-ride +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=ocean_solo_nml, iostat=io_status) + ierr = check_nml_error(io_status,'ocean_solo_nml') +#else + unit = open_namelist_file('input.nml') + read (unit, ocean_solo_nml,iostat=io_status) + ierr = check_nml_error(io_status,'ocean_solo_nml') + call close_file (unit) +#endif + write (stdoutunit,'(/)') + write (stdoutunit,'(/47x,a/)') '======== MODEL BEING DRIVEN BY OCEAN_SOLO_MOD ========' + write (stdoutunit, ocean_solo_nml) + write (stdlogunit, ocean_solo_nml) + + write (stdlogunit,'(/,80("="),/(a))') trim(version), trim(tag) + + ! set the calendar + + select case( uppercase(trim(calendar)) ) + case( 'GREGORIAN' ) + calendar_type = GREGORIAN + case( 'JULIAN' ) + calendar_type = JULIAN + case( 'NOLEAP' ) + calendar_type = NOLEAP + case( 'THIRTY_DAY' ) + calendar_type = THIRTY_DAY_MONTHS + case( 'NO_CALENDAR' ) + calendar_type = NO_CALENDAR + case default + call mpp_error(FATAL, & + 'ocean_solo: ocean_solo_nml entry calendar must be one of GREGORIAN|JULIAN|NOLEAP|THIRTY_DAY|NO_CALENDAR.' ) + end select + + ! get ocean_solo restart : this can override settings from namelist + if (file_exist('INPUT/ocean_solo.res')) then + call mpp_open(unit,'INPUT/ocean_solo.res',form=MPP_ASCII,action=MPP_RDONLY) + read(unit,*) calendar_type + read(unit,*) date_init + read(unit,*) date + call mpp_close(unit) + endif + + if (file_exist('INPUT/ocean_solo.intermediate.res')) then + call mpp_open(unit,'INPUT/ocean_solo.intermediate.res',form=MPP_ASCII,action=MPP_RDONLY) + read(unit,*) date_restart + call mpp_close(unit) + else + date_restart = date_init + endif + + call set_calendar_type (calendar_type) + + !!$ initialize pelists for ocean ensembles set current pelist to ensemble member + !!$ need to call prior to diagnostics_init + !!$ code presently not supported (mjh) + !!$ call ocean_ensemble_init() + + call field_manager_init(nfields) + + call diag_manager_init() + + call time_interp_external_init() + + if (sum(date_init) <= 0) then + call mpp_error(FATAL,& + '==>Error from ocean_solo_mod: date_init must be set either in ocean_solo.res or in ocean_solo_nml') + else + Time_init = set_date(date_init(1),date_init(2), date_init(3), & + date_init(4),date_init(5),date_init(6)) + endif + + if (file_exist('INPUT/ocean_solo.res')) then + Time_start = set_date(date(1),date(2),date(3),date(4),date(5),date(6)) + else + Time_start = Time_init + date = date_init + endif + + Time_end = increment_date(Time_start, years, months, days, hours, minutes, seconds) + Run_len = Time_end - Time_start + + + Time_step_coupled = set_time(dt_cpld, 0) + num_cpld_calls = Run_len / Time_step_coupled + Time = Time_start + + Time_restart_init = set_date(date_restart(1), date_restart(2), date_restart(3), & + date_restart(4), date_restart(5), date_restart(6) ) + Time_restart_current = Time_start + if(ALL(restart_interval ==0)) then + Time_restart = increment_date(Time_end, 1, 0, 0, 0, 0, 0) ! no intermediate restart + else + Time_restart = increment_date(Time_restart_init, restart_interval(1), restart_interval(2), & + restart_interval(3), restart_interval(4), restart_interval(5), restart_interval(6) ) + if(Time_restart <= Time_start) call mpp_error(FATAL, & + '==>Error from program ocean_solo: The first intermediate restart time is no larger than the start time') + end if + + !----------------------------------------------------------------------- + !------------------- some error checks --------------------------------- + if ( num_cpld_calls * Time_step_coupled /= Run_len ) call mpp_error(FATAL, & + '==>Error from program ocean_solo: run length must be multiple of cpld time step', FATAL) + + call mpp_open (unit, 'time_stamp.out', form=MPP_ASCII, action=MPP_APPEND,threading=MPP_SINGLE) + + month = month_name(date(2)) + if ( mpp_pe() == mpp_root_pe() ) write (unit,'(6i4,2x,a3)') date, month(1:3) + + call get_date (Time_end, date(1), date(2), date(3), date(4), date(5), date(6)) + month = month_name(date(2)) + if ( mpp_pe() == mpp_root_pe() ) write (unit,'(6i4,2x,a3)') date, month(1:3) + + call mpp_close (unit) + + !----- check the value of layout and setup the maskmap for domain layout. + if( n_mask > 0 ) then + if( layout_mask(1)*layout_mask(2) - n_mask .NE. mpp_npes() ) call mpp_error(FATAL, & + '==>Error from program ocean_solo: layout(1)*layout(2) - n_mask should equal to npes when n_mask>0') + call mpp_error(NOTE, & + '==>Error from program ocean_solo: layout_mask and mask_list is set in ocean_solo_nml, ' // & + 'the value of layout_mask will override the layout specified in ocean_model_mod') + + allocate(Ocean_sfc%maskmap(layout_mask(1), layout_mask(2)) ) + Ocean_sfc%maskmap = .TRUE. + do n=1, n_mask + if (mask_list(1,n) .gt. layout_mask(1) ) & + call mpp_error( FATAL, & + 'program ocean_solo: mask_list elements outside layout defines.' ) + if (mask_list(2,n) .gt. layout_mask(2) ) & + call mpp_error( FATAL, & + 'program ocean_solo: mask_list elements outside layout defines.' ) + Ocean_sfc%maskmap(mask_list(1,n),mask_list(2,n)) = .false. + enddo + else + if( layout_mask(1)*layout_mask(2) .NE. 0 ) call mpp_error(NOTE, & + 'program ocean_solo: when no region is masked out, layout_mask need not be set' ) + end if + + + + call ocean_model_init(Ocean_sfc, Ocean_state, Time_init, Time) + + call data_override_init(Ocean_domain_in = Ocean_sfc%domain) + + !override_clock = mpp_clock_id('Override', flags=flags,grain=CLOCK_COMPONENT) + + call mpp_get_compute_domain(Ocean_sfc%domain, isc, iec, jsc, jec) + + + allocate ( Ice_ocean_boundary% u_flux (isc:iec,jsc:jec), & + Ice_ocean_boundary% v_flux (isc:iec,jsc:jec), & + Ice_ocean_boundary% t_flux (isc:iec,jsc:jec), & + Ice_ocean_boundary% q_flux (isc:iec,jsc:jec), & + Ice_ocean_boundary% salt_flux (isc:iec,jsc:jec), & + Ice_ocean_boundary% lw_flux (isc:iec,jsc:jec), & + Ice_ocean_boundary% sw_flux_vis_dir (isc:iec,jsc:jec), & + Ice_ocean_boundary% sw_flux_vis_dif (isc:iec,jsc:jec), & + Ice_ocean_boundary% sw_flux_nir_dir (isc:iec,jsc:jec), & + Ice_ocean_boundary% sw_flux_nir_dif (isc:iec,jsc:jec), & + Ice_ocean_boundary% lprec (isc:iec,jsc:jec), & + Ice_ocean_boundary% fprec (isc:iec,jsc:jec), & + Ice_ocean_boundary% runoff (isc:iec,jsc:jec), & + Ice_ocean_boundary% calving (isc:iec,jsc:jec), & + Ice_ocean_boundary% p (isc:iec,jsc:jec)) + + Ice_ocean_boundary%u_flux = 0.0 + Ice_ocean_boundary%v_flux = 0.0 + Ice_ocean_boundary%t_flux = 0.0 + Ice_ocean_boundary%q_flux = 0.0 + Ice_ocean_boundary%salt_flux = 0.0 + Ice_ocean_boundary%lw_flux = 0.0 + Ice_ocean_boundary%sw_flux_vis_dir = 0.0 + Ice_ocean_boundary%sw_flux_vis_dif = 0.0 + Ice_ocean_boundary%sw_flux_nir_dir = 0.0 + Ice_ocean_boundary%sw_flux_nir_dif = 0.0 + Ice_ocean_boundary%lprec = 0.0 + Ice_ocean_boundary%fprec = 0.0 + Ice_ocean_boundary%runoff = 0.0 + Ice_ocean_boundary%calving = 0.0 + Ice_ocean_boundary%p = 0.0 + + call external_coupler_sbc_init(Ocean_sfc%domain, dt_cpld, Run_len) + + ocean_internalstate%ptr%ocean_state_type_ptr => Ocean_state + call ESMF_GridCompSetInternalState(gcomp, ocean_internalstate, rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! Set some MOM_solo specific attributes to be used during finalize + call ESMF_AttributeSet(gcomp, name="dt_cpld", value=dt_cpld, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_AttributeSet(gcomp, name="num_cpld_calls", value=num_cpld_calls, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_AttributeSet(gcomp, name="calendar_type", value=calendar_type, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + timestamp = date_to_string(time_restart) + call ESMF_AttributeSet(gcomp, name="Time_restart", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + timestamp = date_to_string(time_restart_current) + call ESMF_AttributeSet(gcomp, name="Time_restart_current", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + timestamp = date_to_string(time_end) + call ESMF_AttributeSet(gcomp, name="Time_end", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + timestamp = date_to_string(time_init) + call ESMF_AttributeSet(gcomp, name="Time_init", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + timestamp = date_to_string(time_start) + call ESMF_AttributeSet(gcomp, name="Time_start", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + + !----------------------------------------------------------------------------- + + subroutine InitializeP2(gcomp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + type(ESMF_TimeInterval) :: stabilityTimeStep + type(ESMF_Field) :: field + type(ESMF_Grid) :: gridIn + type(ESMF_Grid) :: gridOut + + rc = ESMF_SUCCESS + + ! To start we have a dummy ocean that will not import or export anything. + ! + !! create a Grid object for Fields + !gridIn = NUOPC_GridCreateSimpleXY(10._ESMF_KIND_R8, 20._ESMF_KIND_R8, & + ! 100._ESMF_KIND_R8, 200._ESMF_KIND_R8, 10, 100, rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + !gridOut = gridIn ! for now out same as in + !! importable field: air_pressure_at_sea_level + !field = ESMF_FieldCreate(name="pmsl", grid=gridIn, & + ! typekind=ESMF_TYPEKIND_R8, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + !call NUOPC_StateRealizeField(importState, field=field, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + ! + !! importable field: isotropic_shortwave_radiance_in_air + !field = ESMF_FieldCreate(name="risw", grid=gridIn, & + ! typekind=ESMF_TYPEKIND_R8, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + !call NUOPC_StateRealizeField(importState, field=field, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + + !! exportable field: sea_surface_temperature + !field = ESMF_FieldCreate(name="sst", grid=gridOut, & + ! typekind=ESMF_TYPEKIND_R8, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + !call NUOPC_StateRealizeField(exportState, field=field, rc=rc) + !if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + + end subroutine + + !----------------------------------------------------------------------------- + + ! Ocean solo model uses same clock as parent gridComp + !subroutine SetClock(gcomp, rc) + ! type(ESMF_GridComp) :: gcomp + ! integer, intent(out) :: rc + ! + ! ! local variables + ! type(ESMF_Clock) :: clock + ! type(ESMF_TimeInterval) :: stabilityTimeStep + + ! rc = ESMF_SUCCESS + ! + ! ! query the Component for its clock, importState and exportState + ! call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + ! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + ! + ! ! initialize internal clock + ! ! here: parent Clock and stability timeStep determine actual model timeStep + ! !TODO: stabilityTimeStep should be read in from configuation + ! !TODO: or computed from internal Grid information + ! call ESMF_TimeIntervalSet(stabilityTimeStep, m=60, rc=rc) + ! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + ! call NUOPC_GridCompSetClock(gcomp, clock, stabilityTimeStep, rc=rc) + ! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + ! line=__LINE__, & + ! file=__FILE__)) & + ! return ! bail out + + ! + !end subroutine + + !----------------------------------------------------------------------------- + + subroutine ModelAdvance(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_State) :: importState, exportState + type(ESMF_Time) :: currTime + type(ESMF_TimeInterval) :: timeStep + + type (ocean_public_type), pointer :: Ocean_sfc + type (ocean_state_type), pointer :: Ocean_state + type(ice_ocean_boundary_type), pointer :: Ice_ocean_boundary + + ! define some time types + type(time_type) :: Time + type(time_type) :: Time_step_coupled + type(time_type) :: Time_restart + type(time_type) :: Time_restart_current + + character(len=17) :: calendar = 'julian' + + integer :: dt_cpld = 86400 + integer :: nc + integer :: calendar_type=-1 + + integer :: date_init(6)=0, date(6) + integer :: date_restart(6) + integer :: years=0, months=0, days=0, hours=0, minutes=0, seconds=0 + + integer :: isc,iec,jsc,jec + + integer :: flags=0, override_clock + integer :: nfields + + character(len=9) :: month + character(len=64):: timestamp + integer :: restart_interval(6) = (/1,0,0,0,0,0/) + type(ocean_internalstate_wrapper) :: ocean_internalstate + + + rc = ESMF_SUCCESS + + ! query the Component for its clock, importState and exportState + call ESMF_GridCompGet(gcomp, clock=clock, importState=importState, & + exportState=exportState, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_GridCompGetInternalState(gcomp, ocean_internalstate, rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + Ice_ocean_boundary => ocean_internalstate%ptr%ice_ocean_boundary_type_ptr + Ocean_sfc => ocean_internalstate%ptr%ocean_public_type_ptr + Ocean_state => ocean_internalstate%ptr%ocean_state_type_ptr + + ! HERE THE MODEL ADVANCES: currTime -> currTime + timeStep + + ! Because of the way that the internal Clock was set in SetClock(), + ! its timeStep is likely smaller than the parent timeStep. As a consequence + ! the time interval covered by a single parent timeStep will result in + ! multiple calls to the ModelAdvance() routine. Every time the currTime + ! will come in by one internal timeStep advanced. This goes until the + ! stopTime of the internal Clock has been reached. + + call NUOPC_ClockPrintCurrTime(clock, & + "------>Advancing OCN from: ", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_ClockGet(clock, currTime=currTime, timeStep=timeStep, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call NUOPC_TimePrint(currTime + timeStep, & + "--------------------------------> to: ", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + Time = esmf2fms_time(currTime) + Time_step_coupled = esmf2fms_time(timeStep) + + ! Retrieve some MOM_solo specific attribute + call ESMF_AttributeGet(gcomp, name="dt_cpld", value=dt_cpld, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_AttributeGet(gcomp, name="Time_restart", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time_restart = string_to_date(timestamp) + call ESMF_AttributeGet(gcomp, name="Time_restart_current", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time_restart_current = string_to_date(timestamp) + + override_clock = mpp_clock_id('Override', flags=flags,grain=CLOCK_COMPONENT) + call mpp_clock_begin(override_clock) + + call ice_ocn_bnd_from_data(Ice_ocean_boundary, Time, Time_step_coupled) + + call mpp_clock_end(override_clock) + + call external_coupler_sbc_before(Ice_ocean_boundary, Ocean_sfc, nc, dt_cpld ) + + call update_ocean_model(Ice_ocean_boundary, Ocean_state, Ocean_sfc, Time, Time_step_coupled) + + Time = Time + Time_step_coupled + + if( Time >= Time_restart ) then + Time_restart_current = Time + Time_restart = increment_date(Time, restart_interval(1), restart_interval(2), & + restart_interval(3), restart_interval(4), restart_interval(5), restart_interval(6) ) + timestamp = date_to_string(time_restart_current) + write(*,*) '=> NOTE from program ocean_solo: intermediate restart file is written and ', & + trim(timestamp),' is appended as prefix to each restart file name' + call ocean_model_restart(Ocean_state, timestamp) + call ocean_solo_restart(gcomp, Time, Time_restart_current, timestamp) + end if + + call external_coupler_sbc_after(Ice_ocean_boundary, Ocean_sfc, nc, dt_cpld ) + + ! Set Time_restart_current + timestamp = date_to_string(time_restart_current) + call ESMF_AttributeSet(gcomp, name="Time_restart_current", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + + subroutine ocean_solo_finalize(gcomp, importState, exportState, clock, rc) + + ! input arguments + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + type (ocean_public_type), pointer :: Ocean_sfc + type (ocean_state_type), pointer :: Ocean_state + type(ocean_internalstate_wrapper) :: ocean_internalstate + type(time_type) :: Time, Time_restart_current, Time_end + type(ESMF_Time) :: currTime + type(ESMF_VM) :: vm + integer :: mpi_comm_mom, dt_cpld, num_cpld_calls + character(len=64) :: timestamp + + rc = ESMF_SUCCESS + + call ESMF_GridCompGetInternalState(gcomp, ocean_internalstate, rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + Ocean_sfc => ocean_internalstate%ptr%ocean_public_type_ptr + Ocean_state => ocean_internalstate%ptr%ocean_state_type_ptr + + call ESMF_ClockGet(clock, currTime=currTime, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time = esmf2fms_time(currTime) + + call ESMF_VMGetCurrent(vm=vm, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_VMGet(vm, mpiCommunicator=mpi_comm_mom, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! Retrieve some MOM_solo specific attributes + call ESMF_AttributeGet(gcomp, name="dt_cpld", value=dt_cpld, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_AttributeGet(gcomp, name="num_cpld_calls", value=num_cpld_calls, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_AttributeGet(gcomp, name="Time_end", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time_end = string_to_date(timestamp) + call ESMF_AttributeGet(gcomp, name="Time_restart_current", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time_restart_current= string_to_date(timestamp) + + ! close some of the main components + + call ocean_model_end(Ocean_sfc, Ocean_state, Time) + + call diag_manager_end(Time) + + !! need to reset pelist before calling mpp_clock_end + call mpp_set_current_pelist() + + !! write restart file + call ocean_solo_restart(gcomp, Time_end, Time_restart_current) + + call external_coupler_restart( dt_cpld, num_cpld_calls ) + + call fms_io_exit + + call external_coupler_exit + + call fms_end + + call external_coupler_mpi_exit(mpi_comm_mom, .true.) + + write(*,*) 'MOM: --- completed ---' + + end subroutine + + + !--- writing restart file that contains running time and restart file writing time. + subroutine ocean_solo_restart(gcomp, Time_run, Time_res, time_stamp) + type(ESMF_GridComp), intent(in) :: gcomp + type(time_type), intent(in) :: Time_run, Time_res + character(len=*), intent(in), optional :: time_stamp + + integer :: unit, calendar_type, rc + character(len=64) :: timestamp + type(Time_type) :: Time_init, Time_start + character(len=128) :: file_run, file_res + integer :: yr, mon, day, hr, min, sec + + call ESMF_AttributeGet(gcomp, name="calendar_type", value=calendar_type, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call ESMF_AttributeGet(gcomp, name="Time_init", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time_init = string_to_date(timestamp) + call ESMF_AttributeGet(gcomp, name="Time_start", value=timestamp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + Time_start = string_to_date(timestamp) + + ! write restart file + if(present(time_stamp)) then + file_run = 'RESTART/'//trim(time_stamp)//'.ocean_solo.res' + file_res = 'RESTART/'//trim(time_stamp)//'.ocean_solo.intermediate.res' + else + file_run = 'RESTART/ocean_solo.res' + file_res = 'RESTART/ocean_solo.intermediate.res' + endif + + call mpp_open( unit, file_run, nohdrs=.TRUE. ) + if ( mpp_pe().EQ.mpp_root_pe() )then + write( unit, '(i6,8x,a)' )calendar_type, & + '(Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4)' + + call get_date(Time_init,yr,mon,day,hr,min,sec) + write( unit, '(6i6,8x,a)' )yr,mon,day,hr,min,sec, & + 'Model start time: year, month, day, hour, minute, second' + call get_date(Time_run ,yr,mon,day,hr,min,sec) + write( unit, '(6i6,8x,a)' )yr,mon,day,hr,min,sec, & + 'Current model time: year, month, day, hour, minute, second' + end if + call mpp_close(unit) + + if(Time_res > Time_start) then + call mpp_open( unit, file_res, nohdrs=.TRUE. ) + if ( mpp_pe().EQ.mpp_root_pe() )then + call get_date(Time_res ,yr,mon,day,hr,min,sec) + write( unit, '(6i6,8x,a)' )yr,mon,day,hr,min,sec, & + 'Current intermediate restart time: year, month, day, hour, minute, second' + end if + call mpp_close(unit) + end if + + end subroutine ocean_solo_restart + +!==================================================================== +! get forcing data from data_overide + subroutine ice_ocn_bnd_from_data(x, Time, Time_step_coupled) + + type (ice_ocean_boundary_type) :: x + type(Time_type), intent(in) :: Time, Time_step_coupled + + type(Time_type) :: Time_next + + Time_next = Time + Time_step_coupled + + call data_override('OCN', 't_flux', x%t_flux , Time_next) + call data_override('OCN', 'u_flux', x%u_flux , Time_next) + call data_override('OCN', 'v_flux', x%v_flux , Time_next) + call data_override('OCN', 'q_flux', x%q_flux , Time_next) + call data_override('OCN', 'salt_flux', x%salt_flux , Time_next) + call data_override('OCN', 'lw_flux', x%lw_flux , Time_next) + call data_override('OCN', 'sw_flux_vis_dir', x%sw_flux_vis_dir, Time_next) + call data_override('OCN', 'sw_flux_vis_dif', x%sw_flux_vis_dif, Time_next) + call data_override('OCN', 'sw_flux_nir_dir', x%sw_flux_nir_dir, Time_next) + call data_override('OCN', 'sw_flux_nir_dif', x%sw_flux_nir_dif, Time_next) + call data_override('OCN', 'lprec', x%lprec , Time_next) + call data_override('OCN', 'fprec', x%fprec , Time_next) + call data_override('OCN', 'runoff', x%runoff , Time_next) + call data_override('OCN', 'calving', x%calving , Time_next) + call data_override('OCN', 'p', x%p , Time_next) + + end subroutine ice_ocn_bnd_from_data + + +!----------------------------------------------------------------------------------------- +! +! Subroutines for enabling coupling to external programs through a third party coupler +! such as OASIS/PRISM. +! If no external coupler then these will mostly be dummy routines. +! These routines can also serve as spots to call other user defined routines +!----------------------------------------------------------------------------------------- + +!----------------------------------------------------------------------------------------- +#ifdef OASIS3 + +! Here we provide some hooks for calling an interface between the OASIS3 coupler and MOM. +! The mom_oasis3_interface module is NOT general and it is expected that the user will +! heavily modify it depending on the coupling strategy. +! For clarity all variables should be passed as arguments rather than as globals. +! This may require changes to the argument lists. + + subroutine external_coupler_mpi_init(mom_local_communicator, external_initialization) +! OASIS3/PRISM acts as the master and initializes MPI. Get a local communicator. +! need to initialize prism and get local communicator MPI_COMM_MOM first! + use mom_oasis3_interface_mod, only : mom_prism_init + implicit none + integer, intent(out) :: mom_local_communicator + logical, intent(out) :: external_initialization + mom_local_communicator = -100 ! Is there mpp_undefined parameter corresponding to MPI_UNDEFINED? + ! probably wouldn't need logical flag. + call mom_prism_init(mom_local_communicator) + external_initialization = .true. + end subroutine external_coupler_mpi_init +!----------------------------------------------------------------------------------------- + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_sbc_init(Dom, dt_cpld, Run_len) +! Call to routine initializing arrays etc for transferring via coupler +! Perform sanity checks and make sure all inputs are compatible + use mom_oasis3_interface_mod, only : coupler_init + implicit none + type(domain2d) :: Dom + integer :: dt_cpld + type(time_type) :: Run_len + call coupler_init(Dom, dt_cpld, Run_len=Run_len) + end subroutine external_coupler_sbc_init +!----------------------------------------------------------------------------------------- + + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_sbc_before(Ice_ocean_boundary, Ocean_sfc, nsteps, dt_cpld ) +! Perform transfers before ocean time stepping +! May need special tratment on first call. + + use mom_oasis3_interface_mod, only : from_coupler, into_coupler + + implicit none + type (ice_ocean_boundary_type), intent(INOUT) :: Ice_ocean_boundary + type (ocean_public_type) , intent(INOUT) :: Ocean_sfc + integer , intent(IN) :: nsteps, dt_cpld + + integer :: rtimestep ! Receive timestep + integer :: stimestep ! Send timestep + + rtimestep = (nsteps-1) * dt_cpld ! runtime in this run segment! + stimestep = rtimestep + call from_coupler( rtimestep, Ice_ocean_boundary ) + call into_coupler( stimestep, Ocean_sfc, before_ocean_update = .true.) + end subroutine external_coupler_sbc_before +!----------------------------------------------------------------------------------------- + + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_sbc_after(Ice_ocean_boundary, Ocean_sfc, nsteps, dt_cpld ) +! Perform transfers after ocean time stepping + + use mom_oasis3_interface_mod, only : into_coupler + + implicit none + type (ice_ocean_boundary_type) :: Ice_ocean_boundary + type (ocean_public_type) :: Ocean_sfc + integer :: nsteps, dt_cpld + + integer :: stimestep ! Send timestep + + stimestep = nsteps * dt_cpld ! runtime in this run segment! + call into_coupler(stimestep, Ocean_sfc, before_ocean_update = .false.) + end subroutine external_coupler_sbc_after +!----------------------------------------------------------------------------------------- +!----------------------------------------------------------------------------------------- + subroutine external_coupler_restart( dt_cpld, num_cpld_calls ) +! Clean up as appropriate and write a restart + use mom_oasis3_interface_mod, only : write_coupler_restart + implicit none + integer, intent(in) :: dt_cpld, num_cpld_calls + integer :: timestep + timestep = num_cpld_calls * dt_cpld + call write_coupler_restart(timestep, write_restart=.true.) + end subroutine external_coupler_restart + + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_exit +! Clean up as appropriate +! Final call to external program + use mom_oasis3_interface_mod, only : mom_prism_terminate + call mom_prism_terminate + end subroutine external_coupler_exit +!----------------------------------------------------------------------------------------- + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_mpi_exit(mom_local_communicator, external_initialization) +! mpp_exit wont call MPI_FINALIZE if mom_local_communicator /= MPI_COMM_WORLD + implicit none + integer, intent(in) :: mom_local_communicator + logical, intent(in) :: external_initialization + integer :: ierr + call MPI_FINALIZE(ierr) + return + end subroutine external_coupler_mpi_exit +!----------------------------------------------------------------------------------------- + +#else + +!----------------------------------------------------------------------------------------- + +! Dummy subroutines. + + subroutine external_coupler_mpi_init(mom_local_communicator, external_initialization) + implicit none + integer, intent(out) :: mom_local_communicator + logical, intent(out) :: external_initialization + external_initialization = .false. + mom_local_communicator = -100 ! Is there mpp_undefined parameter corresponding to MPI_UNDEFINED? + ! probably wouldn't need logical flag. + return + end subroutine external_coupler_mpi_init + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_sbc_init(Dom, dt_cpld, Run_len) + implicit none + type(domain2d) :: Dom + integer :: dt_cpld + type(time_type) :: Run_len + return + end subroutine external_coupler_sbc_init + + subroutine external_coupler_sbc_before(Ice_ocean_boundary, Ocean_sfc, nsteps, dt_cpld ) + implicit none + type (ice_ocean_boundary_type), intent(INOUT) :: Ice_ocean_boundary + type (ocean_public_type) , intent(INOUT) :: Ocean_sfc + integer , intent(IN) :: nsteps, dt_cpld + return + end subroutine external_coupler_sbc_before + + + subroutine external_coupler_sbc_after(Ice_ocean_boundary, Ocean_sfc, nsteps, dt_cpld ) + type (ice_ocean_boundary_type) :: Ice_ocean_boundary + type (ocean_public_type) :: Ocean_sfc + integer :: nsteps, dt_cpld + return + end subroutine external_coupler_sbc_after + + subroutine external_coupler_restart( dt_cpld, num_cpld_calls ) + implicit none + integer, intent(in) :: dt_cpld, num_cpld_calls + return + end subroutine external_coupler_restart + + subroutine external_coupler_exit + return + end subroutine external_coupler_exit + +!----------------------------------------------------------------------------------------- + subroutine external_coupler_mpi_exit(mom_local_communicator, external_initialization) + implicit none + integer, intent(in) :: mom_local_communicator + logical, intent(in) :: external_initialization + return + end subroutine external_coupler_mpi_exit +!----------------------------------------------------------------------------------------- + +#endif + +end module ocean_solo_mod + + +!----------------Earth System Model driver ------------------- +! Standard 1 component earth system model driver NUOPC compliant +! +module esm_mod + use constants_mod, only: constants_init + use data_override_mod, only: data_override_init, data_override + use diag_manager_mod, only: diag_manager_init, diag_manager_end + use field_manager_mod, only: field_manager_init + use fms_mod, only: fms_init, fms_end, open_namelist_file, check_nml_error + use fms_mod, only: close_file, file_exist, uppercase + use fms_io_mod, only: fms_io_exit + use mpp_domains_mod, only: domain2d, mpp_get_compute_domain + use mpp_io_mod, only: mpp_open, MPP_RDONLY, MPP_ASCII, MPP_OVERWR, MPP_APPEND, mpp_close, MPP_SINGLE + use mpp_mod, only: input_nml_file, mpp_error, FATAL, NOTE, mpp_pe, mpp_npes, mpp_set_current_pelist + use mpp_mod, only: stdlog, stdout, mpp_root_pe, mpp_clock_id + use mpp_mod, only: mpp_clock_begin, mpp_clock_end, MPP_CLOCK_SYNC + use mpp_mod, only: MPP_CLOCK_DETAILED, CLOCK_COMPONENT, MAXPES + use time_interp_external_mod, only: time_interp_external_init + use time_manager_mod, only: set_calendar_type, time_type, increment_date + use time_manager_mod, only: set_time, set_date, get_time, get_date, month_name + use time_manager_mod, only: GREGORIAN, JULIAN, NOLEAP, THIRTY_DAY_MONTHS, NO_CALENDAR + use time_manager_mod, only: operator( <= ), operator( < ), operator( >= ) + use time_manager_mod, only: operator( + ), operator( - ), operator( / ) + use time_manager_mod, only: operator( * ), operator( /= ), operator( > ) + use time_manager_mod, only: date_to_string + use time_manager_mod, only: fms_get_calendar_type => get_calendar_type + use ocean_model_mod, only: ocean_model_init , update_ocean_model, ocean_model_end + use ocean_model_mod, only: ocean_model_restart, ocean_public_type, ocean_state_type + use ocean_types_mod, only: ice_ocean_boundary_type + + + use ESMF + use NUOPC + use NUOPC_Driver, only: & + driver_routine_SS => routine_SetServices, & + driver_type_IS => type_InternalState, & + driver_label_IS => label_InternalState, & + driver_setMC => label_SetModelCount, & +#ifdef WITHPETLISTS + driver_label_SetModelPetLists => label_SetModelPetLists, & +#endif + driver_label_SetModelServices => label_SetModelServices + + use time_utils_mod + + use ocean_solo_mod + + implicit none + private + public SetServices + + contains + + !----------------------------------------------------------------------- + !------------------- Earth System Model code starts here --------------- + !----------------------------------------------------------------------- + subroutine SetServices(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! NUOPC_Driver registers the generic methods + call driver_routine_SS(gcomp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! attach specializing method(s) +#ifdef WITHPETLISTS + call ESMF_MethodAdd(gcomp, label=driver_label_SetModelPetLists, & + userRoutine=SetModelPetLists, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out +#endif + + call ESMF_MethodAdd(gcomp, label=driver_setMC, & + userRoutine=setModelCount, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_MethodAdd(gcomp, label=driver_label_SetModelServices, & + userRoutine=SetModelServices, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + + !----------------------------------------------------------------------------- + +#ifdef WITHPETLISTS + + subroutine SetModelPetLists(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + integer :: localrc + type(driver_type_IS) :: is + integer :: petCount, i + + rc = ESMF_SUCCESS + + ! query Component for its internal State + nullify(is%wrap) + call ESMF_UserCompGetInternalState(gcomp, driver_label_IS, is, rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! get the petCount + call ESMF_GridCompGet(gcomp, petCount=petCount, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! set petList for OCN -> second half of PETs + allocate(is%wrap%modelPetLists(petCount)) + do i=0, petCount-1 + is%wrap%modelPetLists(i) = i ! PET labeling goes from 0 to petCount-1 + enddo + + end subroutine +#endif + + subroutine setModelCount(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + integer :: localrc + type(driver_type_IS) :: is + integer :: petCount, i + + rc = ESMF_SUCCESS + + ! query Component for its internal State + nullify(is%wrap) + call ESMF_UserCompGetInternalState(gcomp, driver_label_IS, is, rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + !Only ocean model exists + is%wrap%modelCount=1 + + end subroutine + + subroutine SetModelServices(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + integer :: localrc + type(driver_type_IS) :: is + type(ESMF_Grid) :: grid + type(ESMF_Field) :: field + type(ESMF_Time) :: startTime + type(ESMF_Time) :: stopTime + type(ESMF_TimeInterval) :: timeInterval + type(ESMF_TimeInterval) :: timeStep + type(ESMF_Clock) :: internalClock + + integer :: n, m, unit, io_status, ierr + ! Read clock information from namelist + integer :: date_init(6)=0, date(6) + integer :: date_restart(6) + character(len=17) :: calendar = 'julian' + integer :: dt_cpld = 86400 + integer :: years=0, months=0, days=0, hours=0, minutes=0, seconds=0 + integer :: layout_mask(2) = (/0 , 0/) + integer :: n_mask = 0 + integer :: mask_list(2,MAXPES) + integer, parameter :: mp = 2*MAXPES + data ((mask_list(n,m),n=1, 2),m=1,MAXPES) /mp*0/ + integer :: restart_interval(6) = (/0,0,0,0,0,0/) + + namelist /ocean_solo_nml/ date_init, calendar, months, days, hours, minutes, seconds, dt_cpld, & + n_mask, layout_mask, mask_list, restart_interval + + rc = ESMF_SUCCESS + +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=ocean_solo_nml, iostat=io_status) + ierr = check_nml_error(io_status,'ocean_solo_nml') +#else + unit = open_namelist_file('input.nml') + read (unit, ocean_solo_nml,iostat=io_status) + ierr = check_nml_error(io_status,'ocean_solo_nml') + call close_file (unit) +#endif + + write(*,*) 'Time is', date_init(1), date_init(2), date_init(3), & + date_init(4), date_init(5), date_init(6) + ! query Component for its internal State + nullify(is%wrap) + call ESMF_UserCompGetInternalState(gcomp, driver_label_IS, is, rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! SetServices for OCN + call ESMF_GridCompSetServices(is%wrap%modelComp(1), ocean_solo_SS, userRc=localrc, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__, & + rcToReturn=rc)) & + return ! bail out + + ! set the model clock + call ESMF_TimeIntervalSet(timeStep, s=dt_cpld, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_TimeSet(startTime, yy=date_init(1), mm=date_init(2), & + dd=date_init(3), h=date_init(4), m=date_init(5), s=date_init(6), & + calkindflag=fms2esmf_cal(calendar), rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_TimeIntervalSet(timeInterval, mm=months, d=days, h=hours, & + m=minutes, s=seconds, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + stopTime = startTime + timeInterval + + internalClock = ESMF_ClockCreate(name="Application Clock", & + timeStep=timeStep, startTime=startTime, stopTime=stopTime, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_GridCompSet(gcomp, clock=internalClock, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + +end module esm_mod + +program ocean_solo +! +!This is an updated ocean solo model application using NUOPC framework. +! +!Author: Fei Liu +!Thu Feb 7 10:09:06 MST 2013 +! +!Matt Harrison +! +! +!Dave Bi (for OASIS3 hooks) +! +! +!Niki Zadeh (for OASIS3 hooks) +! +! +!V. Balaji +! +! +!Stephen Griffies +! +! +!+! Driver for ocean-only simulations and prototype setup for OASIS3 driver. +! +! +!+! Driver for the ocean-only simulations. Similar to the FMS coupler, but +! allows one to run the ocean model without compiling other models. +! Much simpler than the full FMS coupler. +! +! This driver also provides the prototype hooks for using MOM with OASIS3, +! with this code surrounded by the cpp-preprocessor option "ifdef OASIS3". +! The couping of MOM to OASIS3 has not been tested at GFDL. Rather, +! CSIRO in Australia uses MOM with OASIS3, with Dave.Bi@csiro.au the primary +! contact for questions regarding MOM and OASIS3. +! +! +!+! +! +! The date that the current integration starts with. If the restart file +! ocean_solo.res is present, date_init will be taken from there. +! +! +! The calendar type used by the current integration. Valid values are consistent +! with the time_manager module: 'julian', 'gregorian', 'noleap', or 'thirty_day'. +! The value 'no_calendar' can not be used because the time_manager's date +! function are used. +! +! +! +! The number of months that the current integration will be run for. +! +! +! The number of days that the current integration will be run for. +! +! +! The number of hours that the current integration will be run for. +! +! +! The number of minutes that the current integration will be run for. +! +! +! The number of seconds that the current integration will be run for. +! +! +! Time step in seconds for coupling between ocean and atmospheric models: +! must be an integral multiple of dt_ocean. This is the "slow" timestep. +! Note that for an ocean_solo model, the coupling to an "atmosphere" is the coupling +! to some data files. In this case, dt_cpld represents the time which data is updated. +! For example, if data is "daily", then dt_cpld=86400 should be chosen. +! If data is fixed, then dt_cpld of any integer of dt_ocean is fine, with +! dt_cpld=86400 the default. +! +! +! number of region to be masked out. Its value should be less than MAX_PES. +! +! +! The position of the region to be masked out. mask_list(1,:) is the x-layout position +! and mask_list(2,:) is y-layout position. +! +! +! Processor domain layout for all the component model. layout_mask need to be set when and only +! when n_mask is greater than 0 ( some domain region is masked out ). When this namelist is set, +! it will overload the layout in each component model. The default value is (0,0). +! Currently we require all the component model has the same layout and same grid size. +! +! +! The time interval that write out intermediate restart file. The format is (yr,mo,day,hr,min,sec). +! When restart_interval is all zero, no intermediate restart file will be written out. +! +! +! +! +!+! +! + use constants_mod, only: constants_init + use data_override_mod, only: data_override_init, data_override + use diag_manager_mod, only: diag_manager_init, diag_manager_end + use field_manager_mod, only: field_manager_init + use fms_mod, only: fms_init, fms_end, open_namelist_file, check_nml_error + use fms_mod, only: close_file, file_exist, uppercase + use fms_io_mod, only: fms_io_exit + use mpp_domains_mod, only: domain2d, mpp_get_compute_domain + use mpp_io_mod, only: mpp_open, MPP_RDONLY, MPP_ASCII, MPP_OVERWR, MPP_APPEND, mpp_close, MPP_SINGLE + use mpp_mod, only: input_nml_file, mpp_error, FATAL, NOTE, mpp_pe, mpp_npes, mpp_set_current_pelist + use mpp_mod, only: stdlog, stdout, mpp_root_pe, mpp_clock_id + use mpp_mod, only: mpp_clock_begin, mpp_clock_end, MPP_CLOCK_SYNC + use mpp_mod, only: MPP_CLOCK_DETAILED, CLOCK_COMPONENT, MAXPES + use time_interp_external_mod, only: time_interp_external_init + use time_manager_mod, only: set_calendar_type, time_type, increment_date + use time_manager_mod, only: set_time, set_date, get_time, get_date, month_name + use time_manager_mod, only: GREGORIAN, JULIAN, NOLEAP, THIRTY_DAY_MONTHS, NO_CALENDAR + use time_manager_mod, only: operator( <= ), operator( < ), operator( >= ) + use time_manager_mod, only: operator( + ), operator( - ), operator( / ) + use time_manager_mod, only: operator( * ), operator( /= ), operator( > ) + use time_manager_mod, only: date_to_string + use time_manager_mod, only: fms_get_calendar_type => get_calendar_type + + use ocean_model_mod, only: ocean_model_init , update_ocean_model, ocean_model_end + use ocean_model_mod, only: ocean_model_restart, ocean_public_type, ocean_state_type + use ocean_types_mod, only: ice_ocean_boundary_type + + + use ESMF + use time_utils_mod + use esm_mod + + implicit none + + + !-------------------- main code starts here --------------------- + integer :: rc, urc, mpi_comm_mom + type(ESMF_VM) :: vm + type(ESMF_GridComp) :: esmComp + + ! Initialize ESMF + call ESMF_Initialize(logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_VMGetCurrent(vm, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_VMGet(vm, mpiCommunicator=mpi_comm_mom, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call fms_init(mpi_comm_mom) + + call ESMF_LogWrite("MOM5 ocean solo STARTING", ESMF_LOGMSG_INFO, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create the earth system Component + esmComp = ESMF_GridCompCreate(name="mom_solo", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! SetServices for the earth system Component + call ESMF_GridCompSetServices(esmComp, SetServices, userRc=urc, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Call Initialize for the earth system Component + call ESMF_GridCompInitialize(esmComp, userRc=urc, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Call Run for earth the system Component + call ESMF_GridCompRun(esmComp, userRc=urc, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Call Finalize for the earth system Component + call ESMF_GridCompFinalize(esmComp, userRc=urc, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Destroy the earth system Component + call ESMF_GridCompDestroy(esmComp, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_LogWrite("MOM5 ocean solo FINISHED", ESMF_LOGMSG_INFO, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Finalize ESMF + call ESMF_Finalize() + +end program ocean_solo diff --git a/src/mom5/ocean_bgc/ocean_bgc_restore.F90 b/src/mom5/ocean_bgc/ocean_bgc_restore.F90 index e9cef5872d..8db434cea9 100644 --- a/src/mom5/ocean_bgc/ocean_bgc_restore.F90 +++ b/src/mom5/ocean_bgc/ocean_bgc_restore.F90 @@ -357,8 +357,8 @@ module ocean_bgc_restore_mod integer :: package_index logical :: module_initialized = .false. -character(len=128) :: version = '$Id: ocean_bgc_restore.F90,v 1.1.2.1 2012/05/15 15:55:19 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocean_bgc_restore.F90,v 20.0 2013/12/14 00:09:28 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' ! Input parameters: ! diff --git a/src/mom5/ocean_bgc/ocean_bgc_restore.html b/src/mom5/ocean_bgc/ocean_bgc_restore.html deleted file mode 100644 index 7230014e82..0000000000 --- a/src/mom5/ocean_bgc/ocean_bgc_restore.html +++ /dev/null @@ -1,455 +0,0 @@ - - - -+! 1.The actual run length will be the sum of months, +! days, hours, minutes, and seconds. A run length of zero +! is not a valid option. +! 2.The run length must be an integral multiple of the coupling +! timestep dt_cpld. +!+!Module ocean_bgc_restore_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_bgc_restore_mod
- - - - - -
-OVERVIEW
- -- Ocean Carbon Model Intercomparison Study II: Biotic module -
- - - -- Implementation of routines to solve the OCMIP-2 Biotic - simulations as outlined in the Biotic-HOWTO documentation, - revision 1.7, 1999/10/05. --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
diag_manager_mod
field_manager_mod
fms_mod
fms_io_mod
mpp_mod
time_interp_external_mod
mpp_domains_mod
constants_mod
ocean_tpm_util_mod
fm_util_mod
coupler_types_mod
ocean_types_mod
ocmip2_co2calc_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -locate:
- -- -ocean_bgc_restore_bbc:
- -- -ocean_bgc_restore_end:
- -- -ocean_bgc_restore_restart:
- -- -ocean_bgc_restore_sbc:
- -- -ocean_bgc_restore_flux_init:
- -- -ocean_bgc_restore_init:
- -- -ocean_bgc_restore_init_sfc:
- -- -ocean_bgc_restore_sum_sfc:
- -- -ocean_bgc_restore_zero_sfc:
- -- -ocean_bgc_restore_avg_sfc:
- -- -ocean_bgc_restore_sfc_end:
- -- -ocean_bgc_restore_source:
- -- -ocean_bgc_restore_start:
- -- -set_array:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-locate
--
-- -DESCRIPTION -
-- - After Numerical recipes: - - Given an array XX of length N, and a given value of X, returns a - value of J such that X is between XX(J) and XX(J+1). XX must be - monotonic, either increasing or decreasing. J=0 or J=N is - returned to indicate that X is out of range. - New features: - - If "period" is specified, then the array, xx, is considered - to be periodic with a period of "period". If "x_in" is out - of range, then add or subtract "period" once to attempt to - make "x_in" be in range. - - If "nearest" is specified, and true, then return "j" such - that it is the element of "xx" which is nearest to the value - of "x_in" (where "x_in" may have been modified by the value - "period", above). With this option, "j" will be in - the range 1 <= j <= n. -
-
-
-- - -
-ocean_bgc_restore_bbc
--
-- -DESCRIPTION -
-- - calculate the surface boundary conditions -
-
-
-- - -
-ocean_bgc_restore_end
--
-- -DESCRIPTION -
-- - Clean up various BIOTIC quantities for this run. -
-
-
-- - -
-ocean_bgc_restore_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_bgc_restore_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions -
-
-
-- - -
-ocean_bgc_restore_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocean_bgc_restore_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocean_bgc_restore_init_sfc
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocean_bgc_restore_start -
-
-
-- - -
-ocean_bgc_restore_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_bgc_restore_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_bgc_restore_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_bgc_restore_sfc_end
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations -
-
-
-- - -
-ocean_bgc_restore_source
--
-- -DESCRIPTION -
-- - compute the source terms for the BIOTICs, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocean_bgc_restore_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants for a given run - and allocate diagnostic arrays -
-
-
-- - -
-set_array
--
-- -DESCRIPTION -
-- - Set up an array covering the model domain with a user-specified - value, in user-specified regions. There are a given number of - 2-d regions specified by the values slat, nlat, wlon and elon. - The longitudes are for a cyclic domain, and if wlon and elon - are on opposite sides of the cut, the correct thing will - be done. Elon is considered to be east of wlon, so if elon is - less than wlon, then the region east of elon to the cut will be - filled, and the region from the cut to wlon will be filled. - - After setting up the array in this routine, it may prove useful - to allow fine-tuning the settings via an array in a namelist. - - Arguments: - Input: - num_regions = number of user-specified regions which will be - filled - - wlon = 1-d array of western (starting) longitudes for the - rectangular regions - - elon = 1-d array of eastern (ending) longitudes for the - rectangular regions - - slat = 1-d array of southern (starting) latitudes for the - rectangular regions - - nlat = 1-d array of northern (ending) latitudes for the - rectangular regions - - Note: if slat >= nlat, then nothing is done - for that region - - set_value = the value to assign to array in the user-specified - regions - - unset_value = the value to assign to array outside of the - user-specified regions - - name = character variable used in informative messages - - coastal_only = true to limit changes only to coastal points - (i.e., at least one bordering point is land) - - Output: - - array = 2-d array which will contain the set- and unset- - values. The array is assumed to have a border - one unit wide on all edges, ala MOM. A cyclic - boundary condition will be set if requested. -
-
-
-
-REFERENCES
- ----
-- - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Biotic/HOWTO-Biotic.html -
-- - Press, W. H., S. A. Teukosky, W. T. Vetterling, B. P. Flannery, 1992. - Numerical Recipes in FORTRAN, Second Edition, Cambridge University Press. -
-- - Enting, I.G., T. M. L. Wigley, M. Heimann, 1994. Future Emissions - and concentrations of carbon dioxide: key ocean / atmosphere / - land analyses, CSIRO Aust. Div. Atmos. Res. Tech. Pap. No. 31, - 118 pp. -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocean_generic_tracer.F90 b/src/mom5/ocean_bgc/ocean_generic_tracer.F90 index fc9d613ace..737345bd23 100644 --- a/src/mom5/ocean_bgc/ocean_generic_tracer.F90 +++ b/src/mom5/ocean_bgc/ocean_generic_tracer.F90 @@ -30,10 +30,12 @@ module ocean_generic_mod use generic_tracer, only: generic_tracer_coupler_get, generic_tracer_coupler_set, generic_tracer_register_diag use generic_tracer, only: generic_tracer_end, generic_tracer_get_list, do_generic_tracer, generic_tracer_register use generic_tracer, only: generic_tracer_coupler_zero, generic_tracer_vertdiff_G, generic_tracer_vertdiff_M + use generic_tracer, only: generic_tracer_diag use g_tracer_utils, only: g_tracer_get_name,g_tracer_get_alias,g_tracer_set_values,g_tracer_get_common use g_tracer_utils, only: g_tracer_get_next,g_tracer_type,g_tracer_is_prog,g_tracer_flux_init use g_tracer_utils, only: g_tracer_send_diag,g_tracer_get_values,g_tracer_get_pointer + use g_tracer_utils, only: g_tracer_set_pointer use coupler_types_mod, only: coupler_2d_bc_type @@ -42,7 +44,7 @@ module ocean_generic_mod logical :: module_initialized = .false. ! identification numbers for mpp clocks integer :: id_clock_gt_vertdiff - integer :: id_clock_gt_source,id_clock_gt_btm + integer :: id_clock_gt_source,id_clock_gt_btm,id_clock_gt_diag integer :: id_clock_gt_get_vals,id_clock_gt_set_vals,id_clock_gt_sum_sfc_setval public do_generic_tracer @@ -55,17 +57,26 @@ module ocean_generic_mod public ocean_generic_end public ocean_generic_get_field public ocean_generic_get_field_pointer + public ocean_generic_set_pointer interface ocean_generic_get_field module procedure ocean_generic_get_field_3D module procedure ocean_generic_get_field_4D end interface + interface ocean_generic_set_pointer + module procedure ocean_generic_set_pointer_3D + module procedure ocean_generic_set_pointer_4D + end interface + contains !ALL PE subroutine on Ocean! Due to otpm design the fluxes should be initialized like this on ALL PE's! subroutine ocean_generic_flux_init + integer :: ind + character(len=fm_string_len) :: g_tracer_name,longname, package,units,old_package + real :: const_init_value character(len=fm_string_len), parameter :: sub_name = 'ocean_generic_flux_init' type(g_tracer_type), pointer :: g_tracer_list,g_tracer,g_tracer_next @@ -119,7 +130,7 @@ subroutine ocean_generic_init(Domain,Grid,Time) character(len=fm_string_len) :: g_tracer_name,longname, package,units,old_package,restart_file type(g_tracer_type), pointer :: g_tracer_list,g_tracer,g_tracer_next real :: const_init_value - integer :: ntau, ind + integer :: ntau, ind, length if (module_initialized) return @@ -215,6 +226,7 @@ subroutine ocean_generic_init(Domain,Grid,Time) id_clock_gt_vertdiff = mpp_clock_id('(Ocean generic tracer: vertdiff) ' ,grain=CLOCK_ROUTINE) id_clock_gt_source = mpp_clock_id('(Ocean generic tracer: source) ' ,grain=CLOCK_ROUTINE) id_clock_gt_btm = mpp_clock_id('(Ocean generic tracer: bottom up) ' ,grain=CLOCK_ROUTINE) + id_clock_gt_diag = mpp_clock_id('(Ocean generic tracer: diag) ' ,grain=CLOCK_ROUTINE) id_clock_gt_set_vals = mpp_clock_id('(Ocean generic tracer: set_values) ' ,grain=CLOCK_ROUTINE) id_clock_gt_get_vals = mpp_clock_id('(Ocean generic tracer: get_values) ' ,grain=CLOCK_ROUTINE) id_clock_gt_sum_sfc_setval = mpp_clock_id('(Ocean generic tracer: sumsfcsetv) ' ,grain=CLOCK_ROUTINE) @@ -288,28 +300,6 @@ subroutine ocean_generic_sum_sfc(Disd,Djsd, Ocean, T_prog, Dens, Time ) if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& ": No tracer in the list.") - !For each tracer name get its T_prog index and set its field - g_tracer=>g_tracer_list - call mpp_clock_begin(id_clock_gt_sum_sfc_setval) - do - if(g_tracer_is_prog(g_tracer)) then - call g_tracer_get_alias(g_tracer,g_tracer_name) - g_tracer_index = fm_get_index(trim('/ocean_mod/prog_tracers/'//g_tracer_name)) - if (g_tracer_index .le. 0) & - call mpp_error(FATAL,trim(sub_name) // ' Could not get the index for '//g_tracer_name) - - call g_tracer_set_values(g_tracer,g_tracer_name,'field', T_prog(g_tracer_index)%field(:,:,:,Time%taum1),& - Disd,Djsd,ntau=Time%taum1) - endif - - !traverse the linked list till hit NULL - call g_tracer_get_next(g_tracer, g_tracer_next) - if(.NOT. associated(g_tracer_next)) exit - g_tracer=>g_tracer_next - - enddo - call mpp_clock_end(id_clock_gt_sum_sfc_setval) - call generic_tracer_coupler_set(Ocean%fields,& ST=T_prog(indtemp)%field(:,:,1,Time%taum1),& SS=T_prog(indsal)%field(:,:,1,Time%taum1),& @@ -440,48 +430,16 @@ subroutine ocean_generic_column_physics(Thickness, hblt_depth, Time, Grid, dtts, real, dimension(:), Allocatable :: max_wavelength_band real, dimension(:,:,:), Allocatable :: sw_pen_band real, dimension(:,:,:,:), Allocatable :: opacity_band + logical, save :: initialize_tau_level = .true. character(len=fm_string_len) :: g_tracer_name character(len=fm_string_len), parameter :: sub_name = 'ocean_generic_column_physics' - ! Update the fields of the generic tracers from T_prog - - ! Get the tracer list - call generic_tracer_get_list(g_tracer_list) - if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& - ": No tracer in the list.") - - ! For each tracer name get its T_prog index and set its field - g_tracer=>g_tracer_list - call mpp_clock_begin(id_clock_gt_set_vals) - do - call g_tracer_get_alias(g_tracer,g_tracer_name) - if(g_tracer_is_prog(g_tracer)) then - g_tracer_index = fm_get_index(trim('/ocean_mod/prog_tracers/'//g_tracer_name)) - if (g_tracer_index .le. 0) & - call mpp_error(FATAL,trim(sub_name) // ' Could not get the index for '//g_tracer_name) - - call g_tracer_set_values(g_tracer,g_tracer_name,'field', T_prog(g_tracer_index)%field(:,:,:,Time%taup1), & - Disd,Djsd,ntau=Time%taup1) - ! T_prog(n)%K33_implicit is used in vertdiff method below for calculating vertical diffusivity - call g_tracer_set_values(g_tracer,g_tracer_name,'tendency',T_prog(g_tracer_index)%K33_implicit,Disd,Djsd) - - else - g_tracer_index = fm_get_index(trim('/ocean_mod/diag_tracers/'//g_tracer_name)) - if (g_tracer_index .le. 0) & - call mpp_error(FATAL,trim(sub_name) // ' Could not get the index for '//g_tracer_name) - - call g_tracer_set_values(g_tracer,g_tracer_name,'field', T_diag(g_tracer_index)%field, Disd,Djsd) - endif - - !traverse the linked list till hit NULL - call g_tracer_get_next(g_tracer, g_tracer_next) - if(.NOT. associated(g_tracer_next)) exit - g_tracer=>g_tracer_next - - enddo - call mpp_clock_end(id_clock_gt_set_vals) - + ! + !Update the fields of the generic tracers from T_prog + ! + !This step is not needed any more since generic tracers %field points to and reuse the corresponding MOM arrays. + ! !Update from sources indtemp=-1 indsal=-1 @@ -516,7 +474,7 @@ subroutine ocean_generic_column_physics(Thickness, hblt_depth, Time, Grid, dtts, call generic_tracer_source(T_prog(indtemp)%field(:,:,:,Time%taup1),& T_prog(indsal)%field(:,:,:,Time%taup1), Thickness%rho_dzt(:,:,:,Time%taup1), Thickness%dzt,& hblt_depth, Disd, Djsd, Time%taup1,dtts,Grid%dat, Time%model_time,& - nbands, max_wavelength_band, sw_pen_band, opacity_band, Velocity%current_wave_stress(:,:)) + nbands, max_wavelength_band, sw_pen_band, opacity_band, Grid%ht, Velocity%current_wave_stress(:,:)) call mpp_clock_end(id_clock_gt_source) deallocate(max_wavelength_band,sw_pen_band,opacity_band) @@ -535,15 +493,23 @@ subroutine ocean_generic_column_physics(Thickness, hblt_depth, Time, Grid, dtts, call generic_tracer_update_from_bottom(dtts, Time%taup1, Time%model_time) call mpp_clock_end(id_clock_gt_btm) + ! + ! Finish up generic tracers + ! + call mpp_clock_begin(id_clock_gt_diag) + call generic_tracer_diag(Disd, Djsd, Time%tau, Time%taup1, dtts, Time%model_time, Thickness%dzt, & + Thickness%rho_dzt(:,:,:,Time%tau), Thickness%rho_dzt(:,:,:,Time%taup1)) + call mpp_clock_end(id_clock_gt_diag) + !!nnz: the following is necessary if generic tracers are allocated by MOM ! !Update T_prog fields from generic tracer fields + !This step is not needed for %fields any more since generic tracers %field points to and reuse the corresponding MOM arrays. ! !Get the tracer list call generic_tracer_get_list(g_tracer_list) if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& ": No tracer in the list.") - !For each tracer name get its T_prog or T_diag index and get its fields g_tracer=>g_tracer_list call mpp_clock_begin(id_clock_gt_get_vals) do @@ -553,19 +519,8 @@ subroutine ocean_generic_column_physics(Thickness, hblt_depth, Time, Grid, dtts, if (g_tracer_index .le. 0) & call mpp_error(FATAL,trim(sub_name) // ' Could not get the index for '//g_tracer_name) - call g_tracer_get_values(g_tracer,g_tracer_name,'field', T_prog(g_tracer_index)%field(:,:,:,Time%taup1),& - Disd,Djsd,ntau=Time%taup1) - if (_ALLOCATED(g_tracer%btf) )& call g_tracer_get_values(g_tracer,g_tracer_name,'btf', T_prog(g_tracer_index)%btf, Disd,Djsd) - - else - g_tracer_index = fm_get_index(trim('/ocean_mod/diag_tracers/'//g_tracer_name)) - if (g_tracer_index .le. 0) & - call mpp_error(FATAL,trim(sub_name) // ' Could not get the index for '//g_tracer_name) - - call g_tracer_get_values(g_tracer,g_tracer_name,'field', T_diag(g_tracer_index)%field, Disd,Djsd) - endif !traverse the linked list till hit NULL @@ -607,11 +562,44 @@ subroutine ocean_generic_get_field_3D(name, field) call generic_tracer_get_list(g_tracer_list) call g_tracer_get_pointer(g_tracer_list,name,'field', ptr ) - field = ptr end subroutine ocean_generic_get_field_3D + subroutine ocean_generic_set_pointer_4d(name, member, field, ilb, jlb) + character(len=fm_string_len), parameter :: sub_name = 'ocean_generic_set_pointer_4d' + character(len=*), intent(in) :: name + character(len=*), intent(in) :: member + real, dimension(ilb:,jlb:,:,:), target, intent(in) :: field + integer, intent(in) :: ilb + integer, intent(in) :: jlb + type(g_tracer_type), pointer :: g_tracer_list + + call generic_tracer_get_list(g_tracer_list) + if (associated(g_tracer_list)) then + call g_tracer_set_pointer(g_tracer_list, name, member, field, ilb, jlb) + else + call mpp_error(NOTE, trim(sub_name)// ": No generic tracer in the list. No generic tracers?") + endif + end subroutine ocean_generic_set_pointer_4d + + subroutine ocean_generic_set_pointer_3d(name, member, field, ilb, jlb) + character(len=fm_string_len), parameter :: sub_name = 'ocean_generic_set_pointer_3d' + character(len=*), intent(in) :: name + character(len=*), intent(in) :: member + real, dimension(ilb:,jlb:,:), target, intent(in) :: field + integer, intent(in) :: ilb + integer, intent(in) :: jlb + type(g_tracer_type), pointer :: g_tracer_list + + call generic_tracer_get_list(g_tracer_list) + if (associated(g_tracer_list)) then + call g_tracer_set_pointer(g_tracer_list, name, member, field, ilb, jlb) + else + call mpp_error(NOTE, trim(sub_name)// ": No generic tracer in the list. No generic tracers?") + endif + end subroutine ocean_generic_set_pointer_3d + !! NAME="set_ocean_vgrid_arrays" +!####################################################################### +!! Ends the generic tracer module diff --git a/src/mom5/ocean_bgc/ocean_generic_tracer.html b/src/mom5/ocean_bgc/ocean_generic_tracer.html deleted file mode 100644 index 283b23a799..0000000000 --- a/src/mom5/ocean_bgc/ocean_generic_tracer.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - Module ocean_generic_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_generic_mod
- - - - - -
-OVERVIEW
- -- This module drives the generic version of tracers TOPAZ and CFC. -
- - - - -
- - -
-OTHER MODULES USED
- --- - - -ocean_tpm_util_mod-
ocean_types_mod
ocean_parameters_mod
mpp_mod
field_manager_mod
generic_tracer
g_tracer_utils
coupler_types_mod
-PUBLIC INTERFACE
----
-- -ocean_generic_init:
-- - Initialize: Add the generic tracers -
-- -ocean_generic_zero_sfc:
-- - zero out the coupler values for all generic tracers -
-- -ocean_generic_sum_sfc:
-- - Calculate the surface state and set coupler values -
-- -ocean_generic_sbc:
-- - Get the coupler values -
-- -ocean_generic_column_physics:
-- - Column physics for generic tracers. -
-- -ocean_generic_end:
-- - Ends the generic tracer module -
-
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_generic_init
--call ocean_generic_init (Domain,Grid,Time)--
-- -DESCRIPTION -
-- - This subroutine: - Initializes the generic tracer packages and adds their tracers to the list - Adds the tracers in the list of generic tracers to the set of MOM tracers - (i.e., make them elements of T_prog or T_diag) -
-
-
-- - -
-ocean_generic_zero_sfc
--call ocean_generic_zero_sfc (IOB_struc)--
-- -DESCRIPTION -
-- - This is need since MOM coupler values are acumulated and then divided by time ocean steps. -
-
-
-- - -
-ocean_generic_sum_sfc
--call ocean_generic_sum_sfc (Disd,Djsd, Ocean, T_prog, Dens, Time )--
-- -DESCRIPTION -
-- - This subroutine calculates the surface state and set coupler values for - those generic tracers that havd flux exchange with atmosphere. -
-
-
-- - -
-ocean_generic_sbc
--call ocean_generic_sbc (Ice_ocean_boundary_fluxes,Disd,Djsd, T_prog )--
-- -DESCRIPTION -
-- - This subroutine gets coupler values for - those generic tracers that have flux exchange with atmosphere. -
-
-
-- - -
-ocean_generic_column_physics
--call ocean_generic_column_physics (Thickness, hblt_depth, Time, Grid, dtts, Disd,Djsd, T_prog, T_diag,& sw_pen,opacity, diff_cbt, Dens, river, Velocity )--
-- -DESCRIPTION -
-- - This subroutine: - Update generic tracer concentration fields from sources and sinks. - Vertically diffuse generic tracer concentration fields. - Update generic tracers from bottom and their bottom reservoir. -
-
-
-- - -
-ocean_generic_end
--call ocean_generic_end ---
-- -DESCRIPTION -
-- - Call the end for generic tracer module and deallocate all temp arrays -
-
-
-
--top -- - diff --git a/src/mom5/ocean_bgc/ocean_ibgc.F90 b/src/mom5/ocean_bgc/ocean_ibgc.F90 index 0a42ddd144..9621c64af7 100644 --- a/src/mom5/ocean_bgc/ocean_ibgc.F90 +++ b/src/mom5/ocean_bgc/ocean_ibgc.F90 @@ -553,8 +553,8 @@ module ocean_ibgc_mod integer :: package_index logical :: module_initialized = .false. -character(len=128) :: version = '$Id: ocean_ibgc.F90,v 1.1.2.1 2012/05/15 15:55:19 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocean_ibgc.F90,v 20.0 2013/12/14 00:09:32 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' ! Input parameters: ! diff --git a/src/mom5/ocean_bgc/ocean_ibgc.html b/src/mom5/ocean_bgc/ocean_ibgc.html deleted file mode 100644 index 8ae37c1fb5..0000000000 --- a/src/mom5/ocean_bgc/ocean_ibgc.html +++ /dev/null @@ -1,616 +0,0 @@ - - - -Module ocean_ibgc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_ibgc_mod
- - --Contact: Eric Galbraith - , - Anand Gnanandesikan - -- - -
-Reviewers: Rick Slater - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- IDEALIZED OCEAN BIOGEOCHEMISTRY * - * - An idealized biogeochemical cycling module, in which the ecosystem and * - particles are treated implicitly. This is intended as a first-order * - complexity complement to more intricate ecosystem/biogeochemical models * - such as BLING, or the GFDL TOPAZ model. * - - iBGC is not intended to simulate marine biogeochemistry in the most * - accurate sense possible - that is left to the more complex models. * - Instead, it is intended as a tool for basic research, being easily * - modified, simply understood, and readily used in idealized configurations.* - - Note that the model parameters are not particularly well tuned for any * - ocean model, and the user should feel free to alter anything as they see * - fit. * - -
- - - -- -* Inorganic nutrients are incorporated into organic matter in the presence * -* of light. Once in the organic pool, the nutrient elements are recycled * -* between organisms and labile reservoirs as long as light is present in * -* sufficient abundance to fuel continued growth. In the absence of light, * -* inorganic nutrients gradually accumulate once again. The ideal nutrient * -* tracers are intended to capture the fundamental dynamics of these * -* light-dependent inorganic-organic transitions, but in a very simple, * -* transparent way that depends only on the physical circulation and the * -* availability of PAR. Thus, they ignore the complexities of ecosystems, * -* in terms of uptake dynamics and remineralization pathways. Although this * -* will certainly decrease their ability to reproduce the observed * -* distributions of nutrients in the ocean, they are computationally * -* inexpensive and easy to interpret, features which will hopefully give * -* them some utility. * -* The simplest ideal nutrient tracer, ideal_n, is non-conservative, * -* designed to quickly approach equilibrium (order 10 years), avoiding the * -* need for long integrations. The slightly less straightforward, * -* conservative tracers are remineralized through the water column and * -* therefore approach steady state on much longer, multi-centennial * -* timescales. * -* -* The core behaviour of the ideal nutrients are given by the exponential, * -* exp(-IRR/IRRk). IRR is the available light (average SW radiation, in * -* W/m2, within the grid cell) and IRRk (in W/m2) determines the light * -* level at which the phytoplankton growth rate approaches saturation. * -* Thus, this term is 1 when IRR is 0, and approaches 0 as IRR increases. A * -* larger value for IRRk causes the exponential to approach 0 more slowly, * -* ie. to saturate at a higher light level. * -* -* Uptake is determined by the product of the 1 minus the exponential term, * -* a maximum uptake velocity (Vmax, in s-1), and limitation caused by the * -* concentration of the ideal nutrient itself, N (in mol kg-1): * -* * -* -Vmax * (1 - exp( -IRR / IRRk )) * (N / N + k) * -* * -* The last term causes nutrient uptake to slow as the nutrient * -* concentration approaches 0, according to Michaelis-Menten dynamics. * -* * -* In ideal_n, regeneration is simply a constant rate, R. * -* -* Starting from this simple foundation, biogeochemical functionality is * -* added by creating a macronutrient (iPO4) with identical uptake to * -* ideal_n, but for which mass is conserved within the ocean. This is * -* achieved by separating the uptake into dissolved and particulate * -* organic matter, the latter of which is instantaneously remineralized * -* throughout the water column below according to a variant of the OCMPIP2 * -* protocol. This calculates the remineralization rate at each level as a * -* function of the temperature, base remineralization rate, and sinking * -* rate (itself a function of depth). Any flux reaching the bottom box is * -* instantly remineralized there to conserve mass within the ocean. * -* Meanwhile, Dissolved Organic Phosphorus (iDOP) is transported within the * -* ocean, decaying to PO4 at a temperature-dependent rate. * -* -* Given the apparent importance of iron (Fe) as a limiting micronutrient * -* in the oceans, it seemed interesting to try making another PO4 tracer, * -* limited by Fe, in addition to the basic limitations given above: this is * -* called iPO4f. The iron input is highly idealized, and the scavenging * -* function very simple, but iron-limitation develops and modulates * -* growth rate through iron-light colimitation in a way that may not be * -* totally unlike the real ocean. The Fe-limited PO4 cycle is completely * -* independent of the non-Fe-limited PO4, and they can be run on their own * -* or in parallel for comparison. -* -* A full biogeochemical simulation can then be made by selecting one of * -* the iPO4s as the central bgc variable (default is iPO4). Biological * -* consumption and production of other quantities, including a number of * -* gases and idealized gas tracers, are then determined from the generally * -* reliable Redfield stoichiometries. * -* -* Isotopic fractionations are simulated by multiplying the uptake rate of * -* the chemical species by the isotopic rate ratio, alpha. The tracer * -* concentrations of the heavy isotope species are actually * -* equal to the true concentration divided by the isotopic ratio of the * -* standard, e.g. 15NO3 = [15NO3] * [14Nair] / [15Nair]. The true value in * -* permil is given by (15NO3 / NO3 - 1.) * 1000. * -* -* Dissolved gases are handled according to the OCMIP2 protocol. The air- * -* sea exchange code was taken from the ocmip2_abiotic and ocmip2_biotic * -* modules, with negligible modification. Note that the 14C implementation * -* differs from that of abiotic, in that biological uptake and remineraliz- * -* ation of carbon impact the distribution of 14C, analagous to 15N. * -* -* Chlorophyll is estimated diagnostically from the net bgc iPO4 (or iPO4f) * -* uptake rate, with an adjustment for photoadaptation. - - - A general note on nomenclature - Variables starting with 'j' are source/sink terms; jprod_x is the - biological production term for the quantity 'x'; jremin_x is the - remineralization rate of the quantity 'x'. Variables starting with 'fp' - are sinking particulate flux terms. Most of the 'i's stand for idealized, - as in iBGC, and help to avoid duplication of arrays and tracer names used - by TOPAZ and BLING, so that ibgc can be run in parallel with these other - models. Most of the 'p's stand for particulate, though a lot of them - stand for phosphorus. So, for example, jprod_pip is the production rate - of particulate idealized phosphorus through the uptake of iPO4. - - Tracer units are generally in mol kg-1, with some exceptions (suntan, - ideal_n, Fe). - - A general note on parameter values: - Pretty much all of the parameter values were selected ad hoc, from very - loose principles. They were not particularly well 'tuned' to match any - given circulation model, though they gave reasonable results with the - 3-degree ocean model, om1p7. As such, the user should feel free to make - changes to the default values given here. - Exceptions to this are: gas exchange parameters, radiocarbon decay, - nutrient stoichiometry, fractionation factors. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
field_manager_mod
mpp_mod
fms_mod
fms_io_mod
time_manager_mod
time_interp_external_mod
mpp_domains_mod
constants_mod
ocean_tpm_util_mod
fm_util_mod
ocean_types_mod
ocmip2_co2calc_mod
coupler_types_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -ocean_ibgc_bbc:
- -- -ocean_ibgc_end:
- -- -ocean_ibgc_restart:
- -- -ocean_ibgc_sbc:
- -- -ocean_ibgc_flux_init:
- -- -ocean_ibgc_init:
- -- -ocean_ibgc_init_sfc:
- -- -ocean_ibgc_sum_sfc:
- -- -ocean_ibgc_zero_sfc:
- -- -ocean_ibgc_avg_sfc:
- -- -ocean_ibgc_sfc_end:
- -- -ocean_ibgc_source:
- -- -ocean_ibgc_start:
- -- -ocean_ibgc_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays for quantities with unknown dimensions. - These are arrays that only exist temporarily. -
-
-
-- - -
-ocean_ibgc_bbc
--
-- -DESCRIPTION -
-- - This sets up the boundary conditions at the bottom of the water - column. Here, this does nothing and is just a placeholder. -
-
-
-- - -
-ocean_ibgc_end
--
-- -DESCRIPTION -
-- - Clean up various quantities for this run. This includes writing out - additional information to ensure reproduction across restarts. -
-
-
-- - -
-ocean_ibgc_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_ibgc_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions. This includes things - like gas exchange, atmospheric deposition, and riverine inputs. -
-
-
-- - -
-ocean_ibgc_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocean_ibgc_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocean_ibgc_init_sfc
--
-- -DESCRIPTION -
-- - - SURFACE GAS FLUXES - - This subroutine coordinates the calculation of gas solubilities in the surface layer, - and sends the appropriate values to the coupler. - - First, for CO2 and 14CO2, the carbon solubility and speciation are calculated by the - subroutine co2calc, following the OCMIP2 protocol. These calculations are both made - using total CO2, following which the surface CO2 concentration (CO2*, also known as - H2CO3*) is scaled by the DI14C/DIC ratio to give the surface 14CO2 concentration. - The speciation calculation uses in situ temperature, salinity, idealized PO4 and - idealized SiO4 (which must be scaled to real SiO4 units, since I'm using PO4 units - for iSiO4). - Oxygen solubility is calculated here, using in situ temperature and salinity. - - The actual gas fluxes will be calculated in the coupler using a piston velocity (Kw), - Flux = Kw * (alpha - csurf) - and returned as elements of ice_ocean_boundary_fluxes%bc in the ocean_ibgc_sbc - subroutine. -
-
-
-- - -
-ocean_ibgc_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations. -
-
-
-- - -
-ocean_ibgc_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations. -
-
-
-- - -
-ocean_ibgc_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations. -
-
-
-- - -
-ocean_ibgc_sfc_end
--
-- -DESCRIPTION -
-- - Finish up stuff for surface fields for flux calculations. -
-
-
-- - -
-ocean_ibgc_source
--
-- -DESCRIPTION -
-- - Compute the source terms for the ideal nutrients, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocean_ibgc_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants for a given run - and allocate diagnostic arrays -
-
-
-- - -
-ocean_ibgc_tracer
--
-- -DESCRIPTION -
-- - Perform things that should be done in tracer, but are done here - in order to minimize the number of hooks necessary in the MOM4 basecode. - - Here, it is used only to set the values of preformed iPO4 and iDIC in - the mixed layer. - -
-
-
-
-NAMELIST
- --&ocean_ibgc_nml --
-
----
-- -do_ideal -
-- If true, then do ideal_n and suntan. This does not require any other - part of the model. -
-
-[logical] -- -do_po4 -
-- If true, then do the non-Fe-limited P cycle, iPO4 and iDOP. If either - this or do_po4f is true, PO4_pre and chl will be calculated as well. If - both do_po4 and do_po4f are true, po4 will be the master variable, - unless bgc_felim is true. -
-
-[logical] -- -do_po4f -
-- If true, then do the Fe-limited P cycle, with iFe, iPO4f and DOP. If - either this or do_po4 is true, PO4_pre and chl will be calculated as well. - If both do_po4 and do_po4f are true, po4 will be the master variable, - unless do_bgc_felim is true. -
-
-[logical] -- -do_bgc_felim -
-- If true, then use PO4f as the master variable for biogeochemical - calculations (gases, PO4_pre, chl, isotopes). Requires that do_PO4f be true. -
-
-[logical] -- -do_gasses -
-- If true, then do the gases Dissolved Inorganic Carbon (iDIC) and oxygen - (iO2). Requires that do_po4 and/or do_po4f be true. -
-
-[logical] -- -do_carbon_comp -
-- If true, then do the dissolved inorganic carbon component tracers, - Saturation DIC (iDIC_sat) and preformed DIC (iDIC_pre). Requires - that do_po4 and/or do_po4f be true, and that do_gasses be true. -
-
-[logical] -- -do_radiocarbon -
-- If true, then do the radiocarbon tracers (iDI14C and iDO14C). Requires - that do_po4 and/or do_po4f be true, and that do_gasses be true. -
-
-[logical] -- -do_isio4 -
-- If true, then do silica cycle and silicon isotopes, iSiO4 and i30SiO4. -
-
-[logical] -- -do_no3_iso -
-- If true, then do NO3 isotopes, i15NO3, iN18O3 and iDO15N. Requires that - do_po4 and/or do_po4f be true. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - The basic nutrient uptake equations will be described in an upcoming paper - by Galbraith et al. (in prep.). The remainder of the biogeochemistry - module may be documented more officially elsewhere. All are welcome to use - ibgc model output for the purposes of publication; however, please contact - Eric Galbraith (Eric.Galbraith@mcgill.ca) for the appropriate reference. -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocean_pert_co2.F90 b/src/mom5/ocean_bgc/ocean_pert_co2.F90 index 738f685076..b3d32b3ec8 100644 --- a/src/mom5/ocean_bgc/ocean_pert_co2.F90 +++ b/src/mom5/ocean_bgc/ocean_pert_co2.F90 @@ -146,8 +146,8 @@ module ocean_pert_co2_mod integer :: package_index logical :: module_initialized = .false. -character(len=128) :: version = '$Id: ocean_pert_co2.F90,v 1.1.2.1 2012/05/15 15:55:19 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocean_pert_co2.F90,v 20.0 2013/12/14 00:09:34 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' ! Calculated parameters (with possible initial input values): ! diff --git a/src/mom5/ocean_bgc/ocean_pert_co2.html b/src/mom5/ocean_bgc/ocean_pert_co2.html deleted file mode 100644 index e5d8750467..0000000000 --- a/src/mom5/ocean_bgc/ocean_pert_co2.html +++ /dev/null @@ -1,334 +0,0 @@ - - - -Module ocean_pert_co2_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_pert_co2_mod
- - - - - -
-OVERVIEW
- -- Ocean perturbation CO2 module, based on Sarmiento, Orr and Siegenthaler, 1992 -
- - - -- Implementation of routines to solve the Ocean perturbation CO2 - simulations as outlined by "A Perturbation Simulation of - CO2 Uptake in an Ocean General Circulation Model", Jorge L. Sarmiento, - James C. Orr and Ulrich Siegenthaler, 1992, JGR, 97, - pp 3621-3645. --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
diag_manager_mod
field_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
constants_mod
ocean_tpm_util_mod
fm_util_mod
coupler_types_mod
ocean_types_mod
ocmip2_co2calc_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -ocean_pert_co2_bbc:
- -- -ocean_pert_co2_end:
- -- -ocean_pert_co2_sbc:
- -- -ocean_pert_co2_flux_init:
- -- -ocean_pert_co2_init:
- -- -ocean_pert_co2_init_sfc:
- -- -ocean_pert_co2_sum_sfc:
- -- -ocean_pert_co2_zero_sfc:
- -- -ocean_pert_co2_avg_sfc:
- -- -ocean_pert_co2_sfc_end:
- -- -ocean_pert_co2_source:
- -- -ocean_pert_co2_start:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-ocean_pert_co2_bbc
--
-- -DESCRIPTION -
-- - calculate the surface boundary conditions -
-
-
-- - -
-ocean_pert_co2_end
--
-- -DESCRIPTION -
-- - Clean up various quantities for this run. -
-
-
-- - -
-ocean_pert_co2_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions -
-
-
-- - -
-ocean_pert_co2_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocean_pert_co2_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocean_pert_co2_init_sfc
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocean_pert_co2_start -
-
-
-- - -
-ocean_pert_co2_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_pert_co2_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_pert_co2_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_pert_co2_sfc_end
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations -
-
-
-- - -
-ocean_pert_co2_source
--
-- -DESCRIPTION -
-- - compute the source terms, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocean_pert_co2_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
-
-
-
-REFERENCES
- ----
-- - A Perturbation Simulation of - CO2 Uptake in an Ocean General Circulation Model, Jorge L. Sarmiento, - James C. Orr and Ulrich Siegenthaler, 1992, JGR, 97, - pp 3621-3645. -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocean_po4_pre.F90 b/src/mom5/ocean_bgc/ocean_po4_pre.F90 index 92db5b4ec4..51aba1c18f 100644 --- a/src/mom5/ocean_bgc/ocean_po4_pre.F90 +++ b/src/mom5/ocean_bgc/ocean_po4_pre.F90 @@ -131,8 +131,8 @@ module ocean_po4_pre_mod integer :: package_index logical :: module_initialized = .false. -character(len=128) :: version = '$Id: ocean_po4_pre.F90,v 1.1.2.1 2012/05/15 15:55:19 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocean_po4_pre.F90,v 20.0 2013/12/14 00:09:36 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' type(po4_pre_type), allocatable, dimension(:) :: po4_pre integer :: instances diff --git a/src/mom5/ocean_bgc/ocean_po4_pre.html b/src/mom5/ocean_bgc/ocean_po4_pre.html deleted file mode 100644 index 80313f3c13..0000000000 --- a/src/mom5/ocean_bgc/ocean_po4_pre.html +++ /dev/null @@ -1,424 +0,0 @@ - - - -Module ocean_po4_pre_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_po4_pre_mod
- - - - - -
-OVERVIEW
- -- Add-on ocean biogeochemistry module -
- - - -- This module has simple implementation of preformed phosphate. - Where, - po4_pre=po4, if z <= mld - - It is an optional package that requires TOPAZ, ocmip2_biotic, or ocean_bgc_restore to be running. - - Various mixed layer depth options are available and can be - set via namelist - - 1 = kpp mixed layer (default) - 2 = buoyancy criteria defined mixed layer, where this buoyancy - references in situ density - 3 = buoyancy criteria defined mixed layer, where this buoyancy - references potential density - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
mpp_mod
fms_mod
time_manager_mod
mpp_domains_mod
ocean_tpm_util_mod
fm_util_mod
ocean_types_mod
ocean_tracer_diag_mod
diag_manager_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -ocean_po4_pre_bbc:
- -- -ocean_po4_pre_end:
- -- -ocean_po4_pre_sbc:
- -- -ocean_po4_pre_flux_init:
- -- -ocean_po4_pre_init:
- -- -ocean_po4_pre_init_sfc:
- -- -ocean_po4_pre_sum_sfc:
- -- -ocean_po4_pre_zero_sfc:
- -- -ocean_po4_pre_avg_sfc:
- -- -ocean_po4_pre_sfc_end:
- -- -ocean_po4_pre_source:
- -- -ocean_po4_pre_start:
- -- -ocean_po4_pre_tracer:
- -- -set_array:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-ocean_po4_pre_bbc
--
-- -DESCRIPTION -
-- - calculate the surface boundary conditions -
-
-
-- - -
-ocean_po4_pre_end
--
-- -DESCRIPTION -
-- - Clean up various PO4_PRE quantities for this run. -
-
-
-- - -
-ocean_po4_pre_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions -
-
-
-- - -
-ocean_po4_pre_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocean_po4_pre_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocean_po4_pre_init_sfc
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocean_po4_pre_start -
-
-
-- - -
-ocean_po4_pre_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_po4_pre_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_po4_pre_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocean_po4_pre_sfc_end
--
-- -DESCRIPTION -
-- - Finish up stuff for surface fields for flux calculations -
-
-
-- - -
-ocean_po4_pre_source
--
-- -DESCRIPTION -
-- - compute the source terms for the PO4_PREs, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocean_po4_pre_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants for a given run - and allocate diagnostic arrays -
-
-
-- - -
-ocean_po4_pre_tracer
--
-- -DESCRIPTION -
-- - Perform things that should be done in tracer, but are done here - in order to minimize the number of hooks necessary in the MOM4 basecode -
-
-
-- - -
-set_array
--
-- -DESCRIPTION -
-- - Set up an array covering the model domain with a user-specified - value, in user-specified regions. There are a given number of - 2-d regions specified by the values slat, nlat, wlon and elon. - The longitudes are for a cyclic domain, and if wlon and elon - are on opposite sides of the cut, the correct thing will - be done. Elon is considered to be east of wlon, so if elon is - less than wlon, then the region east of elon to the cut will be - filled, and the region from the cut to wlon will be filled. - - After setting up the array in this routine, it may prove useful - to allow fine-tuning the settings via an array in a namelist. - - Arguments: - Input: - num_regions = number of user-specified regions which will be - filled - - wlon = 1-d array of western (starting) longitudes for the - rectangular regions - - elon = 1-d array of eastern (ending) longitudes for the - rectangular regions - - slat = 1-d array of southern (starting) latitudes for the - rectangular regions - - nlat = 1-d array of northern (ending) latitudes for the - rectangular regions - - Note: if slat >= nlat, then nothing is done - for that region - - set_value = the value to assign to array in the user-specified - regions - - unset_value = the value to assign to array outside of the - user-specified regions - - name = character variable used in informative messages - - coastal_only = true to limit changes only to coastal points - (i.e., at least one bordering point is land) - - Output: - - array = 2-d array which will contain the set- and unset- - values. The array is assumed to have a border - one unit wide on all edges, ala MOM. A cyclic - boundary condition will be set if requested. -
-
-
-
-REFERENCES
- ----
-- - No reference yet. -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocmip2_abiotic.F90 b/src/mom5/ocean_bgc/ocmip2_abiotic.F90 index 37869e56f5..e41b712574 100644 --- a/src/mom5/ocean_bgc/ocmip2_abiotic.F90 +++ b/src/mom5/ocean_bgc/ocmip2_abiotic.F90 @@ -178,8 +178,8 @@ module ocmip2_abiotic_mod integer :: package_index logical :: module_initialized = .false. -character(len=128) :: version = '$Id: ocmip2_abiotic.F90,v 1.1.2.1 2012/05/15 15:55:19 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocmip2_abiotic.F90,v 20.0 2013/12/14 00:09:38 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' ! Input parameters: ! diff --git a/src/mom5/ocean_bgc/ocmip2_abiotic.html b/src/mom5/ocean_bgc/ocmip2_abiotic.html deleted file mode 100644 index 363299d27d..0000000000 --- a/src/mom5/ocean_bgc/ocmip2_abiotic.html +++ /dev/null @@ -1,374 +0,0 @@ - - - -Module ocmip2_abiotic_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocmip2_abiotic_mod
- - - - - -
-OVERVIEW
- -- Ocean Carbon Model Intercomparison Study II: Abiotic module -
- - - -- Implementation of routines to solve the OCMIP-2 Abiotic - simulations as outlined in the Abiotic-HOWTO documentation, - revision 1.7, 1999/10/05. --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
diag_manager_mod
field_manager_mod
fms_mod
fms_io_mod
mpp_mod
time_interp_external_mod
mpp_domains_mod
constants_mod
ocean_tpm_util_mod
fm_util_mod
coupler_types_mod
ocean_types_mod
ocmip2_co2calc_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -ocmip2_abiotic_bbc:
- -- -ocmip2_abiotic_end:
- -- -ocmip2_abiotic_restart:
- -- -ocmip2_abiotic_sbc:
- -- -ocmip2_abiotic_flux_init:
- -- -ocmip2_abiotic_init:
- -- -ocmip2_abiotic_init_sfc:
- -- -ocmip2_abiotic_sum_sfc:
- -- -ocmip2_abiotic_zero_sfc:
- -- -ocmip2_abiotic_avg_sfc:
- -- -ocmip2_abiotic_sfc_end:
- -- -ocmip2_abiotic_source:
- -- -ocmip2_abiotic_start:
- -- -ocmip2_abiotic_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-ocmip2_abiotic_bbc
--
-- -DESCRIPTION -
-- - calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_abiotic_end
--
-- -DESCRIPTION -
-- - Clean up various ABIOTIC quantities for this run. -
-
-
-- - -
-ocmip2_abiotic_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocmip2_abiotic_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_abiotic_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocmip2_abiotic_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocmip2_abiotic_init_sfc
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocmip2_abiotic_start -
-
-
-- - -
-ocmip2_abiotic_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_abiotic_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_abiotic_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_abiotic_sfc_end
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations -
-
-
-- - -
-ocmip2_abiotic_source
--
-- -DESCRIPTION -
-- - compute the source terms for the ABIOTICs, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocmip2_abiotic_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
-
-
-- - -
-ocmip2_abiotic_tracer
--
-- -DESCRIPTION -
-- - Perform things that should be done in tracer, but are done here - in order to minimize the number of hooks necessary in the MOM4 basecode -
-
-
-
-REFERENCES
- ----
-- - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Abiotic/HOWTO-Abiotic.html -
-- - Press, W. H., S. A. Teukosky, W. T. Vetterling, B. P. Flannery, 1992. - Numerical Recipes in FORTRAN, Second Edition, Cambridge University Press. -
-- - Enting, I.G., T. M. L. Wigley, M. Heimann, 1994. Future Emissions - and concentrations of carbon dioxide: key ocean / atmosphere / - land analyses, CSIRO Aust. Div. Atmos. Res. Tech. Pap. No. 31, - 118 pp. -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocmip2_biotic.F90 b/src/mom5/ocean_bgc/ocmip2_biotic.F90 index 298d492f0f..9c28da6069 100644 --- a/src/mom5/ocean_bgc/ocmip2_biotic.F90 +++ b/src/mom5/ocean_bgc/ocmip2_biotic.F90 @@ -253,8 +253,8 @@ module ocmip2_biotic_mod integer :: package_index logical :: module_initialized = .false. -character(len=128) :: version = '$Id: ocmip2_biotic.F90,v 1.1.2.1 2012/05/15 15:55:20 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocmip2_biotic.F90,v 20.0 2013/12/14 00:09:40 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' ! Input parameters: ! diff --git a/src/mom5/ocean_bgc/ocmip2_biotic.html b/src/mom5/ocean_bgc/ocmip2_biotic.html deleted file mode 100644 index 5385246b07..0000000000 --- a/src/mom5/ocean_bgc/ocmip2_biotic.html +++ /dev/null @@ -1,455 +0,0 @@ - - - -Module ocmip2_biotic_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocmip2_biotic_mod
- - - - - -
-OVERVIEW
- -- Ocean Carbon Model Intercomparison Study II: Biotic module -
- - - -- Implementation of routines to solve the OCMIP-2 Biotic - simulations as outlined in the Biotic-HOWTO documentation, - revision 1.7, 1999/10/05. --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
diag_manager_mod
field_manager_mod
fms_mod
fms_io_mod
mpp_mod
time_interp_external_mod
mpp_domains_mod
constants_mod
ocean_tpm_util_mod
fm_util_mod
coupler_types_mod
ocean_types_mod
ocmip2_co2calc_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -locate:
- -- -ocmip2_biotic_bbc:
- -- -ocmip2_biotic_end:
- -- -ocmip2_biotic_restart:
- -- -ocmip2_biotic_sbc:
- -- -ocmip2_biotic_flux_init:
- -- -ocmip2_biotic_init:
- -- -ocmip2_biotic_init_sfc:
- -- -ocmip2_biotic_sum_sfc:
- -- -ocmip2_biotic_zero_sfc:
- -- -ocmip2_biotic_avg_sfc:
- -- -ocmip2_biotic_sfc_end:
- -- -ocmip2_biotic_source:
- -- -ocmip2_biotic_start:
- -- -set_array:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-locate
--
-- -DESCRIPTION -
-- - After Numerical recipes: - - Given an array XX of length N, and a given value of X, returns a - value of J such that X is between XX(J) and XX(J+1). XX must be - monotonic, either increasing or decreasing. J=0 or J=N is - returned to indicate that X is out of range. - New features: - - If "period" is specified, then the array, xx, is considered - to be periodic with a period of "period". If "x_in" is out - of range, then add or subtract "period" once to attempt to - make "x_in" be in range. - - If "nearest" is specified, and true, then return "j" such - that it is the element of "xx" which is nearest to the value - of "x_in" (where "x_in" may have been modified by the value - "period", above). With this option, "j" will be in - the range 1 <= j <= n. -
-
-
-- - -
-ocmip2_biotic_bbc
--
-- -DESCRIPTION -
-- - calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_biotic_end
--
-- -DESCRIPTION -
-- - Clean up various BIOTIC quantities for this run. -
-
-
-- - -
-ocmip2_biotic_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocmip2_biotic_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_biotic_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocmip2_biotic_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocmip2_biotic_init_sfc
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocmip2_biotic_start -
-
-
-- - -
-ocmip2_biotic_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_biotic_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_biotic_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_biotic_sfc_end
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations -
-
-
-- - -
-ocmip2_biotic_source
--
-- -DESCRIPTION -
-- - compute the source terms for the BIOTICs, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocmip2_biotic_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
-
-
-- - -
-set_array
--
-- -DESCRIPTION -
-- - Set up an array covering the model domain with a user-specified - value, in user-specified regions. There are a given number of - 2-d regions specified by the values slat, nlat, wlon and elon. - The longitudes are for a cyclic domain, and if wlon and elon - are on opposite sides of the cut, the correct thing will - be done. Elon is considered to be east of wlon, so if elon is - less than wlon, then the region east of elon to the cut will be - filled, and the region from the cut to wlon will be filled. - - After setting up the array in this routine, it may prove useful - to allow fine-tuning the settings via an array in a namelist. - - Arguments: - Input: - num_regions = number of user-specified regions which will be - filled - - wlon = 1-d array of western (starting) longitudes for the - rectangular regions - - elon = 1-d array of eastern (ending) longitudes for the - rectangular regions - - slat = 1-d array of southern (starting) latitudes for the - rectangular regions - - nlat = 1-d array of northern (ending) latitudes for the - rectangular regions - - Note: if slat >= nlat, then nothing is done - for that region - - set_value = the value to assign to array in the user-specified - regions - - unset_value = the value to assign to array outside of the - user-specified regions - - name = character variable used in informative messages - - coastal_only = true to limit changes only to coastal points - (i.e., at least one bordering point is land) - - Output: - - array = 2-d array which will contain the set- and unset- - values. The array is assumed to have a border - one unit wide on all edges, ala MOM. A cyclic - boundary condition will be set if requested. -
-
-
-
-REFERENCES
- ----
-- - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Biotic/HOWTO-Biotic.html -
-- - Press, W. H., S. A. Teukosky, W. T. Vetterling, B. P. Flannery, 1992. - Numerical Recipes in FORTRAN, Second Edition, Cambridge University Press. -
-- - Enting, I.G., T. M. L. Wigley, M. Heimann, 1994. Future Emissions - and concentrations of carbon dioxide: key ocean / atmosphere / - land analyses, CSIRO Aust. Div. Atmos. Res. Tech. Pap. No. 31, - 118 pp. -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocmip2_cfc.F90 b/src/mom5/ocean_bgc/ocmip2_cfc.F90 index a7da4986e9..ea8ac5c581 100644 --- a/src/mom5/ocean_bgc/ocmip2_cfc.F90 +++ b/src/mom5/ocean_bgc/ocmip2_cfc.F90 @@ -145,8 +145,8 @@ module ocmip2_cfc_mod integer :: indsal integer :: indtemp -character(len=128) :: version = '$Id: ocmip2_cfc.F90,v 1.1.2.1 2012/05/15 15:55:20 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocmip2_cfc.F90,v 20.0 2013/12/14 00:09:42 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' contains diff --git a/src/mom5/ocean_bgc/ocmip2_cfc.html b/src/mom5/ocean_bgc/ocmip2_cfc.html deleted file mode 100644 index 0c5118539b..0000000000 --- a/src/mom5/ocean_bgc/ocmip2_cfc.html +++ /dev/null @@ -1,329 +0,0 @@ - - - -Module ocmip2_cfc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocmip2_cfc_mod
- - - - - -
-OVERVIEW
- -- Ocean Carbon Model Intercomparison Study II: CFC module -
- - - -- Implementation of routines to solve the OCMIP-2 CFC - simulations as outlined in the CFC-HOWTO documentation, - revision 1.6, 1999/04/29. --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
diag_manager_mod
field_manager_mod
fms_mod
ocean_tpm_util_mod
constants_mod
fm_util_mod
mpp_mod
coupler_types_mod
ocean_types_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -ocmip2_cfc_bbc:
- -- -ocmip2_cfc_end:
- -- -ocmip2_cfc_sbc:
- -- -ocmip2_cfc_flux_init:
- -- -ocmip2_cfc_init:
- -- -ocmip2_cfc_init_sfc:
- -- -ocmip2_cfc_sum_sfc:
- -- -ocmip2_cfc_zero_sfc:
- -- -ocmip2_cfc_avg_sfc:
- -- -ocmip2_cfc_sfc_end:
- -- -ocmip2_cfc_source:
- -- -ocmip2_cfc_start:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-ocmip2_cfc_bbc
--
-- -DESCRIPTION -
-- - calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_cfc_end
--
-- -DESCRIPTION -
-- - Clean up various CFC quantities for this run. -
-
-
-- - -
-ocmip2_cfc_sbc
--
-- -DESCRIPTION -
-- - Calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_cfc_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocmip2_cfc_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocmip2_cfc_init_sfc
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocmip2_cfc_start -
-
-
-- - -
-ocmip2_cfc_sum_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_cfc_zero_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_cfc_avg_sfc
--
-- -DESCRIPTION -
-- - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_cfc_sfc_end
--
-- -DESCRIPTION -
-- - Initialize surface fields for flux calculations -
-
-
-- - -
-ocmip2_cfc_source
--
-- -DESCRIPTION -
-- - compute the source terms for the CFCs, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) -
-
-
-- - -
-ocmip2_cfc_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
-
-
-
-REFERENCES
- ----
-- - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/CFC/HOWTO-CFC.html -
-
- -
--top -- - diff --git a/src/mom5/ocean_bgc/ocmip2_co2calc.F90 b/src/mom5/ocean_bgc/ocmip2_co2calc.F90 index 3be4abd732..fa3ac5ee7f 100644 --- a/src/mom5/ocean_bgc/ocmip2_co2calc.F90 +++ b/src/mom5/ocean_bgc/ocmip2_co2calc.F90 @@ -47,8 +47,8 @@ module ocmip2_co2calc_mod public :: ocmip2_co2calc public :: ocmip2_co2_alpha -character(len=128) :: version = '$Id: ocmip2_co2calc.F90,v 1.1.2.1 2012/05/15 15:55:20 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocmip2_co2calc.F90,v 20.0 2013/12/14 00:09:44 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' contains diff --git a/src/mom5/ocean_bgc/ocmip2_co2calc.html b/src/mom5/ocean_bgc/ocmip2_co2calc.html deleted file mode 100644 index 50e50c43c5..0000000000 --- a/src/mom5/ocean_bgc/ocmip2_co2calc.html +++ /dev/null @@ -1,258 +0,0 @@ - - - -Module ocmip2_co2calc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocmip2_co2calc_mod
- - - - - -
-OVERVIEW
- -- Surface fCO2 calculation -
- - - -- Calculate the fugacity of CO2 at the surface in thermodynamic - equilibrium with the current alkalinity (Alk) and total dissolved - inorganic carbon (DIC) at a particular temperature and salinity - using an initial guess for the total hydrogen - ion concentration (htotal) --
- - -
-OTHER MODULES USED
- -- -- - - -
-PUBLIC INTERFACE
----
-- -ocmip2_co2_alpha:
- -- -ocmip2_co2calc:
- -- -drtsafe:
- -- -ta_iter_1:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocmip2_co2_alpha
--
-- -DESCRIPTION -
-- - Calculate CO2 solubility, alpha, from - temperature (t) and salinity (s). - - INPUT - - isd = first i-limit of the arrays with halo - ied = last i-limit of the arrays with halo - jsd = first j-limit of the arrays with halo - jed = last j-limit of the arrays with halo - isc = first i-limit of the arrays for computation - iec = last i-limit of the arrays for computation - jsc = first j-limit of the arrays for computation - jec = last j-limit of the arrays for computation - - t = temperature (degrees C) - - s = salinity (PSU) - - mask = land mask array (0.0 = land) - - OUTPUT - alpha = Solubility of CO2 for air? (mol/kg/atm unless scaled) - - IMPORTANT: Some words about units - (JCO, 4/4/1999) - - - Models may carry tracers in mol/m^3 (on a per volume basis) - - - Conversely, this routine, which was written by observationalists - (C. Sabine and R. Key), passes input arguments in umol/kg - (i.e., on a per mass basis) - - - Thus, if the input or output units need to be changed from/to mol/m^3 - then set scale to an appropriate value. For example, if the model - uses mol/m^3, then scale should be set to something like 1.0/1024.5 - to convert from mol/m^3 to mol/kg. - -
-
-
-- - -
-ocmip2_co2calc
--
-- -DESCRIPTION -
-- - Calculate co2* from total alkalinity and total CO2 at - temperature (t) and salinity (s). - It is assumed that init_ocmip2_co2calc has already been called with - the T and S to calculate the various coefficients. - - INPUT - - isd = first i-limit of the arrays with halo - ied = last i-limit of the arrays with halo - jsd = first j-limit of the arrays with halo - jed = last j-limit of the arrays with halo - isc = first i-limit of the arrays for computation - iec = last i-limit of the arrays for computation - jsc = first j-limit of the arrays for computation - jec = last j-limit of the arrays for computation - - mask = land mask array (0.0 = land) - - t = temperature (degrees C) - - s = salinity (PSU) - - dic_in = total inorganic carbon (mol/kg unless scaled) - where 1 T = 1 metric ton = 1000 kg - - ta_in = total alkalinity (eq/kg unless scaled) - - pt_in = inorganic phosphate (mol/kg unless scaled) - - sit_in = inorganic silicate (mol/kg unless scaled) - - htotallo = factor to set lower limit of htotal range - - htotalhi = factor to set upper limit of htotal range - - htotal = H+ concentraion - - OUTPUT - co2star = CO2*water (kg/kg unless scaled) - alpha = Solubility of CO2 for air? (kg/kg/atm unless scaled) - pco2surf = oceanic pCO2 (ppmv) - - k1 = activity factors for carbonate species - - k2 (see below) - - invtk = 1/(t+273.15) - - IMPORTANT: Some words about units - (JCO, 4/4/1999) - - - Models may carry tracers in mol/m^3 (on a per volume basis) - - - Conversely, this routine, which was written by observationalists - (C. Sabine and R. Key), passes input arguments in umol/kg - (i.e., on a per mass basis) - - - Thus, if the input or output units need to be changed from/to mol/m^3 - then set scale to an appropriate value. For example, if the model - uses mol/m^3, then scale should be set to something like 1.0/1024.5 - to convert from mol/m^3 to mol/kg. - -
-
-
-- - -
-drtsafe
--
-- -DESCRIPTION -
-- - File taken from Numerical Recipes. Modified R. M. Key 4/94 -
-
-
-- - -
-ta_iter_1
--
-- -DESCRIPTION -
-- - This routine expresses TA as a function of DIC, htotal and constants. - It also calculates the derivative of this function with respect to - htotal. It is used in the iterative solution for htotal. In the call - "x" is the input value for htotal, "fn" is the calculated value for TA - and "df" is the value for dTA/dhtotal -
-
-
-
--top -- - diff --git a/src/mom5/ocean_bgc/ocmip2_he.F90 b/src/mom5/ocean_bgc/ocmip2_he.F90 index 53f278ab5a..36a09c5e34 100644 --- a/src/mom5/ocean_bgc/ocmip2_he.F90 +++ b/src/mom5/ocean_bgc/ocmip2_he.F90 @@ -162,8 +162,8 @@ module ocmip2_he_mod integer :: indsal integer :: indtemp -character(len=128) :: version = '$Id: ocmip2_he.F90,v 1.1.2.1 2012/05/15 15:55:20 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocmip2_he.F90,v 20.0 2013/12/14 00:09:46 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' integer :: src_he3_id character*128 :: src_he3_file diff --git a/src/mom5/ocean_bgc/ocmip2_he.html b/src/mom5/ocean_bgc/ocmip2_he.html deleted file mode 100644 index f87c8772d5..0000000000 --- a/src/mom5/ocean_bgc/ocmip2_he.html +++ /dev/null @@ -1,386 +0,0 @@ - - - -Module ocmip2_he_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocmip2_he_mod
- - --Contact: Jennifer Simeon - -- - -
-Reviewers: Eric Galbraith -, - Daniele Bianchi - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean Carbon Model Intercomparison Study II: HE module -
- - - -- Implementation of routines to solve the OCMIP-2 HE - simulations as outlined in the Helium-HOWTO documentation, - revision 1.6, 1999/04/29. - Modified Jan 2008 b1d. Separated atmospheric and mantle component - and added a factor to chance the source strength --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
time_interp_external_mod
diag_manager_mod
field_manager_mod
fms_mod
fms_io_mod
ocean_tpm_util_mod
fm_util_mod
mpp_mod
coupler_types_mod
ocean_types_mod
mpp_domains_mod
atmos_ocean_fluxes_mod
-PUBLIC INTERFACE
----
-- -allocate_arrays:
- -- -ocmip2_he_bbc:
- -- -ocmip2_he_end:
- -- -ocmip2_he_restart:
- -- -ocmip2_he_sbc:
- -- -ocmip2_he_flux_init:
- -- -ocmip2_he_init:
- -- -ocmip2_he_init_sfc:
- -- -ocmip2_he_sum_sfc:
- -- -ocmip2_he_zero_sfc:
- -- -ocmip2_he_avg_sfc:
- -- -ocmip2_he_sfc_end:
- -- -ocmip2_he_source:
- -- -ocmip2_he_start:
- -- -ocmip2_he_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-allocate_arrays
--
-- -DESCRIPTION -
-- - Dynamically allocate arrays -
-
-
-- - -
-ocmip2_he_bbc
--
-- -DESCRIPTION -
-- - Called each time-step - calculate the bottom boundary conditions -
-
-
-- - -
-ocmip2_he_end
--
-- -DESCRIPTION -
-- - Called once at the end of the run - Clean up various HE quantities for this run. -
-
-
-- - -
-ocmip2_he_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocmip2_he_sbc
--
-- -DESCRIPTION -
-- - Called each time-step - Calculate the surface boundary conditions -
-
-
-- - -
-ocmip2_he_flux_init
--
-- -DESCRIPTION -
-- - Called once at the beginning of the run - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocmip2_he_init
--
-- -DESCRIPTION -
-- - Called once at the beginning of the run - Set up any extra fields needed by the tracer packages - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocmip2_he_init_sfc
--
-- -DESCRIPTION -
-- - Called once at the beginning of the run - Initialize surface fields for flux calculations - -
-
-
-- - -
-ocmip2_he_sum_sfc
--
-- -DESCRIPTION -
-- - Called for FMS coupler - ocean_tpm_sum_sfc: Accumulate data for the coupler - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_he_zero_sfc
--
-- -DESCRIPTION -
-- - Zero out the fields for the coupler to allow - for accumulation for the next time period -
-
-
-- - -
-ocmip2_he_avg_sfc
--
-- -DESCRIPTION -
-- - Called for FMS coupler - ocean_tpm_avg_sfc: Take the time-mean of the fields for the coupler - Sum surface fields for flux calculations -
-
-
-- - -
-ocmip2_he_sfc_end
--
-- -DESCRIPTION -
-- - Called for FMS coupler - ocean_tpm_sfc_end: Save out fields for the restart. -
-
-
-- - -
-ocmip2_he_source
--
-- -DESCRIPTION -
-- - compute the source terms for the HEs, including boundary - conditions (not done in setvbc, to minimize number - of hooks required in MOM base code) - As described by J-C Dutay et al.'s Helium HOWTO. - Mantle Helium has a source due to emission of helium rich waters - along ocean ridges on the seafloor. Globally integrated, the source - term amounts to 1000 moles of He-3 per year. Regionally, sources are - partitioned as a function of ridge position, length and spreading rate. - A loss term exists in the air-sea flux of mantle helium. - - The loss term is calculated in the subroutine ocmip2_he_sbc. -
-
-
-- - -
-ocmip2_he_start
--
-- -DESCRIPTION -
-- - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
-
-
-- - -
-ocmip2_he_tracer
--
-- -DESCRIPTION -
-- - Perform things that should be done in tracer, but are done here - in order to minimize the number of hooks necessary in the MOM4 basecode -
-
-
-
-REFERENCES
- ----
-- - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Helium/HOWTO-Helium.html -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob.F90 b/src/mom5/ocean_blobs/ocean_blob.F90 index b8a5e805fa..7dc24c56f6 100644 --- a/src/mom5/ocean_blobs/ocean_blob.F90 +++ b/src/mom5/ocean_blobs/ocean_blob.F90 @@ -208,7 +208,7 @@ module ocean_blob_mod ! CVS stuff character(len=128) :: version = '$$' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character (len=128) :: tagname = '$Name: tikal $' ! initialisation logical :: module_is_initialized=.false. diff --git a/src/mom5/ocean_blobs/ocean_blob.html b/src/mom5/ocean_blobs/ocean_blob.html deleted file mode 100644 index 8710b81e39..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob.html +++ /dev/null @@ -1,513 +0,0 @@ - - - -Module ocean_blob_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_blob_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This is the main "driver" module for the Lagrangian blob scheme. This - module calls other modules that contain the individual parameterisations. - - Please note that the preprocessor option MOM_STATIC_ARRAYS is NOT - supported. This is because to run a model where the memeory statically - allocated without the blob framework will incur a large, unnecessary - increase in memory requirements. -
- - - -- This module is the top-level module of the Lagrangian blob framework. - It calls routines to form blobs, to integrate their properties, to - transfer them from one dynamic regime to another, and also calculates - the L system contribution towards grid cell thickness. - - This module also handles some framework wide variables, mostly - associated with system wide diagnostics and the system wide accounting - required to ensure the Eulerian model and the Lagrangian model can coexist. - - It should be noted that many of the parameterisations are not mutually - exclusive. As such, care should be excercised when creating namelists - for experiments. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_blob_diag_mod
ocean_blob_dynamic_bottom_mod
ocean_blob_dynamic_free_mod
ocean_blob_static_free_mod
ocean_blob_static_bottom_mod
ocean_blob_util_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_blob_init:
- -- -init_blob_thickness:
- -- -ocean_blob_update:
- -- -ocean_blob_cell_update:
- -- -update_L_thickness:
- -- -calculate_rhoT:
- -- -ocean_blob_implicit:
- -- -adjust_L_thickness:
- -- -ocean_blob_diagnose_depth:
- -- -ocean_blob_end:
- -- -write_all_blobs:
- -- -entrainment_checksum:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_blob_init
--
-- -DESCRIPTION -
-- - Initialises the Lagrangian blob module by setting up module wide - variables and calling initialisation scripts for the related modules, - as well as the Lagrangian system itself. - - Infrastructure for communicating between PE's, interpolation of E - system variables to a blob, communicating model wide namelist values - and variables to other modules and picking up restarts is all done. -
-
-
-- - -
-init_blob_thickness
--
-- -DESCRIPTION -
-- - Initialises the L_system thickness, based on the existing blobs -
-
-
-- - -
-ocean_blob_update
--
-- -DESCRIPTION -
-- - Updates the Lagrangian blobs by calling routines that run during the - explicit in time part of the time step. -
-
-
-- - -
-ocean_blob_cell_update
--
-- -DESCRIPTION -
-- - - For bottom blobs, it diagnoses the blobs vertical position in the - models native vertical coordinate. - - For free blobs, it searches for the vertical grid cell that a free - blob resides in. - - We require the information regarding the vertical grid cell that a - blob resides in prior to the calculation of total grid cell thickness - and prior to the calculation of the vertical advection velocity. - - In order to figure out which grid cell the blob is in, we need to - employ different strategies for different coordinate system (see notes - for details). - - For any blobs that penetrate the free surface (which is unlikely, but - not impossible) we immediately kill them, returning their properties - to the surface grid cell of the (i,j) column that they belong to. - - We recalculate a blobs density and volume for taup1, based on the pressure - at the centre of the grid cell that it resides in. - -
-
-
-- - -
-update_L_thickness
--
-- -DESCRIPTION -
-- - Calculates the contribution to thickness of all the blobs for the - L system arrays in the Thickness strcture. - - The mass per unit area from the blobs is also calculated for the - upper and lower part of each grid cell and stored in the L_system - structure. The calculate of mass per unit area is required for - pressure calculations. - - We note that in DEPTH_BASED models, the value for density used is - rho0, while it is the actual density in PRESSURE_BASED models. For - the L_system mass per unit area, the actual density is used for - all supported coordinates. -
-
-
-- - -
-calculate_rhoT
--
-- -DESCRIPTION -
-- - Calculates the density of the combined E and L systems. - - It needs to be done here so that the blobs are taken into account. - -
-
-
-- - -
-ocean_blob_implicit
--
-- -DESCRIPTION -
-- - Updates the Lagrangian blobs by calling routines that run during the - implicit in time part of the time step. -
-
-
-- - -
-adjust_L_thickness
--
-- -DESCRIPTION -
-- - blob_thickness is called after new blobs are formed implicitly in - time. blob_thickness provides the same function as - update_L_thickness, with a couple of subtle differences. - - At the point that this routine is called, we: - 1/ Know the vertical position of an "old" blob relative to the geoid - and in the Eulerian model's native vertical coordinate. We do - not know a blobs depth relative to the sea surface. - 2/ Know the vertical position relative to the sea surface for "new" - blobs, but we do not know its position relative to the geoid or in - the Euerlian model's native vertical coordinate. - - So, blob_thickness uses the logical new, which is part of the blob - derived type, to distinguish between new blobs and old blobs. New - blobs have their position (upper or lower part of a grid cell) - calculated using the depth relative to the sea surface height, while - blobs that are not new have their position calculated using the - Eulerian models native coordinate. - - The accumulation of thickness and mass per unit area are done in the - same was as is done in update_L_thickness. -
-
-
-- - -
-ocean_blob_diagnose_depth
--
-- -DESCRIPTION -
-- - When blobs are created implicitly in time, the sea surface height has - not been calcualted in pressure based models (but depth has). However, - the prognostic variable for blobs is the geodepth and not the depth. So, - for a new blob, we set the depth when it is formed and then calculate - the geodepth here. For existing blobs, we diagnose the depth using - eta_t and geodepth. - - We note that in GEOPOTENTIAL coordinates, depth and geodepth are - equivalent, and so we set them to be equivalent for the blobs too. -
-
-
-- - -
-ocean_blob_end
--
-- -DESCRIPTION -
-- - Writes restarts and do checksums for the blobs at the end of a run. -
-
-
-- - -
-write_all_blobs
--
-- -DESCRIPTION -
-- - A convenient subroutine for debugging that dumps blob details from - every list -
-
-
-- - -
-entrainment_checksum
--
-- -DESCRIPTION -
-- - Do the entrainment checksums -
-
-
-
-NAMELIST
- --&ocean_blob_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. - Default is use_this_module=.false. -
-
-[logical] -- -debug_this_module -
-- Writes additional diagnostic data to fms.out. This - also controls debug output for the other related blob - modules. - Default is debug_this_module=.false. -
-
-[logical] -- -really_debug -
-- Be careful what you wish for, this outputs A LOT of - diagnostics to standard out! - Default is debug_this_module=.false. -
-
-[logical] -- -do_bitwise_exact_sum -
-- When global sum outputs are done there is additional - computational expense to ensure that they are bitwise - the same across an arbitrary number of processors. - However, for debugging purposes, it can be useful - for global sums to be the same. Note, that this differs - from bitwise_reproduction in that it do_bitwise_exact_sum - only applies to the mpp_global_sum diagnostic. - Note that this flag controls the output for all associated - blob modules. - Default is do_bitwise_exact_sum=.false. -
-
-[logical] -- -bitwise_reproduction -
-- There is additional cost involved in ensuring that - results are reproducable across an arbitrary number of - processors and across restarts. - Bitwise reproduction is a very memory intensive operation and should - only be used for debugging. For bitwise_reproduction=.true. We need - to process blobs and their histories in the same relative order - regardless of domain decomposition and restarts. To do so, we save the - "history" of each blob subcycle is saved to a number of arrays (which - can be a very memory intensive process) and process them in order. - Note that this flag controls reproducability for all associated - blob modules. - Bitwise reproducibility is only possible with the appropriate - compiler flags AND when the simulation is run on hardware that is - capable of producing bitwise reproduction. - Default is bitwise_reproduction=.false. -
-
-[logical] -- -blob_small_mass -
-- Will delete blobs of mass less than blob_small_mass. - Note that this variable is for all associated blob - modules. The deletion of blobs is a conservative - action, any mass/tracer fields that are nonzero - have the remaining properties transferred back to the - Eulerian system. So, in principle, blob_small_mass - can actually be a relatively large number, and the - model will remain conservative. It has been found in - certain test cases (with very low tracer values) that - setting blob_small_mass to be very small (i.e. <1e2) - that roundoff error can cause non-trivial errors. So, - it is recommended that blob_small_mass be no smaller than - than 1e3 kg (which is approximately 1.0m**3 -- a very small - blob!) - Default is blob_small_mass=1.e3 -
-
-[real, units: kg] -- -mass_prop_thickness -
-- Sets the maximum proportion of a grid cell that the - Lagrangian system may occupy. This is actually calculated - separately (and therefore must be satisfied separately) for - the uppper and lower portions of a grid cell. - Default is blob_small_mass=0.7 -
-
-[real, units: dimensionless] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, Elements of MOM4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob.xml b/src/mom5/ocean_blobs/ocean_blob.xml deleted file mode 100644 index 9db8c3d09c..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob.xml +++ /dev/null @@ -1,187 +0,0 @@ - - -diff --git a/src/mom5/ocean_blobs/ocean_blob_diag.html b/src/mom5/ocean_blobs/ocean_blob_diag.html deleted file mode 100644 index d054ecdb66..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_diag.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - This is the main "driver" module for the Lagrangian blob scheme. This - module calls other modules that contain the individual parameterisations. - - Please note that the preprocessor option MOM_STATIC_ARRAYS is NOT - supported. This is because to run a model where the memeory statically - allocated without the blob framework will incur a large, unnecessary - increase in memory requirements. - - This module is the top-level module of the Lagrangian blob framework. - It calls routines to form blobs, to integrate their properties, to - transfer them from one dynamic regime to another, and also calculates - the L system contribution towards grid cell thickness. - - This module also handles some framework wide variables, mostly - associated with system wide diagnostics and the system wide accounting - required to ensure the Eulerian model and the Lagrangian model can coexist. - - It should be noted that many of the parameterisations are not mutually - exclusive. As such, care should be excercised when creating namelists - for experiments. - - S.M. Griffies, Elements of MOM4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory - - Must be true to use this module. - Default is use_this_module=.false. - - Writes additional diagnostic data to fms.out. This - also controls debug output for the other related blob - modules. - Default is debug_this_module=.false. - - Be careful what you wish for, this outputs A LOT of - diagnostics to standard out! - Default is debug_this_module=.false. - - When global sum outputs are done there is additional - computational expense to ensure that they are bitwise - the same across an arbitrary number of processors. - However, for debugging purposes, it can be useful - for global sums to be the same. Note, that this differs - from bitwise_reproduction in that it do_bitwise_exact_sum - only applies to the mpp_global_sum diagnostic. - Note that this flag controls the output for all associated - blob modules. - Default is do_bitwise_exact_sum=.false. - - There is additional cost involved in ensuring that - results are reproducable across an arbitrary number of - processors and across restarts. - Bitwise reproduction is a very memory intensive operation and should - only be used for debugging. For bitwise_reproduction=.true. We need - to process blobs and their histories in the same relative order - regardless of domain decomposition and restarts. To do so, we save the - "history" of each blob subcycle is saved to a number of arrays (which - can be a very memory intensive process) and process them in order. - Note that this flag controls reproducability for all associated - blob modules. - Bitwise reproducibility is only possible with the appropriate - compiler flags AND when the simulation is run on hardware that is - capable of producing bitwise reproduction. - Default is bitwise_reproduction=.false. - - Will delete blobs of mass less than blob_small_mass. - Note that this variable is for all associated blob - modules. The deletion of blobs is a conservative - action, any mass/tracer fields that are nonzero - have the remaining properties transferred back to the - Eulerian system. So, in principle, blob_small_mass - can actually be a relatively large number, and the - model will remain conservative. It has been found in - certain test cases (with very low tracer values) that - setting blob_small_mass to be very small (i.e. <1e2) - that roundoff error can cause non-trivial errors. So, - it is recommended that blob_small_mass be no smaller than - than 1e3 kg (which is approximately 1.0m**3 -- a very small - blob!) - Default is blob_small_mass=1.e3 - - Sets the maximum proportion of a grid cell that the - Lagrangian system may occupy. This is actually calculated - separately (and therefore must be satisfied separately) for - the uppper and lower portions of a grid cell. - Default is blob_small_mass=0.7 - - Initialises the Lagrangian blob module by setting up module wide - variables and calling initialisation scripts for the related modules, - as well as the Lagrangian system itself. - - Infrastructure for communicating between PE's, interpolation of E - system variables to a blob, communicating model wide namelist values - and variables to other modules and picking up restarts is all done. - - Initialises the L_system thickness, based on the existing blobs - - Updates the Lagrangian blobs by calling routines that run during the - explicit in time part of the time step. - - - For bottom blobs, it diagnoses the blobs vertical position in the - models native vertical coordinate. - - For free blobs, it searches for the vertical grid cell that a free - blob resides in. - - We require the information regarding the vertical grid cell that a - blob resides in prior to the calculation of total grid cell thickness - and prior to the calculation of the vertical advection velocity. - - In order to figure out which grid cell the blob is in, we need to - employ different strategies for different coordinate system (see notes - for details). - - For any blobs that penetrate the free surface (which is unlikely, but - not impossible) we immediately kill them, returning their properties - to the surface grid cell of the (i,j) column that they belong to. - - We recalculate a blobs density and volume for taup1, based on the pressure - at the centre of the grid cell that it resides in. - - - Calculates the contribution to thickness of all the blobs for the - L system arrays in the Thickness strcture. - - The mass per unit area from the blobs is also calculated for the - upper and lower part of each grid cell and stored in the L_system - structure. The calculate of mass per unit area is required for - pressure calculations. - - We note that in DEPTH_BASED models, the value for density used is - rho0, while it is the actual density in PRESSURE_BASED models. For - the L_system mass per unit area, the actual density is used for - all supported coordinates. - - Calculates the density of the combined E and L systems. - - It needs to be done here so that the blobs are taken into account. - - - Updates the Lagrangian blobs by calling routines that run during the - implicit in time part of the time step. - - blob_thickness is called after new blobs are formed implicitly in - time. blob_thickness provides the same function as - update_L_thickness, with a couple of subtle differences. - - At the point that this routine is called, we: - 1/ Know the vertical position of an "old" blob relative to the geoid - and in the Eulerian model's native vertical coordinate. We do - not know a blobs depth relative to the sea surface. - 2/ Know the vertical position relative to the sea surface for "new" - blobs, but we do not know its position relative to the geoid or in - the Euerlian model's native vertical coordinate. - - So, blob_thickness uses the logical new, which is part of the blob - derived type, to distinguish between new blobs and old blobs. New - blobs have their position (upper or lower part of a grid cell) - calculated using the depth relative to the sea surface height, while - blobs that are not new have their position calculated using the - Eulerian models native coordinate. - - The accumulation of thickness and mass per unit area are done in the - same was as is done in update_L_thickness. - - When blobs are created implicitly in time, the sea surface height has - not been calcualted in pressure based models (but depth has). However, - the prognostic variable for blobs is the geodepth and not the depth. So, - for a new blob, we set the depth when it is formed and then calculate - the geodepth here. For existing blobs, we diagnose the depth using - eta_t and geodepth. - - We note that in GEOPOTENTIAL coordinates, depth and geodepth are - equivalent, and so we set them to be equivalent for the blobs too. - - Writes restarts and do checksums for the blobs at the end of a run. - - A convenient subroutine for debugging that dumps blob details from - every list - - Do the entrainment checksums - Module ocean_blob_diag_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_blob_diag_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Controls the diagnostic output from individual blobs. -
- - - -- Controls the diagnostics from individual blobs. Blob diagnostics - are snapshots at full E system time steps of blob properties. There is - no averaging of individual blob properties. The properties that can be - output are set in a diagnostic file. The name of the diagnostic file - is specified in the namelist. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_mod
ocean_blob_util_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_blob_diag_init:
- -- -blob_diag:
- -- -varid:
- -- -blob_diag_end:
- -- -write_blobs:
- -- -handle_error:
- -- -create_netcdf_file:
- -- -open_netcdf_file:
- -- -close_netcdf_file:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_blob_diag_init
--
-- -DESCRIPTION -
-- - Initialises the blob diagnostic module. -
-
-
-- - -
-blob_diag
--
-- -DESCRIPTION -
-- - Accummulates the blob diagnostics by creating a linked list of - diagnostic blobs. The blobs are kept in the linked list until - there are more than dump_num of them. Then, they are written - (using write_blobs), and erased from memory. -
-
-
-- - -
-varid
--
-- -DESCRIPTION -
-- - Reads the variable id of a netcdf file. -
-
-
-- - -
-blob_diag_end
--
-- -DESCRIPTION -
-- - -
-
-
-- - -
-write_blobs
--
-- -DESCRIPTION -
-- - Write the diagnostics of individual blobs. -
-
-
-- - -
-handle_error
--
-- -DESCRIPTION -
-- - Handles any errors from the reading/writing of netcdf files. It - should (hopefully) provide some sort of useful idea of what went - wrong. -
-
-
-- - -
-create_netcdf_file
--
-- -DESCRIPTION -
-- - Creates a new netcdf file. -
-
-
-- - -
-open_netcdf_file
--
-- -DESCRIPTION -
-- - Opens an existing netcdf file. -
-
-
-- - -
-close_netcdf_file
--
-- -DESCRIPTION -
-- - Closes an existing netcdf file. -
-
-
-
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob_diag.xml b/src/mom5/ocean_blobs/ocean_blob_diag.xml deleted file mode 100644 index 2b1fb5583c..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_diag.xml +++ /dev/null @@ -1,52 +0,0 @@ - - -diff --git a/src/mom5/ocean_blobs/ocean_blob_dynamic_bottom.html b/src/mom5/ocean_blobs/ocean_blob_dynamic_bottom.html deleted file mode 100644 index aaaea33161..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_dynamic_bottom.html +++ /dev/null @@ -1,545 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - Controls the diagnostic output from individual blobs. - - Controls the diagnostics from individual blobs. Blob diagnostics - are snapshots at full E system time steps of blob properties. There is - no averaging of individual blob properties. The properties that can be - output are set in a diagnostic file. The name of the diagnostic file - is specified in the namelist. - - Logical as to whether diagnostics should be saved or not. - Default is .false. - - Name of file to look for blob diagnostic information. - Default is "blob_diag_table" - - The number of entried to keep in memory before writing - them to file. The higher the number, the more memory that - the module will take up, but, it should lower the frequency of - IO operations. - Default is 2000000 - - The frequency (in number of E system time steps) that blob - diagnostics should be saved. - Default is 1 - - Initialises the blob diagnostic module. - - Accummulates the blob diagnostics by creating a linked list of - diagnostic blobs. The blobs are kept in the linked list until - there are more than dump_num of them. Then, they are written - (using write_blobs), and erased from memory. - - Reads the variable id of a netcdf file. - - - Write the diagnostics of individual blobs. - - Handles any errors from the reading/writing of netcdf files. It - should (hopefully) provide some sort of useful idea of what went - wrong. - - Creates a new netcdf file. - - Opens an existing netcdf file. - - Closes an existing netcdf file. - Module ocean_blob_dynamic_bottom_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_blob_dynamic_bottom_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module runs the dynamic bottom blob implementation of the embedded - Lagrangian buoyancy blob framework. The module forms new dynamic - bottom blobs, integrates the properties of existing blobs, and handles - the transfer of free blobs to bottom blobs. -
- - - -- Bottom blobs are formed using the subroutine dynamic_bottom_form_new, - which is called from the main blob driver module. Bottom blobs are - formed explicitly in time, directly after the integration of existing - blobs. - - The properties of a bottom blob are also integrated in this module, - that is, position, velocity, mass and tracer content. Position and - velocity are integrated using an adaptive step Runge-Kutta scheme. - There are several schemes available of varying order. - - The module also recieves blobs that are transferring from the free - blob dynamic regime to the bottom blob dynamic regime (i.e. free - blobs that have interacted with topography). --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_blob_util_mod
ocean_density_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -blob_dynamic_bottom_init:
- -- -blob_dynamic_bottom_update:
- -- -dynamic_update:
- -- -transfer_free_to_bottom:
- -- -dynamic_bottom_form_new:
- -- -blob_dynamic_bottom_end:
- -- -packbuffer:
- -- -unpackbuffer:
- -- -increase_buffer:
- -- -send_buffer:
- -- -receive_buffer:
- -- -clear_buffer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-blob_dynamic_bottom_init
--
-- -DESCRIPTION -
-- - Initialises the dynamic free blobs by checking the namelist and also - inherited namelists (from ocean_blob_nml). Also sets up some useful - constants (including spatially varying constants) - particularly for - the formation of bottom blobs. It also allocates memory to special - halo=2 masks and sets up the blob buffers for sending blobs from one - PE to another. -
-
-
-- - -
-blob_dynamic_bottom_update
--
-- -DESCRIPTION -
-- - This routine calls the routine to update blob positions. When - bitwise_reproduction=.false., it also figures out when to continue - the integration of blobs that have changed PE's. -
-
-
-- - -
-dynamic_update
--
-- -DESCRIPTION -
-- - This routine contains the RK scheme used to integrate the position - and velocity of blobs. It also does many checks for (and - subsequently handles) things like grounding of blobs, blobs going to - different PEs, blobs that separate from topography, blobs that - detrain to less than small_mass and blobs going outside the compute - domain. - - It also does the interpolation of E system variables to a blob. -
-
-
-- - -
-transfer_free_to_bottom
--
-- -DESCRIPTION -
-- - Takes free blobs that have interacted with topography and turns them - into bottom blobs. -
-
-
-- - -
-dynamic_bottom_form_new
--
-- -DESCRIPTION -
-- - Initialises blobs that are formed when an on-shelf/off-shelf - instability occurs. The method used for determining an instability - and the initial conditions are based on that of Campin and Goosse - (1999). - - When the density difference between the shallow ocean cell and the - deep ocean cell (referenced to the deep ocean cell) exceeds the - namelist variable rho_threshold, a blob is formed. The deep ocean - cell is chosen based on which deep ocean cell (in the k plane) - the blob topography intersects. - - After formation, the new blobs are added to the bottom blob linked - list, and, their properties are integrated, starting at time taup1. -
-
-
-- - -
-blob_dynamic_bottom_end
--
-- -DESCRIPTION -
-- - Clears memory to give a nice clean ending to the run. -
-
-
-- - -
-packbuffer
--
-- -DESCRIPTION -
-- - Packs a buffer with all the information needed to send a blob from - one PE to another. -
-
-
-- - -
-unpackbuffer
--
-- -DESCRIPTION -
-- - Unpacks a received buffer. -
-
-
-- - -
-increase_buffer
--
-- -DESCRIPTION -
-- - Increases the buffer size for sending blobs from one PE to another. -
-
-
-- - -
-send_buffer
--
-- -DESCRIPTION -
-- - Sends a buffer to an adjoining PE -
-
-
-- - -
-receive_buffer
--
-- -DESCRIPTION -
-- - Receives a buffer from an adjoining PE -
-
-
-- - -
-clear_buffer
--
-- -DESCRIPTION -
-- - Clears the contents of a buffer -
-
-
-
-NAMELIST
- --&ocean_blob_dynamic_bottom_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. - Default is use_this_module=.false. -
-
-[logical] -- -blob_overflow_mu -
-- Frictional dissipation rate used for calculating initial - properties of bottom blobs. Corresponds to mu in Campin and - Goosse (1999). Units are 1/s. - Default is blob_overflow_mu=1.0e-4 -
-
-[real] -- -blob_overflow_delta -
-- Fraction of a grid cell participating in an overflow event. - Corresponds to delta in Campin and Goosse (1999). Dimensionless. - Default is blob_overflow_mu=1.0e-4 -
-
-[real] -- -drag -
-- Coefficient of drag used for bottom stress drag. - Corresponds to Cd in Price and Baringer (1994). Dimensionless. - Default is drag=3.0e-3 -
-
-[real] -- -det_param -
-- The detrainment parameter (kg m^2/s). - Corresponds to Gamma in the notes. - Default is det_param=5.0e-8 - -
-
-[real] -- -max_detrainment -
-- The Maximum allowable detrainment velocity (m/s). - Default is max_detrainment=1.0e-3 -
-
-[real] -- -rel_error -
-- Relative error for the RK scheme (dimensionless). - A smaller number is more accurate, but, - is more computationally expensive. Corresponds to - zeta* in the notes. - Must be 0<rel_error<=1.0 - Default is rel_error=0.01 -
-
-[real] -- -safety_factor -
-- Safety factor for the RK scheme (dimensionless). - A smaller number should reduce the number - of rejected steps, but, decreases the locally - extrapolated step. Corresponds to varrho in - the notes. - Must be 0<safety_factor<=1.0 - Default is safety_factor=0.8 -
-
-[real] -- -minstep -
-- Minimum step size (in seconds) for a blob. - Default is minstep=9.0 -
-
-[real] -- -elastic -
-- The elasticity of a blob's collision with - the topography. Corresponds to epsilon in - the notes. Should have values 0<=elastic<=1.0 - Values greater than 1 would be super-elastic, - and values less than 0 would send the blob - in the opposite direction than it should be - going in. - Default is elastic=1.0 -
-
-[real] -- -min_do_levels -
-- Minimum number of deep ocean levels for - overflows to be considered. That is, how many - k levels lower should the deep ocean water column - be than the shelf/shallow ocean column. Value - must be greater than 0. - Default is min_do_levels=1 -
-
-[integer] -- -rho_threshold -
-- The density difference required before a blob - is formed. rho_threshold must be greater than - zero. - Default is rho_threshold=0.01 -
-
-[real] -- -large_speed -
-- A value for error checking. If the speed of a - blob exceeds large_speed in any of x,y,z then - a warning flag is raised. - Default is large_speed=10.0 -
-
-[real] -- -no_rotation -
-- Sets the coriolis parameter to zero regardless - of latitude - Default is no_rotation=.false. -
-
-[real] -- -critical_richardson -
-- The critical Richardson number for the entrainment - velocity. Default is based on Price and Baringer - (1994). - Default is critical_richardson=0.8 -
-
-[real] -
- - - - -
-REFERENCES
- ----
-- - Price, J.F., Baringer, M.O'N. (1994) Outflows and deep water production - by marginal seas. Progress in Oceanography 33(3), 161-200. -
-- - Campin, J-.M., Goosse, H. (1999) Parameterization of a density-driven - downsloping flow for a coarse-resolution ocean model in z-coordinate. - Tellus 51A(3), 412-430. -
-- - Bogacki, P., Shampine, L.F. (1989) A 3(2) pair of Runge-Kutta formulas. - Applied Mathematical Letters 2(4), 321-325. -
-- - Cash, J.R., Karp, A.H. (1990) A variable order Runge-Kutta method for - initial value problems with rapidly varying right-hand sides. - ACM Transactions on Mathematical Software 16(3), 201-222. -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob_dynamic_bottom.xml b/src/mom5/ocean_blobs/ocean_blob_dynamic_bottom.xml deleted file mode 100644 index 3f803d07d4..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_dynamic_bottom.xml +++ /dev/null @@ -1,168 +0,0 @@ - - -diff --git a/src/mom5/ocean_blobs/ocean_blob_dynamic_free.html b/src/mom5/ocean_blobs/ocean_blob_dynamic_free.html deleted file mode 100644 index 5b373c87fd..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_dynamic_free.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - This module runs the dynamic bottom blob implementation of the embedded - Lagrangian buoyancy blob framework. The module forms new dynamic - bottom blobs, integrates the properties of existing blobs, and handles - the transfer of free blobs to bottom blobs. - - Bottom blobs are formed using the subroutine dynamic_bottom_form_new, - which is called from the main blob driver module. Bottom blobs are - formed explicitly in time, directly after the integration of existing - blobs. - - The properties of a bottom blob are also integrated in this module, - that is, position, velocity, mass and tracer content. Position and - velocity are integrated using an adaptive step Runge-Kutta scheme. - There are several schemes available of varying order. - - The module also recieves blobs that are transferring from the free - blob dynamic regime to the bottom blob dynamic regime (i.e. free - blobs that have interacted with topography). - - Price, J.F., Baringer, M.O'N. (1994) Outflows and deep water production - by marginal seas. Progress in Oceanography 33(3), 161-200. - - Campin, J-.M., Goosse, H. (1999) Parameterization of a density-driven - downsloping flow for a coarse-resolution ocean model in z-coordinate. - Tellus 51A(3), 412-430. - - Bogacki, P., Shampine, L.F. (1989) A 3(2) pair of Runge-Kutta formulas. - Applied Mathematical Letters 2(4), 321-325. - - Cash, J.R., Karp, A.H. (1990) A variable order Runge-Kutta method for - initial value problems with rapidly varying right-hand sides. - ACM Transactions on Mathematical Software 16(3), 201-222. - - Must be true to use this module. - Default is use_this_module=.false. - - Frictional dissipation rate used for calculating initial - properties of bottom blobs. Corresponds to mu in Campin and - Goosse (1999). Units are 1/s. - Default is blob_overflow_mu=1.0e-4 - - Fraction of a grid cell participating in an overflow event. - Corresponds to delta in Campin and Goosse (1999). Dimensionless. - Default is blob_overflow_mu=1.0e-4 - - Coefficient of drag used for bottom stress drag. - Corresponds to Cd in Price and Baringer (1994). Dimensionless. - Default is drag=3.0e-3 - - The detrainment parameter (kg m^2/s). - Corresponds to Gamma in the notes. - Default is det_param=5.0e-8 - - - The Maximum allowable detrainment velocity (m/s). - Default is max_detrainment=1.0e-3 - - Relative error for the RK scheme (dimensionless). - A smaller number is more accurate, but, - is more computationally expensive. Corresponds to - zeta* in the notes. - Must be 0<rel_error<=1.0 - Default is rel_error=0.01 - - Safety factor for the RK scheme (dimensionless). - A smaller number should reduce the number - of rejected steps, but, decreases the locally - extrapolated step. Corresponds to varrho in - the notes. - Must be 0<safety_factor<=1.0 - Default is safety_factor=0.8 - - Minimum step size (in seconds) for a blob. - Default is minstep=9.0 - - The elasticity of a blob's collision with - the topography. Corresponds to epsilon in - the notes. Should have values 0<=elastic<=1.0 - Values greater than 1 would be super-elastic, - and values less than 0 would send the blob - in the opposite direction than it should be - going in. - Default is elastic=1.0 - - Minimum number of deep ocean levels for - overflows to be considered. That is, how many - k levels lower should the deep ocean water column - be than the shelf/shallow ocean column. Value - must be greater than 0. - Default is min_do_levels=1 - - The density difference required before a blob - is formed. rho_threshold must be greater than - zero. - Default is rho_threshold=0.01 - - A value for error checking. If the speed of a - blob exceeds large_speed in any of x,y,z then - a warning flag is raised. - Default is large_speed=10.0 - - Sets the coriolis parameter to zero regardless - of latitude - Default is no_rotation=.false. - - The critical Richardson number for the entrainment - velocity. Default is based on Price and Baringer - (1994). - Default is critical_richardson=0.8 - - Initialises the dynamic free blobs by checking the namelist and also - inherited namelists (from ocean_blob_nml). Also sets up some useful - constants (including spatially varying constants) - particularly for - the formation of bottom blobs. It also allocates memory to special - halo=2 masks and sets up the blob buffers for sending blobs from one - PE to another. - - This routine calls the routine to update blob positions. When - bitwise_reproduction=.false., it also figures out when to continue - the integration of blobs that have changed PE's. - - This routine contains the RK scheme used to integrate the position - and velocity of blobs. It also does many checks for (and - subsequently handles) things like grounding of blobs, blobs going to - different PEs, blobs that separate from topography, blobs that - detrain to less than small_mass and blobs going outside the compute - domain. - - It also does the interpolation of E system variables to a blob. - - Takes free blobs that have interacted with topography and turns them - into bottom blobs. - - Initialises blobs that are formed when an on-shelf/off-shelf - instability occurs. The method used for determining an instability - and the initial conditions are based on that of Campin and Goosse - (1999). - - When the density difference between the shallow ocean cell and the - deep ocean cell (referenced to the deep ocean cell) exceeds the - namelist variable rho_threshold, a blob is formed. The deep ocean - cell is chosen based on which deep ocean cell (in the k plane) - the blob topography intersects. - - After formation, the new blobs are added to the bottom blob linked - list, and, their properties are integrated, starting at time taup1. - - Clears memory to give a nice clean ending to the run. - - Packs a buffer with all the information needed to send a blob from - one PE to another. - - Unpacks a received buffer. - - Increases the buffer size for sending blobs from one PE to another. - - Sends a buffer to an adjoining PE - - Receives a buffer from an adjoining PE - - Clears the contents of a buffer - Module ocean_blob_dynamic_free_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_blob_dynamic_free_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module runs the dynamic free blob implementation of the embedded - Lagrangian blob framework. The module forms new dynamic free blobs, - integrates the properties of existing blobs, and handles the transfer - of bottom blobs to free blobs. -
- - - -- Free blobs are formed using the subroutine blob_dynamic_free_implicit, - which is called from the blob driver module. Free blobs must be formed - implicitly in time so that the surface forcing has already been applied. - - The properties of free blobs are also integrated in this module, that is, - position, velocity, mass and tracer content. Position and velocity are - integrated using an adaptive step Runge-Kutta scheme. There are several - schemes available of varying order. - - The module also receives blobs that are transferring from the bottom - blob dynamic regime to the free blob regime (i.e. they have separated - from the bottom boundary). --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_blob_util_mod
ocean_density_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -blob_dynamic_free_init:
- -- -blob_dynamic_free_implicit:
- -- -blob_dynamic_free_update:
- -- -dynamic_update:
- -- -transfer_bottom_to_free:
- -- -blob_dynamic_free_end:
- -- -packbuffer:
- -- -unpackbuffer:
- -- -increase_buffer:
- -- -send_buffer:
- -- -receive_buffer:
- -- -clear_buffer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-blob_dynamic_free_init
--
-- -DESCRIPTION -
-- - Initialises the dynamic free blobs by checking the namelist and also - inherited namelists (from ocean_blob_nml). Also sets up some useful - constants, allocates memory to special halo=2 masks and sets up - the blob buffers for sending blobs from one PE to another. -
-
-
-- - -
-blob_dynamic_free_implicit
--
-- -DESCRIPTION -
-- - Initialises dynamic blobs in vertical statically unstable regions. - Due to the instability condition, blobs should be formed after the - surface forcing has been applied (which is a major source of - instability in the water column). The surface forcing is applied - implicitly in time in MOM, therefore, we must form blobs implicitly - in time. - - If N^2<bv_freq_threshold, then, two blobs are formed. One rising - and one sinking. The rising blobs is destroyed immediately (after - it has been moved up one cell) and its properties returned to the E - system. The sinking blob is added to a linked list, and its - properties integrated at a later time step. -
-
-
-- - -
-blob_dynamic_free_update
--
-- -DESCRIPTION -
-- - This routine calls the routine to update blob positions. When - bitwise_reproduction=.false., it also figures out when to continue - the integration of blobs that have changed PE's. -
-
-
-- - -
-dynamic_update
--
-- -DESCRIPTION -
-- - This routine contains the RK scheme used to integrate the position - and velocity of blobs. It also does many checks for (and - subsequently handles) things like grounding of blobs, blobs going to - different PEs, blobs that interact with topography, blobs that - detrain to less than small_mass and blobs going outside the compute - domain. - - It also does the interpolation of E system variables to a blob. -
-
-
-- - -
-transfer_bottom_to_free
--
-- -DESCRIPTION -
-- - Takes bottom blobs that have separated from the bottom boundary and - turns it into a free blob. -
-
-
-- - -
-blob_dynamic_free_end
--
-- -DESCRIPTION -
-- - Clears memory to give a nice clean ending to the run. -
-
-
-- - -
-packbuffer
--
-- -DESCRIPTION -
-- - Packs a buffer with all the information needed to send a blob from - one PE to another. -
-
-
-- - -
-unpackbuffer
--
-- -DESCRIPTION -
-- - Unpacks a received buffer. -
-
-
-- - -
-increase_buffer
--
-- -DESCRIPTION -
-- - Increases the buffer size for sending blobs from one PE to another. -
-
-
-- - -
-send_buffer
--
-- -DESCRIPTION -
-- - Sends a buffer to an adjoining PE -
-
-
-- - -
-receive_buffer
--
-- -DESCRIPTION -
-- - Receives a buffer from an adjoining PE -
-
-
-- - -
-clear_buffer
--
-- -DESCRIPTION -
-- - Clears the contents of a buffer -
-
-
-
-REFERENCES
- ----
-- - Bogacki, P., Shampine, L.F., (1989) A 3(2) pair of Runge-Kutta formulas. - Applied Mathematical Letters 2(4), 321-325. -
-- - Cash, J.R., Karp, A.H. (1990) A variable order Runge-Kutta method for - initial value problems with rapidly varying right-hand sides. - ACM Transactions on Mathematical Software 16(3), 201-222. -
-- - Griffies, S.M., Harrison, M.J., Pacanowski, R.C., Rosati, A. (2004) - A Technical Guide to MOM4. GFDL Ocean Group Technical Report No. 5. - NOAA/Geophysical Fluid Dynamics Laboratory. -
-- - Marshall, J., Schott, F. (1999) Open-ocean convection: Observations, theory, - and models. Reviews of Geophysics 37(1), 1-64. -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob_dynamic_free.xml b/src/mom5/ocean_blobs/ocean_blob_dynamic_free.xml deleted file mode 100644 index 56fc3144bd..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_dynamic_free.xml +++ /dev/null @@ -1,150 +0,0 @@ - - -diff --git a/src/mom5/ocean_blobs/ocean_blob_static_bottom.html b/src/mom5/ocean_blobs/ocean_blob_static_bottom.html deleted file mode 100644 index be577db17c..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_static_bottom.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - This module runs the dynamic free blob implementation of the embedded - Lagrangian blob framework. The module forms new dynamic free blobs, - integrates the properties of existing blobs, and handles the transfer - of bottom blobs to free blobs. - - Free blobs are formed using the subroutine blob_dynamic_free_implicit, - which is called from the blob driver module. Free blobs must be formed - implicitly in time so that the surface forcing has already been applied. - - The properties of free blobs are also integrated in this module, that is, - position, velocity, mass and tracer content. Position and velocity are - integrated using an adaptive step Runge-Kutta scheme. There are several - schemes available of varying order. - - The module also receives blobs that are transferring from the bottom - blob dynamic regime to the free blob regime (i.e. they have separated - from the bottom boundary). - - Bogacki, P., Shampine, L.F., (1989) A 3(2) pair of Runge-Kutta formulas. - Applied Mathematical Letters 2(4), 321-325. - - Cash, J.R., Karp, A.H. (1990) A variable order Runge-Kutta method for - initial value problems with rapidly varying right-hand sides. - ACM Transactions on Mathematical Software 16(3), 201-222. - - Griffies, S.M., Harrison, M.J., Pacanowski, R.C., Rosati, A. (2004) - A Technical Guide to MOM4. GFDL Ocean Group Technical Report No. 5. - NOAA/Geophysical Fluid Dynamics Laboratory. - - Marshall, J., Schott, F. (1999) Open-ocean convection: Observations, theory, - and models. Reviews of Geophysics 37(1), 1-64. - - Must be true to use this module. - Default is use_this_module=.false. - - Rayleigh drag coefficient (1/s) for new blobs that - are formed due to the vertical instability - criterion. Corresponds to alpha in the notes. - Default is rayleigh_drag_new=1.0e-5 - - Rayleigh drag coefficient (1/s) for bottom blobs - that become free blobs. Corresponds to alpha in - the notes. - Default is rayleigh_drag_bot=1.0e-7 - - Decide which method to use to integrate the - blobs. Choices are 'BS_RK3(2)' or 'CK_RK5(4)' - for the Bogaki-Shampine or Cash-Karp methods - respectively. - Default is update_method='CK_RK5(4) - - Relative error for the RK scheme (dimensionless). - A smaller number is more accurate, but, - is more computationally expensive. Corresponds to - zeta* in the notes. - Must be 0<rel_error<=1.0 - Default is rel_error=0.01 - - Safety factor for the RK scheme (dimensionless). - A smaller number should reduce the number - of rejected steps, but, decreases the locally - extrapolated step. Corresponds to varrho in - the notes. - Must be 0<safety_factor<=1.0 - Default is safety_factor=0.8 - - Minimum step size (in seconds) for a blob. - Default is minstep=9.0 - - An Adjustment for blob size, 0<size_fact<=1.0 - Corresponds to Lambda in the notes. - Default is size_fact=1.0 - - The detrainment parameter (kg m^2/s). - Corresponds to Gamma in the notes. - Default is det_param=5.0e-8 - - The Maximum allowable detrainment velocity (m/s). - Default is max_detrainment=1.0e-3 - - The buoyancy frequency threshold at which - the scheme will start to create blobs, i.e. - blobs will be formed when N^2<bv_freq_threshold - Default is bv_freq_threshold=-1.0e-15 - - Whether to use the buoyancy frequency calculated - from the combined E and L system (true) or, from - the E system only (false). - Default is full_N2=.true. - - A value for error checking. If the speed of a - blob exceeds large_speed in any of x,y,z then - a warning flag is raised. - Default is large_speed=10.0 - - Initialises the dynamic free blobs by checking the namelist and also - inherited namelists (from ocean_blob_nml). Also sets up some useful - constants, allocates memory to special halo=2 masks and sets up - the blob buffers for sending blobs from one PE to another. - - Initialises dynamic blobs in vertical statically unstable regions. - Due to the instability condition, blobs should be formed after the - surface forcing has been applied (which is a major source of - instability in the water column). The surface forcing is applied - implicitly in time in MOM, therefore, we must form blobs implicitly - in time. - - If N^2<bv_freq_threshold, then, two blobs are formed. One rising - and one sinking. The rising blobs is destroyed immediately (after - it has been moved up one cell) and its properties returned to the E - system. The sinking blob is added to a linked list, and its - properties integrated at a later time step. - - This routine calls the routine to update blob positions. When - bitwise_reproduction=.false., it also figures out when to continue - the integration of blobs that have changed PE's. - - This routine contains the RK scheme used to integrate the position - and velocity of blobs. It also does many checks for (and - subsequently handles) things like grounding of blobs, blobs going to - different PEs, blobs that interact with topography, blobs that - detrain to less than small_mass and blobs going outside the compute - domain. - - It also does the interpolation of E system variables to a blob. - - Takes bottom blobs that have separated from the bottom boundary and - turns it into a free blob. - - Clears memory to give a nice clean ending to the run. - - Packs a buffer with all the information needed to send a blob from - one PE to another. - - Unpacks a received buffer. - - Increases the buffer size for sending blobs from one PE to another. - - Sends a buffer to an adjoining PE - - Receives a buffer from an adjoining PE - - Clears the contents of a buffer - Module ocean_blob_static_bottom_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_blob_static_bottom_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Contains static bottom blob parameterisations, namely the Campin and - Goossee (1999) scheme and some variations. -
- - - -- Presently, there is only one static bottom blob scheme implemented - (although, there are three potential variants), and there are no plans - to implement any additional schemes. - - The scheme that is implemented emulates the Campin and Goossee (1999) - scheme, as well as having two additional variations for this scheme, - in which the "plumbing" is change. - - Details of the variations can be found in Bates et al. (2010) and are - controlled by the namelist options overflow_no_return and - overflow_one_return. --
- - -
-OTHER MODULES USED
- --- - - -fms_mod-
mpp_domains_mod
mpp_mod
ocean_blob_util_mod
ocean_density_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -blob_static_bottom_init:
- -- -blob_overflow_like:
- -- -blob_static_bottom_end:
- -- -allocate_buffer:
- -- -increase_buffer:
- -- -send_buffer:
- -- -receive_buffer:
- -- -clear_buffer:
- -- -deallocate_buffer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-blob_static_bottom_init
--
-- -DESCRIPTION -
-- - Initialises the static bottom blob module. -
-
-
-- - -
-blob_overflow_like
--
-- -DESCRIPTION -
-- - Run the Lagrangian blob model for the Overflow schemes. These - schemes are static schemes and uses Lagrangian blobs to transport - tracer and mass down slopes where an onshelf/offshelf instability - exists. - - This scheme is activated by setting the namelist variable - blob_overflow=.true. - - There are three flavours to this scheme, which are detailed in - sections 2.4 and 2.5 of Bates et al. for further details. The three - flavours are: - 1/ A Campin and Goosse (1999) scheme in which the full "plumbing" of - water going off shelf to the deep ocean and deep ocean waters - returning on shelf is specified (described in full in section 2.4 - of Bates et al.) - 2/ Only the lateral part of the plumbing is specified and all vertical - movement of water within the deep ocean column is taken care of - (described in full in section 2.5 of Bates et al.). This option is - activated by setting the namelist variable overflow_one_return=.true. - 3/ Only the movement of shelf water to the deep ocean column is - explicitly dealt with (described in full in section 2.5 of Bates - et al.). This option is activated by setting the namelist variable - overflow_no_return=.true. - - Other namelist variables associated with this scheme are: - blob_overflow_mu (real), which is the coefficient of friction used - used to calculate the overflow velocity, - blob_overflow_delta (real), which is the fraction of a grid cell that - participates in any one overflow event, - blob_overflow_umax (real), which is the maximum overflow velocity. - Depending on the flavour of scheme chosen and the impact that you want - it to have, typical values should be O(0.01) to O(1). -
-
-
-- - -
-blob_static_bottom_end
--
-- -DESCRIPTION -
-- - Does what is necessary to finish the run. -
-
-
-- - -
-allocate_buffer
--
-- -DESCRIPTION -
-- - Increases the buffer size for sending blobs from one PE to another. -
-
-
-- - -
-increase_buffer
--
-- -DESCRIPTION -
-- - Increases the buffer size for sending blobs from one PE to another. -
-
-
-- - -
-send_buffer
--
-- -DESCRIPTION -
-- - Sends a buffer to an adjoining PE -
-
-
-- - -
-receive_buffer
--
-- -DESCRIPTION -
-- - Receives a buffer from an adjoining PE -
-
-
-- - -
-clear_buffer
--
-- -DESCRIPTION -
-- - Clears the contents of a buffer -
-
-
-- - -
-deallocate_buffer
--
-- -DESCRIPTION -
-- - Deallocates memory from a buffer (usually at the end of a run). -
-
-
-
-NAMELIST
- --&ocean_blob_static_bottom_nml --
-
----
-- -blob_overflow -
-- if true, will use a Campin and Goosse (1999) style overflow - formulation. - Default is blob_overflow=.false. -
-
-[logical] -- -blob_overflow_mu -
-- Frictional dissipation used in blob_overflow scheme - Default is blob_overflow_mu=1.0e-4 -
-
-[real, units: 1/s] -- -blob_overflow_delta -
-- Fraction of grid cell participating in overflow - Valid values are 0<=delta<=1 - Default is blob_overflow_delta=1/3 -
-
-[real] -- -blob_overflow_umax -
-- Maximum downslope speed allowed for overflow - Default is blob_overflow_umax=0.01 -
-
-[real, units: m/s] -- -overflow_no_return -
-- When .false. creates return blobs to replicate the - original Campin and Goosse scheme. When .true. only - creates blobs that sink. See further overflow_one_return -
-
-[logical] -- -overflow_one_return -
-- Creates a single return blob when .true. Cannot be .true. - when overflow_no_return is also .true. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Bates, M.L., Griffies, S.M., England, M.H., Adcroft, A.J. (2009) - Lagrangian blobs of buoyancy embedded in Eulerian models: a framework - to parameterise vertical and downslope motion of gravitationally unstable - water parcels. Unpublished Notes. -
-- - S.M. Griffies, Elements of mom4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - Campin, J.-M., Goossee, H., 1999, Parameterization of density-driven - downsloping flow for a coarse-resolution ocean model in z-coordinate. - Tellus 51A (3), 412-430 -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob_static_bottom.xml b/src/mom5/ocean_blobs/ocean_blob_static_bottom.xml deleted file mode 100644 index 777da47073..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_static_bottom.xml +++ /dev/null @@ -1,103 +0,0 @@ - - -diff --git a/src/mom5/ocean_blobs/ocean_blob_static_free.html b/src/mom5/ocean_blobs/ocean_blob_static_free.html deleted file mode 100644 index 9d93ea67e3..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_static_free.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - Contains static bottom blob parameterisations, namely the Campin and - Goossee (1999) scheme and some variations. - - Presently, there is only one static bottom blob scheme implemented - (although, there are three potential variants), and there are no plans - to implement any additional schemes. - - The scheme that is implemented emulates the Campin and Goossee (1999) - scheme, as well as having two additional variations for this scheme, - in which the "plumbing" is change. - - Details of the variations can be found in Bates et al. (2010) and are - controlled by the namelist options overflow_no_return and - overflow_one_return. - - Bates, M.L., Griffies, S.M., England, M.H., Adcroft, A.J. (2009) - Lagrangian blobs of buoyancy embedded in Eulerian models: a framework - to parameterise vertical and downslope motion of gravitationally unstable - water parcels. Unpublished Notes. - - S.M. Griffies, Elements of mom4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory - - Campin, J.-M., Goossee, H., 1999, Parameterization of density-driven - downsloping flow for a coarse-resolution ocean model in z-coordinate. - Tellus 51A (3), 412-430 - - if true, will use a Campin and Goosse (1999) style overflow - formulation. - Default is blob_overflow=.false. - - Frictional dissipation used in blob_overflow scheme - Default is blob_overflow_mu=1.0e-4 - - Fraction of grid cell participating in overflow - Valid values are 0<=delta<=1 - Default is blob_overflow_delta=1/3 - - Maximum downslope speed allowed for overflow - Default is blob_overflow_umax=0.01 - - When .false. creates return blobs to replicate the - original Campin and Goosse scheme. When .true. only - creates blobs that sink. See further overflow_one_return - - Creates a single return blob when .true. Cannot be .true. - when overflow_no_return is also .true. - - Initialises the static bottom blob module. - - Run the Lagrangian blob model for the Overflow schemes. These - schemes are static schemes and uses Lagrangian blobs to transport - tracer and mass down slopes where an onshelf/offshelf instability - exists. - - This scheme is activated by setting the namelist variable - blob_overflow=.true. - - There are three flavours to this scheme, which are detailed in - sections 2.4 and 2.5 of Bates et al. for further details. The three - flavours are: - 1/ A Campin and Goosse (1999) scheme in which the full "plumbing" of - water going off shelf to the deep ocean and deep ocean waters - returning on shelf is specified (described in full in section 2.4 - of Bates et al.) - 2/ Only the lateral part of the plumbing is specified and all vertical - movement of water within the deep ocean column is taken care of - (described in full in section 2.5 of Bates et al.). This option is - activated by setting the namelist variable overflow_one_return=.true. - 3/ Only the movement of shelf water to the deep ocean column is - explicitly dealt with (described in full in section 2.5 of Bates - et al.). This option is activated by setting the namelist variable - overflow_no_return=.true. - - Other namelist variables associated with this scheme are: - blob_overflow_mu (real), which is the coefficient of friction used - used to calculate the overflow velocity, - blob_overflow_delta (real), which is the fraction of a grid cell that - participates in any one overflow event, - blob_overflow_umax (real), which is the maximum overflow velocity. - Depending on the flavour of scheme chosen and the impact that you want - it to have, typical values should be O(0.01) to O(1). - - Does what is necessary to finish the run. - - Increases the buffer size for sending blobs from one PE to another. - - Increases the buffer size for sending blobs from one PE to another. - - Sends a buffer to an adjoining PE - - Receives a buffer from an adjoining PE - - Clears the contents of a buffer - - Deallocates memory from a buffer (usually at the end of a run). - Module ocean_blob_static_free_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_blob_static_free_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module controls and runs the free static Lagrangian blob - parameterisations. -
- - - -- There are three available static blob schemes. None are sanctioned - for their physical integrity, but they have been important in the - development and testing of the Lagrangian framework. - - The first free static scheme emulates the NCON scheme of Cox (1984). - The second is a scheme that acts in a diffusive manner, while the third - swaps the properties of adjacent grid cells. Details of all three schemes - can be found in Bates et al. (2010). --
- - -
-OTHER MODULES USED
- --- - - -fms_mod-
ocean_blob_util_mod
ocean_density_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -blob_static_free_init:
- -- -blob_static_free:
- -- -blob_ncon_like_scheme:
- -- -blob_static_free_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-blob_static_free_init
--
-- -DESCRIPTION -
-- - Initialises the free static schemes. -
-
-
-- - -
-blob_static_free
--
-- -DESCRIPTION -
-- - A subroutine that is called by the main driver blob module, - ocean_blob_mod. The present module in turn calls the three available - static schemes. They are not mutually exclusive and so may be run - in any combination. - - Note that only the NCON-like scheme has been implemented. -
-
-
-- - -
-blob_ncon_like_scheme
--
-- -DESCRIPTION -
-- - Run the Lagrangian blob model for the NCon-like scheme. This scheme - is a static scheme and uses Lagrangian blobs to homogenise adjacent - vertical grid cells by by transferring mass and tracer between them. - - This scheme is activated by setting the namelist variable - blob_ncon_like=.true. The number of times that the domain is checked - for instability is set by the integer namelist variable ncon_blob, of - which the default value is 7. - - It is based on the original convective adjustment scheme of - Cox (1984). - - See section 2.1 of Bates et al. for further details. -
-
-
-- - -
-blob_static_free_end
--
-- -DESCRIPTION -
-- - Ends the free static module. -
-
-
-
-NAMELIST
- --&ocean_blob_static_free_nml --
-
----
-- -blob_ncon_like -
-- If true, will use NCon-like formulation. - Default blob_ncon_like = .true. -
-
-[logical] -- -blob_diff_like -
-- If true, will use the diffusion-like formulation. - Default is "blob_diff_like=.false. -
-
-[logical] -- -blob_swap_like -
-- If true, will use the swap-like formulation. - Default is blob_switch_like=.false. -
-
-[logical] -- -ncon_blob -
-- The number of times that the water column is checked and adjusted - for instability. -
-
-[integer] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, Elements of mom4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - Cox, M.D., 1984, A Primitive Equation, 3-Dimensional Model of the - Ocean. NOAA/Geophysical Fluid Dynamics Laboratory -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob_static_free.xml b/src/mom5/ocean_blobs/ocean_blob_static_free.xml deleted file mode 100644 index eb0ad38321..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_static_free.xml +++ /dev/null @@ -1,61 +0,0 @@ - - -diff --git a/src/mom5/ocean_blobs/ocean_blob_util.html b/src/mom5/ocean_blobs/ocean_blob_util.html deleted file mode 100644 index 797666aa4a..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_util.html +++ /dev/null @@ -1,644 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - This module controls and runs the free static Lagrangian blob - parameterisations. - - There are three available static blob schemes. None are sanctioned - for their physical integrity, but they have been important in the - development and testing of the Lagrangian framework. - - The first free static scheme emulates the NCON scheme of Cox (1984). - The second is a scheme that acts in a diffusive manner, while the third - swaps the properties of adjacent grid cells. Details of all three schemes - can be found in Bates et al. (2010). - - S.M. Griffies, Elements of mom4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory - - Cox, M.D., 1984, A Primitive Equation, 3-Dimensional Model of the - Ocean. NOAA/Geophysical Fluid Dynamics Laboratory - - If true, will use NCon-like formulation. - Default blob_ncon_like = .true. - - If true, will use the diffusion-like formulation. - Default is "blob_diff_like=.false. - - If true, will use the swap-like formulation. - Default is blob_switch_like=.false. - - The number of times that the water column is checked and adjusted - for instability. - - Initialises the free static schemes. - - A subroutine that is called by the main driver blob module, - ocean_blob_mod. The present module in turn calls the three available - static schemes. They are not mutually exclusive and so may be run - in any combination. - - Note that only the NCON-like scheme has been implemented. - - Run the Lagrangian blob model for the NCon-like scheme. This scheme - is a static scheme and uses Lagrangian blobs to homogenise adjacent - vertical grid cells by by transferring mass and tracer between them. - - This scheme is activated by setting the namelist variable - blob_ncon_like=.true. The number of times that the domain is checked - for instability is set by the integer namelist variable ncon_blob, of - which the default value is 7. - - It is based on the original convective adjustment scheme of - Cox (1984). - - See section 2.1 of Bates et al. for further details. - - Ends the free static module. - Module ocean_blob_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_blob_util_mod
- - --Contact: Michael L. Bates -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module contains subroutines that are common (or are likely to - need be common to future implementations) to some or all of the - various modules that run the Lagrangian blob scheme. -
- - - -- This module contains subroutines that are common (or may be common - in a future implementation) to some of the modules that make up the - blobs framework. - - Some of the subroutines contained herein perform tasks such as - performing checksums, checking a linked lists for very small blobs - (and deleting them), inserting blobs into a list, a bunch of routines - for writing blob restart and history files, grid cell search algorithms, - buffer manipulations, computations etc. - - The module has no namelist. All potential namelist variables are - controlled through the ocean_blob_mod namelist. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_domains_mod
mpp_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -blob_util_init:
- -- -blob_chksum:
- -- -lagrangian_system_chksum:
- -- -E_and_L_totals:
- -- -write_blobs:
- -- -blob_delete:
- -- -unlink_blob:
- -- -insert_blob:
- -- -count_blob:
- -- -put_att:
- -- -inq_var:
- -- -get_double:
- -- -get_int:
- -- -put_double:
- -- -put_int:
- -- -def_var:
- -- -give_error_code:
- -- -hashfun:
- -- -blob_util_end:
- -- -check_ijcell:
- -- -check_kcell:
- -- -kill_blob:
- -- -free_blob_memory:
- -- -allocate_interaction_memory:
- -- -reallocate_interaction_memory:
- -- -interp_tcoeff:
- -- -interp_ucoeff:
- -- -check_cyclic:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-blob_util_init
--
-- -DESCRIPTION -
-- - Initialises this module. -
-
-
-- - -
-blob_chksum
--
-- -DESCRIPTION -
-- - Performs global sums and checksums for all blob types (for diagnostic - purposes). -
-
-
-- - -
-lagrangian_system_chksum
--
-- -DESCRIPTION -
-- - - Performs checksums for the Lagrangian_system derived type. This is - the derived type that stores all of the "gridded" blob variables, - and is essential for the accounting required to interact with the - Eulerian model in a conservative manner. The checksums are for - diagnostic purposes. - -
-
-
-- - -
-E_and_L_totals
--
-- -DESCRIPTION -
-- - Gives a brief summary of the total mass, volume and tracer content - of the E, L and total systems. Usually used for debuggin purposes. -
-
-
-- - -
-write_blobs
--
-- -DESCRIPTION -
-- - Dumps most of the information carried around by blobs, for all blobs - in a particular list. Useful for debugging. -
-
-
-- - -
-blob_delete
--
-- -DESCRIPTION -
-- - Deletes all (nearly) zero mass blob objects from the linked list. - The size of the blobs that are deleted is controlled by the variable - blob_small_mass in the ocean_blob_nml. -
-
-
-- - -
-unlink_blob
--
-- -DESCRIPTION -
-- - Unlinks a blob from a doubly linked list. It returns pointers to - the blob, the head of the list, the (formerly) previous blob in the - list and the (formerly) next blob in the list. -
-
-
-- - -
-insert_blob
--
-- -DESCRIPTION -
-- - Inserts a blob to the linked list. The relative order of blobs in - a linked list determines whether bitwise reproduction is possible. - - Regardless of bitwise reproducability or not, we must ensure that - blobs always appear in the same relative order when we are using - dynamic blobs because if we have a situation where dztL>dztT, we - start destroying blobs to enforce dztL<dztT. In order that we do - not significantly change answers, we must always destroy the same - blob, regardless of domain decomposition, restarts, etc. So, we must - always sort blobs so they appear in the linked list in the same - relative order. -
-
-
-- - -
-count_blob
--
-- -DESCRIPTION -
-- - Allocates a blob its hash and a number. These two numbers can - uniquely identify any blob. The hash and number is based on the grid - cell of origin. Each grid cell has a unique hash. We have an array - which keeps track of the number of blobs formed in a grid cell. These - two numbers give the unique identifier. So, we also need to increment - the counter array. -
-
-
-- - -
-put_att
--
-- -DESCRIPTION -
-- - Writes an attribute to a netcdf file. -
-
-
-- - -
-inq_var
--
-- -DESCRIPTION -
-- - Gets the variable identifier from a netcdf file. -
-
-
-- - -
-get_double
--
-- -DESCRIPTION -
-- - Gets the value of a "double" variable from a netcdf file -
-
-
-- - -
-get_int
--
-- -DESCRIPTION -
-- - Gets the value of an integer variable from a netcdf file -
-
-
-- - -
-put_double
--
-- -DESCRIPTION -
-- - Writes the value of a "double" variable to a netcdf file -
-
-
-- - -
-put_int
--
-- -DESCRIPTION -
-- - Writes the value of an integer variable to a netcdf file -
-
-
-- - -
-def_var
--
-- -DESCRIPTION -
-- - Defines a netcdf variable -
-
-
-- - -
-give_error_code
--
-- -DESCRIPTION -
-- - Gives error descriptions for netcdf calls. -
-
-
-- - -
-hashfun
--
-- -DESCRIPTION -
-- - Calculates the hash -
-
-
-- - -
-blob_util_end
--
-- -DESCRIPTION -
-- - Does what is necessary to shut down the module. -
-
-
-- - -
-check_ijcell
--
-- -DESCRIPTION -
-- - Checks whether a blob (horizontally) resides in a grid cell or not. - If it does not it figures out which direction the blob is in and - checks the neighbouring grid cell, until it finds which grid cell - the blob resides in. - - It uses a cross product technique from computational geometry - (Cormen et al., 2001). -
-
-
-- - -
-check_kcell
--
-- -DESCRIPTION -
-- - Searches for which (vertical) grid cell a blob resides in). -
-
-
-- - -
-kill_blob
--
-- -DESCRIPTION -
-- - Kills a blob by returning all of its remaining properties to the E - system. -
-
-
-- - -
-free_blob_memory
--
-- -DESCRIPTION -
-- - Frees the heap memory taken up by a blob. -
-
-
-- - -
-allocate_interaction_memory
--
-- -DESCRIPTION -
-- - Allocates the history arrays for a blob (only used when - bitwise_reproduction=.true. in the ocean_blob_nml). -
-
-
-- - -
-reallocate_interaction_memory
--
-- -DESCRIPTION -
-- - Different blobs can have different history memory requirements. - When they change from one type of blob to another, we need to change - the memory allocated to a blob to reflect the new requirements. This - is only necessary if bitwise_reproduction=.true. in the ocean_blob_nml. -
-
-
-- - -
-interp_tcoeff
--
-- -DESCRIPTION -
-- - Used for the horizontal interpolation of T grid variables. The - routine returns coefficients required for inverse distance - weighting (Shephard, 1968). -
-
-
-- - -
-interp_ucoeff
--
-- -DESCRIPTION -
-- - Used for the horizontal interpolation of U grid variables. The - routine returns coefficients required for inverse distance - weighting (Shephard, 1968). -
-
-
-- - -
-check_cyclic
--
-- -DESCRIPTION -
-- - Checks and adjusts blob position and grid cell index - for cylclic/periodic domains, as well as - the Murray (1996) tripolar grid. -
-
-
-
-REFERENCES
- ----
-- - Cormen, T. H, Leiserson, C. E. Rivest, R. L., Stein, C. (2001) Introduction - to Algorithms. The MIT Press. -
-- - Shepard, D. (1968) A two-dimensional interpolation function for - irregularly-spaced data. In: Proceedings of the 1968 23rd ACM national - conference. ACM '68. ACM, New York, NY, USA, pp. 517-524. -
-- - Murray, R. J. (1996) Explicit generation of orthogonal grids for - ocean models. Journal of Computational Physics 126, 251-273. -
-
- -
--top -- - diff --git a/src/mom5/ocean_blobs/ocean_blob_util.xml b/src/mom5/ocean_blobs/ocean_blob_util.xml deleted file mode 100644 index a4bed2ba4d..0000000000 --- a/src/mom5/ocean_blobs/ocean_blob_util.xml +++ /dev/null @@ -1,134 +0,0 @@ - - -diff --git a/src/mom5/ocean_core/ocean_advection_velocity.F90 b/src/mom5/ocean_core/ocean_advection_velocity.F90 index 1b95156848..77cfa4a02d 100644 --- a/src/mom5/ocean_core/ocean_advection_velocity.F90 +++ b/src/mom5/ocean_core/ocean_advection_velocity.F90 @@ -226,12 +226,13 @@ module ocean_advection_velocity_mod private inflow_nboundary_init character(len=128) :: version=& - '$Id: ocean_advection_velocity.F90,v 1.1.2.8.16.2 2013/04/03 19:00:31 smg Exp $' + '$Id: ocean_advection_velocity.F90,v 20.0.4.1 2014/01/22 17:19:10 smg Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_201303_smg $' + '$Name: mom5_tikal_22jan2014_smg $' -logical :: have_obc = .false. -logical :: module_is_initialized = .FALSE. +logical :: have_obc = .false. +logical :: module_is_initialized = .FALSE. +logical :: prescribe_advection_velocity = .false. real :: max_advection_velocity = -1.0 logical :: debug_this_module = .false. @@ -365,6 +366,7 @@ subroutine ocean_advection_velocity_init(Grid, Domain, Time, Time_steps, Thickne if(read_advection_velocity .or. read_advection_transport) then call read_advection(Time, Thickness, Adv_vel) + prescribe_advection_velocity = .true. endif if(constant_advection_velocity) then @@ -372,6 +374,7 @@ subroutine ocean_advection_velocity_init(Grid, Domain, Time, Time_steps, Thickne '==>Note: Using ocean_advection_velocity_mod with constant_advection_velocity=.true.' write(stdoutunit,'(a)') & ' Will hold the advection velocity components constant in time. ' + prescribe_advection_velocity = .true. endif if(use_blobs .and. horz_grid == MOM_CGRID) then @@ -592,7 +595,7 @@ subroutine ocean_advection_velocity (Velocity, Time, Thickness, Dens, pme, river ! Remap these to get the corresponding advection velocity components ! (uhrho_eu,vhrho_nu) to advect B-grid horizontal momentum. - if(.not. constant_advection_velocity .and. horz_grid == MOM_BGRID) then + if(.not. prescribe_advection_velocity .and. horz_grid == MOM_BGRID) then do k=1,nk Adv_vel%uhrho_et(:,:,k) = & @@ -639,11 +642,11 @@ subroutine ocean_advection_velocity (Velocity, Time, Thickness, Dens, pme, river endif - endif ! endif for .not. constant_advection_velocity and MOM_BGRID + endif ! endif for .not. prescribe_advection_velocity and MOM_BGRID ! smg: June 2012: C-grid yet to be updated for blobs. - if(.not. constant_advection_velocity .and. horz_grid == MOM_CGRID) then + if(.not. prescribe_advection_velocity .and. horz_grid == MOM_CGRID) then do k=1,nk do j=jsd,jed @@ -666,7 +669,7 @@ subroutine ocean_advection_velocity (Velocity, Time, Thickness, Dens, pme, river *Grd%tmask(:,:,k) enddo - endif ! endif for .not. constant_advection_velocity and MOM_CGRID + endif ! endif for .not. prescribe_advection_velocity and MOM_CGRID if (have_obc) then @@ -932,7 +935,7 @@ subroutine read_advection(Time, Thickness, Adv_vel) type(ocean_thickness_type), intent(in) :: Thickness type(ocean_adv_vel_type), intent(inout) :: Adv_vel - integer :: k + integer :: i,j,k character(len=128) :: filename allocate (ue(isd:ied,jsd:jed,nk)) @@ -945,10 +948,19 @@ subroutine read_advection(Time, Thickness, Adv_vel) filename = 'INPUT/ocean_advect_velocity.nc' if (file_exist(trim(filename))) then call read_data(filename,'ue',ue,Dom%domain2d,timelevel=1) - call mpp_update_domains(ue(:,:,:), Dom%domain2d) call read_data(filename,'vn',vn,Dom%domain2d,timelevel=1) - call mpp_update_domains(vn(:,:,:), Dom%domain2d) call read_data(filename,'wb',wb,Dom%domain2d,timelevel=1) + do k=1,nk + do j=jsd,jed + do i=isd,ied + ue(i,j,k) = ue(i,j,k)*Grd%tmask(i,j,k) + vn(i,j,k) = vn(i,j,k)*Grd%tmask(i,j,k) + wb(i,j,k) = wb(i,j,k)*Grd%tmask(i,j,k) + enddo + enddo + enddo + call mpp_update_domains(ue(:,:,:), Dom%domain2d) + call mpp_update_domains(vn(:,:,:), Dom%domain2d) call mpp_update_domains(wb(:,:,:), Dom%domain2d) else call mpp_error(FATAL,& diff --git a/src/mom5/ocean_core/ocean_advection_velocity.html b/src/mom5/ocean_core/ocean_advection_velocity.html deleted file mode 100644 index 5cc2454f45..0000000000 --- a/src/mom5/ocean_core/ocean_advection_velocity.html +++ /dev/null @@ -1,335 +0,0 @@ - - - - Michael L. Bates - Stephen M. Griffies - - This module contains subroutines that are common (or are likely to - need be common to future implementations) to some or all of the - various modules that run the Lagrangian blob scheme. - - This module contains subroutines that are common (or may be common - in a future implementation) to some of the modules that make up the - blobs framework. - - Some of the subroutines contained herein perform tasks such as - performing checksums, checking a linked lists for very small blobs - (and deleting them), inserting blobs into a list, a bunch of routines - for writing blob restart and history files, grid cell search algorithms, - buffer manipulations, computations etc. - - The module has no namelist. All potential namelist variables are - controlled through the ocean_blob_mod namelist. - - Cormen, T. H, Leiserson, C. E. Rivest, R. L., Stein, C. (2001) Introduction - to Algorithms. The MIT Press. - - Shepard, D. (1968) A two-dimensional interpolation function for - irregularly-spaced data. In: Proceedings of the 1968 23rd ACM national - conference. ACM '68. ACM, New York, NY, USA, pp. 517-524. - - Murray, R. J. (1996) Explicit generation of orthogonal grids for - ocean models. Journal of Computational Physics 126, 251-273. - - Initialises this module. - - Performs global sums and checksums for all blob types (for diagnostic - purposes). - - - Performs checksums for the Lagrangian_system derived type. This is - the derived type that stores all of the "gridded" blob variables, - and is essential for the accounting required to interact with the - Eulerian model in a conservative manner. The checksums are for - diagnostic purposes. - - - Gives a brief summary of the total mass, volume and tracer content - of the E, L and total systems. Usually used for debuggin purposes. - - Dumps most of the information carried around by blobs, for all blobs - in a particular list. Useful for debugging. - - Deletes all (nearly) zero mass blob objects from the linked list. - The size of the blobs that are deleted is controlled by the variable - blob_small_mass in the ocean_blob_nml. - - Unlinks a blob from a doubly linked list. It returns pointers to - the blob, the head of the list, the (formerly) previous blob in the - list and the (formerly) next blob in the list. - - Inserts a blob to the linked list. The relative order of blobs in - a linked list determines whether bitwise reproduction is possible. - - Regardless of bitwise reproducability or not, we must ensure that - blobs always appear in the same relative order when we are using - dynamic blobs because if we have a situation where dztL>dztT, we - start destroying blobs to enforce dztL<dztT. In order that we do - not significantly change answers, we must always destroy the same - blob, regardless of domain decomposition, restarts, etc. So, we must - always sort blobs so they appear in the linked list in the same - relative order. - - Allocates a blob its hash and a number. These two numbers can - uniquely identify any blob. The hash and number is based on the grid - cell of origin. Each grid cell has a unique hash. We have an array - which keeps track of the number of blobs formed in a grid cell. These - two numbers give the unique identifier. So, we also need to increment - the counter array. - - Writes an attribute to a netcdf file. - - Gets the variable identifier from a netcdf file. - - Gets the value of a "double" variable from a netcdf file - - Gets the value of an integer variable from a netcdf file - - Writes the value of a "double" variable to a netcdf file - - Writes the value of an integer variable to a netcdf file - - Defines a netcdf variable - - Gives error descriptions for netcdf calls. - - Calculates the hash - - Does what is necessary to shut down the module. - - Checks whether a blob (horizontally) resides in a grid cell or not. - If it does not it figures out which direction the blob is in and - checks the neighbouring grid cell, until it finds which grid cell - the blob resides in. - - It uses a cross product technique from computational geometry - (Cormen et al., 2001). - - Searches for which (vertical) grid cell a blob resides in). - - Kills a blob by returning all of its remaining properties to the E - system. - - Frees the heap memory taken up by a blob. - - Allocates the history arrays for a blob (only used when - bitwise_reproduction=.true. in the ocean_blob_nml). - - Different blobs can have different history memory requirements. - When they change from one type of blob to another, we need to change - the memory allocated to a blob to reflect the new requirements. This - is only necessary if bitwise_reproduction=.true. in the ocean_blob_nml. - - Used for the horizontal interpolation of T grid variables. The - routine returns coefficients required for inverse distance - weighting (Shephard, 1968). - - Used for the horizontal interpolation of U grid variables. The - routine returns coefficients required for inverse distance - weighting (Shephard, 1968). - - Checks and adjusts blob position and grid cell index - for cylclic/periodic domains, as well as - the Murray (1996) tripolar grid. - Module ocean_advection_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_advection_velocity_mod
- - - - - -
-OVERVIEW
- -- Advection velocity components for tracer and momenta transport, with - options for B-grid or C-grid. -
- - - -- The module computes the horizontal and vertical components to the - advection velocity on the face of tracer and velocity cells. - Options are provided for either the B-grid or C-grid. - - The three velocity components are related by continuity. - - All components are density weighted, and the - horizontal components are thickness weighted. - - Some diagnostics related to fluid mass transport - classified according to both depth and density classes - are also computed. - --
- - -
-OTHER MODULES USED
- --- - - -axis_utils_mod-
constants_mod
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
ocean_obc_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_advection_velocity_init:
- -- -ocean_advection_velocity:
- -- -check_vert_cfl_blobs:
- -- -read_advect_velocity:
- -- -inflow_nboundary_init:
- -- -ocean_advection_velocity_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_advection_velocity_init
--
-- -DESCRIPTION -
-- - Initialize the advection velocity module -
-
-
-- - -
-ocean_advection_velocity
--
-- -DESCRIPTION -
-- - Compute thickness weighted and density weighted advection velocity - components for the B-grid on the T-cells and U-cells. -
-
-
-- - -
-check_vert_cfl_blobs
--
-- -DESCRIPTION -
-- - This routine is useful to check for strong vertical motions in the - presence of Lagrangian blobs. The CFL check is the same as in the - module ocean_adv_vel_diag.F90, but we have more local control here - so it is useful in the development stages of the blobs. -
-
-
-- - -
-read_advect_velocity
--
-- -DESCRIPTION -
-- - For reading in the advection velocity components. Assume that - the advection velocity components read in from a file are in units - of meter/sec and placed on the T-cell faces, as in a C-grid ocean model. - - This routine assumes that the read-in velocity components already - have the proper masking. - - The main application of this routine is for developing idealized - test cases for tracer advection. -
-
-
-- - -
-inflow_nboundary_init
--
-- -DESCRIPTION -
-- - Initialize the advection velocity used for specifying a nonzero - southward inflow introduced to the domain from the northern boundary. - -
-
-
-- - -
-ocean_advection_velocity_end
--
-- -DESCRIPTION -
-- - Write a restart if necessary - -
-
-
-
-NAMELIST
- --&ocean_advection_velocity_nml --
-
----
-- -debug_this_module -
-- For debugging. -
-
-[logical] -- -inflow_nboundary -
-- For adding an inflow velocity from the northern boundary. - Default is inflow_nboundary=.false. -
-
-[logical] -- -read_advection_velocity -
-- For reading in a file with specified zonal, meridional, - and vertical components to the advection velocity. - The file should have velocity at the east face of T-cell, - north face, and bottom, just as on a C-grid. The units - should be m/s for each component. MOM then multiplies - but the appropriate thickness and density factors to - generate transport for use in the model. - Default read_zonal_advection_velocity=.false. -
-
-[logical] -- -constant_advection_velocity -
-- When reading in the advection velocity components, we - may choose to keep them constant in time. This facilitates - idealized tests of tracer advection. - Default constant_advection_velocity=.false. -
-
-[logical] -- -max_advection_velocity -
-- This is a check value used to determine if the time steps will result in - linearly stable advection. If set to a number < 0, then model will estimate the - value as a function of maximum grid size. - Note that this time step check is not rigorous, and it depends on the details of - the advection scheme. Nonetheless, it provides some useful warning for setting the - time steps in the model. -
-
-[real, units: meter/sec] -
- - - - -
-REFERENCES
- ----
-- - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- - -
-NOTES
- -- The expressions for the horizontal components for tracer advection - allow for a proper conversion between pressure work and buoyancy. --
-
- The B-grid remapping operators are derived from considerations of linear - interpolation and volume conservation. A "remapping error" is - computed to determine consistency between the tracer and velocity - grid advection velocities. This error is roundoff only for cases - where the horizontal tracer and velocity grids are linearly related, - as is the case for the spherical coordinate version of MOM. The - tripolar version of MOM does not have tracer and velocity grids - related linearly, and so the "remapping error" is nontrivial. The - significance of this error is unclear. No adverse effects have been - identified. -
-
- The vertical velocity components for both the tracer and velocity cells - are diagnosed via continuity (either volume or mass conservation depending - on the use of the Boussinesq or non-Boussinesq versions of MOM). -
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_barotropic.F90 b/src/mom5/ocean_core/ocean_barotropic.F90 index 94f8b40bc0..8920c2ada0 100644 --- a/src/mom5/ocean_core/ocean_barotropic.F90 +++ b/src/mom5/ocean_core/ocean_barotropic.F90 @@ -1,19 +1,19 @@ module ocean_barotropic_mod #define COMP isc:iec,jsc:jec ! -!S.M. Griffies +! S.M. Griffies ! ! !Martin Schmidt (OBC) ! ! -!Zhi Liang (OBC and halos) +! Zhi Liang (OBC and halos) ! ! -!Harper Simmons (tides) +! Harper Simmons (tides) ! ! -!M.J. Harrison +! M.J. Harrison ! ! !@@ -664,9 +664,9 @@ module ocean_barotropic_mod character(len=128) :: & - version='$Id: ocean_barotropic.F90,v 1.1.2.10 2012/06/08 00:45:19 Stephen.Griffies Exp $' + version='$Id: ocean_barotropic.F90,v 20.0 2013/12/14 00:10:34 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' #include @@ -5642,7 +5642,7 @@ end subroutine barotropic_chksum ! will be equal, and they will be equal to the rigid lid barotropic ! streamfunction in the Boussinesq case. ! -! Original algorithm: Stephen.Griffies@noaa.gov +! Original algorithm: Stephen.Griffies ! ! 13MAR2007: Change units to 10^9 kg/s, which is a "mass Sv" ! This is the natural unit of transport for a mass-based diff --git a/src/mom5/ocean_core/ocean_barotropic.html b/src/mom5/ocean_core/ocean_barotropic.html deleted file mode 100644 index f29e6d4bb5..0000000000 --- a/src/mom5/ocean_core/ocean_barotropic.html +++ /dev/null @@ -1,1491 +0,0 @@ - - - - Module ocean_barotropic_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_barotropic_mod
- - --Contact: S.M. Griffies - , - Martin Schmidt (OBC) - , - Zhi Liang (OBC and halos) - , - Harper Simmons (tides) - -- - -
-Reviewers: M.J. Harrison - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Update the vertically integrated dynamics using a - split-explicit algorithm. -
- - - -- - This module time steps the vertically integrated dynamics - using a predictor-Corrector with adjustable dissipation. - - This code uses a split-explicit method. There have been no - no rigid lid available in MOM since MOM3. - - Treatment is provided for both depth-based Boussinesq - and pressure-based non-Boussinesq vertical coordinates. - - Treatment is provided for both a Bgrid or Cgrid horizontal layout. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
time_manager_mod
time_interp_external_mod
ocean_bih_friction_mod
ocean_domains_mod
ocean_lap_friction_mod
ocean_obc_barotrop_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_barotropic_init:
- -- -barotropic_diag_init:
- -- -eta_terms_diagnose_init:
- -- -eta_and_pbot_update:
- -- -eta_and_pbot_diagnose:
- -- -eta_and_pbot_tendency:
- -- -update_ocean_barotropic:
- -- -ocean_barotropic_forcing:
- -- -ocean_mass_forcing:
- -- -pred_corr_tropic_depth_bgrid:
- -- -pred_corr_tropic_depth_cgrid:
- -- -pred_corr_tropic_press_bgrid:
- -- -pred_corr_tropic_press_cgrid:
- -- -eta_smooth_diagnosed:
- -- -ocean_eta_smooth:
- -- -ocean_pbot_smooth:
- -- -barotropic_integrals:
- -- -barotropic_energy:
- -- -read_barotropic:
- -- -ocean_barotropic_restart:
- -- -ocean_barotropic_end:
- -- -maximum_convrhoud:
- -- -barotropic_chksum:
- -- -psi_compute:
- -- -eta_terms_diagnose:
- -- -eta_truncate:
- -- -eta_check:
- -- -tidal_forcing_init:
- -- -geoid_forcing_init:
- -- -get_tidal_forcing:
- -- -ideal_initialize_eta:
- -- -REMAP_BT_TO_BU_LOCAL:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_barotropic_init
--
-- -DESCRIPTION -
-- - Initialize the barotropic module -
-
-
-- - -
-barotropic_diag_init
--
-- -DESCRIPTION -
-- - Initialize diagnostic indices for the module. - - Diagnose the static arrays. -
-
-
-- - -
-eta_terms_diagnose_init
--
-- -DESCRIPTION -
-- - Initialize diagnostic indices for the eta_terms related diagnostics. -
-
-
-- - -
-eta_and_pbot_update
--
-- -DESCRIPTION -
-- - Time step the surface height or pbot using a "big" time step. - These fields are coincident in time with ocean tracers. - - NOTE: For pbot_t updates, we time step anompb for accuracy, then - add rho0grav*ht to get pbot_t. - -
-
-
-- - -
-eta_and_pbot_diagnose
--
-- -DESCRIPTION -
-- - Diagnose surface height or pbot depending on the vertical coordinate. - - Note that dzt has been updated to taup1 before this routine is called, - since we have already called update_tcell_thickness. - - Also, compute geodepth_zt in this routine. It is necessary to do - do this step here, since for pressure coordinate models we do not - know eta_t(taup1) until this routine. - - June 2011: note to smg: - Consider changing taup1 to tau in rho, since we - do not yet know the taup1 value. Not a fundamental issue, - but may be cleaner. It will change bits, however. - -
-
-
-- - -
-eta_and_pbot_tendency
--
-- -DESCRIPTION -
-- - Compute tendency for surface height or bottom pressure. - - If use_blobs=.true., then we include the divergence from - the Lagrangian system. - -
-
-
-- - -
-update_ocean_barotropic
--
-- -DESCRIPTION -
-- - Time step the external mode fields using - a predictor-corrector scheme. Time average these fields to - update the vertically integrated density weighted velocity - (urhod,vrhod) and the time averaged surface height eta_t_bar - or bottom pressure anompb_bar. - - NOTE: surface pressure gradient and gradient of anomalous - bottom pressure are needed for the energy analysis. - - Also, if splitting=false or update_velocity_via_uprime=.false., - use these for velocity update in ocean_velocity_mod. - - Include the tidal forcing if present. - - Include geoid perturbation if present. - - Use time averaged eta and pbot to ensure the stable pressure gradient - for use with splitting=false or update_velocity_via_uprime=.false. - -
-
-
-- - -
-ocean_barotropic_forcing
--
-- -DESCRIPTION -
-- - Construct the vertically integrated forcing. This forcing is to be - held constant over the barotropic timesteps. At the time of calling - this routine, accel has the contributions from explicit-time - forcing, except for the following: - - 1. Coriolis force is updated on the barotropic time steps when - integrating the barotropic dynamics. So it should not - be included in forcing_bt. - - 2. Contributions from smf and bmf are added to forcing_bt to allow - for simpler handling of vertical friction implicitly in time. - - 3. The accel array is already thickness and density weighted, so - a vertical density weighted integral is here just a vertical sum. - -
-
-
-- - -
-ocean_mass_forcing
--
-- -DESCRIPTION -
-- - Construct the vertically integrated mass source for - evolution of the free surface and/or bottom pressure. - - Also construct the time tendency for the atmospheric pressure. - -
-
-
-- - -
-pred_corr_tropic_depth_bgrid
--
-- -DESCRIPTION -
-- - Integrate barotropic dynamics for "nts" timesteps using - predictor-corrector. Assume depth-like vertical coordinate - so solve for surface height. - - This scheme is more stable than leap_frog since it can run with - longer time steps to resolve external mode gravity waves. It also - provides some extra smoothing when pred_corr_gamma > 0 and so the options - smooth_eta_t_bt_laplacian and smooth_eta_t_bt_biharmonic may not be - needed. - - Time steps Bgrid layout of discrete fields. - -
-
-
-- - -
-pred_corr_tropic_depth_cgrid
--
-- -DESCRIPTION -
-- - Integrate barotropic dynamics for "nts" timesteps using - predictor-corrector. Assume depth-like vertical coordinate - so solve for surface height. - - Cgrid horizontal layout. - - This scheme is more stable than leap_frog since it can run with - longer time steps to resolve external mode gravity waves. It also - provides some extra smoothing when pred_corr_gamma > 0. - We assume pred_corr_gamma > 0 in this routine. - -
-
-
-- - -
-pred_corr_tropic_press_bgrid
--
-- -DESCRIPTION -
-- - Integrate barotropic dynamics for "nts" timesteps using - predictor-corrector. Assume pressure-like vertical coordinate - so solve here for the bottom pressure. - - This scheme provides some smoothing of small spatial scales - when pred_corr_gamma > 0. - - NOTE: the pressure gradient force is based on gradients of - (pbot_t_bt - rho0*grav*ht) rather than gradients of pbot_t_bt. - This approach aims to improve accuracy of the pressure force. - - Time steps Bgrid layout of discrete fields. - -
-
-
-- - -
-pred_corr_tropic_press_cgrid
--
-- -DESCRIPTION -
-- - Integrate barotropic dynamics for "nts" timesteps using - predictor-corrector. Assume pressure-like vertical coordinate - so solve here for the bottom pressure. - - This scheme provides some smoothing of small spatial scales - with requirement that pred_corr_gamma > 0. - - NOTE: the pressure gradient force is based on gradients of - (pbot_t_bt - rho0*grav*ht) rather than gradients of pbot_t_bt. - This approach aims to improve accuracy of the pressure force. - - Time steps Cgrid layout of discrete fields. - -
-
-
-- - -
-eta_smooth_diagnosed
--
-- -DESCRIPTION -
-- - Smooth eta_t for case when running with pressure models and wish - to have a diagnostic eta field smoothed. This option is most - useful for the Bgrid, which has a checkerboard null mode when - discretizing gravity waves. The Cgrid has no gravity wave noise - so may not need this smoother. -
-
-
-- - -
-ocean_eta_smooth
--
-- -DESCRIPTION -
-- - Compute tendency for smoothing eta and tracer. - - Use either a laplacian or a biharmonic smoothing operator. - - This smoothing option is most useful for the Bgrid, which has - a checkerboard null mode when discretizing gravity waves. The - Cgrid has no gravity wave noise so may not need this smoother. - - Recommend against using the biharmonic, since it is not a - positive definite operator and so can lead to extrema. - Biharmonic is retained for legacy purposes. - -
-
-
-- - -
-ocean_pbot_smooth
--
-- -DESCRIPTION -
-- - Compute tendency for diffusion of (pbot_t-pbot0) in both pbot_t - and tracer. Need to consider tracer in order to maintain compability - between tracer and mass conservation equations. - - Use either a laplacian or a biharmonic smoother. - - This smoothing option is most useful for the Bgrid, which has - a checkerboard null mode when discretizing gravity waves. The - Cgrid has no gravity wave noise so may not need this smoother. - - Recommend against using the biharmonic, since it is - NOT a positive definite operator and so can lead to extrema. - -
-
-
-- - -
-barotropic_integrals
--
-- -DESCRIPTION -
-- - Compute area averaged fresh water and surface height and ocean mass. -
-
-
-- - -
-barotropic_energy
--
-- -DESCRIPTION -
-- - Compute energetics of vertically integrated flow. -
-
-
-- - -
-read_barotropic
--
-- -DESCRIPTION -
-- - Read in external mode fields from restart file. -
-
-
-- - -
-ocean_barotropic_restart
--
-- -DESCRIPTION -
-- - - Write out restart files registered through register_restart_file - Call to reset_field_pointer only needed for fields with a time index. - -
-
-
-- - -
-ocean_barotropic_end
--
-- -DESCRIPTION -
-- - Write out external mode fields to restart file. -
-
-
-- - -
-maximum_convrhoud
--
-- -DESCRIPTION -
-- - Compute maximum convergence(rho_ud,rho_vd). -
-
-
-- - -
-barotropic_chksum
--
-- -DESCRIPTION -
-- - Compute checksum for external mode fields. -
-
-
-- - -
-psi_compute
--
-- -DESCRIPTION -
-- - Compute quasi-barotropic streamfunctions for diagnostic purposes. - When no fresh water and steady state, these two streamfunctions - will be equal, and they will be equal to the rigid lid barotropic - streamfunction in the Boussinesq case. - - Original algorithm: Stephen.Griffies - - 13MAR2007: Change units to 10^9 kg/s, which is a "mass Sv" - This is the natural unit of transport for a mass-based - vertical coordinate model. - - Updated Dec2009 to be compatible with tx_trans and ty_trans - calculation. - -
-
-
-- - -
-eta_terms_diagnose
--
-- -DESCRIPTION -
-- - Diagnose various contributions to the sea level. - - WARNING: The steric diagnostics from this subroutine are confusing - when evaluated in a Boussinesq model. The reason is that volume - conserving Boussinesq models have spurious mass sources, which - corrupt the bottom pressure signal. One needs to apply corrections - to make sense of the Boussinesq models for purposes of studying - mass budgets, including the local contribution to steric effects. - - contributions from dynamics, mass, and steric: - - eta_nonbouss = (eta_dynamic + eta_water + eta_source) + eta_steric - = eta_nonsteric + eta_steric - - For PRESSURE_BASED vertical coordinates, eta_smooth_tend has - already been computed in subroutine eta_smooth_diagnosed. - We do not add this contribution to eta_nonbouss, since this - piece is not part of the tendencies affecting bottom pressure. - It is only added for cosmetic reasons. It is for this reason - that eta_smooth is NOT included in the restart file. - - For calculation of the steric contribution, a single time step - scheme is assumed, which is the recommended time stepping in MOM. - - For DEPTH_BASED models, the smoothing of eta is included in - Ext_mode%source, so eta_smooth_tend is zero for depth-based models. - - For PRESSURE_BASED vertical coordinates, eta_nonbouss as computed - in this routine is very close to the prognostic eta_t. Differences - arise from any possible smoothing applied to the diagnosed eta_t. - -
-
-
-- - -
-eta_truncate
--
-- -DESCRIPTION -
-- - - Truncate eta_t to keep - - dzt(1) + eta_t >= frac_crit_cell_height*dzt(1) - - and - - eta_t <= eta_max - - May be needed when run GEOPOTENTIAL models. - -
-
-
-- - -
-eta_check
--
-- -DESCRIPTION -
-- - Perform diagnostic check on top cell thickness. Useful when - when use GEOPOTENTIAL vertical coordinate. - -
-
-
-- - -
-tidal_forcing_init
--
-- -DESCRIPTION -
-- - Initialize fields needed for lunar and solar tidal forcing. -
-
-
-- - -
-geoid_forcing_init
--
-- -DESCRIPTION -
-- - Initialize fields needed for modifying the geoid, relative to the - standard geoid. -
-
-
-- - -
-get_tidal_forcing
--
-- -DESCRIPTION -
-- - Compute equilibrium tidal forcing. -
-
-
-- - -
-ideal_initialize_eta
--
-- -DESCRIPTION -
-- - Idealized initial condition for eta. -
-
-
-- - -
-REMAP_BT_TO_BU_LOCAL
--
-- -DESCRIPTION -
-- - Local version of the operator, needed here for initialization - when read in eta information from an initialization file. - Since barotropic is initialized prior to operators, we need - to have this operator here locally. -
-
-
-
-NAMELIST
- --&ocean_barotropic_nml --
-
----
-- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -zero_tendency -
-- If true, will not integrate the barotropic fields. -
-
-[logical] -- -zero_forcing_bt -
-- Will set to zero all of the terms forcing the barotropic velocity. -
-
-[logical] -- -zero_nonlinear_forcing_bt -
-- Will set to zero the nonlinear forcing terms, leaving only the smf and bmf - terms to force the barotropic velocity. -
-
-[logical] -- -zero_eta_ic -
-- To initialize eta_t to zero. -
-
-[logical] -- -zero_eta_t -
-- To maintain eta_t at zero, but to allow other fields to evolve. - For debugging. Default zero_eta_t=.false. -
-
-[logical] -- -zero_eta_u -
-- To maintain eta_u at zero, but to allow other fields to evolve. - For debugging. Default zero_eta_u=.false. -
-
-[logical] -- -zero_eta_tendency -
-- To maintain deta_dt at zero. For debugging. - Default zero_eta_t=.false. -
-
-[logical] -- -ideal_initial_eta -
-- To initialize eta_t to an ideal profile. This option overrides - all other initialization that may have occurred. - Default=.false. -
-
-[logical] -- -ideal_initial_eta_amplitude -
-- Amplitude for initializing eta with an ideal profile. - Default ideal_initial_eta_amplitude = 5.0 -
-
-[real, units: metre] -- -ideal_initial_eta_xwidth -
-- Width in x-direction for sine-wave profile. - Default xwidth=100e3 -
-
-[real, units: metre] -- -ideal_initial_eta_ywidth -
-- Width in y-direction for sine-wave profile. - Default ywidth=100e3 -
-
-[real, units: metre] -- -barotropic_time_stepping_A -
-- Use the general approach from MOM4.0, in which the eta_t and - pbot_t fields are updated with a big time step. - This is the recommended approach for most applications that - do not employ and open boundary condition. - Default barotropic_time_stepping_A=.false. -
-
-[logical] -- -barotropic_time_stepping_B -
-- Use the alternative approach in which we assume the barotropic - scheme is a predictor-corrector, which is now the default - in MOM. We use this assumption so that the eta_t and - pbot_t fields are updated with a time average. This - approach is used for open boundary condition applications. - Default barotropic_time_stepping_A=.false. -
-
-[logical] -- -pred_corr_gamma -
-- Dimensionless dissipation parameter for the preditor-corrector - scheme. Setting pred_corr_gamma=0.0 reduces the scheme to a - forward-backward, but it has been found to be unstable. - So pred_corr_gamma > 0.0 is recommended. Note that - pred_corr_gamma > 0.25 may be over-dissipated and so may - go unstable. Default pred_corr_gamma=0.2. -
-
-[real, units: dimensionless] -- -smooth_eta_t_bt_laplacian -
-- For spatially smoothing the eta_t field at each barotropic - time step using a Laplacian operator. This option may not - be necessary when pred_corr_gamma > 0.0, since the - predictor-corrector approach has dissipation from - pred_corr_gamma > 0.0. Also, smoothing is not needed - in general for Cgrid MOM, since the gravity wave null mode - only appears for the Bgrid. This option is only - applicable for DEPTH_BASED vertical coordinates. - Default smooth_eta_t_bt_laplacian=.false. -
-
-[logical] -- -smooth_eta_t_bt_biharmonic -
-- For spatially smoothing the eta_t field at each barotropic - time step using a biharmonic operator. May not be necessary - when pred_corr_gamma > 0.0, since predictor-corrector has - dissipation from pred_corr_gamma > 0.0. Also, smoothing is not - needed in general for Cgrid MOM, since the gravity wave null - mode only appears for the Bgrid. Applicable just for - DEPTH_BASED vertical coordinates. WARNING: this operator - is NOT positive definite, and so can produce spurious - extrema. It is not generally recommended just for this - reason. Default smooth_eta_t_bt_laplacian=.false. -
-
-[logical] -- -smooth_eta_t_laplacian -
-- For spatially smoothing the eta_t field on the big time step - by using a laplacian operator. For compatibility - and global conservation, must also introduce a mixing - to the thickness weighted tracer concentration in the k=1 cell. - Applicable just for DEPTH_BASED vertical coordinates. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - Default mooth_eta_t_laplacian=.true. -
-
-[logical] -- -smooth_eta_t_biharmonic -
-- For spatially smoothing the eta_t field on the big time step - by using a biharmonic operator. For compatibility - and global conservation, must also introduce a mixing - to the thickness weighted tracer concentration in the k=1 cell. - Applicable just for DEPTH_BASED vertical coordinates. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - WARNING: This operator is NOT positive definite, and so can - produce spurious extrema. It is not recommended just for this - reason. Default smooth_eta_t_biharmonic=.false. -
-
-[logical] -- -eta_offset -
-- Uniform offset for use in determining the filter - acting on tracer when smoothing the surface height. - Default eta_offset=1e-12. -
-
-[real, units: metre] -- -smooth_eta_diag_laplacian -
-- For spatially smoothing the diagnosed eta_t field - using a laplacian operator. This option is used for - PRESSURE_BASED vertical coordinates, in which case - the free surface is diagnosed rather than prognosed. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - Default smooth_eta_diag_laplacian=.true. -
-
-[logical] -- -smooth_eta_diag_biharmonic -
-- For spatially smoothing the diagnosed eta_t field - using a biharmonic operator. This option is used for - PRESSURE_BASED vertical coordinates, in which case - the free surface is diagnosed rather than prognosed. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - Default smooth_eta_diag_biharmonic=.false. -
-
-[logical] -- -vel_micom_lap_diag -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of diagnosed surface height. - Default vel_micom_lap_diag=0.2. -
-
-[real, units: m/sec] -- -vel_micom_bih_diag -
-- Velocity scale that is used for computing the MICOM biharmonic mixing - coefficient used in the biharmonic smoothing of diagnosed surface height. - Default vel_micom_bih_diag=0.1. -
-
-[real, units: m/sec] -- -smooth_anompb_bt_laplacian -
-- For spatially smoothing anomalous pbot_t at each barotropic - time step using a Laplacian operator. May not be necessary when - pred_corr_gamma > 0.0, since predictor-corrector has dissipation - from pred_corr_gamma > 0.0. This option is applicable just - for PRESSURE_BASED vertical coordinates. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - Default smooth_anompb_bt_laplacian=.false. -
-
-[logical] -- -smooth_anompb_bt_biharmonic -
-- For spatially smoothing the anomalous pbot_t field at each barotropic - time step using a biharmonic operator. May not be necessary when - when pred_corr_gamma > 0.0, since predictor-corrector has dissipation - from pred_corr_gamma > 0.0. This option is applicable just for - PRESSURE_BASED vertical coordinates. Also, smoothing is not - needed in general for Cgrid MOM, since the gravity wave null - mode only appears for the Bgrid. WARNING: This operator is - NOT positive definite, and so can produce spurious extrema. - It is not recommended just for this reason. - Default smooth_anompb_bt_biharmonic=.false. -
-
-[logical] -- -smooth_pbot_t_laplacian -
-- For spatially smoothing pbot_t-pbot0 on the big time step - using a laplacian operator. For compatibility - and global conservation, must also introduce a mixing - to the thickness weighted tracer concentration in the k=kbot cell. - Applicable just for PRESSURE_BASED vertical coordinates. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - Default smooth_pbot_t_laplacian=.true. -
-
-[logical] -- -smooth_pbot_t_biharmonic -
-- For spatially smoothing pbot_t-pbot0 on the big time step - by using a biharmonic operator. For compatibility - and global conservation, must also introduce a mixing - to the thickness weighted tracer concentration in the k=kbot cell. - Applicable just for PRESSURE_BASED vertical coordinates. - Also, smoothing is not needed in general for Cgrid MOM, - since the gravity wave null mode only appears for the Bgrid. - WARNING: This operator is NOT positive definite, and so can - produce spurious extrema. It is not recommended just for this - reason. Default smooth_pbot_t_biharmonic=.false. -
-
-[logical] -- -smooth_pbot_t_biharmonic_legacy -
-- For using an older version of the smooth_pbot_t_biharmonic - scheme. The smooth_pbot_t_biharmonic_legacy option has a - minor bug, but it is maintained in order to allow for - backward compatible legacy simulations. It is not - recommended for new simulations. - To use it requires also setting smooth_pbot_t_biharmonic=.true. - Default smooth_pbot_t_biharmonic_legacy=.false. -
-
-[logical] -- -pbot_offset -
-- Uniform offset for use in determining the filter - acting on tracer when smoothing the bottom pressure anomaly. - Default pbot_offset=1e-12. -
-
-[real, units: Pa] -- -vel_micom_lap -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of surface height - or anomalous bottom pressure. Default vel_micom_lap=0.05. -
-
-[real, units: m/sec] -- -vel_micom_bih -
-- Velocity scale that is used for computing the MICOM biharmonic mixing - coefficient used in the biharmonic smoothing of surface height - or anomalous bottom pressure. Default vel_micom_bih=0.01. -
-
-[real, units: m/sec] -- -udrho_bt_lap -
-- The vertically integrated horizontal momentum can be noisy - on the Bgrid. It is therefore sometimes useful to add a - smoothing operator to the barotropic time stepping. - Here, we apply the laplacian friction as coded in the friction - module using the vertically averaged isotropic viscosity as well as a - background, and we do so on each barotropic time step. It is an - expensive option. It is an option rarely used GFDL. - This options will soon be removed from MOM. - Default udrho_bt_lap=.false. -
-
-[logical] -- -udrho_bt_bih -
-- The vertically integrated horizontal momentum on the Bgrid can be - noisy. It is therefore sometimes useful to add a smoothing - operator. Here, we apply the biharmonic friction as coded in - the friction module using the vertically averaged isotropic - viscosity as well as a background. Do so on each barotropic - time step, which makes it an expensive option. This option is - rarely used GFDL. Default udrho_bt_bih=.false. - This options will soon be removed from MOM. -
-
-[logical] -- -udrho_lap -
-- The vertically integrated horizontal momentum on the Bgrid can be - noisy. It is therefore sometimes useful to add a smoothing - operator. Here, we apply the laplacian friction as coded in - the friction module using the vertically averaged isotropic - viscosity as well as a background. Do so just on the baroclinic - time step, so the option is less expensive than udrho_bt_lap. - This options will soon be removed from MOM. - Default udrho_lap=.false. -
-
-[logical] -- -udrho_bih -
-- The vertically integrated horizontal momentum on the Bgrid can be - noisy. It is therefore sometimes useful to add a smoothing - operator. Here, we apply the biharmonic friction as coded in - the friction module using the vertically averaged isotropic - viscosity as well as a background. Do so just on the baroclinic - time step, so the option is less expensive than udrho_bt_lap. - This options will soon be removed from MOM. - Default udrho_bih=.false. -
-
-[logical] -- -udrho_lap_vel_micom -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of udrho. - This options will soon be removed from MOM. - Default udrho_lap_vel_micom=.05 -
-
-[real, units: m/sec] -- -udrho_bih_vel_micom -
-- Velocity scale that is used for computing the MICOM biharmonic mixing - coefficient used in the biharmonic smoothing of udrho. - This options will soon be removed from MOM. - Default udrho_bih_vel_micom=.01 -
-
-[real, units: m/sec] -- -tidal_forcing_m2 -
-- Forces from lunar M2 tidal constituent. - Default tidal_forcing_m2=.false. -
-
-[logical] -- -tidal_forcing_8 -
-- Forces from 8 lunar and solar tidal constituents. - Default tidal_forcing_8=.false. -
-
-[logical] -- -tidal_forcing_ideal -
-- For ideal tidal forcing, which has a bump configuration. - Default tidal_forcing_ideal=.false. -
-
-[logical] -- -alphat -
-- Dimensionless self-attraction and loading term. Used only - when tidal_forcing=.true. Default alphat=0.948. -
-
-[real, units: dimensionless] -- -geoid_forcing -
-- For modifying the geoid, implemented as a time independent - tidal forcing. Need to read in a file to obtain the offset - geoid profile. Default geoid_forcing=.false. -
-
-[logical] -- -truncate_eta -
-- To truncate the surface height so to ensure positive thickness - within the top cell. This method will not conserve volume or tracer. - It is coded for cases when conservation is not critical but wish to - run GEOPOTENTIAL models w/ large free surface height deviations, such - as when running with tides and very fine vertical resolution. The preferred - approach is to use zstar or pstart vertical coordinates. - Default truncate_eta = .false.. -
-
-[logical] -- -verbose_truncate -
-- For verbose printout on truncate_eta -
-
-[logical] -- -frac_crit_cell_height -
-- When use GEOPOTENTIAL vertical coordinate, the top model tracer grid - cell has thickness dzt(i,j,1) = dzt(1) + eta_t(i,j). - 0 < frac_crit_cell_height <= 1 sets the fraction of dzt(1) that is allowed - prior to bringing the model down due to overly small dzt(i,j,1). - Default frac_crit_cell_height=0.20. -
-
-[real, units: dimensionless] -- -eta_max -
-- The maximum positive eta_t allowed when truncate_eta is true. - Default eta_max = 5.0. -
-
-[real, units: meter] -- -barotropic_halo -
-- Set barotropic_halo > 1 to use wide halo in the barotropic time step to improve the - performance. In barotropic time step, most time is spent on mpp_update_domains. Use - wide halo to decrease the number of mpp_update_domain calls and hence improve the - performance. The default value is barotropic_halo=1, which is the older approach - (non-wide halo). Users are encouraged to experiment with larger halos, as the - model speedup can be tremendous. -
-
-[INTEGER] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - Default do_bitwise_exact_sum=.false. -
-
-[logical] -- -debug_this_module -
-- Print out lots of diagnostics of use for debugging. - Default debug_this_module=.false. -
-
-[logical] -- -verbose_init -
-- For brief or full printout on initialization - Default verbose_init=.true. -
-
-[logical] -- -diag_step -
-- Frequency for output of ascii barotropic diagnostics. - Setting diag_step=1 will compute diagnostics each time - step and print to stdout. This setting is useful when - developing a model in order to examine various budgets - and stability issues. But when running production, one - should set diag_step to a mucch larger number in order to - reduce i/o and model cost. Default diag_step=-1, - which means will not compute any of the online diagnostics. -
-
-[integer] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, R.C. Pacanowski, R.M. Schmidt, and V. Balaji - Tracer Conservation with an Explicit Free Surface Method for - Z-coordinate Ocean Models - Monthly Weather Review (2001) vol 129 pages 1081--1098 -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models - Princeton University Press (2004) -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_bbc.F90 b/src/mom5/ocean_core/ocean_bbc.F90 index c15a7c2695..42dc0dc629 100644 --- a/src/mom5/ocean_core/ocean_bbc.F90 +++ b/src/mom5/ocean_core/ocean_bbc.F90 @@ -171,9 +171,9 @@ module ocean_bbc_mod type(ocean_domain_type), pointer :: Dom =>NULL() character(len=128) :: version=& - '$Id: ocean_bbc.F90,v 1.1.2.7 2012/06/04 00:11:43 Stephen.Griffies Exp $' + '$Id: ocean_bbc.F90,v 20.0 2013/12/14 00:10:36 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public :: ocean_bbc_init public :: get_ocean_bbc diff --git a/src/mom5/ocean_core/ocean_bbc.html b/src/mom5/ocean_core/ocean_bbc.html deleted file mode 100644 index f39dbc469f..0000000000 --- a/src/mom5/ocean_core/ocean_bbc.html +++ /dev/null @@ -1,395 +0,0 @@ - - - -Module ocean_bbc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_bbc_mod
- - --Contact: Matthew Harrison -, - S.M. Griffies -, - Martin Schmidt -, - Hyun-Chul Lee - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Set bottom boundary conditions -
- - - -- Set bottom boundary conditions --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
wave_types_mod
ocean_wave_mod
-PUBLIC INTERFACE
----
-- -ocean_bbc_init:
- -- -get_ocean_bbc:
- -- -current_wave_drag_diag:
- -- -wave_u_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_bbc_init
--
-- -DESCRIPTION -
-- - Initialize the bottom boundary condition module -
-
-
-- - -
-get_ocean_bbc
--
-- -DESCRIPTION -
-- - Set bottom boundary conditions for velocity and tracer. - - Dimensions of bottom momentum flux are - N/m^2 = (kg/m^3)*(m^2/s^2). - - Note the use of rho0 for the conversion from m^2/s^2 to - (kg/m^3)*(m^2/s^2). We do not know the precise value - of cdbot, so the rho0 approximate value is well within - our level of uncertainty. No reason therefore to - use in situ rho for this conversion, even when using - non-Boussinesq version of MOM. - - - Note that bmf needs to be computed on the data domain since the - halo values are accessed in ocean_vert_gotm.F90. - -
-
-
-- - -
-current_wave_drag_diag
--
-- -DESCRIPTION -
-- - calculates wave-current bottom shear stress - using model of Grand and Madsen(1979) J. Geophys. Res. 84, C4, 1797 - see Signell et. al (1990) J. Geophys. Res. 95, C6, 9671 - - input bot_vel: current velocity at u points - Note: assumed that this is the velocity just above the bottom boundary layer. - - A relation between grain size, ripples steepness and and roughness is - assumed. More general relations are possible but not needed, since - the output is used only to parameterise resuspension of organic matter - in the ecosystem model ocean_shared/generic_tracers/generic_ERGOM.F90. - - output: effective drag coefficient drag_coeff. - It is valid for momentum flux from currents into the bottom, but - from combined waves+current action. - Velocity%current_wave_stress is the stress from waves and currents - to the sediment. - - Note: - - 1/ drag_coeff in this routine arises from both (waves+current); - That is, ustar**2/uref**2 1 meter above the bottom. - - 2/ bottom velocity is taken just above the bottom boundary layer, and - assumed here to be at lowest u point. - - 3/ to understand the calculation of shear stress acting on grains - at sediment surface ("wrk1_2d(i,j) = (ustar2/ucomb)*0.3152"), - see Kuhrts et al. (2004) Eqs. (4,5,6,7). - Assume a thin skin friction layer according to Smith, McLean (1977) - thickness of the skin friction layer zskin scales with roughness length ruff - grained sediments are characterised by median diameter d50[m] - ripples at sea bottom have spacing lambda and height eta with steepness eta/lambda=0.1 - common approx. for grain roughness length = d50/12 - Nielsen (1983) form drag roughness length = (8/30)*eta*(eta/lambda) ==> (8/3000)*lambda - Yalin (1977) lambda = 1000*d50 ==> form drag = (8/3)*d50 - ruff = grain + form drag = (1/12+8/3)*d50 = (33/12)*d50 = 33*grain - Smith, McLean (1977) zskin = 0.09*grain*(lambda/grain)**0.8 = 165*grain = 5*ruff - matching at zskin leads to log(zskin/ruff)/log(zskin/grain)) = log(5)/log(165) = 0.3152 - the current induced skin friction velocity is derived from matching skin friction - to wave boundary layer. - - 4/ Algorithm has yet to be updated for Cgrid. - - April 2012 - martin.schmidt@io-warnemuende.de - -
-
-
-- - -
-wave_u_diag
--
-- -DESCRIPTION -
-- - calculates wave bottom shear stress velocity - wave friction factor is parametrized by approximation of - Nielsen (1992), Coastal bottom boundary layers and sediment transport! - - April 2012 - martin.schmidt@io-warnemuende.de - -
-
-
-
-NAMELIST
- --&ocean_bbc_nml --
-
----
-- -cdbot -
-- Dimensionless coefficient for quadratic bottom drag. -
-
-[real, units: dimensionless] -- -bmf_implicit -
-- For incorporating the bottom momentum drag implicitly in time. - Default is bmf_implicit=.false. -
-
-[logical] -- -cdbot_law_of_wall -
-- For determining bottom drag coefficient using a constant roughness length. - Will take maximum between cdbot and the computed value using law of - wall log-profile. This option of use when have very very - refined vertical resolution (say on order of meters) near the bottom. - Terrain following coordinates should use this option since they generally - have very refined vertical grid spacing on topography. - Default is cdbot_law_of_wall=.false. -
-
-[logical] -- -law_of_wall_rough_length -
-- Bottom roughness length. Default is law_of_wall_rough_length=0.01m, following - the default used in the Princeton Ocean Model (POM). This value - corresponds to "Law of Wall" physics. -
-
-[real, units: metre] -- -cdbot_roughness_length -
-- For determining bottom drag coefficient using a map of the roughness length. - This approach is more relevant for coarse models - than the constant roughness length used in the cdbot_law_of_wall option. - Default is cdbot_roughness_length=.false. -
-
-[logical] -- -cdbot_roughness_uamp -
-- For determining bottom drag coefficient using a map of the roughness length - and tidal velocity amplitude. - This approach is more relevant for coarse models - than the constant roughness length used in the cdbot_law_of_wall option. - cdbot_lo <= cdbot(i,j) <= cdbot_hi. - Default is cdbot_roughness_length=.false. -
-
-[logical] -- -cdbot_HH -
-- H0 in a parameterization of cdbot_roughness_uamp. - Default is cdbot_HH=1100.0. -
-
-[real, units: m] -- -cdbot_UU -
-- U0 in a parameterization of cdbot_roughness_uamp. - Default is cdbot_UU=1.0. -
-
-[real, units: m/s] -- -cdbot_wave -
-- For determining bottom drag coefficient using a map of the roughness length - and the surface wind wave field. The modified drag coefficient is calculated - following Grant and Mattsen. Likewise this method can be improved using - more sophisticated wave models including swell. - Default is cdbot_wave=.false. -
-
-[logical] -- -uresidual -
-- Residual bottom velocity due to unresolved fluctuations (e.g., waves and tides) - that contribute to bottom dissipation. Should be set to zero when running - with explicit representation of tidal forcing and when waves are well resolved. - Default is uresidual=.05. -
-
-[real, units: m/s] -- -uvmag_max -
-- Maximum magnitude of the bottom velocity used to compute the bottom - momentum drag. Default is uvmag_max=10.0. -
-
-[real, units: m/s] -- -bmf_max -
-- Maximum magnitude of the bottom momentum drag. - Default is bmf_max=1.0. -
-
-[real, units: N/m2] -- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
-- - S.M. Griffies, 2012: Elements of MOM -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_coriolis.F90 b/src/mom5/ocean_core/ocean_coriolis.F90 index cfb87f410c..673497fc4e 100644 --- a/src/mom5/ocean_core/ocean_coriolis.F90 +++ b/src/mom5/ocean_core/ocean_coriolis.F90 @@ -1,10 +1,10 @@ module ocean_coriolis_mod #define COMP isc:iec,jsc:jec ! -!A. Rosati +! A. Rosati ! ! -!S.M. Griffies +! S.M. Griffies ! ! !@@ -98,9 +98,9 @@ module ocean_coriolis_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=128) :: version = & - '$Id: ocean_coriolis.F90,v 1.1.2.5 2012/06/01 17:55:58 Stephen.Griffies Exp $' + '$Id: ocean_coriolis.F90,v 20.0 2013/12/14 00:10:38 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! for Bgrid or Cgrid integer :: horz_grid diff --git a/src/mom5/ocean_core/ocean_coriolis.html b/src/mom5/ocean_core/ocean_coriolis.html deleted file mode 100644 index 096bff068f..0000000000 --- a/src/mom5/ocean_core/ocean_coriolis.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - Module ocean_coriolis_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_coriolis_mod
- - - - - -
-OVERVIEW
- -- Compute the Coriolis acceleration for either Bgrid or Cgrid. -
- - - -- This module computes Coriolis acceleration on either a Bgrid or Cgrid. - Coriolis and beta parameters are located at B-grid - velocity point, which equals the C-grid vorticity point. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_coriolis_init:
- -- -coriolis_force_bgrid:
- -- -coriolis_force_bgrid_implicit:
- -- -coriolis_force_cgrid:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_coriolis_init
--
-- -DESCRIPTION -
-- - Initialize the Coriolis module. -
-
-
-- - -
-coriolis_force_bgrid
--
-- -DESCRIPTION -
-- - Compute thickness and density weighted acceleration due to Coriolis - force on a B-grid. -
-
-
-- - -
-coriolis_force_bgrid_implicit
--
-- -DESCRIPTION -
-- - Contributions to thickness weighted and density weighted - acceleration from time-implicit Coriolis force. -
-
-
-- - -
-coriolis_force_cgrid
--
-- -DESCRIPTION -
-- - - Compute thickness and density weighted acceleration due to Coriolis - force on a C-grid. - -
-
-
-
-NAMELIST
- --&ocean_coriolis_nml --
-
----
-- -debug_this_module -
-- For debugging. -
-
-[logical] -- -use_this_module -
-- Must be true to add contributions from Coriolis force. -
-
-[logical] -- -acor -
-- acor=0.0 means explicit Coriolis force. 0.5 < = acor < 1.0 means semi-implicit, - and acor = 1.0 is implicit. This option is only relevant for the Bgrid, since - the C-grid compute Coriolis using 3rd order Adams-Bashforth scheme. For the Bgrid, the - semi-implicit method removes dtuv time step constraint associated with inertial oscillations, - but it leads to Coriolis force affecting energy balances. - If use two-level tendency discretization, then acor=0 is NOT allowed since the - model will be linearly unstable with growth rate going as f*(delta time). -
-
-[real] -
- - - - -
-REFERENCES
- ----
-- - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_density.F90 b/src/mom5/ocean_core/ocean_density.F90 index 9512f3c1ec..a1ef30d75b 100644 --- a/src/mom5/ocean_core/ocean_density.F90 +++ b/src/mom5/ocean_core/ocean_density.F90 @@ -529,6 +529,7 @@ module ocean_density_mod !for restart integer :: id_restart_rho = 0 +integer :: id_restart_rho_s = 0 type(restart_file_type), save :: Den_restart #include@@ -537,9 +538,9 @@ module ocean_density_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=128) :: version=& - '$Id: ocean_density.F90,v 1.1.2.2 2012/05/17 13:41:40 smg Exp $' + '$Id: ocean_density.F90,v 20.0 2013/12/14 00:10:40 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public ocean_density_init public ocean_density_end @@ -1045,6 +1046,8 @@ subroutine ocean_density_init (Grid, Domain, Time, Time_steps, Thickness, T_prog filename = 'ocean_density.res.nc' id_restart_rho = register_restart_field(Den_restart, filename, 'rho', Dens%rho(:,:,:,taup1), & domain=Dom%domain2d ) + id_restart_rho_s = register_restart_field(Den_restart, filename, 'rho_salinity', Dens%rho_salinity(:,:,:,taup1), & + domain=Dom%domain2d ) id_restart(1) = register_restart_field(Den_restart, filename, 'pressure_at_depth', Dens%pressure_at_depth(:,:,:), & domain=Dom%domain2d ) id_restart(2) = register_restart_field(Den_restart, filename, 'denominator_r', denominator_r(:,:,:), & @@ -1056,11 +1059,6 @@ subroutine ocean_density_init (Grid, Domain, Time, Time_steps, Thickness, T_prog id_restart(5) = register_restart_field(Den_restart, filename, 'drhodz_zt', Dens%drhodz_zt(:,:,:), & domain=Dom%domain2d ) - write (stdoutunit,'(/a)') ' Initialising salinity for use in density calculation' - call update_ocean_density_salinity(T_prog,taum1,Dens) - call update_ocean_density_salinity(T_prog,tau,Dens) - call update_ocean_density_salinity(T_prog,taup1,Dens) - ! pointers to relevant salinity and temperature to enhance readability salinity => Dens%rho_salinity(:,:,:,tau) temperature => T_prog(index_temp)%field(:,:,:,tau) @@ -1068,6 +1066,11 @@ subroutine ocean_density_init (Grid, Domain, Time, Time_steps, Thickness, T_prog filename = 'INPUT/ocean_density.res.nc' if (.NOT.file_exist(trim(filename)) )then + write (stdoutunit,'(/a)') ' Initialising salinity for use in density calculation' + call update_ocean_density_salinity(T_prog,taum1,Dens) + call update_ocean_density_salinity(T_prog,tau,Dens) + call update_ocean_density_salinity(T_prog,taup1,Dens) + Dens%rho(:,:,:,taum1) = density(salinity, temperature, Dens%pressure_at_depth(:,:,:)) Dens%rho(:,:,:,tau) = Dens%rho(:,:,:,taum1) Dens%rho(:,:,:,taup1) = Dens%rho(:,:,:,taum1) @@ -1102,6 +1105,25 @@ subroutine ocean_density_init (Grid, Domain, Time, Time_steps, Thickness, T_prog write(stdoutunit,'(a)') '==>Note: ocean_density_mod: did not read density derivatives from restart.' endif + ! determine whether to read rho_salinity at the initial time step of + ! integration. Early versions of MOM4p1 did not contain the rho_salinity + ! in the restart file. This allows older restart files to be used with + ! newer releases of MOM. + if(field_exist(filename, 'rho_salinity')) then + write (stdoutunit,'(/a)') ' Initializing salinity for use in density calculation from restart' + call restore_state( Den_restart, id_restart_rho_s ) + Dens%rho_salinity(:,:,:,taum1) = Dens%rho_salinity(:,:,:,taup1) + Dens%rho_salinity(:,:,:,tau) = Dens%rho_salinity(:,:,:,taup1) + call mpp_update_domains(Dens%rho_salinity(:,:,:,taum1),Dom%domain2d) + call mpp_update_domains(Dens%rho_salinity(:,:,:,tau), Dom%domain2d) + call mpp_update_domains(Dens%rho_salinity(:,:,:,taup1),Dom%domain2d) + else + write (stdoutunit,'(/a)') ' Initialising salinity for use in density calculation' + call update_ocean_density_salinity(T_prog,taum1,Dens) + call update_ocean_density_salinity(T_prog,tau,Dens) + call update_ocean_density_salinity(T_prog,taup1,Dens) + endif + endif ! compute buoyancy frequency for diagnostic purposes @@ -1538,59 +1560,59 @@ subroutine density_coeffs_init() stdoutunit=stdout() ! for the TESO10 EOS - mbfj_rho = 1.017775176234136e+3 - mbfj_alpha = 2.435473441547041e-4 - mbfj_beta = 7.284367916939847e-4 + mbfj_rho = 1.017775176234136d+3 + mbfj_alpha = 2.435473441547041d-4 + mbfj_beta = 7.284367916939847d-4 mb_neutralrho=1033.093610463980 - v01 = 9.998420897506056e+2 + v01 = 9.998420897506056d+2 v02 = 2.839940833161907 - v03 = -3.147759265588511e-2 - v04 = 1.181805545074306e-3 + v03 = -3.147759265588511d-2 + v04 = 1.181805545074306d-3 v05 = -6.698001071123802 - v06 = -2.986498947203215e-2 - v07 = 2.327859407479162e-4 - v08 = -3.988822378968490e-2 - v09 = 5.095422573880500e-4 - v10 = -1.426984671633621e-5 - v11 = 1.645039373682922e-7 - v12 = -2.233269627352527e-2 - v13 = -3.436090079851880e-4 - v14 = 3.726050720345733e-6 - v15 = -1.806789763745328e-4 - v16 = 6.876837219536232e-7 - v17 = -3.087032500374211e-7 - v18 = -1.988366587925593e-8 - v19 = -1.061519070296458e-11 - v20 = 1.550932729220080e-10 + v06 = -2.986498947203215d-2 + v07 = 2.327859407479162d-4 + v08 = -3.988822378968490d-2 + v09 = 5.095422573880500d-4 + v10 = -1.426984671633621d-5 + v11 = 1.645039373682922d-7 + v12 = -2.233269627352527d-2 + v13 = -3.436090079851880d-4 + v14 = 3.726050720345733d-6 + v15 = -1.806789763745328d-4 + v16 = 6.876837219536232d-7 + v17 = -3.087032500374211d-7 + v18 = -1.988366587925593d-8 + v19 = -1.061519070296458d-11 + v20 = 1.550932729220080d-10 v21 = 1.0 - v22 = 2.775927747785646e-3 - v23 = -2.349607444135925e-5 - v24 = 1.119513357486743e-6 - v25 = 6.743689325042773e-10 - v26 = -7.521448093615448e-3 - v27 = -2.764306979894411e-5 - v28 = 1.262937315098546e-7 - v29 = 9.527875081696435e-10 - v30 = -1.811147201949891e-11 - v31 = -3.303308871386421e-5 - v32 = 3.801564588876298e-7 - v33 = -7.672876869259043e-9 - v34 = -4.634182341116144e-11 - v35 = 2.681097235569143e-12 - v36 = 5.419326551148740e-6 - v37 = -2.742185394906099e-5 - v38 = -3.212746477974189e-7 - v39 = 3.191413910561627e-9 - v40 = -1.931012931541776e-12 - v41 = -1.105097577149576e-7 - v42 = 6.211426728363857e-10 - v43 = -1.119011592875110e-10 - v44 = -1.941660213148725e-11 - v45 = -1.864826425365600e-14 - v46 = 1.119522344879478e-14 - v47 = -1.200507748551599e-15 - v48 = 6.057902487546866e-17 + v22 = 2.775927747785646d-3 + v23 = -2.349607444135925d-5 + v24 = 1.119513357486743d-6 + v25 = 6.743689325042773d-10 + v26 = -7.521448093615448d-3 + v27 = -2.764306979894411d-5 + v28 = 1.262937315098546d-7 + v29 = 9.527875081696435d-10 + v30 = -1.811147201949891d-11 + v31 = -3.303308871386421d-5 + v32 = 3.801564588876298d-7 + v33 = -7.672876869259043d-9 + v34 = -4.634182341116144d-11 + v35 = 2.681097235569143d-12 + v36 = 5.419326551148740d-6 + v37 = -2.742185394906099d-5 + v38 = -3.212746477974189d-7 + v39 = 3.191413910561627d-9 + v40 = -1.931012931541776d-12 + v41 = -1.105097577149576d-7 + v42 = 6.211426728363857d-10 + v43 = -1.119011592875110d-10 + v44 = -1.941660213148725d-11 + v45 = -1.864826425365600d-14 + v46 = 1.119522344879478d-14 + v47 = -1.200507748551599d-15 + v48 = 6.057902487546866d-17 ! Save some multiples two_v03 = 2.0*v03 @@ -1676,116 +1698,116 @@ subroutine density_coeffs_init() ! 25 coefficients in the preTEOS10 equation of state if(temp_variable==CONSERVATIVE_TEMP) then - jmfwg_rho = 1017.842890411975 - jmfwg_alpha = 2.436057013634649e-4 - jmfwg_beta = 7.314818108935248e-4 - - a0 = 9.9983912878771446e+02 - a1 = 7.0687133522652896 - a2 = -2.2746841916232965e-02 - a3 = 5.6569114861400121e-04 - a4 = 2.3849975952593345 - a5 = 3.1761924314867009e-04 - a6 = 1.7459053010547962e-03 - a7 = 1.2192536310173776e-02 - a8 = 2.4643435731663949e-07 - a9 = 4.0525405332794888e-06 - a10 = -2.3890831309113187e-08 - a11 = -5.9016182471196891e-12 - - b0 = 1.0000000000000000 - b1 = 7.0051665739672298e-03 - b2 = -1.5040804107377016e-05 - b3 = 5.3943915288426715e-07 - b4 = 3.3811600427083414e-10 - b5 = 1.5599507046153769e-03 - b6 = -1.8137352466500517e-06 - b7 = -3.3580158763335367e-10 - b8 = 5.7149997597561099e-06 - b9 = 7.8025873978107375e-10 - b10 = 7.1038052872522844e-06 - b11 = -2.1692301739460094e-17 - b12 = -8.2564080016458560e-18 + jmfwg_rho = 1017.842890411975d0 + jmfwg_alpha = 2.436057013634649d-4 + jmfwg_beta = 7.314818108935248d-4 + + a0 = 9.9983912878771446d+02 + a1 = 7.0687133522652896d+00 + a2 = -2.2746841916232965d-02 + a3 = 5.6569114861400121d-04 + a4 = 2.3849975952593345d+00 + a5 = 3.1761924314867009d-04 + a6 = 1.7459053010547962d-03 + a7 = 1.2192536310173776d-02 + a8 = 2.4643435731663949d-07 + a9 = 4.0525405332794888d-06 + a10 = -2.3890831309113187d-08 + a11 = -5.9016182471196891d-12 + + b0 = 1.0000000000000000d+00 + b1 = 7.0051665739672298d-03 + b2 = -1.5040804107377016d-05 + b3 = 5.3943915288426715d-07 + b4 = 3.3811600427083414d-10 + b5 = 1.5599507046153769d-03 + b6 = -1.8137352466500517d-06 + b7 = -3.3580158763335367d-10 + b8 = 5.7149997597561099d-06 + b9 = 7.8025873978107375d-10 + b10 = 7.1038052872522844d-06 + b11 = -2.1692301739460094d-17 + b12 = -8.2564080016458560d-18 ! Coefficients for neutral density based on McDougall/Jackett (2005). ! To be replaced by Klocker/McDougall approach in near future. - rho_neutralrho=1024.43863927763 + rho_neutralrho=1024.43863927763d0 - a0n = 1.0022048243661291e+003 - a1n = 2.0634684367767725e-001 - a2n = 8.0483030880783291e-002 - a3n = -3.6670094757260206e-004 - a4n = -1.4602011474139313e-003 - a5n = -2.5860953752447594e-003 - a6n = -3.0498135030851449e-007 - - b0n = 1.0000000000000000 - b1n = 4.4946117492521496e-005 - b2n = 7.9275128750339643e-005 - b3n = -1.2358702241599250e-007 - b4n = -4.1775515358142458e-009 - b5n = -4.3024523119324234e-004 - b6n = 6.3377762448794933e-006 - b7n = -7.2640466666916413e-010 - b8n = -5.1075068249838284e-005 - b9n = -5.8104725917890170e-009 + a0n = 1.0022048243661291d+003 + a1n = 2.0634684367767725d-001 + a2n = 8.0483030880783291d-002 + a3n = -3.6670094757260206d-004 + a4n = -1.4602011474139313d-003 + a5n = -2.5860953752447594d-003 + a6n = -3.0498135030851449d-007 + + b0n = 1.0000000000000000d+000 + b1n = 4.4946117492521496d-005 + b2n = 7.9275128750339643d-005 + b3n = -1.2358702241599250d-007 + b4n = -4.1775515358142458d-009 + b5n = -4.3024523119324234d-004 + b6n = 6.3377762448794933d-006 + b7n = -7.2640466666916413d-010 + b8n = -5.1075068249838284d-005 + b9n = -5.8104725917890170d-009 elseif(temp_variable==POTENTIAL_TEMP) then - jmfwg_rho = 1017.728868019642 - jmfwg_alpha = 2.525481286927133e-4 - jmfwg_beta = 7.379638527217575e-4 - - a0 = 9.9984085444849347e+02 - a1 = 7.3471625860981584 - a2 = -5.3211231792841769e-02 - a3 = 3.6492439109814549e-04 - a4 = 2.5880571023991390 - a5 = -6.7168282786692355e-03 - a6 = 1.9203202055760151e-03 - a7 = 1.1798263740430364e-02 - a8 = 9.8920219266399117e-08 - a9 = 4.6996642771754730e-06 - a10 = -2.5862187075154352e-08 - a11 = -3.2921414007960662e-12 - - b0 = 1.0000000000000000 - b1 = 7.2815210113327091e-03 - b2 = -4.4787265461983921e-05 - b3 = 3.3851002965802430e-07 - b4 = 1.3651202389758572e-10 - b5 = 1.7632126669040377e-03 - b6 = -8.8066583251206474e-06 - b7 = -1.8832689434804897e-10 - b8 = 5.7463776745432097e-06 - b9 = 1.4716275472242334e-09 - b10 = 6.7103246285651894e-06 - b11 = -2.4461698007024582e-17 - b12 = -9.1534417604289062e-18 + jmfwg_rho = 1017.728868019642d0 + jmfwg_alpha = 2.525481286927133d-4 + jmfwg_beta = 7.379638527217575d-4 + + a0 = 9.9984085444849347d+02 + a1 = 7.3471625860981584d+00 + a2 = -5.3211231792841769d-02 + a3 = 3.6492439109814549d-04 + a4 = 2.5880571023991390d+00 + a5 = -6.7168282786692355d-03 + a6 = 1.9203202055760151d-03 + a7 = 1.1798263740430364d-02 + a8 = 9.8920219266399117d-08 + a9 = 4.6996642771754730d-06 + a10 = -2.5862187075154352d-08 + a11 = -3.2921414007960662d-12 + + b0 = 1.0000000000000000d+00 + b1 = 7.2815210113327091d-03 + b2 = -4.4787265461983921d-05 + b3 = 3.3851002965802430d-07 + b4 = 1.3651202389758572d-10 + b5 = 1.7632126669040377d-03 + b6 = -8.8066583251206474d-06 + b7 = -1.8832689434804897d-10 + b8 = 5.7463776745432097d-06 + b9 = 1.4716275472242334d-09 + b10 = 6.7103246285651894d-06 + b11 = -2.4461698007024582d-17 + b12 = -9.1534417604289062d-18 ! Coefficients for neutral density based on McDougall/Jackett (2005). ! To be replaced by Klocker/McDougall approach in near future. - rho_neutralrho=1024.59416751197 - - a0n = 1.0023063688892480e+003 - a1n = 2.2280832068441331e-001 - a2n = 8.1157118782170051e-002 - a3n = -4.3159255086706703e-004 - a4n = -1.0304537539692924e-004 - a5n = -3.1710675488863952e-003 - a6n = -1.7052298331414675e-007 - - b0n = 1.0000000000000000 - b1n = 4.3907692647825900e-005 - b2n = 7.8717799560577725e-005 - b3n = -1.6212552470310961e-007 - b4n = -2.3850178558212048e-009 - b5n = -5.1268124398160734e-004 - b6n = 6.0399864718597388e-006 - b7n = -2.2744455733317707e-009 - b8n = -3.6138532339703262e-005 - b9n = -1.3409379420216683e-009 + rho_neutralrho=1024.59416751197d0 + + a0n = 1.0023063688892480d+003 + a1n = 2.2280832068441331d-001 + a2n = 8.1157118782170051d-002 + a3n = -4.3159255086706703d-004 + a4n = -1.0304537539692924d-004 + a5n = -3.1710675488863952d-003 + a6n = -1.7052298331414675d-007 + + b0n = 1.0000000000000000d+000 + b1n = 4.3907692647825900d-005 + b2n = 7.8717799560577725d-005 + b3n = -1.6212552470310961d-007 + b4n = -2.3850178558212048d-009 + b5n = -5.1268124398160734d-004 + b6n = 6.0399864718597388d-006 + b7n = -2.2744455733317707d-009 + b8n = -3.6138532339703262d-005 + b9n = -1.3409379420216683d-009 endif @@ -4399,6 +4421,7 @@ subroutine ocean_density_restart(Time, Dens, time_stamp) taup1 = Time%taup1 call reset_field_pointer(Den_restart, id_restart_rho, Dens%rho(:,:,:,taup1) ) + call reset_field_pointer(Den_restart, id_restart_rho_s, Dens%rho_salinity(:,:,:,taup1) ) call save_restart(Den_restart, time_stamp) diff --git a/src/mom5/ocean_core/ocean_density.html b/src/mom5/ocean_core/ocean_density.html deleted file mode 100644 index 098bf83419..0000000000 --- a/src/mom5/ocean_core/ocean_density.html +++ /dev/null @@ -1,1241 +0,0 @@ - - - - Module ocean_density_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_density_mod
- - - - - -
-OVERVIEW
- -- Compute density and related quantities. -
- - - -- - This module computes the in-situ density and its partial derivatives with - respect to conservative temperature or potential temperature, and with - respect to salinity. - - There are three basic means for performing this calculation. - - A/ Linear equation for use in idealized studies - - This equation renders density a linear function of potential - temperature and salinity. All nonlinearities are ignored, as are - pressure effects. - - The valid range for theta and salinity arbitrary for the - linear equation of state. - - B/ pre-TEOS10 method: this method uses density as a rational - polynomial function of potential temperature, practical salinity, - and gauge pressure. There is also an implementation that computes - density as a function of conservative temperature rather than - potential temperature. The equation of state is based on that - documented in Jackett, McDougall, Feistel, Wright, and Griffies(2006). - - This equation of state is valid over a "cone-shaped" range - corresponding to - - 0psu <= salinity <= 40 psu - - -3C <= theta <= 40C "theta" = either conservative or potential temp - - 0dbar <= pressure <= 8000dbar - - with the cone getting smaller in the deeper ocean where - theta and salinity vary over a smaller range. - - Input variables are the following: - - --salinity in psu or g/kg - --conservative temperature or potential temperature (theta) in deg C - --pressure in dbars (1bar = 10dbar = 10^5 Newton/m^2 = 10^5 Pascals). - - Note that in the ocean, pressure increases roughly by 1dbar for each meter depth. - Also note that pressure is the "sea pressure", which is the absolute pressure - minus the pressure of a standard atmosphere, which is 10.1325 dbars. - - check values-
- - for "theta" = conservative temperature - rho(s=20psu,theta=20C,p=1000dbar) = 1017.842890411975 (kg/m^3)
- alpha(s=20psu,theta=20C,p=1000dbar) = 2.436057013634649e-4 (1/C)
- beta(s=20psu,theta=20C,p=1000dbar) = 7.314818108935248e-4 (1/psu)
- - for "theta" = potential temperature - rho(s=20psu,theta=20C,p=1000dbar) = 1017.728868019642 (kg/m^3)
- alpha(s=20psu,theta=20C,p=1000dbar) = 2.525481286927133e-4 (1/C)
- beta(s=20psu,theta=20C,p=1000dbar) = 7.379638527217575e-4 (1/psu)
- - This equation of state should be suitable for purposes of realistic - global ocean climate modeling. - - C/ TEOS10 method: this method makes use of the recommendations from - the SCOR working group on seawater thermodynamics, 2010. Here, density - is a function of conservative temperature and absolute salinity. - The equation is valid from 0 g/kg salinty to a very large value. - - -
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
platform_mod
time_manager_mod
field_manager_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_pressure_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_density_init:
- -- -density_diagnostics_init:
- -- -density_coeffs_init:
- -- -ocean_density_diag:
- -- -update_ocean_density_salinity:
- -- -update_ocean_density:
- -- -density_field:
- -- -density_level:
- -- -density_line:
- -- -neutral_density_field:
- -- -neutral_density_point:
- -- -potential_density:
- -- -compute_density_diagnostics:
- -- -compute_diagnostic_factors:
- -- -density_sfc:
- -- -density_point:
- -- -density_derivs_field:
- -- -density_derivs_level:
- -- -density_derivs_point:
- -- -cabbeling_thermobaricity:
- -- -calc_cabbeling_thermobaricity:
- -- -density_delta_z:
- -- -density_delta_sfc:
- -- -ocean_density_end:
- -- -ocean_density_restart:
- -- -ocean_density_chksum:
- -- -compute_buoyfreq:
- -- -buoyfreq2:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_density_init
--
-- -DESCRIPTION -
-- - Initialize the density module -
-
-
-- - -
-density_diagnostics_init
--
-- -DESCRIPTION -
-- - Register the diagnostic fields. -
-
-
-- - -
-density_coeffs_init
--
-- -DESCRIPTION -
-- - Initialize the EOS coefficients, and write some test values. -
-
-
-- - -
-ocean_density_diag
--
-- -DESCRIPTION -
-- - Diagnostic ocean density fields: neutral density and potential density. - Also send some diagnostics to diagnostic manager. -
-
-
-- - -
-update_ocean_density_salinity
--
-- -DESCRIPTION -
-- - - If TEOS-10 is being used then we need to multiply Preformed Salinity and the - Salinity factor to obtain absolute salinity for use in the TEOS10 EOS. - - If not using TEOS10 EOS, then copy the practical salinity into the - density_salinity field for use in the preTEOS10 EOS or the linear EOS. - - Note that halo values are not generally valid for taup1 until the halos - for index_salt and index_Fdelta have been updated inside of ocean_model.F90. - -
-
-
-- - -
-update_ocean_density
--
-- -DESCRIPTION -
-- - Diagnose pressure_at_depth and ocean density. - Also send some diagnostics to diagnostic manager. -
-
-
-- - -
-density_field
--
-- -DESCRIPTION -
-- - Compute density for all grid points. - - Note that pressure here is - - sea pressure = absolute pressure - press_standard (dbars) - - and salinity is in model units (psu or g/kg). - -
-
-
-- - -
-density_level
--
-- -DESCRIPTION -
-- - Compute density at a particular k-level. - - Note that pressure here is - - sea pressure = absolute pressure - press_standard (dbars) - -
-
-
-- - -
-density_line
--
-- -DESCRIPTION -
-- - Compute density at a particular k-level and j index. This scheme - is used in the vectorized version of the full convection scheme. - - Note that pressure here is - - sea pressure = absolute pressure - press_standard - -
-
-
-- - -
-neutral_density_field
--
-- -DESCRIPTION -
-- - Compute neutral density for use in various layer diagnostics. - - Two options are presently available: - - A/ use rational polynomial (to be done) - - B/ use potential density referenced to pressure potrho_press - McDougall recommends potential density referenced to 2000dbar, - since the rational polynomial is not too good. - - Note that presently, the rational polynomial method defaults to - potential density referenced to 2000dbar. - The polynomial approximation from McDougall and Jackett (2005) - is not recommended (as per Trevor McDougall, 2011). A new polynomial - is being constructed and should be ready end of 2011. - -
-
-
-- - -
-neutral_density_point
--
-- -DESCRIPTION -
-- - Compute neutral density for use in various layer diagnostics. - - Only test here the rational polynomial - approximation given by McDougall and Jackett (2005). - This test needs to be updated. - -
-
-
-- - -
-potential_density
--
-- -DESCRIPTION -
-- - Compute potential density referenced to some given sea pressure. - - Note that potential density referenced to the surface (i.e., sigma_0) - has a zero sea pressure, so pressure=0.0 should be the argument - to the function. - - Note that pressure here is - sea pressure = absolute pressure - press_standard (dbars) - - input pressure < 0 is an error, and model is brought down. - -
-
-
-- - -
-compute_density_diagnostics
--
-- -DESCRIPTION -
-- - Diagnostics related to density. -
-
-
-- - -
-compute_diagnostic_factors
--
-- -DESCRIPTION -
-- - - 1/ Compute ratio |grad neutral rho| / |grad local ref pot rho| - for use in tform water mass analysis as per Iudicone et al. (2008). - - 2/ Compute rho*Area(h)/gamma_h, where "h" is the direction where - gamma has the largest stratification, and where gamma is the - locally referenced potential density. - -
-
-
-- - -
-density_sfc
--
-- -DESCRIPTION -
-- - Compute density as a function of surface salinity, surface theta, - and in situ sea pressure. - - Note that pressure here is - sea pressure = absolute pressure - press_standard (dbars) - - For use in KPP mixed layer scheme -
-
-
-- - -
-density_point
--
-- -DESCRIPTION -
-- - Compute density at a single model grid point. - - Note that pressure here is - - sea pressure = absolute pressure - press_standard (dbars) - -
-
-
-- - -
-density_derivs_field
--
-- -DESCRIPTION -
-- - Compute partial derivative of density with respect to - temperature and with respect to salinity. Hold pressure constant. - - Pressure here is - - sea pressure = absolute press - press_standard (dbars) - -
-
-
-- - -
-density_derivs_level
--
-- -DESCRIPTION -
-- - Compute partial derivative of density with respect to - temperature and with respect to salinity. Hold pressure constant. - - Pressure here is sea pressure = absolute press - press_standard - -
-
-
-- - -
-density_derivs_point
--
-- -DESCRIPTION -
-- - Compute partial derivative of density with respect to - temperature and with respect to salinity. Do so here for a point. - - Pressure here is - - sea pressure = absolute pressure - press_standard (dbars) - -
-
-
-- - -
-cabbeling_thermobaricity
--
-- -DESCRIPTION -
-- - Diagnostic sends for cabbeling and thermobaricity parameters. - - Pressure here is - sea pressure = absolute press - press_standard (dbars) - -
-
-
-- - -
-calc_cabbeling_thermobaricity
--
-- -DESCRIPTION -
-- - Compute cabbeling and thermobaricity parameters, as defined in - McDougall (1987). - - Pressure here is - sea pressure = absolute press - press_standard (dbars) - -
-
-
-- - -
-density_delta_z
--
-- -DESCRIPTION -
-- - rho(k)-rho(k+1) for all i,j with both temperatures referenced to the - deeper pressure depth. - - Of use for KPP scheme. -
-
-
-- - -
-density_delta_sfc
--
-- -DESCRIPTION -
-- - rho(1)-rho(k+1) for all i,j. - - Of use for KPP scheme. -
-
-
-- - -
-ocean_density_end
--
-- -DESCRIPTION -
-- - - Write density and pressure_at_depth to a restart. - -
-
-
-- - -
-ocean_density_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_density_chksum
--
-- -DESCRIPTION -
-- - Compute checksums for density. -
-
-
-- - -
-compute_buoyfreq
--
-- -DESCRIPTION -
-- - - Diagnose the buoyancy frequency, both at T-points and at - vertical interfaces of T-cells. - - Author: Stephen.Griffies - -
-
-
-- - -
-buoyfreq2
--
-- -DESCRIPTION -
-- - - Diagnose the square of the buoyancy frequency at the bottom of - T-cells, NOT at T-points. - The algorithm follows that used by the private function - compute_buoyfreq in the density module. - - We take the square of the buoyancy frequency as is, we do not - smooth or force it to be positive. This allows us to search for - instabilities. - - Authors: m.bates -
-
-
-
-NAMELIST
- --&ocean_density_nml --
-
----
-- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -press_standard -
-- Standard atmospheric pressure (dbar). The realistic - EOS used in MOM requires "sea pressure" as an argument - rather than absolute pressure. Sea pressure is - absolute pressure minus a standard atmospheric pressure - of 10.1325dbar. - - For models that do have a realistic atmospheric loading, then it - is appropriate to remove 10.1325dbar prior to computing the EOS. - For those cases with zero atmospheric pressure, then it is not - necessary to remove the standard atmosphere. The default for the - press_standard is 0.0dbar. -
-
-[real, units: dbar] -- -t_test -
-- Conservative temperature or potential temperature for - testing the EOS. -
-
-[real, units: C] -- -s_test -
-- Salinity for testing the EOS. -
-
-[real, units: psu or g/kg] -- -p_test -
-- Sea pressure for testing the EOS. -
-
-[real, units: dbar] -- -tn_test -
-- Conservative temperature or potential temperature for - testing the equation for neutral density. -
-
-[real, units: C] -- -sn_test -
-- Salinity the equation for neutral density. -
-
-[real, units: psu or g/kg] -- -eos_teos10 -
-- Set to true to use TEOS-10 equation of state, which - is a function of conservative temperature and absolute - salinity. - Default eos_teos10=.false. -
-
-[logical] -- -eos_preteos10 -
-- Set to true to use pre-TEOS-10 equation of state, which - is a function of potential temperature and practical salinity, - or conservative temperature and practical salinity. - Default eos_preteos10=.false. -
-
-[logical] -- -eos_linear -
-- Set to true to use an idealized linear equation of state, which - has no pressure dependence, and is a linear function of salinity - and temperature. - Default eos_linear=.false. -
-
-[logical] -- -alpha_linear_eos -
-- Constant "thermal expansion coefficient" for linear EOS - rho = rho0 - alpha_linear_eos*theta + beta_linear_eos*salinity -
-
-[real] -- -beta_linear_eos -
-- Constant "saline contraction coefficient" for linear EOS - rho = rho0 - alpha_linear_eos*theta + beta_linear_eos*salinity -
-
-[real] -- -potrho_press -
-- Reference sea pressure for computing diagnostic potential density - of use for computing diagnostics with potential density. - Default potrho_press=2000.0 -
-
-[real, units: dbar] -- -potrho_min -
-- Minimum potential density used to partition vertical according - to potential density. -
-
-[real, units: kg/m^3] -- -potrho_max -
-- Maximum potential density used to partition vertical according - to potential density. -
-
-[real, units: kg/m^3] -- -neutral_density_omega -
-- Set to true to compute the neutral density according to - the omega method based on Klocker and McDougall. - This approach has not yet been coded. Presently as a - placeholder we use potential density referenced to 2000dbar. - Default neutral_density_omega=.false. -
-
-[logical] -- -neutral_density_potrho -
-- Set to true to compute the neutral density as just - a selected potential density, set according to potrho_press. - Since the neutral_density_omega approach has yet to be coded, - we only have the neutral_density_potrho option to choose from - at this time. - Default neutral_density_potrho=.true. -
-
-[logical] -- -neutralrho_min -
-- Minimum neutral density used to partition vertical according - to rational polynomial approximation to neutral density. -
-
-[real, units: kg/m^3] -- -neutralrho_max -
-- Maximum neutral density used to partition vertical according - to rational polynomial approximation to neutral density. -
-
-[real, units: kg/m^3] -- -theta_min -
-- Minimum conservative temperature or potential temperature used to - partition vertical according to temperature. -
-
-[real, units: C] -- -theta_max -
-- Maximum conservative temperature or potential temperature used to - partition vertical according to temperature. -
-
-[real, units: C] -- -layer_nk -
-- Number of classes used to partition vertical according to potential density, - conservative temperature, or potential temperature. Used for diagnostics. -
-
-[integer] -- -buoyfreq_smooth_vert -
-- To smooth the vertical temp and salt derivative for diagnosing - the buoyancy frequency. Default buoyfreq_smooth_vert=.true. -
-
-[logical] -- -epsln_drhodz -
-- To normalize the inverse vertical derivative of neutral density - for computing the buoyancy frequency. Default epsln_drhodz=1e-10. -
-
-[real, units: kg/m4] -- -epsln_drhodz_diag -
-- To normalize the inverse vertical derivative of neutral density - for computing neutral_rho and wdian diagnostics. - Default epsln_drhodz_diag=1e-10. -
-
-[real, units: kg/m4] -- -smax_diag -
-- A diagnostic maximum neutral slope for use in computing which direction - is deemed the most stratified. For use in computing the stratification_factor - which is then used to diagnose the dianeutral mass transport. - smax_diag should corresond to the choice used in neutral diffusion scheme. - Should have 0 <= smax_diag <= 1.0. - Default smax_diag=-1.0, in which case we compute the smax according to - the vertical to horizontal grid aspect ratio. This method ensures that - the slope is adequately "resolved" by the grid. -
-
-[real, units: dimensionless] -- -smax_min_in_column -
-- To compute the diagnostic maximum neutral slope within a column as the minimum - vertical to horizontal grid aspect ratio. This method ensures that - the slope is adequately "resolved" by the grid, and that all depths use the - same definition of "resolved", even if presumably thicker grid cells can - "resolve" larger neutral slopes. This approach is not very useful generally, - so it is retained only for testing purposes. - Default smax_min_in_column=.false. -
-
-[logical] -- -mask_domain_restart -
-- For cases where use the domain masking, it is necessary to initialize the field - denominator_r to nonzero in order to avoid NaNs in the case when change processor - layout in between restarts. Note that when use solid wall boundary conditions, - this logical should remain false in order to bitwise reproduce across restarts. - Default mask_domain_restart=.false. -
-
-[logical] -- -drhodz_diag_stable -
-- When computing drhodz_diag, we can enforce that it is negative, - thus reflecting a stable stratification. The field drhodz_diag - is used for many water mass transformation diagnostics, such as - wdian_rho. Allowing for unstable profiles can bias the wdian_rho - calculation in an improper way, since the magnitude of drhodz_diag - is very small when it is positive, whereas it is larger magnitude when - negative. Default drhodz_diag_stable=.true. -
-
-[logical] -- -grad_nrho_lrpotrho_compute -
-- To perform the diagnostic calculation of grad_nrho_lrpotrho - for analysis diagnostics. This factor is not well constrained, - and can be problematic in certain regions. So presently we do - not recommend computing it, so that the default - is grad_nrho_lrpotrho_compute=.false. -
-
-[logical] -- -grad_nrho_lrpotrho_max -
-- Maximum value used for grad_nrho_lrpotrho. - Default grad_nrho_lrpotrho_max=10. -
-
-[real, units: dimensionless] -- -grad_nrho_lrpotrho_min -
-- Minimum value used for grad_nrho_lrpotrho. - Default grad_nrho_lrpotrho_min=1. -
-
-[real, units: dimensionless] -- -smooth_stratification_factor -
-- For doing an S2D smoothing of the stratification factor used - for diagnostic purposes. Requires an extra call to mpp update. - Default smooth_stratification_factor=.false. since the smoothing - incurs a cost that should be borne only when desired. -
-
-[logical] -- -update_diagnostic_factors -
-- To update the watermass_factor and stratification_factor - for use in the water mass transformation diagnostics. - Default update_diagnostic_factors=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging nonlinear equation of state -
-
-[logical] -- -rho0_density -
-- For debugging, it is often useful to have rho=rho0 uniform. -
-
-[logical] -- -density_equal_potrho -
-- For idealized tests, set the in situ density equal to the - potential density referenced to potrho_press. All density - derivatives will also be computed with respect to constant - potrho_press pressure. - Default density_equal_potrho=.false. -
-
-[logical] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase - efficiency. - default: do_bitwise_exact_sum=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A - computationally efficient 48-term expression for the density of - seawater in terms of Conservative Temperature, and related properties - of seawater. To be submitted to Ocean Science. -
-- - IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of - seawater 2010: Calculation and use of thermodynamic properties. - Intergovernmental Oceanographic Commission, Manuals and Guides No. - 56, UNESCO (English), 196 pp. -
-- - D. Iudicone, G. Madec, and T.J. McDougall (2008) - Water-mass transformations in a neutral density framework and the - key role of light penetration. JPO vol 38, pages 1357-1376. -
-- - Jackett, McDougall, Feistel, Wright, and Griffies (2006) - Algorithms for density, potential temperature, conservative - temperature, and freezing temperature of seawater. - Journal of Atmospheric and Oceanic Technology, 2006, - volume 23, pages 1709-1728. -
-- - McDougall and Jackett (2005) - The material derivative of neutral density - Journal of Marine Research, vol 63, pages 159-185. -
-- - Feistel (2003), A new extended Gibbs thermodynamic potential - of seawater. Progress in Oceanography. vol 58, pages 43-114. -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
-- - S.M. Griffies, R.C. Pacanowski, R.M. Schmidt, and V. Balaji - Tracer Conservation with an Explicit Free Surface Method for - Z-coordinate Ocean Models - Monthly Weather Review (2001) vol 129 pages 1081--1098 -
-- - T. McDougall (1987) - Cabbeling, Thermobaricity, and water mass conversion - JGR vol 92, pages 5448-5464 -
-
- - -
-NOTES
- -- - Density is computed as a function of conservative temperature (degC) - or potential temperature (degC), salinity (psu or g/kg), and pressure (dbar). - The pressure contribution includes that from the free surface height - and the applied atmospheric and/or sea ice pressure. However, it is referenced - to standard atmosphere, so that we use the "gauge" pressure rather than the - full in-situ pressure. - - For vert_coordinate==GEOPOTENTIAL, ZSTAR, or ZSIGMA, baroclinic component of - hydrostatic pressure is not known until density is known. In this case, - the baroclinic pressure contribution to density is lagged by a time step. - rho(tau) = rho[theta(tau),s(tau), p_atm(tau) + p_fs(tau) + p_baroclinic(tau-1)]. - This issue does not arise when using vert_coordinate=PRESSURE, PSTAR, or PSIGMA. - --
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_domains.F90 b/src/mom5/ocean_core/ocean_domains.F90 index e6508cec3c..cc0d6e98aa 100644 --- a/src/mom5/ocean_core/ocean_domains.F90 +++ b/src/mom5/ocean_core/ocean_domains.F90 @@ -60,8 +60,8 @@ module ocean_domains_mod integer, dimension(2) :: domain_layout=(/1,1/) integer, dimension(2) :: io_domain_layout=(/0,0/) -character(len=128) :: version='$Id: ocean_domains.F90,v 1.1.2.2 2012/05/17 13:41:40 smg Exp $' -character(len=128) :: tagname='$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version='$Id: ocean_domains.F90,v 20.0 2013/12/14 00:10:42 fms Exp $' +character(len=128) :: tagname='$Name: tikal $' character(len=32) :: name_default = 'mom_domain' @@ -129,13 +129,11 @@ subroutine set_ocean_domain (Domain, Grid, xhalo, yhalo, name, layout, io_layout character(len=*), intent(in), optional :: name real :: ph, pc - integer :: nhp, ncp, ncp_max, ncp_min, ncpx, ncpy, lay_out(2) + integer :: n, nhp, ncp, ncp_max, ncp_min, ncpx, ncpy, lay_out(2), xsiz, ysiz integer :: mpp_stack_size=-1 character(len=32) :: name_ -#ifdef MOM_STATIC_ARRAYS - integer :: xsiz, ysiz - character(len=4) :: char_xsiz, char_ysiz -#endif + character(len=4) :: char_lay1, char_lay2, char_npes, char_xsiz, char_ysiz + if (PRESENT(layout)) domain_layout = layout if (PRESENT(io_layout)) io_domain_layout = io_layout diff --git a/src/mom5/ocean_core/ocean_domains.html b/src/mom5/ocean_core/ocean_domains.html deleted file mode 100644 index 4b687d29f4..0000000000 --- a/src/mom5/ocean_core/ocean_domains.html +++ /dev/null @@ -1,292 +0,0 @@ - - - -Module ocean_domains_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_domains_mod
- - - - - -
-OVERVIEW
- -- Set the ocean domain parameters. -
- - - -- The module computes the horizontal domain parameters needed to - run MOM in a parallel computational environment. --
- - -
-OTHER MODULES USED
- --- - - -fms_mod-
mpp_domains_mod
mpp_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_domain_init:
- -- -set_ocean_domain:
- -- -get_local_indices:
- -- -get_domain_offsets:
- -- -get_active_indices:
- -- -get_global_indices:
- -- -reduce_active_domain:
- -- -get_halo_sizes:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_domain_init
--
-- -DESCRIPTION -
-- - Initialise the domain module. -
-
-
-- - -
-set_ocean_domain
--
-- -DESCRIPTION -
-- - For setting the ocean domain layout and associated parameters. -
-
-
-- - -
-get_local_indices
--
-- -DESCRIPTION -
-- - For getting local indices from domain derived type. -
-
-
-- - -
-get_domain_offsets
--
-- -DESCRIPTION -
-- - For getting domain offsets from domain derived type. -
-
-
-- - -
-get_active_indices
--
-- -DESCRIPTION -
-- - For getting active domain indices from domain derived type. -
-
-
-- - -
-get_global_indices
--
-- -DESCRIPTION -
-- - For getting global indices from domain derived type. -
-
-
-- - -
-reduce_active_domain
--
-- -DESCRIPTION -
-- - For getting reducing the active domain -
-
-
-- - -
-get_halo_sizes
--
-- -DESCRIPTION -
-- - For getting halo sizes from domain derived type. -
-
-
-
-NAMELIST
- --&ocean_domains_nml --
-
----
-- -halo -
-- For specifying the halo size by hand. -
-
-[integer, units: dimensionless] -- -max_tracers -
-- temporary - need to call domains_init before tracer_init - Used for computing mpp_stack_size. -
-
-[integer, units: dimensionless] -- -x_cyclic_offset -
-- offset to be applied on x-direction boundary condition. Its value could - be positive or negative and the default value is 0. When the y-direction - boundary condition is folded-north(tripolar grid), x_cyclic_offset must - be 0. For torus (cyclic in x and y-direction), at least one of - x_cyclic_offset and y_cyclic_offset must be 0. -
-
-[integer, units: dimensionless] -- -y_cyclic_offset -
-- offset to be applied on y-direction boundary condition. Its value could - be positive or negative and the default value is 0. For torus (cyclic - in x and y-direction), at least one of x_cyclic_offset and - y_cyclic_offset must be 0. -
-
-[integer, units: dimensionless] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_grids.F90 b/src/mom5/ocean_core/ocean_grids.F90 index ff486705c8..3a794cf244 100644 --- a/src/mom5/ocean_core/ocean_grids.F90 +++ b/src/mom5/ocean_core/ocean_grids.F90 @@ -125,9 +125,9 @@ module ocean_grids_mod logical :: used character(len=128) :: version=& - '$Id: ocean_grids.F90,v 1.1.2.10 2012/06/04 00:11:43 Stephen.Griffies Exp $' + '$Id: ocean_grids.F90,v 20.0 2013/12/14 00:10:44 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public ocean_grids_init public set_ocean_grid_size @@ -1668,6 +1668,12 @@ subroutine set_ocean_vgrid_arrays (Domain, Grid, obc) end subroutine set_ocean_vgrid_arrays !+! +! NAME="wscale" @@ -2031,10 +2071,12 @@ end subroutine ddmix ! ! ! -subroutine blmix_kpp(diff_cbt, visc_cbu) +subroutine blmix_kpp(diff_cbt, visc_cbu, do_wave) real, dimension(isd:ied,jsd:jed,nk,2) :: diff_cbt real, dimension(isd:ied,jsd:jed,nk) :: visc_cbu + logical,intent(in) :: do_wave + real :: zt_kl_dummy real :: delhat, R, dvdzup, dvdzdn real :: viscp, difsp, diftp, visch, difsh, difth, f1 @@ -2056,7 +2098,7 @@ subroutine blmix_kpp(diff_cbt, visc_cbu) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy=0.0 - call wscale (iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale (iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) do j=jsc,jec do i = isc,iec @@ -2126,7 +2168,7 @@ subroutine blmix_kpp(diff_cbt, visc_cbu) iwscale_use_hbl_eq_zt=0 zt_kl_dummy=0.0 - call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) !----------------------------------------------------------------------- ! compute the dimensionless shape functions at the interfaces @@ -2161,10 +2203,16 @@ subroutine blmix_kpp(diff_cbt, visc_cbu) !----------------------------------------------------------------------- ! nonlocal transport term = ghats *+! Initialize some grid diagnostics. +! subroutine init_grids_diag(Grid, Time) type(ocean_grid_type), intent(inout) :: grid diff --git a/src/mom5/ocean_core/ocean_grids.html b/src/mom5/ocean_core/ocean_grids.html deleted file mode 100644 index 5b05ec6b62..0000000000 --- a/src/mom5/ocean_core/ocean_grids.html +++ /dev/null @@ -1,340 +0,0 @@ - - - -Module ocean_grids_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_grids_mod
- - --Contact: Zhi Liang - -- - -
-Reviewers: M.J. Harrison -, - - S.M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Set up the ocean model grid spacing -
- - - -- This module sets up the ocean model grid based on information read in - from the grid_spec.nc file. It translates the generic names from the - grid_spec.nc file to the names used by MOM. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
mosaic_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_grids_init:
- -- -set_ocean_grid_size:
- -- -set_ocean_hgrid_arrays:
- -- -set_ocean_vgrid_arrays:
- -- -axes_info:
- -- -update_boundaries:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_grids_init
--
-- -DESCRIPTION -
-- - Initialize the grids module. -
-
-
-- - -
-set_ocean_grid_size
--
-- -DESCRIPTION -
-- - Set the ocean grid size. Model expects the grid specification file - to be called grid_spec.nc. -
-
-
-- - -
-set_ocean_hgrid_arrays
--
-- -DESCRIPTION -
-- - Define horizontal (and some vertical) grid arrays. - ---------------------------------------------------------------------------------------------------------------------- - Grid% grid_spec grid_spec grid_spec Description - var field field field - VERSION_0 VERSION_1 VERSION_2(mosaic) ---------------------------------------------------------------------------------------------------------------------- - ocean_vgrid.nc - k=1,nk - zt zt zt zeta(2k-1) - zw zw zb zeta(2k) - - ocean_hgrid.nc - i=1,ni - j=1,nj - grid_x_t gridlon_t grid_x_T x(2i ,2) - grid_x_u gridlon_vert_t grid_x_C x(2i+1,1) - grid_y_t gridlat_t grid_y_T y(ni/4,2j) - grid_y_u gridlat_vert_t grid_y_C y(ni/4,2j+1) - -T - xt(i,j) geolon_t(i,j) x_T(i,j) x(2i,2j) - yt geolat_t y_T y(2i,2j) - dtw dtw ds_01_11_T dx(2i-1,2j) distance to western face of t cell - dte dte ds_11_21_T dx(2i,2j) distance to eastern face of t cell - dts dts ds_10_11_T dy(2i,2j-1) distance to southern face of t cell - dtn dtn ds_11_12_T dy(2i,2j) distance to northern face of t cell - - dxt dxt ds_01_21_T dx(2i,2j) +dx(2i-1,2j) width of t cell - dxtn dxtn ds_02_22_T dx(2i-1,2j+1)+dx(2i,2j+1) width of northern face of t cell - dxte dxte ds_00_20_C dx(2i,2j) +dx(2i+1,2j) distance to adjacent t cell to the east! - dyt dyt ds_10_12_T dy(2i,2j) +dy(2i,2j-1) height of t cell - dytn dytn ds_00_02_C dy(2i,2j) +dy(2i,2j+1) distance to adjacent t cell to the north! - dyte dyte ds_20_22_T dy(2i+1,2j-1)+dy(2i+1,2j) height of eastern face of t cell - -C - NOTE: The "first" (I,J) C-cell is the one shifted NE of the "first" (I,J) T-cell - - - xu geolon_c x_C x(2i+1,2j+1) - yu geolat_c y_c y(2i+1,2j+1) - dxu dxu ds_01_21_C dx(2i+1,2j+1)+dx(2i,2j+1) width of u cell - dxun dxun ds_02_22_C dx(2i,2j+2)+dx(2i+1,2j+2) width of northern face of u cell - dyu dyu ds_10_12_C dy(2i+1,2j+1)+dy(2i+1,2j) height of u cell - dyue dyue ds_20_22_C dy(2i+2,2j)+dy(2i+2,2j+1) height of eastern face of u cell - - dyun dyun ds_11_12_C dy(2i+1,2j+1)+dy(2i+1,2j+2) distance to adjacent u cell to the north - +ds_10_11_C(i,j+1) satisfies sum rule dyte(i,j)=dyun(i,j-1) - dxue dxue ds_11_21_C dx(2i+1,2j+1)+dx(2i+2,2j+1) distance to adjacent u cell to the east! - +ds_01_11_C(i+1,j) - - duw duw ds_01_11_C dx(2i,2j+1) distance to western face of u cell - due due ds_11_21_C dx(2i+1,2j+1) distance to eastern face of u cell - dus dus ds_10_11_C dy(2i+1,2j) distance to southern face of u cell - dun dun ds_11_12_C dy(2i+1,2j+1) distance to northern face of u cell - - sin_rot sin_rot angle_C sin(angle_dx(2*i+1,2*j+1) sin of rotation angle at corner cell centers - cos_rot cos_rot angle_C cos(angle_dx(2*i+1,2*j+1) cos of rotation angle at corner cell centers - -Following are the available fields in mosaic files --------------------------------------------------------- -Mosaic file fields --------------------------------------------------------- -ocean_hgrid.nc x, y, dx, dy, angle_dx, area -ocean_vgrid.nc zeta -topog.nc depth - -
-
-
-- - -
-set_ocean_vgrid_arrays
--
-- -DESCRIPTION -
-- - Compute vertical (and some horizontal) grids for ocean model. - Also compute axes information for diagnostic manager. -
-
-
-- - -
-axes_info
--
-- -DESCRIPTION -
-- - Set up axes definitions. -
-
-
-- - -
-update_boundaries
--
-- -DESCRIPTION -
-- - Set halo points at model boundaries equal to values at boundaries - if no grid connectivity exists. If model is connected along - boundary (e.g., tripolar) then use mpp_update_domains. -
-
-
-
-NAMELIST
- --&ocean_grids_nml --
-
----
-- -read_rho0_profile -
-- To read in an initial rho0(k) profile to assist in defining the - initial settings for the pressure increments dst, for use in - setting the pressure-based vertical coordinate grids. Ideally, - this profile is determined by the level averaged density in - the initial conditions. Note that it is essential to have - rho0_profile have a sensible value at all depths even if there - is no water there, since there are places where we divide by - rho0_profile in rock. Also, be mindful that with denser water - at depth, the pressure levels will be coarser at depth than if - using the trivial density profile rho0(k)=rho0. - This option is experimental, so it is recommended that user - maintain the default read_rho0_profile=.false. -
-
-[logical] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is do_bitwise_exact_sum=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging. Note that most of the debugging stuff - has been removed, but keep flag around in case need in future. -
-
-[logical] -- -verbose_init -
-- Prints out lots of initial checksums. Useful to have on, so - defaulted to true. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, M.J. Harrison, A. Rosati, and R.C. Pacanowski - A Technical Guide to MOM4 (2003) -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_model.F90 b/src/mom5/ocean_core/ocean_model.F90 index 2a388fa777..08f8b6a352 100644 --- a/src/mom5/ocean_core/ocean_model.F90 +++ b/src/mom5/ocean_core/ocean_model.F90 @@ -1,9 +1,9 @@ module ocean_model_mod ! -!Stephen M. Griffies +! Stephen M. Griffies ! ! -!Matt Harrison +! Matt Harrison ! ! !@@ -212,7 +212,7 @@ module ocean_model_mod use fms_mod, only: clock_flag_default use fms_io_mod, only: set_domain, nullify_domain, parse_mask_table use mpp_domains_mod, only: domain2d, BITWISE_EXACT_SUM, NON_BITWISE_EXACT_SUM -use mpp_domains_mod, only: mpp_update_domains, BGRID_NE, CGRID_NE +use mpp_domains_mod, only: mpp_update_domains, BGRID_NE, CGRID_NE, mpp_get_compute_domain use mpp_mod, only: input_nml_file, mpp_error, mpp_pe, mpp_npes, mpp_chksum, stdlog, stdout use mpp_mod, only: mpp_clock_id, mpp_clock_begin, mpp_clock_end use mpp_mod, only: CLOCK_COMPONENT, CLOCK_SUBCOMPONENT, CLOCK_MODULE, CLOCK_ROUTINE @@ -330,8 +330,13 @@ module ocean_model_mod use ocean_wave_mod, only: ocean_wave_init, ocean_wave_end, ocean_wave_model #ifdef ENABLE_ODA +#ifdef ENABLE_ECDA + use oda_types_mod, only : da_flux_type + use oda_driver_ecda_mod, only : init_oda, oda, oda_end +#else use oda_driver_mod, only : init_oda, oda #endif +#endif implicit none @@ -340,6 +345,10 @@ module ocean_model_mod #include +#if defined (ENABLE_ODA) && defined (ENABLE_ECDA) + integer :: is_sfc, ie_sfc, js_sfc, je_sfc, i_shift, j_shift, ii, jj ! snz +#endif + #ifdef MOM_STATIC_ARRAYS real, dimension(isd:ied,jsd:jed,nk,2) :: diff_cbt ! diffusion coefficient at base of tracer cells (m^2/sec): @@ -447,8 +456,8 @@ module ocean_model_mod character(len=32) :: horizontal_grid='bgrid' integer :: horz_grid=1 - character(len=128) :: version = '$Id: ocean_model.F90,v 1.1.2.26.2.1 2012/06/17 12:29:16 smg Exp $' - character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' + character(len=128) :: version = '$Id: ocean_model.F90,v 20.0 2013/12/14 00:10:47 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' type(ocean_external_mode_type), save :: Ext_mode type(ocean_adv_vel_type), save :: Adv_vel @@ -471,6 +480,10 @@ module ocean_model_mod type(ocean_wave_type), target, save :: Waves +#if defined (ENABLE_ODA) && defined (ENABLE_ECDA) + type(da_flux_type), target, save :: da_flux ! snz +#endif + ! identification numbers for mpp clocks integer :: id_init integer :: id_advect @@ -601,7 +614,14 @@ module ocean_model_mod logical :: use_blobs =.false. logical :: introduce_blobs =.false. logical :: use_velocity_override =.false. + logical :: do_wave =.false. + ! Namelist variables for ECDA + real :: beta_txty = 0.0 + real :: beta_tf = 0.0 + real :: beta_qf = 0.0 + real :: beta_lwsw = 0.0 + type, public :: ocean_state_type; private ! This type is private, and can therefore vary between different ocean models. ! All information entire ocean state may be contained here, although it is not @@ -615,7 +635,7 @@ module ocean_model_mod baroclinic_split, barotropic_split, surface_height_split, & layout, io_layout, debug, vertical_coordinate, dt_ocean, cmip_units,& horizontal_grid, use_blobs, use_velocity_override, mask_table, & - introduce_blobs + introduce_blobs, beta_txty, beta_tf, beta_qf, beta_lwsw contains @@ -1148,6 +1168,22 @@ subroutine ocean_model_init(Ocean, Ocean_state, Time_init, Time_in) allocate(rossby_radius(isd:ied,jsd:jed)) allocate(swheat(isd:ied,jsd:jed,nk)) #endif +#if defined (ENABLE_ODA) && defined (ENABLE_ECDA) + allocate(da_flux%u_flux(isd:ied,jsd:jed)) ! snz + allocate(da_flux%v_flux(isd:ied,jsd:jed)) ! snz + ! allocate(da_flux%t_flux(isd:ied,jsd:jed)) ! snz + ! allocate(da_flux%q_flux(isd:ied,jsd:jed)) ! snz + ! allocate(da_flux%lw_flux(isd:ied,jsd:jed)) ! snz + ! allocate(da_flux%salt_flux(isd:ied,jsd:jed)) ! snz + + da_flux%u_flux(:,:) = 0.0 ! snz + da_flux%v_flux(:,:) = 0.0 ! snz + ! da_flux%t_flux(:,:) = 0.0 ! snz + ! da_flux%q_flux(:,:) = 0.0 ! snz + ! da_flux%lw_flux(:,:) = 0.0 ! snz + ! da_flux%salt_flux(:,:) = 0.0 ! snz +#endif + diff_cbt = 0.0 visc_cbu = 0.0 visc_cbt = 0.0 @@ -1280,7 +1316,11 @@ subroutine ocean_model_init(Ocean, Ocean_state, Time_init, Time_in) #ifdef ENABLE_ODA +#ifdef ENABLE_ECDA + call init_oda(Time, Domain, Grid, T_prog(:)) +#else call init_oda(Domain, Grid, Time, T_prog(:)) +#endif #endif call ocean_drifters_init(Domain, Grid, Time, T_prog(:), Velocity, Adv_vel) @@ -1304,6 +1344,10 @@ subroutine ocean_model_init(Ocean, Ocean_state, Time_init, Time_in) call nullify_domain() call mpp_clock_end(id_init) +#if defined (ENABLE_ODA) && defined (ENABLE_ECDA) + call mpp_get_compute_domain(Ocean%Domain, is_sfc, ie_sfc, js_sfc, je_sfc) ! snz +#endif + write(stdoutunit,'(/52x,a/)') '======== COMPLETED MOM INITIALIZATION ========' end subroutine ocean_model_init @@ -1338,13 +1382,14 @@ end subroutine ocean_model_init ! ! subroutine update_ocean_model(Ice_ocean_boundary, Ocean_state, Ocean_sfc, & - time_start_update, Ocean_coupling_time_step) + time_start_update, Ocean_coupling_time_step, do_wave_in) type(ice_ocean_boundary_type), intent(inout) :: Ice_ocean_boundary type(ocean_state_type), pointer :: Ocean_state type(ocean_public_type), intent(inout) :: Ocean_sfc type(time_type), intent(in) :: time_start_update type(time_type), intent(in) :: Ocean_coupling_time_step - + logical, optional, intent(in) :: do_wave_in + integer :: seconds, days integer :: num_ocn integer :: taum1, tau, taup1 integer :: i, j, k, n @@ -1360,6 +1405,8 @@ subroutine update_ocean_model(Ice_ocean_boundary, Ocean_state, Ocean_sfc, & first_ocn_call=.false. endif + !Override do_wave by the coupler value + if(present(do_wave_in)) do_wave=do_wave_in ! Loop over num_ocean_calls, moved here from the coupler due to interface changes do num_ocn = 1,num_ocean_calls @@ -1463,6 +1510,29 @@ subroutine update_ocean_model(Ice_ocean_boundary, Ocean_state, Ocean_sfc, & call ocean_wave_model(Time, Waves, Ice_ocean_boundary) call mpp_clock_end(id_wave) +#if defined (ENABLE_ODA) && defined (ENABLE_ECDA) + i_shift = isc - is_sfc + j_shift = jsc - js_sfc + do j=js_sfc, je_sfc + jj = j + j_shift + do i=is_sfc, ie_sfc + ii = i + i_shift + Ice_ocean_boundary%u_flux(i,j) = Ice_ocean_boundary%u_flux(i,j) +& + beta_txty*da_flux%u_flux(ii,jj) + Ice_ocean_boundary%v_flux(i,j) = Ice_ocean_boundary%v_flux(i,j) +& + beta_txty*da_flux%v_flux(ii,jj) + ! Ice_ocean_boundary%t_flux(i,j) = Ice_ocean_boundary%t_flux(i,j) +& + ! beta_tf*da_flux%t_flux(ii,jj) + ! Ice_ocean_boundary%q_flux(i,j) = Ice_ocean_boundary%q_flux(i,j) +& + ! beta_qf*da_flux%q_flux(ii,jj) + ! Ice_ocean_boundary%lw_flux(i,j) = Ice_ocean_boundary%lw_flux(i,j) +& + ! beta_lwsw*da_flux%lw_flux(ii,jj) + ! Ice_ocean_boundary%salt_flux(i,j) = Ice_ocean_boundary%salt_flux(i,j) +& + ! beta_lwsw*da_flux%salt_flux(ii,jj) + enddo + enddo +#endif + ! obtain surface boundary fluxes from coupler call mpp_clock_begin(id_sbc) call get_ocean_sbc(Time, Ice_ocean_boundary, Thickness, Dens, Ext_mode, & @@ -1505,7 +1575,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, Ocean_state, Ocean_sfc, & call mpp_clock_begin(id_vmix) call vert_mix_coeff(Time, Thickness, Velocity, T_prog(1:num_prog_tracers),& T_diag(1:num_diag_tracers), Dens, swflx, sw_frac_zt, pme, & - river, visc_cbu, visc_cbt, diff_cbt, surf_blthick) + river, visc_cbu, visc_cbt, diff_cbt, surf_blthick, do_wave) call mpp_clock_end(id_vmix) ! compute ocean tendencies from tracer packages @@ -1879,7 +1949,52 @@ subroutine update_ocean_model(Ice_ocean_boundary, Ocean_state, Ocean_sfc, & ! modifications to prognostic variables using ocean data assimilation #ifdef ENABLE_ODA call mpp_clock_begin(id_oda) +#ifdef ENABLE_ECDA + call get_time(Time%model_time, seconds, days) + if (seconds == 0 .or. seconds == 43200 ) then + do j=js_sfc, je_sfc + jj = j + j_shift + do i=is_sfc, ie_sfc + ii = i + i_shift + da_flux%u_flux(ii,jj) = Ice_ocean_boundary%u_flux(i,j) + da_flux%v_flux(ii,jj) = Ice_ocean_boundary%v_flux(i,j) + ! da_flux%t_flux(ii,jj) = Ice_ocean_boundary%t_flux(i,j) + ! da_flux%q_flux(ii,jj) = Ice_ocean_boundary%q_flux(i,j) + ! da_flux%lw_flux(ii,jj) = Ice_ocean_boundary%lw_flux(i,j) + ! da_flux%salt_flux(ii,jj) = Ice_ocean_boundary%salt_flux(i,j) + enddo + enddo + end if + + call mpp_update_domains(da_flux%u_flux(:,:), da_flux%v_flux(:,:), Domain%domain2d,gridtype=BGRID_NE) + ! call mpp_update_domains(da_flux%t_flux(:,:), Domain%domain2d) + ! call mpp_update_domains(da_flux%q_flux(:,:), Domain%domain2d) + ! call mpp_update_domains(da_flux%lw_flux(:,:), Domain%domain2d) + ! call mpp_update_domains(da_flux%salt_flux(:,:), Domain%domain2d) + + call mpp_update_domains(Velocity%u(:,:,:,1,taup1), Velocity%u(:,:,:,2,taup1), Domain%domain2d,gridtype=BGRID_NE) + do n = 1, num_prog_tracers ! snz + call mpp_update_domains(T_prog(n)%field(:,:,:,taup1), Domain%domain2d) + end do + call mpp_update_domains(Ext_mode%eta_t(:,:,taup1), Domain%domain2d) + + call oda(Time, T_prog(1:num_prog_tracers), Velocity, da_flux, Ext_mode) + + call mpp_update_domains(Ext_mode%eta_t(:,:,taup1), Domain%domain2d) + + call mpp_update_domains(da_flux%u_flux(:,:), da_flux%v_flux(:,:), Domain%domain2d,gridtype=BGRID_NE) + ! call mpp_update_domains(da_flux%t_flux(:,:), Domain%domain2d) + ! call mpp_update_domains(da_flux%q_flux(:,:), Domain%domain2d) + ! call mpp_update_domains(da_flux%lw_flux(:,:), Domain%domain2d) + ! call mpp_update_domains(da_flux%salt_flux(:,:), Domain%domain2d) + + do n = 1, num_prog_tracers ! snz + call mpp_update_domains(T_prog(n)%field(:,:,:,taup1), Domain%domain2d) + end do + call mpp_update_domains(Velocity%u(:,:,:,1,taup1), Velocity%u(:,:,:,2,taup1), Domain%domain2d,gridtype=BGRID_NE) +#else call oda(Time, T_prog(1:num_prog_tracers)) +#endif call mpp_clock_end(id_oda) #endif @@ -2070,6 +2185,10 @@ subroutine ocean_model_end(Ocean_sfc, Ocean_state, Time_in) integer :: stdoutunit stdoutunit=stdout() +#if defined (ENABLE_ODA) && defined (ENABLE_ECDA) + call oda_end() +#endif + call ocean_blob_end(Time, T_prog(:), Lagrangian_system) call ocean_advection_velocity_end(Time, Adv_vel, use_blobs) call ocean_tracer_end(Time, T_prog(:), T_diag(:), use_blobs) @@ -2085,9 +2204,9 @@ subroutine ocean_model_end(Ocean_sfc, Ocean_state, Time_in) call ocean_thickness_end(Time, Grid, introduce_blobs, Thickness) call ocean_density_end(Time, Dens, use_blobs) if(have_obc) call ocean_obc_end(Time, have_obc) - call ocean_sfc_end() + call ocean_sfc_end(Ocean_sfc) call ocean_vert_mix_end(Time) - call ocean_drifters_end() + call ocean_drifters_end(Grid) call ocean_wave_end(Time, Waves) write (stdoutunit,'(//,1x,a)') & diff --git a/src/mom5/ocean_core/ocean_model.html b/src/mom5/ocean_core/ocean_model.html deleted file mode 100644 index b1c52a1df8..0000000000 --- a/src/mom5/ocean_core/ocean_model.html +++ /dev/null @@ -1,1020 +0,0 @@ - - - - Module ocean_model_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_model_mod
- - --Contact: Stephen M. Griffies -, - Matt Harrison - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Time step the ocean model using either a twolevel staggered scheme - (the default) or threelevel leap-frog scheme (the older approach). - Threelevel scheme remains only for legacy purposes and is not - recommended for normal use. -
- - - -- Top level module for ocean model. Contains routines for - initialization, termination, and update of ocean model state. - - Design consideration: declarations of top level ocean variables - are private to this module and hence are only available to other routines - through argument lists. For instance, timestep information is passed to - the various modules on the initialization call and stored internally - in the respective modules. This is a crucial design consideration sinces - it maintains modularity and hence maintainability of the code. --
- - -
-OTHER MODULES USED
- --- - - -fms_mod-
fms_io_mod
mpp_domains_mod
mpp_mod
stock_constants_mod
time_interp_external_mod
time_manager_mod
ocean_advection_velocity_mod
ocean_barotropic_mod
ocean_bbc_mod
ocean_bih_friction_mod
ocean_blob_mod
ocean_convect_mod
ocean_coriolis_mod
ocean_density_mod
ocean_diagnostics_mod
ocean_domains_mod
ocean_form_drag_mod
ocean_grids_mod
ocean_increment_eta_mod
ocean_increment_tracer_mod
ocean_increment_velocity_mod
ocean_lap_tracer_mod
ocean_bih_tracer_mod
ocean_lap_friction_mod
ocean_mixdownslope_mod
ocean_momentum_source_mod
ocean_nphysics_mod
ocean_nphysics_new_mod
ocean_obc_mod
ocean_operators_mod
ocean_overexchange_mod
ocean_overflow_mod
ocean_overflow_OFP_mod
ocean_passive_mod
ocean_pressure_mod
ocean_rivermix_mod
ocean_riverspread_mod
ocean_parameters_mod
ocean_sbc_mod
ocean_shortwave_mod
ocean_sigma_transport_mod
ocean_sponges_eta_mod
ocean_sponges_tracer_mod
ocean_sponges_velocity_mod
ocean_submesoscale_mod
ocean_tempsalt_mod
ocean_thickness_mod
ocean_topog_mod
ocean_tracer_advect_mod
ocean_tracer_mod
ocean_tracer_util_mod
ocean_tpm_mod
ocean_types_mod
ocean_util_mod
ocean_velocity_advect_mod
ocean_velocity_diag_mod
ocean_velocity_mod
ocean_vert_mix_mod
ocean_vert_gotm_mod
ocean_workspace_mod
ocean_xlandinsert_mod
ocean_xlandmix_mod
ocean_drifters_mod
wave_types_mod
ocean_wave_mod
oda_driver_mod
-PUBLIC INTERFACE
----
-- -ocean_model_init:
- -- -update_ocean_model:
- -- -get_ocean_grid_size:
- -- -get_ocean_domain:
- -- -ocean_model_init_sfc:
- -- -ocean_model_flux_init:
- -- -ocean_model_end:
- -- -ocean_model_restart:
- -- -ocean_stock_pe:
- -- -mom4_get_Tsurf:
- -- -mom4_get_Ssurf:
- -- -mom4_get_thickness:
- -- -mom4_get_density:
- -- -mom4_get_prog_tracer:
- -- -mom4_get_temperature_index:
- -- -mom4_get_salinity_index:
- -- -mom4_get_dimensions:
- -- -mom4_get_UVsurf:
- -- -mom4_get_UV:
- -- -mom4_U_to_T_2d:
- -- -mom4_get_latlon_UV:
-- - Gets horizontal velocity components (u,v) (in m/s) on T points (A mesh) - along geographical (latlon) directions in compute domain. -
-- -mom4_get_diag_axes:
- -- -mom4_get_num_diag_tracers:
-- - Returns the module variable num_diag_tracers -
-- -mom4_get_num_prog_tracers:
-- - Returns the module variable num_prog_tracers -
-- -mom4_get_surface_tmask:
-- - Gets the pointer to 2D array Grid%tmask(:,:,1) -
-- -mom4_get_ocean_data:
-- - Gets one of the 2D array data of ocean type -
-
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_model_init
--
-- -DESCRIPTION -
-- - Initialize the ocean model. - Arguments: - Ocean (inout) - A structure containing various publicly visible ocean - surface properties after initialization. - OS (pointer)- A structure whose internal contents are private - to ocean_model_mod that may be used to contain all - information about the ocean's interior state. - Time_init (in) - The start time for the coupled model's calendar. - Time_in (in) - The time at which to initialize the ocean model. -
-
-
-- - -
-update_ocean_model
--
-- -DESCRIPTION -
-- - Update in time the ocean model fields. - This subroutine uses the forcing in Ice_ocean_boundary to advance the - ocean model's state from the input value of Ocean_state (which must be for - time time_start_update) for a time interval of Ocean_coupling_time_step, - returning the publicly visible ocean surface properties in Ocean_sfc and - storing the new ocean properties in Ocean_state. - - Arguments: - Ice_ocean_boundary - A structure containing the various forcing - fields coming from the ice. It is intent in. - Ocean_state - A structure containing the internal ocean state. - Ocean_sfc - A structure containing all the publicly visible ocean - surface fields after a coupling time step. - time_start_update - The time at the beginning of the update step. - Ocean_coupling_time_step - The amount of time over which to advance - the ocean. - Note: although several types are declared intent(inout), this is to allow for - the possibility of halo updates and to keep previously allocated memory. - In practice, Ice_ocean_boundary is intent in, Ocean_state is private to - this module and intent inout, and Ocean_sfc is intent out. -
-
-
-- - -
-get_ocean_grid_size
--
-- -DESCRIPTION -
-- - Obtain the ocean grid size. -
-
-
-- - -
-get_ocean_domain
--
-- -DESCRIPTION -
-- - Obtain the ocean domain size. -
-
-
-- - -
-ocean_model_init_sfc
--
-- -DESCRIPTION -
-- - Call ocean_tpm_init_sfc and pass it the needed arguments, most of which - are local to the ocean model. -
-
-
-- - -
-ocean_model_flux_init
--
-- -DESCRIPTION -
-- - Call ocean_tpm_flux_init and pass it the needed arguments, most of which - are local to the ocean model. - - Currently, no arguments are passed. -
-
-
-- - -
-ocean_model_end
--
-- -DESCRIPTION -
-- - Close down the ocean model - This subroutine terminates the model run, saving the ocean state in a - restart file and deallocating any data associated with the ocean. - - NOTE from nnz: This module keeps its own Time and does not need the Time_in argument. - Arguments: - Ocean_state (type(ocean_state_type), pointer) - A structure containing the internal ocean state. - Time_in (type(time_type), intent(in)) - The model time, used for writing restarts. - Ocean_sfc (type(ocean_public_type), optional, intent(inout))- An ocean_public_type structure that is to be - deallocated upon termination. -
-
-
-- - -
-ocean_model_restart
--
-- -DESCRIPTION -
-- - write out restart file. -
-
-
-- - -
-ocean_stock_pe
--
-- -DESCRIPTION -
-- - Returns stocks of total ocean heat and water water for conservation - checks. Report here values just on a single PE. Global sums - are done in the coupler. - - This routine is part of a group of similar routines in other - FMS component models that aims to quantify the conservation of - scalar properties between the component models when running - coupled models. - -
-
-
-- - -
-mom4_get_Tsurf
--
-- -DESCRIPTION -
-- - Return the surface temperature in degrees K -
-
-
-- - -
-mom4_get_Ssurf
--
-- -DESCRIPTION -
-- - Return the surface salinity in psu -
-
-
-- - -
-mom4_get_thickness
--
-- -DESCRIPTION -
-- - Return thickness (in meters) of each layer. -
-
-
-- - -
-mom4_get_density
--
-- -DESCRIPTION -
-- - Return density (in kg/m^3). -
-
-
-- - -
-mom4_get_prog_tracer
--
-- -DESCRIPTION -
-- - Return prognostic tracer data. -
-
-
-- - -
-mom4_get_temperature_index
--
-- -DESCRIPTION -
-- - Return temperature index from prognostic tracer table, which can - then be used to extract data. -
-
-
-- - -
-mom4_get_salinity_index
--
-- -DESCRIPTION -
-- - Return salt index from prognostic tracer table, which can - then be used to extract data. -
-
-
-- - -
-mom4_get_dimensions
--
-- -DESCRIPTION -
-- - Return dimensions of data in compute domain -
-
-
-- - -
-mom4_get_UVsurf
--
-- -DESCRIPTION -
-- - Return horizontal velocity vector components (u,v) on the - A grid (tracer-points). - - Note that these velocity components are oriented according to the - grid lines (i-lines and j-lines). They are generally NOT mapped - to latitude-longitude lines, unless using a spherical coordinate - grid specification. -
-
-
-- - -
-mom4_get_UV
--
-- -DESCRIPTION -
-- - Return horizontal velocity vector (u,v) (in m/s) on T points (A mesh). - - Note that these velocity components are oriented according to the - grid lines (i-lines and j-lines). They are generally NOT mapped - to latitude-longitude lines, unless using a spherical coordinate - grid specification. -
-
-
-- - -
-mom4_U_to_T_2d
--
-- -DESCRIPTION -
-- - Interpolate (u,v) velocity components from U (B-grid) to - T points (A-grid). -
-
-
-- - -
-mom4_get_latlon_UV
-use ocean_model_mod real, dimension(isc:, jsc:, :) :: u,v integer :: ierr call mom4_get_latlon_UV (ua, va, ierr)--
-- -DESCRIPTION -
-- - Note that these velocity components are oriented along the - geographical latitude-longitude lines. - - im,j i,j - B-------B-------B-------B y - | | | | ^ - | | i,j| | | /lon - |---A---|---A---|---A---| | / - | | | | \ | / - | |im,jm |i,jm | \|/ rot angle - B-------B-------B-------B ---X-------------> x - | | | | /|\ - | | | | / | \ - |---A---|---A---|---A---| | \lat - | | | | | \ - | | | | - B-------B-------B-------B - -
-
-
-- -OUTPUT -
-- -
--
-- -ua - array will contain velocity component along x direction upon return - -
[real, dimension(isc:, jsc:, :)]- -va - array will contain velocity component along y direction upon return - -
[real, dimension(isc:, jsc:, :)]- -ierr - error status will be zero for success and nonzero for failure - -
[ineger]
-- - -
-mom4_get_diag_axes
--
-- -DESCRIPTION -
-- - Return axes indices for diag manager. -
-
-
-- - -
-mom4_get_num_diag_tracers
-use ocean_model_mod mom4_get_num_diag_tracers ()--
-- -DESCRIPTION -
-- - This function returns the number of ocean diagnostic tracers if not -1. - It send a FATAL message if num_diag_tracers is not set (i.e. is -1) - before this function call. -
-
-
-- -INPUT -
-- -
--
-- -- No inputs needed. - -
[]
-- -OUTPUT -
-- -
--
-- -- This function returns an integer. - -
[integer]
-- - -
-mom4_get_num_prog_tracers
-use ocean_model_mod mom4_get_num_prog_tracers ()--
-- -DESCRIPTION -
-- - This function returns the number of ocean prognostic tracers if not -1. - It send a FATAL message if num_prog_tracers is not set (i.e. is -1) - before this function call. -
-
-
-- -INPUT -
-- -
--
-- -- No inputs needed. - -
[]
-- -OUTPUT -
-- -
--
-- -- This function returns an integer. - -
[integer]
-- - -
-mom4_get_surface_tmask
-use ocean_model_mod real, dimension(:,:), pointer :: temp call mom4_get_surface_tmask (temp)--
-- -DESCRIPTION -
-- - This subroutine gets the pointer to a 2D array with values of the tmask - (land/sea mask for T cells based on s-coordinate) at the ocean surface . -
-
-
-- -OUTPUT -
-- -
--
-- -surfaceTmask - pointer to 2 dimensional array of tmask at the ocean surface. - -
[real, dimension(:,:),pointer]
-- - -
-mom4_get_ocean_data
-use ocean_model_mod real, dimension(:,:), pointer :: temp call mom4_get_ocean_data (Ocean,'s_surf',temp)--
-- -DESCRIPTION -
-- - This subroutine gets one of the following data arrays of ocean_public_type - depending on the passed "name" argument, it sends a FATAL signal otherwise - Ocean%t_surf when name='t_surf' - Ocean%s_surf when name='s_surf' - Ocean%u_surf when name='u_surf' - Ocean%v_surf when name='v_surf' - Ocean%sea_lev when name='sea_lev' - Ocean%frazil when name='frazil' -
-
-
-- -INPUT -
-- -
--
-- -Ocean - ocean type - -
[type(ocean_public_type)]- -name - one of 't_surf','s_surf','u_surf','v_surf','sea_lev','frazil' - -
[character(len=*)]
-- -OUTPUT -
-- -
--
-- -dataArrayPointer - pointer to 2 dimensional array corresponding to "name" argument, at the ocean surface. - -
[real, dimension(:,:), pointer]
-
-NAMELIST
- --&ocean_model_nml --
-
----
-- -layout -
-- Processor domain layout for ocean model. -
-
-[integer] -- -io_layout -
-- Processor IO domain layout for ocean model. The default value is (0,0). - If either io_layout(1) or (2) is 0, it will default to the number of - processors in the computational layout, except restart file will default - to single file if fms_io_nml fileset_write is set to 'single'. When - both entry of io_layout is positive, io_domain will be defined(a pointer in domain2d) - and number of distributed files will be layout(1)*layout(2). For example, assume - the restart file is ocean_velocity.res.nc and the diagnostics file is ocean_daily.nc, - if the layout = (1,2), the restart files will be ocean_velocity.res.nc.0000 and - ocean_veloicity.res.nc.0001, the diagnostics files will be ocean_daily.res.nc.0000 - and ocean_daily.res.nc.0001. When the io_domain is defined, restart file and - diagnostics file name will be controlled by the io_domain (ignoring fms_io_nml fileset_write). -
-
-[integer, dimension(2)] -- -dt_ocean -
-- Ocean model time step in seconds. -
-
-[integer, default: -1] -- -time_tendency -
-- - Possible time stepping schemes are the following. - - 1. "threelevel" has the following characteristics - - leap-frog for the time tendency which means the - inviscid/nondissipative processes are at time tau. - - forward for lateral mixing processes (dissipation at taum1) - - implicit for vertical dissipative (with aidif = 1.0) - - semi-implicit for Coriolis (with acor>0) - - Because of the need to apply time filters to suppress - leap-frog splitting, the threelevel time stepping scheme - does not conserve total tracer content in the model. - - 2. "twolevel" has the following characteristics: - - staggered 2nd order forward time tendency, which means - that tracer advection, lateral tracer and velocity mixing, - are at time tau. Pressure gradients are at taup1. - - Adams-Bashforth (either 2nd or 3rd order) for velocity advection - Third order is default as it is more stable. - - implicit vertical mixing (with aidif = 1.0) - - semi-implicit for Coriolis (with acor > 0) - - This scheme conserves total volume and tracer in the ocean model. - -
-
-[character] -- -vertical_coordinate -
-- This string determines the vertical coordinate used in MOM. - - There are 3 + 3 options in MOM: - Depth-based Boussinesq are 'geopotential', 'zstar', 'zsigma', - Pressure-based non-Boussinesq are 'pressure', 'pstar', and 'psigma'. - - The two terrain-following sigma options are not well tested in MOM, - whereas the other options are standard. The recommended Boussinesq - vertical coordinate is zstar, and the recommended non-Boussineq - coordinate is pstar. The default is vertical_coordinate='zstar'. -
-
-[character] -- -horizontal_grid -
-- This string determines the arrangement of variables on the - discrete horizontal grid. The standard case is horizontal_grid='bgrid'. - However, the C-grid is being developed in MOM. It is not yet - supported for general use. Default horizontal_grid='bgrid'. -
-
-[character] -- -impose_init_from_restart -
-- Consider the following situation: We have run the model for many years - and generated restarts. Time%init is then .false. Then, we wish to start - a series of perturbation experiments from this restart file. The generic - situation is for Time%init to then be .true. However, we need it to be - .false. in MOM in order to have a proper reading of the full restart - information. Setting impose_init_from_restart=.true. will facilitate - this setup. The default is impose_init_from_restart=.false., in which case - the model will run through its normal start/stop segments using restarts. -
-
-[logical] -- -baroclinic_split -
-- baroclinic_split = dtts/dtuv - = (tracer time step)/(baroclinic time step) - = (ocean model time step)/(baroclinic time step) - Transients corrupted if baroclinic_split > 1, so it is recommended - to use baroclinic_split=1. -
-
-[integer] -- -barotropic_split -
-- Ratio barotropic_split = dtuv/dtbt - = (baroclinic time step)/(barotropic time step). - Must be large enough to resolve the barotropic gravity waves - captured by the barotropic part of the model. - Barotropic waves are dissipated when this splitting - is greater than unity. Model algorithm is not fully - implemented when barotropic_split=1, so user beware - if wishing to run an unsplit model simulation. -
-
-[integer] -- -surface_height_split -
-- Ratio surface_height_split = dtts/dteta - = (tracer time step)/(surface height time step) - = (tracer time step)/(bottom pressure time step) - Typically this split is set to unity for models where baroclinic_split=1, - but something larger when baroclinic_split is order 10. dteta is the time - step used for update of eta_t or pbot_t. If surface_height_split is - not equal to unity, then tracer conservation properties are compromised. -
-
-[integer] -- -reinitialize_thickness -
-- When initialized with a nontrivial eta field, it is - necessary to reinitialize the thickness arrays. -
-
-[logical] -- -cmip_units -
-- For CMIP output, we need to have temperature in deg K and - mass transport in kg/s. The flag cmip_units=.true. will - diagnose CMIP5-related fields with the CMIP units for sending - to the diagnostic manager. - Default cmip_units=.false. -
-
-[logical] -- -use_blobs -
-- For introducing Lagrangian blobs. - Default use_blobs=.false. -
-
-[logical] -- -use_velocity_override -
-- For over-riding the velocity field with values from - a file. Note that we need separate files for - (u,v) read into ocean_velocity.F90, as well as - (udrho,vdrho) read into ocean_barotropic.F90. - Default use_velocity_override=.false. -
-
-[logical] -- -debug -
-- For overall model debugging. Set true to print cksums at - each timestep for debugging purposes. -
-
-[logical] -- -mask_table -
-- A text file to specify n_mask, layout and mask_list. This table - aims to reduce the number of processors that are cycling over pure - land regions. These processors will be masked out of regions that - which contain all land points. - - The default file name of mask_table is "INPUT/ocean_mask_table". - Please note that the file name must begin with "INPUT/". - - The first line of mask_table is the number of region to be masked out. - The second line is the layout of the model. User need to set ocean_model_nml - variable layout to be the same as the second line of the mask table. - The following n_mask line will be the position of the processor to be masked out. - - The mask_table could be created by tools check_mask. - - For example the mask_table will be as following if n_mask=2, layout=4,6 and - the processor (1,2) and (3,6) are to be masked out. - 2 - 4,6 - 1,2 - 3,6 -
-
-[character] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_obc.F90 b/src/mom5/ocean_core/ocean_obc.F90 index 655e066942..bf2dd10715 100644 --- a/src/mom5/ocean_core/ocean_obc.F90 +++ b/src/mom5/ocean_core/ocean_obc.F90 @@ -647,7 +647,7 @@ end function tm_scale_to_secs integer :: i_sw, j_sw, i_nw, j_nw, i_se, j_se, i_ne, j_ne character(len=128) :: version = '$ID$' - character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' + character (len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. integer :: nt = 0 ! number of tracers real, allocatable :: wrk(:,:,:) ! needed for output of phase speed and other quantities diff --git a/src/mom5/ocean_core/ocean_obc.html b/src/mom5/ocean_core/ocean_obc.html deleted file mode 100644 index 17f1bc70b8..0000000000 --- a/src/mom5/ocean_core/ocean_obc.html +++ /dev/null @@ -1,1136 +0,0 @@ - - - -Module ocean_obc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_obc_mod
- - --Contact: Martin Schmidt , - Mike Herzfeld , - Zhi Liang , - Matthew Harrison -- - -
-Reviewers: Stephen Griffies -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Open Boundary condition for MOM. -
- - - -- This module can extrapolate data on the open lateral - boundaries for MOM. Tracer and surface height - are extrapolated on the boundary by using implicit radiation - boundary conditions, velocities are calculated on the boundary - from a linear equation (omitted advection equation). The - gradient of each field is supposed to be zero between boundary - points and the first points accross the boundary. - - This scheme has been tested only with the following vertical coordinates: - vertical_coordinate=='geopotential' - vertical_coordinate=='zstar' - Notably, there is no OBC prescription for pressure coordinates. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
data_override_mod
diag_manager_mod
fms_mod
fms_io_mod
mpp_io_mod
mpp_domains_mod
mpp_mod
time_interp_external_mod
time_manager_mod
tracer_manager_mod
ocean_util_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_obc_barotrop_mod
-PUBLIC INTERFACE
----
-- -obc_update_boundary:
- -- -obc_zero_boundary:
- -- -ocean_obc_enhance_visc_back:
- -- -ocean_obc_enhance_diff_back:
- -- -ocean_obc_init:
- -- -ocean_obc_tracer_init:
- -- -ocean_obc_prepare:
- -- -:
- -- -ocean_obc_adjust_divud:
- -- -ocean_obc_mixing:
- -- -ocean_obc_adjust_advel:
- -- -ocean_obc_adjust_forcing_bt:
- -- -ocean_obc_enhance_diff_back_3d:
- -- -ocean_obc_enhance_diff_back_2d:
- -- -ocean_obc_enhance_visc_back_2d:
- -- -ocean_obc_enhance_visc_back_3d:
- -- -ocean_obc_tracer:
- -- -ocean_obc_check_topog:
- -- -ocean_obc_set_mask:
- -- -ocean_obc_restart:
- -- -ocean_obc_end:
- -- -ocean_obc_mass_flux:
- -- -ocean_obc_tracer_flux:
- -- -store_ocean_obc_tracer_flux:
- -- -store_ocean_obc_pressure_grad:
- -- -check_eta_OBC:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-obc_update_boundary
--
--
-- -DESCRIPTION -
-- - update field on the halo points at the global boundaries. -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -field - field to be update on the boundary - -
[real, dimension(:,:,:,:)]
-- - -
-obc_zero_boundary
--
--
-- -DESCRIPTION -
-- - set field at open boundaries to zero. -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -field - field to be set to zero on the boundary - -
-- - -
-ocean_obc_enhance_visc_back
--
--
-- -DESCRIPTION -
-- - enhance viscosity near open boundaries -
-
-
-- - -
-ocean_obc_enhance_diff_back
--
--
-- -DESCRIPTION -
-- - enhance diffusion near open boundaries -
-
-
-- - -
-ocean_obc_init
-subroutine ocean_obc_init(have_obc, Time, Time_steps, Domain, Grid, Ocean_options, ver_coordinate, debug)--
-- -DESCRIPTION -
-- - Allocates space and initializes a derived-type variable that - contains domain decompostion and grid information. -
-
-
-- -INPUT -
-- -
--
-- -dtts, dtuv, dtbt, dteta - -
[real]- -Domain - A derived data type that contains domain information for MOM. - -
[type(ocean_domain_type)]- -Grid - A derived data type that contains grid information for MOM. - -
[type(ocean_grid_type)]
-- -INPUT/OUTPUT -
-- -
--
-- -have_obc - logical variable to indicate if there is any open boundary condition. - if true, open boudanry exists. - -
[logical]
-- - -
-ocean_obc_tracer_init
-subroutine ocean_obc_tracer_init(Time, T_prog, num_prog_tracers, debug)--
-- -DESCRIPTION -
-- - Allocates space and initializes all stuff for tracers at OBC -
-
-
-- -INPUT -
-- -
--
-- -debug - -
[logical]
-- - -
-ocean_obc_prepare
-subroutine ocean_obc_prepare(Time, Thickness, Ext_mode, T_prog)--
-- -DESCRIPTION -
-- - Prepares OBC - -
-
-
-- - - -
-subroutine ocean_obc_surface_height(Time, Ext_mode, dtime)--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_adjust_divud
-subroutine ocean_obc_adjust_divud(divud)--
-- -DESCRIPTION -
- -
-
-- -INPUT/OUTPUT -
-- -
--
-- -divud - -
[real, dimension(isd:,jsd:)]
-- - -
-ocean_obc_mixing
-subroutine ocean_obc_mixing(visc_cbt, diff_cbt, field1, field2)--
-- -DESCRIPTION -
- -
-
-- -INPUT/OUTPUT -
-- -
--
-- -visc_cbu - -
[real, dimension(isd:,jsd:,:)]- -diff_cbt - -
[real, dimension(isd:,jsd:,:,2)]
-- - -
-ocean_obc_adjust_advel
-subroutine ocean_obc_adjust_advel(Adv_vel)--
-- -DESCRIPTION -
-- - Subtract wrong vertical bottom velocity -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -Adv_vel - Advection velocities - -
[ocean_adv_vel_type]
-- - -
-ocean_obc_adjust_forcing_bt
-subroutine ocean_obc_adjust_forcing_bt(Ext_mode)--
-- -DESCRIPTION -
-- - Add wrong pressure gradient -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -Ext_mode - -
[ocean_external_mode_type]
-- - -
-ocean_obc_enhance_diff_back_3d
-subroutine ocean_obc_enhance_diff_back_3d(diff_cet, diff_cnt, scheme)--
-- -DESCRIPTION -
-- - enhance diffusion near open boundary -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -diff_cet - -
[real array 3D]- -diff_cnt - -
[real array 3D]
-- - -
-ocean_obc_enhance_diff_back_2d
-subroutine ocean_obc_enhance_diff_back_2d(aiso_back, scheme)--
-- -DESCRIPTION -
-- - enhance diffusivity near open boundary -
-
-
-- -INPUT -
-- -
--
-- -aiso_back - -
[real array 2D]
-- - -
-ocean_obc_enhance_visc_back_2d
-subroutine ocean_obc_enhance_visc_back_2d(aiso_back, scheme)--
-- -DESCRIPTION -
-- - enhance viscosity near open boundary -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -aiso_back - -
[real array 2D]
-- - -
-ocean_obc_enhance_visc_back_3d
-subroutine ocean_obc_enhance_visc_back_3d(aiso_back, aaniso_back, scheme)--
-- -DESCRIPTION -
-- - enhance viscosity near open boundary. Maximum viscosity for - stability is set on the boundary, linearly decreasing to the - interior value at enh_pnts into the interior. -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -aiso_back - -
[real array 3D]- -aaniso_back - -
[real array 3D]
-- - -
-ocean_obc_tracer
-subroutine ocean_obc_tracer(tracer, adv_vet, adv_vnt, Thickness, pme, taum1, tau, taup1, time, name, tn)--
-- -DESCRIPTION -
-- - Extrapolate tracer on the open boundaries for ocean model and regional atmosphere model. -
-
-
-- -INPUT -
-- -
--
-- -rho_dztr - contains Thickness%rho_dztr from update_tracer - -
[real, dimension(isc:,jsc:,:)]- -taum1, tau, taup1 - time step index - -
[integer]- -time - model time - -
[type(time_type)]- -name - tracer name. - -
[character(len=*)]- -n - tracer number - -
[integer]
-- -INPUT/OUTPUT -
-- -
--
-- -tracer - Tracer field - -
[real, dimension(isd:,jsd:,:,:)]
-- - -
-ocean_obc_check_topog
--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_set_mask
--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_obc_end
--
-- -DESCRIPTION -
-- - Destructor routine. Release memory. -
-
-
-- -OUTPUT -
-- -
--
-- -have_obc - Contains open boundary information - -
[logical]
-- - -
-ocean_obc_mass_flux
--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_tracer_flux
--
-- -DESCRIPTION -
- -
-
-- - -
-store_ocean_obc_tracer_flux
--
-- -DESCRIPTION -
- -
-
-- - -
-store_ocean_obc_pressure_grad
--
-- -DESCRIPTION -
- -
-
-- - -
-check_eta_OBC
--
-- -DESCRIPTION -
- -
-
-
-NAMELIST
- --&ocean_obc_nml --
-
----
-- -nobc -
-- number of open boundary condition. Its value should be less than max_obc. Increase max_obc if needed. -
-
-[integer] -- -direction -
-- open boundary direction. Each element value should be west, east, south or north. -
-
-[character(len=10), dimension(max_obc)] -- -is, ie, js, je -
-- open boundary position. -
-
-[integer, dimension(max_obc)] -- -name -
-- type of open bounday. -
-
-[character(len=32), dimension(max_obc)] -- -obc_nor -
-- Normal velocity OBC -
-
-[character, dimension(max_obc)] -- -obc_tan -
-- Tangential velocity OBC -
-
-[character, dimension(max_obc)] -- -obc_eta -
-- Surface elevation OBC -
-
-[character, dimension(max_obc)] -- -obc_tra -
-- Tracers OBC -
-
-[character, dimension(max_obc,max_prog_tracers)] -- -obc_mix -
-- Vertical mixing coefficient OBC -
-
-[character, dimension(max_obc)] -- -obc_relax_eta -
-- logical variable that decide whether relax eta or not. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_consider_convu -
-- logical variable that decide whether to account for one - component of convu within the boundary. The appropriate behavior - depends on the model configuration. - Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_vert_advel_t -
-- logical variable that decide whether to account for vertical - advection of tracers at the boundary. The appropriate behavior - depends on the model configuration. - Default value is .false. (Currently inactive) -
-
-[logical, dimension(max_obc)] -- -obc_vert_advel_u -
-- logical variable that decide whether to account for vertical - advection of momentum at the boundary. The appropriate behavior - depends on the model configuration. - Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_relax_eta_profile -
-- logical variable that decide whether relax eta to a prescribed profile or not. - Default value is .false. In this case only the average sea level is relaxed, - the profile, hence the geostrophic current, is unchanged. -
-
-[logical, dimension(max_obc)] -- -obc_relax_tracer -
-- logical variable that decide whether relax tracer or not. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_flow_relax -
-- Integer variable specifying the flow relaxation zone - (flow realxation of Martinsen and Engedahl (1987). Default value is 1. -
-
-[integer, dimension(max_obc)] -- -obc_consider_sources -
-- Logical variable specifying if source and SGS terms of the normal tracer - scheme are valid. Default value is .false.. -
-
-[logical, dimension(max_obc)] -- -obc_tracer_no_inflow -
-- logical variable that decide whether apply orlanski obc on tracer or not. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -ctrop_max -
-- Maximum value to clip diagnosed barotropic phase speed in terms of sqrt(gH). - Should be about 1. -
-
-[real, dimension(max_obc)] -- -ctrop_min -
-- Minimum value to diagnosed barotropic phase speed in terms of sqrt(gH). - Should be about 0. Default is 0.1. -
-
-[real, dimension(max_obc)] -- -ctrop_inc -
-- value to be set for barotropic phase speed if incoming waves are diagnosed. - (in terms of sqrt(gH)) Should be about 0. Default is 0. -
-
-[real, dimension(max_obc)] -- -rel_coef_eta_in -
-- Relaxation coefficient to be used for incoming wave situation. -
-
-[real, dimension(max_obc)] -- -rel_coef_eta_out -
-- Relaxation coefficient to be used for outgoing wave situation. - Should be smaller then or equal to rel_coef_eta_in. -
-
-[real, dimension(max_obc)] -- -filename_eta -
-- Filename to read sea level data. -
-
-[character, dimension(max_obc)] -- -fieldname_eta -
-- Fieldname to read sea level data. -
-
-[character, dimension(max_obc)] -- -rel_eta_pnts -
-- Relax sea level at a stripe of rel_eta_pnts. Default = 1. -
-
-[integer, dimension(max_obc)] -- -rel_coef_tracer_in -
-- Relaxation coefficient to be used for inflow situation. -
-
-[real, dimension(max_obc,max_prog_tracers)] -- -rel_coef_tracer_out -
-- Relaxation coefficient to be used for outflow situation. - Should be smaller then or equal to rel_coef_tracer_in. -
-
-[real, dimension(max_obc,max_prog_tracers)] -- -rel_clin_pnts -
-- Relax a tracer at a stripe of rel_clin_pnts. Default = 1. -
-
-[integer, dimension(max_obc,max_prog_tracers)] -- -filename_tracer -
-- Filename to read a tracer. It is allowed to put all data for a boundary in one file. -
-
-[character, dimension(max_obc,max_prog_tracers)] -- -fieldname_tracer -
-- Fieldname of a tracer. -
-
-[character, dimension(max_obc,max_prog_tracers)] -- -obc_enhance_visc_back -
-- logical variable that decide whether to enhance viscosity at the boundary. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_enhance_diff_back -
-- logical variable that decide whether to enhance mixing at the boundary. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -enh_fac_v -
-- 'Safety factor' applied to maximum stable viscosity at the boundary. Default = 0.9 -
-
-[real, dimension(max_obc)] -- -enh_fac_d -
-- Factor applied to enhance mixing at the boundary. Default = 1. -
-
-[real, dimension(max_obc)] -- -enh_pnts -
-- Enhance viscosity and mixing at a stripe of enh_pnts - decreasing with the distance from the boundary. Default = 1. -
-
-[integer, dimension(max_obc)] -- -debug_phase_speed -
-- Includes the phase speed into the model output. -
-
-[logical] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -nt -
-- number of tracers to use open boundary condition. -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_obc_barotrop.F90 b/src/mom5/ocean_core/ocean_obc_barotrop.F90 index 6778f236be..8b9cce0442 100644 --- a/src/mom5/ocean_core/ocean_obc_barotrop.F90 +++ b/src/mom5/ocean_core/ocean_obc_barotrop.F90 @@ -628,7 +628,7 @@ end function tm_scale_to_secs integer :: i_sw, j_sw, i_nw, j_nw, i_se, j_se, i_ne, j_ne character(len=128) :: version = '$ID$' - character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' + character (len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. real, allocatable :: wrk2(:) ! needed for enhanced diffusion real, allocatable :: wrk3(:) ! needed for enhanced diffusion diff --git a/src/mom5/ocean_core/ocean_obc_barotrop.html b/src/mom5/ocean_core/ocean_obc_barotrop.html deleted file mode 100644 index 148e1687ce..0000000000 --- a/src/mom5/ocean_core/ocean_obc_barotrop.html +++ /dev/null @@ -1,869 +0,0 @@ - - - -Module ocean_obc_barotrop_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_obc_barotrop_mod
- - --Contact: Martin Schmidt , - Mike Herzfeld , - Zhi Liang , - Matthew Harrison -- - -
-Reviewers: Stephen Griffies -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Open Boundary condition for MOM. -
- - - -- This module can extrapolate data on the open lateral - boundaries for MOM. Tracer and surface height - are extrapolated on the boundary by using implicit radiation - boundary conditions, velocities are calculated on the boundary - from a linear equation (omitted advection equation). The - gradient of each field is supposed to be zero between boundary - points and the first points accross the boundary. - - This scheme has been tested only with the following vertical coordinates: - vertical_coordinate=='geopotential' - vertical_coordinate=='zstar' - Notably, there is no OBC prescription for pressure coordinates. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
data_override_mod
diag_manager_mod
fms_mod
fms_io_mod
mpp_io_mod
mpp_domains_mod
mpp_mod
time_interp_external_mod
time_manager_mod
tracer_manager_mod
ocean_util_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -obc_update_boundary:
- -- -obc_zero_boundary:
- -- -ocean_obc_barotrop_init:
- -- -:
- -- -ocean_obc_prepare:
- -- -ocean_obc_adjust_divud:
- -- -ocean_obc_damp_newton:
- -- -ocean_obc_ud:
- -- -ocean_obc_barotropic:
- -- -ocean_obc_restart:
- -- -ocean_obc_end:
- -- -phase_speed_IOW:
- -- -phase_speed_ORLANS:
- -- -phase_speed_GRAVTY:
- -- -phase_speed_MILLER:
- -- -phase_speed_RAYMND:
- -- -boundary_average:
- -- -check_eta_OBC:
- -- -mpp_update_domains_obc:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-obc_update_boundary
--
--
-- -DESCRIPTION -
-- - update field on the halo points at the global boundaries. -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -field - field to be update on the boundary - -
-- - -
-obc_zero_boundary
--
--
-- -DESCRIPTION -
-- - set field at open boundaries to zero. -
-
-
-- -INPUT/OUTPUT -
-- -
--
-- -field - field to be set to zero on the boundary - -
-- - -
-ocean_obc_barotrop_init
-subroutine ocean_obc_barotrop_init(have_obc, Time, Time_steps, Domain, Grid, Ocean_options, & - use_legacy_barotropic_halos, debug)--
-- -DESCRIPTION -
-- - Allocates space and initializes a derived-type variable that - contains domain decompostion and grid information. -
-
-
-- -INPUT -
-- -
--
-- -dtts, dtuv, dtbt, dteta - -
[real]- -Domain - A derived data type that contains domain information for MOM. - -
[type(ocean_domain_type)]- -Grid - A derived data type that contains grid information for MOM. - -
[type(ocean_grid_type)]
-- -INPUT/OUTPUT -
-- -
--
-- -have_obc - logical variable to indicate if there is any open boundary condition. - if true, open boudanry exists. - -
[logical]
-- - - -
-function ocean_obc_check_for_update()--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_prepare
-subroutine ocean_obc_prepare(Time, Ext_mode)--
-- -DESCRIPTION -
-- - Prepares OBC - -
-
-
-- - -
-ocean_obc_adjust_divud
-subroutine ocean_obc_adjust_divud(divud)--
-- -DESCRIPTION -
- -
-
-- -INPUT/OUTPUT -
-- -
--
-- -divud - -
[real, dimension(isd:,jsd:)]
-- - -
-ocean_obc_damp_newton
-subroutine ocean_obc_damp_newton(udrho_bt,forcing)--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_ud
-subroutine ocean_obc_ud(eta_t, udrho)--
-- -DESCRIPTION -
- -
-
-- - -
-ocean_obc_barotropic
-subroutine ocean_obc_barotropic(eta, taum1, tau, taup1, tstep)--
-- -DESCRIPTION -
- -
-
-- -INPUT -
-- -
--
-- -taum1, tau, taup1 - -
[integer]
-- -INPUT/OUTPUT -
-- -
--
-- -eta - -
[real, dimension(isd:,jsd:,:)]
-- - -
-ocean_obc_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_obc_end
--
-- -DESCRIPTION -
-- - Destructor routine. Release memory. -
-
-
-- -OUTPUT -
-- -
--
-- -have_obc - Contains open boundary information - -
[logical]
-- - -
-phase_speed_IOW
--
-- -DESCRIPTION -
- -
-
-- - -
-phase_speed_ORLANS
--
-- -DESCRIPTION -
- -
-
-- - -
-phase_speed_GRAVTY
--
-- -DESCRIPTION -
- -
-
-- - -
-phase_speed_MILLER
--
-- -DESCRIPTION -
- -
-
-- - -
-phase_speed_RAYMND
--
-- -DESCRIPTION -
- -
-
-- - -
-boundary_average
--
-- -DESCRIPTION -
- -
-
-- - -
-check_eta_OBC
--
-- -DESCRIPTION -
- -
-
-- - -
-mpp_update_domains_obc
--
-- -DESCRIPTION -
- -
-
-
-NAMELIST
- --&ocean_obc_nml --
-
----
-- -nobc -
-- number of open boundary condition. Its value should be less than max_obc. Increase max_obc if needed. -
-
-[integer] -- -direction -
-- open boundary direction. Each element value should be west, east, south or north. -
-
-[character(len=10), dimension(max_obc)] -- -is, ie, js, je -
-- open boundary position. -
-
-[integer, dimension(max_obc)] -- -name -
-- type of open bounday. -
-
-[character(len=32), dimension(max_obc)] -- -obc_nor -
-- Normal velocity OBC -
-
-[character, dimension(max_obc)] -- -obc_tan -
-- Tangential velocity OBC -
-
-[character, dimension(max_obc)] -- -obc_eta -
-- Surface elevation OBC -
-
-[character, dimension(max_obc)] -- -obc_tra -
-- Tracers OBC -
-
-[character, dimension(max_obc,max_prog_tracers)] -- -obc_mix -
-- Vertical mixing coefficient OBC -
-
-[character, dimension(max_obc)] -- -obc_relax_eta -
-- logical variable that decide whether relax eta or not. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_consider_convu -
-- logical variable that decide whether to account for one - component of convu within the boundary. The appropriate behavior - depends on the model configuration. - Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_vert_advel_t -
-- logical variable that decide whether to account for vertical - advection of tracers at the boundary. The appropriate behavior - depends on the model configuration. - Default value is .false. (Currently inactive) -
-
-[logical, dimension(max_obc)] -- -obc_vert_advel_u -
-- logical variable that decide whether to account for vertical - advection of momentum at the boundary. The appropriate behavior - depends on the model configuration. - Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_relax_eta_profile -
-- logical variable that decide whether relax eta to a prescribed profile or not. - Default value is .false. In this case only the average sea level is relaxed, - the profile, hence the geostrophic current, is unchanged. -
-
-[logical, dimension(max_obc)] -- -obc_relax_tracer -
-- logical variable that decide whether relax tracer or not. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_flow_relax -
-- Integer variable specifying the flow relaxation zone - (flow realxation of Martinsen and Engedahl (1987). Default value is 1. -
-
-[integer, dimension(max_obc)] -- -obc_consider_sources -
-- Logical variable specifying if source and SGS terms of the normal tracer - scheme are valid. Default value is .false.. -
-
-[logical, dimension(max_obc)] -- -obc_tracer_no_inflow -
-- logical variable that decide whether apply orlanski obc on tracer or not. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -ctrop_max -
-- Maximum value to clip diagnosed barotropic phase speed in terms of sqrt(gH). - Should be about 1. -
-
-[real, dimension(max_obc)] -- -ctrop_min -
-- Minimum value to diagnosed barotropic phase speed in terms of sqrt(gH). - Should be about 0. Default is 0.1. -
-
-[real, dimension(max_obc)] -- -ctrop_inc -
-- value to be set for barotropic phase speed if incoming waves are diagnosed. - (in terms of sqrt(gH)) Should be about 0. Default is 0. -
-
-[real, dimension(max_obc)] -- -rel_coef_eta_in -
-- Relaxation coefficient to be used for incoming wave situation. -
-
-[real, dimension(max_obc)] -- -rel_coef_eta_out -
-- Relaxation coefficient to be used for outgoing wave situation. - Should be smaller then or equal to rel_coef_eta_in. -
-
-[real, dimension(max_obc)] -- -filename_eta -
-- Filename to read sea level data. -
-
-[character, dimension(max_obc)] -- -fieldname_eta -
-- Fieldname to read sea level data. -
-
-[character, dimension(max_obc)] -- -rel_eta_pnts -
-- Relax sea level at a stripe of rel_eta_pnts. Default = 1. -
-
-[integer, dimension(max_obc)] -- -rel_coef_tracer_in -
-- Relaxation coefficient to be used for inflow situation. -
-
-[real, dimension(max_obc,max_prog_tracers)] -- -rel_coef_tracer_out -
-- Relaxation coefficient to be used for outflow situation. - Should be smaller then or equal to rel_coef_tracer_in. -
-
-[real, dimension(max_obc,max_prog_tracers)] -- -rel_clin_pnts -
-- Relax a tracer at a stripe of rel_clin_pnts. Default = 1. -
-
-[integer, dimension(max_obc,max_prog_tracers)] -- -filename_tracer -
-- Filename to read a tracer. It is allowed to put all data for a boundary in one file. -
-
-[character, dimension(max_obc,max_prog_tracers)] -- -fieldname_tracer -
-- Fieldname of a tracer. -
-
-[character, dimension(max_obc,max_prog_tracers)] -- -obc_enhance_visc_back -
-- logical variable that decide whether to enhance viscosity at the boundary. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -obc_enhance_diff_back -
-- logical variable that decide whether to enhance mixing at the boundary. Default value is .false. -
-
-[logical, dimension(max_obc)] -- -enh_fac_v -
-- 'Safety factor' applied to maximum stable viscosity at the boundary. Default = 0.9 -
-
-[real, dimension(max_obc)] -- -enh_fac_d -
-- Factor applied to enhance mixing at the boundary. Default = 1. -
-
-[real, dimension(max_obc)] -- -enh_pnts -
-- Enhance viscosity and mixing at a stripe of enh_pnts - decreasing with the distance from the boundary. Default = 1. -
-
-[integer, dimension(max_obc)] -- -debug_phase_speed -
-- Includes the phase speed into the model output. -
-
-[logical] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -nt -
-- number of tracers to use open boundary condition. -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_operators.F90 b/src/mom5/ocean_core/ocean_operators.F90 index f2a05c0506..c89ebb14ad 100644 --- a/src/mom5/ocean_core/ocean_operators.F90 +++ b/src/mom5/ocean_core/ocean_operators.F90 @@ -1,15 +1,15 @@ module ocean_operators_mod ! -!S.M. Griffies +! S.M. Griffies ! ! -!A. Rosati +! A. Rosati ! ! -!Zhi Liang +! Zhi Liang ! ! -!Alexander Pletzer +! Alexander Pletzer ! ! !@@ -163,10 +163,10 @@ module ocean_operators_mod type(ocean_domain_type), pointer :: Dom_bt => NULL() character (len=128) :: version = & - '$Id: ocean_operators.F90,v 1.1.2.5 2012/06/01 20:47:08 Stephen.Griffies Exp $' + '$Id: ocean_operators.F90,v 20.0 2013/12/14 00:10:53 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' type(ocean_grid_type), pointer :: Grd =>NULL() type(ocean_domain_type), pointer :: Dom =>NULL() @@ -521,7 +521,7 @@ function DIV_UD (ud, halo_in, halo_out ) jstart = jsc - halo_out jend = jec + halo_out - DIV_UD = 0.0 + DIV_UD = 0.d0 if(horz_grid == MOM_CGRID) then diff --git a/src/mom5/ocean_core/ocean_operators.html b/src/mom5/ocean_core/ocean_operators.html deleted file mode 100644 index 4d2ddab920..0000000000 --- a/src/mom5/ocean_core/ocean_operators.html +++ /dev/null @@ -1,1110 +0,0 @@ - - - - Module ocean_operators_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_operators_mod
- - --Contact: S.M. Griffies - -- - -
-Reviewers: A. Rosati -, - Zhi Liang -, - Alexander Pletzer - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Operators for MOM -
- - - -- This module computes discrete operators used by MOM. --
- - -
-OTHER MODULES USED
- --- - - -mpp_domains_mod-
mpp_mod
fms_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_operators_init:
- -- -set_barotropic_domain:
- -- -get_use_legacy_DIV_UD:
- -- -REMAP_NT_TO_NU:
- -- -REMAP_ET_TO_EU:
- -- -REMAP_BT_TO_BU:
- -- -DIV_UD:
- -- -GRAD_BAROTROPIC_P:
- -- -S2D:
- -- -LAP_T:
- -- -FAX:
- -- -BAX:
- -- -FAY:
- -- -BAY:
- -- -BDX_EU:
- -- -BDX_ET:
- -- -FDX_U:
- -- -FDX_ZT:
- -- -FDX_T:
- -- -FDY_ZT:
- -- -FDY_T:
- -- -FDX_NT:
- -- -BDY_NU:
- -- -BDY_NT:
- -- -FDY_U:
- -- -FDY_ET:
- -- -FDZ_T:
- -- -FMX:
- -- -FMY:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_operators_init
--
-- -DESCRIPTION -
-- - Initialize the operator module -
-
-
-- - -
-set_barotropic_domain
--
-- -DESCRIPTION -
-- - Set the barotropic domain used in barotropic time step. -
-
-
-- -INPUT -
-- -
--
-- -Domain_in - Store the barotropic domain. - -
[type(ocean_domain_type)]
-- - -
-get_use_legacy_DIV_UD
--
-- -DESCRIPTION -
-- - Return the value of ocean_operators_nml variable use_legacy_DIV_UD -
-
-
-- - -
-REMAP_NT_TO_NU
--
-- -DESCRIPTION -
-- - REMAP_NT_TO_NU remaps a normal flux at the north - face of T-cells to the north face of U-cells -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be remapped - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-REMAP_ET_TO_EU
--
-- -DESCRIPTION -
-- - REMAP_ET_TO_EU remaps a normal flux at the east - face of T-cells to the east face of U-cells -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be remapped - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-REMAP_BT_TO_BU
--
-- -DESCRIPTION -
-- - REMAP_BT_TO_BU remaps a T-cell thickness or - vertical velocity on the base of T-cells to U-cells -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be remapped - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-DIV_UD
--
-- -DESCRIPTION -
-- - Compute divergence of vertically integrated velocity. - For MOM with generalized vertical coordinates, ud has an extra - density factor built in. - - The Bgrid uh and vh fields are located on the corner points, so require - some backward averaging. - - The Cgrid uh and vh fields are located on the T-cell faces, so need no - spatial averaging. - - Bgrid code is a speedier version of -
-
- uhy(:,:) = BAY(ud(:,:,1)*dyu(:,:)) -
- vhx(:,:) = BAX(ud(:,:,2)*dxu(:,:)) -
- DIV_UD(ud) = BDX_ET(uhy(:,:)/dyte(:,:)) + BDY_NT(vhx(:,:)/dxtn(:,:)) - -
-
-- - -
-GRAD_BAROTROPIC_P
--
-- -DESCRIPTION -
-- - Compute horizontal gradient of the pressure field associated with - either the free surface height or the bottom pressure. - - Account taken here for either Bgrid or Cgrid operators. - For the Bgrid, the gradient is centered onto the U-cell - for use in updating barotropic velocity. For the Cgrid, the - two components are centred on the T-cell faces. - - The Bgrid algorithm is a speedier version of -
-
- grad_barotropic_p(:,:,1) = FDX_NT(FAY(press(:,:))) -
- grad_barotropic_p(:,:,2) = FDY_ET(FAX(press(:,:))) -
-
-- - -
-S2D
--
-- -DESCRIPTION -
-- - Smooth a 2D field with a 2D version of a 1D filter with weights (1/4, 1/2, 1/4) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be smoothed - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-LAP_T
--
-- -DESCRIPTION -
-- - Compute horizontal 5-point Laplacian operator on eta_t. - Result lives at T-cell center. - - Redundancy update for tripolar is needed to conserve - total volume and tracer. It is likely unimportant - when call LAP_T from within the barotropic loop. Yet it - is essential when call LAP_T from ocean_surface_smooth. - - Mixing coefficient is assumed to be centred on the T-cell. - It is averaged to compute its value on the i-face and j-face - for computing fluxes. - -
-
-
-- - -
-FAX
--
-- -DESCRIPTION -
-- - Forwards average in the i-direction on the X-axis. - If input is a(i,j) then output is defined at (i+1/2,j) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be averaged - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BAX
--
-- -DESCRIPTION -
-- - Backwards average in the i-direction along the X-axis. - If input is a(i,j) then output is defined at (i-1/2,j) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be averaged - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FAY
--
-- -DESCRIPTION -
-- - Forwards average in the j-direction on the Y-axis - If input is a(i,j) then output is defined at (i,j+1/2) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be averaged - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BAY
--
-- -DESCRIPTION -
-- - Backwards average in the j-direction along the Y-axis - If input is a(i,j) then output is defined at (i,j-1/2) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be averaged - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BDX_EU
--
-- -DESCRIPTION -
-- - Backwards Derivative in X of a quantity defined on the East face of a U-cell - If input is a(i,j) then output is defined at (i-1/2,j) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BDX_ET
--
-- -DESCRIPTION -
-- - Backwards derivative in X of a quantity defined on the East face of a T-cell. - If input is a(i,j) then output is defined at (i-1/2,j) -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDX_U
--
-- -DESCRIPTION -
-- - Forward Derivative in X of a quantity defined on the grid point of a U-cell. - If input is a(i,j) then output is defined at (i+1/2,j). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDX_ZT
--
-- -DESCRIPTION -
-- - - Forward Derivative in X of a quantity defined on a tracer grid point - where it is necessary to take derivative with depth held constant. - When grid points live at different depths, then have an extra - contribution to the derivative. - - Input a(i,j,1) is at the grid point of a T-cell at level k-1. - Input a(i,j,2) is at the grid point of a T-cell at level k. - - Output is defined at (i+1/2,j) which is at the east face in a T-cell at level k. - -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]- -k - Depth level - -
[integer]
-- - -
-FDX_T
--
-- -DESCRIPTION -
-- - - Forward Derivative in X of a quantity defined on the grid point - of a T-cell. - - For lateral derivatives where vertical coordinate is held constant. - - Input a(i,j) is at the grid point of a T-cell - Output is defined at (i+1/2,j) which is at the east face in a T-cell. - -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDY_ZT
--
-- -DESCRIPTION -
-- - Forward Derivative in Y of a quantity defined on a tracer grid point - where it is necessary to take derivative with depth held constant. - When grid points live at different depths, then have an extra - contribution to the derivative. - - Input a(i,j,1) is at the grid point of a T-cell at level k-1. - Input a(i,j,2) is at the grid point of a T-cell at level k. - - Output is defined at (i,j+1/2) which is at the north face in a T-cell at level k. - -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]- -k - Depth level - -
[integer]
-- - -
-FDY_T
--
-- -DESCRIPTION -
-- - Forward Derivative in Y of a quantity defined on the grid Point - of a T-cell. - - For lateral derivatives where vertical coordinate is held constant. - - Input a(i,j) is at the grid point of a T-cell. - Output is defined at (i,j+1/2) which is at the north face in a T-cell. - -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDX_NT
--
-- -DESCRIPTION -
-- - Forward Derivative in X of a quantity defined on the North face of a T-cell. - If input is a(i,j) then output is defined at (i+1/2,j). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BDY_NU
--
-- -DESCRIPTION -
-- - Backward Derivative in Y of a quantity defined on the North face of a U-cell. - If input is a(i,j) then output is defined at (i,j-1/2). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BDY_NT
--
-- -DESCRIPTION -
-- - Backward Derivative in Y of a quantity defined on the North face of a T-cell. - If input is a(i,j) then output is defined at (i,j-1/2). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDY_U
--
-- -DESCRIPTION -
-- - Forward Derivative in Y of a quantity defined on the grid Point of a U-cell. - If input is a(i,j) then output is defined at (i,j+1/2). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDY_ET
--
-- -DESCRIPTION -
-- - Forward Derivative in Y of a quantity defined on the East face of a T-cell. - If input is a(i,j) then output is defined at (i,j+1/2). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FDZ_T
--
-- -DESCRIPTION -
-- - Forward Derivative in Z of a field on the T-cell point at level k. - - input a(i,j,1) is at the grid point of a T-cell at level k. - input a(i,j,2) is at the grid point of a T-cell at level k+1. - - output is at (i,j,k+3/2) which is bottom face of T-cell at level k. - - minus sign due to convention that z-increases upwards, whereas - k increases downward. - -
-
-
-- -INPUT -
-- -
--
-- -a - Field to be finite differenced - -
[real, dimension(isd:ied,jsd:jed)]- -k - Depth level index - -
[integer]
-- - -
-FMX
--
-- -DESCRIPTION -
-- - Forwards Minimum in the X direction. - If input is a(i,j) then output is defined at (i+1/2,j). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to find minimum - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-FMY
--
-- -DESCRIPTION -
-- - Forwards Minimum in the Y direction. - If input is a(i,j) then output is defined at (i,j+1/2). -
-
-
-- -INPUT -
-- -
--
-- -a - Field to find minimum - -
[real, dimension(isd:ied,jsd:jed)]
-
-NAMELIST
- --&ocean_operators_nml --
-
----
-- -use_legacy_DIV_UD -
-- Set use_legacy_DIV_UD=.true. to reproduce Riga results for - DIV_UD on Bgrid. For the case that the model grid is tripolar grid, - when barotropic_halo > 1 in ocean_barotropic.F90, then - we must set use_legacy_DIV_UD=.false., since will not reproduce between - different number of processors if set use_legacy_DIV_UD=.true. - - Tests indicate that with wider barotropic halos, there are - some performance enhancements for use_legacy_DIV_UD=.false. - Hence, the default is use_legacy_DIV_UD=.false. - - For the case that the model grid is regular lat-lon grid, - use_legacy_DIV_UD could be set to .true. or .false. for - any positive value of barotropic_halo. - - Note that the only difference between the new and old DIV_UD - is order of operations induced by parentheses, which occurs in the - tripolar fold region in the Arctic: - old: DIV_UD(i,j) = (uh_bay - uhim_bay + vh_bax - vhjm_bax)*datr_bt(i,j) - new: DIV_UD(i,j) = ((uh_bay - uhim_bay) + (vh_bax - vhjm_bax))*datr_bt(i,j) -
-
-[logical] -
- - - - -
-NOTES
- -- All operators will be replaced by generic forms when Fortran - can properly support functions of allocatable arrays. The - problems presently with this replacement are are as follows: - Allocatable arrays cannot be inside of derived types. - Only pointers to allocatable arrays can be inside derived types. - Supposedly the former will be allowed in Fortran 95 - Also, functions cannot be typed as a derived type without conflicts - which preclude using function as general operators operating on - derived types. --
-
- Mnemonics for simple operators - - 1st letter (direction of operation) -
- F => Forward direction with respect to the index. -
- B => Backward direction with respect to the index. - - 2nd letter (operation) -
- D => Derivative -
- A => Average -
- M => Minimum - - 3rd letter (axis) - - X => along the X axis -
- Y => along the Y axis -
- Z => along the Z axis - - 4th letter (placement of quantity being operated on) - - E => East face -
- N => North face -
- B => Bottom face -
- P => Point (grid point within cell) - - 5th letter (type of grid cell) - - U => U-cell -
- T => T-cell -
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_parameters.F90 b/src/mom5/ocean_core/ocean_parameters.F90 index 4f755d2f6c..49d32796cc 100644 --- a/src/mom5/ocean_core/ocean_parameters.F90 +++ b/src/mom5/ocean_core/ocean_parameters.F90 @@ -176,9 +176,9 @@ module ocean_parameters_mod real, public :: grav = 9.80 ! specific heat capacity J/(kg degC) for seawater - real, public :: cp_ocean = 3992.10322329649 - real, parameter, public :: CP_OCEAN_PRETEOS10 = 3992.10322329649 - real, parameter, public :: CP_OCEAN_TEOS10 = 3991.86795711963 + real, public :: cp_ocean = 3992.10322329649d0 + real, parameter, public :: CP_OCEAN_PRETEOS10 = 3992.10322329649d0 + real, parameter, public :: CP_OCEAN_TEOS10 = 3991.86795711963d0 ! specific heat capacity J/(kg degC) for calving land ice. ! this value is consistent with that used in the GFDL land model. @@ -196,7 +196,7 @@ module ocean_parameters_mod ! product of rho0*cp_ocean ! (kg/m^3)*(cal/kg/deg C)(joules/cal) = (joules/m^3/deg C) - real, public :: rho_cp = 1035.0 * 3992.10322329649 + real, public :: rho_cp = 1035.0 * 3992.10322329649d0 ! freezing point of fresh water at standard atmos pressure real, public :: tfreeze = 273.15 @@ -212,9 +212,9 @@ module ocean_parameters_mod character(len=128) :: version = & - '$Id: ocean_parameters.F90,v 1.1.2.3 2012/05/25 01:07:34 Stephen.Griffies Exp $' + '$Id: ocean_parameters.F90,v 20.0 2013/12/14 00:10:55 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' namelist /ocean_parameters_nml/ cp_ocean, cp_liquid_runoff, cp_solid_runoff, & rho0, tfreeze, omega_earth, grav diff --git a/src/mom5/ocean_core/ocean_parameters.html b/src/mom5/ocean_core/ocean_parameters.html deleted file mode 100644 index 74263d67d2..0000000000 --- a/src/mom5/ocean_core/ocean_parameters.html +++ /dev/null @@ -1,231 +0,0 @@ - - - -Module ocean_parameters_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_parameters_mod
- - - - - -
-OVERVIEW
- -- This module contains some parameters used in MOM. -
- - - -- The parameter settings for numerical and/or physical schemes. - Also some physical constants, whose values can be modified via namelist. --
- - -
-OTHER MODULES USED
- --- - - -mpp_mod-
fms_mod
-PUBLIC INTERFACE
----
-- -ocean_parameters_init:
- -- -ocean_parameters_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_parameters_init
--
-- -DESCRIPTION -
-- - Initialize the parameter module, passing cp_ocean back to ocean_model.F90 - and setting all other parameters that will be used throughout the model - simulation. - - Note: we do not enable check_nml_error, since the default settings - are generally those recommended for simulations. - -
-
-
-- - -
-ocean_parameters_end
--
-- -DESCRIPTION -
-- - Summarize the basic physical parameters used in the simulation. -
-
-
-
-NAMELIST
- --&ocean_parameters_nml --
-
----
-- -cp_ocean -
-- Specific heat capacity J/(kg degC) for liquid seawater. - Values are taken from from Jackett etal (2006) for preTEOS10 and - from TEOS-10 manual for TEOS10 value. The default values differ - from that in shared/constants since the MOM defaults are more updated. - Note that there is a check inside of ocean_tempsalt.F90 to ensure that - cp_ocean=cp_ocean_teos10 if using the teos10 recommendations, - and cp_ocean=cp_ocean_preteos10 for cases not using teos10. -
-
-[real, units: J/(kg degC)] -- -cp_solid_runoff -
-- Specific heat capacity J/(kg degC) for solid water runoff via calving land ice. - Default cp_solid_runoff = 2106.0 is consistent with that used in the - GFDL land model. -
-
-[real, units: J/(kg degC)] -- -cp_liquid_runoff -
-- Specific heat capacity J/(kg degC) for liquid water runoff from land. - Default cp_liquid_runoff = 4218.0 is consistent with that used in the - GFDL land model. -
-
-[real, units: J/(kg degC)] -- -rho0 -
-- Boussinesq reference density. Default rho0=1035.0 - corresponds to the value in Gill (page 47), where he notes - that the ocean density typically deviates less than 2 per cent - from this value. But if using the Boussinesq approximation for - other water bodies, such as the Baltic, then may wish to change - rho0 to a more appropriate value. -
-
-[real, units: kg/m^3] -- -tfreeze -
-- freezing point of fresh water at standard atmos pressure. - Default tfreeze=273.15 -
-
-[real, units: Kelvin] -- -omega_earth -
-- rotation of earth in radians per second - Default omega_earth= 7.2921e-5, as per equation (4.1) in Griffies (2004). -
-
-[real, units: radians per second] -- -grav -
-- Gravitational acceleration at earth surface. Assumed to be constant - throughout the ocean domain. Default grav=9.8 corresponds to the - "grav" parameter from shared/constants.F90. -
-
-[real, units: m/s^2] -- -von_karman -
-- Von Karman constant for law of wall turbulence. - Default von_karman=0.4. - Note: due to answer changes on some compilers, von_karman - has been removed from nml and is now set as a hard-value - to be consistent with earlier simulations (06mar2012). -
-
-[real, units: dimensionless] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_pressure.F90 b/src/mom5/ocean_core/ocean_pressure.F90 index aed2db27de..0ef7b95640 100644 --- a/src/mom5/ocean_core/ocean_pressure.F90 +++ b/src/mom5/ocean_core/ocean_pressure.F90 @@ -1,11 +1,11 @@ module ocean_pressure_mod #define COMP isc:iec,jsc:jec ! -!+! ! S.M. Griffies ! ! -!+! ! A. Rosati ! ! @@ -111,9 +111,9 @@ module ocean_pressure_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=128) :: version = & - '$Id: ocean_pressure.F90,v 1.1.2.8 2012/06/08 02:06:42 Stephen.Griffies Exp $' + '$Id: ocean_pressure.F90,v 20.0 2013/12/14 00:10:57 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! for vertical coordinate integer :: vert_coordinate diff --git a/src/mom5/ocean_core/ocean_pressure.html b/src/mom5/ocean_core/ocean_pressure.html deleted file mode 100644 index ce16f6b897..0000000000 --- a/src/mom5/ocean_core/ocean_pressure.html +++ /dev/null @@ -1,620 +0,0 @@ - - - -Module ocean_pressure_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_pressure_mod
- - - - - -
-OVERVIEW
- -- Compute the hydrostatic pressure and forces from pressure. - Includes methods for either Bgrid or Cgrid. -
- - - -- This module computes hydrostatic pressure and the pressure force - acting at a velocity point (traditional finite difference approach). - This force is used for the linear momentum equation. - - This module takes account of the vertical coordinate, - which determines details of the calculation. - - This module allows for either Bgrid or Cgrid calculation. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_io_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
ocean_obc_mod
-PUBLIC INTERFACE
----
-- -ocean_pressure_init:
- -- -pressure_force:
- -- -press_grad_force_depth_bgrid:
- -- -press_grad_force_press_bgrid:
- -- -press_grad_force_depth_cgrid:
- -- -press_grad_force_press_cgrid:
- -- -pressure_in_dbars:
- -- -hydrostatic_pressure:
- -- -geopotential_anomaly:
- -- -press_grad_force_depth_blob:
- -- -press_grad_force_press_blob:
- -- -pressure_in_dbars_blob:
- -- -hydrostatic_pressure_blob:
- -- -geopotential_anomaly_blob:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_pressure_init
--
-- -DESCRIPTION -
-- - Initialize the pressure module -
-
-
-- - -
-pressure_force
--
-- -DESCRIPTION -
-- - Compute the horizontal force [Pa=N/m^2] from pressure. - - Use the traditional approach whereby the pressure force - is computed as a finite difference gradient centred - at the U-cell point. - -
-
-
-- - -
-press_grad_force_depth_bgrid
--
-- -DESCRIPTION -
-- - Compute the force from pressure using a finite difference method - to compute the thickness weighted pressure gradient at the - velocity cell point. - - Assume B-grid arrangement here. - - For depth-like vertical coordinates, we exclude surface and applied - pressures (i.e., we are computing here the gradient of the baroclinic - pressure). The surface and applied pressures are accounted for in - the barotropic module. - - Account is taken of variable partial cell thickness. - - 1 = dp/dx; 2 = dp/dy - - Thickness weight since this is what we wish to use in update of - the velocity. Resulting thickness weighted pressure gradient has - dimensions of Pa = N/m^2 = kg/(m*s^2). - - Thickness%dzu should be at tau. - -
-
-
-- - -
-press_grad_force_press_bgrid
--
-- -DESCRIPTION -
-- - Compute the force from pressure using a finite difference method - to compute the thickness weighted pressure gradient at the - velocity cell corner point. - - Assume B-grid arrangement here. - - For pressure-like vertical coordinates, we omit the bottom pressure - and bottom geopotential. These pressures are accounted for in the - barotropic module. - - Account is taken of variable partial cell thickness. - - 1 = dp/dx; 2 = dp/dy - - Thickness weight since this is what we wish to use in update of - the velocity. Resulting thickness weighted pressure gradient has - dimensions of Pa = N/m^2 = kg/(m*s^2). - - Thickness%dzu should be at tau. - -
-
-
-- - -
-press_grad_force_depth_cgrid
--
-- -DESCRIPTION -
-- - Compute the force from pressure using a finite difference method - to compute the thickness weighted pressure gradient at the - T-cell face, thus acting on the C-grid velocity components. - - Assume C-grid arrangement here. - - For depth-like vertical coordinates, we exclude surface and applied - pressures (i.e., we are computing here the gradient of the baroclinic - pressure). The surface and applied pressures are included in - ocean_barotropic. - - Account is taken of variable partial cell thickness. - - 1 = dp/dx; 2 = dp/dy - - Thickness weight since this is what we wish to use in update of - the velocity. Resulting thickness weighted pressure gradient has - dimensions of Pa = N/m^2 = kg/(m*s^2). - - Thickness%dzten should be at time tau. - -
-
-
-- - -
-press_grad_force_press_cgrid
--
-- -DESCRIPTION -
-- - Compute the force from pressure using a finite difference method - to compute the thickness weighted pressure gradient at the - T-cell face, thus acting on the C-grid velocity components. - - Assume C-grid arrangement here. - - For pressure-like vertical coordinates, we omit the bottom pressure - and bottom geopotential; these are handled in ocean_barotropic. - - Account is taken of variable partial cell thickness. - - 1 = dp/dx; 2 = dp/dy - - Thickness weight since this is what we wish to use in update of - the velocity. Resulting thickness weighted pressure gradient has - dimensions of Pa = N/m^2 = kg/(m*s^2). - - Thickness%dzu should be at tau. - -
-
-
-- - -
-pressure_in_dbars
--
-- -DESCRIPTION -
-- - Compute pressure (dbars) exerted at T cell grid point by weight of - water column above the grid point. - - rho = density in kg/m^3 - - psurf = surface pressure in Pa= kg/(m*s^2) = hydrostatic pressure - at z=0 associated with fluid between z=0 and z=eta_t. - Also include pressure from atmosphere and ice, both of which - are part of the patm array. - - This routine is used by ocean_density to compute the pressure - used in the equation of state. It is only called when the - vertical coordinate is DEPTH_BASED. - -
-
-
-- - -
-hydrostatic_pressure
--
-- -DESCRIPTION -
-- - Hydrostatic pressure [Pa=N/m^2=kg/(m*s^2)] at T cell grid points. - - For GEOPOTENTIAL vertical coordinate, integration is - from z=0 to depth of grid point. This integration results in - the so-called "baroclinic" pressure. - - For ZSTAR or ZSIGMA, vertical coordinate, integration is from z=eta to - depth of grid point. This is allowed because ZSTAR and ZSIGMA - absorb the undulations of the surface height into their definition. - - If the input density "rho" is an anomoly, the resulting presure - will be a hydrostatic pressure anomoly. If "rho" is full density, - the presure will be a full hydrostatic pressure. - -
-
-
-- - -
-geopotential_anomaly
--
-- -DESCRIPTION -
-- - Geopotential anomaly [m^2/s^2] at T cell grid points. - Integration here is from z=-H to depth of grid point. - - Input should be density anomaly rhoprime = rho-rho0. - - This function is needed when computing pressure gradient - for PRESSURE_BASED vertical coordinates. - - WARNING: Thickness%method==FINITEVOLUME has been found to be - problematic. It remains under development. It is NOT - supported for general use. - -
-
-
-- - -
-press_grad_force_depth_blob
--
-- -DESCRIPTION -
-- - This routine respects the partition between Eulerian system mass - and the Lagrangian system mass associated with the Lagrangian blobs - model. The pressure gradient from the total (combined Eulerian and - Lagrangian systems) is calculated. Aside from that, the routine is - the same as for press_grad_force_depth. - - Compute the force from pressure using a finite difference method - to compute the thickness weighted pressure gradient at the - velocity cell point. - - For depth-like vertical coordinates, we exclude surface and applied - pressures (i.e., we are computing here the gradient of the baroclinic - pressure). Account is taken of variable partial cell thickness. - 1 = dp/dx; 2 = dp/dy - - Thickness weight since this is what we wish to use in update of - the velocity. Resulting thickness weighted pressure gradient has - dimensions of Pa = N/m^2 = kg/(m*s^2). - - Thickness%dzu should be at tau. -
-
-
-- - -
-press_grad_force_press_blob
--
-- -DESCRIPTION -
-- - This routine respects the partition between Eulerian system mass - and the Lagrangian system mass associated with the Lagrangian blobs - model. The pressure gradient from the total (combined Eulerian and - Lagrangian systems) system is calculated. Aside from that, the routine - is the same as for press_grad_force_press. - - Compute the force from pressure using a finite difference method - to compute the thickness weighted pressure gradient at the - velocity cell point. - - For pressure-like vertical coordinates, we omit the bottom pressure - and bottom geopotential. Account is taken of variable partial cell - thickness. 1 = dp/dx; 2 = dp/dy - - Thickness weight since this is what we wish to use in update of - the velocity. Resulting thickness weighted pressure gradient has - dimensions of Pa = N/m^2 = kg/(m*s^2). - - Thickness%dzu should be at tau. - -
-
-
-- - -
-pressure_in_dbars_blob
--
-- -DESCRIPTION -
-- - This routine respects the partition between Eulerian system mass - and the Lagrangian system mass associated with the Lagrangian blobs - model. The pressure from the combined system is calculated. - Aside from that, the routine is the same as for pressure_in_dbars. - - Compute pressure (dbars) exerted at T cell grid point by weight of - water column above the grid point. - - rho = density in kg/m^3 - - psurf = surface pressure in Pa= kg/(m*s^2) = hydrostatic pressure - at z=0 associated with fluid between z=0 and z=eta_t. - Also include pressure from atmosphere and ice, both of which - are part of the patm array. - - This routine is used by ocean_density to compute the pressure - used in the equation of state. It is only called when the - vertical coordinate is DEPTH_BASED. - -
-
-
-- - -
-hydrostatic_pressure_blob
--
-- -DESCRIPTION -
-- - This routine respects the partition between Eulerian system mass - and the Lagrangian system mass associated with the Lagrangian blobs - model. The hydrostatic pressure from the combined system is - calculated. Aside from that, the routine is the same as for - Hydrostatic_pressure. - - Hydrostatic pressure [Pa=N/m^2=kg/(m*s^2)] at T cell grid points. - - For GEOPOTENTIAL vertical coordinate, integration is - from z=0 to depth of grid point. This integration results in - the so-called "baroclinic" pressure. - - For ZSTAR, vertical coordinate, integration is from z=eta to - depth of grid point. This is allowed because ZSTAR - absorbs the undulations of the surface height into their definition. - - If the input density "rho" is an anomoly, the resulting presure - will be a hydrostatic pressure anomoly. If "rho" is full density, - the presure will be a full hydrostatic pressure. - -
-
-
-- - -
-geopotential_anomaly_blob
--
-- -DESCRIPTION -
-- - This routine respects the partition between Eulerian system mass - and the Lagrangian system mass associated with the Lagrangian blobs - model. The geopotential from the combined system is calculated. - Aside from that, the routine is the same as for geopotential_anomaly. - - Geopotential anomaly [m^2/s^2] at T cell grid points. - Integration here is from z=-H to depth of grid point. - - Input should be density anomaly rhoprime = rho-rho0. - - This function is needed when computing pressure gradient - for PRESSURE_BASED vertical coordinates. - - WARNING: Thickness%method==FINITEVOLUME has been found to be - problematic. It remains under development. It is NOT - supported for general use. - -
-
-
-
-NAMELIST
- --&ocean_pressure_nml --
-
----
-- -debug_this_module -
-- For debugging. -
-
-[logical] -- -zero_correction_term_grad -
-- For debugging it is often useful to zero the contribution to the - pressure gradient that arises from the "correction" term. - Implemented only for depth based vertical coordinate models. -
-
-[logical] -- -zero_diagonal_press_grad -
-- For debugging it is often useful to zero the contribution to the - pressure gradient that arises from the along k-level gradient. - Implemented only for depth based vertical coordinate models. -
-
-[logical] -- -zero_pressure_force -
-- For debugging it is often useful to zero the pressure force - to zero. -
-
-[logical] -- -zero_eta_over_h_zstar_pressure -
-- For debugging zstar, we drop any eta/H contribution to - the hydrostatic pressure. This is wrong physically, but - useful for certain tests. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, 2012: Elements of MOM -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_sbc.F90 b/src/mom5/ocean_core/ocean_sbc.F90 index 6cac05e54a..5dae19b0fb 100644 --- a/src/mom5/ocean_core/ocean_sbc.F90 +++ b/src/mom5/ocean_core/ocean_sbc.F90 @@ -542,6 +542,10 @@ module ocean_sbc_mod integer :: id_vstokes =-1 integer :: id_stokes_depth =-1 +integer :: id_ustoke =-1 +integer :: id_vstoke =-1 +integer :: id_wavlen =-1 + integer :: id_net_sfc_heating =-1 integer :: id_total_net_sfc_heating =-1 @@ -745,9 +749,9 @@ module ocean_sbc_mod character(len=128) :: version=& - '$Id: ocean_sbc.F90,v 1.1.2.8 2012/05/31 17:09:53 Stephen.Griffies Exp $' + '$Id: ocean_sbc.F90,v 20.0 2013/12/14 00:10:59 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized =.false. logical :: use_waterflux =.true. @@ -756,6 +760,8 @@ module ocean_sbc_mod logical :: use_waterflux_override_fprec =.false. logical :: use_waterflux_override_evap =.false. logical :: rotate_winds =.false. +logical :: taux_sinx =.false. +logical :: tauy_siny =.false. logical :: runoffspread =.false. logical :: calvingspread =.false. logical :: salt_restore_under_ice =.true. @@ -787,6 +793,7 @@ module ocean_sbc_mod logical :: use_ideal_runoff =.false. logical :: use_ideal_calving =.false. logical :: read_stokes_drift =.false. +logical :: do_langmuir =.false. real :: constant_sss_for_restore = 35.0 real :: constant_sst_for_restore = 12.0 @@ -817,7 +824,7 @@ module ocean_sbc_mod namelist /ocean_sbc_nml/ temp_restore_tscale, salt_restore_tscale, salt_restore_under_ice, salt_restore_as_salt_flux, & eta_restore_tscale, zero_net_pme_eta_restore, & - rotate_winds, use_waterflux, waterflux_tavg, max_ice_thickness, runoffspread, calvingspread, & + rotate_winds, taux_sinx, tauy_siny, use_waterflux, waterflux_tavg, max_ice_thickness, runoffspread, calvingspread, & use_waterflux_override_calving, use_waterflux_override_evap, use_waterflux_override_fprec, & salinity_ref, zero_net_salt_restore, zero_net_water_restore, zero_net_water_coupler, zero_net_water_couple_restore, & zero_net_salt_correction, zero_net_water_correction, & @@ -828,7 +835,7 @@ module ocean_sbc_mod temp_correction_scale, salt_correction_scale, tau_x_correction_scale, tau_y_correction_scale, do_bitwise_exact_sum, & sbc_heat_fluxes_const, sbc_heat_fluxes_const_value, sbc_heat_fluxes_const_seasonal, & use_constant_sss_for_restore, constant_sss_for_restore, use_constant_sst_for_restore, constant_sst_for_restore, & - use_ideal_calving, use_ideal_runoff, constant_hlf, constant_hlv, read_stokes_drift + use_ideal_calving, use_ideal_runoff, constant_hlf, constant_hlv, read_stokes_drift, do_langmuir contains @@ -967,7 +974,8 @@ subroutine ocean_sbc_init(Grid, Domain, Time, T_prog, T_diag, & Ocean_sfc%s_surf = 0.0 ! time averaged sss (psu) passed to atmosphere/ice models Ocean_sfc%u_surf = 0.0 ! time averaged u-current (m/sec) passed to atmosphere/ice models Ocean_sfc%v_surf = 0.0 ! time averaged v-current (m/sec) passed to atmosphere/ice models - Ocean_sfc%sea_lev = 0.0 ! time averaged thickness of top model grid cell (m) plus patm/(grav*rho0) + Ocean_sfc%sea_lev = 0.0 ! time averaged thickness of top model grid cell (m) plus patm/(grav*rho0) + ! minus h_geoid - h_tide Ocean_sfc%frazil = 0.0 ! time accumulated frazil (J/m^2) passed to ice model Ocean_sfc%area = Grid%dat(isc:iec, jsc:jec) * Grid%tmask(isc:iec, jsc:jec, 1) !grid cell area @@ -1512,6 +1520,19 @@ subroutine ocean_sbc_diag_init(Time, Dens, T_prog) ! register dynamic fields + id_ustoke = register_diag_field('ocean_model','ww3 ustoke', Grd%vel_axes_uv(1:2),& + Time%model_time, 'i-directed stokes drift velocity', 'm/s', & + missing_value=missing_value,range=(/-10.,10./), & + standard_name='surface stokes drift x-velocity') + + id_vstoke = register_diag_field('ocean_model','ww3 vstoke', Grd%vel_axes_uv(1:2),& + Time%model_time, 'j-directed stokes drift velocity', 'm/s', & + missing_value=missing_value,range=(/-10.,10./), & + standard_name='surface stokes drift y-velocity') + + id_wavlen = register_diag_field('ocean_model','ww3 wavlen', Grd%tracer_axes(1:2), & + Time%model_time, 'mean wave length', 'm') + id_tau_x = register_diag_field('ocean_model','tau_x', Grd%vel_axes_u(1:2), & Time%model_time, 'i-directed wind stress forcing u-velocity', 'N/m^2',& missing_value=missing_value,range=(/-10.,10./), & @@ -2449,7 +2470,7 @@ end subroutine ocean_sbc_diag_init ! Ocean_sfc%s_surf = time averaged sss (psu) passed to atmosphere/ice models ! Ocean_sfc%u_surf = time averaged u-current (m/sec) passed to atmosphere/ice models ! Ocean_sfc%v_surf = time averaged v-current (m/sec) passed to atmosphere/ice models -! Ocean_sfc%sea_lev = time averaged ocean free surface height (m) plus patm/(grav*rho0) +! Ocean_sfc%sea_lev = time averaged ocean free surface height (m) plus patm/(grav*rho0) - h_geoid - h_tide ! Ocean_sfc%frazil = time accumulated frazil (J/m^2) passed to ice model. time averaging ! not performed, since ice model needs the frazil accumulated over the ! ocean time steps. Note that Ocean_sfc%frazil is accumulated, whereas @@ -2809,7 +2830,8 @@ end subroutine ocean_sfc_restart ! T_diag%frazil, which is saved in the diagnostic tracer restart file. ! ! -subroutine ocean_sfc_end() +subroutine ocean_sfc_end(Ocean_sfc) + type(ocean_public_type), intent(in), target :: Ocean_sfc call ocean_sfc_restart @@ -2902,7 +2924,18 @@ subroutine get_ocean_sbc(Time, Ice_ocean_boundary, Thickness, Dens, Ext_mode, T_ enddo enddo - + !------- Calculate Langmuir turbulence enhancement and stokes drift if do_langmuir is true ------------------------ + if ( do_langmuir ) then + do j = jsc_bnd,jec_bnd + do i = isc_bnd,iec_bnd + ii = i + i_shift + jj = j + j_shift + Velocity%ustoke(ii,jj) = Ice_ocean_boundary%ustoke(i,j) + Velocity%vstoke(ii,jj) = Ice_ocean_boundary%vstoke(i,j) + Velocity%wavlen(ii,jj)= Ice_ocean_boundary%wavlen(i,j) + enddo + enddo + endif !--------momentum fluxes------------------------------------- ! @@ -2931,6 +2964,26 @@ subroutine get_ocean_sbc(Time, Ice_ocean_boundary, Thickness, Dens, Ext_mode, T_ enddo endif + ! for idealized tests + if (taux_sinx) then + do j=jsc,jec + do i=isc,iec + Velocity%smf_bgrid(i,j,1) = 0.1*sin(Grd%xu(i,j)/(2.0*pi))*Grd%umask(i,j,1) + Velocity%smf_bgrid(i,j,2) = 0.0 + enddo + enddo + endif + + ! for idealized tests + if (tauy_siny) then + do j=jsc,jec + do i=isc,iec + Velocity%smf_bgrid(i,j,1) = 0.0 + Velocity%smf_bgrid(i,j,2) = 0.1*sin(Grd%yu(i,j)/(2.0*pi))*Grd%umask(i,j,1) + enddo + enddo + endif + ! mpp update domain is needed for vertical mixing schemes such ! as KPP and GOTM, as well as to get c-grid version of smf. call mpp_update_domains(Velocity%smf_bgrid(:,:,1),Velocity%smf_bgrid(:,:,2),Dom%domain2d,gridtype=BGRID_NE) @@ -2957,7 +3010,7 @@ subroutine get_ocean_sbc(Time, Ice_ocean_boundary, Thickness, Dens, Ext_mode, T_ enddo enddo - ! for use in forcing momentum equation + ! for use in forcing momentum if(horz_grid == MOM_BGRID) then do n=1,2 do j=jsc,jec @@ -4368,6 +4421,24 @@ subroutine ocean_sbc_diag(Time, Velocity, Thickness, Dens, T_prog, Ice_ocean_bou endif + !----Langmuir turbulence related diagnostics------------------------------- + ! i-directed stokes drift velocity (m/s) + if (do_langmuir) then + if (id_ustoke > 0) used = send_data(id_ustoke, Velocity%ustoke(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + ! j-directed stokes drift velocity (m/s) + if (id_vstoke > 0) used = send_data(id_vstoke, Velocity%vstoke(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + ! mean wave length (m) + if (id_wavlen > 0) used = send_data(id_wavlen, Velocity%wavlen(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + ! wind stress curl (N/m^3) averaged to U-point ! Ekman pumping velocity averaged to U-point if (id_tau_curl > 0 .or. id_ekman_we > 0) then @@ -4637,16 +4708,20 @@ subroutine ocean_sbc_diag(Time, Velocity, Thickness, Dens, T_prog, Ice_ocean_bou endif ! net heat flux from radiation+latent+sensible (as passed through coupler) + mass transport + ! note that the addition of frozen_precip is operationally how the model computes the + ! heat contribution from mass transport. however, it is arguably not correct, since + ! the frozen precip is typically best approximated to be at 0C, rather than SST. But + ! we diagnose the contribution in this manner in order to agree with the prognostic model + ! methods. if(id_net_sfc_heating > 0) then wrk1_2d(:,:) = 0.0 do j=jsc,jec do i=isc,iec - wrk1_2d(i,j) = T_prog(index_temp)%conversion*( & - T_prog(index_temp)%stf(i,j) & - + T_prog(index_temp)%runoff_tracer_flux(i,j) & - + T_prog(index_temp)%calving_tracer_flux(i,j) & - + liquid_precip(i,j)*T_prog(index_temp)%tpme(i,j) & - + evaporation(i,j)*T_prog(index_temp)%tpme(i,j) ) + wrk1_2d(i,j) = T_prog(index_temp)%conversion*( & + T_prog(index_temp)%stf(i,j) & + + T_prog(index_temp)%runoff_tracer_flux(i,j) & + + T_prog(index_temp)%calving_tracer_flux(i,j) & + + (frozen_precip(i,j)+liquid_precip(i,j)+evaporation(i,j))*T_prog(index_temp)%tpme(i,j) ) enddo enddo call diagnose_2d(Time, Grd, id_net_sfc_heating, wrk1_2d(:,:)) @@ -4656,13 +4731,12 @@ subroutine ocean_sbc_diag(Time, Velocity, Thickness, Dens, T_prog, Ice_ocean_bou wrk1_2d(:,:) = 0.0 do j=jsc,jec do i=isc,iec - wrk1_2d(i,j) = Grd%tmask(i,j,1)*Grd%dat(i,j) & - *T_prog(index_temp)%conversion*( & - T_prog(index_temp)%stf(i,j) & - + T_prog(index_temp)%runoff_tracer_flux(i,j) & - + T_prog(index_temp)%calving_tracer_flux(i,j) & - + liquid_precip(i,j)*T_prog(index_temp)%tpme(i,j) & - + evaporation(i,j)*T_prog(index_temp)%tpme(i,j) ) + wrk1_2d(i,j) = Grd%tmask(i,j,1)*Grd%dat(i,j) & + *T_prog(index_temp)%conversion*( & + T_prog(index_temp)%stf(i,j) & + + T_prog(index_temp)%runoff_tracer_flux(i,j) & + + T_prog(index_temp)%calving_tracer_flux(i,j) & + + (frozen_precip(i,j)+liquid_precip(i,j)+evaporation(i,j))*T_prog(index_temp)%tpme(i,j) ) enddo enddo call diagnose_sum(Time, Grd, Dom, id_total_net_sfc_heating, wrk1_2d, 1e-15) @@ -4693,6 +4767,7 @@ subroutine ocean_sbc_diag(Time, Velocity, Thickness, Dens, T_prog, Ice_ocean_bou ! evaporative heat flux (W/m2) (<0 cools ocean) if (id_evap_heat > 0) then + tmp_flux=0.0 do j=jsc_bnd,jec_bnd do i=isc_bnd,iec_bnd ii=i+i_shift @@ -4704,6 +4779,7 @@ subroutine ocean_sbc_diag(Time, Velocity, Thickness, Dens, T_prog, Ice_ocean_bou endif ! total evaporative heating (Watts) if (id_total_ocean_evap_heat > 0) then + tmp_flux=0.0 do j=jsc_bnd,jec_bnd do i=isc_bnd,iec_bnd ii=i+i_shift @@ -5292,13 +5368,13 @@ subroutine compute_latent_heat_fusion(salinity) real, dimension(isd:,jsd:), intent(in) :: salinity -real, parameter :: c0 = 3.334265169240710e5 -real, parameter :: c1 = -2.789444646733159 -real, parameter :: c3 = -4.984585692734338e3 -real, parameter :: c6 = 1.195857305019339e3 -real, parameter :: c10 = -5.792068522727968e2 -real, parameter :: c15 = 6.836527214265952e2 -real, parameter :: c21 = -2.371103254714944e2 +real, parameter :: c0 = 3.334265169240710d5 +real, parameter :: c1 = -2.789444646733159d0 +real, parameter :: c3 = -4.984585692734338d3 +real, parameter :: c6 = 1.195857305019339d3 +real, parameter :: c10 = -5.792068522727968d2 +real, parameter :: c15 = 6.836527214265952d2 +real, parameter :: c21 = -2.371103254714944d2 real :: x integer :: i,j diff --git a/src/mom5/ocean_core/ocean_sbc.html b/src/mom5/ocean_core/ocean_sbc.html deleted file mode 100644 index 3c7a4f76ce..0000000000 --- a/src/mom5/ocean_core/ocean_sbc.html +++ /dev/null @@ -1,1122 +0,0 @@ - - - -Module ocean_sbc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_sbc_mod
- - --Contact: S. M. Griffies - -- - -
-Reviewers: M.J. Harrison -, - A. Rosati - , - - V. Balaji - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Set up the surface boundary conditions for MOM. -
- - - -- - This module sets up the surface boundary conditions for MOM. - Also fill Ocean_sfc derived-type used to pass information to other - component models. Also write diagnostics related to surface - boundary forcing. - - The surface temperature should be the surface insitu temperature, - which is the same as the surface potential temperature. When the - model prognostic temperature variable is conservative temperature, - then the surface potential temperature is carried in T_diag(index_diag_temp). - The resulting heat flux is potential enthalpy, which is the correct - field to be forcing the T_prog(index_temp) field when the prognostic - temperature field is the conservative temperature. - - We assume the winds passed to the ocean are on the B-grid - velocity point. Likewise, we pass the currents back to the coupler - on the B-grid point. Code will need to be modified if using another - assumption. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_riverspread_mod
ocean_tracer_util_mod
ocean_tpm_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_sbc_init:
- -- -ocean_sbc_diag_init:
- -- -initialize_ocean_sfc:
- -- -sum_ocean_sfc:
- -- -zero_ocean_sfc:
- -- -avg_ocean_sfc:
- -- -ocean_sfc_restart:
- -- -ocean_sfc_end:
- -- -get_ocean_sbc:
- -- -flux_adjust:
- -- -ocean_sbc_diag:
- -- -:
- -- -:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_sbc_init
--
-- -DESCRIPTION -
-- - Initialize the ocean sbc module. -
-
-
-- - -
-ocean_sbc_diag_init
--
-- -DESCRIPTION -
-- - Initialize the ocean sbc diagnostics. - Send some static diagnostics to diagnostic manager. -
-
-
-- - -
-initialize_ocean_sfc
--
-- -DESCRIPTION -
-- - Initialize the ocean surface type, which passes information between ocean - and other component models. - - Note that ocean model sst passed to the atmosphere must be the surface - potential temperature (which is equated to surface in situ temperature). - If the ocean prognostic temperature variable is conservative temperature, - then the sst is carried in T_diag(index_diag_temp). If the prognostic - temperature is potential temperature, then the sst is carried in - T_prog(index_temp). - - Note that we assume the winds passed to the ocean are on the B-grid - velocity point. Likewise, we pass the currents back to the coupler - on the B-grid point. Code will need to be modified if using another - coupler assumption. - - Ocean_sfc%t_surf = time averaged sst (Kelvin) passed to atmosphere/ice model - Ocean_sfc%s_surf = time averaged sss (psu) passed to atmosphere/ice models - Ocean_sfc%u_surf = time averaged u-current (m/sec) passed to atmosphere/ice models - Ocean_sfc%v_surf = time averaged v-current (m/sec) passed to atmosphere/ice models - Ocean_sfc%sea_lev = time averaged ocean free surface height (m) plus patm/(grav*rho0) - Ocean_sfc%frazil = time accumulated frazil (J/m^2) passed to ice model. time averaging - not performed, since ice model needs the frazil accumulated over the - ocean time steps. Note that Ocean_sfc%frazil is accumulated, whereas - T_diag%frazil (saved in diagnostic tracer restart file) is instantaneous. - -
-
-
-- - -
-sum_ocean_sfc
--
-- -DESCRIPTION -
-- - Accumulate the ocean_sfc derived type over the course of the - ocean component sub-cycling used when coupling to other models. - - Note that ocean model sst passed to the atmosphere must be the surface - potential temperature (which is equated to surface in situ temperature). - If the ocean prognostic temperature variable is conservative temperature, - then the sst is carried in T_diag(index_diag_temp). If the prognostic - temperature is potential temperature, then the sst is carried in - T_prog(index_temp). - - Note that this routine is called after eta_and_pbot_diagnose, - so Thickness%eta is eta_t(taup1). - -
-
-
-- - -
-zero_ocean_sfc
--
-- -DESCRIPTION -
-- - Zero the elements of the Ocean_sfc derived type. -
-
-
-- - -
-avg_ocean_sfc
--
-- -DESCRIPTION -
-- - Compute average of ocean surface quantities. This is for coupling, - where pass time averaged information from ocean to other component - models. Note that Ocean_sfc%frazil is NOT time averaged. Rather, it - is accumulated from T_diag(index_frazil)%field in subroutine sum_ocean_sfc. - Doing so is necessary for heat conservation between ocean and sea - ice systems. Since it is not time averaged, frazil is not part of - this averaging subroutine. - - Note that ocean model SST passed to the atmosphere is the surface - potential temperature (which is equal to surface in situ temperature). - If the ocean prognostic temperature variable is conservative temperature, - then the sst is carried in T_diag(index_diag_temp). If the prognostic - temperature is potential temperature, then the sst is carried in - T_prog(index_temp). - - Note that if one removes the averaging, then we take only the - latest values of the surface fields. This approach has been - found useful to stabilize the "concurrent" coupling approach. - - Note that this routine is called after eta_and_pbot_diagnose, - so Thickness%eta is eta_t(taup1). - -
-
-
-- - -
-ocean_sfc_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_sfc_end
--
-- -DESCRIPTION -
-- - Save information from Ocean_sfc to restarts. Note that it is - important in general to distinguish the time accumulated quantity - Ocean_sfc%frazil, saved here, from the instantaneous quantity - T_diag%frazil, which is saved in the diagnostic tracer restart file. -
-
-
-- - -
-get_ocean_sbc
--
-- -DESCRIPTION -
-- - Subroutine to get the surface fluxes passed into the ocean from - other component models. - - **momentum fluxes from wind stress and momentum of pme and rivers - **stokes drift from surface wave model - **water fluxes and temp/salinity in water fluxes - **salt fluxes; real or virtual - **heat fluxes - **applied surface pressure - -
-
-
-- - -
-flux_adjust
--
-- -DESCRIPTION -
-- - Subroutine to compute the surface fluxes derived from a - restoring condition and/or correction from an input file. - - We use a convention whereby a positive - flux enters the ocean: (+) down convention. - - When restoring salinity, one may choose to convert this - flux to an implied water flux, or keep it a salt flux. - Converting to a water flux will alter the sea level, and - so alter the concentration of other tracers. - The default is to keep it as a salt flux. - -
-
-
-- - -
-ocean_sbc_diag
--
-- -DESCRIPTION -
-- - Compute and send diagnostics from get_ocean_sbc. -
-
-
-- - - -
--
-- -DESCRIPTION -
-- - TEOS-10 expression for latent heat of fusion at the sea surface (p=0dbar) - - The following is from the from the matlab routine due to - McDougall and Barker with respect to the full pressure dependent - formulation. - - Note that the computed latent heat of fusion from this function has - errors that range between -0.4 and 0.3 J kg^-1, when compared with the - latent heats of melting derived from the Gibbs functions of ice and of - seawater (using the SIA code of TEOS-10). However, the underlying data to - the Gibbs function contains uncertainities of 200 J kg^-1 (IOC et al., 2010). - - The reference for this routine is - - IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of - seawater - 2010: Calculation and use of thermodynamic properties. - Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, - UNESCO (English), 196 pp. Available from http://www.TEOS-10.org - See section 3.34 of the TEOS-10 Manual. -
-
-
-- - - -
--
-- -DESCRIPTION -
-- - TEOS-10 expression for latent heat of vaporization at the sea surface - (p=0dbar). - The following is from the From the original matlab routine due to - Barker, McDougall and Feistel - - Calculates latent heat, or enthalpy, of evaporation at p = 0 (the - surface). It is defined as a function of Absolute Salinity, SA, and - Conservative Temperature, CT, and is valid in the ranges - 0 < SA < 42 g/kg and 0 < CT < 40 deg C. The errors range between - -0.4 and 0.6 J/kg - - IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of - seawater - 2010: Calculation and use of thermodynamic properties. - Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, - UNESCO (English), 196 pp. Available from http://www.TEOS-10.org - See section 3.39 of the TEOS-10 Manual. - -
-
-
-
-NAMELIST
- --&ocean_sbc_nml --
-
----
-- -use_waterflux -
-- Set to true when wish to use real fresh water flux as opposed to virtual - salt fluxes. This is the recommended method. The alternative virtual - tracer flux method (use_waterflux=.false.) is not routinely used at - GFDL, so it may suffer from poor testing. - Default use_waterflux=.true. -
-
-[logical] -- -waterflux_tavg -
-- Set to true when aiming to suppress the leap-frog computational mode - by setting pme and river equal to a time averaged value over the - present and previous time step. This method requires an extra - field in the restart file. This method is not needed when using - the TWO_LEVEL time tendency. It remains for those who wish to - use the leap-frog THREE_LEVEL time stepping scheme. - Note that it does not lead to simple checks of conservation across - model components, since there is a time averaging performed for - the water flux added to the ocean model. It is generally NOT - recommended. Default waterflux_tavg=.false. -
-
-[logical] -- -use_ideal_runoff -
-- To add an idealized liquid runoff read from a file. - This runoff is assumed to enter the ocean with the same temperature as - SST, and to be liquid. It is an additional runoff, so that any other - runoff remains unaltered. The runoff coming from idealized runoff is - NOT subject to the global normalization realized from - zero_net_water_coupler=.true. - Default use_ideal_runoff=.false. -
-
-[logical] -- -use_ideal_calving -
-- To add an idealized solid runoff or calving read from a file. - This calving runoff is assumed to require melting, so it extracts - latent heat of fusion from the liquid ocean - The runoff coming from idealized cavling is NOT subject to - the global normalization realized from zero_net_water_coupler=.true. - Default use_ideal_calving=.false. -
-
-[logical] -- -use_waterflux_override_calving -
-- Set to true will allow for model to incorporate the latent heating - from a calving field that comes in through coupled model instantaneous - interactions, but later will over-ride the mass flux from calving with - a dataset that is read in from a climatology or observations. - The idea is to only modify the mass contribution from calving through - the over-ride, and leave the latent heat contribution untouched. - Default use_waterflux_override_calving=.false. -
-
-[logical] -- -use_waterflux_override_fprec -
-- Set to true will allow for model to incorporate the latent heating - from a fprec field that comes in through coupled model instantaneous - interactions, but later will over-ride the mass flux from fprec with - a dataset that is read in from a climatology or observations. - The idea is to only modify the mass contribution from fprec through - the over-ride, and leave the latent heat contribution untouched. - Default use_waterflux_override_fprec=.false. -
-
-[logical] -- -use_waterflux_override_evap -
-- Set to true will allow for model to incorporate the latent heating - from an evap field that comes in through coupled model instantaneous - interactions, but later will over-ride the mass flux from evap with - a dataset that is read in from a climatology or observations. - The idea is to only modify the mass contribution from evap through - the over-ride, and leave the latent heat contribution untouched. - Default use_waterflux_override_evap=.false. -
-
-[logical] -- -temp_restore_tscale -
-- Time scale in days for restoring temperature within the top model - grid cell. -
-
-[real, units: day] -- -salt_restore_tscale -
-- Time scale in days for restoring salinity within the top model - grid cell. -
-
-[real, units: day] -- -eta_restore_tscale -
-- Time scale in days for restoring surface height to produce a modification to - surface water flux. This option is only available when run with - use_waterflux=.true. -
-
-[real, units: day] -- -use_constant_sst_for_restore -
-- To over-ride the sfc_restore.nc value for temp restoring. - use_constant_sst_for_restore=.false. -
-
-[logical] -- -constant_sst_for_restore -
-- The SST value used if use_constant_sst_for_restore=.true. - Default constant_sst_for_restore=12.0 -
-
-[real, units: degC] -- -salt_restore_as_salt_flux -
-- When running a use_waterflux=.true. model, we may choose to add the - salinity from a restoring condition as a salt flux or convert to - a fresh water flux. The addition of salt does not alter the sea - level nor does it alter the concentration of other tracers, whereas - converting to an implied water flux will alter sea level and other - concentrations. So we generally recommend the default - salt_restore_as_salt_flux=.true. -
-
-[logical] -- -use_constant_sss_for_restore -
-- To over-ride the sfc_restore.nc value for salinity restoring. - use_constant_sss_for_restore=.false. -
-
-[logical] -- -constant_sss_for_restore -
-- The SSS value used if use_constant_sss_for_restore=.true. - Default constant_sss_for_restore=35.0 -
-
-[real, units: psu] -- -max_delta_salinity_restore -
-- When computing the restoring flux for salinity, we can define - a maximum absolute value for the difference between salinity(k=1) - and the restoring salinity from a dataset. This approach is useful - especially in NAtl western boundary, where poor Gulf Stream separation - can lead to large salinity biases. If restore too much the salinity - field, we can spuriously transport large amounts of fresh water to the - subpoloar gyre, thus impacting the overturning circulation too much. - If max_delta_salinity_restore < 0.0, then will NOT provide a max to the - delta salinity; will instead compute an unbounded restoring flux. - Default max_delta_salinity_restore=-0.50. -
-
-[real, units: ppt] -- -read_restore_mask -
-- For reading in a mask that selects regions of the domain - that are restored (mask=1) or not restored (mask=0). - Default read_restore_mask=.false., whereby restore_mask - is set to tmask(k=1). -
-
-[logical] -- -restore_mask_gfdl -
-- For modifying the restore mask based on reading in - the GFDL regional mask. Default restore_mask_gfdl=.false. -
-
-[logical] -- -salinity_ref -
-- Reference salinity used for converting fresh water flux - to salt flux. -
-
-[real, units: psu] -- -salt_restore_under_ice -
-- Logical indicating whether to restore salinity under sea ice or not. - When .false. then will not restore salinity in regions where we - use a "frazil" condition as a proxy for where sea-ice is present. - Do not use sea ice extent from a sea ice model since we generally do - not pass information regarding ice extent between the sea ice model - and the ocean model. -
-
-[logical] -- -zero_net_salt_restore -
-- Logical indicating whether to remove the area mean of the salinity - restore flux so there is a net zero input of salt to the ocean - associated with restoring. -
-
-[logical] -- -zero_net_salt_correction -
-- Logical indicating whether to remove the area mean of the salinity - correction flux so there is a net zero input of salt to the ocean - associated with salt correction. -
-
-[logical] -- -zero_net_water_restore -
-- Logical indicating whether to remove the area mean of the water - restore flux so there is a net zero input of water to the ocean - associated with restoring. -
-
-[logical] -- -zero_net_water_correction -
-- Logical indicating whether to remove the area mean of the water - correction flux so there is a net zero input of water to the ocean - associated with water correction. -
-
-[logical] -- -zero_net_water_coupler -
-- Logical indicating whether to remove the area mean of the water - passed through the coupler so there is a net zero input of - fresh water to the ocean associated with p-e+r. Do so by removing - area mean from pme--keep river values unchanged. Note that a choice - must be made whether to remove the area mean from rivers or pme. - We choose pme since it is more evenly distributed than rivers. - Also note that we DO NOT include the ice melt in this normalization. - The reason is that we only wish to ensure the ocean+ice system - has a zero net water. When melt or form sea ice, this only transfers - water between liquid ocean and solid sea ice, and no normalization is - appropriate for this case. It is only the water exchanged with the - land and atmosphere that is normalized. -
-
-[logical] -- -zero_net_water_couple_restore -
-- This logical keeps the total water forcing on the ocean+ice system - to a global mean of zero at each time step. We DO NOT include - the ice melt in this normalization. - Setting zero_net_water_couple_restore to true may be appropriate when - running an ice-ocean model using a bulk formulae to compute - evaporation (e.g., CORE) and when only providing a weak (or zero) - salinity restoring. It is not appropriate when running a coupled - ocean-atmosphere model, where the moisture budget should be - conserved without an artificial removal of the global mean. -
-
-[logical] -- -land_model_heat_fluxes -
-- For the case where land model passes through the coupler the heat flux - associated with the liquid runoff and calving land ice fields. - This heat flux is computed relative to 0C, and takes the form - heat flux = mass flux of water * temp of water * heat capacity, - where the water can be either liquid or solid. For many coupled models, - the water temperature is assumed to be that of the SST. But - more complete land models now carry the heat of its water relative to 0C, - in which case the ocean model does not need to assume anything about the - heat content of the land water. - Default land_model_heat_fluxes=.false. -
-
-[logical] -- -debug_water_fluxes -
-- Logical for debugging water fluxes. Must be true for any of the - options zero_water_fluxes, zero_calving_fluxes, zero_pme_fluxes - or zero_runoff_fluxes to be enabled. - Default debug_water_fluxes=.false. -
-
-[logical] -- -zero_water_fluxes -
-- Logical for debugging to zero the pme, river, and pme_taum1 into - ocean, over-riding any input from Ice_ocean_boundary. - Default zero_water_fluxes=.false. -
-
-[logical] -- -zero_calving_fluxes -
-- Logical for debugging to zero the calving flux passed into the ocean. - Default zero_calving_fluxes=.false. -
-
-[logical] -- -zero_pme_fluxes -
-- Logical for debugging to zero the pme flux passed into the ocean. - Default zero_pme_fluxes=.false. -
-
-[logical] -- -zero_runoff_fluxes -
-- Logical for debugging to zero the runoff flux passed into the ocean. - Default zero_runoff_fluxes=.false. -
-
-[logical] -- -zero_river_fluxes -
-- Logical for debugging to zero the river (calving+runoff) flux passed into the ocean. - Default zero_river_fluxes=.false. -
-
-[logical] -- -convert_river_to_pme -
-- Logical for debugging. Here we add the river water input (calving+runoff) - to pme, then set river=calving=runoff=0.0. - Default convert_river_to_pme=.false. -
-
-[logical] -- -sbc_heat_fluxes_const -
-- Logical for setting the surface heat flux from the coupler - to a global constant. Default is sbc_heat_fluxes_const=.false. -
-
-[logical] -- -sbc_heat_fluxes_const_seasonal -
-- Logical for setting the surface heat flux from the coupler - to a global constant, and giving it a seasonally varying amplitude. - Default is sbc_heat_fluxes_const_seasonal=.false. -
-
-[logical] -- -sbc_heat_fluxes_const_value -
-- Value for the constant heat flux when using - sbc_heat_fluxes_const=.true. - Default sbc_heat_fluxes_const_value=0.0. -
-
-[real, units: W/m2] -- -zero_heat_fluxes -
-- Logical for debugging to set all heat fluxes into the ocean to zero, - over-riding any input from Ice_ocean_boundary. Default is .false. -
-
-[logical] -- -zero_surface_stress -
-- Logical for debugging to zero all surface stress applied to the ocean, - over-riding any input from Ice_ocean_boundary. Default is .false. -
-
-[logical] -- -rotate_winds -
-- Set to true when need to rotate the winds onto the ocean model grid. - This is needed for cases where the winds are on a spherical grid and - the ocean model uses tripolar=.true. If generate the wind data on - the ocean model grid, then do not need to rotate, since the rotation - has already been done. -
-
-[logical] -- -max_ice_thickness -
-- When coupling MOM to an ice model, the sea ice thickness may need - to be restricted to prevent vanishing top-level in MOM. Set - max_ice_thickness (meters) < dzt(k=1) to restrict. This truncation - avoids the numerical problem but we loose mass conservation in the coupled - sea ice and ocean system. We also alter the pressure felt on the ocean - as applied by the sea ice. Different vertical coordinates are needed - to do the problem more realistically. - - Note that the problem of vanishing top layer is removed when use - either ZSTAR or PSTAR as vertical coordinate. -
-
-[real, units: m] -- -ice_salt_concentration -
-- The salt concentration of sea ice. This is taken as a bulk value, and should - be the same as that used by the ice model. Default is ice_salt_concentration=0.005, - as that is the value used in the GFDL coupled climate model. -
-
-[real, units: kg salt / kg ice] -- -runoff_salinity -
-- The salinity of river runoff water. Default is runoff_salinity=0.0. -
-
-[real, units: g salt / kg runoff water (ppt)] -- -runoff_temp_min -
-- The minimum temperature that river runoff into the ocean is assigned. - Default runoff_temp_min=0.0. -
-
-[real, units: DegC] -- -runoffspread -
-- Set to true if wish to use the spread_river_horz algorithm to spread - the river runoff flux horizontally over an area into the ocean wider than - set by the coupler. This option requires the setup of a table for - determining the points over which we spread. - Default runoffspread=.false. -
-
-[logical] -- -calvingspread -
-- Set to true if wish to use the spread_river_horz algorithm to spread - the calving flux horizontally over an area into the ocean wider than - set by the coupler. This option requires the setup of a table for - determining the points over which we spread. - Default calvingspread=.false. -
-
-[logical] -- -avg_sfc_velocity -
-- If set to true, the u and v fields passed up to the sea ice - are averaged over a coupling interval. TRUE by default. -
-
-[logical] -- -avg_sfc_temp_salt_eta -
-- If set to true, the t, s and sea_level fields passed up to the sea ice - are averaged over a coupling interval. TRUE by default. -
-
-[logical] -- -use_full_patm_for_sea_level -
-- The option use_full_patm_for_sea_level allows for the passing - of the sea level including the full weight of sea ice back to - the ice model. This approach maintains the max weight on the liquid - ocean according to the nml variable max_ice_thickness. But it does - allow the sea ice to know when there is actually more sea ice than that - set by max_ice_thickness. This option then provides for a negative - feedback on the runaway growth of sea ice, since the full pressure acting to - make the ice flow will be correctly felt. This is a new option, and is not - fully tested, So the default is use_full_patm_for_sea_level=.false -
-
-[logical] -- -do_flux_correction -
-- For applying surface flux correction to to a tracer or wind stress field. - This code is used at GFDL for idealized perturbation experiments, such - as when one wishes to artificially enhance the wind stress to test - model sensitivity. It is also appropriate for coupled models that - may require a modification to the fluxes arrising from a coupled model, - via reading in information from a pre-defined - data file, - Default do_flux_correction=.false. -
-
-[logical] -- -temp_correction_scale -
-- A scale multiplying the flux correction for temperature. - Default temp_correction_scale=0.0. -
-
-[real, units: dimensionless] -- -salt_correction_scale -
-- A scale multiplying the flux correction for salinity. - Default salt_correction_scale=0.0. -
-
-[real, units: dimensionless] -- -tau_x_correction_scale -
-- A scale multiplying the flux correction for tau_x. - Default tau_x_correction_scale=0.0. -
-
-[real, units: dimensionless] -- -tau_y_correction_scale -
-- A scale multiplying the flux correction for tau_y. - Default tau_y_correction_scale=0.0. -
-
-[real, units: dimensionless] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is do_bitwise_exact_sum=.true. in order to ensure answers - do not change when alter processors. But if wish to enhance the efficiency - of coupled ocean-ice models that use one of the global normalization options - zero_net_salt_restore =.true. - zero_net_salt_correction =.true. - zero_net_water_restore =.true. - zero_net_water_correction =.true. - zero_net_water_coupler =.true. - zero_net_water_couple_restore=.true. - then one may wish to consider setting do_bitwise_exact_sum=.false. -
-
-[logical] -- -constant_hlf -
-- Treat latent heat of fusion as a constant. Otherwise, use the TEOS-10 - approach in which hlf is function of surface salinity. - Note, TEOS-10 approach is only valid using Absolute Salinity and - conservative temperature as the prognostic fields. - Default constant_hlf = .true., which is the case for pre-TEOS-10 methods. -
-
-[logical] -- -constant_hlv -
-- Treat latent heat of vaporization as a constant. Otherwise, use the TEOS-10 - approach in which hlf is function of surface salinity. - Note, TEOS-10 approach is only valid using Absolute Salinity and - conservative temperature as the prognostic fields. - Default constant_hlv = .true., which is the case for pre-TEOS-10 methods. -
-
-[logical] -- -read_stokes_drift -
-- This option is to be used when coupling to a surface wave model such as - Wavewatch III that provides both the Stokes drift (m/s) velocity at the - ocean surface, and a decay scale for projecting the Stokes - drift into the interior. Default read_stokes_drift = .false. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_thickness.F90 b/src/mom5/ocean_core/ocean_thickness.F90 index f00a52b270..39f36faee3 100644 --- a/src/mom5/ocean_core/ocean_thickness.F90 +++ b/src/mom5/ocean_core/ocean_thickness.F90 @@ -288,9 +288,9 @@ module ocean_thickness_mod character(len=128) :: version=& - '$Id: ocean_thickness.F90,v 1.1.2.10 2012/06/04 00:11:43 Stephen.Griffies Exp $' + '$Id: ocean_thickness.F90,v 20.0 2013/12/14 00:12:33 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' type(ocean_domain_type), pointer :: Dom =>NULL() @@ -647,7 +647,7 @@ subroutine ocean_thickness_init (Time, Time_steps, Domain, Grid, Ext_mode, Thic do j=jsc,jec do i=isc,iec if(Grid%ht(i,j) > 0.0 .and. Grid%ht(i,j) < thickness_dzt_min) then - write(unit,'(/a,i4,a,i4,a,e22.12,a,e22.12)') & + write(unit,'(/a,i4,a,i4,e22.12,a,e22.12)') & '==>Error: ocean_thickness_init: ht(',i+Dom%ioff,',',j+Dom%joff,') = ',Grid%ht(i,j), & 'is less than the chosen setting for thickness_dzt_min = ',thickness_dzt_min error_flag=.true. @@ -665,7 +665,7 @@ subroutine ocean_thickness_init (Time, Time_steps, Domain, Grid, Ext_mode, Thic do j=jsc,jec do i=isc,iec if(Grid%ht(i,j) > 0.0 .and. Grid%ht(i,j) < thickness_dzt_min_init) then - write(unit,'(/a,i4,a,i4,a,e22.12,a,e22.12)') & + write(unit,'(/a,i4,a,i4,e22.12,a,e22.12)') & '==>Error: ocean_thickness_init: ht(',i+Dom%ioff,',',j+Dom%joff,') = ',Grid%ht(i,j), & 'is less than the chosen setting for thickness_dzt_min_init = ',thickness_dzt_min_init error_flag=.true. @@ -1488,7 +1488,6 @@ subroutine ocean_thickness_init_adjust(Grid, Time, Dens, Ext_mode, Thickness) real, dimension(isd:ied,jsd:jed) :: fraction_differ real, dimension(isd:ied,jsd:jed) :: rescale_mass real, dimension(isd:ied,jsd:jed) :: ht_mod - real, dimension(isd:ied,jsd:jed,nk) :: inv_dzt_dst integer :: stdoutunit stdoutunit=stdout() @@ -1536,6 +1535,7 @@ subroutine ocean_thickness_init_adjust(Grid, Time, Dens, Ext_mode, Thickness) write(stdoutunit,'(/a/)') & '==>Note: ocean_thickness_init_adjust adjusting time=0 vgrid using in situ density.' + wrk1(:,:,:) = 0.0 wrk2(:,:,:) = 0.0 wrk3(:,:,:) = 0.0 wrk4(:,:,:) = 0.0 @@ -1564,7 +1564,7 @@ subroutine ocean_thickness_init_adjust(Grid, Time, Dens, Ext_mode, Thickness) Thickness%dzt(i,j,k) = Thickness%dst(i,j,k)*Thickness%dzt_dst(i,j,k) Thickness%rho_dzt(i,j,k,:) = density_tmp*Thickness%dzt(i,j,k) Thickness%rho_dztr(i,j,k) = 1.0/(Thickness%rho_dzt(i,j,k,tau)+epsln) - inv_dzt_dst(i,j,k) = 1.0/Thickness%dzt_dst(i,j,k) + wrk1(i,j,k) = 1.0/Thickness%dzt_dst(i,j,k) enddo enddo enddo @@ -1661,7 +1661,7 @@ subroutine ocean_thickness_init_adjust(Grid, Time, Dens, Ext_mode, Thickness) Thickness%dztup(i,j,k) = Thickness%dstup(i,j,k)*Thickness%dzt_dst(i,j,k) Thickness%rho_dzt(i,j,k,:) = density_tmp*Thickness%dzt(i,j,k) Thickness%rho_dztr(i,j,k) = 1.0/(Thickness%rho_dzt(i,j,k,tau)+epsln) - inv_dzt_dst(i,j,k) = 1.0/Thickness%dzt_dst(i,j,k) + wrk1(i,j,k) = 1.0/Thickness%dzt_dst(i,j,k) enddo enddo enddo @@ -1780,7 +1780,7 @@ subroutine ocean_thickness_init_adjust(Grid, Time, Dens, Ext_mode, Thickness) do k=1,nk-1 do j=jsd,jed do i=isd,ied - Thickness%dzwt(i,j,k) = 2.0*Thickness%dswt(i,j,k)/(inv_dzt_dst(i,j,k)+inv_dzt_dst(i,j,k+1)) + Thickness%dzwt(i,j,k) = 2.0*Thickness%dswt(i,j,k)/(wrk1(i,j,k)+wrk1(i,j,k+1)) enddo enddo enddo diff --git a/src/mom5/ocean_core/ocean_thickness.html b/src/mom5/ocean_core/ocean_thickness.html deleted file mode 100644 index ed2a9d6804..0000000000 --- a/src/mom5/ocean_core/ocean_thickness.html +++ /dev/null @@ -1,881 +0,0 @@ - - - -Module ocean_thickness_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_thickness_mod
- - - - - -
-OVERVIEW
- -- Determine thickness of grid cells. -
- - - -- This module determines the thickness of grid cells. - Thicknesses are generally time dependent and functions - of the vertical coordinate. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_grids_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_thickness_init:
- -- -thickness_initialize:
- -- -ocean_thickness_init_adjust:
- -- -thickness_restart:
- -- -calculate_restart_thickness:
- -- -dst_land_adjust:
- -- -update_tcell_thickness:
- -- -update_ucell_thickness:
- -- -rho_dzt_tendency:
- -- -thickness_chksum:
- -- -thickness_details:
- -- -ocean_thickness_restart:
- -- -ocean_thickness_end:
- -- -REMAP_ZT_TO_ZU:
- -- -dzt_dst_update:
- -- -update_tcell_thick_blob:
- -- -update_E_thickness:
- -- -thickness_chksum_blobs:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_thickness_init
--
-- -DESCRIPTION -
-- - Initialize the thickness type. - - For pressure-based vertical coordinates, this initialization here - is preliminary. -
-
-
-- - -
-thickness_initialize
--
-- -DESCRIPTION -
-- - Initialize vertical thicknesses of grid cells. - For Boussinesq models, this code assumes the - surface heights eta_t and eta_u are zero. - - The values here are relevant for the time=0 initialization - of the model. Some time independent arrays are also set here, - but they are over-written if there is a restart file. - - For pressure based vertical coordinates, the results here - assume density = rho0_profile(k). The values are readjusted in - ocean_thickness_init_adjust after we have determined the initial - in situ density. This readjustment may involve enforcing an - initial eta field of zero value, or the default which allows - for eta to initially be nonzero. - -
-
-
-- - -
-ocean_thickness_init_adjust
--
-- -DESCRIPTION -
-- - - When initializing the pressure model, we can choose to initialize - with a zero surface height, which requires some adjustment of - bottom depths, or allow the surface height to be nonzero. - - The default is a nonzero surface height via - initialize_zero_eta=.false. - -=============================================================== - The following comments refer to the possible issues arising - from enforcing eta=0 on initialiation via - initialize_zero_eta=.true. - - If we wish to enforce eta=0 on initialization, then we determine - the depth of ocean needed to ensure a minimum bottom cell - thickness as set by nml paramter thickness_dzt_min_init. - This bottom depth is a function of the initial in-situ density - as well as the nml thickness_dzt_min_init. - - If Grid%ht is sufficient according to the specifications of - thickness_dzt_min_init and the initial in-situ density, then - model is likely to remain stable, in that there is very small - chance of losing bottom cell. - (assuming thickness_dzt_min_init is > 5.0 or so). - - If Grid%ht is too shallow, again given the initial rho and - pressure increments dst, then it is recommended that the user - modify either the initial density (not easy) or the bottom - topography (easy). The modifications are often quite trivial, - depending on thickness_dzt_min_init and how light certain regions - of the model are. The array "ht_mod" can be saved in the - diag_table and compared to Grid%ht to see what modifications - are required. If modificatations are to be made to the original - grid_spec.nc file, simply use the NCO commands as follows: - - 1/ remove the original depth_t array from the original grid spec - file, and write out a new grid spec file absent the depth_t array. - ncea -x -v depth_t grid_spec_old.nc grid_spec_new.nc - - 2/ append to the new grid spec file the modified bottom topography - array ht_mod, which was generated in an earlier run of the model. - ncea -A -v ht_mod history_file_with_ht_mod.nc grid_spec_new.nc - - 3/ rename ht_mod to depth_t to conform to standard MOM grid_spec - name convention. - ncvarrename new_grid.nc ht_mod depth_t - - If there are no modifications required to the depth_t array, - then it is unlikely that the pressure model will evolve to the - point of loosing the bottom cell and thus the model will remain - stable. This conclusion is certainly based on the degree to which - the model is run with changes in water masses. - -=============================================================== - - NOTE: We generally compute values for the grid increments over - land. The land values that are in the global halos are not - going to be available from the restart files. Hence, they - will need to be recomputed when restarting the model. This - recalculation is done in dst_land_adjust. - - The land values are needed for use in computing U-cell grid - factors using remapping operators. If we naively place zeros - in the land, then, for example, rho_dzu next to land will be - wrong, as it will be based on averaging a non-zero interior - rho_dzt value with a rho_dzt incorretly set to zero, and so - lead to spuriously small rho_dzu values next to land. Note that - the placement of nonzero values of the grid values over land - is something that is trivially done for the z-models. More care - is needed with pressure models. - -
-
-
-- - -
-thickness_restart
--
-- -DESCRIPTION -
-- - Read basic elements of thickness derived type from restart, - then set remaining elements of the type. - - Note that some array elements may be time independent. - Their values have already been set in thickness_initialize - or ocean_thickness_init_adjust, and they should not be - over-written here (in particular, they should not be - reset here to zero). - - To ensure reproducibility across restarts, this routine - uses the same logic as update_tcell_thickness and - update_ucell_thickness. This is particularly important - for the terrain following calculations. - - Note that ocean_thickness_init is called prior to - ocean_operators_init. Hence, we cannot use any - operators in this subroutine. - -
-
-
-- - -
-calculate_restart_thickness
--
-- -DESCRIPTION -
-- - This subroutine calculates the total thickness and the E contribution - to thickness. It is used for the press, pstar and zstar vertical - coordinates. -
-
-
-- - -
-dst_land_adjust
--
-- -DESCRIPTION -
-- - For computing the grid values inside land in global halos. - These values are not zero, and so they are not available from - restart file. They are needed for pressure-based vertical - coordinate models in order to get the U-cell values at - global land boundaries via the remap operator. - - This step is necessitated by the modifications to dst - and other arrays made in ocean_thickness_init_adjust. -
-
-
-- - -
-update_tcell_thickness
--
-- -DESCRIPTION -
-- - Update time dependent thickness of T cells. When not using the - Lagrangian blob scheme. For routines relevant to the blobs, we use: - 1/ update_tcell_thic_blob - 2/ update_E_thickness - 3/ dzt_dst_update - which are further down the module. - - Notes - - 1. For pressure-based coordinates, must use rho(tau) since - rho(taup1) has not yet been computed. This is a limitation of - the "z-like" algorithm approach used in MOM. It is minor, - however, since rho(tau) is very close to rho(taup1). Also, this - approach comes with the advantage of rendering vertical - physical processes (e.g., diffusion) linear for the general - coordinates in MOM, just as with geopotential models. - - 2. For all coordinates, need to place something reasonable over - land for dz increments to preclude division by zero. - For GEOPOTENTIAL and ZSTAR, we just use the time=zero value for dzt. - For ZSIGMA we set a minimum depth for a fictitious layer over land. - For PRESSURE and PSTAR, we set rho=rho0_profile and use the time=0 dzt values. - For PSIGMA, we rho=rho0_profile and use the fictitious layer over land. - The treatment of these land-points only contributes to the treatment - of the U-cell grid quantities in the halos and on land, as they are - computed via the REMAP_ZT_TO_ZU operator. - - 3. We need to update s-coordinate increments for GEOPOTENTIAL and - PRESSURE. It is only for these two coordinates that we modify the - endpoint values for the s-grid increments. - -
-
-
-- - -
-update_ucell_thickness
--
-- -DESCRIPTION -
-- - Update time dependent thickness of U cells. - - Notes - - The computation of the depth arrays is a bit ad hoc. Here are - the methods and their rationale. - - 1. For terrain following coordinates, the remap operator will entrain - the very shallow layer T-points over land into the four-point averaging. - This will cause the resulting U-cell depths next to land to be far shallower - than what they should be. To avoid this problem, we set the U-cell depths the - same as the T-cell depths. This specification causes no problems for budgets - or energetic balance since Grid%umask array is already defined according to - the usual B-grid specification. - - 2. For non-terrain and non-geopotential coordinates, compute U-cell thicknesses - as min of surrounding T-cell thicknesses. This method follows that - used with earlier MOM versions for the bottom partial step topography. - Experiments with ZSTAR reveal that we must use the min function for dzu - computation, rather than the alternative of a remap operator. If using - the remap operator and nontrivial topography, then the velocity field can - develop nontrivial noise. We have found that can compute dzwu using the - remap operator without introducing noise. But we choose to use the - min function to maintain compatibility with traditional approach in - geopotential vertical coordinate versions of MOM. - - If use_blobs=.true. in the ocean_model_nml, we adopt the following: - *dzuT = min of surrounting T-cell thickness, - *dzuL = min of surrounting T-cell thickness, - *dzu = *dzuT - *dztL -
-
-
-- - -
-rho_dzt_tendency
--
-- -DESCRIPTION -
-- - Compute tendency for rho_dzt. This tendency is a function of the - vertical coordinate. -
-
-
-- - -
-thickness_chksum
--
-- -DESCRIPTION -
-- - - Compute checksum for thickness components . - Only print checksums for fields that should agree across restarts. - -
-
-
-- - -
-thickness_details
--
-- -DESCRIPTION -
-- - - For debugging, we print here some details of the grid at a particular - (i,j) point. - -
-
-
-- - -
-ocean_thickness_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_thickness_end
--
-- -DESCRIPTION -
-- - Write basic elements of thickness derived type to restart -
-
-
-- - -
-REMAP_ZT_TO_ZU
--
-- -DESCRIPTION -
-- - REMAP_ZT_TO_ZU remaps a T-cell thickness or vertical depth on a - T-cell to the corresponding place on U-cell. - - This is the same operator as REMAP_BT_TO_BU. - It is needed for ocean_thickness_init since this routine is called - prior to ocean_operators_init. This is a bit awkward, but - ocean_operators needs thickness values, so it must be called - after thickness is initialized. -
-
-
-- - -
-dzt_dst_update
--
-- -DESCRIPTION -
-- - Calculate the quantity dzt_dst. dzt_dst is required by the Lagrangian - blob framework in order to calculate the grid cell the a blob resides - in at taup1. This information is required prior to the the earliest - time that we can update the total thickness. As such, we are - motivated to separate this calculation when use_blobs=.true. - When use_blobs=.false. the calculation is conducted when the tcell - thickness is updated. - We also update coordinate increments for GEOPOTENTIAL and PRESSURE. - Only for these two coordinates do we need to modify the endpoint - values for the s-grid increments. Other MOM coordinates have dst - and dswt constant in time. - - Note that at present, GEOPOTENTIAL coordinates are not supported - by this implementation of the blob framework. -
-
-
-- - -
-update_tcell_thick_blob
--
-- -DESCRIPTION -
-- - The same principle is used as for update_tcell_thickness, however, - this routine is specific to the Lagrangian blob scheme. - - The routine calculates the total tracer grid cell thickness for the - various vertical coordinate systems (excluding ZSGIMA and PSIGMA). - Major things to note are: - 1/ dzt_dst is calculated previously using dzt_dst_update - 2/ this routine does not calculate the L or E system thicknesses, - those are calculated separately. - 3/ This routine is not called unless use_blobs=.true. in - ocean_model_nml. - - Note that the present implementation of the Lagrangian blobs does - not support ZSIGMA or ZPRESSURE coordinates. GEOPOTENTIAL is also - not supported. - - Also note that we calculate the total density weighted thickness, - rho_dztT, is calculated differently to how the density weighted - thickness is calculated without the blobs, rho_dzt. - rho_dztT(taup1) = rho_dztT(tau) + dtime*rho_dzt_tendency -
-
-
-- - -
-update_E_thickness
--
-- -DESCRIPTION -
-- - Calculates the E system thickness using the basic formulation, - E_thickness = Total_thickness - L_thickness - - Note that this routine is called twice each time step. Once from - update_ocean_model, and once from the update_ocean_tracer. The - second call is required after the implicit adjustment involving - blobs. -
-
-
-- - -
-thickness_chksum_blobs
--
-- -DESCRIPTION -
-- - Compute checksum for thickness components for the Lagrangian and - total thicknesses. - - Only print checksums for fields that should agree across restarts. - -
-
-
-
-NAMELIST
- --&ocean_thickness_nml --
-
----
-- -debug_this_module -
-- For debugging. -
-
-[logical] -- -debug_this_module_detail -
-- For debugging pressure coordinate models. Lots of grid information - printed. -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -linear_free_surface -
-- For debugging, set the thickness of top cell in - geopotential model to time independent values. - This option is needed if use the kappa_sort diagnostic. - Default linear_free_surface=.false. -
-
-[logical] -- -thickness_method -
-- To determine whether use energetic method or finite volume method - to compute the thickness of a grid cell. Options are - thickness_method=energetic or thickness_method=finitevolume. - There is little overall difference in results for pbot and eta. - However, it has been found that for realistic bottom topography - simulations, the vertical velocity component is very noisy with - the finitevolume approach. So this approach is considered - experimental. The default is thickness_method='energetic'. -
-
-[character] -- -full_step_topography -
-- For case where with to only have the dzt be determined by the full step - bottom topography. This nml option is provided only for backwards - compatibility with older mom experiments using the full step topog. -
-
-[logical] -- -enforce_positive_dzt -
-- For cases where wish to run model even with negative thickness. - Default enforce_positive_dzt=.false. -
-
-[logical] -- -epsilon_init_thickness -
-- For determining how strict we are to check for the thickness of - a column when initializing pressure based vertical coordinate models. -
-
-[dimensionless] -- -thickness_dzt_min -
-- Minimum dzt set when enforce_positive_dzt set true. - Default thickness_dzt_min=1.0. -
-
-[real, units: m] -- -initialize_zero_eta -
-- For pressure-based models, we can (with some work) initialize the - model to have a zero surface height. The recomended approach is to - allow the surface height to be whatever it wants to be, and let adjustments - smooth it over time. Default initialize_zero_eta=.false. -
-
-[logical] -- -thickness_dzt_min_init -
-- For determining a modified bottom depth array - that is required to ensure pressure model, based on initial - in-situ density, retains a nontrivial bottom cell thickness - in the case when initialize_zero_eta=0.0 - Default thickness_dzt_min_init=5.0. -
-
-[real, units: m] -- -rescale_mass_to_get_ht_mod -
-- Expedient to allow for the computation of ht_mod. - in the case when initialize_zero_eta=.true. Here, - we run the pressure based model with a rescaled mass that - is sufficient to maintain non-negative dzt, at least for - a short period. This allows for one to run a day integration - to produce ht_mod. rescale_mass_to_get_ht_mod=.true. will - produce spurious results in general due to problems with the - pressure gradient computation. So it is not recommended for - more than initial day or so. Default rescale_mass_to_get_ht_mod=.false. -
-
-[logical] -- -read_rescale_rho0_mask -
-- For reading in a basin mask of use to re-define rho0 in - isolated regions such as the Black Sea. This is used for - modifying the definition of the pressure or pstar levels - during the initialization of the thicknesses dst. This - approach is appropriate in general, but has only been tested - when modify the pressure levels within a fully enclosed basin. - Default read_rescale_rho0_mask=.false. -
-
-[logical] -- -rescale_rho0_mask_gfdl -
-- For specifying the rescale_rho0_mask based on reading in - the GFDL regional mask. Default rescale_rho0_mask_gfdl=.false. -
-
-[logical] -- -rescale_rho0_basin_label -
-- For rescaling rho0 in a basin with a number rescale_rho0_basin_label. - For the Black Sea using GFDL basin masks in OM3, - rescale_rho0_basin_label=7.0. Default rescale_rho0_basin_label=-1.0 -
-
-[real] -- -rescale_rho0_value -
-- Fractional value for rescaling rho0 in the a region. - Default rescale_rho0_value=1.0. -
-
-[logical] -- -depth_min_for_sigma -
-- For sigma coordinates, have minimum depth so that have layers defined - globally. Masks will zero out results over land, but for numerics - it is useful to compute everywhere. Default depth_min_for_sigma=0.01. -
-
-[real, units: m] -- -read_rho0_profile -
-- To read in an initial rho0(z) profile to assist in defining the - initial settings for the pressure increments dst, for use in - setting the pressure-based vertical coordinate grids. Ideally, - this profile is determined by the level averaged density in - the initial conditions. Note that it is essential to have - rho0_profile have a sensible value at all depths even if there - is no water there, since there are places where we divide by - rho0_profile in rock. Also, be mindful that with denser water - at depth, the pressure levels will be coarser at depth than if - using the trivial density profile rho0(k)=rho0. - This option is experimental, so it is recommended that user - maintain the default read_rho0_profile=.false. -
-
-[logical] -- -pbot0_simple -
-- For testing purposes, have this option compute pbot0=g*rho0*ht - with rho0= constant. Default pbot0_simple=.false. -
-
-[logical] -- -update_dzwu_k0 -
-- A bug in certain versions of MOM4p1 was present, whereby - Thickness%dzwu(i,j,k=0) was never updated, except for GEOPOTENTIAL - vertical coordinates. This logical, whose default is - update_dzwu_k0=.true., is provided for legacy purposes. - To test the older results, have update_dzwu_k0=.false. -
-
-[logical] -- -max_num_bad_print -
-- Maximum bad grid cells printout for identifying problematic simulations. - Default max_num_bad_print=25. -
-
-[integer] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_topog.F90 b/src/mom5/ocean_core/ocean_topog.F90 index d5ce0150d8..a5be0dc1ee 100644 --- a/src/mom5/ocean_core/ocean_topog.F90 +++ b/src/mom5/ocean_core/ocean_topog.F90 @@ -61,8 +61,8 @@ module ocean_topog_mod implicit none private -character(len=256) :: version='CVS $Id: ocean_topog.F90,v 1.1.2.2 2012/05/17 13:41:40 smg Exp $' -character(len=256) :: tagname='Tag $Name: mom5_siena_08jun2012_smg $' +character(len=256) :: version='CVS $Id: ocean_topog.F90,v 20.0 2013/12/14 00:12:35 fms Exp $' +character(len=256) :: tagname='Tag $Name: tikal $' #includediff --git a/src/mom5/ocean_core/ocean_topog.html b/src/mom5/ocean_core/ocean_topog.html deleted file mode 100644 index 2fedb0d381..0000000000 --- a/src/mom5/ocean_core/ocean_topog.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - Module ocean_topog_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_topog_mod
- - - - - -
-OVERVIEW
- -- Set up ocean bottom topography. -
- - - -- Set up ocean bottom topography. Reads information from grid specification file. --
- - -
-OTHER MODULES USED
- --- - - -fms_mod-
mpp_domains_mod
mpp_mod
axis_utils_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_topog_init:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_topog_init
--
-- -DESCRIPTION -
-- - Initialize the ocean bottom topography. - - There are two reasons to prefer land be at j=1. - - A/ MOM employs a northest B-grid. To construct - horizontal remapping operators, we need information - about grid factors one row outside of the global - domain boundaries. In particular, we need j=0 - grid information. However, when constructing the grid spec - file, we assume nothing about the region outside - the global domain. So MOM's requirement of j=0 - grid information necessitates extrapolation. - This extrapolation is done inside ocean_grids.F90, and - it can lead to non-symmetric values of grid spacing - for the region j=0 and j=nj, even if the domain global - limits are symmetric across the equator. - - B/ The FMS Sea Ice Simulator (SIS) requires land to be present - for all points at jsc+joff=1. If this is not the case, then - the ocean model cannot be coupled to SIS. The SIS requirement - of all land at jsc+joff=1 is related to the use of a northeast - B-grid convention. To couple the models, the ocean grid - must be generated with fill_first_row=.true. - -
-
-
-
-NAMELIST
- --&ocean_topog_nml --
-
----
-- -debug_this_module -
-- For debugging. -
-
-[logical] -- -flat_bottom -
-- For debugging, it is often useful to over-ride the grid spec file - and simply make the domain flat bottom. -
-
-[logical] -- -flat_bottom_kmt -
-- Number of depth levels to use for the flat_bottom option. -
-
-[integer] -- -flat_bottom_ht -
-- Depth to make the flat_bottom. -
-
-[real] -- -min_thickness -
-- min_thickness is only used for Mosaic grid. Since there is no kmt available - in mosaic grid, need to set min_thickness to configure kmt based on ht and zw. - Default min_thickness=1.0 metre. -
-
-[real] -- -kmt_recompute -
-- To recompute the kmt array based on min_thickness. This step is not recommended - in general, since it can modify the kmt array which may be in the grid spec file. - But it may be of use for specialized situations, such as when you wish to use - the same topography file with a refined vertical resolution. -
-
-[logical] -- -kmt_recompute_offset -
-- To recompute the kmt array based on min_thickness, with an offset - determined by kmt_recompute_offset. Default kmt_recompute_offset=0. -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_types.F90 b/src/mom5/ocean_core/ocean_types.F90 index 17e042da26..5455912235 100644 --- a/src/mom5/ocean_core/ocean_types.F90 +++ b/src/mom5/ocean_core/ocean_types.F90 @@ -16,10 +16,10 @@ module ocean_types_mod ! -!Matt Harrison +! Matt Harrison ! ! -!+! ! S. M. Griffies ! ! @@ -46,9 +46,9 @@ module ocean_types_mod logical :: module_is_initialized=.false. character(len=128) :: version = & - '$Id: ocean_types.F90,v 1.1.2.17 2012/06/04 00:11:43 Stephen.Griffies Exp $' + '$Id: ocean_types.F90,v 20.0 2013/12/14 00:12:37 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' type, public :: obc_flux @@ -140,7 +140,7 @@ module ocean_types_mod real, dimension(isd:ied,jsd:jed,nk) :: rho_dzt_tendency ! rho_dzt tendency (kg/m^3)*(m/s) - real, dimension(isd:ied,jsd:jed) :: sea_lev ! eta_t + patm/(rho0*grav) - eta_geoid - eta_tide (m) at time taup1 for coupler + real, dimension(isd:ied,jsd:jed) :: sea_lev ! eta_t + patm/(rho0*grav) - eta_geoid - eta_tide (m) at time taup1 for coupler real, dimension(isd:ied,jsd:jed,nk) :: dzt ! thickness (m) of T cell at time tau/taup1 real, dimension(isd:ied,jsd:jed,nk,2) :: dzten ! thickness (m) of east/north face of T cell at time tau/taup1 real, dimension(isd:ied,jsd:jed,nk) :: dzu ! thickness (m) of U cell at time tau/taup1 @@ -556,11 +556,16 @@ module ocean_types_mod real, dimension(isd:ied,jsd:jed,2) :: smf_cgrid ! momentum flux per mass into ocean surface at Cgrid u/v points (N/m^2) real, dimension(isd:ied,jsd:jed,2) :: bmf ! momentum flux per mass into ocean bottom (N/m^2) real, dimension(isd:ied,jsd:jed) :: gamma ! dimensionful bottom drag coefficient (kg/(m^2 sec)) + real, dimension(isd:ied,jsd:jed) :: langmuirfactor ! dimensionless langmuir turbulence enhancement factor (non dimensional) + real, dimension(isd:ied,jsd:jed) :: ustoke ! x-dir surface stokes drift (m/s) + real, dimension(isd:ied,jsd:jed) :: vstoke ! y-dir surface stokes drift (m/s) + real, dimension(isd:ied,jsd:jed) :: wavlen ! wave length (m) real, dimension(isd:ied,jsd:jed) :: cdbot_array ! dimensionless static bottom drag coefficient real, dimension(isd:ied,jsd:jed) :: current_wave_stress !wave-current bottom stress for sediment dynamics (N/m^2) real, dimension(isd:ied,jsd:jed) :: rossby_radius ! first baroclinic rossby radius (m) real, dimension(isd:ied,jsd:jed) :: stokes_depth ! depth scale (m) used for exponential decay of surface wave Stokes velocity real, dimension(isd:ied,jsd:jed,nk,2) :: stokes_drift ! Stokes drift velocity (m/s) from surface wave model + real, dimension(isd:ied,jsd:jed,nk,2) :: stokes_force ! Coriolis force from Stokes drift (N/m^2) real, dimension(isd:ied,jsd:jed,nk,2) :: press_force ! thickness*density weighted (i,j)-directed press force (N/m^2) real, dimension(isd:ied,jsd:jed,nk,2) :: accel ! thickness*density weighted (i,j)-directed acceleration (N/m^2) real, dimension(isd:ied,jsd:jed,nk,2) :: vfrict_impl ! thickness*density weighted vertical friction (N/m^2) @@ -672,7 +677,7 @@ module ocean_types_mod real, dimension(:,:,:), _ALLOCATABLE :: rho_dzt_tendency _NULL ! rho_dzt tendency (kg/m^3)*(m/s) - real, dimension(:,:), _ALLOCATABLE :: sea_lev _NULL ! eta_t + patm/(rho0*grav) - eta_geoid - eta_tide (m) at time taup1 for coupler + real, dimension(:,:), _ALLOCATABLE :: sea_lev _NULL ! eta_t + patm/(rho0*grav) - eta_geoid - eta_tide (m) at time taup1 for coupler real, dimension(:,:,:), _ALLOCATABLE :: dzt _NULL ! E system contribution to dztT real, dimension(:,:,:,:), _ALLOCATABLE :: dzten _NULL ! E system contribution to dzt at east/north face of T-cell @@ -1079,11 +1084,16 @@ module ocean_types_mod real, _ALLOCATABLE, dimension(:,:,:) :: smf_cgrid _NULL ! momentum flux into ocn surface (N/m^2) at Cgrid u/v points real, _ALLOCATABLE, dimension(:,:,:) :: bmf _NULL ! momentum flux per mass into ocean bottom (N/m^2) real, _ALLOCATABLE, dimension(:,:) :: gamma _NULL ! dimensionful bottom drag coefficient (kg/(m^2 sec)) + real, _ALLOCATABLE, dimension(:,:) :: langmuirfactor _NULL ! Langmuir turbulence enhancement factor + real, _ALLOCATABLE, dimension(:,:) :: ustoke _NULL ! x-dir surface stokes drift + real, _ALLOCATABLE, dimension(:,:) :: vstoke _NULL ! y-dir surface stokes drift + real, _ALLOCATABLE, dimension(:,:) :: wavlen _NULL ! wave length real, _ALLOCATABLE, dimension(:,:) :: cdbot_array _NULL ! dimensionless static bottom drag coefficient real, _ALLOCATABLE, dimension(:,:) :: current_wave_stress _NULL !wave-current bottom stress for sediment dynamics (N/m^2) real, _ALLOCATABLE, dimension(:,:) :: rossby_radius _NULL ! first baroclinic rossby radius (m) real, _ALLOCATABLE, dimension(:,:) :: stokes_depth _NULL ! depth scale (m) for exp decay of surface wave Stokes vel real, _ALLOCATABLE, dimension(:,:,:,:) :: stokes_drift _NULL ! Stokes drift velocity (m/s) from surface wave model + real, _ALLOCATABLE, dimension(:,:,:,:) :: stokes_force _NULL ! Coriolis force from Stokes drift velocity (N/m2) real, _ALLOCATABLE, dimension(:,:,:,:) :: press_force _NULL ! rho*dz*horz (i,j)-directed press force (N/m^2) real, _ALLOCATABLE, dimension(:,:,:,:) :: accel _NULL ! rho*dz*velocity (i,j)-directed acceleration (N/m^2) real, _ALLOCATABLE, dimension(:,:,:,:) :: vfrict_impl _NULL ! rho*dz*vertical friction (N/m^2) @@ -1201,6 +1211,10 @@ module ocean_types_mod real, pointer, dimension(:,:) :: calving_hflx =>NULL() ! heat flux, relative to 0C, of frozen land water into ocean (W/m2) real, pointer, dimension(:,:) :: p =>NULL() ! pressure of overlying sea ice and atmosphere (Pa) real, pointer, dimension(:,:) :: mi =>NULL() ! mass of overlying sea ice + real, pointer, dimension(:,:) :: langmuirfactor =>NULL() ! langmuir turbulence boost factor (non-dimensional) + real, pointer, dimension(:,:) :: ustoke =>NULL() ! x-dir surface stokes drift + real, pointer, dimension(:,:) :: vstoke =>NULL() ! y-dir surface stokes drift + real, pointer, dimension(:,:) :: wavlen =>NULL() ! wave length integer :: xtype ! REGRID, REDIST or DIRECT @@ -1217,7 +1231,7 @@ module ocean_types_mod real, pointer, dimension(:,:) :: s_surf =>NULL() ! SSS on t-cell (psu) real, pointer, dimension(:,:) :: u_surf =>NULL() ! i-directed surface ocean velocity on u-cell (m/s) real, pointer, dimension(:,:) :: v_surf =>NULL() ! j-directed surface ocean velocity on u-cell (m/s) - real, pointer, dimension(:,:) :: sea_lev =>NULL() ! eta_t + patm/(rho0*grav) - eta_geoid - eta_tide (m) + real, pointer, dimension(:,:) :: sea_lev =>NULL() ! eta_t + patm/(rho0*grav) - eta_geoid - eta_tide (m) real, pointer, dimension(:,:) :: frazil =>NULL() ! accumulated heating (J/m^2) from ! frazil formation in the ocean real, pointer, dimension(:,:) :: area =>NULL() ! T-cell area. diff --git a/src/mom5/ocean_core/ocean_types.html b/src/mom5/ocean_core/ocean_types.html deleted file mode 100644 index fba3cceb28..0000000000 --- a/src/mom5/ocean_core/ocean_types.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -Module ocean_types_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_types_mod
- - - - - -
-OVERVIEW
- -- This module contains type declarations and default values for ocean model. -
- - - -- This module contains type declarations and default values for ocean model. - Multiple model realizations need to be distinguished by - an ensemble_id for use by the diag_manager. --
- - -
-OTHER MODULES USED
- --- - - -coupler_types_mod-
field_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
time_manager_mod
-PUBLIC INTERFACE
----
-- -ocean_types_init:
- -
- - -
-PUBLIC ROUTINES
- - - - - - - - -
--top -- - diff --git a/src/mom5/ocean_core/ocean_util.html b/src/mom5/ocean_core/ocean_util.html deleted file mode 100644 index 4b5e4154a7..0000000000 --- a/src/mom5/ocean_core/ocean_util.html +++ /dev/null @@ -1,519 +0,0 @@ - - - -Module ocean_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_util_mod
- - --Contact: Matt Harrison -, - Tim Leslie - -- - -
-Reviewers: S.M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module contains many routines of use for MOM. -
- - - -- A utility module for MOM. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_util_init:
- -- -invtri:
- -- -invtri_bmf:
- -- -iplot:
- -- -matrix:
- -- -write_timestamp:
- -- -write_chksum_header:
- -- -write_note:
- -- -write_warning:
- -- -write_line:
- -- -write_chksum_3d:
- -- -write_chksum_2d:
- -- -write_chksum_2d_int:
- -- -check_restart:
- -- -write_summary:
- -- -diagnose_3d:
- -- -diagnose_2d:
- -- -diagnose_2d_int:
- -- -diagnose_3d_int:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_util_init
--
-- -DESCRIPTION -
-- - Initialize MOM utilities. -
-
-
-- - -
-invtri
--
-- -DESCRIPTION -
-- - Solve the vertical diffusion equation implicitly using the - method of inverting a tridiagonal matrix as described in - Numerical Recipes in Fortran, The art of Scientific Computing, - Second Edition, Press, Teukolsky, Vetterling, Flannery, 1992 - pages 42,43. - - This routine assumes that the variables are defined at grid points, - and the top and bottom b.c. are flux conditions. - - inputs: - - z = right hand side terms - - nk = number of vertical levels - - topbc = top boundary condition - - botbc = bottom boundary condition - - dcb = vertical mixing coeff at base of cell - - tdt = timestep over which do implicit update - - kmz = level indicator - - mask = land/sea mask - - outputs: - - z = returned solution - -
-
-
-- - -
-invtri_bmf
--
-- -DESCRIPTION -
-- - Solve the vertical friction equation implicitly using the - method of inverting a tridiagonal matrix as described in - Numerical Recipes in Fortran, The art of Scientific Computing, - Second Edition, Press, Teukolsky, Vetterling, Flannery, 1992 - pages 42,43. - - This routine assumes that the variables are defined at grid points, - and the top b.c. is a flux condition. The bottom b.c. is assumed - to be a bottom drag which is implemented implicitly, thus allowing - for large values of the bottom drag coefficient. - - NOTE: This routine is generally only called when doing the bmf - implicitly in time. The original invtri is used for explicit - bmf. - - inputs: - - z = right hand side terms - - nk = number of vertical levels - - topbc = top boundary condition - - botbc = time explicit bottom boundary condition (zero in this routine, since bmf is implicit) - - gamma = botttom drag factor scaling the u(taup1) contribution to bottom drag - - dcb = vertical mixing coeff at base of cell - - tdt = timestep over which do implicit update - - kmz = level indicator - - mask = land/sea mask - - outputs: - - z = returned solution - -
-
-
-- - -
-iplot
--
-- -DESCRIPTION -
-- - - map integer array "iarray" into characters for printing with - format (a1) to provide a contour map of the integer field. - note: max number of unique characters = 80 - - inputs: - - iarray = integer array to be plotted - - is = starting index along inner dimension of "iarray" - - ie = ending index along inner dimension of "iarray" - - js = starting index along outer dimension of "iarray" - - je = ending index along outer dimension of "iarray" - - output: prints contour map of "iarray" - -
-
-
-- - -
-matrix
--
-- -DESCRIPTION -
-- - matrix is a general two-dimensional array printing routine, - input: - - array = the array to be printed - - istrt = the 1st element of the 1st dimension to be printed - - im = the last element of the 1st dimension to be printed - - jstrt = the 1st element of the 2nd dimension to be printed - - jm = the last element of the 2nd dimension to be printed - the 2nd dimension is printed in reverse order if both - jstrt and jm are negative - - scale = a scaling factor by which array is divided before - printing. (if this is zero, no scaling is done.) - if scale=0, 10 columns are printed across in e format - if scale>0, 20 columns are printed across in f format - - output: print "array" as a matrix - -
-
-
-- - -
-write_timestamp
--
-- -DESCRIPTION -
-- - Write the time stamp. -
-
-
-- - -
-write_chksum_header
--
-- -DESCRIPTION -
-- - Write the checksum header. -
-
-
-- - -
-write_note
--
-- -DESCRIPTION -
-- - Write a note. -
-
-
-- - -
-write_warning
--
-- -DESCRIPTION -
-- - Write a warning. -
-
-
-- - -
-write_line
--
-- -DESCRIPTION -
-- - Write a message. -
-
-
-- - -
-write_chksum_3d
--
-- -DESCRIPTION -
-- - Write a 3d checksum. -
-
-
-- - -
-write_chksum_2d
--
-- -DESCRIPTION -
-- - Write a 2d checksum. -
-
-
-- - -
-write_chksum_2d_int
--
-- -DESCRIPTION -
-- - Write a 2d integer checksum. -
-
-
-- - -
-check_restart
--
-- -DESCRIPTION -
-- - Write a note regarding the restart setup. -
-
-
-- - -
-write_summary
--
-- -DESCRIPTION -
-- - Write a summary note. -
-
-
-- - -
-diagnose_3d
--
-- -DESCRIPTION -
-- - Helper function for diagnosting 3D data using the grid tmask. -
-
-
-- - -
-diagnose_2d
--
-- -DESCRIPTION -
-- - Helper function for diagnosting 2D data using the grid tmask. -
-
-
-- - -
-diagnose_2d_int
--
-- -DESCRIPTION -
-- - Helper function for diagnosting 2D data using the grid tmask. -
-
-
-- - -
-diagnose_3d_int
--
-- -DESCRIPTION -
-- - Helper function for diagnosting 3D data using the grid tmask. -
-
-
-
--top -- - diff --git a/src/mom5/ocean_core/ocean_velocity.F90 b/src/mom5/ocean_core/ocean_velocity.F90 index d1779bd1b1..24f2cea209 100644 --- a/src/mom5/ocean_core/ocean_velocity.F90 +++ b/src/mom5/ocean_core/ocean_velocity.F90 @@ -1,14 +1,14 @@ module ocean_velocity_mod #define COMP isc:iec,jsc:jec ! -!+! ! S.M. Griffies ! ! -!A. Rosati +! A. Rosati ! ! -!+! ! M.J. Harrison ! ! @@ -229,9 +229,9 @@ module ocean_velocity_mod integer :: unit=6 character(len=128) :: & - version='$Id: ocean_velocity.F90,v 1.1.2.16 2012/06/04 00:11:43 Stephen.Griffies Exp $' + version='$Id: ocean_velocity.F90,v 20.0 2013/12/14 00:12:41 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: have_obc = .false. @@ -394,6 +394,10 @@ subroutine ocean_velocity_init (Grid, Domain, Time, Time_steps, Ocean_options, & allocate (Velocity%smf_cgrid(isd:ied,jsd:jed,2)) allocate (Velocity%bmf(isd:ied,jsd:jed,2)) allocate (Velocity%gamma(isd:ied,jsd:jed)) + allocate (Velocity%langmuirfactor(isd:ied,jsd:jed)) + allocate (Velocity%ustoke(isd:ied,jsd:jed)) + allocate (Velocity%vstoke(isd:ied,jsd:jed)) + allocate (Velocity%wavlen(isd:ied,jsd:jed)) allocate (Velocity%cdbot_array(isd:ied,jsd:jed)) allocate (Velocity%rossby_radius(isd:ied,jsd:jed)) allocate (Velocity%stokes_depth(isd:ied,jsd:jed)) @@ -415,6 +419,10 @@ subroutine ocean_velocity_init (Grid, Domain, Time, Time_steps, Ocean_options, & Velocity%smf_cgrid = 0.0 Velocity%bmf = 0.0 Velocity%gamma = 0.0 + Velocity%langmuirfactor = 1.0 + Velocity%ustoke = 0.0 + Velocity%vstoke = 0.0 + Velocity%wavlen = 1.0 Velocity%cdbot_array = 0.0 Velocity%rossby_radius = 1.e5 Velocity%stokes_depth = 0.0 @@ -1825,7 +1833,7 @@ end subroutine ocean_velocity_chksum ! ! Use rho_dzu weighting to account for nonBoussinesq. ! -! Author: Stephen.Griffies@noaa.gov +! Author: Stephen.Griffies ! ! ! diff --git a/src/mom5/ocean_core/ocean_velocity.html b/src/mom5/ocean_core/ocean_velocity.html deleted file mode 100644 index c9367f38fe..0000000000 --- a/src/mom5/ocean_core/ocean_velocity.html +++ /dev/null @@ -1,629 +0,0 @@ - - - -Module ocean_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_velocity_mod
- - --Contact: - S.M. Griffies - , - A. Rosati - -- - -
-Reviewers: - M.J. Harrison - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Time step the velocity field. -
- - - -- This module steps the velocity field forward in time. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
time_interp_external_mod
ocean_bih_friction_mod
ocean_coriolis_mod
ocean_domains_mod
ocean_form_drag_mod
ocean_lap_friction_mod
ocean_momentum_source_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_pressure_mod
ocean_types_mod
ocean_util_mod
ocean_velocity_advect_mod
ocean_velocity_diag_mod
ocean_vert_mix_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_velocity_init:
- -- -check_gravity_wave_cfl:
- -- -ocean_explicit_accel_a:
- -- -ocean_explicit_accel_b:
- -- -ocean_implicit_accel:
- -- -update_ocean_velocity_bgrid:
- -- -update_ocean_velocity_cgrid:
- -- -ocean_velocity_restart:
- -- -ocean_velocity_end:
- -- -velocity_truncate:
- -- -ocean_velocity_chksum:
- -- -remap_s_to_depth:
- -- -stokes_coriolis_force:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_velocity_init
--
-- -DESCRIPTION -
-- - Initialize terms for the velocity equation. -
-
-
-- - -
-check_gravity_wave_cfl
--
-- -DESCRIPTION -
-- - Check CFL for internal gravity waves. -
-
-
-- - -
-ocean_explicit_accel_a
--
-- -DESCRIPTION -
-- - - Time explicit contributions to thickness weighted and density - weighted acceleration. - - Omit here the Coriolis force and vertical friction. - They are omitted in order to facilitate the construction of the - vertically integrated forcing of the barotropic dynamics. - They will be added later in ocean_explicit_accel_b. - -
-
-
-- - -
-ocean_explicit_accel_b
--
-- -DESCRIPTION -
-- - - Add the contributions from the Coriolis force, computed explicitly - in time, and those from explicit vertical friction. Add these to - the thickness weighted and density weighted acceleration. - - Note: no visc_cbu_form_drag is included here, since it must - be handled via implicit vertical friction to maintain stability - for general cases. - -
-
-
-- - -
-ocean_implicit_accel
--
-- -DESCRIPTION -
-- - - Add the time implicit contributions from the Coriolis force - and vertical friction. Add these to the thickness weighted - and density weighted acceleration. - - Note the contribution from visc_cbu_form_drag is used for - implicit vertical friction. - - Note there is no time implicit Coriolis for Cgrid. - -
-
-
-- - -
-update_ocean_velocity_bgrid
--
-- -DESCRIPTION -
-- - Update velocity components. - There are two general methods available. - - 1/ update baroclinic velocity; then add (udrho,vdrho) from external - mode algorithm to get the full velocity field. This method is - analogous to the older approach with the rigid lid. - - 2/ update the full velocity, so there is no need to introduce the - intermediate step with the baroclinic velocity. To remain stable, - we must use the time filtered barotropic pressure gradient. - We then diagnose the vertically integrated horizontal momentum - (udrho,vdrho) and its convergence, since these fields are needed - elsewhere. - -
-
-
-- - -
-update_ocean_velocity_cgrid
--
-- -DESCRIPTION -
-- - Update velocity components, assuming Cgrid layout. - - Also assume splitting, so update baroclinic velocity; - then add (udrho,vdrho) from external mode algorithm to get the - full velocity field. This method is - analogous to the older approach with the rigid lid. - - As we have already called update_ucell_thickness, the array - rho_dzten has been udpated to taup1. We use Adv_vel to obtain - the tau value of (u,v)*rho_dzten, since Adv_vel has been computed - at the start of the time stepping using (u,v)(tau). - -
-
-
-- - -
-ocean_velocity_restart
--
-- -DESCRIPTION -
-- - - Write out restart files registered through register_restart_file - -
-
-
-- - -
-ocean_velocity_end
--
-- -DESCRIPTION -
-- - - Write velocity field to a restart - -
-
-
-- - -
-velocity_truncate
--
-- -DESCRIPTION -
-- - Truncate velocity so that either component - has magnitude no larger than nml specified value. - -
-
-
-- - -
-ocean_velocity_chksum
--
-- -DESCRIPTION -
-- - Compute checksum for velocity components -
-
-
-- - -
-remap_s_to_depth
--
-- -DESCRIPTION -
-- - - Remap in the vertical from s-coordinate to depth and then send to - diagnostic manager. - - This routine is mostly of use for terrain following vertical - coordinates, which generally deviate a lot from depth or pressure - coordinates. The zstar and pstar coordinates are very similar - to z or pressure, so there is no need to do the remapping for - purposes of visualization. - - The routine needs to be made more general and faster. - It also has been found to be problematic, so it is NOT - recommended. It remains here as a template for a better algorithm. - Remapping methods in Ferret are much better. - - Use rho_dzu weighting to account for nonBoussinesq. - - Author: Stephen.Griffies - -
-
-
-- - -
-stokes_coriolis_force
--
-- -DESCRIPTION -
-- - - Time explicit contributions to thickness weighted and density - weighted acceleration from the Stokes coriolis force, where the - Stokes drift arises from surface ocean waves. To obtain the - Stokes drift requires coupling MOM to a surface wave model. - - Assume stokes_drift is on U-grid point (smg: to be revisited). - -
-
-
-
-NAMELIST
- --&ocean_velocity_nml --
-
----
-- -debug_this_module -
-- For debugging. -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -update_velocity_via_uprime -
-- When updating the velocity, this method first computes uprime - as the updated velocity minus the barotropic pressure gradient. - This approach is motivated from the rigid lid approach, in which - the surface pressure was never used to update the barotropic - fields. - With the explicit free surface, we have the choice to - update the full velocity field, with the barotropic contributions - to the pressure field resulting from a time average in the - external mode algorithm. This approach is for testing only, - and it has been found to be unstable for many cases. - - update_velocity_via_uprime=.true. uses the older aproach, - in which the udrho,vdrho fields are taken from the external - mode module. - - update_velocity_via_uprime=.false. only takes the time averaged - pressure from the external mode, and thus updates the full - velocity and so recomputes the udrho,vdrho fields. - - Default update_velocity_via_uprime=.true. - The case of update_velocity_via_uprime=.false. is for testing only. - It is not supported for general use. -
-
-[logical] -- -use_constant_velocity -
-- For running with time independent constant velocity. - For use with idealized cases. Default=.false. -
-
-[logical] -- -constant_u -
-- For running with use_constant_velocity. - Set the i-velocity component to this value. - Default constant_u=0.0 -
-
-[real, units: meter/sec] -- -constant_v -
-- For running with use_constant_velocity. - Set the j-velocity component to this value. - Default constant_v=0.0 -
-
-[real, units: meter/sec] -- -zero_tendency -
-- For debugging. Will freeze the baroclinic velocity fields. -
-
-[logical] -- -zero_tendency_explicit_a -
-- For debugging. Will not use explicit-a part of the tendency. -
-
-[logical] -- -zero_tendency_explicit_b -
-- For debugging. Will not use explicit-b part of the tendency. -
-
-[logical] -- -zero_tendency_implicit -
-- For debugging. Will not use implicit part of the tendency. -
-
-[logical] -- -truncate_velocity -
-- Truncate the baroclinic velocity to a maximum value. Useful for cases where - the initial spin-up initiates spuriously large model velocities that would - otherwise cause the model to blow-up. Also can be used as a very simple - "polar filter" in cases where have spherical coordinates and wish to avoid - using the traditional polar filters. -
-
-[logical] -- -truncate_velocity_value -
-- Speed above which will truncate the baroclinic velocity -
-
-[real, units: meter/sec] -- -truncate_velocity_lat -
-- Latitude poleward of which we truncate the velocity. Useful in cases - when wish to truncate the velocity only in polar regions. Default is 0.0 -
-
-[real, units: dimensionless] -- -truncate_verbose -
-- For verbose printout -
-
-[logical] -- -max_cgint -
-- Maximum internal gravity wave speed--used for diagnosing conservative - estimate of stable time steps. -
-
-[real] -- -adams_bashforth_epsilon -
-- Dimensionless parameter for 2nd order Adams-Bashforth implementation of - velocity advection. Values between 0.5 and 1.0 are recommended. - Value of 0.5 leads to second order accurate, but it is formally - weakly unstable (Durran, Section 2.3.4). -
-
-[real, units: dimensionless] -- -adams_bashforth_third -
-- For a third order treatment of the velocity advection. - This is stable and so needs no temporal dissipation - (Section 2.3.6 of Durran). This is the model default. -
-
-[logical] -- -use_stokes_coriolis_force -
-- For including the contribution to the Coriolis force from surface wave - induced Stokes drift. This force requires the coupling to a prognostic - surface wave model. Default use_stokes_coriolis_force=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Durran, Numerical Methods for Wave Equations in Geophysical - Fluid Dynamics (1999). -
-- - R.C. Pacanowski and S.M. Griffies, The MOM3 Manual (1999). - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - S.M. Griffies, R.C. Pacanowski, R.M. Schmidt, and V. Balaji - Tracer Conservation with an Explicit Free Surface Method for - Z-coordinate Ocean Models - Monthly Weather Review (2001) vol 129 pages 1081--1098 -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and - A. Rosati, A Technical Guide to MOM4 (2004). - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - S.M. Griffies, Fundamentals of Ocean Climate Models (2004). - Princeton University Press. -
-- - S.M. Griffies (2012), Elements of MOM -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_velocity_advect.F90 b/src/mom5/ocean_core/ocean_velocity_advect.F90 index 94266be3c6..44d8e76071 100644 --- a/src/mom5/ocean_core/ocean_velocity_advect.F90 +++ b/src/mom5/ocean_core/ocean_velocity_advect.F90 @@ -127,9 +127,9 @@ module ocean_velocity_advect_mod type(ocean_domain_type), pointer :: Dom =>NULL() character(len=128) :: version=& - '$Id: ocean_velocity_advect.F90,v 1.1.2.5 2012/06/08 00:44:45 Stephen.Griffies Exp $' + '$Id: ocean_velocity_advect.F90,v 20.0 2013/12/14 00:12:43 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: advection_scheme = 2 logical :: module_is_initialized = .false. diff --git a/src/mom5/ocean_core/ocean_velocity_advect.html b/src/mom5/ocean_core/ocean_velocity_advect.html deleted file mode 100644 index 3615f2bbd1..0000000000 --- a/src/mom5/ocean_core/ocean_velocity_advect.html +++ /dev/null @@ -1,339 +0,0 @@ - - - -Module ocean_velocity_advect_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_velocity_advect_mod
- - - - - -
-OVERVIEW
- -- Velocity advective transport. -
- - - -- This module computes advection of velocity using one of the - following advection schemes: - 1/ second order centered - 2/ first order upwind --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_velocity_advect_init:
- -- -horz_advection_of_velocity:
- -- -horz_advection_centered:
- -- -horz_advection_upwind:
- -- -vert_advection_of_velocity:
- -- -vert_advection_centered:
- -- -vert_advection_upwind:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_velocity_advect_init
--
-- -DESCRIPTION -
-- - Initialize the velocity advection module. -
-
-
-- - -
-horz_advection_of_velocity
--
-- -DESCRIPTION -
-- - - Compute thickness weighted and density weighted acceleration - (kg/m^3)*(m^2/s^2) due to horizontal (constant k-level) - advection of velocity. - -
-
-
-- - -
-horz_advection_centered
--
-- -DESCRIPTION -
-- - - Compute thickness weighted and density weighted acceleration - (kg/m^3)*(m^2/s^2) due to horizontal (constant k-level) - advection of velocity. - - Use second order centered method for either Bgrid or Cgrid. - -
-
-
-- - -
-horz_advection_upwind
--
-- -DESCRIPTION -
-- - - Compute thickness weighted and density weighted acceleration - (kg/m^3)*(m^2/s^2) due to horizontal (constant k-level) - advection of velocity. - - Use first order upwind method. Not coded for Cgrid, since - first order upwind method is rarely used. - -
-
-
-- - -
-vert_advection_of_velocity
--
-- -DESCRIPTION -
-- - - Compute thickness weighted and density weighted acceleration - (kg/m^3)*(m^2/s^2) due to vertical advection of velocity. - - Include vertical advection due to fresh water entering surface cells. - -
-
-
-- - -
-vert_advection_centered
--
-- -DESCRIPTION -
-- - - Compute thickness weighted and density weighted acceleration - (kg/m^3)*(m^2/s^2) due to vertical advection of velocity. - - Include vertical advection due to fresh water entering surface cells. - Assume upme and uriver are the most fundamental fields, passed through - the FMS coupler on the Bgrid velocity point. So use these to average - onto the C-grid velocity points. Likewise, pme and river are fundamental, - and sit on the T-grid. - - Use second order centered method here. - -
-
-
-- - -
-vert_advection_upwind
--
-- -DESCRIPTION -
-- - - Compute thickness weighted and density weighted acceleration - (kg/m^3)*(m^2/s^2) due to vertical advection of velocity. - - Include vertical advection due to fresh water entering surface cells. - - Use first order upwind method here. Not coded for Cgrid, since - first order upwind method is rarely used. - -
-
-
-
-NAMELIST
- --&ocean_velocity_advect_nml --
-
----
-- -debug_this_module -
-- For debugging -
-
-[logical] -- -zero_velocity_advect_horz -
-- For debugging, it is often useful to remove horizontal advection of velocity. -
-
-[logical] -- -zero_velocity_advect_vert -
-- For debugging, it is often useful to remove vertical advection of velocity. -
-
-[logical] -- -velocity_advect_centered -
-- For using the standard second order centered method for - computing the advection of linear momentum. This is the - default: velocity_advect_centered=.true. -
-
-[logical] -- -velocity_advect_upwind -
-- For using the first order upwind method for - computing the advection of linear momentum. - Default: velocity_advect_upwind=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) -
-- - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
-- - S.M. Griffies: Elements of MOM (2012) -
-- - Hundsdorder and Trompert (1994), "Method of lines and - direct discretization: a comparison for linear - advection", Applied Numerical Mathematics, - pages 469--490. -
-
- -
--top -- - diff --git a/src/mom5/ocean_core/ocean_workspace.html b/src/mom5/ocean_core/ocean_workspace.html deleted file mode 100644 index 47cfec2e16..0000000000 --- a/src/mom5/ocean_core/ocean_workspace.html +++ /dev/null @@ -1,123 +0,0 @@ - - - -Module ocean_workspace_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_workspace_mod
- - - - - -
-OVERVIEW
- -- This module allocates some workspace for use in MOM. -
- - - -- This module allocates some workspace for use in MOM. --
- - -
-OTHER MODULES USED
- --- - - -ocean_types_mod-
-PUBLIC INTERFACE
----
-- -ocean_workspace_init:
- -- -ocean_workspace_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_workspace_init
--
-- -DESCRIPTION -
-- - Initialize MOM workspace module. -
-
-
-- - -
-ocean_workspace_end
--
-- -DESCRIPTION -
-- - End MOM workspace. -
-
-
-
--top -- - diff --git a/src/mom5/ocean_core/oda_driver.html b/src/mom5/ocean_core/oda_driver.html deleted file mode 100644 index 63cf70adfb..0000000000 --- a/src/mom5/ocean_core/oda_driver.html +++ /dev/null @@ -1,332 +0,0 @@ - - - -Module oda_driver_mod - - - - -PUBLIC INTERFACE - ~ PUBLIC DATA - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module oda_driver_mod
- - - - - -
-OVERVIEW
- -- Top-level interface between MOM and ocean data assimilation modules -
- - - -- Top level module for ocean data assimilation. Contains routines for - initialization, termination and update of ocean data assimilation increments. - - 1.) Get Observations for current model time (and domain) - based on data window (default=15 days). For PE subdomains, - data are included if they lie within the region bounded by the - cell centers on the first x/y halo extent. - - 2.) - IF EAKF (!!not yet implemented!!) - a.) ensemble state is distributed among NPES as follows: - Ens01:0:(NPE1-1), Ens02:NPE1:(NPE1+NPE2-1),..., - EnsN:sum(NPE1+...+NPE(N-1)):NPES - b.) Redistribute state to ensemble vector using global PEset. - (Ens01,...,EnsN):0:NPES - c.) Calculate increments using Ensemble information. - d.) Re-distribute increments to members and revert to - original PEset. - ELSE IF Var2d - Minimize quadratic CF based on specfied prior correlation maps - and optionally time-variant prior error variance. - ELSE ??? - - ENDIF - - 3.) Apply increments to model state based on prior analysis. - Distribute increments uniformly over analysis period if "do_iau=T". - - 4.) Check for convective instability after applying increments. - - 5.) Write Profile (observation space) first guess, analysis and mis-fits - -======================================================================== --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
ensemble_manager_mod
mpp_domains_mod
mpp_mod
mpp_io_mod
oda_types_mod
oda_core_mod
time_manager_mod
write_ocean_data_mod
ocean_convect_mod
ocean_domains_mod
ocean_grids_mod
ocean_parameters_mod
ocean_topog_mod
ocean_types_mod
ocean_workspace_mod
fms_mod
diag_manager_mod
-PUBLIC INTERFACE
- -
- - -
-PUBLIC DATA
- --- - --
-- -Name Type Value Units Description -- -use_this_module logical --- --- - use the oda module - -
-
-PUBLIC ROUTINES
- --
- - - - -- - -
-init_oda
--
-- -DESCRIPTION -
-- - Initialize ODA core. Grid and Domain association. -
-
-
-- -INPUT -
-- -
--
-- -Domain - -
[ocean_domain_type]- -Grid - -
[ocean_grid_type]- -Ocn_Time - -
[ocean_time_type]- -T_prog - -
[ocean_tracer_type(:)]- -Velocity - -
[ocean_velocity_type]- -Ext_mode - -
[ocean_external_mode_type]
-- - -
-oda
--
-- -DESCRIPTION -
-- - Request ocean state increments -
-
-
-- -INPUT -
-- -
--
-- -Ocn_Time - -
[ocean_type_type]
-- -INPUT/OUTPUT -
-- -
--
-- -T_prog - -
[ocean_prog_tracer_type(:)]- -Velocity - -
[ocean_velocity_type]- -Ext_mode - -
[ocean_external_mode_type]- -Thickness - -
[ocean_thickness_type]- -Dens - -
[ocean_density_type]
-
-NAMELIST
- --&oda_nml --
-
----
-- -assim_method -
-- Options are: Var2d, EAKF and NO_ASSIM -
-
-[character] -- -assim_start_lat -
-- Southern data mask boundary -
-
-[real] -- -assim_end_lat -
-- Northern data mask boundary -
-
-[real] -- -nk_asm -
-- Bottom model level for data mask -
-
-[integer] -- -assim_interval -
-- Time between calls to oda (hours) -
-
-[integer] -- -do_iau -
-- Incremental analysis update (evenly distribute increments between - calls to ODA.) -
-
-[logical] -- -do_convect_adjust -
-- Adjust for gravitational instability in model after applying increments. -
-
-[logical] -- -max_profiles -
-- Size of allocation for profile data -
-
-[integer] -- -max_sfc_obs -
-- Size of allocation for surface observations -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_diag/ocean_adv_vel_diag.F90 b/src/mom5/ocean_diag/ocean_adv_vel_diag.F90 index 2bfd45854e..5893b17739 100644 --- a/src/mom5/ocean_diag/ocean_adv_vel_diag.F90 +++ b/src/mom5/ocean_diag/ocean_adv_vel_diag.F90 @@ -1,6 +1,6 @@ module ocean_adv_vel_diag_mod ! -!S.M. Griffies +! S.M. Griffies ! ! !@@ -123,9 +123,9 @@ module ocean_adv_vel_diag_mod logical :: module_is_initialized = .FALSE. character(len=128) :: version=& - '$Id: ocean_adv_vel_diag.F90,v 1.1.2.4 2012/06/03 00:41:57 Stephen.Griffies Exp $' + '$Id: ocean_adv_vel_diag.F90,v 20.0 2013/12/14 00:12:49 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public ocean_adv_vel_diag_init public ocean_adv_vel_diagnostics @@ -968,18 +968,18 @@ end subroutine transport_on_s ! ! code history: ! -! 2002: Stephen.Griffies@noaa.gov -! Zhi.Liang@noaa.gov -! Alexander.Pletzer@noaa.gov +! 2002: Stephen.Griffies +! Zhi.Liang +! Alexander.Pletzer ! ! 2007: updated algorithm with weighting as done in the paper ! Lee, Nurser, Coward, and de Cuevas, 2007: ! "Eddy advective and diffusive transports of heat and salt ! in the Southern Ocean" JPO, vol 37, pages 1376-1393 ! -! 2010: updated by Rusty.Benson@noaa.gov for optimization. +! 2010: updated by Rusty.Benson for optimization. ! -! 2010: Corrected weighting by Stephen.Griffies@noaa.gov +! 2010: Corrected weighting by Stephen.Griffies ! ! 2010: Removed the weighting in favor of a strait rebinning ! approach. The weighting approach was @@ -1078,17 +1078,17 @@ end subroutine transport_on_nrho ! ! Code history ! -! 2002: Stephen.Griffies@noaa.gov -! Zhi.Liang@noaa.gov -! Alexander.Pletzer@noaa.gov +! 2002: Stephen.Griffies +! Zhi.Liang +! Alexander.Pletzer ! ! 2007: updated algorithm with weighting as done in the paper ! Lee, Nurser, Coward, and de Cuevas, 2007: ! "Eddy advective and diffusive transports of heat and salt ! in the Southern Ocean" JPO, vol 37, pages 1376-1393 ! -! 2010: updated by Rusty.Benson@noaa.gov for optimization. -! corrected weigthing by Stephen.Griffies@noaa.gov +! 2010: updated by Rusty.Benson for optimization. +! corrected weigthing by Stephen.Griffies ! ! 2010: Removed the weighting in favor of a strait rebinning ! approach. The weighting approach was @@ -1188,17 +1188,17 @@ end subroutine transport_on_rho ! ! Code history ! -! 2002: Stephen.Griffies@noaa.gov -! Zhi.Liang@noaa.gov -! Alexander.Pletzer@noaa.gov +! 2002: Stephen.Griffies +! Zhi.Liang +! Alexander.Pletzer ! ! 2007: updated algorithm with weighting as done in the paper ! Lee, Nurser, Coward, and de Cuevas, 2007: ! "Eddy advective and diffusive transports of heat and salt ! in the Southern Ocean" JPO, vol 37, pages 1376-1393 ! -! 2010: updated by Rusty.Benson@noaa.gov for optimization. -! corrected weigthing by Stephen.Griffies@noaa.gov +! 2010: updated by Rusty.Benson for optimization. +! corrected weigthing by Stephen.Griffies ! ! 2010: Removed the weighting in favor of a strait rebinning ! approach. The weighting approach was diff --git a/src/mom5/ocean_diag/ocean_adv_vel_diag.html b/src/mom5/ocean_diag/ocean_adv_vel_diag.html deleted file mode 100644 index ed34898177..0000000000 --- a/src/mom5/ocean_diag/ocean_adv_vel_diag.html +++ /dev/null @@ -1,441 +0,0 @@ - - - - Module ocean_adv_vel_diag_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_adv_vel_diag_mod
- - - - - -
-OVERVIEW
- -- Numerical diagnostics for advection velocity related quantities. -
- - - -- Numerical diagnostics for advection velocity related quantities. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
time_manager_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_adv_vel_diag_init:
- -- -ocean_adv_vel_diagnostics:
- -- -remapping_check:
- -- -cfl_check1:
- -- -cfl_check2:
- -- -maximum_bottom_w:
- -- -max_continuity_error:
- -- -transport_on_s:
- -- -transport_on_nrho:
- -- -transport_on_rho:
- -- -transport_on_theta:
- -- -vertical_reynolds_check:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_adv_vel_diag_init
--
-- -DESCRIPTION -
-- - Initialize the ocean_adv_vel_diag module containing subroutines - diagnosing advection velocity related properties of the simulation. -
-
-
-- - -
-ocean_adv_vel_diagnostics
--
-- -DESCRIPTION -
-- - Call diagnostics related to the velocity. -
-
-
-- - -
-remapping_check
--
-- -DESCRIPTION -
-- - Compute remapping error. This error will be roundoff only for model - grids where the tracer and velocity grid cell distances are - linearly related. The spherical version of MOM satisfies the - appropriate relation, and so should maintain roundoff for the - remapping error. The tripolar version of MOM does not have - tracer and velocity grids related linearly, and so the - "remapping error" is nontrivial. The significance of this error - is unclear. No adverse effects have been identified. -
-
-
-- - -
-cfl_check1
--
-- -DESCRIPTION -
-- - Perform the first of two CFL checks for vertical velocity component. - - Vectorized version from Russell.Fiedler@csiro.au computes cfl - values at a single latitude. The location of the maximum at this - latitude is calculated via the maxloc() intrinsic. The maximum - value for this processor is then updated if necessary. - -
-
-
-- - -
-cfl_check2
--
-- -DESCRIPTION -
-- - Perform the second of two vertical CFL checks. - - Bring the model down if too many large Courant numbers detected. -
-
-
-- - -
-maximum_bottom_w
--
-- -DESCRIPTION -
-- - Compute maximum vertical velocity on the bottom of tracer and velocity cells. - The vertical velocity at bottom of a column of tracer cells should be roundoff. - For flat bottom simulations, the vertical velocity on the bottom of the - velocity cell column should also be roundoff. For simulations with topography, - the vertical velocity on the bottom of a velocity cell column will not vanish - due to the effects of topography. -
-
-
-- - -
-max_continuity_error
--
-- -DESCRIPTION -
-- - Compute continuity error. Should be roundoff if all is working well. -
-
-
-- - -
-transport_on_s
--
-- -DESCRIPTION -
-- - Compute transports on s-levels (defined by same k-level) - and send to diag_manager. -
-
-
-- - -
-transport_on_nrho
--
-- -DESCRIPTION -
-- - Classify horizontal transport according to neutral density classes. - - NOTE: This diagnostic works with transport through cell faces. - To get transport_on_nrho, a binning must be done, rather than - a remapping (as done for trans_rho_gm). - - code history: - - 2002: Stephen.Griffies - Zhi.Liang - Alexander.Pletzer - - 2007: updated algorithm with weighting as done in the paper - Lee, Nurser, Coward, and de Cuevas, 2007: - "Eddy advective and diffusive transports of heat and salt - in the Southern Ocean" JPO, vol 37, pages 1376-1393 - - 2010: updated by Rusty.Benson for optimization. - - 2010: Corrected weighting by Stephen.Griffies - - 2010: Removed the weighting in favor of a strait rebinning - approach. The weighting approach was - unnecessary, and added more cost to the scheme. - -
-
-
-- - -
-transport_on_rho
--
-- -DESCRIPTION -
-- - Classify horizontal transport according to potential density classes. - - Diagnostic makes sense when potrho is monotonically increasing with - depth, although the algorithm does not explicitly make this assumption. - - NOTE: This diagnostic works with transport through cell faces. - To get transport_on_rho, a binning must be done, rather than - a remapping (as done for trans_rho_gm). - - Code history - - 2002: Stephen.Griffies - Zhi.Liang - Alexander.Pletzer - - 2007: updated algorithm with weighting as done in the paper - Lee, Nurser, Coward, and de Cuevas, 2007: - "Eddy advective and diffusive transports of heat and salt - in the Southern Ocean" JPO, vol 37, pages 1376-1393 - - 2010: updated by Rusty.Benson for optimization. - corrected weigthing by Stephen.Griffies - - 2010: Removed the weighting in favor of a strait rebinning - approach. The weighting approach was - unnecessary, and added more cost to the scheme. - -
-
-
-- - -
-transport_on_theta
--
-- -DESCRIPTION -
-- - Classify horizontal transport of mass according to potential - temperature classes. This diagnostic is useful to deduce the - heat that is transported between potential temperature classes. - - Diagnostic makes sense when theta is monotonically decreasing - with depth, although the algorithm does not explicitly make - this assumption. - - NOTE: This diagnostic works with transport through cell faces. - To get transport_on_theta, a binning must be done, rather than - a remapping (as done for trans_rho_gm). - - Code history - - 2002: Stephen.Griffies - Zhi.Liang - Alexander.Pletzer - - 2007: updated algorithm with weighting as done in the paper - Lee, Nurser, Coward, and de Cuevas, 2007: - "Eddy advective and diffusive transports of heat and salt - in the Southern Ocean" JPO, vol 37, pages 1376-1393 - - 2010: updated by Rusty.Benson for optimization. - corrected weigthing by Stephen.Griffies - - 2010: Removed the weighting in favor of a strait rebinning - approach. The weighting approach was - unnecessary, and added more cost to the scheme. - -
-
-
-- - -
-vertical_reynolds_check
--
-- -DESCRIPTION -
-- - This subroutine computes the Reynolds number associated with vertical - friction visc_cbt and vertical velocity wrho_bt. This check is - appropriate for either Bgrid or Cgrid. -
-
-
-
-NAMELIST
- --&ocean_adv_vel_diag_nml --
-
----
-- -max_cfl_value -
-- Critical value for Courant number, above which the model will be brought down. -
-
-[real, units: dimensionless] -- -large_cfl_value -
-- Large value for Courant number, above which will write some diagnostics. -
-
-[real, units: dimensionless] -- -verbose_cfl -
-- For printing out lots of information about regions of large Courant numbers. -
-
-[logical] -- -diag_step -
-- Number of time steps between which compute the diagnostics. -
-
-[integer, units: dimensionless] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_diag/ocean_diagnostics.F90 b/src/mom5/ocean_diag/ocean_diagnostics.F90 index e6a417b136..53e771e4c4 100644 --- a/src/mom5/ocean_diag/ocean_diagnostics.F90 +++ b/src/mom5/ocean_diag/ocean_diagnostics.F90 @@ -1,6 +1,6 @@ module ocean_diagnostics_mod ! -!S.M. Griffies +! S.M. Griffies ! ! !@@ -48,9 +48,9 @@ module ocean_diagnostics_mod logical :: module_is_initialized = .FALSE. character(len=128) :: version=& - '$Id: ocean_diagnostics.F90,v 1.1.2.6 2012/06/03 00:41:57 Stephen.Griffies Exp $' + '$Id: ocean_diagnostics.F90,v 20.0 2013/12/14 00:12:51 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public :: ocean_diag_init, ocean_diagnostics diff --git a/src/mom5/ocean_diag/ocean_diagnostics.html b/src/mom5/ocean_diag/ocean_diagnostics.html deleted file mode 100644 index b44acc377e..0000000000 --- a/src/mom5/ocean_diag/ocean_diagnostics.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - Module ocean_diagnostics_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_diagnostics_mod
- - - - - -
-OVERVIEW
- -- Routine that calls the various numerical diagnostics. -
- - - -- Routine that calls the various numerical diagnostics. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_manager_mod
ocean_adv_vel_diag_mod
ocean_domains_mod
ocean_tracer_diag_mod
ocean_types_mod
ocean_velocity_diag_mod
-PUBLIC INTERFACE
----
-- -ocean_diag_init:
- -- -ocean_diagnostics:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_diag_init
--
-- -DESCRIPTION -
-- - Initialize the ocean_diag module. -
-
-
-- - -
-ocean_diagnostics
--
-- -DESCRIPTION -
-- - Call some ocean numerical diagnostics -
-
-
-
--top -- - diff --git a/src/mom5/ocean_diag/ocean_drifters.F90 b/src/mom5/ocean_diag/ocean_drifters.F90 index fe843defdf..9bc6882169 100644 --- a/src/mom5/ocean_diag/ocean_drifters.F90 +++ b/src/mom5/ocean_diag/ocean_drifters.F90 @@ -315,15 +315,17 @@ subroutine update_ocean_drifters(Velocity, Adv_vel, T_prog, Grid, Time) end subroutine update_ocean_drifters - subroutine ocean_drifters_end() + subroutine ocean_drifters_end(Grid) + type(ocean_grid_type) :: Grid if(.not. use_this_module) return - ! write restart file, optionally with lon/lat data coordinates + ! write restart file, optionally with lon/lat data coordinates (under development) call drifters_write_restart(drfts, filename='RESTART/drifters_inp.nc', & +! & x1=Grid%grid_x_u, y1=Grid%grid_y_u, geolon1=Grid%xt, & +! & x2=Grid%grid_x_u, y2=Grid%grid_y_u, geolat2=Grid%yt, & ermesg=ermesg) - ! destroy call drifters_del(drfts, ermesg=ermesg) diff --git a/src/mom5/ocean_diag/ocean_drifters.html b/src/mom5/ocean_diag/ocean_drifters.html deleted file mode 100644 index 103043aae5..0000000000 --- a/src/mom5/ocean_diag/ocean_drifters.html +++ /dev/null @@ -1,116 +0,0 @@ - - - -Module ocean_drifters_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_drifters_mod
- - - - - -
-OVERVIEW
- -- Advect USER supplied drifters using the shared/drifters package. -
- - - -- Advect USER supplied drifters using the shared/drifters package. --
- - -
-OTHER MODULES USED
- --- - - -drifters_mod-
fms_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
- - -
-PUBLIC ROUTINES
- -- - - - -
-NAMELIST
- --&ocean_drifters_nml --
-
----
-- -use_this_module -
-- Must be true to run this module. Default use_this_module=.false. -
-
-[logical] -- -output_interval -
-- Interval in timesteps between drifter writes -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_diag/ocean_tracer_diag.F90 b/src/mom5/ocean_diag/ocean_tracer_diag.F90 index 68c2e7b782..60aac2596f 100644 --- a/src/mom5/ocean_diag/ocean_tracer_diag.F90 +++ b/src/mom5/ocean_diag/ocean_tracer_diag.F90 @@ -191,9 +191,9 @@ module ocean_tracer_diag_mod integer :: tendency=0 character(len=128) :: version=& - '$Id: ocean_tracer_diag.F90,v 1.1.2.3 2012/06/01 20:47:08 Stephen.Griffies Exp $' + '$Id: ocean_tracer_diag.F90,v 20.0 2013/12/14 00:12:55 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! for tracer conservation: need to know num_prog_tracers to allocate real, dimension(:,:,:), allocatable :: tracer_source @@ -1656,7 +1656,7 @@ end subroutine compute_subduction ! Work with taup1 values, since Thickness type is filled with taup1 ! thickness fields. ! -! Stephen.Griffies@noaa.gov +! Stephen.Griffies ! July 2013 ! ! diff --git a/src/mom5/ocean_diag/ocean_tracer_diag.html b/src/mom5/ocean_diag/ocean_tracer_diag.html deleted file mode 100644 index 0d2a63aab1..0000000000 --- a/src/mom5/ocean_diag/ocean_tracer_diag.html +++ /dev/null @@ -1,1127 +0,0 @@ - - - -Module ocean_tracer_diag_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_tracer_diag_mod
- - - - - -
-OVERVIEW
- -- Routines for tracer diagnostics -
- - - -- Routines for tracer diagnostics. Some are printed to ascii output, some are sent - to diagnostic manager. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_density_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_tracer_diag_init:
- -- -ocean_tracer_diagnostics:
- -- -calc_mixed_layer_depth:
- -- -mixed_layer_depth:
- -- -mixed_layer_depth_dtheta:
- -- -compute_subduction:
- -- -tracer_change:
- -- -total_tracer:
- -- -klevel_total_tracer:
- -- -total_mass:
- -- -total_volume:
- -- -klevel_total_mass:
- -- -tracer_integrals:
- -- -tracer_land_cell_check:
- -- -mass_conservation:
- -- -tracer_conservation:
- -- -diagnose_kappa_sort:
- -- -diagnose_kappa_simple:
- -- -diagnose_depth_of_potrho:
- -- -diagnose_depth_of_theta:
- -- -diagnose_tracer_on_rho:
- -- -diagnose_tracer_zrho_on_rho:
- -- -calc_potrho_mixed_layer:
- -- -potrho_mixed_layer:
- -- -send_total_mass:
- -- -send_total_volume:
- -- -send_total_tracer:
- -- -send_global_ave_tracer:
- -- -send_global_ave_pressure:
- -- -send_surface_ave_tracer:
- -- -send_surface_area_ave_tracer:
- -- -send_tracer_variance:
- -- -diagnose_eta_tend_3dflux:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_tracer_diag_init
--
-- -DESCRIPTION -
-- - Initialize the ocean_tracer_diag module containing subroutines - diagnosing tracer related properties of the simulation. These are - not terms in the equations, but rather they are diagnosed from - terms. -
-
-
-- - -
-ocean_tracer_diagnostics
--
-- -DESCRIPTION -
-- - Call diagnostics related to the tracer fields. -
-
-
-- - -
-calc_mixed_layer_depth
--
-- -DESCRIPTION -
-- - - Calculate the mixed layer depth (m), which is defined as the depth ( > 0 ) - where the buoyancy difference with respect to the surface level is - equal to buoyancy_crit (m/s^2). - - Note that the mixed layer depth is taken with respect to the ocean surface - at z=eta_t, so the mixed layer depth is always positive. That is, the mld - is here defined as a thickness of water. - -
-
-
-- - -
-mixed_layer_depth
--
-- -DESCRIPTION -
-- - - Diagnose mixed layer depth (m). - Call calc_mixed_layer_depth to determine the mixed layer depth. - Also compute neutral density at depth of the mixed layer. -
-
-
-- - -
-mixed_layer_depth_dtheta
--
-- -DESCRIPTION -
-- - - Calculate the depth required to reach a temperature that is - dtheta cooler than the surface temperature. - - Note: - 1/ mixed_layer_depth_dtheta is taken with respect to the ocean surface - at z=eta_t. - - 2/ mixed_layer_depth_dtheta is no greater than the ocean depth + eta_t. - - Coded March 2010 by Stephen.Griffies - -
-
-
-- - -
-compute_subduction
--
-- -DESCRIPTION -
-- - Diagnose subduction rate (kg/sec) based on kinematic method to compute - mass transport through base of mixed layer. - - Some approximations made for convenience: - 1/ use velocity at time tau - use tracer at time tau - use thickness at time taup1, since all pieces of Thickness - have already been updated to taup1. - - 2/ horizontally interpolate B-grid to C-grid velocity components, - but then vertically interpolate using mld computed at T-points. - - Stephen.Griffies - March 2012 -
-
-
-- - -
-tracer_change
--
-- -DESCRIPTION -
-- - - Compute change in tracer over a time step and difference between - this change and the boundary forcing. - - This routine is very useful for detecting bugs in tracer routines. - -
-
-
-- - -
-total_tracer
--
-- -DESCRIPTION -
-- - Compute integrated tracer in model. -
-
-
-- - -
-klevel_total_tracer
--
-- -DESCRIPTION -
-- - Compute integrated tracer on a k-level. -
-
-
-- - -
-total_mass
--
-- -DESCRIPTION -
-- - Compute total ocean tracer cell mass. For Boussinesq fluid, - mass is determined using rho0 for density. -
-
-
-- - -
-total_volume
--
-- -DESCRIPTION -
-- - Compute total ocean tracer cell volume. -
-
-
-- - -
-klevel_total_mass
--
-- -DESCRIPTION -
-- - Compute ocean tracer cell mass in a k-level. For Boussinesq fluid, - mass is determined using rho0 for density. -
-
-
-- - -
-tracer_integrals
--
-- -DESCRIPTION -
-- - Compute some integrated tracer diagnostics. -
-
-
-- - -
-tracer_land_cell_check
--
-- -DESCRIPTION -
-- - Check to be sure ocean tracer is zero over land -
-
-
-- - -
-mass_conservation
--
-- -DESCRIPTION -
-- - Compute change in mass over many time steps, and compare to the - input of mass through surface to check for mass conservation. - -============================================================ - - threelevel scheme - - Here is the logic for the accumulation of the fluxes and - comparisons between mass/volumes at the start and the end. - - Consider accumulation over four leap-frog time steps. - Ignore time filtering. - - mass(2) = mass(0) + 2dt*F(1) taup1=2, taum1=0, tau=1 - - mass(3) = mass(1) + 2dt*F(2) taup1=3, taum1=1, tau=2 - - mass(4) = mass(2) + 2dt*F(3) taup1=4, taum1=2, tau=3 - - mass(5) = mass(3) + 2dt*F(4) taup1=5, taum1=3, tau=4 - - Hence, - - [mass(4) + mass(5)] = [mass(0) + mass(1)] + 2dt*[F(1)+F(2)+F(3)+F(4)] - - For this example, we have - - itts_mass=1 through itte_mass=4 for accumulating fluxes - - itt=itts_mass=1=tau we use taum1=0 and tau=1 to get starting mass - - itt=itte_mass=4=tau we use tau=4 and taup1=5 to get the final mass - -============================================================ - - twolevel scheme - - Here is the logic for the accumulation of the fluxes and - comparisons between mass/volumes at the start and the end. - - Consider accumulation over four time steps. - - mass(3/2) = mass(1/2) + dt*F(1) taup1=3/2, taum1=1/2, tau=1 - - mass(5/2) = mass(3/2) + dt*F(2) taup1=5/2, taum1=3/2, tau=2 - - mass(7/2) = mass(5/2) + dt*F(3) taup1=7/2, taum1=5/2, tau=3 - - mass(9/2) = mass(7/2) + dt*F(4) taup1=9/2, taum1=7/2, tau=4 - - Hence, - - mass(9/2) = mass(1/2) + dt*[F(1)+F(2)+F(3)+F(4)] - - For this example, we have - - itts_mass=1 through itte_mass=4 for accumulating fluxes - - itt=itts_mass=1=tau we use taum1=1/2 to get starting mass - - itt=itte_mass=4=tau we use taup1=9/2 to get the final mass - -
-
-
-- - -
-tracer_conservation
--
-- -DESCRIPTION -
-- - Compute change in global integrated tracer over many time steps, - and compare to the input of tracer through the boundaries to - check for total tracer conservation. - - Accumulate fluxes as in the mass_conservation diagnostic. - -
-
-
-- - -
-diagnose_kappa_sort
--
-- -DESCRIPTION -
-- - Routine to diagnose the amount of mixing between classes of a - particular tracer. Temperature is used as default. - Method follows that used in the paper - - Spurious diapycnal mixing associated with advection in a - z-coordinate ocean model, 2000: S.M. Griffies, R.C. - Pacanowski, and R.W. Hallberg. Monthly Weather Review, vol 128, 538--564. - - This diagnostic is most useful when computing the levels of - effective dia-tracer mixing occuring in a model run with - zero buoyancy forcing at the boundaries. - - Algorithm notes: - - -assumes flat ocean bottom--non-flat bottoms loose the precise relation - between sorted depth and true ocean depth. This is a minor inconvenience. - The code is actually written so that the horizontal area of each - layer can be different. This will allow for this diagnostic to be - used, say, for simple topography, such as bowl or bump. - - -assumes Boussinesq fluid so that consider volume instead of mass of a cell. - Also his means that dzt = rho0r*rho_dzt - - -assumes area integrated eta_t is zero, so domain volume is static. - This is the case when there are no water boundary fluxes. - - -Results are meaningful only when dxt*dyt*dst of each grid cell - is the same. This is best realized with a beta-plane or f-plane - geometry, and with zstar vertical coordinate. - - My best understanding of this limitation is related to systematic - biases in roundoff errors that result when the grid cells have - varying volumes. - - If choose to use geopotential vertical coordinate, it is best - to set linear_free_surface=.true. in ocean_thickness_nml, - so that Thickness%rho_dzt = rho0%Grd%dzt. The sorting model of - mixing has not been generalized to evolving layer thicknesses - with geopotential. - - With zstar, the dst is constant in time, and the sorting method - will sort to a depth in zstar space rather than geopotential space. - This is a trivial distinction in principle, but should help with - some roundoff issues in practice. - - -assumes tendency=TWO_LEVEL, which is exploited here to save memory. - - Numerical roundoff is a real issue with this diagnostic. - It is critical that full double precision be used - to garner sensible results. - - -defines some global arrays, so requires large memory. - This feature can be removed if parallel sort is - implemented. So far, such has not been done. - - -Effective kappa is set to zero at top of top-most cell. - It is then diagnosed as zero (or roundoff) at bottom - of the column if there are zero boundary buoyancy fluxes. - - -when computing density, we do rho=-alpha*theta. - We drop the rho0 factor in order to reduce roundoff. - Likewise, we assume alpha=1.0 rather than alpha=alpha_linear_eos - We use alpha=1.0 to improve precision. - With alpha=1.0 and rho=-alpha*theta, the rho variable - is then just minus theta. - - -minimum vertical density gradient rho_grad_min is necessary to - avoid errors with truncation in the division by drho/dz when compute kappa. - rho_grad_min corresponds roughly to the precision of the computation. - Physically, with - - N^2 = -(g/rho0)(drho/dz) - - then rho_grad_min sets a minimum N^2 resolved. - This corresponds to a frequency f=N/2pi. The typical - period of inertial oscillations in the deep ocean is 6hrs - (Pickard and Emery, page 55-56). In the upper ocean, it is - 10-30 minutes, in pycnocline it is smaller still. - So to cover the majority of the ocean's stratification, - we will want to set rho_grad_min to something smaller than 9e-6. - - To bin the effective diffusivity, it is also useful to have a max - vertical density gradient. - --versions: - - mom4p0 method assumed rigid lid, or zero surface height undulations. - Fit the following equation to the model data - \partial_{t}(rho_sort) = (F_{k}-F_{k-1})/dzw - - mom4p1 method fits the following equation to model data - \partial_{t}(dzt_sort*theta_sort) = F_{k} - F_{k-1} - Fits this equation assuming two-time level tendency - - revision: 05/2005 - revision: 07/2007 - Stephen.Griffies - -
-
-
-- - -
-diagnose_kappa_simple
--
-- -DESCRIPTION -
-- - Routine to diagnose the amount of mixing between classes of a - particular tracer. Temperature is used as default. - - Compute horizontal average of temp to define a stable profile. - Evolution of this profile defines an effective diffusity. - - This diffusivity is different than the one diagnosed - from the adiabatic sorting approach. The sorting approach is - more relevant. The two approaches agree when there - is zero baroclinicity, and the present simple scheme is - useful ONLY to help debug the sorting routine. - -
-
-
-- - -
-diagnose_depth_of_potrho
--
-- -DESCRIPTION -
-- - - Diagnose depth (m) of a potential density surface surface relative to - the ocean surface at z=eta (not relative to z=0). - - Method uses linear interpolation to find the depth of a - potential rho surface. - - Scheme currently does not forward (backwards) interpolate if - rho surface lies within lowest (uppermost) grid cell. - - Diagnostic only makes sense when rho is monotonically - increasing as go deeper in water column. - - Author: Harper.Simmons - Zhi.Liang -
-
-
-- - -
-diagnose_depth_of_theta
--
-- -DESCRIPTION -
-- - - Diagnose depth (m) of a potential temperature surface relative to - the ocean surface at z=eta (not relative to z=0). - - Method uses linear interpolation to find the depth of a - potential temp surface. - - Scheme currently does not forward (backwards) interpolate if - theta surface lies within lowest (uppermost) grid cell. - - Diagnostic only makes sense when theta is monotonically - decreasing as go deeper in water column. - - Based on "diagnose_depth_of_potrho" by Harper.Simmons - - Author: Stephen.Griffies - Zhi.Liang -
-
-
-- - -
-diagnose_tracer_on_rho
--
-- -DESCRIPTION -
-- - Diagnose tracer concentration on potential density surface. - Method based on diagnose_depth_of_potrho diagnostic. - - Author: Stephen.Griffies - - Updated Oct 2009 to be more vectorized - -
-
-
-- - -
-diagnose_tracer_zrho_on_rho
--
-- -DESCRIPTION -
-- - Diagnose tracer concentration * dz/drho on potential density surface. - This product, when integrated over dx*dy*drho, will yield the same - total tracer (to within roundoff) as the usual tracer concentration - integrated over dx*dy*dz. - - compute abs(dz/drho)==dz/drho in order to have tracer_zrho_on_rho - with same sign as tracer. - - Method based on diagnose_tracer_on_rho diagnostic. - - Author: Stephen.Griffies - Updated Oct 2009 to be more vectorized - -
-
-
-- - -
-calc_potrho_mixed_layer
--
-- -DESCRIPTION -
-- - Calculate the mixed layer depth and potential density at mixed layer base - according to depth at which buoyancy is greater than buoyancy_crit - relative to the surface. Compute the buoyancy using potential - density, rather than the insitu density, since we aim for this - diagnostic to be comparable to diagnostics from isopcynal models. - - Note that the mixed layer depth is taken with respect to the ocean surface, - and so the mixed layer depth is always positive. That is, the mld is here - defined as a thickness of water. - -
-
-
-- - -
-potrho_mixed_layer
--
-- -DESCRIPTION -
-- - Determine mixed layer depth and potential density at mixed layer base - according to depth at which buoyancy is greater than buoyancy_crit - relative to the surface. - Call calc_potrho_mixed_layer to calculate the quantities. - -
-
-
-- - -
-send_total_mass
--
-- -DESCRIPTION -
-- - Send total liquid seawater mass to diagnostic manager. -
-
-
-- - -
-send_total_volume
--
-- -DESCRIPTION -
-- - Send total liquid seawater mass to diagnostic manager. -
-
-
-- - -
-send_total_tracer
--
-- -DESCRIPTION -
-- - Send total tracer to diagnostic manager. -
-
-
-- - -
-send_global_ave_tracer
--
-- -DESCRIPTION -
-- - Send global averaged tracer to diagnostic manager. -
-
-
-- - -
-send_global_ave_pressure
--
-- -DESCRIPTION -
-- - Send global averaged pressure to diagnostic manager. -
-
-
-- - -
-send_surface_ave_tracer
--
-- -DESCRIPTION -
-- - Send global averaged surface tracer to diagnostic manager. - Note the presence of a rho_dzt weighting here... -
-
-
-- - -
-send_surface_area_ave_tracer
--
-- -DESCRIPTION -
-- - Send global area averaged surface tracer to diagnostic manager. - Note the weigthing is just area, with no thickness nor density. -
-
-
-- - -
-send_tracer_variance
--
-- -DESCRIPTION -
-- - - Compute the global and k-level tracer variance. - -
-
-
-- - -
-diagnose_eta_tend_3dflux
--
-- -DESCRIPTION -
-- - Diagnose contribution to global mean sea level evolution arising - from a 3d MOM flux computed from a parameterization. - - fluxes are assumed to have the following dimensions: - flux_x = (dy*dz)*diffusivity*rho*tracer_derivative_x - flux_y = (dx*dz)*diffusivity*rho*tracer_derivative_y - flux_z = diffusivity*rho*tracer_derivative_z - - Subroutine history: - Jan2012 version 1.0: Stephen.Griffies - -
-
-
-
-NAMELIST
- --&ocean_tracer_diag_nml --
-
----
-- -tracer_conserve_days -
-- Number of days between which compute the tracer conservation diagnostics. -
-
-[real, units: days] -- -diag_step -
-- Number of time steps between which compute the diagnostics. -
-
-[integer, units: dimensionless] -- -debug_diagnose_mixingA -
-- Set true for help with debugging the diagnostic for mixing. -
-
-[logical] -- -debug_diagnose_mixingB -
-- Set true for more help with debugging the diagnostic for mixing. - Lots of output. -
-
-[logical] -- -debug_diagnose_mixingC -
-- Set true for more help with debugging the diagnostic for mixing. - Lots of output. -
-
-[logical] -- -debug_diagnose_mixingD -
-- Set true for more help with debugging the diagnostic for mixing. - Lots of output. -
-
-[logical] -- -smooth_kappa_sort -
-- Number of 1-2-1 smooths applied to kappa_sort -
-
-[integer] -- -smooth_dzt_rho_sort -
-- Number of 1-2-1 smooths applied to rho_sort -
-
-[integer] -- -rho_grad_min -
-- min vertical density gradient (kg/m^3/m) used in computing kappa sorted - in the diagnostic mixing sorted. -
-
-[real, units: kg/m^3/m] -- -rho_grad_max -
-- max vertical density gradient (kg/m^3/m) used in computing kappa sorted -
-
-[real, units: kg/m^3/m] -- -buoyancy_crit -
-- Critical buoyancy difference relative to surface for computing mixed - layer depth. Default buoyancy_crit=0.0003. -
-
-[real, units: m/s^2] -- -dtheta_crit -
-- Critical temperature difference relative to surface for computing - mixed_layer_depth_dtheta . Default dtheta_crit=2.0. -
-
-[real, units: degC] -- -diagnose_mixing_days -
-- Days over which time average the thickness weighted density before taking its - time tendency for use in computing the effective diapycnal diffusivity. -
-
-[real, units: day] -- -psu2ppt -
-- The preTEOS10 EOS used in MOM requires salinity to - use the Practical Salinity Scale (pss). This scale is - also known as the Practical Salinity Unit (psu). - - However, salinity as an absolute concentration in - parts per thousand is more convenient to use when - performing budget analyses such as in this module. - Conversion between pss and ppt depends on the precise - ratio of ions in the seawater. Hence, the conversion - is not constant. However, it is close to a constant, - as reported in Jackett etal (2004). For purposes of - budgets, we take this conversion as a constant. - The conversion is - - s(ppt) = psu2ppt * s(psu) - - where again s(psu) is what MOM carries as its - prognostic salinity field when preTEOS10 EOS is used. - - Jackett etal (2004), correcting a type in equation (53) - of Feistel (2003), report that - - s(ppt) = 1.004867 * s(psu) - -
-
-[real] -- -smooth_mld -
-- Smooth the diagnosed mixed layer depth. Default smooth_mld=.false. -
-
-[integer] -- -smooth_mld_for_subduction -
-- Smooth the diagnosed mixed layer depth to be used for subduction - diagnostics. Default smooth_mld_for_subduction=.true. -
-
-[integer] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_diag/ocean_tracer_util.html b/src/mom5/ocean_diag/ocean_tracer_util.html deleted file mode 100644 index 573608e50b..0000000000 --- a/src/mom5/ocean_diag/ocean_tracer_util.html +++ /dev/null @@ -1,404 +0,0 @@ - - - -Module ocean_tracer_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_tracer_util_mod
- - - - - -
-OVERVIEW
- -- This module contains many routines of use for tracer diagnostics in MOM. -
- - - -- Tracer utility module for MOM. Of use for tracer diagnostics. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_mod
platform_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_tracer_util_init:
- -- -tracer_min_max:
- -- -dzt_min_max:
- -- -tracer_prog_chksum:
- -- -tracer_diag_chksum:
- -- -tracer_psom_chksum:
- -- -sort_pick_array:
- -- -sort_shell_array:
- -- -rebin_onto_rho:
- -- -diagnose_mass_of_layer_orig:
- -- -diagnose_mass_of_layer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_tracer_util_init
--
-- -DESCRIPTION -
-- - Initialize MOM tracer utilities. -
-
-
-- - -
-tracer_min_max
--
-- -DESCRIPTION -
-- - Compute the global min and max for tracers. - - Vectorized using maxloc() and minloc() intrinsic functions by - Russell.Fiedler@csiro.au (May 2005). - - Modified by Zhi.Liang (July 2005) - -
-
-
-- - -
-dzt_min_max
--
-- -DESCRIPTION -
-- - Compute the global min and max for dzt. - - Modified by Stephen.Griffies from subroutine tracer_min_max - -
-
-
-- - -
-tracer_prog_chksum
--
-- -DESCRIPTION -
-- - Compute checksums for prognostic tracers -
-
-
-- - -
-tracer_diag_chksum
--
-- -DESCRIPTION -
-- - Compute checksums for diagnostic tracers -
-
-
-- - -
-tracer_psom_chksum
--
-- -DESCRIPTION -
-- - Compute checksums for PSOM advection second order moments. -
-
-
-- - -
-sort_pick_array
--
-- -DESCRIPTION -
-- - Simplest, and slowest, sorting algorithm from Numerical Recipes. - Called "sort_pick" in Numerical Recipes. - - Input are two arrays, first array defines the ascending sort - and second is a slave to the sort. - - Typical example is sorting a vector of water parcels lightest - to densest, with slave being volume of the parcels. - - More sophisticated sorting algorithms exist, and may need to - be coded should this method prove too slow. - - This scheme has order N^2 operations, which is a lot. - - output has array(1) smallest and a(nsortpts) largest - with corresponding slave array. - - coded Stephen.Griffies June 2005 - -
-
-
-- - -
-sort_shell_array
--
-- -DESCRIPTION -
-- - Shell (or diminishing increment) sort from Numerical Recipes. - Called "sort_shell" in Numerical Recipes. - - Input are two arrays, first array defines the ascending sort - and second is a slave to the sort array. - - Typical example is sorting a vector of water parcels lightest - to densest, with slave being volume of the parcels. - - More sophisticated sorting algorithms exist, and may need to - be coded should this method prove too slow. - - This scheme has order N^(5/4) operations. - - output has array(1) smallest and a(nsortpts) largest, - with corresponding ordering for slave array. - - coded Stephen.Griffies June 2005 - -
-
-
-- - -
-rebin_onto_rho
--
-- -DESCRIPTION -
-- - Bin a level input tendency field according to density classes. - The binning is meant for tendencies and transports, as used in particular - for the neut_rho, wdian_rho, and tform_rho diagnostics. - - Note that if use rebin_onto_rho_all_values=.false. then will - not be consistent with transport_on_nrho calculation, which includes - bins all grid cells, including those outside of range for the bounds. - - Stephen.Griffies - April 2012: algorithm made identical to transport_on_nrho as - computed in ocean_adv_vel_diag. - -
-
-
-- - -
-diagnose_mass_of_layer_orig
--
-- -DESCRIPTION -
-- - - Diagnose the mass of a layer as a function of layer and (i,j). - - Method uses linear interpolation to find the mass per area of - layer boundaries, which are then used to get mass per area of - layer, and then mass through multipication by area. - - Scheme currently does not forward (backwards) interpolate if - layer boundary lies within lowest (uppermost) grid cell. - - Diagnostic only makes sense when layer_level is monotonically - increasing as go deeper in water column. - - layer_bounds = neutral density of layer interfaces - mass_level = mass per area at bottom of tracer cell - layer_level = neutral density of model grid levels - mass_layer = diagnosed mass of a neutral density layer - -
-
-
-- - -
-diagnose_mass_of_layer
--
-- -DESCRIPTION -
-- - - Diagnose the mass of a layer as a function of layer and (i,j). - - Method uses linear interpolation to find the mass per area of - layer boundaries, which are then used to get mass per area of - layer, and then mass through multipication by area. - - Diagnostic only makes sense when layer_level is monotonically - increasing as go deeper in water column. - -
-
-
-
-NAMELIST
- --&ocean_tracer_util_nml --
-
----
-- -rebin_onto_rho_all_values -
-- Set true to if wish to bin all values into density classes, even - those cells whose density is outside the max and min range of the - density bins. The default is rebin_onto_rho_all_values=.true., - which means those cells with extreme density values will be included. - This default is consistent with the default computation of - transport_on_nrho. -
-
-[logical] -- -debug_diagnose_mass_of_layer -
-- To help debug the algorithm to diagnose mass of fluid within - a neutral density layer. - Default: debug_diagnose_mass_of_layer=.false. -
-
-[logical] -- -epsln_diagnose_mass_of_layer -
-- Relative mass difference allowable between layer and level total mass. - Default: epsln_diagnose_mass_of_layer=1e-4. -
-
-[real] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_diag/ocean_velocity_diag.F90 b/src/mom5/ocean_diag/ocean_velocity_diag.F90 index 1b33ce86f0..6d2fa65dc2 100644 --- a/src/mom5/ocean_diag/ocean_velocity_diag.F90 +++ b/src/mom5/ocean_diag/ocean_velocity_diag.F90 @@ -1,7 +1,7 @@ module ocean_velocity_diag_mod #define COMP isc:iec,jsc:jec ! -!S.M. Griffies +! S.M. Griffies ! ! !@@ -180,9 +180,9 @@ module ocean_velocity_diag_mod logical :: module_is_initialized = .FALSE. character(len=128) :: version=& - '$Id: ocean_velocity_diag.F90,v 1.1.2.12 2012/06/04 00:11:43 Stephen.Griffies Exp $' + '$Id: ocean_velocity_diag.F90,v 20.0 2013/12/14 00:12:59 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public ocean_velocity_diag_init public ocean_velocity_diagnostics @@ -1029,7 +1029,7 @@ end subroutine velocity_change ! ! Diagnose topostrophy as per Greg Holloway. ! -! Stephen.Griffies@noaa.gov +! Stephen.Griffies ! March 2012 ! ! diff --git a/src/mom5/ocean_diag/ocean_velocity_diag.html b/src/mom5/ocean_diag/ocean_velocity_diag.html deleted file mode 100644 index aee3cbe032..0000000000 --- a/src/mom5/ocean_diag/ocean_velocity_diag.html +++ /dev/null @@ -1,541 +0,0 @@ - - - - Module ocean_velocity_diag_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_velocity_diag_mod
- - - - - -
-OVERVIEW
- -- Numerical diagnostics for velocity related quantities. -
- - - -- This module contains some diagnostics for velocity related quantities. - Account is taken for either Bgrid or Cgrid layout of the velocity - and related discrete fields. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_bih_friction_mod
ocean_coriolis_mod
ocean_domains_mod
ocean_form_drag_mod
ocean_lap_friction_mod
ocean_momentum_source_mod
ocean_operators_mod
ocean_parameters_mod
ocean_pressure_mod
ocean_types_mod
ocean_util_mod
ocean_velocity_advect_mod
ocean_vert_mix_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_velocity_diag_init:
- -- -ocean_velocity_diagnostics:
- -- -potential_energy:
- -- -kinetic_energy:
- -- -velocity_land_cell_check:
- -- -velocity_change:
- -- -compute_topostrophy:
- -- -compute_vorticity:
- -- -pressure_conversion:
- -- -pressure_energy:
- -- -friction_energy:
- -- -vert_dissipation:
- -- -energy_analysis:
- -- -cfl_check1_bgrid:
- -- -cfl_check1_cgrid:
- -- -cfl_check2_bgrid:
- -- -cfl_check2_cgrid:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_velocity_diag_init
--
-- -DESCRIPTION -
-- - Initialize the ocean_velocity_diag module containing subroutines - diagnosing velocity related properties of the simulation. These are - not terms in the equations, but rather they are diagnosed from - terms. -
-
-
-- - -
-ocean_velocity_diagnostics
--
-- -DESCRIPTION -
-- - Call diagnostics related to the velocity. -
-
-
-- - -
-potential_energy
--
-- -DESCRIPTION -
-- - - Compute gravitational potential energy (Joules) relative to z=0 - taken with respect to the value at the initial time step. - -
-
-
-- - -
-kinetic_energy
--
-- -DESCRIPTION -
-- - Compute global integrated horizontal kinetic energy. -
-
-
-- - -
-velocity_land_cell_check
--
-- -DESCRIPTION -
-- - See if there are any points over land with nonzero ocean velocity -
-
-
-- - -
-velocity_change
--
-- -DESCRIPTION -
-- - Determine the number of points that have large single-time step - changes in the absolute value of the velocity. -
-
-
-- - -
-compute_topostrophy
--
-- -DESCRIPTION -
-- - - Diagnose topostrophy as per Greg Holloway. - - Stephen.Griffies - March 2012 - -
-
-
-- - -
-compute_vorticity
--
-- -DESCRIPTION -
-- - Compute z-component to vorticity. -
-
-
-- - -
-pressure_conversion
--
-- -DESCRIPTION -
-- - Perform pressure conversion error analysis. This analysis should be - computed prior to update_ucell_thickness since we need to use dzu(tau) - and dzten(tau) here rather than dzu(taup1) or dzten(taup1). - - Account taken for Bgrid and Cgrid. However, blobs need to be updated - for Cgrid. - -
-
-
-- - -
-pressure_energy
--
-- -DESCRIPTION -
-- - Diagnose u dot grad(p) for diagnostic purposes. These maps - when summed over all grid points will result in an energy - that is equal to pint+pext as computed in pressure_conversion. - - Account taken of either Bgrid or Cgrid. - -
-
-
-- - -
-friction_energy
--
-- -DESCRIPTION -
-- - Diagnose u dot Friction for diagnostic purposes. - - Account taken for either Bgrid or Cgrid. - - NOTE: - - A) DO NOT split into baroclinic and barotropic pieces. Just compute - u dot F using full velocity field u. Otherwise, the calculation emulates - that done in energy_analysis subroutine. - - B) DO NOT remove the effects from bottom drag and from surface stress. - The reason is that bottom drag and surface stress are incorporated to - the vertical friction operator, even when doing vertical friction - implicitly in time. So it is tough to remove these effects in an - explicitl diagnostic manner. So the u dot vertical friction piece - includes BOTH surface and bottom stress. - -
-
-
-- - -
-vert_dissipation
--
-- -DESCRIPTION -
-- - Diagnose dissipation from vertical friction due just to viscosity. - - Units W/m^2 - - Assumptions: - - 1/ Ignore bottom drag here...just concerned with viscosity. - - 2/ Assume vertical friction is handled implicitly in time. - -
-
-
-- - -
-energy_analysis
--
-- -DESCRIPTION -
-- - Perform energy analysis by taking scalar product of horizontal - velocity with the velocity equations and integrating over the ocean volume. - - Pressure conversions have already been computed in pressure_conversion - subroutine. It is necessary to perform that analysis earlier than - the call to update_ucell_thickness inside ocean_model_mod, whereas - the remaining elements in the energy analysis can be called at the - end of the update for velocity. -
-
-
-- - -
-cfl_check1_bgrid
--
-- -DESCRIPTION -
-- - Perform the first of two CFL checks on horizontal velocity. - - Assume Bgrid here. - - Vectorized version from Russell.Fiedler@csiro.au computes cfl - values at a single latitude. The location of the maximum at this - latitude is calculated via the maxloc() intrinsic. The maximum - value for this processor is then updated if necessary. - -
-
-
-- - -
-cfl_check1_cgrid
--
-- -DESCRIPTION -
-- - Perform the first of two CFL checks on horizontal velocity. - - Assume Cgrid here. - - Vectorized version from Russell.Fiedler@csiro.au computes cfl - values at a single latitude. The location of the maximum at this - latitude is calculated via the maxloc() intrinsic. The maximum - value for this processor is then updated if necessary. - -
-
-
-- - -
-cfl_check2_bgrid
--
-- -DESCRIPTION -
-- - Perform the second of two CFL checks on horizontal velocity. - - Assume Bgrid here. - - Bring the model down if too many large Courant numbers detected. -
-
-
-- - -
-cfl_check2_cgrid
--
-- -DESCRIPTION -
-- - Perform the second of two CFL checks on horizontal velocity. - - Assume Cgrid here. - - Bring the model down if too many large Courant numbers detected. -
-
-
-
-NAMELIST
- --&ocean_velocity_diag_nml --
-
----
-- -diag_step -
-- Number of time steps between which compute the diagnostics. -
-
-[integer, units: dimensionless] -- -energy_diag_step -
-- Perform energy analysis every n timesteps (1==every time step). - This diagnostic is expensive, so should be used sparingly during - production runs. -
-
-[integer] -- -land_cell_num_max -
-- Maximum number of land cells where will printout nonzero velocity points. - Default land_cell_num_max=100. -
-
-[integer, units: dimensionless] -- -max_cfl_value -
-- Critical value for Courant number, above which the model will be brought down. -
-
-[real, units: dimensionless] -- -large_cfl_value -
-- Large value for Courant number, above which will write some diagnostics. -
-
-[real, units: dimensionless] -- -verbose_cfl -
-- For printing out lots of information about regions of large Courant numbers. -
-
-[logical] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. -
-
-[logical] -- -debug_this_module -
-- For some debugging purposes -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/gotm-4.0/doc/README b/src/mom5/ocean_param/gotm-4.0/doc/README index 7250356f8d..69c8e06caf 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/README +++ b/src/mom5/ocean_param/gotm-4.0/doc/README @@ -1,5 +1,5 @@ # -#$Id: README,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +#$Id: README,v 20.0 2013/12/14 00:13:03 fms Exp $ # Currently, there are three versions of the GOTM documentation with the diff --git a/src/mom5/ocean_param/gotm-4.0/doc/a4.tex b/src/mom5/ocean_param/gotm-4.0/doc/a4.tex index dfe5ab0b7a..cebf836f8a 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/a4.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/a4.tex @@ -1,5 +1,5 @@ % -%$Id: a4.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: a4.tex,v 20.0 2013/12/14 00:13:04 fms Exp $ % \documentclass[a4paper,twoside,11pt]{article} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/airseaIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/airseaIntro.tex index c71c44335e..16b3f1874a 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/airseaIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/airseaIntro.tex @@ -1,5 +1,5 @@ % -%$Id: airseaIntro.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: airseaIntro.tex,v 20.0 2013/12/14 00:13:05 fms Exp $ % \section{Air--Sea interaction \label{sec:airseaIntro}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/cases.tex b/src/mom5/ocean_param/gotm-4.0/doc/cases.tex index 5191ea0f22..10bad2abae 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/cases.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/cases.tex @@ -1,5 +1,5 @@ % -%$Id: cases.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: cases.tex,v 20.0 2013/12/14 00:13:07 fms Exp $ % \section{GOTM scenarios \label{sec:cases}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/definitions.tex b/src/mom5/ocean_param/gotm-4.0/doc/definitions.tex index 20770045a8..b85a0d91c3 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/definitions.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/definitions.tex @@ -1,5 +1,5 @@ % -%$Id: definitions.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: definitions.tex,v 20.0 2013/12/14 00:13:08 fms Exp $ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/mom5/ocean_param/gotm-4.0/doc/extraIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/extraIntro.tex index 011cc8000f..c777d495c2 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/extraIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/extraIntro.tex @@ -1,5 +1,5 @@ % -%$Id: extraIntro.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: extraIntro.tex,v 20.0 2013/12/14 00:13:09 fms Exp $ % \section{Extra features \label{sec:extra}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/gotm.bib b/src/mom5/ocean_param/gotm-4.0/doc/gotm.bib index f27458676e..740f4f9931 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/gotm.bib +++ b/src/mom5/ocean_param/gotm-4.0/doc/gotm.bib @@ -1,5 +1,5 @@ % -%$Id: gotm.bib,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: gotm.bib,v 20.0 2013/12/14 00:13:10 fms Exp $ % @String{OMOD = "Ocean Modelling"} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/gotm_pub.bib b/src/mom5/ocean_param/gotm-4.0/doc/gotm_pub.bib index 84a6394c53..36fba73e66 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/gotm_pub.bib +++ b/src/mom5/ocean_param/gotm-4.0/doc/gotm_pub.bib @@ -1,5 +1,5 @@ % -%$Id: gotm_pub.bib,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: gotm_pub.bib,v 20.0 2013/12/14 00:13:11 fms Exp $ % %@String{OMOD = "Ocean Modelling"} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/guiIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/guiIntro.tex index 3c44449abd..de9a993030 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/guiIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/guiIntro.tex @@ -1,5 +1,5 @@ % -%$Id: guiIntro.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: guiIntro.tex,v 20.0 2013/12/14 00:13:12 fms Exp $ % \section{Running GOTM in a GUI\label{sec:guiIntro}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/html.tex b/src/mom5/ocean_param/gotm-4.0/doc/html.tex index d06dbc4d22..4be3f4ca00 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/html.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/html.tex @@ -1,5 +1,5 @@ % -%$Id: html.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: html.tex,v 20.0 2013/12/14 00:13:13 fms Exp $ % \documentclass[a4paper,twoside]{article} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/introduction.tex b/src/mom5/ocean_param/gotm-4.0/doc/introduction.tex index 16c6a84da4..a7b1827980 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/introduction.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/introduction.tex @@ -1,5 +1,5 @@ % -%$Id: introduction.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: introduction.tex,v 20.0 2013/12/14 00:13:14 fms Exp $ % \section{Introduction} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/letter.tex b/src/mom5/ocean_param/gotm-4.0/doc/letter.tex index e3af3901f7..82baaa4308 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/letter.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/letter.tex @@ -1,5 +1,5 @@ % -%$Id: letter.tex,v 1.1.2.1 2012/05/15 15:59:42 smg Exp $ +%$Id: letter.tex,v 20.0 2013/12/14 00:13:15 fms Exp $ % \documentclass[letter,twoside]{article} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/mainIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/mainIntro.tex index c00a50ed44..d655d768e3 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/mainIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/mainIntro.tex @@ -1,5 +1,5 @@ % -%$Id: mainIntro.tex,v 1.1.2.1 2012/05/15 15:59:43 smg Exp $ +%$Id: mainIntro.tex,v 20.0 2013/12/14 00:13:16 fms Exp $ % \section{The GOTM main program \label{sec:mainIntro}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/meanflowIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/meanflowIntro.tex index f806ac32ef..fa05615bb0 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/meanflowIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/meanflowIntro.tex @@ -1,5 +1,5 @@ % -%$Id: meanflowIntro.tex,v 1.1.2.1 2012/05/15 15:59:43 smg Exp $ +%$Id: meanflowIntro.tex,v 20.0 2013/12/14 00:13:18 fms Exp $ % \section{The mean flow model \label{sec:meanflowIntro}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/observationsIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/observationsIntro.tex index 3d3bdbb9bb..b596231a57 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/observationsIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/observationsIntro.tex @@ -1,5 +1,5 @@ % -%$Id: observationsIntro.tex,v 1.1.2.1 2012/05/15 15:59:43 smg Exp $ +%$Id: observationsIntro.tex,v 20.0 2013/12/14 00:13:19 fms Exp $ % \section{Working with observed data in GOTM} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/outputIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/outputIntro.tex index def8ba95b8..7fb71809c1 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/outputIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/outputIntro.tex @@ -1,5 +1,5 @@ % -%$Id: outputIntro.tex,v 1.1.2.1 2012/05/15 15:59:43 smg Exp $ +%$Id: outputIntro.tex,v 20.0 2013/12/14 00:13:20 fms Exp $ % \section{Saving the results \label{sec:output} } diff --git a/src/mom5/ocean_param/gotm-4.0/doc/turbulenceIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/turbulenceIntro.tex index facd133806..6b88d70fed 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/turbulenceIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/turbulenceIntro.tex @@ -1,5 +1,5 @@ % -%$Id: turbulenceIntro.tex,v 1.1.2.1 2012/05/15 15:59:43 smg Exp $ +%$Id: turbulenceIntro.tex,v 20.0 2013/12/14 00:13:21 fms Exp $ % \section{The turbulence model \label{sec:turbulenceIntro}} diff --git a/src/mom5/ocean_param/gotm-4.0/doc/utilIntro.tex b/src/mom5/ocean_param/gotm-4.0/doc/utilIntro.tex index ad5706f6a9..89a97f20b0 100644 --- a/src/mom5/ocean_param/gotm-4.0/doc/utilIntro.tex +++ b/src/mom5/ocean_param/gotm-4.0/doc/utilIntro.tex @@ -1,5 +1,5 @@ % -%$Id: utilIntro.tex,v 1.1.2.1 2012/05/15 15:59:43 smg Exp $ +%$Id: utilIntro.tex,v 20.0 2013/12/14 00:13:22 fms Exp $ % \section{Utilities}\label{sec:util} diff --git a/src/mom5/ocean_param/gotm-4.0/include/cppdefs.h b/src/mom5/ocean_param/gotm-4.0/include/cppdefs.h index a8ba8b815c..fd1ffede1d 100644 --- a/src/mom5/ocean_param/gotm-4.0/include/cppdefs.h +++ b/src/mom5/ocean_param/gotm-4.0/include/cppdefs.h @@ -55,13 +55,8 @@ #else #define REALTYPE real(kind=8) !#define MPI_REALTYPE MPI_DOUBLE_PRECISION -#ifdef GFORTRAN -#define _ZERO_ 0.0 -#define _ONE_ 1.0 -#else -#define _ZERO_ 0.0d0 -#define _ONE_ 1.0d0 -#endif +#define _ZERO_ 0.0_8 +#define _ONE_ 1.0_8 #endif ! non-local fluxes diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/algebraiclength.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/algebraiclength.F90 index 0458740958..05aaa4777c 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/algebraiclength.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/algebraiclength.F90 @@ -133,6 +133,9 @@ subroutine algebraiclength(method,nlev,z0b,z0s,depth,h,NN) ! Original author(s): Manuel Ruiz Villarreal, Hans Burchard ! ! $Log: algebraiclength.F90,v $ +! Revision 20.0 2013/12/14 00:13:26 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/alpha_mnb.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/alpha_mnb.F90 index dc66ce8a7c..2f7f050b2d 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/alpha_mnb.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/alpha_mnb.F90 @@ -32,6 +32,9 @@ subroutine alpha_mnb(nlev,NN,SS) ! Original author(s): Lars Umlauf ! ! $Log: alpha_mnb.F90,v $ +! Revision 20.0 2013/12/14 00:13:27 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_a.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_a.F90 index 12741737f0..d942b22d41 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_a.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_a.F90 @@ -108,6 +108,9 @@ subroutine cmue_a(nlev) ! Original author(s): Lars Umlauf ! ! $Log: cmue_a.F90,v $ +! Revision 20.0 2013/12/14 00:13:28 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_b.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_b.F90 index dc02aef112..1403627f30 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_b.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_b.F90 @@ -45,6 +45,9 @@ subroutine cmue_b(nlev) ! Original author(s): Lars Umlauf ! ! $Log: cmue_b.F90,v $ +! Revision 20.0 2013/12/14 00:13:29 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_c.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_c.F90 index 75f94bd412..01b0a3dd89 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_c.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_c.F90 @@ -100,14 +100,17 @@ subroutine cmue_c(nlev) integer, intent(in) :: nlev ! !DEFINED PARAMETERS: - REALTYPE, parameter :: asLimitFact=1.0 - REALTYPE, parameter :: anLimitFact=0.5 + REALTYPE, parameter :: asLimitFact=1.0d0 + REALTYPE, parameter :: anLimitFact=0.5d0 ! ! !REVISION HISTORY: ! Original author(s): Lars Umlauf ! ! $Log: cmue_c.F90,v $ +! Revision 20.0 2013/12/14 00:13:30 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_d.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_d.F90 index bbbe583e00..8b81c00b29 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_d.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_d.F90 @@ -48,14 +48,17 @@ subroutine cmue_d(nlev) integer, intent(in) :: nlev ! !DEFINED PARAMETERS: - REALTYPE, parameter :: anLimitFact = 0.5 - REALTYPE, parameter :: small = 1.0e-10 + REALTYPE, parameter :: anLimitFact = 0.5D0 + REALTYPE, parameter :: small = 1.0D-10 ! ! !REVISION HISTORY: ! Original author(s): Lars Umlauf ! ! $Log: cmue_d.F90,v $ +! Revision 20.0 2013/12/14 00:13:31 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_ma.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_ma.F90 index b5f54d0aa9..66c3db37de 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_ma.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_ma.F90 @@ -36,6 +36,9 @@ subroutine cmue_ma(nlev) ! Original author(s): Hans Burchard & Karsten Bolding ! ! $Log: cmue_ma.F90,v $ +! Revision 20.0 2013/12/14 00:13:32 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_rf.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_rf.F90 index 3f7089afcf..88e71cab22 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_rf.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_rf.F90 @@ -57,6 +57,9 @@ subroutine cmue_rf(nlev) ! Original author(s): Manuel Ruiz Villarreal, Hans Burchard ! ! $Log: cmue_rf.F90,v $ +! Revision 20.0 2013/12/14 00:13:33 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_sg.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_sg.F90 index 551a8f1cf4..12f25122a5 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_sg.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/cmue_sg.F90 @@ -37,6 +37,9 @@ subroutine cmue_sg(nlev) ! Original author(s): Hans Burchard & Karsten Bolding ! ! $Log: cmue_sg.F90,v $ +! Revision 20.0 2013/12/14 00:13:34 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/compute_cpsi3.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/compute_cpsi3.F90 index a092deb35e..b1b15b248f 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/compute_cpsi3.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/compute_cpsi3.F90 @@ -31,6 +31,9 @@ REALTYPE function compute_cpsi3(c1,c2,Ri) ! Original author(s): Hans Burchard, Lars Umlauf ! ! $Log: compute_cpsi3.F90,v $ +! Revision 20.0 2013/12/14 00:13:35 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/dissipationeq.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/dissipationeq.F90 index 4ddcacb4f4..007f367888 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/dissipationeq.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/dissipationeq.F90 @@ -102,6 +102,9 @@ subroutine dissipationeq(nlev,dt,u_taus,u_taub,z0s,z0b,h,NN,SS) ! ! $Log: dissipationeq.F90,v $ +! Revision 20.0 2013/12/14 00:13:37 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/epsbalgebraic.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/epsbalgebraic.F90 index 7ce9889498..be0c723c7c 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/epsbalgebraic.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/epsbalgebraic.F90 @@ -33,6 +33,9 @@ subroutine epsbalgebraic(nlev) ! Original author(s): Lars Umlauf ! ! $Log: epsbalgebraic.F90,v $ +! Revision 20.0 2013/12/14 00:13:38 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies @@ -62,7 +65,7 @@ subroutine epsbalgebraic(nlev) !----------------------------------------------------------------------- !BOC - one_over_ctt=1.0/ctt + one_over_ctt=1.0D0/ctt do i=0,nlev epsb(i) = one_over_ctt*eps(i)/tke(i)*kb(i) diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/fk_craig.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/fk_craig.F90 index 729e8f9acc..c07be37563 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/fk_craig.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/fk_craig.F90 @@ -29,6 +29,9 @@ REALTYPE function fk_craig(u_tau,eta) ! Original author(s): Lars Umlauf ! ! $Log: fk_craig.F90,v $ +! Revision 20.0 2013/12/14 00:13:39 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/genericeq.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/genericeq.F90 index 8c2217c8d5..8c0be03ba6 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/genericeq.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/genericeq.F90 @@ -155,6 +155,9 @@ subroutine genericeq(nlev,dt,u_taus,u_taub,z0s,z0b,h,NN,SS) ! Original author(s): Lars Umlauf and Hans Burchard ! $Log: genericeq.F90,v $ +! Revision 20.0 2013/12/14 00:13:40 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/gotm_lib_version.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/gotm_lib_version.F90 index 8c6c5772f8..0842a938b4 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/gotm_lib_version.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/gotm_lib_version.F90 @@ -20,6 +20,9 @@ subroutine gotm_lib_version(unit) ! Original author(s): Karsten Bolding & Hans Burchard ! ! $Log: gotm_lib_version.F90,v $ +! Revision 20.0 2013/12/14 00:13:41 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/ispralength.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/ispralength.F90 index 1d2588b392..7c115cc728 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/ispralength.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/ispralength.F90 @@ -56,6 +56,9 @@ subroutine ispralength(nlev,NN,h,depth) ! Original author(s): Manuel Ruiz Villarreal, Hans Burchard ! ! $Log: ispralength.F90,v $ +! Revision 20.0 2013/12/14 00:13:43 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/kbalgebraic.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/kbalgebraic.F90 index 6328e94a1a..3a6db7aded 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/kbalgebraic.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/kbalgebraic.F90 @@ -42,6 +42,9 @@ subroutine kbalgebraic(nlev) ! Original author(s): Lars Umlauf ! ! $Log: kbalgebraic.F90,v $ +! Revision 20.0 2013/12/14 00:13:44 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/kbeq.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/kbeq.F90 index 1fba476337..61f4651345 100755 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/kbeq.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/kbeq.F90 @@ -74,6 +74,9 @@ subroutine kbeq(nlev,dt,u_taus,u_taub,z0s,z0b,h,NN,SS) ! Original author(s): Lars Umlauf ! $Log: kbeq.F90,v $ +! Revision 20.0 2013/12/14 00:13:45 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/kpp.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/kpp.F90 index e6b2a4bb74..981e163b3c 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/kpp.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/kpp.F90 @@ -324,6 +324,9 @@ module kpp ! Original author(s): Lars Umlauf ! ! $Log: kpp.F90,v $ +! Revision 20.0 2013/12/14 00:13:46 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies @@ -933,9 +936,9 @@ subroutine interior(nlev,NN,NNT,NNS,SS) shear2 = SS(i) cff = shear2*shear2/(shear2*shear2+16.0E-10) nu_sx = cff*nu_sx -# else +# else KPP_SHEAR nu_sx=_ZERO_ -# endif +# endif KPP_SHEAR #ifdef KPP_INTERNAL_WAVE ! @@ -952,7 +955,7 @@ subroutine interior(nlev,NN,NNT,NNS,SS) #else iwm = _ZERO_ iws = _ZERO_ -#endif +#endif KPP_INTERNAL_WAVE # ifdef KPP_CONVEC @@ -962,9 +965,9 @@ subroutine interior(nlev,NN,NNT,NNS,SS) cff = min(_ONE_,(bvfcon-cff)/bvfcon) nu_sxc = _ONE_-cff*cff nu_sxc = nu_sxc*nu_sxc*nu_sxc -# else +# else KPP_CONVEC nu_sxc = _ZERO_ -# endif +# endif KPP_CONVEC ! ! Sum contributions due to internal wave breaking, shear instability ! and convective diffusivity due to shear instability. @@ -1027,7 +1030,7 @@ subroutine interior(nlev,NN,NNT,NNS,SS) nuh(i)=nuh(i) + nu_ddt nus(i)=nuh(i) + nu_dds -# endif +# endif KPP_DDMIX enddo ! loop over interior points diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/lengthscaleeq.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/lengthscaleeq.F90 index 24ff4428f5..2f75310a41 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/lengthscaleeq.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/lengthscaleeq.F90 @@ -109,6 +109,9 @@ subroutine lengthscaleeq(nlev,dt,depth,u_taus,u_taub,z0s,z0b,h,NN,SS) ! H. Burchard and K. Bolding ! ! $Log: lengthscaleeq.F90,v $ +! Revision 20.0 2013/12/14 00:13:47 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/potentialml.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/potentialml.F90 index 8278b89e32..2de880c466 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/potentialml.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/potentialml.F90 @@ -66,6 +66,9 @@ subroutine potentialml(nlev,z0b,z0s,h,depth,NN) ! Original author(s): Manuel Ruiz Villarreal, Hans Burchard ! ! $Log: potentialml.F90,v $ +! Revision 20.0 2013/12/14 00:13:48 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/production.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/production.F90 index 008fe1235f..5cfda26edb 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/production.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/production.F90 @@ -76,6 +76,9 @@ subroutine production(nlev,NN,SS,xP) ! Original author(s): Karsten Bolding, Hans Burchard ! ! $Log: production.F90,v $ +! Revision 20.0 2013/12/14 00:13:49 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:53 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/q2over2eq.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/q2over2eq.F90 index 27bd120932..2944161ba9 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/q2over2eq.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/q2over2eq.F90 @@ -80,6 +80,9 @@ subroutine q2over2eq(nlev,dt,u_taus,u_taub,z0s,z0b,h,NN,SS) ! Original author(s): Lars Umlauf ! ! $Log: q2over2eq.F90,v $ +! Revision 20.0 2013/12/14 00:13:50 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:54 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/r_ratio.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/r_ratio.F90 index 5dac81d858..8f71206bd3 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/r_ratio.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/r_ratio.F90 @@ -24,6 +24,9 @@ subroutine r_ratio(nlev) ! Original author(s): Lars Umlauf ! ! $Log: r_ratio.F90,v $ +! Revision 20.0 2013/12/14 00:13:51 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:54 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/tkealgebraic.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/tkealgebraic.F90 index bef2e751b6..294ef9ddb0 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/tkealgebraic.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/tkealgebraic.F90 @@ -59,6 +59,9 @@ subroutine tkealgebraic(nlev,u_taus,u_taub,NN,SS) ! Original author(s): Hans Burchard & Karsten Bolding ! ! $Log: tkealgebraic.F90,v $ +! Revision 20.0 2013/12/14 00:13:52 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:54 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/tkeeq.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/tkeeq.F90 index 7f7afbb8ea..5513d21f22 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/tkeeq.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/tkeeq.F90 @@ -95,6 +95,9 @@ subroutine tkeeq(nlev,dt,u_taus,u_taub,z0s,z0b,h,NN,SS) ! H. Burchard and K. Bolding) ! ! $Log: tkeeq.F90,v $ +! Revision 20.0 2013/12/14 00:13:53 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:54 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/turbulence.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/turbulence.F90 index d75e9518c2..61c03a332c 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/turbulence.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/turbulence.F90 @@ -262,6 +262,9 @@ module turbulence ! ! $Log: turbulence.F90,v $ +! Revision 20.0 2013/12/14 00:13:54 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:54 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies @@ -602,15 +605,15 @@ subroutine init_turbulence(namlst,fn,nlev) allocate(num(0:nlev),stat=rc) if (rc /= 0) stop 'init_turbulence: Error allocating (num)' - num = 1.0e-6 + num = 1.0D-6 allocate(nuh(0:nlev),stat=rc) if (rc /= 0) stop 'init_turbulence: Error allocating (nuh)' - nuh = 1.0e-6 + nuh = 1.0D-6 allocate(nus(0:nlev),stat=rc) if (rc /= 0) stop 'init_turbulence: Error allocating (nus)' - nus = 1.0e-6 + nus = 1.0D-6 allocate(gamu(0:nlev),stat=rc) if (rc /= 0) stop 'init_turbulence: Error allocating (gamu)' diff --git a/src/mom5/ocean_param/gotm-4.0/turbulence/variances.F90 b/src/mom5/ocean_param/gotm-4.0/turbulence/variances.F90 index 0ba0104e66..db3a04cc77 100644 --- a/src/mom5/ocean_param/gotm-4.0/turbulence/variances.F90 +++ b/src/mom5/ocean_param/gotm-4.0/turbulence/variances.F90 @@ -62,6 +62,9 @@ subroutine variances(nlev,SSU,SSV) ! Original author(s): Lars Umlauf ! ! $Log: variances.F90,v $ +! Revision 20.0 2013/12/14 00:13:55 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:00:54 smg ! initial cvs ci for these modules to mom5. ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/adv_center.F90 b/src/mom5/ocean_param/gotm-4.0/util/adv_center.F90 index 72cb581051..cc7b8f5a05 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/adv_center.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/adv_center.F90 @@ -200,13 +200,16 @@ subroutine adv_center(N,dt,h,ho,ww,Bcup,Bcdw,Yup,Ydw,method,mode,Y) REALTYPE :: Y(0:N) ! ! !DEFINED PARAMETERS: - REALTYPE, parameter :: one6th=1.0/6.0 + REALTYPE, parameter :: one6th=1.0d0/6.0d0 integer, parameter :: itmax=100 ! ! !REVISION HISTORY: ! Original author(s): Lars Umlauf ! ! $Log: adv_center.F90,v $ +! Revision 20.0 2013/12/14 00:13:57 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/convert_fluxes.F90 b/src/mom5/ocean_param/gotm-4.0/util/convert_fluxes.F90 index f8983fa1dd..892e3283c3 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/convert_fluxes.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/convert_fluxes.F90 @@ -48,6 +48,9 @@ subroutine convert_fluxes(nlev,g,cp,rho_0,heat,p_e,rad,T,S, & ! !REVISION HISTORY: ! Original author(s): Lars Umlauf ! $Log: convert_fluxes.F90,v $ +! Revision 20.0 2013/12/14 00:13:58 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/diff_center.F90 b/src/mom5/ocean_param/gotm-4.0/util/diff_center.F90 index 1e879f2672..2515f87b8d 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/diff_center.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/diff_center.F90 @@ -110,6 +110,9 @@ subroutine diff_center(N,dt,cnpar,posconc,h,Bcup,Bcdw, & ! Original author(s): Lars Umlauf ! ! $Log: diff_center.F90,v $ +! Revision 20.0 2013/12/14 00:13:59 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/diff_face.F90 b/src/mom5/ocean_param/gotm-4.0/util/diff_face.F90 index cd2eb95658..05b369ce8c 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/diff_face.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/diff_face.F90 @@ -60,6 +60,9 @@ subroutine diff_face(N,dt,cnpar,h,Bcup,Bcdw,Yup,Ydw,nuY,Lsour,Qsour,Y) ! Original author(s): Lars Umlauf ! ! $Log: diff_face.F90,v $ +! Revision 20.0 2013/12/14 00:14:00 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/eqstate.F90 b/src/mom5/ocean_param/gotm-4.0/util/eqstate.F90 index 8c4dea0186..689df67217 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/eqstate.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/eqstate.F90 @@ -59,6 +59,9 @@ MODULE eqstate ! Original author(s): Hans Burchard & Karsten Bolding ! ! $Log: eqstate.F90,v $ +! Revision 20.0 2013/12/14 00:14:01 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies @@ -502,24 +505,24 @@ REALTYPE function rho_feistel(s,th,p,UNPress) sqrts = sqrt(s) -anum = 9.9984085444849347e+02 + & - th*( 7.3471625860981584 + & - th*(-5.3211231792841769e-02 + & - th* 3.6492439109814549e-04)) + & - s*( 2.5880571023991390 - & - th* 6.7168282786692355e-03 + & - s* 1.9203202055760151e-03) +anum = 9.9984085444849347d+02 + & + th*( 7.3471625860981584d+00 + & + th*(-5.3211231792841769d-02 + & + th* 3.6492439109814549d-04)) + & + s*( 2.5880571023991390d+00 - & + th* 6.7168282786692355d-03 + & + s* 1.9203202055760151d-03) -aden = 1.0000000000000000 + & - th*( 7.2815210113327091e-03 + & - th*(-4.4787265461983921e-05 + & - th*( 3.3851002965802430e-07 + & - th* 1.3651202389758572e-10))) + & - s*( 1.7632126669040377e-03 - & - th*( 8.8066583251206474e-06 + & - th2* 1.8832689434804897e-10) + & - sqrts*( 5.7463776745432097e-06 + & - th2* 1.4716275472242334e-09)) +aden = 1.0000000000000000d+00 + & + th*( 7.2815210113327091d-03 + & + th*(-4.4787265461983921d-05 + & + th*( 3.3851002965802430d-07 + & + th* 1.3651202389758572d-10))) + & + s*( 1.7632126669040377d-03 - & + th*( 8.8066583251206474d-06 + & + th2* 1.8832689434804897d-10) + & + sqrts*( 5.7463776745432097d-06 + & + th2* 1.4716275472242334d-09)) @@ -527,15 +530,15 @@ REALTYPE function rho_feistel(s,th,p,UNPress) pth = p*th - anum = anum + p*( 1.1798263740430364e-02 + & - th2* 9.8920219266399117e-08 + & - s* 4.6996642771754730e-06 - & - p*( 2.5862187075154352e-08 + & - th2* 3.2921414007960662e-12)) + anum = anum + p*( 1.1798263740430364d-02 + & + th2* 9.8920219266399117d-08 + & + s* 4.6996642771754730d-06 - & + p*( 2.5862187075154352d-08 + & + th2* 3.2921414007960662d-12)) - aden = aden + p*( 6.7103246285651894e-06 - & - pth*(th2* 2.4461698007024582e-17 + & - p* 9.1534417604289062e-18)) + aden = aden + p*( 6.7103246285651894d-06 - & + pth*(th2* 2.4461698007024582d-17 + & + p* 9.1534417604289062d-18)) end if diff --git a/src/mom5/ocean_param/gotm-4.0/util/gridinterpol.F90 b/src/mom5/ocean_param/gotm-4.0/util/gridinterpol.F90 index 416280364a..5f13e9f21c 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/gridinterpol.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/gridinterpol.F90 @@ -27,6 +27,9 @@ subroutine gridinterpol(N,cols,obs_z,obs_prof,nlev,model_z,model_prof) ! !REVISION HISTORY: ! Original author(s): Karsten Bolding & Hans Burchard ! $Log: gridinterpol.F90,v $ +! Revision 20.0 2013/12/14 00:14:02 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/lagrange.F90 b/src/mom5/ocean_param/gotm-4.0/util/lagrange.F90 index ca22f3d4a9..6626a3b599 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/lagrange.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/lagrange.F90 @@ -50,6 +50,9 @@ subroutine lagrange(nlev,dt,zlev,nuh,w,npar,active,zi,zp) ! Original author(s): Hans Burchard & Karsten Bolding ! ! $Log: lagrange.F90,v $ +! Revision 20.0 2013/12/14 00:14:03 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/ode_solvers.F90 b/src/mom5/ocean_param/gotm-4.0/util/ode_solvers.F90 index fd1fa9f226..7f9164cae0 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/ode_solvers.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/ode_solvers.F90 @@ -1070,7 +1070,7 @@ subroutine right_hand_side(first,numc,nlev,cc,rhs) first=.false. do ci=1,nlev - call findp_bisection(numc, cc(:,ci), derivative(:,ci), dt, 1.e-9, pi) + call findp_bisection(numc, cc(:,ci), derivative(:,ci), dt, 1.d-9, pi) cc(:,ci) = cc(:,ci) + dt*derivative(:,ci)*pi end do @@ -1152,7 +1152,7 @@ subroutine right_hand_side(first,numc,nlev,cc,rhs) first=.false. do ci=1,nlev - call findp_bisection(numc, cc(:,ci), rhs(:,ci), dt, 1.e-9, pi) + call findp_bisection(numc, cc(:,ci), rhs(:,ci), dt, 1.d-9, pi) cc_med(:,ci) = cc(:,ci) + dt*rhs(:,ci)*pi end do @@ -1166,7 +1166,7 @@ subroutine right_hand_side(first,numc,nlev,cc,rhs) if (rhs(i,ci) .lt. 0.) rhs(:,ci) = rhs(:,ci) * cc(i,ci)/cc_med(i,ci) end do - call findp_bisection(numc, cc(:,ci), rhs(:,ci), dt, 1.e-9, pi) + call findp_bisection(numc, cc(:,ci), rhs(:,ci), dt, 1.d-9, pi) cc(:,ci) = cc(:,ci) + dt*rhs(:,ci)*pi end do ! ci (z-levels) diff --git a/src/mom5/ocean_param/gotm-4.0/util/time.F90 b/src/mom5/ocean_param/gotm-4.0/util/time.F90 index 3609c4af57..6f5e05e05d 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/time.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/time.F90 @@ -45,6 +45,9 @@ MODULE time ! !REVISION HISTORY: ! Original author(s): Karsten Bolding & Hans Burchard ! $Log: time.F90,v $ +! Revision 20.0 2013/12/14 00:14:05 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/tridiagonal_gotm.F90 b/src/mom5/ocean_param/gotm-4.0/util/tridiagonal_gotm.F90 index a0358b97a1..68c659e9a7 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/tridiagonal_gotm.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/tridiagonal_gotm.F90 @@ -21,6 +21,9 @@ MODULE mtridiagonal ! !REVISION HISTORY: ! Original author(s): Hans Burchard & Karsten Bolding ! $Log: tridiagonal_gotm.F90,v $ +! Revision 20.0 2013/12/14 00:14:06 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies @@ -154,6 +157,9 @@ subroutine tridiagonal(N,fi,lt,value) ! !REVISION HISTORY: ! Original author(s): Hans Burchard & Karsten Bolding ! $Log: tridiagonal_gotm.F90,v $ +! Revision 20.0 2013/12/14 00:14:06 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/gotm-4.0/util/util.F90 b/src/mom5/ocean_param/gotm-4.0/util/util.F90 index 2aca76cac8..0fd5ed2f67 100644 --- a/src/mom5/ocean_param/gotm-4.0/util/util.F90 +++ b/src/mom5/ocean_param/gotm-4.0/util/util.F90 @@ -58,6 +58,9 @@ MODULE util ! Original author(s): Lars Umlauf ! ! $Log: util.F90,v $ +! Revision 20.0 2013/12/14 00:14:07 fms +! Merged revision 1.1.2.1 onto trunk +! ! Revision 1.1.2.1 2012/05/15 16:01:18 smg ! initial cvs ci to mom5 ! AUTHOR:Griffies diff --git a/src/mom5/ocean_param/lateral/ocean_bih_friction.F90 b/src/mom5/ocean_param/lateral/ocean_bih_friction.F90 index f65568e047..607f1d4489 100644 --- a/src/mom5/ocean_param/lateral/ocean_bih_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_bih_friction.F90 @@ -116,9 +116,9 @@ module ocean_bih_friction_mod integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk character(len=256) :: version=& - '=>Using: ocean_bih_friction.f90 ($Id: ocean_bih_friction.F90,v 1.1.2.2 2012/05/29 03:34:52 Stephen.Griffies Exp $)' + '=>Using: ocean_bih_friction.f90 ($Id: ocean_bih_friction.F90,v 20.0 2013/12/14 00:14:08 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .false. logical :: write_a_restart = .true. diff --git a/src/mom5/ocean_param/lateral/ocean_bih_friction.html b/src/mom5/ocean_param/lateral/ocean_bih_friction.html deleted file mode 100644 index 4e94f5a22d..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bih_friction.html +++ /dev/null @@ -1,273 +0,0 @@ - - - -Module ocean_bih_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_bih_friction_mod
- - - - - -
-OVERVIEW
- -- This module calls the appropriate lateral biharmonic friction modules. -
- - - -- This module serves as an interface to the chosen lateral - biharmonic friction modules. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_bihcgrid_friction_mod
ocean_bihcst_friction_mod
ocean_bihgen_friction_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_bih_friction_init:
- -- -bih_friction:
- -- -bih_viscosity_check:
- -- -bih_reynolds_check:
- -- -bih_friction_barotropic:
- -- -ocean_bih_friction_restart:
- -- -ocean_bih_friction_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_bih_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal biharmonic friction module. -
-
-
-- - -
-bih_friction
--
-- -DESCRIPTION -
-- - Compute the thickness weighted and density weighted accel due to - lateral biharmonic friction. Add this contribution to Velocity%accel. -
-
-
-- - -
-bih_viscosity_check
--
-- -DESCRIPTION -
-- - To check that the viscosity is not too large. -
-
-
-- - -
-bih_reynolds_check
--
-- -DESCRIPTION -
-- - To check that the Reynolds number is not too large. -
-
-
-- - -
-bih_friction_barotropic
--
-- -DESCRIPTION -
-- - - This routine computes the biharmonic friction acting on a two-dim - array. It uses the two-dimensional vertically averaged viscosity - used in the biharmonic friction module. The intent is to apply this - 2d operator to the vertically integrated horizontal momentum. We - ignore the spherical metric terms in this form of the operator, - since we are aiming for a fast smoothing operator to be applied - during each of the many barotropic time steps. We also apply - just the isotropic portion of the more general anisotropic - biharmonic operator. - - This method has only been implemented for Bgrid MOM. It is - rarely used and remains only for legacy. - -
-
-
-- - -
-ocean_bih_friction_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_bih_friction_end
--
-- -DESCRIPTION -
-- - Write to restart of the vertically averaged viscosity. -
-
-
-
-NAMELIST
- --&ocean_bih_friction_nml --
-
----
-- -bih_friction_scheme -
-- To determine the biharmonic friction scheme: "const" or "general" -
-
-[character] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -
- - - - -
-NOTES
- -- The model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_bih_friction.xml b/src/mom5/ocean_param/lateral/ocean_bih_friction.xml deleted file mode 100644 index e452410a16..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bih_friction.xml +++ /dev/null @@ -1,51 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_bih_tracer.F90 b/src/mom5/ocean_param/lateral/ocean_bih_tracer.F90 index b0f500092d..4d362978df 100644 --- a/src/mom5/ocean_param/lateral/ocean_bih_tracer.F90 +++ b/src/mom5/ocean_param/lateral/ocean_bih_tracer.F90 @@ -108,9 +108,9 @@ module ocean_bih_tracer_mod integer :: id_ah_biharmonic character(len=128) :: version=& - '=>Using: /bih/ocean_bih_tracer.F90 ($Id: ocean_bih_tracer.F90,v 1.1.2.2 2012/06/01 20:47:08 Stephen.Griffies Exp $)' + '=>Using: /bih/ocean_bih_tracer.F90 ($Id: ocean_bih_tracer.F90,v 20.0 2013/12/14 00:14:10 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' type(ocean_grid_type), pointer :: Grd => NULL() type(ocean_domain_type), pointer :: Dom => NULL() diff --git a/src/mom5/ocean_param/lateral/ocean_bih_tracer.html b/src/mom5/ocean_param/lateral/ocean_bih_tracer.html deleted file mode 100644 index 9f2d98fe21..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bih_tracer.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - Stephen M. Griffies - - This module calls the appropriate lateral biharmonic friction modules. - - This module serves as an interface to the chosen lateral - biharmonic friction modules. - - The model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. - - To determine the biharmonic friction scheme: "const" or "general" - - For debugging. - - Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. - - Initialize the horizontal biharmonic friction module. - - Compute the thickness weighted and density weighted accel due to - lateral biharmonic friction. Add this contribution to Velocity%accel. - - To check that the viscosity is not too large. - - To check that the Reynolds number is not too large. - - - This routine computes the biharmonic friction acting on a two-dim - array. It uses the two-dimensional vertically averaged viscosity - used in the biharmonic friction module. The intent is to apply this - 2d operator to the vertically integrated horizontal momentum. We - ignore the spherical metric terms in this form of the operator, - since we are aiming for a fast smoothing operator to be applied - during each of the many barotropic time steps. We also apply - just the isotropic portion of the more general anisotropic - biharmonic operator. - - This method has only been implemented for Bgrid MOM. It is - rarely used and remains only for legacy. - - - Write out restart files registered through register_restart_file - - Write to restart of the vertically averaged viscosity. - Module ocean_bih_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_bih_tracer_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted and density weighted time tendency - for tracer from biharmonic tracer mixing. -
- - - -- There are two main options for computing the fluxes. - - (1) The lateral fluxes can be aligned with the z-coordinate surfaces, - in which case the fluxes must be approximated if (i) we use non-geopotential - vertical coordinates, (ii) next to partial bottom step topography. - This form of the diffusion is not recommended since it can lead to - the creation of spurious extrema. - - (2) The lateral fluxes can be aligned surfaces of constant vertical - coordinate. In this case the fluxes are no longer strictly "horizontal." - Howerver, the operator is simpler and it ensures that no suprious - extrema are created. It is for this reason that the simpler operator - is preferred. - - The diffusivity used to determine the strength of the tendency can be - a general function of space yet it is constant in time. A namelist - option exists that determines this diffusivity as a local function - of the grid spacing. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_operators_mod
ocean_obc_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_bih_tracer_init:
- -- -bih_tracer:
- -- -delsq_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_bih_tracer_init
--
-- -DESCRIPTION -
-- - Initialize the biharmonic tracer mixing module by - registering fields for diagnostic output and performing some - numerical checks to see that diffusivity is set appropriately. -
-
-
-- - -
-bih_tracer
--
-- -DESCRIPTION -
-- - This function computes the thickness weighted and density weighted - time tendency for tracer from biharmonic mixing. -
-
-
-- - -
-delsq_tracer
--
-- -DESCRIPTION -
-- - Subroutine computes the laplacian operator acting on tracer with unit - diffusivity. Units of del2_tracer are tracer/length^2 -
-
-
-
-NAMELIST
- --&ocean_bih_tracer_nml --
-
----
-- -use_this_module -
-- Must be true to use this module -
-
-[logical] -- -horz_z_diffuse -
-- To compute fluxes along surfaces of constant depth. - This operation must necessarily be approximate for the two - cases (i) non-geopotential vertical coordinates, (2) - next to partial bottom step topography. There are cases where - use of this operator can lead to spurious creation of extrema - due to truncation errors associated with the "slope" term. - The option to use horz_z_diffuse=.true. is maintained for - legacy purposes alone. -
-
-[logical] -- -horz_s_diffuse -
-- To compute diffusion along surfaces of constant vertical s-coordinate. -
-
-[logical] -- -abih -
-- This is the value for the space-time constant biharmonic diffusivity. -
-
-[real, units: m^4/sec] -- -tracer_mix_micom -
-- If .true., then the diffusivity is set according to a velocity scale times - the cube of the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model. -
-
-[logical] -- -vel_micom -
-- Velocity scale that is used for computing the MICOM diffusivity. -
-
-[real, units: m/sec] -- -read_diffusivity_mask -
-- Allows for reading of a mask that to apply diffusivity - only in selected regions. - Default read_diffusivity_mask=.false. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_bih_tracer.xml b/src/mom5/ocean_param/lateral/ocean_bih_tracer.xml deleted file mode 100644 index 4cbb120f80..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bih_tracer.xml +++ /dev/null @@ -1,62 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.F90 b/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.F90 index 0d709b83b9..421fad9e53 100644 --- a/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.F90 @@ -215,7 +215,6 @@ module ocean_bihcgrid_friction_mod integer :: id_cos2theta =-1 integer :: id_neptune_bih_u =-1 integer :: id_neptune_bih_v =-1 -integer :: id_neptune_psi =-1 integer :: id_ncar_rescale =-1 integer :: id_along =-1 integer :: id_across =-1 @@ -339,9 +338,9 @@ module ocean_bihcgrid_friction_mod type(ocean_domain_type), pointer :: Dom => NULL() character(len=256) :: version=& - '=>Using: ocean_bihcgrid_friction.F90 ($Id: ocean_bihcgrid_friction.F90,v 1.1.2.7.20.1 2013/04/03 13:25:24 smg Exp $)' + '=>Using: ocean_bihcgrid_friction.F90 ($Id: ocean_bihcgrid_friction.F90,v 20.0 2013/12/14 00:14:12 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_201303_smg $' + '$Name: tikal $' logical :: use_this_module = .false. logical :: debug_this_module = .false. diff --git a/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.html b/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.html deleted file mode 100644 index 39fe67af3a..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.html +++ /dev/null @@ -1,560 +0,0 @@ - - - - Stephen M. Griffies - - Thickness weighted and density weighted time tendency - for tracer from biharmonic tracer mixing. - - There are two main options for computing the fluxes. - - (1) The lateral fluxes can be aligned with the z-coordinate surfaces, - in which case the fluxes must be approximated if (i) we use non-geopotential - vertical coordinates, (ii) next to partial bottom step topography. - This form of the diffusion is not recommended since it can lead to - the creation of spurious extrema. - - (2) The lateral fluxes can be aligned surfaces of constant vertical - coordinate. In this case the fluxes are no longer strictly "horizontal." - Howerver, the operator is simpler and it ensures that no suprious - extrema are created. It is for this reason that the simpler operator - is preferred. - - The diffusivity used to determine the strength of the tendency can be - a general function of space yet it is constant in time. A namelist - option exists that determines this diffusivity as a local function - of the grid spacing. - - Must be true to use this module - - To compute fluxes along surfaces of constant depth. - This operation must necessarily be approximate for the two - cases (i) non-geopotential vertical coordinates, (2) - next to partial bottom step topography. There are cases where - use of this operator can lead to spurious creation of extrema - due to truncation errors associated with the "slope" term. - The option to use horz_z_diffuse=.true. is maintained for - legacy purposes alone. - - To compute diffusion along surfaces of constant vertical s-coordinate. - - This is the value for the space-time constant biharmonic diffusivity. - - If .true., then the diffusivity is set according to a velocity scale times - the cube of the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model. - - Velocity scale that is used for computing the MICOM diffusivity. - - Allows for reading of a mask that to apply diffusivity - only in selected regions. - Default read_diffusivity_mask=.false. - - Initialize the biharmonic tracer mixing module by - registering fields for diagnostic output and performing some - numerical checks to see that diffusivity is set appropriately. - - This function computes the thickness weighted and density weighted - time tendency for tracer from biharmonic mixing. - - Subroutine computes the laplacian operator acting on tracer with unit - diffusivity. Units of del2_tracer are tracer/length^2 - Module ocean_bihcgrid_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_bihcgrid_friction_mod
- - - - - -
-OVERVIEW
- -- This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal biharmonic friction. - Friction is formulated for the C-grid here. -
- - - -- This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal biharmonic friction. - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach; a grid-scale dependent - background viscosity; or other options. - The form of the friction operator can be isotropic or - anisotropic in the horizontal plane. - - Friction is formulated for the C-grid in this module. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_bihcgrid_friction_init:
- -- -bihcgrid_friction:
- -- -ncar_boundary_scale_read:
- -- -ncar_boundary_scale_create:
- -- -bihcgrid_viscosity_check:
- -- -bihcgrid_reynolds_check:
- -- -compute_neptune_velocity:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_bihcgrid_friction_init
--
-- -DESCRIPTION -
-- - Initialize the lateral biharmonic friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. -
-
-
-- - -
-bihcgrid_friction
--
-- -DESCRIPTION -
-- - This routine computes thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - biharmonic friction. - - The algorithm is derived from a functional approach that ensures - kinetic energy is consistenty dissipated for all flow configurations. - The stencil is far simpler than the B-grid approach. In particular, - there are no triads here for the C-grid. - - Fundamental to the scheme are the rates of horizontal deformation - horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y - horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x - Units of the tension and strain are sec^-1. - - As shown in Griffies and Hallberg (2000), - a biharmonic operator with a nonconstant viscosity is guaranteed to - dissipate kinetic energy *only* when using the sqrt of the biharmonic - viscosity at each of the two stages of the algorithm. - The sqrt approach is employed here. - -
-
-
-- - -
-ncar_boundary_scale_read
--
-- -DESCRIPTION -
-- - - Read in the 3d ncar boundary scaling field and use this to - rescale the background viscosities. - - To use this routine, we need to already have generated the field - ncar_rescale using the routine ncar_boundary_scale_create. - - The advantage of reading ncar_rescale is that we do not need to - introduce any global 2d arrays required for ncar_boundary_scale_create. - So the idea is to pay the price once by running ncar_boundary_scale_create, - save ncar_rescale, then read that field in during subsequent runs through - ncar_boundary_scale_read. - - Here are the steps: - 1/ run one time with ncar_boundary_scaling_read=.false. - and ncar_boundary_scaling=.true. - Be sure that the field ncar_rescale is saved in diagnostic table. - To ensure answers agree whether reading ncar_rescale or creating it - during initialization, it is necessary to save ncar_rescale using the - double precision option in the diagnostic table (packing=1). - - 2/ extract field ncar_rescale from the diagnostics output - and place into its own file INPUT/ncar_rescale.nc - example extraction using ncks: - ncks -v ncar_rescale 19900101.ocean_month.nc ncar_rescale.nc - - 3/ set ncar_boundary_scaling_read=.true. - and ncar_boundary_scaling=.true., and now run the model - reading in ncar_rescale rather than regenerating - it during each initialization (which can be a bottleneck - for large models on huge processor counts). - - 4/ As a check that all is fine, save ncar_rescale as a diagnostic - for both the create and the read stage and make sure they agree. - Also, all checksums should agree whether reading in ncar_rescale - or creating it each initialization, so long as the ncar_rescale.nc - was saved with double precision (see step 1/ above). - -
-
-
-- - -
-ncar_boundary_scale_create
--
-- -DESCRIPTION -
-- - - Recale the background viscosities to be larger in the western - boundary regions. The algorithm is taken directly from the - anisotropic_ncar routine in ocean_lapgen_friction.F90. - - NOTE: The nearest western boundary computations are done along the - model i-grid lines. Therefore, viscosity based on these are - only approximate in the high Northern Hemisphere when using - generalized coordinates with coordinate pole(s) shifted onto - land. - -
-
-
-- - -
-bihcgrid_viscosity_check
--
-- -DESCRIPTION -
-- - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. -
-
-
-- - -
-bihcgrid_reynolds_check
--
-- -DESCRIPTION -
-- - Subroutine to compute the biharmonic grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. -
-
-
-- - -
-compute_neptune_velocity
--
-- -DESCRIPTION -
-- - Compute Neptune velocity. - - Method follows that of - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - This approach is slightly different than the Eby and Holloway - method implemented in the laplacian module. There is no fundamental - reason to favor one versus the other. We use the Maltrud and - Holloway method here sinc they implemented it for biharmonic. - - May 2012 - Stephen.Griffies - -
-
-
-
-NAMELIST
- --&ocean_bihcgrid_friction_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging by printing checksums. -
-
-[logical] -- -k_smag_iso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. -
-
-[real, units: dimensionless] -- -k_smag_aniso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. -
-
-[real, units: dimensionless] -- -vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity. -
-
-[real, units: m/sec] -- -vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity. -
-
-[real, units: m/sec] -- -equatorial_zonal -
-- Orient the anisotropic friction within a latitudinal band according to zonal direction. -
-
-[logical] -- -equatorial_zonal_lat -
-- Latitudinal band to use the zonal friction orientation. -
-
-[real] -- -equatorial_no_smag -
-- Turn smag off within equatorial_zonal_lat region. -
-
-[logical] -- -eq_vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity within - a user specified equatorial band. -
-
-[real] -- -eq_vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity within - a user specified equatorial band. -
-
-[real] -- -eq_lat_micom -
-- Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom_iso and eq_vel_micom_aniso. -
-
-[real] -- -neptune -
-- Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. -
-
-[logical] -- -neptune_length_eq -
-- Length scale used to compute Neptune velocity at equator. -
-
-[real, units: m] -- -neptune_length_pole -
-- Length scale used to compute Neptune velocity at pole. -
-
-[real, units: m] -- -neptune_depth_min -
-- Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 -
-
-[real, units: m] -- -neptune_smooth -
-- For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. -
-
-[logical] -- -neptune_smooth_num -
-- Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. -
-
-[integer] -- -use_side_drag_friction -
-- For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. -
-
-[logical] -- -side_drag_friction_scaling -
-- Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. -
-
-[real] -- -side_drag_friction_uvmag_max -
-- Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. -
-
-[real, units: m/s] -- -side_drag_friction_max -
-- Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations - in ocean_bbc. Default side_drag_friction_max=1.0. -
-
-[real, units: N/m^2] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use in large-scale - eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946 -
-- - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
-- - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
-- - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
-- - Griffies: Elements of MOM (2012) -
-
- - -
-NOTES
- -- The ocean model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some simulations. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.xml b/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.xml deleted file mode 100644 index 60469c0fa5..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bihcgrid_friction.xml +++ /dev/null @@ -1,209 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_bihcst_friction.F90 b/src/mom5/ocean_param/lateral/ocean_bihcst_friction.F90 index 73d3dd5971..1ef65e688d 100644 --- a/src/mom5/ocean_param/lateral/ocean_bihcst_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_bihcst_friction.F90 @@ -137,10 +137,10 @@ module ocean_bihcst_friction_mod integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk character(len=256) :: version=& - '=>Using: ocean_bihcst_friction.f90 ($Id: ocean_bihcst_friction.F90,v 1.1.2.4 2012/06/08 20:15:35 Stephen.Griffies Exp $)' + '=>Using: ocean_bihcst_friction.f90 ($Id: ocean_bihcst_friction.F90,v 20.0 2013/12/14 00:14:14 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. logical :: use_this_module = .false. diff --git a/src/mom5/ocean_param/lateral/ocean_bihcst_friction.html b/src/mom5/ocean_param/lateral/ocean_bihcst_friction.html deleted file mode 100644 index 6f6c3d2ef7..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bihcst_friction.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - S. M. Griffies - - This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal biharmonic friction. - Friction is formulated for the C-grid here. - - This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal biharmonic friction. - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach; a grid-scale dependent - background viscosity; or other options. - The form of the friction operator can be isotropic or - anisotropic in the horizontal plane. - - Friction is formulated for the C-grid in this module. - - - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use in large-scale - eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946 - - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. - - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. - - Griffies: Elements of MOM (2012) - - The ocean model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some simulations. - - Must be true to use this module. Default is false. - - For debugging by printing checksums. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. - - Velocity scale that is used for computing the MICOM isotropic viscosity. - - Velocity scale that is used for computing the MICOM anisotropic viscosity. - - Orient the anisotropic friction within a latitudinal band according to zonal direction. - - Latitudinal band to use the zonal friction orientation. - - Turn smag off within equatorial_zonal_lat region. - - Velocity scale that is used for computing the MICOM isotropic viscosity within - a user specified equatorial band. - - Velocity scale that is used for computing the MICOM anisotropic viscosity within - a user specified equatorial band. - - Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom_iso and eq_vel_micom_aniso. - - Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. - - Length scale used to compute Neptune velocity at equator. - - Length scale used to compute Neptune velocity at pole. - - Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 - - For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. - - Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. - - For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. - - Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. - - Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. - - Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations - in ocean_bbc. Default side_drag_friction_max=1.0. - - Initialize the lateral biharmonic friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. - - This routine computes thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - biharmonic friction. - - The algorithm is derived from a functional approach that ensures - kinetic energy is consistenty dissipated for all flow configurations. - The stencil is far simpler than the B-grid approach. In particular, - there are no triads here for the C-grid. - - Fundamental to the scheme are the rates of horizontal deformation - horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y - horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x - Units of the tension and strain are sec^-1. - - As shown in Griffies and Hallberg (2000), - a biharmonic operator with a nonconstant viscosity is guaranteed to - dissipate kinetic energy *only* when using the sqrt of the biharmonic - viscosity at each of the two stages of the algorithm. - The sqrt approach is employed here. - - - - Read in the 3d ncar boundary scaling field and use this to - rescale the background viscosities. - - To use this routine, we need to already have generated the field - ncar_rescale using the routine ncar_boundary_scale_create. - - The advantage of reading ncar_rescale is that we do not need to - introduce any global 2d arrays required for ncar_boundary_scale_create. - So the idea is to pay the price once by running ncar_boundary_scale_create, - save ncar_rescale, then read that field in during subsequent runs through - ncar_boundary_scale_read. - - Here are the steps: - 1/ run one time with ncar_boundary_scaling_read=.false. - and ncar_boundary_scaling=.true. - Be sure that the field ncar_rescale is saved in diagnostic table. - To ensure answers agree whether reading ncar_rescale or creating it - during initialization, it is necessary to save ncar_rescale using the - double precision option in the diagnostic table (packing=1). - - 2/ extract field ncar_rescale from the diagnostics output - and place into its own file INPUT/ncar_rescale.nc - example extraction using ncks: - ncks -v ncar_rescale 19900101.ocean_month.nc ncar_rescale.nc - - 3/ set ncar_boundary_scaling_read=.true. - and ncar_boundary_scaling=.true., and now run the model - reading in ncar_rescale rather than regenerating - it during each initialization (which can be a bottleneck - for large models on huge processor counts). - - 4/ As a check that all is fine, save ncar_rescale as a diagnostic - for both the create and the read stage and make sure they agree. - Also, all checksums should agree whether reading in ncar_rescale - or creating it each initialization, so long as the ncar_rescale.nc - was saved with double precision (see step 1/ above). - - - - Recale the background viscosities to be larger in the western - boundary regions. The algorithm is taken directly from the - anisotropic_ncar routine in ocean_lapgen_friction.F90. - - NOTE: The nearest western boundary computations are done along the - model i-grid lines. Therefore, viscosity based on these are - only approximate in the high Northern Hemisphere when using - generalized coordinates with coordinate pole(s) shifted onto - land. - - - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. - - Subroutine to compute the biharmonic grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. - - Compute Neptune velocity. - - Method follows that of - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - This approach is slightly different than the Eby and Holloway - method implemented in the laplacian module. There is no fundamental - reason to favor one versus the other. We use the Maltrud and - Holloway method here sinc they implemented it for biharmonic. - - May 2012 - Stephen.Griffies - - Module ocean_bihcst_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_bihcst_friction_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted and density weighted time tendency for velocity - from horizontal biharmonic friction -
- - - -- This module computes the thickness and density weighted time tendency - for horizontal velocity arising from horizontal biharmonic friction. - The viscosity used to determine the strength of the tendency - can be a general function of space yet it is constant in time. - A namelist option exists that determines this viscosity - as a local function of the grid spacing. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_bihcst_friction_init:
- -- -bihcst_friction:
- -- -delsq_velocity:
- -- -bihcst_viscosity_check:
- -- -bihcst_reynolds_check:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_bihcst_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal biharmonic friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. -
-
-
-- - -
-bihcst_friction
--
-- -DESCRIPTION -
-- - This subroutine computes the thickness weighted acceleration on - horizontal velocity arising from horizontal biharmonic friction. -
-
-
-- - -
-delsq_velocity
--
-- -DESCRIPTION -
-- - Subroutine computes the laplacian operator acting on velocity. -
-
-
-- - -
-bihcst_viscosity_check
--
-- -DESCRIPTION -
-- - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. -
-
-
-- - -
-bihcst_reynolds_check
--
-- -DESCRIPTION -
-- - Subroutine to compute the biharmonic grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. -
-
-
-
-NAMELIST
- --&ocean_bihcst_friction_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging by printing checksums. -
-
-[logical] -- -abih -
-- This is the value for the space-time constant biharmonic viscosity. -
-
-[real, units: m^4/sec] -- -velocity_mix_micom -
-- If .true., then the viscosity is set according to a velocity scale times - the cube of the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model. -
-
-[logical] -- -vel_micom -
-- Velocity scale that is used for computing the MICOM viscosity. -
-
-[real, units: m/sec] -- -eq_vel_micom -
-- Velocity scale that is used for computing the MICOM viscosity within a latitude - band surrounding the equator. This is useful for some models of enhanced equatorial - resolution that can maintain numerical integrity in this region with less friction - than outside the tropical band. -
-
-[real, units: m/sec] -- -eq_lat_micom -
-- Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom. -
-
-[real] -
- - - - -
-REFERENCES
- ----
-- - R. J. Murray and C.J.C. Reason, - A curvilinear version of the Bryan-Cox ocean model - Journal Computational Physics (2002), vol 171, pages 1-46 -
-- - Elements of MOM (2012), S.M. Griffies -
-
- - -
-NOTES
- -- The numerical implementation requires one call to mpp_update_domains if - running the model with halo=1. --
-
- This scheme has been found to be faster than the Smagorinsky viscosity - scheme. However, the algorithm here is less robust since it - contains null modes in the terms associated with the sphericity - of the earth. Hence, there may be flow configurations that are - not dissipated. -
-
- The model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. -
-
- The numerical implementation in mom4p1 and mom5 does not include the sink due - to partial bottom cells. This sink was implemented in mom2 and mom3 - and mom4. It is not known how relevant this sink is. -
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_bihcst_friction.xml b/src/mom5/ocean_param/lateral/ocean_bihcst_friction.xml deleted file mode 100644 index 46227e343d..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bihcst_friction.xml +++ /dev/null @@ -1,74 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_bihgen_friction.F90 b/src/mom5/ocean_param/lateral/ocean_bihgen_friction.F90 index a718ab5a80..d069923e18 100644 --- a/src/mom5/ocean_param/lateral/ocean_bihgen_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_bihgen_friction.F90 @@ -415,9 +415,9 @@ module ocean_bihgen_friction_mod type(ocean_domain_type), pointer :: Dom => NULL() character(len=256) :: version=& - '=>Using: ocean_bihgen_friction.F90 ($Id: ocean_bihgen_friction.F90,v 1.1.2.5.14.1 2013/04/03 13:25:25 smg Exp $)' + '=>Using: ocean_bihgen_friction.F90 ($Id: ocean_bihgen_friction.F90,v 20.0 2013/12/14 00:14:16 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_201303_smg $' + '$Name: tikal $' logical :: use_this_module = .false. logical :: debug_this_module = .false. diff --git a/src/mom5/ocean_param/lateral/ocean_bihgen_friction.html b/src/mom5/ocean_param/lateral/ocean_bihgen_friction.html deleted file mode 100644 index 64c94356f5..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bihgen_friction.html +++ /dev/null @@ -1,742 +0,0 @@ - - - - Stephen M. Griffies - - Thickness weighted and density weighted time tendency for velocity - from horizontal biharmonic friction - - This module computes the thickness and density weighted time tendency - for horizontal velocity arising from horizontal biharmonic friction. - The viscosity used to determine the strength of the tendency - can be a general function of space yet it is constant in time. - A namelist option exists that determines this viscosity - as a local function of the grid spacing. - - R. J. Murray and C.J.C. Reason, - A curvilinear version of the Bryan-Cox ocean model - Journal Computational Physics (2002), vol 171, pages 1-46 - - Elements of MOM (2012), S.M. Griffies - - The numerical implementation requires one call to mpp_update_domains if - running the model with halo=1. - - This scheme has been found to be faster than the Smagorinsky viscosity - scheme. However, the algorithm here is less robust since it - contains null modes in the terms associated with the sphericity - of the earth. Hence, there may be flow configurations that are - not dissipated. - - The model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. - - The numerical implementation in mom4p1 and mom5 does not include the sink due - to partial bottom cells. This sink was implemented in mom2 and mom3 - and mom4. It is not known how relevant this sink is. - - Must be true to use this module. Default is false. - - For debugging by printing checksums. - - This is the value for the space-time constant biharmonic viscosity. - - If .true., then the viscosity is set according to a velocity scale times - the cube of the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model. - - Velocity scale that is used for computing the MICOM viscosity. - - Velocity scale that is used for computing the MICOM viscosity within a latitude - band surrounding the equator. This is useful for some models of enhanced equatorial - resolution that can maintain numerical integrity in this region with less friction - than outside the tropical band. - - Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom. - - Initialize the horizontal biharmonic friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. - - This subroutine computes the thickness weighted acceleration on - horizontal velocity arising from horizontal biharmonic friction. - - Subroutine computes the laplacian operator acting on velocity. - - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. - - Subroutine to compute the biharmonic grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. - Module ocean_bihgen_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_bihgen_friction_mod
- - - - - -
-OVERVIEW
- -- This module computes thickness weighted and density weighted - time tendency for horizontal velocity arising from - biharmonic friction. -
- - - -- This module computes thickness weighted and density weighted - time tendency for horizontal velocity arising from biharmonic - friction. - - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach as well as a grid-scale dependent - background viscosity. The form of the friction operator - can be isotropic or anisotropic in the lateral plane. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_bihgen_friction_init:
- -- -bihgen_friction:
- -- -ncar_boundary_scale_read:
- -- -ncar_boundary_scale_create:
- -- -BDX_EU_smag:
- -- -BDY_NU_smag:
- -- -bihgen_viscosity_check:
- -- -bihgen_reynolds_check:
- -- -compute_neptune_velocity:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_bihgen_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal biharmonic friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. -
-
-
-- - -
-bihgen_friction
--
-- -DESCRIPTION -
-- - This subroutine computes the time tendency for horizontal - velocity (i.e., the acceleration) from horizontal biharmonic friction. - The algorithm is derived from a functional approach that ensures kinetic - energy is consistenty dissipated for all flow configurations. - The triad do-loops are expanded in order to enhance the - ability of cache-based machines to keep most of the variables - on-cache. - - Fundamental to the scheme are the rates of horizontal deformation
-
- horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y
- horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x
- Units of the tension and strain are sec^-1. - - Four tensions and four strains are computed for each velocity point,
- corresponding to the four triads surrounding the point.
- The following notation is used to distinguish the triads:
- (0,1)=northwest triad (1,1)=northeast triad,
- (0,0)=southwest triad, (1,0)=southeast triad - - A triad contributes when at least one of its velocities is - not a land point. In order to obtain the correct tension - and strain next to boundaries, tension and strain should not be - masked with umask. - - As shown in Griffies and Hallberg (2000), - a biharmonic operator with a nonconstant viscosity is guaranteed to - dissipate kinetic energy *only* when using the sqrt of the biharmonic - viscosity at each of the two stages of the algorithm. - The sqrt approach is employed here. - -
-
-- - -
-ncar_boundary_scale_read
--
-- -DESCRIPTION -
-- - - Read in the 3d ncar boundary scaling field and use this to - rescale the background viscosities. - - To use this routine, we need to already have generated the field - ncar_rescale using the routine ncar_boundary_scale_create. - - The advantage of reading ncar_rescale is that we do not need to - introduce any global 2d arrays required for ncar_boundary_scale_create. - So the idea is to pay the price once by running ncar_boundary_scale_create, - save ncar_rescale, then read that field in during subsequent runs through - ncar_boundary_scale_read. - - Here are the steps: - 1/ run one time with ncar_boundary_scaling_read=.false. - and ncar_boundary_scaling=.true. - Be sure that the field ncar_rescale is saved in diagnostic table. - To ensure answers agree whether reading ncar_rescale or creating it - during initialization, it is necessary to save ncar_rescale using the - double precision option in the diagnostic table (packing=1). - - 2/ extract field ncar_rescale from the diagnostics output - and place into its own file INPUT/ncar_rescale.nc - example extraction using ncks: - ncks -v ncar_rescale 19900101.ocean_month.nc ncar_rescale.nc - - 3/ set ncar_boundary_scaling_read=.true. - and ncar_boundary_scaling=.true., and now run the model - reading in ncar_rescale rather than regenerating - it during each initialization (which can be a bottleneck - for large models on huge processor counts). - - 4/ As a check that all is fine, save ncar_rescale as a diagnostic - for both the create and the read stage and make sure they agree. - Also, all checksums should agree whether reading in ncar_rescale - or creating it each initialization, so long as the ncar_rescale.nc - was saved with double precision (see step 1/ above). - -
-
-
-- - -
-ncar_boundary_scale_create
--
-- -DESCRIPTION -
-- - - Recale the background viscosities to be larger in the western - boundary regions. The algorithm is taken directly from the - anisotropic_ncar routine in ocean_lapgen_friction.F90. - - NOTE: The nearest western boundary computations are done along the - model i-grid lines. Therefore, viscosity based on these are - only approximate in the high Northern Hemisphere when using - generalized coordinates with coordinate pole(s) shifted onto - land. - -
-
-
-- - -
-BDX_EU_smag
--
-- -DESCRIPTION -
-- - Compute backwards Derivative in X of a quantity defined on the east - face of a U-cell. Slightly modified version of BDX_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i-1/2,j). - - BDX_EU_smag changes dimensions by m^-3 - -
-
-
-- -INPUT -
-- -
--
-- -a - field defined on the east face of a U-cell - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BDY_NU_smag
--
-- -DESCRIPTION -
-- - Compute backwards Derivative in Y of a quantity defined on the north - face of a U-cell. Slightly modified version of BDY_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i,j-1/2). - - BDY_EU_smag changes dimensions by m^-3 - -
-
-
-- -INPUT -
-- -
--
-- -a - field defined on the north face of a U-cell - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-bihgen_viscosity_check
--
-- -DESCRIPTION -
-- - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. -
-
-
-- - -
-bihgen_reynolds_check
--
-- -DESCRIPTION -
-- - Subroutine to compute the biharmonic grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. -
-
-
-- - -
-compute_neptune_velocity
--
-- -DESCRIPTION -
-- - Compute Neptune velocity. - - Method follows that of - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - March 2012 - Stephen.Griffies - -
-
-
-
-NAMELIST
- --&ocean_bihgen_friction_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging by printing checksums. -
-
-[logical] -- -k_smag_iso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. -
-
-[real, units: dimensionless] -- -k_smag_aniso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. -
-
-[real, units: dimensionless] -- -vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity. -
-
-[real, units: m/sec] -- -vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity. -
-
-[real, units: m/sec] -- -visc_crit_scale -
-- Scaling factor used to determine the critical viscosity, above which - the viscosity is not allowed to reach. - Use visc_crit_scale < 1.0 for cases where the visc_crit from linear stability - allows for still too large of a viscosity. Use visc_crit_scale>1.0 when wish - to allow for larger viscosity. Default is visc_crit_scale=1.0. -
-
-[real, units: dimensionless] -- -equatorial_zonal -
-- Orient the anisotropic friction within a latitudinal band according - to zonal direction. -
-
-[real] -- -equatorial_zonal_lat -
-- Latitudinal band to use the zonal friction orientation. -
-
-[real] -- -eq_vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity - within a user specified equatorial band. -
-
-[real] -- -eq_vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic - viscosity within a user specified equatorial band. -
-
-[real] -- -eq_lat_micom -
-- Equatorial latitude band (degrees) within which the MICOM viscosity - is set according to eq_vel_micom_iso and eq_vel_micom_aniso. -
-
-[real] -- -bottom_5point -
-- To alleviate problems with small partial cells, it is often necessary - to reduce the operator to the traditional 5-point Laplacian at the - ocean bottom. This logical implements this mixing. - Default bottom_5point=.false. -
-
-[logical] -- -vel_micom_bottom -
-- Velocity scale that is used for computing the MICOM viscosity for - 5point Laplacian at the bottom. -
-
-[real, units: m/sec] -- -ncar_boundary_scaling -
-- To enhance the velocity scale used in western boundaries - for the isotropic and anisotropic background viscosities, - we compute a scaling using the algorithm from the laplacian - NCAR anisotropic scheme. - Default ncar_boundary_scaling=.false. -
-
-[logical] -- -ncar_boundary_scaling_read -
-- To read in the ncar boundary scaling field rather than - generating it during initialization. Generating during - initialization can be a bottle-neck on fine resolution models - since there are some global 2d fields needed. So if the - rescaling is produced once and then saved, it can be read - in during subsequent runs without incurring the slowdown - of re-generating the scalings. - Default ncar_boundary_scaling_read=.false. -
-
-[logical] -- -ncar_rescale_power -
-- For determining rescaling of the viscosity so to enhance the - friction near the western boundaries. Default ncar_rescale_power=1. -
-
-[integer, units: dimensionless] -- -ncar_vconst_4 -
-- Inverse damping length for exponential falloff of the velocity scale - as move eastward away from western boundary. Default ncar_vconst_4=2.e-8. -
-
-[real, units: 1/cm] -- -ncar_vconst_5 -
-- For determining number of grid points in boundary calculation. - Default ncar_vconst_5=3. -
-
-[integer, units: dimensionless] -- -neptune -
-- Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. -
-
-[logical] -- -neptune_length_eq -
-- Length scale used to compute Neptune velocity at equator. - Default neptune_length_eq= 4.2e3 from Maltrud and Holloway. -
-
-[real, units: m] -- -neptune_length_pole -
-- Length scale used to compute Neptune velocity at pole. - Default neptune_length_pole= 17.0e3 from Maltrud and Holloway. -
-
-[real, units: m] -- -neptune_depth_min -
-- Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 from Maltrud and Holloway. -
-
-[real, units: m] -- -neptune_smooth -
-- For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. -
-
-[logical] -- -neptune_smooth_num -
-- Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. -
-
-[integer] -- -neptune_scaling -
-- Overall scaling parameter to help tune neptune. - Default neptune_scaling=1.0 -
-
-[real] -- -visc_diverge_scaling -
-- Dimensionless scaling used for divergence based viscosity. - Default visc_diverge_scaling=0.0 turns off the scheme. - visc_diverge_scaling=10.0 produces sensible viscosities for - 1-degree model. May need tuning for different resolutions. -
-
-[real] -- -use_side_drag_friction -
-- For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. -
-
-[logical] -- -side_drag_friction_scaling -
-- Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. -
-
-[real] -- -side_drag_friction_uvmag_max -
-- Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. -
-
-[real, units: m/s] -- -side_drag_friction_max -
-- Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations. - Default side_drag_friction_max=1.0. -
-
-[real, units: N/m^2] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use - in large-scale eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946. -
-- - R.D. Smith and J.C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
-- - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
-- - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
-- - S.M. Griffies, 2004: - Fundamentals of Ocean Climate Models - Princeton University Press -
-- - Griffies, Elements of MOM (2012) -
-
- - -
-NOTES
- -- The ocean model can generally run with both Laplacian and biharmonic - friction enabled at the same time. Such has been found useful - for some eddying ocean simulations. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_bihgen_friction.xml b/src/mom5/ocean_param/lateral/ocean_bihgen_friction.xml deleted file mode 100644 index c01f155a34..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_bihgen_friction.xml +++ /dev/null @@ -1,284 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_lap_friction.F90 b/src/mom5/ocean_param/lateral/ocean_lap_friction.F90 index 9489915c04..b703798c6e 100644 --- a/src/mom5/ocean_param/lateral/ocean_lap_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_lap_friction.F90 @@ -115,9 +115,9 @@ module ocean_lap_friction_mod integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk character(len=256) :: version=& - '=>Using: ocean_lap_friction.f90 ($Id: ocean_lap_friction.F90,v 1.1.2.6.6.1 2012/07/10 03:45:18 smg Exp $)' + '=>Using: ocean_lap_friction.f90 ($Id: ocean_lap_friction.F90,v 20.0 2013/12/14 00:14:18 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. logical :: write_a_restart = .true. diff --git a/src/mom5/ocean_param/lateral/ocean_lap_friction.html b/src/mom5/ocean_param/lateral/ocean_lap_friction.html deleted file mode 100644 index 37737acce8..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lap_friction.html +++ /dev/null @@ -1,276 +0,0 @@ - - - - S. M. Griffies - - This module computes thickness weighted and density weighted - time tendency for horizontal velocity arising from - biharmonic friction. - - This module computes thickness weighted and density weighted - time tendency for horizontal velocity arising from biharmonic - friction. - - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach as well as a grid-scale dependent - background viscosity. The form of the friction operator - can be isotropic or anisotropic in the lateral plane. - - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use - in large-scale eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946. - - R.D. Smith and J.C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. - - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. - - S.M. Griffies, 2004: - Fundamentals of Ocean Climate Models - Princeton University Press - - Griffies, Elements of MOM (2012) - - The ocean model can generally run with both Laplacian and biharmonic - friction enabled at the same time. Such has been found useful - for some eddying ocean simulations. - - Must be true to use this module. Default is false. - - For debugging by printing checksums. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. - - Velocity scale that is used for computing the MICOM isotropic viscosity. - - Velocity scale that is used for computing the MICOM anisotropic viscosity. - - Scaling factor used to determine the critical viscosity, above which - the viscosity is not allowed to reach. - Use visc_crit_scale < 1.0 for cases where the visc_crit from linear stability - allows for still too large of a viscosity. Use visc_crit_scale>1.0 when wish - to allow for larger viscosity. Default is visc_crit_scale=1.0. - - Orient the anisotropic friction within a latitudinal band according - to zonal direction. - - Latitudinal band to use the zonal friction orientation. - - Velocity scale that is used for computing the MICOM isotropic viscosity - within a user specified equatorial band. - - Velocity scale that is used for computing the MICOM anisotropic - viscosity within a user specified equatorial band. - - Equatorial latitude band (degrees) within which the MICOM viscosity - is set according to eq_vel_micom_iso and eq_vel_micom_aniso. - - To alleviate problems with small partial cells, it is often necessary - to reduce the operator to the traditional 5-point Laplacian at the - ocean bottom. This logical implements this mixing. - Default bottom_5point=.false. - - Velocity scale that is used for computing the MICOM viscosity for - 5point Laplacian at the bottom. - - To enhance the velocity scale used in western boundaries - for the isotropic and anisotropic background viscosities, - we compute a scaling using the algorithm from the laplacian - NCAR anisotropic scheme. - Default ncar_boundary_scaling=.false. - - To read in the ncar boundary scaling field rather than - generating it during initialization. Generating during - initialization can be a bottle-neck on fine resolution models - since there are some global 2d fields needed. So if the - rescaling is produced once and then saved, it can be read - in during subsequent runs without incurring the slowdown - of re-generating the scalings. - Default ncar_boundary_scaling_read=.false. - - For determining rescaling of the viscosity so to enhance the - friction near the western boundaries. Default ncar_rescale_power=1. - - Inverse damping length for exponential falloff of the velocity scale - as move eastward away from western boundary. Default ncar_vconst_4=2.e-8. - - For determining number of grid points in boundary calculation. - Default ncar_vconst_5=3. - - Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. - - Length scale used to compute Neptune velocity at equator. - Default neptune_length_eq= 4.2e3 from Maltrud and Holloway. - - Length scale used to compute Neptune velocity at pole. - Default neptune_length_pole= 17.0e3 from Maltrud and Holloway. - - Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 from Maltrud and Holloway. - - For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. - - Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. - - Overall scaling parameter to help tune neptune. - Default neptune_scaling=1.0 - - Dimensionless scaling used for divergence based viscosity. - Default visc_diverge_scaling=0.0 turns off the scheme. - visc_diverge_scaling=10.0 produces sensible viscosities for - 1-degree model. May need tuning for different resolutions. - - For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. - - Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. - - Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. - - Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations. - Default side_drag_friction_max=1.0. - - Initialize the horizontal biharmonic friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. - - This subroutine computes the time tendency for horizontal - velocity (i.e., the acceleration) from horizontal biharmonic friction. - The algorithm is derived from a functional approach that ensures kinetic - energy is consistenty dissipated for all flow configurations. - The triad do-loops are expanded in order to enhance the - ability of cache-based machines to keep most of the variables - on-cache. - - Fundamental to the scheme are the rates of horizontal deformation
- horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y
- horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x
- Units of the tension and strain are sec^-1. - - Four tensions and four strains are computed for each velocity point,
- corresponding to the four triads surrounding the point.
- The following notation is used to distinguish the triads:
- (0,1)=northwest triad (1,1)=northeast triad,
- (0,0)=southwest triad, (1,0)=southeast triad - - A triad contributes when at least one of its velocities is - not a land point. In order to obtain the correct tension - and strain next to boundaries, tension and strain should not be - masked with umask. - - As shown in Griffies and Hallberg (2000), - a biharmonic operator with a nonconstant viscosity is guaranteed to - dissipate kinetic energy *only* when using the sqrt of the biharmonic - viscosity at each of the two stages of the algorithm. - The sqrt approach is employed here. - -- - Read in the 3d ncar boundary scaling field and use this to - rescale the background viscosities. - - To use this routine, we need to already have generated the field - ncar_rescale using the routine ncar_boundary_scale_create. - - The advantage of reading ncar_rescale is that we do not need to - introduce any global 2d arrays required for ncar_boundary_scale_create. - So the idea is to pay the price once by running ncar_boundary_scale_create, - save ncar_rescale, then read that field in during subsequent runs through - ncar_boundary_scale_read. - - Here are the steps: - 1/ run one time with ncar_boundary_scaling_read=.false. - and ncar_boundary_scaling=.true. - Be sure that the field ncar_rescale is saved in diagnostic table. - To ensure answers agree whether reading ncar_rescale or creating it - during initialization, it is necessary to save ncar_rescale using the - double precision option in the diagnostic table (packing=1). - - 2/ extract field ncar_rescale from the diagnostics output - and place into its own file INPUT/ncar_rescale.nc - example extraction using ncks: - ncks -v ncar_rescale 19900101.ocean_month.nc ncar_rescale.nc - - 3/ set ncar_boundary_scaling_read=.true. - and ncar_boundary_scaling=.true., and now run the model - reading in ncar_rescale rather than regenerating - it during each initialization (which can be a bottleneck - for large models on huge processor counts). - - 4/ As a check that all is fine, save ncar_rescale as a diagnostic - for both the create and the read stage and make sure they agree. - Also, all checksums should agree whether reading in ncar_rescale - or creating it each initialization, so long as the ncar_rescale.nc - was saved with double precision (see step 1/ above). - - - - Recale the background viscosities to be larger in the western - boundary regions. The algorithm is taken directly from the - anisotropic_ncar routine in ocean_lapgen_friction.F90. - - NOTE: The nearest western boundary computations are done along the - model i-grid lines. Therefore, viscosity based on these are - only approximate in the high Northern Hemisphere when using - generalized coordinates with coordinate pole(s) shifted onto - land. - - - Compute backwards Derivative in X of a quantity defined on the east - face of a U-cell. Slightly modified version of BDX_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i-1/2,j). - - BDX_EU_smag changes dimensions by m^-3 - - - field defined on the east face of a U-cell - - Compute backwards Derivative in Y of a quantity defined on the north - face of a U-cell. Slightly modified version of BDY_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i,j-1/2). - - BDY_EU_smag changes dimensions by m^-3 - - - field defined on the north face of a U-cell - - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. - - Subroutine to compute the biharmonic grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. - - Compute Neptune velocity. - - Method follows that of - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - March 2012 - Stephen.Griffies - - Module ocean_lap_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_lap_friction_mod
- - - - - -
-OVERVIEW
- -- This module calls the appropriate lateral laplacian friction modules. -
- - - -- This module serves as an interface to the chosen lateral - laplacian friction modules. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_lapcst_friction_mod
ocean_lapgen_friction_mod
ocean_lapcgrid_friction_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_lap_friction_init:
- -- -lap_friction:
- -- -lap_viscosity_check:
- -- -lap_reynolds_check:
- -- -lap_friction_barotropic:
- -- -ocean_lap_friction_restart:
- -- -ocean_lap_friction_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_lap_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal Laplacian friction module. -
-
-
-- - -
-lap_friction
--
-- -DESCRIPTION -
-- - Compute the thickness weighted and density weighted accel due to - lateral laplacian friction. Add this contribution to Velocity%accel. -
-
-
-- - -
-lap_viscosity_check
--
-- -DESCRIPTION -
-- - To check that the viscosity is not too large. -
-
-
-- - -
-lap_reynolds_check
--
-- -DESCRIPTION -
-- - To check that the Reynolds number is not too large. -
-
-
-- - -
-lap_friction_barotropic
--
-- -DESCRIPTION -
-- - - This routine computes the laplacian friction acting on a two-dim - array. It uses the two-dimensional vertically averaged viscosity - used in the laplacian friction module. The intent is to apply this - 2d operator to the vertically integrated horizontal momentum. We - ignore the spherical metric terms in this form of the operator, - since we are aiming for a fast smoothing operator to be applied - during each of the many barotropic time steps. We also apply - just the isotropic portion of the more general anisotropic - laplacian operator. - - This scheme is only meant for the B-grid version of MOM. It - has not been generalized to the C-grid, since the C-grid has - less noise in the barotropic gravity waves anyhow, so it is - unlikely there will need to be extra friction applied to the - C-grid barotropic equations. - -
-
-
-- - -
-ocean_lap_friction_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_lap_friction_end
--
-- -DESCRIPTION -
-- - Write to restart of the vertically averaged viscosity. -
-
-
-
-NAMELIST
- --&ocean_lap_friction_nml --
-
----
-- -lap_friction_scheme -
-- To determine the laplacian friction scheme: "const" or "general" -
-
-[character] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -
- - - - -
-NOTES
- -- The model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_lap_friction.xml b/src/mom5/ocean_param/lateral/ocean_lap_friction.xml deleted file mode 100644 index c494fe4312..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lap_friction.xml +++ /dev/null @@ -1,54 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_lap_tracer.F90 b/src/mom5/ocean_param/lateral/ocean_lap_tracer.F90 index 455d230150..d72e15e364 100644 --- a/src/mom5/ocean_param/lateral/ocean_lap_tracer.F90 +++ b/src/mom5/ocean_param/lateral/ocean_lap_tracer.F90 @@ -129,9 +129,9 @@ module ocean_lap_tracer_mod real, dimension(:,:,:), allocatable :: diffusivity_mask ! 3d mask to selectively apply diffusion character(len=128) :: version=& - '$Id: ocean_lap_tracer.F90,v 1.1.2.2 2012/06/01 20:47:08 Stephen.Griffies Exp $' + '$Id: ocean_lap_tracer.F90,v 20.0 2013/12/14 00:14:20 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' type(ocean_grid_type), pointer :: Grd => NULL() type(ocean_domain_type), pointer :: Dom => NULL() diff --git a/src/mom5/ocean_param/lateral/ocean_lap_tracer.html b/src/mom5/ocean_param/lateral/ocean_lap_tracer.html deleted file mode 100644 index 69628785a6..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lap_tracer.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - Stephen M. Griffies - - This module calls the appropriate lateral laplacian friction modules. - - This module serves as an interface to the chosen lateral - laplacian friction modules. - - The model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. - - To determine the laplacian friction scheme: "const" or "general" - - For debugging. - - Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. - - Initialize the horizontal Laplacian friction module. - - Compute the thickness weighted and density weighted accel due to - lateral laplacian friction. Add this contribution to Velocity%accel. - - To check that the viscosity is not too large. - - To check that the Reynolds number is not too large. - - - This routine computes the laplacian friction acting on a two-dim - array. It uses the two-dimensional vertically averaged viscosity - used in the laplacian friction module. The intent is to apply this - 2d operator to the vertically integrated horizontal momentum. We - ignore the spherical metric terms in this form of the operator, - since we are aiming for a fast smoothing operator to be applied - during each of the many barotropic time steps. We also apply - just the isotropic portion of the more general anisotropic - laplacian operator. - - This scheme is only meant for the B-grid version of MOM. It - has not been generalized to the C-grid, since the C-grid has - less noise in the barotropic gravity waves anyhow, so it is - unlikely there will need to be extra friction applied to the - C-grid barotropic equations. - - - Write out restart files registered through register_restart_file - - Write to restart of the vertically averaged viscosity. - Module ocean_lap_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_lap_tracer_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted and density weighted time tendency - for tracer from lateral laplacian diffusion. -
- - - -- This module computes lateral laplacian diffusion of a tracer. - There are two main options. - - (1) The lateral tracer fluxes can be aligned with the z-coordinate surfaces, - in which case the fluxes must be approximated if (i) we use non-geopotential - vertical coordinates, (ii) next to partial bottom step topography. - This form of the diffusion is not recommended since it can lead to - the creation of spurious extrema. - - (2) The lateral tracer fluxes can be aligned surfaces of constant vertical - coordinate. In this case the fluxes are no longer strictly "horizontal." - However, the operator is simpler and it ensures that no suprious - extrema are created. It is for this reason that the simpler operator - is preferred. - - The diffusivity used to determine the strength of the tendency can be - a general function of space yet it is constant in time. A namelist - option exists that determines this diffusivity as a local function - of the grid spacing. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_lap_tracer_init:
- -- -lap_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_lap_tracer_init
--
-- -DESCRIPTION -
-- - Initialize the laplacian diffusion module by - registering fields for diagnostic output and performing some - numerical checks to see that diffusivity is set appropriately. -
-
-
-- - -
-lap_tracer
--
-- -DESCRIPTION -
-- - This function computes the thickness weighted and density weighted - time tendency for tracer from lateral laplacian diffusion. -
-
-
-
-NAMELIST
- --&ocean_lap_tracer_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -horz_z_diffuse -
-- To compute diffusion along surfaces of constant depth. - This operation must necessarily be approximate for the two - cases (i) non-geopotential vertical coordinates, (2) - next to partial bottom step topography. There are cases where - use of this operator can lead to spurious creation of extrema - due to truncation errors associated with the "slope" term. - For most cases where lateral diffusion is required, we - will want it to be "diffusive" in the sense that no extrema are - created. So the default is horz_z_diffuse=.false. - The option to use horz_z_diffuse=.true. is maintained for - legacy purposes alone. -
-
-[logical] -- -horz_s_diffuse -
-- To compute diffusion along surfaces of constant vertical s-coordinate. - This operation is ensured of obtaining a smoothing operator - that does not create extrema. It is the default for this - reason. -
-
-[logical] -- -alap -
-- This is the value for the space-time constant Laplacian diffusivity. -
-
-[real, units: m^2/sec] -- -tracer_mix_micom -
-- If .true., then the diffusivity is set according to a velocity scale times - the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model (MICOM). -
-
-[logical] -- -vel_micom -
-- Velocity scale that is used for computing the MICOM diffusivity. -
-
-[real, units: m/sec] -- -read_diffusivity_mask -
-- Allows for reading of a mask that to apply diffusivity - only in selected regions. - Default read_diffusivity_mask=.false. -
-
-[logical] -- -verbose_init -
-- For verbose writes during initialization -
-
-[logical] -
- - - - -
-NOTES
- -- The numerical implementation requires no calls to mpp_update_domains. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_lap_tracer.xml b/src/mom5/ocean_param/lateral/ocean_lap_tracer.xml deleted file mode 100644 index ad66d67d56..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lap_tracer.xml +++ /dev/null @@ -1,70 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.F90 b/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.F90 index e6a133c403..5a8b7829ff 100644 --- a/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.F90 @@ -351,9 +351,9 @@ module ocean_lapcgrid_friction_mod type(ocean_domain_type), pointer :: Dom => NULL() character(len=256) :: version=& - '=>Using: ocean_lapcgrid_friction.F90 ($Id: ocean_lapcgrid_friction.F90,v 1.1.2.5 2012/06/08 20:15:35 Stephen.Griffies Exp $)' + '=>Using: ocean_lapcgrid_friction.F90 ($Id: ocean_lapcgrid_friction.F90,v 20.0 2013/12/14 00:14:22 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: use_this_module = .false. logical :: debug_this_module = .false. diff --git a/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.html b/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.html deleted file mode 100644 index a27a43ed70..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.html +++ /dev/null @@ -1,574 +0,0 @@ - - - - Stephen M. Griffies - - Thickness weighted and density weighted time tendency - for tracer from lateral laplacian diffusion. - - This module computes lateral laplacian diffusion of a tracer. - There are two main options. - - (1) The lateral tracer fluxes can be aligned with the z-coordinate surfaces, - in which case the fluxes must be approximated if (i) we use non-geopotential - vertical coordinates, (ii) next to partial bottom step topography. - This form of the diffusion is not recommended since it can lead to - the creation of spurious extrema. - - (2) The lateral tracer fluxes can be aligned surfaces of constant vertical - coordinate. In this case the fluxes are no longer strictly "horizontal." - However, the operator is simpler and it ensures that no suprious - extrema are created. It is for this reason that the simpler operator - is preferred. - - The diffusivity used to determine the strength of the tendency can be - a general function of space yet it is constant in time. A namelist - option exists that determines this diffusivity as a local function - of the grid spacing. - - The numerical implementation requires no calls to mpp_update_domains. - - Must be true to use this module. Default is false. - - To compute diffusion along surfaces of constant depth. - This operation must necessarily be approximate for the two - cases (i) non-geopotential vertical coordinates, (2) - next to partial bottom step topography. There are cases where - use of this operator can lead to spurious creation of extrema - due to truncation errors associated with the "slope" term. - For most cases where lateral diffusion is required, we - will want it to be "diffusive" in the sense that no extrema are - created. So the default is horz_z_diffuse=.false. - The option to use horz_z_diffuse=.true. is maintained for - legacy purposes alone. - - To compute diffusion along surfaces of constant vertical s-coordinate. - This operation is ensured of obtaining a smoothing operator - that does not create extrema. It is the default for this - reason. - - This is the value for the space-time constant Laplacian diffusivity. - - If .true., then the diffusivity is set according to a velocity scale times - the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model (MICOM). - - Velocity scale that is used for computing the MICOM diffusivity. - - Allows for reading of a mask that to apply diffusivity - only in selected regions. - Default read_diffusivity_mask=.false. - - For verbose writes during initialization - - Initialize the laplacian diffusion module by - registering fields for diagnostic output and performing some - numerical checks to see that diffusivity is set appropriately. - - This function computes the thickness weighted and density weighted - time tendency for tracer from lateral laplacian diffusion. - Module ocean_lapcgrid_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_lapcgrid_friction_mod
- - - - - -
-OVERVIEW
- -- This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - Friction is formulated for the C-grid here. -
- - - -- This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach as well as a grid-scale dependent - background viscosity. The form of the friction operator - can be isotropic or anisotropic in the horizontal plane. - - - Friction is formulated for the C-grid here. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_lapcgrid_friction_init:
- -- -lapcgrid_friction:
- -- -lapcgrid_viscosity_check:
- -- -lapcgrid_reynolds_check:
- -- -compute_neptune_velocity:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_lapcgrid_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal Laplacian friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. -
-
-
-- - -
-lapcgrid_friction
--
-- -DESCRIPTION -
-- - This routine computes thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - Laplacian friction. - - The algorithm is derived from a functional approach that ensures - kinetic energy is consistenty dissipated for all flow configurations. - The stencil is far simpler than the B-grid approach. In particular, - there are no triads here for the C-grid. - - Fundamental to the scheme are the rates of horizontal deformation - horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y - horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x - Units of the tension and strain are sec^-1. - -
-
-
-- - -
-lapcgrid_viscosity_check
--
-- -DESCRIPTION -
-- - Subroutine to perform linear stability check for the Laplacian - operator given a value for the horizontal biharmonic viscosity. -
-
-
-- - -
-lapcgrid_reynolds_check
--
-- -DESCRIPTION -
-- - Subroutine to compute the LLaplacian grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. -
-
-
-- -INPUT -
-- -
--
-- -u - Horizontal velocity field at time tau - -
[real, dimension(isd:ied,jsd:jed,nk,2)]
-- - -
-compute_neptune_velocity
--
-- -DESCRIPTION -
-- - Compute Neptune velocity for c-grid. - - Method follows that used in MOM2 and MOM3 as implemented by - Greg Holloway (zounds@ios.bc.ca) and Michael Eby (eby@uvic.ca) - Coded in mom4 by Stephen.Griffies - - Neptune is calculated as an equilibrium streamfunction given by - pnep = -f*snep*snep*ht and is applied through friction whereby - the solution is damped towards the equilibrium streamfunction - rather than being damped towards zero kinetic energy. - - hu = depth of B-grid velocity corner - snep = spnep + (senep-spnep)*(0.5 + 0.5*cos(2.0*latitude)) - - Neptune length scale snep has a value of senep at the - equator and smoothly changes to spnep at the poles - - Reference: - Holloway, G., 1992: Representing topographic stress for large - scale ocean models, J. Phys. Oceanogr., 22, 1033-1046 - - Eby and Holloway, 1994: Sensitivity of a large scale ocean model - to a parameterization of topographic stress. JPO, vol. 24, - pages 2577-2588 - - March 2012 - Stephen.Griffies - Algorithm updated to Eby and Holloway (1994) - - May 2012 - Stephen.Griffies - upgraded to Cgrid - -
-
-
-
-NAMELIST
- --&ocean_lapcgrid_friction_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging by printing checksums. -
-
-[logical] -- -viscosity_scale_by_rossby -
-- To scale down the laplacian viscosity according to the relative scale of the - horizontal grid and the first baroclinic Rossby radius. This is a useful - scheme for models that resolve the Rossby radius in the lower latitudes, and so - presumably do not wish to have much laplacian friction, whereas the higher latitudes - need more friction. Default viscosity_scale_by_rossby=.false. -
-
-[logical] -- -viscosity_scale_by_rossby_power -
-- The power used to determine the viscosity scaling function. - Default viscosity_scale_by_rossby_power=2.0. -
-
-[real] -- -divergence_damp -
-- To damp the divergence field. -
-
-[logical] -- -divergence_damp_vel_micom -
-- Velocity scale to set the viscosity used with divergence damping. -
-
-[real, units: m/s] -- -k_smag_iso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. -
-
-[real, units: dimensionless] -- -k_smag_aniso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. -
-
-[real, units: dimensionless] -- -vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity. -
-
-[real, units: m/sec] -- -vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity. -
-
-[real, units: m/sec] -- -equatorial_zonal -
-- Orient the anisotropic friction within a latitudinal band according to zonal direction. -
-
-[logical] -- -equatorial_zonal_lat -
-- Latitudinal band to use the zonal friction orientation. -
-
-[real] -- -equatorial_no_smag -
-- Turn smag off within equatorial_zonal_lat region. -
-
-[logical] -- -eq_vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity within - a user specified equatorial band. -
-
-[real] -- -eq_vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity within - a user specified equatorial band. -
-
-[real] -- -eq_lat_micom -
-- Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom_iso and eq_vel_micom_aniso. -
-
-[real] -- -restrict_polar_visc -
-- For restricting the background viscosity poleward of a - latitude. This method may be useful for coupling to an ice model - in which case the horizontal viscosity may need to be a bit - smaller to maintain time step constraints. This is because the - effective friction is larger than that just within the ocean. -
-
-[logical] -- -restrict_polar_visc_lat -
-- Latitude poleward of which we restrict the viscosity. -
-
-[real] -- -restrict_polar_visc_ratio -
-- Ratio of the normal critical value that we limit the - viscosity to be no greater than. If restrict_polar_visc_ratio=1.0 - then there is no special limitation of the viscosity beyond that - of the one-dimensional stability constraint. -
-
-[real] -- -neptune -
-- Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. -
-
-[logical] -- -neptune_length_eq -
-- Length scale used to compute Neptune velocity at equator. -
-
-[real, units: m] -- -neptune_length_pole -
-- Length scale used to compute Neptune velocity at pole. -
-
-[real, units: m] -- -neptune_depth_min -
-- Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 -
-
-[real, units: m] -- -neptune_smooth -
-- For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. -
-
-[logical] -- -neptune_smooth_num -
-- Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. -
-
-[integer] -- -use_side_drag_friction -
-- For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. -
-
-[logical] -- -side_drag_friction_scaling -
-- Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. -
-
-[real] -- -side_drag_friction_uvmag_max -
-- Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. -
-
-[real, units: m/s] -- -side_drag_friction_max -
-- Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations - in ocean_bbc. Default side_drag_friction_max=1.0. -
-
-[real, units: N/m^2] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use in large-scale - eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946 -
-- - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
-- - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
-- - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
-- - Griffies: Elements of MOM (2012) -
-
- - -
-NOTES
- -- The ocean model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.xml b/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.xml deleted file mode 100644 index 9f3b9bf188..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lapcgrid_friction.xml +++ /dev/null @@ -1,200 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_lapcst_friction.F90 b/src/mom5/ocean_param/lateral/ocean_lapcst_friction.F90 index 92d7e7f305..c5c8ebfa43 100644 --- a/src/mom5/ocean_param/lateral/ocean_lapcst_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_lapcst_friction.F90 @@ -129,9 +129,9 @@ module ocean_lapcst_friction_mod integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk character(len=256) :: version=& - '=>Using: ocean_lapcst_friction.f90 ($Id: ocean_lapcst_friction.F90,v 1.1.2.4 2012/06/01 20:47:08 Stephen.Griffies Exp $)' + '=>Using: ocean_lapcst_friction.f90 ($Id: ocean_lapcst_friction.F90,v 20.0 2013/12/14 00:14:24 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: use_this_module = .false. logical :: debug_this_module = .false. diff --git a/src/mom5/ocean_param/lateral/ocean_lapcst_friction.html b/src/mom5/ocean_param/lateral/ocean_lapcst_friction.html deleted file mode 100644 index 9303429f3d..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lapcst_friction.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - S. M. Griffies - - This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - Friction is formulated for the C-grid here. - - This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach as well as a grid-scale dependent - background viscosity. The form of the friction operator - can be isotropic or anisotropic in the horizontal plane. - - - Friction is formulated for the C-grid here. - - - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use in large-scale - eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946 - - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. - - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. - - Griffies: Elements of MOM (2012) - - The ocean model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. - - Must be true to use this module. Default is false. - - For debugging by printing checksums. - - To scale down the laplacian viscosity according to the relative scale of the - horizontal grid and the first baroclinic Rossby radius. This is a useful - scheme for models that resolve the Rossby radius in the lower latitudes, and so - presumably do not wish to have much laplacian friction, whereas the higher latitudes - need more friction. Default viscosity_scale_by_rossby=.false. - - The power used to determine the viscosity scaling function. - Default viscosity_scale_by_rossby_power=2.0. - - To damp the divergence field. - - Velocity scale to set the viscosity used with divergence damping. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. - - Velocity scale that is used for computing the MICOM isotropic viscosity. - - Velocity scale that is used for computing the MICOM anisotropic viscosity. - - Orient the anisotropic friction within a latitudinal band according to zonal direction. - - Latitudinal band to use the zonal friction orientation. - - Turn smag off within equatorial_zonal_lat region. - - Velocity scale that is used for computing the MICOM isotropic viscosity within - a user specified equatorial band. - - Velocity scale that is used for computing the MICOM anisotropic viscosity within - a user specified equatorial band. - - Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom_iso and eq_vel_micom_aniso. - - For restricting the background viscosity poleward of a - latitude. This method may be useful for coupling to an ice model - in which case the horizontal viscosity may need to be a bit - smaller to maintain time step constraints. This is because the - effective friction is larger than that just within the ocean. - - Latitude poleward of which we restrict the viscosity. - - Ratio of the normal critical value that we limit the - viscosity to be no greater than. If restrict_polar_visc_ratio=1.0 - then there is no special limitation of the viscosity beyond that - of the one-dimensional stability constraint. - - Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. - - Length scale used to compute Neptune velocity at equator. - - Length scale used to compute Neptune velocity at pole. - - Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 - - For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. - - Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. - - For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. - - Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. - - Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. - - Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations - in ocean_bbc. Default side_drag_friction_max=1.0. - - Initialize the horizontal Laplacian friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. - - This routine computes thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - Laplacian friction. - - The algorithm is derived from a functional approach that ensures - kinetic energy is consistenty dissipated for all flow configurations. - The stencil is far simpler than the B-grid approach. In particular, - there are no triads here for the C-grid. - - Fundamental to the scheme are the rates of horizontal deformation - horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y - horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x - Units of the tension and strain are sec^-1. - - - Subroutine to perform linear stability check for the Laplacian - operator given a value for the horizontal biharmonic viscosity. - - Subroutine to compute the LLaplacian grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. - - Horizontal velocity field at time tau - - Compute Neptune velocity for c-grid. - - Method follows that used in MOM2 and MOM3 as implemented by - Greg Holloway (zounds@ios.bc.ca) and Michael Eby (eby@uvic.ca) - Coded in mom4 by Stephen.Griffies - - Neptune is calculated as an equilibrium streamfunction given by - pnep = -f*snep*snep*ht and is applied through friction whereby - the solution is damped towards the equilibrium streamfunction - rather than being damped towards zero kinetic energy. - - hu = depth of B-grid velocity corner - snep = spnep + (senep-spnep)*(0.5 + 0.5*cos(2.0*latitude)) - - Neptune length scale snep has a value of senep at the - equator and smoothly changes to spnep at the poles - - Reference: - Holloway, G., 1992: Representing topographic stress for large - scale ocean models, J. Phys. Oceanogr., 22, 1033-1046 - - Eby and Holloway, 1994: Sensitivity of a large scale ocean model - to a parameterization of topographic stress. JPO, vol. 24, - pages 2577-2588 - - March 2012 - Stephen.Griffies - Algorithm updated to Eby and Holloway (1994) - - May 2012 - Stephen.Griffies - upgraded to Cgrid - - Module ocean_lapcst_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_lapcst_friction_mod
- - - - - -
-OVERVIEW
- -- This module computes the thickness weighted and density weighted - acceleration for horizontal velocity arising from horizontal - Laplacian friction. -
- - - -- This module computes the thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - Laplacian friction. - - The viscosity used to determine the strength of the tendency - can be a general function of space yet it is constant in time. - A namelist option exists that determines this viscosity - as a local function of the grid spacing. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_lapcst_friction_init:
- -- -lapcst_friction:
- -- -lapcst_viscosity_check:
- -- -lapcst_reynolds_check:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_lapcst_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal Laplacian friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. -
-
-
-- - -
-lapcst_friction
--
-- -DESCRIPTION -
-- - This routine computes the rho*thickness weighted time tendency for - horizontal velocity from horizontal Laplacian friction. -
-
-
-- - -
-lapcst_viscosity_check
--
-- -DESCRIPTION -
-- - Perform linear stability check for the Laplacian operator - given a value for the horizontal laplacian viscosity. -
-
-
-- - -
-lapcst_reynolds_check
--
-- -DESCRIPTION -
-- - Subroutine to compute the Laplacian grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. -
-
-
-
-NAMELIST
- --&ocean_lapcst_friction_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging by printing checksums. -
-
-[logical] -- -alap -
-- This is the value for the space-time constant Laplacian viscosity. -
-
-[real, units: m^2/sec] -- -velocity_mix_micom -
-- If .true., then the viscosity is set according to a velocity scale times - the cube of the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model. -
-
-[logical] -- -vel_micom -
-- Velocity scale that is used for computing the MICOM viscosity. -
-
-[real, units: m/sec] -
- - - - -
-REFERENCES
- ----
-- - R. J. Murray and C. J. C. Reason, - A curvilinear version of the Bryan-Cox ocean model - Journal of Computational Physics (2002), vol 171, pages 1--46 -
-- - S.M. Griffies, Elements of MOM (2012) -
-
- - -
-NOTES
- -- The numerical implementation requires no calls to mpp_update_domains. --
-
- This scheme has been found to be faster than the Smagorinsky viscosity - scheme. However, the algorithm here is less robust since it - contains null modes in the terms associated with the sphericity - of the earth. Hence, there may be flow configurations that are - not dissipated. -
-
- The sink from drag next to partial cells has been dropped - from MOM4p1. -
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_lapcst_friction.xml b/src/mom5/ocean_param/lateral/ocean_lapcst_friction.xml deleted file mode 100644 index 7da01929e3..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lapcst_friction.xml +++ /dev/null @@ -1,62 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_lapgen_friction.F90 b/src/mom5/ocean_param/lateral/ocean_lapgen_friction.F90 index 3b7a9f2d9f..e6ba6a6573 100644 --- a/src/mom5/ocean_param/lateral/ocean_lapgen_friction.F90 +++ b/src/mom5/ocean_param/lateral/ocean_lapgen_friction.F90 @@ -445,9 +445,9 @@ module ocean_lapgen_friction_mod type(ocean_domain_type), pointer :: Dom => NULL() character(len=256) :: version=& - '=>Using: ocean_lapgen_friction.F90 ($Id: ocean_lapgen_friction.F90,v 1.1.2.4.14.1 2013/04/03 13:25:25 smg Exp $)' + '=>Using: ocean_lapgen_friction.F90 ($Id: ocean_lapgen_friction.F90,v 20.0 2013/12/14 00:14:26 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_201303_smg $' + '$Name: tikal $' logical :: use_this_module = .false. logical :: debug_this_module = .false. @@ -1093,8 +1093,8 @@ subroutine lapgen_friction(Time, Thickness, Adv_vel, Velocity, & usqrd = (Velocity%u(i,j,k,1,taum1)-neptune_velocity(i,j,1))**2 vsqrd = (Velocity%u(i,j,k,2,taum1)-neptune_velocity(i,j,2))**2 umagr = 1.0/(epsln + usqrd + vsqrd) - sin2theta(i,j) = 2.0*(Velocity%u(i,j,k,1,taum1) - neptune_velocity(i,j,1))* & - (Velocity%u(i,j,k,2,taum1) - neptune_velocity(i,j,2))*umagr + sin2theta(i,j) = 2.0*(Velocity%u(i,j,k,1,taum1)-neptune_velocity(i,j,1)) & + *(Velocity%u(i,j,k,2,taum1)-neptune_velocity(i,j,2))*umagr cos2theta(i,j) = (usqrd-vsqrd)*umagr endif @@ -1370,7 +1370,7 @@ subroutine lapgen_friction(Time, Thickness, Adv_vel, Velocity, & enddo enddo enddo - call diagnose_3d_u(TIme, Grd, id_horz_lap_diss, wrk2(:,:,:)) + call diagnose_3d_u(Time, Grd, id_horz_lap_diss, wrk2(:,:,:)) endif call diagnose_2d_u(Time, Grd, id_viscosity_scaling, viscosity_scaling(:,:)) diff --git a/src/mom5/ocean_param/lateral/ocean_lapgen_friction.html b/src/mom5/ocean_param/lateral/ocean_lapgen_friction.html deleted file mode 100644 index 22e6940d1c..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lapgen_friction.html +++ /dev/null @@ -1,883 +0,0 @@ - - - - Stephen M. Griffies - - This module computes the thickness weighted and density weighted - acceleration for horizontal velocity arising from horizontal - Laplacian friction. - - This module computes the thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - Laplacian friction. - - The viscosity used to determine the strength of the tendency - can be a general function of space yet it is constant in time. - A namelist option exists that determines this viscosity - as a local function of the grid spacing. - - - R. J. Murray and C. J. C. Reason, - A curvilinear version of the Bryan-Cox ocean model - Journal of Computational Physics (2002), vol 171, pages 1--46 - - S.M. Griffies, Elements of MOM (2012) - - The numerical implementation requires no calls to mpp_update_domains. - - This scheme has been found to be faster than the Smagorinsky viscosity - scheme. However, the algorithm here is less robust since it - contains null modes in the terms associated with the sphericity - of the earth. Hence, there may be flow configurations that are - not dissipated. - - The sink from drag next to partial cells has been dropped - from MOM4p1. - - Must be true to use this module. Default is false. - - For debugging by printing checksums. - - This is the value for the space-time constant Laplacian viscosity. - - If .true., then the viscosity is set according to a velocity scale times - the cube of the grid spacing. It is based on an approach recommended by - Eric Chassignet that is used in the Miami Isopycnal Model. - - Velocity scale that is used for computing the MICOM viscosity. - - Initialize the horizontal Laplacian friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. - - This routine computes the rho*thickness weighted time tendency for - horizontal velocity from horizontal Laplacian friction. - - Perform linear stability check for the Laplacian operator - given a value for the horizontal laplacian viscosity. - - Subroutine to compute the Laplacian grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. - Module ocean_lapgen_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_lapgen_friction_mod
- - - - - -
-OVERVIEW
- -- This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. -
- - - -- This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach as well as a grid-scale dependent - background viscosity. The form of the friction operator - can be isotropic or anisotropic in the horizontal plane. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_lapgen_friction_init:
- -- -lapgen_friction:
- -- -BDX_EU_smag:
- -- -BDY_NU_smag:
- -- -anisotropic_ncar:
- -- -lapgen_viscosity_check:
- -- -lapgen_reynolds_check:
- -- -compute_neptune_velocity:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_lapgen_friction_init
--
-- -DESCRIPTION -
-- - Initialize the horizontal Laplacian friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. -
-
-
-- - -
-lapgen_friction
--
-- -DESCRIPTION -
-- - This routine computes thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - Laplacian friction. - - The algorithm is derived from a functional approach that ensures - kinetic energy is consistenty dissipated for all flow configurations. - The triad do-loops are expanded in order to enhance the - ability of cache-based machines to keep most of the variables - on-cache. - - Fundamental to the scheme are the rates of horizontal deformation
-
- horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y
- horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x
- Units of the tension and strain are sec^-1. - - Four tensions and four strains are computed for each velocity point,
- corresponding to the four triads surrounding the point.
- The following notation is used to distinguish the triads:
- (0,1)=northwest triad (1,1)=northeast triad,
- (0,0)=southwest triad, (1,0)=southeast triad - - A triad contributes when at least one of its velocities is - not a land point. In order to obtain the correct tension - and strain next to boundaries, tension and strain should not be - masked with umask. - -
-
-- - -
-BDX_EU_smag
--
-- -DESCRIPTION -
-- - Compute backwards derivative in X of a quantity defined on the east - face of a U-cell. Slightly modified version of BDX_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i-1/2,j). - - BDX_EU_smag(a) has dimensions of a*m^-3 - -
-
-
-- -INPUT -
-- -
--
-- -a - field defined on the east face of a U-cell - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-BDY_NU_smag
--
-- -DESCRIPTION -
-- - Compute backwards derivative in Y of a quantity defined on the north - face of a U-cell. Slightly modified version of BDY_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i,j-1/2) - - BDY_NU_smag(a) has dimensions of a*m^-3 - -
-
-
-- -INPUT -
-- -
--
-- -a - field defined on the north face of a U-cell - -
[real, dimension(isd:ied,jsd:jed)]
-- - -
-anisotropic_ncar
--
-- -DESCRIPTION -
-- - - Spatially-varying anisotropic viscosity initialization - - This routine defines NCOM-like spatial distributions of - viscosity coefficients F_PARA and F_PERP. - Uses NCAR CCSM2.0 algorithm with cm^2/sec --> m^2/sec. - - written by: Stephen Yeager 3/2000
-
- - modified by: Gokhan Danabasoglu (08/2001)
- - port to mom4: Stephen.Griffies (9/2002) - - update to mom4p1 based on new tunes from NCAR - Stephen.Griffies (7/2007) - - - "A_viscosity" = F_PARA = Along = viscosity parallel to flow - = max{0.5*visc_vel_scale(z)*A*max[dx,dy],vconst_6} - - where
- A = 0.425 * cos(pi*y*radian/30) + 0.575 for |y*radian| < 30
- A = 0.15 otherwise - - Here, A provides a horizontal variation for visc_vel_scale. - - "B_viscosity" = F_PERP = Across = viscosity perpendicular to flow = max( bu, bv) - - and
- F_PARA = min(F_PARA, AMAX_CFL),
- F_PERP = min(F_PERP, AMAX_CFL),
- F_PARA = max(F_PARA, F_PERP)
- are enforced - - In the above equations, - - bu = vconst_1 * ( 1 + vconst_2 * ( 1 + cos( 2*y + pi ) ) )
- bv = vconst_3 * beta_f * dx^3 * exp( - (vconst_4 * distance)^2 )
- - with
- beta_f (x,y) = 2 * omega_earth* cos(ULAT(i,j)) / radius
- distance (x,y,z) = actual distance to "vconst_5" points
- west of the nearest western boundary
- dx (x,y) = DXU(i,j)
- dy (x,y) = DYU(i,j)
- visc_vel_scale (z) = vconst_7 * exp(-zt(k)/visc_vel_scale_length)
- visc_vel_scale_length = e-folding scale ( default = 1500.0e2 cm)
- y (x,y) = ULAT(i,j), latitude of "u/v" grid pts in radians
- In MOM, ULAT(radians) = xu*pi/180 with xu(i,j) the longitude of U grid points in degrees - - "vconst_#" are input parameters defined in namelist ocean_lapgen_friction_general_nml. - "vconst_1", "vconst_6", and "vconst_4" have dimensions of cm^2/s, - cm^2/s, and 1/cm, respectively. "vconst_5" is an INTEGER. - - NOTE: The nearest western boundary computations are done along the - model i-grid lines. Therefore, viscosity based on these are - only approximate in the high Northern Hemisphere when using - generalized coordinates with coordinate pole(s) shifted onto land. - -
-
-- - -
-lapgen_viscosity_check
--
-- -DESCRIPTION -
-- - Subroutine to perform linear stability check for the Laplacian - operator given a value for the horizontal biharmonic viscosity. -
-
-
-- - -
-lapgen_reynolds_check
--
-- -DESCRIPTION -
-- - Subroutine to compute the LLaplacian grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. -
-
-
-- -INPUT -
-- -
--
-- -u - Horizontal velocity field at time tau - -
[real, dimension(isd:ied,jsd:jed,nk,2)]
-- - -
-compute_neptune_velocity
--
-- -DESCRIPTION -
-- - Compute Neptune velocity. - - Method follows that used in MOM2 and MOM3 as implemented by - Greg Holloway (zounds@ios.bc.ca) and Michael Eby (eby@uvic.ca) - Coded in mom4 by Stephen.Griffies - - Neptune is calculated as an equilibrium streamfunction given by - pnep = -f*snep*snep*ht and is applied through friction whereby - the solution is damped towards the equilibrium streamfunction - rather than being damped towards zero kinetic energy. - - ht = depth of tracer cells - snep = spnep + (senep-spnep)*(0.5 + 0.5*cos(2.0*latitude)) - - Neptune length scale snep has a value of senep at the - equator and smoothly changes to spnep at the poles - - Reference: - Holloway, G., 1992: Representing topographic stress for large - scale ocean models, J. Phys. Oceanogr., 22, 1033-1046 - - Eby and Holloway, 1994: Sensitivity of a large scale ocean model - to a parameterization of topographic stress. JPO, vol. 24, - pages 2577-2588 - - March 2012 - Stephen.Griffies - Algorithm updated to Eby and Holloway (1994) - -
-
-
-
-NAMELIST
- --&ocean_lapgen_friction_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging by printing checksums. -
-
-[logical] -- -viscosity_scale_by_rossby -
-- To scale down the laplacian viscosity according to the relative scale of the - horizontal grid and the first baroclinic Rossby radius. This is a useful - scheme for models that resolve the Rossby radius in the lower latitudes, and so - presumably do not wish to have much laplacian friction, whereas the higher latitudes - need more friction. Default viscosity_scale_by_rossby=.false. -
-
-[logical] -- -viscosity_scale_by_rossby_power -
-- The power used to determine the viscosity scaling function. - Default viscosity_scale_by_rossby_power=2.0. -
-
-[real] -- -divergence_damp -
-- To damp the divergence field. -
-
-[logical] -- -divergence_damp_vel_micom -
-- Velocity scale to set the viscosity used with divergence damping. -
-
-[real, units: m/s] -- -k_smag_iso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. -
-
-[real, units: dimensionless] -- -k_smag_aniso -
-- This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. -
-
-[real, units: dimensionless] -- -viscosity_ncar -
-- Anisotropic background viscosities used by NCAR. -
-
-[logical] -- -viscosity_ncar_2000 -
-- Anisotropic background viscosities used by NCAR, using the - formulation as of 2000. Default viscosity_ncar_2000=.true. -
-
-[logical] -- -viscosity_ncar_2007 -
-- Anisotropic background viscosities used by NCAR, using the - formulation as of 2007. Default viscosity_ncar_2007=.false. -
-
-[logical] -- -vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity. -
-
-[real, units: m/sec] -- -vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity. -
-
-[real, units: m/sec] -- -equatorial_zonal -
-- Orient the anisotropic friction within a latitudinal band according to zonal direction. -
-
-[logical] -- -equatorial_zonal_lat -
-- Latitudinal band to use the zonal friction orientation. -
-
-[real] -- -ncar_isotropic_off_equator -
-- Polewards of equatorial_zonal_lat, revert NCAR scheme to isotropic -
-
-[logical] -- -equatorial_no_smag -
-- Turn smag off within equatorial_zonal_lat region. -
-
-[logical] -- -eq_vel_micom_iso -
-- Velocity scale that is used for computing the MICOM isotropic viscosity within - a user specified equatorial band. -
-
-[real] -- -eq_vel_micom_aniso -
-- Velocity scale that is used for computing the MICOM anisotropic viscosity within - a user specified equatorial band. -
-
-[real] -- -eq_lat_micom -
-- Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom_iso and eq_vel_micom_aniso. -
-
-[real] -- -restrict_polar_visc -
-- For restricting the background viscosity poleward of a - latitude. This method may be useful for coupling to an ice model - in which case the horizontal viscosity may need to be a bit - smaller to maintain time step constraints. This is because the - effective friction is larger than that just within the ocean. -
-
-[logical] -- -restrict_polar_visc_lat -
-- Latitude poleward of which we restrict the viscosity. -
-
-[real] -- -restrict_polar_visc_ratio -
-- Ratio of the normal critical value that we limit the - viscosity to be no greater than. If restrict_polar_visc_ratio=1.0 - then there is no special limitation of the viscosity beyond that - of the one-dimensional stability constraint. -
-
-[real] -- -bottom_5point -
-- To alleviate problems with small partial cells, it is often necessary to reduce the - operator to the traditional 5-point Laplacian at the ocean bottom. This logical - implements this mixing. Default bottom_5point=.false. -
-
-[logical] -- -neptune -
-- Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. -
-
-[logical] -- -neptune_length_eq -
-- Length scale used to compute Neptune velocity at equator. -
-
-[real, units: m] -- -neptune_length_pole -
-- Length scale used to compute Neptune velocity at pole. -
-
-[real, units: m] -- -neptune_depth_min -
-- Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 -
-
-[real, units: m] -- -neptune_smooth -
-- For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. -
-
-[logical] -- -neptune_smooth_num -
-- Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. -
-
-[integer] -- -vconst_1 -
-- Background viscosity for NCAR algorithm. -
-
-[real, units: cm^2/sec] -- -vconst_2 -
-- For NCAR viscosity algorithm. -
-
-[real] -- -vconst_3 -
-- For NCAR viscosity algorithm. -
-
-[real] -- -vconst_4 -
-- For NCAR viscosity algorithm. -
-
-[real, units: 1/cm] -- -vconst_5 -
-- For NCAR viscosity algorithm. -
-
-[integer] -- -vconst_6 -
-- For NCAR viscosity algorithm. -
-
-[real, units: cm^2/sec] -- -vconst_7 -
-- For NCAR viscosity algorithm. -
-
-[, units: cm/sec] -- -vconst_8 -
-- For NCAR viscosity algorithm. -
-
-[, units: degrees] -- -visc_vel_scale_length -
-- For NCAR viscosity algorithm: efolding depth for - depth dependent background viscosity. - Default visc_vel_scale_length=1500.e2 cm -
-
-[, units: cm] -- -ncar_isotropic_at_depth -
-- Sets the NCAR scheme to be isotropic beneath a chosen depth. -
-
-[logical] -- -ncar_isotropic_depth -
-- Sets the NCAR scheme to be isotropic beneath this chosen depth. -
-
-[real, units: m] -- -ncar_isotropic_at_depth_visc -
-- Sets the NCAR scheme to be isotropic beneath this chosen depth, with - minimum viscosity set according to this value. -
-
-[real, units: m2/sec] -- -debug_ncar_A -
-- Sets f_perp=f_para for debugging purposes with the NCAR scheme. -
-
-[logical] -- -debug_ncar_B -
-- Sets f_para=f_perp for debugging purposes with the NCAR scheme. -
-
-[logical] -- -use_side_drag_friction -
-- For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. -
-
-[logical] -- -side_drag_friction_scaling -
-- Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. -
-
-[real] -- -side_drag_friction_uvmag_max -
-- Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. -
-
-[real, units: m/s] -- -side_drag_friction_max -
-- Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations. - Default side_drag_friction_max=1.0. -
-
-[real, units: N/m^2] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use in large-scale - eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946 -
-- - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
-- - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
-- - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
-- - Griffies: Elements of MOM (2012) -
-
- - -
-NOTES
- -- The ocean model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. --
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_lapgen_friction.xml b/src/mom5/ocean_param/lateral/ocean_lapgen_friction.xml deleted file mode 100644 index 3d3495da77..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_lapgen_friction.xml +++ /dev/null @@ -1,328 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_mixdownslope.F90 b/src/mom5/ocean_param/lateral/ocean_mixdownslope.F90 index f9a05c52af..d0241a18ac 100644 --- a/src/mom5/ocean_param/lateral/ocean_mixdownslope.F90 +++ b/src/mom5/ocean_param/lateral/ocean_mixdownslope.F90 @@ -191,9 +191,9 @@ module ocean_mixdownslope_mod character(len=128) :: version=& - '=>Using: ocean_mixdownslope.f90 ($Id: ocean_mixdownslope.F90,v 1.1.2.2 2012/05/17 13:41:45 smg Exp $)' + '=>Using: ocean_mixdownslope.f90 ($Id: ocean_mixdownslope.F90,v 20.0 2013/12/14 00:14:28 fms Exp $)' character (len=128) :: tagname=& - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! number of prognostic tracers integer :: num_prog_tracers=0 @@ -894,8 +894,16 @@ subroutine mixdownslope (Time, Thickness, T_prog, Dens, index_temp, index_salt) enddo enddo - if(id_mixdownslope(nt) > 0) then - call diagnose_3d(Time, Grd, id_mixdownslope(nt), T_prog(nt)%conversion*tend_mix(:,:,:)) + if(id_mixdownslope(nt) > 0) then + wrk1(:,:,:) = 0.0 + do k=1,nk + do j=jsc,jec + do i=isc,iec + wrk1(i,j,k) = tend_mix(i,j,k)*mixdownslope_mask(i,j) + enddo + enddo + enddo + call diagnose_3d(Time, Grd, id_mixdownslope(nt), wrk1(:,:,:)) endif if(nt==index_temp) then diff --git a/src/mom5/ocean_param/lateral/ocean_mixdownslope.html b/src/mom5/ocean_param/lateral/ocean_mixdownslope.html deleted file mode 100644 index 494575e3ad..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_mixdownslope.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - S. M. Griffies - - This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - - This module computes the thickness weighted time tendency for - horizontal velocity arising from horizontal Laplacian friction. - The viscosity used to determine the strength of the tendency - can be a general function of space and time as specified by - the Smagorinsky approach as well as a grid-scale dependent - background viscosity. The form of the friction operator - can be isotropic or anisotropic in the horizontal plane. - - S.M. Griffies and R.W. Hallberg, 2000: - Biharmonic friction with a Smagorinsky viscosity for use in large-scale - eddy-permitting ocean models - Monthly Weather Review, vol. 128, pages 2935-2946 - - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. - - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. - - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. - - Griffies: Elements of MOM (2012) - - The ocean model can generally run with both Laplacian and biharmonic friction - enabled at the same time. Such has been found useful for some eddying - ocean simulations. - - Must be true to use this module. Default is false. - - For debugging by printing checksums. - - To scale down the laplacian viscosity according to the relative scale of the - horizontal grid and the first baroclinic Rossby radius. This is a useful - scheme for models that resolve the Rossby radius in the lower latitudes, and so - presumably do not wish to have much laplacian friction, whereas the higher latitudes - need more friction. Default viscosity_scale_by_rossby=.false. - - The power used to determine the viscosity scaling function. - Default viscosity_scale_by_rossby_power=2.0. - - To damp the divergence field. - - Velocity scale to set the viscosity used with divergence damping. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky isotropic viscosity. - - This is the dimensionless Smagorinsky coefficient used to set the scale - of the Smagorinsky anisotropic viscosity. - - Anisotropic background viscosities used by NCAR. - - Anisotropic background viscosities used by NCAR, using the - formulation as of 2000. Default viscosity_ncar_2000=.true. - - Anisotropic background viscosities used by NCAR, using the - formulation as of 2007. Default viscosity_ncar_2007=.false. - - Velocity scale that is used for computing the MICOM isotropic viscosity. - - Velocity scale that is used for computing the MICOM anisotropic viscosity. - - Orient the anisotropic friction within a latitudinal band according to zonal direction. - - Latitudinal band to use the zonal friction orientation. - - Polewards of equatorial_zonal_lat, revert NCAR scheme to isotropic - - Turn smag off within equatorial_zonal_lat region. - - Velocity scale that is used for computing the MICOM isotropic viscosity within - a user specified equatorial band. - - Velocity scale that is used for computing the MICOM anisotropic viscosity within - a user specified equatorial band. - - Equatorial latitude band (degrees) within which the MICOM viscosity is set according - to eq_vel_micom_iso and eq_vel_micom_aniso. - - For restricting the background viscosity poleward of a - latitude. This method may be useful for coupling to an ice model - in which case the horizontal viscosity may need to be a bit - smaller to maintain time step constraints. This is because the - effective friction is larger than that just within the ocean. - - Latitude poleward of which we restrict the viscosity. - - Ratio of the normal critical value that we limit the - viscosity to be no greater than. If restrict_polar_visc_ratio=1.0 - then there is no special limitation of the viscosity beyond that - of the one-dimensional stability constraint. - - To alleviate problems with small partial cells, it is often necessary to reduce the - operator to the traditional 5-point Laplacian at the ocean bottom. This logical - implements this mixing. Default bottom_5point=.false. - - Set to true for computing friction relative to Neptune barotropic velocity. - Default neptune=.false. - - Length scale used to compute Neptune velocity at equator. - - Length scale used to compute Neptune velocity at pole. - - Minimum depth scale used for computing Neptune velocity. - Default neptune_depth_min=100.0 - - For doing a horizontal 1-2-1 smoothing on the diagnosed - neptune velocity scale. - Default neptune_smooth=.true. - - Number of smoothing passes for neptune velocity. - Default neptune_smooth_num=1. - - Background viscosity for NCAR algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm. - - For NCAR viscosity algorithm: efolding depth for - depth dependent background viscosity. - Default visc_vel_scale_length=1500.e2 cm - - Sets the NCAR scheme to be isotropic beneath a chosen depth. - - Sets the NCAR scheme to be isotropic beneath this chosen depth. - - Sets the NCAR scheme to be isotropic beneath this chosen depth, with - minimum viscosity set according to this value. - - Sets f_perp=f_para for debugging purposes with the NCAR scheme. - - Sets f_para=f_perp for debugging purposes with the NCAR scheme. - - For converting friction at U-cells next to walls into - a drag law, as per Deremble et al. Use cdbot_array - from ocean_core/ocean_bbc.F90 to compute drag force. - Default use_side_drag_friction=.false. - - Dimensionless scaling used for cdbot_array when setting - side drag friction. So the effective side dragy coefficient - is side_drag_friction_scaling*cdbot_array. - Default side_drag_friction_scaling=1.0. - - Maximum magnitude of horizontal velocity used to compute the - side drag friction. This parameter can be useful especially - for pressure models where the bottom cells can be quite thin - and subject to sporadic large magnitudes. We do the same thing with - bottom drag calculations. - Default side_drag_friction_uvmag_max=10.0. - - Maximum magnitude of the side drag induced friction. - This parameter can be useful especially for pressure models - where the bottom cells can be quite thin and subject to sporadic - large magnitudes. We do the same thing with bottom drag calculations. - Default side_drag_friction_max=1.0. - - Initialize the horizontal Laplacian friction module by - registering fields for diagnostic output and performing some - numerical checks to see that viscosity is set appropriately. - - This routine computes thickness weighted and density weighted - time tendency for horizontal velocity arising from horizontal - Laplacian friction. - - The algorithm is derived from a functional approach that ensures - kinetic energy is consistenty dissipated for all flow configurations. - The triad do-loops are expanded in order to enhance the - ability of cache-based machines to keep most of the variables - on-cache. - - Fundamental to the scheme are the rates of horizontal deformation
- horizontal tension = DT = (dy)(u/dy)_x - (dx)(v/dx)_y
- horizontal strain = DS = (dx)(u/dx)_y + (dy)(v/dy)_x
- Units of the tension and strain are sec^-1. - - Four tensions and four strains are computed for each velocity point,
- corresponding to the four triads surrounding the point.
- The following notation is used to distinguish the triads:
- (0,1)=northwest triad (1,1)=northeast triad,
- (0,0)=southwest triad, (1,0)=southeast triad - - A triad contributes when at least one of its velocities is - not a land point. In order to obtain the correct tension - and strain next to boundaries, tension and strain should not be - masked with umask. - -- Compute backwards derivative in X of a quantity defined on the east - face of a U-cell. Slightly modified version of BDX_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i-1/2,j). - - BDX_EU_smag(a) has dimensions of a*m^-3 - - - field defined on the east face of a U-cell - - Compute backwards derivative in Y of a quantity defined on the north - face of a U-cell. Slightly modified version of BDY_EU used in - ocean_operators.F90. If input is a(i,j) then output is defined - at (i,j-1/2) - - BDY_NU_smag(a) has dimensions of a*m^-3 - - - field defined on the north face of a U-cell - - - Spatially-varying anisotropic viscosity initialization - - This routine defines NCOM-like spatial distributions of - viscosity coefficients F_PARA and F_PERP. - Uses NCAR CCSM2.0 algorithm with cm^2/sec --> m^2/sec. - - written by: Stephen Yeager 3/2000
- - modified by: Gokhan Danabasoglu (08/2001)
- - port to mom4: Stephen.Griffies (9/2002) - - update to mom4p1 based on new tunes from NCAR - Stephen.Griffies (7/2007) - - - "A_viscosity" = F_PARA = Along = viscosity parallel to flow - = max{0.5*visc_vel_scale(z)*A*max[dx,dy],vconst_6} - - where
- A = 0.425 * cos(pi*y*radian/30) + 0.575 for |y*radian| < 30
- A = 0.15 otherwise - - Here, A provides a horizontal variation for visc_vel_scale. - - "B_viscosity" = F_PERP = Across = viscosity perpendicular to flow = max( bu, bv) - - and
- F_PARA = min(F_PARA, AMAX_CFL),
- F_PERP = min(F_PERP, AMAX_CFL),
- F_PARA = max(F_PARA, F_PERP)
- are enforced - - In the above equations, - - bu = vconst_1 * ( 1 + vconst_2 * ( 1 + cos( 2*y + pi ) ) )
- bv = vconst_3 * beta_f * dx^3 * exp( - (vconst_4 * distance)^2 )
- - with
- beta_f (x,y) = 2 * omega_earth* cos(ULAT(i,j)) / radius
- distance (x,y,z) = actual distance to "vconst_5" points
- west of the nearest western boundary
- dx (x,y) = DXU(i,j)
- dy (x,y) = DYU(i,j)
- visc_vel_scale (z) = vconst_7 * exp(-zt(k)/visc_vel_scale_length)
- visc_vel_scale_length = e-folding scale ( default = 1500.0e2 cm)
- y (x,y) = ULAT(i,j), latitude of "u/v" grid pts in radians
- In MOM, ULAT(radians) = xu*pi/180 with xu(i,j) the longitude of U grid points in degrees - - "vconst_#" are input parameters defined in namelist ocean_lapgen_friction_general_nml. - "vconst_1", "vconst_6", and "vconst_4" have dimensions of cm^2/s, - cm^2/s, and 1/cm, respectively. "vconst_5" is an INTEGER. - - NOTE: The nearest western boundary computations are done along the - model i-grid lines. Therefore, viscosity based on these are - only approximate in the high Northern Hemisphere when using - generalized coordinates with coordinate pole(s) shifted onto land. - -- Subroutine to perform linear stability check for the Laplacian - operator given a value for the horizontal biharmonic viscosity. - - Subroutine to compute the LLaplacian grid Reynolds number. Large - Reynolds numbers indicate regions where solution may experience - some grid noise due to lack of enough horizontal friction. - - Horizontal velocity field at time tau - - Compute Neptune velocity. - - Method follows that used in MOM2 and MOM3 as implemented by - Greg Holloway (zounds@ios.bc.ca) and Michael Eby (eby@uvic.ca) - Coded in mom4 by Stephen.Griffies - - Neptune is calculated as an equilibrium streamfunction given by - pnep = -f*snep*snep*ht and is applied through friction whereby - the solution is damped towards the equilibrium streamfunction - rather than being damped towards zero kinetic energy. - - ht = depth of tracer cells - snep = spnep + (senep-spnep)*(0.5 + 0.5*cos(2.0*latitude)) - - Neptune length scale snep has a value of senep at the - equator and smoothly changes to spnep at the poles - - Reference: - Holloway, G., 1992: Representing topographic stress for large - scale ocean models, J. Phys. Oceanogr., 22, 1033-1046 - - Eby and Holloway, 1994: Sensitivity of a large scale ocean model - to a parameterization of topographic stress. JPO, vol. 24, - pages 2577-2588 - - March 2012 - Stephen.Griffies - Algorithm updated to Eby and Holloway (1994) - - Module ocean_mixdownslope_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_mixdownslope_mod
- - - - - -
-OVERVIEW
- -- Mixing of tracer between dense shallow parcel and - deeper parcels downslope. -
- - - -- Mixing of tracer properties as dense shallow parcel is discharged - into deeper water to approach the parcel's depth of neutral buoyancy. - This module can be characterized as a mixture of the approach from - Campin and Goosse (1999) and slope convection. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_mixdownslope_init:
- -- -mixdownslope:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_mixdownslope_init
--
-- -DESCRIPTION -
-- - Initial set up for mixing of tracers into the abyss next to topography. -
-
-
-- - -
-mixdownslope
--
-- -DESCRIPTION -
-- - Compute thickness and density weighted tracer tendency [tracer*rho*m/s] - due to exchange of tracer properties in regions where density-driven - downslope transport is favorable. - - Allow for exchanges to occur over horizontally - distant points, so long as the dense shallow parcel finds that it - will sit on the bottom of the horizontally adjacent columns. Doing - so requires a search algorithm, which requires some if-test logic - as well as extended halos. Note that the halos cannot be extended - to larger than the size of the computational domain on a processor. - This restriction limits the extent that we can search horizontally. - - The rates for the exchange are functions of the topographic slope - and the density differences between parcels. - - This scheme can be characterized as a slope convection based on - logic incorporated into the overflow and overexchange schemes. - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from mixdownslope on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_mixdownslope_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging -
-
-[logical] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. -
-
-[logical] -- -mixdownslope_npts -
-- Number of horizontally distant points used in search downslope. - Note: it is not possible to have - mixdownslope_npts greater than or equal to the computational domain - extents, as this would require updates across multiple processors. - Default mixdownslope_npts=1. -
-
-[integer] -- -mixdownslope_frac_central -
-- Fraction of the central cell that participates in downslope mixing - in any particular direction. Default mixdownslope_frac_central=0.25 -
-
-[real] -- -mixdownslope_weight_far -
-- To place more weight on points further from central point. This may - be done to enhance properties getting downslope. Default is - mixdownslope_weight_far=.false. -
-
-[logical] -- -mixdownslope_width -
-- Width of the re-weighting function used to emphasize points further - along in the search for exchange points. Default mixdownslope_width=1. -
-
-[integer] -- -read_mixdownslope_mask -
-- For reading in a mask that selects regions of the domain - where mixdownslope is allowed to function (mask=1) or not - to function (mask=0). Default read_mixdownslope_mask=.false., - whereby mixdownslope_mask is set to tmask(k=1). -
-
-[logical] -- -mixdownslope_mask_gfdl -
-- For modifying the mixdownslope mask based on reading in - the GFDL regional mask. Default mixdownslope_mask_gfdl=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 -
-- - S.M. Griffies: Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_mixdownslope.xml b/src/mom5/ocean_param/lateral/ocean_mixdownslope.xml deleted file mode 100644 index a76672a800..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_mixdownslope.xml +++ /dev/null @@ -1,76 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_sigma_transport.F90 b/src/mom5/ocean_param/lateral/ocean_sigma_transport.F90 index 098929975c..cb63c75e37 100644 --- a/src/mom5/ocean_param/lateral/ocean_sigma_transport.F90 +++ b/src/mom5/ocean_param/lateral/ocean_sigma_transport.F90 @@ -342,9 +342,9 @@ module ocean_sigma_transport_mod integer :: index_salt=-1 character(len=128) :: version=& - '$Id: ocean_sigma_transport.F90,v 1.1.2.2 2012/05/17 13:41:45 smg Exp $' + '$Id: ocean_sigma_transport.F90,v 20.0 2013/12/14 00:14:30 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: unit=6 logical :: module_is_initialized = .FALSE. diff --git a/src/mom5/ocean_param/lateral/ocean_sigma_transport.html b/src/mom5/ocean_param/lateral/ocean_sigma_transport.html deleted file mode 100644 index 69673c4605..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_sigma_transport.html +++ /dev/null @@ -1,519 +0,0 @@ - - - - S.M. Griffies - - Mixing of tracer between dense shallow parcel and - deeper parcels downslope. - - Mixing of tracer properties as dense shallow parcel is discharged - into deeper water to approach the parcel's depth of neutral buoyancy. - This module can be characterized as a mixture of the approach from - Campin and Goosse (1999) and slope convection. - - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 - - S.M. Griffies: Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory - - For using this module. Default use_this_module=.false. - - For debugging - - Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. - - Number of horizontally distant points used in search downslope. - Note: it is not possible to have - mixdownslope_npts greater than or equal to the computational domain - extents, as this would require updates across multiple processors. - Default mixdownslope_npts=1. - - Fraction of the central cell that participates in downslope mixing - in any particular direction. Default mixdownslope_frac_central=0.25 - - To place more weight on points further from central point. This may - be done to enhance properties getting downslope. Default is - mixdownslope_weight_far=.false. - - Width of the re-weighting function used to emphasize points further - along in the search for exchange points. Default mixdownslope_width=1. - - For reading in a mask that selects regions of the domain - where mixdownslope is allowed to function (mask=1) or not - to function (mask=0). Default read_mixdownslope_mask=.false., - whereby mixdownslope_mask is set to tmask(k=1). - - For modifying the mixdownslope mask based on reading in - the GFDL regional mask. Default mixdownslope_mask_gfdl=.false. - - Initial set up for mixing of tracers into the abyss next to topography. - - Compute thickness and density weighted tracer tendency [tracer*rho*m/s] - due to exchange of tracer properties in regions where density-driven - downslope transport is favorable. - - Allow for exchanges to occur over horizontally - distant points, so long as the dense shallow parcel finds that it - will sit on the bottom of the horizontally adjacent columns. Doing - so requires a search algorithm, which requires some if-test logic - as well as extended halos. Note that the halos cannot be extended - to larger than the size of the computational domain on a processor. - This restriction limits the extent that we can search horizontally. - - The rates for the exchange are functions of the topographic slope - and the density differences between parcels. - - This scheme can be characterized as a slope convection based on - logic incorporated into the overflow and overexchange schemes. - - - Initialization of watermass diagnostic output files. - - Diagnose effects from mixdownslope on the watermass transformation. - Module ocean_sigma_transport_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_sigma_transport_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted and density weighted time tendency for - tracer from transport within a bottom "sigma" layer. - The advective portion of this routine is experimental, - and has many problems. It is retained in MOM for - exploratory use only. Also note that the advection - contributes a lot of instability when running realistic - simulations with pressure vertical coordinates. The - instability mechanism is unknown. -
- - - -- This module computes the thickness weighted and density weighted - time tendency for tracer arising from - - 1. Laplacian diffusion within a bottom turbulent boundary layer. - - 2. Upwind advection within this layer. Advection velocities - determined by model resolved velocity and parameterized - downslope velocity. We use first order upwind tracer advection - to ensure positive definite tracer transport in the sigma - layer. As the sigma layer is a proxy for a bottom turbulent - boundary layer, the added mixing from the first order upwind - should be physically acceptable. - - CAUTION: The advective portion of this algorithm has problems - and it retained in MOM only for research purposes. It - is NOT supported for general use. - - The diffusivity used to determine the strength of the diffusion - is generally set to be a function of the local horizontal grid - spacing. Diffusivity is the sum of an a priori background plus - a velocity dependent diffusivity. It is large if there is a - a heavier parcel living adjacent within the "sigma layer" above - a lighter parcel. It is small otherwise. - - The advection is set to zero if the density is not downslope - favorable. That is, rho_{,x} * H_{,x} < 0 for downslope - flow in the x-direction, and likewise in the y-direction. - - The thickness of the bottom layer can span more than a single - bottom grid cell. This feature allows the sigma - layer thickness to undulate in time according to the convergence - or divergence of mass within the sigma layer. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_density_mod
ocean_operators_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_sigma_transport_init:
- -- -sigma_transport:
- -- -ocean_sigma_transport_restart:
- -- -ocean_sigma_transport_end:
- -- -advect_sigma_upwind:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_sigma_transport_init
--
-- -DESCRIPTION -
-- - Initialize the sigma transport module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. -
-
-
-- - -
-sigma_transport
--
-- -DESCRIPTION -
-- - This subroutine computes the thickness weighted and density - weighted time tendency for tracer arising from transport in a - bottom turbulent boundary layer. The result is stored in - tracer th_tendency. - - NOTE: In this algorithm, we ideally wish to have advection - velocity components on full data domain. Unfortunately, - from ocean_advection_velocity_mod, they are only known - on the following domains: - - Adv_vel%uhrho_et: (isd,ied) x (jsc,jed) - Adv_vel%vhrho_nt: (isc,ied) x (jsd,jed). - - So to proceed with the sigma_transport algorithm, we - transfer into local arrays and then update. These - updates may be avoided (possibly), but at the price - of much more logic in the algorithm. We choose to - instead do the updates and have less logic. This - decision may need to be revisited. - - CAUTION: The advective portion of this algorithm - has fundamental problems. It is retained in MOM - only for process physics research purposes. It is - NOT recommended for use in general use. - -
-
-
-- - -
-ocean_sigma_transport_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_sigma_transport_end
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-- - -
-advect_sigma_upwind
--
-- -DESCRIPTION -
-- - First order upwind to advect tracers in sigma layer. -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from sigma transport on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_sigma_transport_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -sigma_diffusion_on -
-- For using sigma diffusion. Default is true. -
-
-[logical] -- -sigma_advection_on -
-- For using sigma advection. Default is false. -
-
-[logical] -- -sigma_advection_sgs_only -
-- In many cases, adding the resolved transport to the - sigma-advective transport produces a tremendous level of - noise at the bottom. The problem is that there are - grid-scale features that may cause large jumps in whether - the velocity should be added or not, depending on the logic - of the scheme. For this reason, it may be prudent to remove - the resolved velocity from that contributing to the sigma - transport scheme. Note that its removal from sigma transport - does not remove the contributions of the resolved velocity - from the resolved advective transport arising from - ocean_tracer_advect_mod. It simply removes it from the - added transport arising in the sigma transport module. - Default is sigma_advection_sgs_only=.true. -
-
-[logical] -- -sigma_advection_check -
-- If true, then will only include the resolved advection - velocity in the sigma-layer if the direction of - transport is downslope favorable for enhancing deep density. - IF false, then will include the velocity regardless. - This option aims to reduce the large divergences - that occur for the case when only include the velocity - if it is favorable for deep water getting more dense. - Default is sigma_advection_check=.true. -
-
-[logical] -- -thickness_sigma_layer -
-- Initial thickness of the bottom sigma layer. -
-
-[real, units: meter] -- -thickness_sigma_min -
-- Minimum thickness of the bottom sigma layer. -
-
-[real, units: meter] -- -thickness_sigma_max -
-- Maximum thickness of the bottom sigma layer. -
-
-[real, units: meter] -- -sigma_just_in_bottom_cell -
-- For just having sigma layer in the bottom cell, as in mom4p0. - This option must be .false. in order to use sigma_advection_on=.true. - Default sigma_just_in_bottom_cell=.true. -
-
-[logical] -- -tmask_sigma_on -
-- IF .true. then masks out fluxes passing into the sigma layer, except those - associated with sigma transport. Typically set to .false. -
-
-[logical] -- -sigma_diffusivity -
-- Sigma tracer diffusivity for use if not using micom diffusivity. -
-
-[real, units: m^2/sec] -- -sigma_diffusivity_ratio -
-- When flow along sigma surface is stable (i.e., heavy parcels are below lighter parcels) - then sigma diffusivity is reduced by sigma_diffusivity_ratio from the case where - heavy parcels are above lighter parcels. -
-
-[real, units: dimensionless] -- -tracer_mix_micom -
-- If .true., then the sigma diffusivity is set according to a velocity scale - times the grid spacing. -
-
-[logical] -- -vel_micom -
-- Velocity scale that is used for computing the MICOM diffusivity. -
-
-[real, units: m/sec] -- -campingoose_mu -
-- Dissipation rate for the bottom friction. Campin and Goosse - suggest campingoose_mu=10^-4 -
-
-[real, units: inverse seconds] -- -campingoose_delta -
-- Fraction of a grid cell participating in the overflow process. - Campin and Goosse suggest campingoose_delta=1/3. -
-
-[real, units: dimensionless] -- -sigma_umax -
-- Maximum downslope speed allowed in sigma layer. - In some cases, the model will be unstable if sigma_umax - is too large. -
-
-[real, units: m/s] -- -smooth_sigma_velocity -
-- To smooth the sigma advective transport velocity. - Default is smooth_sigma_velocity=.true. -
-
-[logical] -- -smooth_sigma_thickness -
-- To smooth the sigma thickness. This may be needed especially - for case with sigma advection, in which case the thickness - can become noisy. Default is smooth_sigma_thickness=.true. -
-
-[logical] -- -sigma_velmicom -
-- For smoothing the sigma_thickness, use this as velocity scale to - determine the thickness diffusivity. - Default is smooth_velmicom = 0.2 -
-
-[real, units: m/s] -
- - - - -
-REFERENCES
- ----
-- - A. Beckmann and R. Doscher, 1997: A method for improved - representation of dense water spreading over - topography in geopotential--coordinate models - Journal of Physical Oceanography, vol 27, - pages 581--59. -
-- - R. Doscher and A. Beckmann, 2000: - Effects of a bottom boundary layer parameterization - in a coarse-resolution model of the North Atlantic Ocean - Journal of Atmospheric and Oceanic Technology, - vol 17 pages 698--707 -
-- - Campin and Goosse 1999: Parameterization of density-driven downsloping - flow for a coarse-resolution model in z-coordinate", Tellus 51A, - pages 412-430. -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_sigma_transport.xml b/src/mom5/ocean_param/lateral/ocean_sigma_transport.xml deleted file mode 100644 index 78f28c7598..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_sigma_transport.xml +++ /dev/null @@ -1,182 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/lateral/ocean_submesoscale.F90 b/src/mom5/ocean_param/lateral/ocean_submesoscale.F90 index 94b9d3cb1b..1d20cb7686 100644 --- a/src/mom5/ocean_param/lateral/ocean_submesoscale.F90 +++ b/src/mom5/ocean_param/lateral/ocean_submesoscale.F90 @@ -352,7 +352,7 @@ module ocean_submesoscale_mod type(ocean_domain_type), save :: Dom_flux_sub character(len=128) :: version='$$' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character (len=128) :: tagname = '$Name: tikal $' #ifdef MOM_STATIC_ARRAYS diff --git a/src/mom5/ocean_param/lateral/ocean_submesoscale.html b/src/mom5/ocean_param/lateral/ocean_submesoscale.html deleted file mode 100644 index 7e6e7c5efa..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_submesoscale.html +++ /dev/null @@ -1,929 +0,0 @@ - - - - Stephen M. Griffies - - Thickness weighted and density weighted time tendency for - tracer from transport within a bottom "sigma" layer. - The advective portion of this routine is experimental, - and has many problems. It is retained in MOM for - exploratory use only. Also note that the advection - contributes a lot of instability when running realistic - simulations with pressure vertical coordinates. The - instability mechanism is unknown. - - This module computes the thickness weighted and density weighted - time tendency for tracer arising from - - 1. Laplacian diffusion within a bottom turbulent boundary layer. - - 2. Upwind advection within this layer. Advection velocities - determined by model resolved velocity and parameterized - downslope velocity. We use first order upwind tracer advection - to ensure positive definite tracer transport in the sigma - layer. As the sigma layer is a proxy for a bottom turbulent - boundary layer, the added mixing from the first order upwind - should be physically acceptable. - - CAUTION: The advective portion of this algorithm has problems - and it retained in MOM only for research purposes. It - is NOT supported for general use. - - The diffusivity used to determine the strength of the diffusion - is generally set to be a function of the local horizontal grid - spacing. Diffusivity is the sum of an a priori background plus - a velocity dependent diffusivity. It is large if there is a - a heavier parcel living adjacent within the "sigma layer" above - a lighter parcel. It is small otherwise. - - The advection is set to zero if the density is not downslope - favorable. That is, rho_{,x} * H_{,x} < 0 for downslope - flow in the x-direction, and likewise in the y-direction. - - The thickness of the bottom layer can span more than a single - bottom grid cell. This feature allows the sigma - layer thickness to undulate in time according to the convergence - or divergence of mass within the sigma layer. - - - A. Beckmann and R. Doscher, 1997: A method for improved - representation of dense water spreading over - topography in geopotential--coordinate models - Journal of Physical Oceanography, vol 27, - pages 581--59. - - R. Doscher and A. Beckmann, 2000: - Effects of a bottom boundary layer parameterization - in a coarse-resolution model of the North Atlantic Ocean - Journal of Atmospheric and Oceanic Technology, - vol 17 pages 698--707 - - Campin and Goosse 1999: Parameterization of density-driven downsloping - flow for a coarse-resolution model in z-coordinate", Tellus 51A, - pages 412-430. - - S.M. Griffies: Elements of MOM (2012) - - Must be true to use this module. Default is false. - - For debugging. - - For using sigma diffusion. Default is true. - - For using sigma advection. Default is false. - - In many cases, adding the resolved transport to the - sigma-advective transport produces a tremendous level of - noise at the bottom. The problem is that there are - grid-scale features that may cause large jumps in whether - the velocity should be added or not, depending on the logic - of the scheme. For this reason, it may be prudent to remove - the resolved velocity from that contributing to the sigma - transport scheme. Note that its removal from sigma transport - does not remove the contributions of the resolved velocity - from the resolved advective transport arising from - ocean_tracer_advect_mod. It simply removes it from the - added transport arising in the sigma transport module. - Default is sigma_advection_sgs_only=.true. - - If true, then will only include the resolved advection - velocity in the sigma-layer if the direction of - transport is downslope favorable for enhancing deep density. - IF false, then will include the velocity regardless. - This option aims to reduce the large divergences - that occur for the case when only include the velocity - if it is favorable for deep water getting more dense. - Default is sigma_advection_check=.true. - - Initial thickness of the bottom sigma layer. - - Minimum thickness of the bottom sigma layer. - - Maximum thickness of the bottom sigma layer. - - For just having sigma layer in the bottom cell, as in mom4p0. - This option must be .false. in order to use sigma_advection_on=.true. - Default sigma_just_in_bottom_cell=.true. - - IF .true. then masks out fluxes passing into the sigma layer, except those - associated with sigma transport. Typically set to .false. - - Sigma tracer diffusivity for use if not using micom diffusivity. - - When flow along sigma surface is stable (i.e., heavy parcels are below lighter parcels) - then sigma diffusivity is reduced by sigma_diffusivity_ratio from the case where - heavy parcels are above lighter parcels. - - If .true., then the sigma diffusivity is set according to a velocity scale - times the grid spacing. - - Velocity scale that is used for computing the MICOM diffusivity. - - Dissipation rate for the bottom friction. Campin and Goosse - suggest campingoose_mu=10^-4 - - Fraction of a grid cell participating in the overflow process. - Campin and Goosse suggest campingoose_delta=1/3. - - Maximum downslope speed allowed in sigma layer. - In some cases, the model will be unstable if sigma_umax - is too large. - - To smooth the sigma advective transport velocity. - Default is smooth_sigma_velocity=.true. - - To smooth the sigma thickness. This may be needed especially - for case with sigma advection, in which case the thickness - can become noisy. Default is smooth_sigma_thickness=.true. - - For smoothing the sigma_thickness, use this as velocity scale to - determine the thickness diffusivity. - Default is smooth_velmicom = 0.2 - - Initialize the sigma transport module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. - - This subroutine computes the thickness weighted and density - weighted time tendency for tracer arising from transport in a - bottom turbulent boundary layer. The result is stored in - tracer th_tendency. - - NOTE: In this algorithm, we ideally wish to have advection - velocity components on full data domain. Unfortunately, - from ocean_advection_velocity_mod, they are only known - on the following domains: - - Adv_vel%uhrho_et: (isd,ied) x (jsc,jed) - Adv_vel%vhrho_nt: (isc,ied) x (jsd,jed). - - So to proceed with the sigma_transport algorithm, we - transfer into local arrays and then update. These - updates may be avoided (possibly), but at the price - of much more logic in the algorithm. We choose to - instead do the updates and have less logic. This - decision may need to be revisited. - - CAUTION: The advective portion of this algorithm - has fundamental problems. It is retained in MOM - only for process physics research purposes. It is - NOT recommended for use in general use. - - - Write out restart files registered through register_restart_file - - Write to restart. - - First order upwind to advect tracers in sigma layer. - - Initialization of watermass diagnostic output files. - - Diagnose effects from sigma transport on the watermass transformation. - Module ocean_submesoscale_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_submesoscale_mod
- - - - - -
-OVERVIEW
- -- This module computes a streamfunction within - the upper surface boundary layer, and applies this - streamfunction to all tracers. It also optionally - applies horizontal diffusion in the surface layer - as determined by the strength of the streamfunction. -
- - - -- This module computes a streamfunction within - the upper surface boundary layer, and applies this - streamfunction to all tracers. It also optionally - applies horizontal diffusion in the surface layer - as determined by the strength of the streamfunction. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_tracer_diag_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_submesoscale_init:
- -- -submeso_restrat:
- -- -compute_bldepth:
- -- -tracer_derivs:
- -- -salinity_derivs:
- -- -compute_psi:
- -- -compute_psi_legacy:
- -- -compute_transport:
- -- -compute_submeso_skewsion:
- -- -compute_flux_x:
- -- -compute_flux_y:
- -- -compute_flux_z:
- -- -compute_submeso_upwind:
- -- -compute_submeso_sweby:
- -- -compute_submeso_diffusion:
- -- -maximum_bottom_w_general:
- -- -transport_on_nrho_submeso:
- -- -transport_on_nrho_submeso_adv:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -- -watermass_diag_diffusion:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_submesoscale_init
--
-- -DESCRIPTION -
-- - Initialization for the ocean_submesoscale module. -
-
-
-- - -
-submeso_restrat
--
-- -DESCRIPTION -
-- - This routine computes a thickness and density weighted time tendency - for each tracer, arising from the effects of parameterized - submesoscale eddies acting in the surface mixed layer. -
-
-
-- - -
-compute_bldepth
--
-- -DESCRIPTION -
-- - Compute the boundary layer depth and kblt. -
-
-
-- - -
-tracer_derivs
--
-- -DESCRIPTION -
-- - Compute the tracer derivatives, with the - lateral derivatives computed along constant k-level. -
-
-
-- - -
-salinity_derivs
--
-- -DESCRIPTION -
-- - Compute the density-salinity derivatives, with lateral - derivative computed on constant k-level. -
-
-
-- - -
-compute_psi
--
-- -DESCRIPTION -
-- - Compute the vector streamfunction from parameterized - submesoscale restratification. - - Units of psi are m^2/sec - - psix is defined on north face of tracer cell for jq=0,1. - psiy is defined on east face of tracer cell for ip=0,1. - - NOTE: the mpp updates for psix and psiy are treated as a - scalar, whereas they are actually components to a pseudo-vector. - Some further thought is required for the tripolar grid. We ignore - this detail in the present implementation. - -
-
-
-- - -
-compute_psi_legacy
--
-- -DESCRIPTION -
-- - Compute the vector streamfunction - - Units of psi are m^2/sec - - If computing skewsion tendency, then need psi at depth_zt. - If computing advection tendency, then need psi at depth_zwt. - - Jan2012: This scheme has problems with the limiters and smoothers. - These problems become particularly egregious when trying to compute - an advective flux rather than a skew flux. This routine is - retained only for legacy purposes. - Stephen.Griffies - -
-
-
-- - -
-compute_transport
--
-- -DESCRIPTION -
-- - Compute the mass transport from submeso. - - This routine is a diagnostic routine if skewsion, and - part of the calculation of the eddy-induced velocity if - advective approach used. - - Comments on the scheme: - - 1/ compute vertical component from convergence of horizontal, just - as for the vertical velocity component for the Eulerian transport. - - 2/ wrho_bt_submeso(:,:,k=0) = 0.0 by definition - - 3/ expand the BDX_ET and BDY_NT operators for efficiency. - - 4/ mask to zero those regions where the horizontal divergence - vanishes, as these are regions beneath the submeso boundary - layer. Base the mask on horz divergence rather than kblt(i,j), - since any smoothing performed to uhrho_et_submeso and vhrho_nt_submeso - will modify the region of nonzero submesoscale advection so that - it reaches potentially to below kblt. - -
-
-
-- - -
-compute_submeso_skewsion
--
-- -DESCRIPTION -
-- - Compute tendency from submeso skewsion. -
-
-
-- - -
-compute_flux_x
--
-- -DESCRIPTION -
-- - - Subroutine computes the zonal submesoscale tracer skew flux component. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-compute_flux_y
--
-- -DESCRIPTION -
-- - - Subroutine computes the meridional submesoscale tracer skew flux component. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-compute_flux_z
--
-- -DESCRIPTION -
-- - - Subroutine computes the vertical submeso tracer skew flux component. - - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - -
-
-
-- - -
-compute_submeso_upwind
--
-- -DESCRIPTION -
-- - First order upwind to compute the tendency from submeso advection. - - Although this method adds diffusion, some of the mixing - is physically relevant. Absent this mixing, the submesoscale - parameterization is incomplete. The submesoscale parameterization is, - afterall, active only in the mixed layer, where there is lot of - physical mixing. - - Use of first order upwind ensures that the tendency computed - from submesoscale parameterization will not, in principle, - introduce extrema. However, there remain some issues with large - tendencies appearing near boundaries that may compromise this - monotonicity property. - - Apply masks so that there is no flux leaving cell next to bottom. - -
-
-
-- - -
-compute_submeso_sweby
--
-- -DESCRIPTION -
-- - Sweby scheme to compute the tendency from submeso advection. - Algorithm taken after advect_tracer_sweby_all in the module - ocean_tracers/ocean_tracer_advect.F90. - - Jan 2012: Stephen.Griffies - This scheme has known bugs; it is not meant for general use. - -
-
-
-- - -
-compute_submeso_diffusion
--
-- -DESCRIPTION -
-- - Compute tendency from submeso horizontal diffusion. -
-
-
-- - -
-maximum_bottom_w_general
--
-- -DESCRIPTION -
-- - Compute maximum vertical velocity from submeso. -
-
-
-- - -
-transport_on_nrho_submeso
--
-- -DESCRIPTION -
-- - Classify horizontal submeso mass transport according to neutral - density classes. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_rho_submeso, a remapping is - performed, rather than the binning done for transport_on_nrho_submeso_adv. - - This is the same algorithm as used for GM skew fluxes on rho surfaces. - - Caveat: Since the submeso scheme operates only in the mixed layer, - there are difficulties mapping this transport to neutral density - layers. The user should be mindful of the problems with this - remapping. An alternative that may be more suitable is to use - Ferret to remap the time mean submeso transport to the time mean - neutral density surfaces. There are missing correlations, but for - many purposes, the Ferret remapping may be preferable. - - Briefly, the Ferret command is the following: - - let ty_trans_nrho_submeso_new = ZAXREPLACE(TY_TRANS_SUBMESO,NEUTRAL_RHO,TY_TRANS_NRHO) - where TY_TRANS_SUBMESO is the level-space transport - NEUTRAL_RHO is the level space version of the neutral density - TY_TRANS_NRHO is any density space field whose vertical coordinates - are accessed for the remapping. -
-
-
-- - -
-transport_on_nrho_submeso_adv
--
-- -DESCRIPTION -
-- - Classify horizontal transport according to neutral density classes. - - Based on transport_on_nrho in ocean_diag/ocean_adv_diag.F90. - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from submesoscale on watermass transformation. -
-
-
-- - -
-watermass_diag_diffusion
--
-- -DESCRIPTION -
-- - Diagnose effects from submesoscale horizontal diffusion - on watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_submesoscale_nml --
-
----
-- -use_this_module= -
-- Must be .true. to use this module. -
-
-[logical] -- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -- -diag_step -
-- Number of time steps between computing max bottom value for - wrho_bt_submeso. Default diag_step=1200. -
-
-[integer] -- -submeso_skew_flux -
-- For computing the tendency as convergence of skew flux. - This is the recommended method. - Default submeso_skew_flux=.true. -
-
-[logical] -- -submeso_advect_flux -
-- For computing the tendency as convergence of advective flux. - This approach uses either a flux limited sweby advection or - first order upwind, both of which ensure that the resulting - tendency will not create extrema in the tracer field. - Default submeso_advect_flux=.false. -
-
-[logical] -- -submeso_advect_upwind -
-- For computing the tendency as convergence of a first order - advective flux. - Default submeso_advect_upwind=.true. -
-
-[logical] -- -submeso_advect_sweby -
-- For computing the tendency as convergence of a sweby - advective flux. This routine is incomplete and has a bug. - Default submeso_advect_sweby=.false. -
-
-[logical] -- -submeso_advect_limit -
-- For limiting the value of the horizontal transports - to be less than a velocity scale set by limit_psi_velocity_scale. - This option is not needed if limit_psi=.true. - Default submeso_advect_limit=.false. -
-
-[logical] -- -submeso_advect_zero_bdy -
-- For removing the advective transport next to boundaries. - This is useful since computation of the advective transport - velocity components can be problematic next to boundaries. - Default submeso_advect_zero_bdy=.false. -
-
-[logical] -- -smooth_advect_transport -
-- For doing a horizontal 1-2-1 smoothing on the diagnosed - uhrho_et_submeso and vhrho_nt_submeso fields. - Default smooth_advect_transport=.true. -
-
-[logical] -- -smooth_advect_transport_num -
-- Number of iterations for the smooothing of horizontal transport. - Default smooth_advect_transport_num=2. -
-
-[integer] -- -submeso_diag_advect_transport -
-- For diagnosing the advective mass transport even when - using the skew approach. - Default submeso_diag_advect_transport=.false. -
-
-[logical] -- -submeso_diffusion -
-- For computing a horizontal diffusive flux in the boundary layer - as determined by the strength of the vector streamfunction. - Default submeso_diffusion=.false. -
-
-[logical] -- -submeso_diffusion_biharmonic -
-- The default submeso diffusion is Laplacian. However, one may wish to - use a biharmonic mixing operator instead. - Default submeso_diffusion_biharmonic=.false. -
-
-[logical] -- -submeso_diffusion_scale -
-- A dimensionless scaling to be used for scaling up or down the effects from - horizontal diffusion in the boundary layer. Default submeso_diffusion_scale=1.0. -
-
-[real, units: dimensionless] -- -use_hblt_constant -
-- For running with a constant boundary layer depth. This for the case when - not using a realistic mixed layer scheme. Default use_hblt_constant=.false. -
-
-[logical] -- -constant_hblt -
-- The boundary layer depth for the case when use_hblt_constant=.true. - Default constant_hblt=100.0. -
-
-[real, units: metre] -- -use_hblt_equal_mld -
-- For using the diagnosed mld as the hblt for submeso. - This is useful for those test models that do not have a mixed layer - scheme enabled, such as KPP, where the mixed layer scheme provides a - boundary layer depth. In this case, it is sensible to employ the diagnosed - mixed layer depth for the submeso scheme. Additionally, in general it is - more physical to use the mld than the KPP hblt as the depth over which - the submesoscale eddies act. Hence, default use_hblt_equal_mld=.true. -
-
-[logical] -- -min_kblt -
-- The minimum number of vertical cells in the surface boundary layer - that are required in order to compute the submesoscale streamfunction. - Default min_kblt=4. Need at least three to fit a parabola with zero - streamfunction at the top and bottom of the boundary layer. -
-
-[integer, units: dimensionless] -- -minimum_hblt -
-- For setting a floor to the hblt used for submesoscale scheme. - Default minimum_hblt=0.0. -
-
-[real, units: metre] -- -smooth_hblt -
-- For smoothing on the submeso bldepth field. This is useful - since the bldepth obtained from KPP or diagnosed mld can - have some grid noise. - Default smooth_hblt=.false. since this agrees with legacy. - Note that this scheme fails to reproduce across - processor layout, so it remains broken. -
-
-[logical] -- -smooth_hblt_num -
-- Number of iterations for the smooothing of bldepth. - Default smooth_hblt_num=1. -
-
-[integer] -- -use_psi_legacy -
-- For computing psi using older legacy methods. - These methods are not ideal, and can be problematic - depending on nml settings for the limiters and smoothers. - This option is retained only for legacy purposes. - Default use_psi_legacy=.false. -
-
-[logical] -- -smooth_psi -
-- For doing a horizontal 1-2-1 smoothing on the - psix_horz and psiy_horz fields. - Default smooth_psi=.true. -
-
-[logical] -- -smooth_psi_num -
-- Number of iterations for the smooothing of psi. - Default smooth_psi_num=2. -
-
-[integer] -- -limit_psi -
-- For limiting the magnitude of psi in order to reduce possibility of - model crashes. Rescales the full psi to maintain vertical structure - but to keep overall magnitude within bounds. - Default limit_psi=.false. -
-
-[logical] -- -limit_psi_velocity_scale -
-- Velocity scale used to limit the value of psi when limit_psi=.true. - Default limit_psi_velocity_scale=5.0 -
-
-[real, units: metre/sec] -- -submeso_limit_flux -
-- For limiting the fluxes arising from submeso scheme, according to - tmask_limit. When reach a point where tmask_limit=1.0, then set - the submeso flux for this cell to zero. - Default submeso_limit_flux=.true. -
-
-[logical] -- -coefficient_ce -
-- The dimensionless coefficient from the Fox-Kemper etal scheme. - They recommend setting coefficient_ce between 0.06 and 0.08. - Default coefficient_ce=0.07. -
-
-[real, units: dimensionless] -- -time_constant -
-- Timescale to mix momentum across the mixed layer. - Default time_constant=86400.0 = 1day. -
-
-[real, units: seconds] -- -front_length_const -
-- Take constant horizontal length scale of submesoscale front. - Default front_length_const=5e3. -
-
-[real, units: metre] -- -front_length_deform_radius -
-- To compute the front length using the mixed layer deformation - radius. Default front_length_deform_radius=.true. Note, - will have a floor on the variable front length set by the - nml setting for front_length_const. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Fox-Kemper, Ferrari, and Hallberg 2008: Parameterization of - mixed layer eddies. Part I: theory and diagnosis - Journal of Physical Oceanography, vol. 38, pages 1145-1165. -
-- - Fox-Kemper, Danabasoglu, Ferrari, and Hallberg 2008: - Parameterizing submesoscale physics in global models. - Clivar Exchanges, vol 13, no.1, Jan2008. pages 3-5. -
-- - Fox-Kemper, Danabasoglu, Ferrari, Griffies, Hallberg, - Holland, Peacock, Samuels, 2011: Parameterization of - Mixed Layer Eddies. III: Global Implementation and - Impact on Ocean Climate Simulations, Ocean Modelling, - vol. 39, pages 61-78. -
-- - Griffies, 2012: Elements of MOM -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/lateral/ocean_submesoscale.xml b/src/mom5/ocean_param/lateral/ocean_submesoscale.xml deleted file mode 100644 index 13466f03fd..0000000000 --- a/src/mom5/ocean_param/lateral/ocean_submesoscale.xml +++ /dev/null @@ -1,316 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics.F90 index c70d174c94..449f576c9f 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics.F90 @@ -97,9 +97,9 @@ module ocean_nphysics_mod #include S. M. Griffies - - This module computes a streamfunction within - the upper surface boundary layer, and applies this - streamfunction to all tracers. It also optionally - applies horizontal diffusion in the surface layer - as determined by the strength of the streamfunction. - - This module computes a streamfunction within - the upper surface boundary layer, and applies this - streamfunction to all tracers. It also optionally - applies horizontal diffusion in the surface layer - as determined by the strength of the streamfunction. - - Fox-Kemper, Ferrari, and Hallberg 2008: Parameterization of - mixed layer eddies. Part I: theory and diagnosis - Journal of Physical Oceanography, vol. 38, pages 1145-1165. - - Fox-Kemper, Danabasoglu, Ferrari, and Hallberg 2008: - Parameterizing submesoscale physics in global models. - Clivar Exchanges, vol 13, no.1, Jan2008. pages 3-5. - - Fox-Kemper, Danabasoglu, Ferrari, Griffies, Hallberg, - Holland, Peacock, Samuels, 2011: Parameterization of - Mixed Layer Eddies. III: Global Implementation and - Impact on Ocean Climate Simulations, Ocean Modelling, - vol. 39, pages 61-78. - - Griffies, 2012: Elements of MOM - - Must be .true. to use this module. - - For debugging purposes. - - Number of time steps between computing max bottom value for - wrho_bt_submeso. Default diag_step=1200. - - For computing the tendency as convergence of skew flux. - This is the recommended method. - Default submeso_skew_flux=.true. - - For computing the tendency as convergence of advective flux. - This approach uses either a flux limited sweby advection or - first order upwind, both of which ensure that the resulting - tendency will not create extrema in the tracer field. - Default submeso_advect_flux=.false. - - For computing the tendency as convergence of a first order - advective flux. - Default submeso_advect_upwind=.true. - - For computing the tendency as convergence of a sweby - advective flux. This routine is incomplete and has a bug. - Default submeso_advect_sweby=.false. - - For limiting the value of the horizontal transports - to be less than a velocity scale set by limit_psi_velocity_scale. - This option is not needed if limit_psi=.true. - Default submeso_advect_limit=.false. - - For removing the advective transport next to boundaries. - This is useful since computation of the advective transport - velocity components can be problematic next to boundaries. - Default submeso_advect_zero_bdy=.false. - - For doing a horizontal 1-2-1 smoothing on the diagnosed - uhrho_et_submeso and vhrho_nt_submeso fields. - Default smooth_advect_transport=.true. - - Number of iterations for the smooothing of horizontal transport. - Default smooth_advect_transport_num=2. - - For diagnosing the advective mass transport even when - using the skew approach. - Default submeso_diag_advect_transport=.false. - - For computing a horizontal diffusive flux in the boundary layer - as determined by the strength of the vector streamfunction. - Default submeso_diffusion=.false. - - The default submeso diffusion is Laplacian. However, one may wish to - use a biharmonic mixing operator instead. - Default submeso_diffusion_biharmonic=.false. - - A dimensionless scaling to be used for scaling up or down the effects from - horizontal diffusion in the boundary layer. Default submeso_diffusion_scale=1.0. - - For running with a constant boundary layer depth. This for the case when - not using a realistic mixed layer scheme. Default use_hblt_constant=.false. - - The boundary layer depth for the case when use_hblt_constant=.true. - Default constant_hblt=100.0. - - For using the diagnosed mld as the hblt for submeso. - This is useful for those test models that do not have a mixed layer - scheme enabled, such as KPP, where the mixed layer scheme provides a - boundary layer depth. In this case, it is sensible to employ the diagnosed - mixed layer depth for the submeso scheme. Additionally, in general it is - more physical to use the mld than the KPP hblt as the depth over which - the submesoscale eddies act. Hence, default use_hblt_equal_mld=.true. - - The minimum number of vertical cells in the surface boundary layer - that are required in order to compute the submesoscale streamfunction. - Default min_kblt=4. Need at least three to fit a parabola with zero - streamfunction at the top and bottom of the boundary layer. - - For setting a floor to the hblt used for submesoscale scheme. - Default minimum_hblt=0.0. - - For smoothing on the submeso bldepth field. This is useful - since the bldepth obtained from KPP or diagnosed mld can - have some grid noise. - Default smooth_hblt=.false. since this agrees with legacy. - Note that this scheme fails to reproduce across - processor layout, so it remains broken. - - Number of iterations for the smooothing of bldepth. - Default smooth_hblt_num=1. - - For computing psi using older legacy methods. - These methods are not ideal, and can be problematic - depending on nml settings for the limiters and smoothers. - This option is retained only for legacy purposes. - Default use_psi_legacy=.false. - - For doing a horizontal 1-2-1 smoothing on the - psix_horz and psiy_horz fields. - Default smooth_psi=.true. - - Number of iterations for the smooothing of psi. - Default smooth_psi_num=2. - - For limiting the magnitude of psi in order to reduce possibility of - model crashes. Rescales the full psi to maintain vertical structure - but to keep overall magnitude within bounds. - Default limit_psi=.false. - - Velocity scale used to limit the value of psi when limit_psi=.true. - Default limit_psi_velocity_scale=5.0 - - For limiting the fluxes arising from submeso scheme, according to - tmask_limit. When reach a point where tmask_limit=1.0, then set - the submeso flux for this cell to zero. - Default submeso_limit_flux=.true. - - The dimensionless coefficient from the Fox-Kemper etal scheme. - They recommend setting coefficient_ce between 0.06 and 0.08. - Default coefficient_ce=0.07. - - Timescale to mix momentum across the mixed layer. - Default time_constant=86400.0 = 1day. - - Take constant horizontal length scale of submesoscale front. - Default front_length_const=5e3. - - To compute the front length using the mixed layer deformation - radius. Default front_length_deform_radius=.true. Note, - will have a floor on the variable front length set by the - nml setting for front_length_const. - - Initialization for the ocean_submesoscale module. - - This routine computes a thickness and density weighted time tendency - for each tracer, arising from the effects of parameterized - submesoscale eddies acting in the surface mixed layer. - - Compute the boundary layer depth and kblt. - - Compute the tracer derivatives, with the - lateral derivatives computed along constant k-level. - - Compute the density-salinity derivatives, with lateral - derivative computed on constant k-level. - - Compute the vector streamfunction from parameterized - submesoscale restratification. - - Units of psi are m^2/sec - - psix is defined on north face of tracer cell for jq=0,1. - psiy is defined on east face of tracer cell for ip=0,1. - - NOTE: the mpp updates for psix and psiy are treated as a - scalar, whereas they are actually components to a pseudo-vector. - Some further thought is required for the tripolar grid. We ignore - this detail in the present implementation. - - - Compute the vector streamfunction - - Units of psi are m^2/sec - - If computing skewsion tendency, then need psi at depth_zt. - If computing advection tendency, then need psi at depth_zwt. - - Jan2012: This scheme has problems with the limiters and smoothers. - These problems become particularly egregious when trying to compute - an advective flux rather than a skew flux. This routine is - retained only for legacy purposes. - Stephen.Griffies - - - Compute the mass transport from submeso. - - This routine is a diagnostic routine if skewsion, and - part of the calculation of the eddy-induced velocity if - advective approach used. - - Comments on the scheme: - - 1/ compute vertical component from convergence of horizontal, just - as for the vertical velocity component for the Eulerian transport. - - 2/ wrho_bt_submeso(:,:,k=0) = 0.0 by definition - - 3/ expand the BDX_ET and BDY_NT operators for efficiency. - - 4/ mask to zero those regions where the horizontal divergence - vanishes, as these are regions beneath the submeso boundary - layer. Base the mask on horz divergence rather than kblt(i,j), - since any smoothing performed to uhrho_et_submeso and vhrho_nt_submeso - will modify the region of nonzero submesoscale advection so that - it reaches potentially to below kblt. - - - Compute tendency from submeso skewsion. - - - Subroutine computes the zonal submesoscale tracer skew flux component. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - - - Subroutine computes the meridional submesoscale tracer skew flux component. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - - - Subroutine computes the vertical submeso tracer skew flux component. - - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - - First order upwind to compute the tendency from submeso advection. - - Although this method adds diffusion, some of the mixing - is physically relevant. Absent this mixing, the submesoscale - parameterization is incomplete. The submesoscale parameterization is, - afterall, active only in the mixed layer, where there is lot of - physical mixing. - - Use of first order upwind ensures that the tendency computed - from submesoscale parameterization will not, in principle, - introduce extrema. However, there remain some issues with large - tendencies appearing near boundaries that may compromise this - monotonicity property. - - Apply masks so that there is no flux leaving cell next to bottom. - - - Sweby scheme to compute the tendency from submeso advection. - Algorithm taken after advect_tracer_sweby_all in the module - ocean_tracers/ocean_tracer_advect.F90. - - Jan 2012: Stephen.Griffies - This scheme has known bugs; it is not meant for general use. - - - Compute tendency from submeso horizontal diffusion. - - Compute maximum vertical velocity from submeso. - - Classify horizontal submeso mass transport according to neutral - density classes. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_rho_submeso, a remapping is - performed, rather than the binning done for transport_on_nrho_submeso_adv. - - This is the same algorithm as used for GM skew fluxes on rho surfaces. - - Caveat: Since the submeso scheme operates only in the mixed layer, - there are difficulties mapping this transport to neutral density - layers. The user should be mindful of the problems with this - remapping. An alternative that may be more suitable is to use - Ferret to remap the time mean submeso transport to the time mean - neutral density surfaces. There are missing correlations, but for - many purposes, the Ferret remapping may be preferable. - - Briefly, the Ferret command is the following: - - let ty_trans_nrho_submeso_new = ZAXREPLACE(TY_TRANS_SUBMESO,NEUTRAL_RHO,TY_TRANS_NRHO) - where TY_TRANS_SUBMESO is the level-space transport - NEUTRAL_RHO is the level space version of the neutral density - TY_TRANS_NRHO is any density space field whose vertical coordinates - are accessed for the remapping. - - Classify horizontal transport according to neutral density classes. - - Based on transport_on_nrho in ocean_diag/ocean_adv_diag.F90. - - - Initialization of watermass diagnostic output files. - - Diagnose effects from submesoscale on watermass transformation. - - Diagnose effects from submesoscale horizontal diffusion - on watermass transformation. - character(len=128) :: version=& - '$Id: ocean_nphysics.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics.F90,v 20.0 2013/12/14 00:14:34 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics.html b/src/mom5/ocean_param/neutral/ocean_nphysics.html deleted file mode 100644 index bbdef7dc97..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - Module ocean_nphysics_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_mod
- - - - - -
-OVERVIEW
- -- - Driver for ocean neutral physics. -
- - - -- Driver for ocean neutral physics. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_nphysics_util_mod
ocean_nphysicsA_mod
ocean_nphysicsB_mod
ocean_nphysicsC_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysics_init:
- -- -neutral_physics:
- -- -ocean_nphysics_restart:
- -- -ocean_nphysics_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysics_init
--
-- -DESCRIPTION -
-- - Initialize the neutral physics module. -
-
-
-- - -
-neutral_physics
--
-- -DESCRIPTION -
-- - - Call the relevant neutral physics scheme. - -
-
-
-- - -
-ocean_nphysics_restart
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-- - -
-ocean_nphysics_end
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-
-NAMELIST
- --&ocean_nphysics_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. - Default use_this_module=.false. -
-
-[logical] -- -debug_this_module -
-- For printing starting and ending checksums for restarts - Default debug_this_module=.false. -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -use_nphysicsA -
-- For using the nphysicsA method of neutral physics, based on that - developed in MOM4.0. This scheme is more robust and recommended for - general use. Default use_nphysicsA=.true. -
-
-[logical] -- -use_nphysicsB -
-- For using the nphysicsB method of neutral physics. This method is - experimental, and is not recommended for general use. - Default use_nphysicsB=.false. -
-
-[logical] -- -use_nphysicsC -
-- For using the nphysicsC method of neutral physics. This method is - experimental, and is not recommended for general use. - Default use_nphysicsC=.false. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics.xml b/src/mom5/ocean_param/neutral/ocean_nphysics.xml deleted file mode 100644 index a4c8d0e3a1..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics.xml +++ /dev/null @@ -1,44 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsA.F90 b/src/mom5/ocean_param/neutral/ocean_nphysicsA.F90 index 4dcdd52344..3bc6d49ba7 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsA.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysicsA.F90 @@ -426,9 +426,9 @@ module ocean_nphysicsA_mod integer :: neutralrho_nk character(len=128) :: version=& - '$Id: ocean_nphysicsA.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysicsA.F90,v 20.0 2013/12/14 00:14:36 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsA.html b/src/mom5/ocean_param/neutral/ocean_nphysicsA.html deleted file mode 100644 index 207e24bf46..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsA.html +++ /dev/null @@ -1,720 +0,0 @@ - - - - Stephen M. Griffies - Tim Leslie - - - Driver for ocean neutral physics. - - Driver for ocean neutral physics. - - Must be true to use this module. - Default use_this_module=.false. - - For printing starting and ending checksums for restarts - Default debug_this_module=.false. - - Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. - - For using the nphysicsA method of neutral physics, based on that - developed in MOM4.0. This scheme is more robust and recommended for - general use. Default use_nphysicsA=.true. - - For using the nphysicsB method of neutral physics. This method is - experimental, and is not recommended for general use. - Default use_nphysicsB=.false. - - For using the nphysicsC method of neutral physics. This method is - experimental, and is not recommended for general use. - Default use_nphysicsC=.false. - - Initialize the neutral physics module. - - - Call the relevant neutral physics scheme. - - - Write to restart. - - Write to restart. - Module ocean_nphysicsA_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysicsA_mod
- - --Contact: Stephen M. Griffies -, - Russell Fiedler - -- - -
-Reviewers: Tim Leslie - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian GM skew-diffusion. -
- - - -- This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian GM skew-diffusion. The algorithms are based on - MOM4p0d methods. The fundamental differences from the ocean_nphysicsB - methods relate to the handling of fluxes near the domain boundaries. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_domains_mod
ocean_nphysics_util_mod
ocean_operators_mod
ocean_parameters_mod
ocean_sigma_transport_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysicsA_init:
- -- -nphysicsA:
- -- -neutral_blayer:
- -- -fz_terms:
- -- -fz_terms_diag:
- -- -fx_flux:
- -- -fx_flux_diag:
- -- -fy_flux:
- -- -fy_flux_diag:
- -- -fz_flux:
- -- -fz_flux_diag:
- -- -gm_velocity:
- -- -slope_function_gm:
- -- -nphysics_diagnostics:
- -- -ocean_nphysicsA_restart:
- -- -ocean_nphysicsA_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysicsA_init
--
-- -DESCRIPTION -
-- - Initialize the neutral physics module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. -
-
-
-- - -
-nphysicsA
--
-- -DESCRIPTION -
-- - This function computes the thickness weighted and density weighted - time tendency for tracer from neutral physics. Full discussion - and details are provided by Griffies (2004). - - Here is a brief summary. - ----How the neutral diffusive flux components are computed: - - The vertical flux component is split into diagonal (3,3) and - off-diagonal (3,1) and (3,2) terms. The off-diagonal (3,1) and (3,2) - terms are included explicitly in time. The main contribution from the - (3,3) term to the time tendency is included implicitly in time - along with the usual contribution from diapycnal processes - (vertical mixing schemes). This is the K33_implicit term. - This approach is necessary with high vertical resolution, as - noted by Cox (1987). However, splitting the vertical flux into - an implicit and explicit piece compromises the - integrity of the vertical flux component (see Griffies et al. 1998). - So to minimize the disparity engendered by this split, the portion of - K33 that can be stably included explicitly in time is computed along - with the (3,1) and (3,2) terms. - - All other terms in the mixing tensor are included explicitly in time - using a forward time step as required for temporal stability of - numerical diffusive processes. - - The off-diagonal terms in the horizontal flux components, and all terms - in the vertical flux component, are tapered in regions of steep neutral - slope according to the requirements of linear stability. MOM allows for - choice of two tapering schemes: - - (a) the tanh taper of Danabasoglu and McWilliams (1995) - (b) the quadratic scheme of Gerdes, Koberle, and Willebrand (1991) - - Linear stability is far less stringent on the diagonal (1,1) and (2,2) - part of the horizontal flux. Indeed, these terms in practice need - not be tapered in steep sloped regions. The namelist - neutral_taper_diagonal=.false. keeps the diagnonal terms maintained - for all neutral slopes. This approach assists in reducing numerical - noise in regions where the physical system experiences a lot of - diapycnal mixing anyhow. - ----How the skew diffusive flux components are computed: - - The GM skew flux components are purely off-diagonal. - They are generally tapered when neutral slope - is large (neutral_physics_simple=.false). - Doing so maintains a nontrivial GM slumping effect even when the - neutral slopes are vertical. The alternative neutral_physics_simple=.true. - is the approach used in MOM3, whereby GM effects are removed - in steep sloped regions. neutral_physics_simple=.false. is - less efficient, but has been seen to yield superior simulations. - -
-
-
-- - -
-neutral_blayer
--
-- -DESCRIPTION -
-- - Subroutine computes the boundary layer as determined by - 1. steep neutral slopes - 2. depth within which typical mesoscale eddies are partially outcropped - 3. depth within which vertical mixing scheme (e.g., kpp) computes a boundary layer - - Note: Only consider surface boundary layers here. - - Scheme originally coded for MOM4.0 by Stephen.Griffies - with help for optimization by Russell.Fiedler@csiro.au. - -
-
-
-- - -
-fz_terms
--
-- -DESCRIPTION -
-- - Subroutine computes the tracer independent pieces of the vertical - flux component. As a result of this routine, - Array tensor_31 = x-diffusivity*slope (m^2/sec) for fz - Array tensor_32 = y-diffusivity*slope (m^2/sec) for fz - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Also will compute the squared Eady growth rate, with the maximum - slope contributing to this growth rate set by smax. -
-
-
-- - -
-fz_terms_diag
--
-- -DESCRIPTION -
-- - For saving the contributions from GM and Redi separately, it is - necessary to compute the tensor_redi component here. - - We do so here, reproducing some lines of code from fz_terms, - to reduce minimize the need to impinge on the case when NOT - using this generally expensive (memory and computational) - diagnostic. - - This routine MUST be called prior to fz_terms, since we use - tensor_31 and tensor_32 in their raw slope forms here. - -
-
-
-- - -
-fx_flux
--
-- -DESCRIPTION -
-- - Subroutine computes the i-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fx_flux_diag
--
-- -DESCRIPTION -
-- - Subroutine computes the i-directed neutral physics tracer flux component - for Redi separately from GM, in order to diagnose GM and Redi - fluxes independent of one another. - - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fy_flux
--
-- -DESCRIPTION -
-- - Subroutine computes the j-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fy_flux_diag
--
-- -DESCRIPTION -
-- - Subroutine computes the j-directed neutral physics tracer flux component - for Redi separately, in order to diagnose GM and Redi contributions - independent of one another. - - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fz_flux
--
-- -DESCRIPTION -
-- - Subroutine computes the vertical neutral physics tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - -
-
-
-- - -
-fz_flux_diag
--
-- -DESCRIPTION -
-- - For diagnosing the GM and Redi pieces separately. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - -
-
-
-- - -
-gm_velocity
--
-- -DESCRIPTION -
-- - Subroutine computes GM eddy-induced velocity field for diagnostics. - Compute ustar and vstar at U-cell point, and wstar at T-cell bottom. - - Do a two-point average rather than more democratic four-point avg - in order to avoid having to call mpp_update domains on tensor_31 and - tensor_32. The 0.5 factor is due to the two-point average. - - Note that this algorithm is ad hoc. Researchers interested in this - field may wish to test alternatives. -
-
-
-- - -
-slope_function_gm
--
-- -DESCRIPTION -
-- - Function for defining effective slope in diagnostic GM velocity - calculation. Used only for diagnostic purposes. -
-
-
-- - -
-nphysics_diagnostics
--
-- -DESCRIPTION -
-- - Send some diagnostics to diagnostics manager. -
-
-
-- - -
-ocean_nphysicsA_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_nphysicsA_end
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-
-NAMELIST
- --&ocean_nphysicsA_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For printing starting and ending checksums for restarts -
-
-[logical] -- -use_gm_skew -
-- Must be true to use GM skewsion. Set to false if wish to - incorporate the "GM-effect" through form drag, as in - ocean_form_drag module. Default use_gm_skew=.true. -
-
-[logical] -- -diffusion_all_explicit -
-- To compute all contributions from neutral diffusion explicitly in time, including - the K33 diagonal piece. This approach is available only when have small time - steps and/or running with just a single tracer. It is for testing purposes. -
-
-[logical] -- -neutral_physics_simple -
-- If .true. then must have aredi_equal_agm=.true.. The horizontal fluxes are then - computed as horizontal downgradient diffusive fluxes regardless the neutral slope. - This approach precluds one from being able to have the GM-skew fluxes remain active - in the steep sloped regions, thus shutting off their effects to reduce the slopes - of isopycnals in convective and mixed layer regimes. It is for this reason that - neutral_physics_simple=.false. is the recommended default in MOM. -
-
-[logical] -- -neutral_physics_limit -
-- When tracer falls outside a specified range, revert to horizontal - diffusive fluxes at this cell. This is an ad hoc and incomplete attempt - to maintain monotonicity with the neutral physics scheme. - Default neutral_physics_limit=.true. -
-
-[logical] -- -tmask_neutral_on -
-- If .true. then this logical reduces the neutral fluxes to - horizontal/vertical diffusion next to boundaries. - This approach has been found to reduce spurious - extrema resulting from truncation of triads used to compute - a neutral flux component. Default tmask_neutral_on=.false. -
-
-[logical] -- -dm_taper -
-- Set to true to use the tanh tapering scheme of Danabasoglu and McWilliams. - Default is true. -
-
-[logical] -- -gkw_taper -
-- Set to true to use the quadradic tapering scheme of Gerdes, Koberle, and Willebrand. - Default is false. -
-
-[logical] -- -neutral_linear_gm_taper -
-- If .true. then with neutral_physics_simple=.false., will linearly taper GM - skew fluxes towards the surface within regions of steep neutral slopes. - This approach leads to a constant horizontal eddy-induced velocity in - the steeply sloping regions and is recommended for realistic simulations. -
-
-[logical] -- -neutral_sine_taper -
-- If .true. then with neutral_physics_simple=.false., will apply a sine-taper - to GM and neutral diffusive fluxes in regions where the penetration depth - of eddies is deeper than the grid point. This method is essential for - fine vertical resolution grids. -
-
-[logical] -- -turb_blayer_min -
-- Minimum depth of a surface turbulent boundary layer - used in the transition of the neutral physics fluxes - to the surface. Note that in MOM4.0, - turb_blayer_min was always set to zero. -
-
-[real] -- -neutral_blayer_diagnose -
-- Diagnose properties of the neutral physics boundary layer, whether have - neutral_linear_gm_taper or neutral_sine_taper true or not. -
-
-[logical] -- -neutral_taper_diagonal -
-- For cases with neutral_physics_simple=.false., then neutral_taper_diagonal=.true. - will taper the diagonal pieces of the horizontal flux components when neutral slopes - are steep. With neutral_taper_diagonal=.false., then the horizontal flux components will - remain enabled for all slopes, thus producing horizontal downgradient diffusion in - regions of vertical neutral directions. -
-
-[logical, units: dimensionless] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, - J.K. Dukowicz, and R.D. Smith - Isoneutral diffusion in a z-coordinate ocean model - Journal of Physical Oceanography (1998) vol 28 pages 805-830 -
-- - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
-- - S.M. Griffies, Elements of MOM (2012) -
-- - G. Danabasoglu and J. C. McWilliams - Sensitivity of the global ocean circulation to - parameterizations of mesoscale tracer transports - Journal of Climate (1995) vol 8 pages 2967--2987 -
-- - Gerdes, Koberle, and Willebrand - The influence of numerical advection schemes on the results of ocean - general circulation models, Climate Dynamics (1991), vol. 5, - pages 211--226. -
-
- - -
-NOTES
- -- Numerical implementation of the flux components follows the triad - approach documented in the references and implemented in MOM2 and MOM3. - The MOM algorithm accounts for partial bottom cells and generalized - orthogonal horizontal coordinates. --
-
- neutral_physics_simple=.true. requires aredi_equal_agm=.true. - neutral_physics_simple=.true. results in down-gradient - horizontal flux components. This setting reduces the overall cost - of the neutral physics scheme, but it is not used at GFDL - anymore, since we favor methods whereby treatment of GM and Redi - in the boundary layers are distinct. -
-
- In steep slope regions, neutral diffusive fluxes are tapered to - zero with the tanh taper of Danabasoglu and McWilliams (1995) or the - quadratic scheme of Gerdes, Koberle, and Willebrand. However, if - neutral_physics_simple=.false., the GM skew-diffusive fluxes - can remain nonzero if have neutral_linear_gm_taper=.true. -
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsA.xml b/src/mom5/ocean_param/neutral/ocean_nphysicsA.xml deleted file mode 100644 index d3362f4c69..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsA.xml +++ /dev/null @@ -1,278 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsB.F90 b/src/mom5/ocean_param/neutral/ocean_nphysicsB.F90 index 244fc1b368..4b90414dc8 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsB.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysicsB.F90 @@ -411,9 +411,9 @@ module ocean_nphysicsB_mod integer :: neutralrho_nk character(len=128) :: version=& - '$Id: ocean_nphysicsB.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysicsB.F90,v 20.0 2013/12/14 00:14:38 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsB.html b/src/mom5/ocean_param/neutral/ocean_nphysicsB.html deleted file mode 100644 index 2713c9f11a..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsB.html +++ /dev/null @@ -1,678 +0,0 @@ - - - - Stephen M. Griffies - Russell Fiedler - Tim Leslie - - Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian GM skew-diffusion. - - This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian GM skew-diffusion. The algorithms are based on - MOM4p0d methods. The fundamental differences from the ocean_nphysicsB - methods relate to the handling of fluxes near the domain boundaries. - - S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, - J.K. Dukowicz, and R.D. Smith - Isoneutral diffusion in a z-coordinate ocean model - Journal of Physical Oceanography (1998) vol 28 pages 805-830 - - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 - - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press - - S.M. Griffies, Elements of MOM (2012) - - G. Danabasoglu and J. C. McWilliams - Sensitivity of the global ocean circulation to - parameterizations of mesoscale tracer transports - Journal of Climate (1995) vol 8 pages 2967--2987 - - Gerdes, Koberle, and Willebrand - The influence of numerical advection schemes on the results of ocean - general circulation models, Climate Dynamics (1991), vol. 5, - pages 211--226. - - Numerical implementation of the flux components follows the triad - approach documented in the references and implemented in MOM2 and MOM3. - The MOM algorithm accounts for partial bottom cells and generalized - orthogonal horizontal coordinates. - - neutral_physics_simple=.true. requires aredi_equal_agm=.true. - neutral_physics_simple=.true. results in down-gradient - horizontal flux components. This setting reduces the overall cost - of the neutral physics scheme, but it is not used at GFDL - anymore, since we favor methods whereby treatment of GM and Redi - in the boundary layers are distinct. - - In steep slope regions, neutral diffusive fluxes are tapered to - zero with the tanh taper of Danabasoglu and McWilliams (1995) or the - quadratic scheme of Gerdes, Koberle, and Willebrand. However, if - neutral_physics_simple=.false., the GM skew-diffusive fluxes - can remain nonzero if have neutral_linear_gm_taper=.true. - - Must be true to use this module. Default is false. - - For printing starting and ending checksums for restarts - - Must be true to use GM skewsion. Set to false if wish to - incorporate the "GM-effect" through form drag, as in - ocean_form_drag module. Default use_gm_skew=.true. - - To compute all contributions from neutral diffusion explicitly in time, including - the K33 diagonal piece. This approach is available only when have small time - steps and/or running with just a single tracer. It is for testing purposes. - - If .true. then must have aredi_equal_agm=.true.. The horizontal fluxes are then - computed as horizontal downgradient diffusive fluxes regardless the neutral slope. - This approach precluds one from being able to have the GM-skew fluxes remain active - in the steep sloped regions, thus shutting off their effects to reduce the slopes - of isopycnals in convective and mixed layer regimes. It is for this reason that - neutral_physics_simple=.false. is the recommended default in MOM. - - When tracer falls outside a specified range, revert to horizontal - diffusive fluxes at this cell. This is an ad hoc and incomplete attempt - to maintain monotonicity with the neutral physics scheme. - Default neutral_physics_limit=.true. - - If .true. then this logical reduces the neutral fluxes to - horizontal/vertical diffusion next to boundaries. - This approach has been found to reduce spurious - extrema resulting from truncation of triads used to compute - a neutral flux component. Default tmask_neutral_on=.false. - - Set to true to use the tanh tapering scheme of Danabasoglu and McWilliams. - Default is true. - - Set to true to use the quadradic tapering scheme of Gerdes, Koberle, and Willebrand. - Default is false. - - If .true. then with neutral_physics_simple=.false., will linearly taper GM - skew fluxes towards the surface within regions of steep neutral slopes. - This approach leads to a constant horizontal eddy-induced velocity in - the steeply sloping regions and is recommended for realistic simulations. - - If .true. then with neutral_physics_simple=.false., will apply a sine-taper - to GM and neutral diffusive fluxes in regions where the penetration depth - of eddies is deeper than the grid point. This method is essential for - fine vertical resolution grids. - - Minimum depth of a surface turbulent boundary layer - used in the transition of the neutral physics fluxes - to the surface. Note that in MOM4.0, - turb_blayer_min was always set to zero. - - Diagnose properties of the neutral physics boundary layer, whether have - neutral_linear_gm_taper or neutral_sine_taper true or not. - - For cases with neutral_physics_simple=.false., then neutral_taper_diagonal=.true. - will taper the diagonal pieces of the horizontal flux components when neutral slopes - are steep. With neutral_taper_diagonal=.false., then the horizontal flux components will - remain enabled for all slopes, thus producing horizontal downgradient diffusion in - regions of vertical neutral directions. - - Initialize the neutral physics module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. - - This function computes the thickness weighted and density weighted - time tendency for tracer from neutral physics. Full discussion - and details are provided by Griffies (2004). - - Here is a brief summary. - ----How the neutral diffusive flux components are computed: - - The vertical flux component is split into diagonal (3,3) and - off-diagonal (3,1) and (3,2) terms. The off-diagonal (3,1) and (3,2) - terms are included explicitly in time. The main contribution from the - (3,3) term to the time tendency is included implicitly in time - along with the usual contribution from diapycnal processes - (vertical mixing schemes). This is the K33_implicit term. - This approach is necessary with high vertical resolution, as - noted by Cox (1987). However, splitting the vertical flux into - an implicit and explicit piece compromises the - integrity of the vertical flux component (see Griffies et al. 1998). - So to minimize the disparity engendered by this split, the portion of - K33 that can be stably included explicitly in time is computed along - with the (3,1) and (3,2) terms. - - All other terms in the mixing tensor are included explicitly in time - using a forward time step as required for temporal stability of - numerical diffusive processes. - - The off-diagonal terms in the horizontal flux components, and all terms - in the vertical flux component, are tapered in regions of steep neutral - slope according to the requirements of linear stability. MOM allows for - choice of two tapering schemes: - - (a) the tanh taper of Danabasoglu and McWilliams (1995) - (b) the quadratic scheme of Gerdes, Koberle, and Willebrand (1991) - - Linear stability is far less stringent on the diagonal (1,1) and (2,2) - part of the horizontal flux. Indeed, these terms in practice need - not be tapered in steep sloped regions. The namelist - neutral_taper_diagonal=.false. keeps the diagnonal terms maintained - for all neutral slopes. This approach assists in reducing numerical - noise in regions where the physical system experiences a lot of - diapycnal mixing anyhow. - ----How the skew diffusive flux components are computed: - - The GM skew flux components are purely off-diagonal. - They are generally tapered when neutral slope - is large (neutral_physics_simple=.false). - Doing so maintains a nontrivial GM slumping effect even when the - neutral slopes are vertical. The alternative neutral_physics_simple=.true. - is the approach used in MOM3, whereby GM effects are removed - in steep sloped regions. neutral_physics_simple=.false. is - less efficient, but has been seen to yield superior simulations. - - - Subroutine computes the boundary layer as determined by - 1. steep neutral slopes - 2. depth within which typical mesoscale eddies are partially outcropped - 3. depth within which vertical mixing scheme (e.g., kpp) computes a boundary layer - - Note: Only consider surface boundary layers here. - - Scheme originally coded for MOM4.0 by Stephen.Griffies - with help for optimization by Russell.Fiedler@csiro.au. - - - Subroutine computes the tracer independent pieces of the vertical - flux component. As a result of this routine, - Array tensor_31 = x-diffusivity*slope (m^2/sec) for fz - Array tensor_32 = y-diffusivity*slope (m^2/sec) for fz - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Also will compute the squared Eady growth rate, with the maximum - slope contributing to this growth rate set by smax. - - For saving the contributions from GM and Redi separately, it is - necessary to compute the tensor_redi component here. - - We do so here, reproducing some lines of code from fz_terms, - to reduce minimize the need to impinge on the case when NOT - using this generally expensive (memory and computational) - diagnostic. - - This routine MUST be called prior to fz_terms, since we use - tensor_31 and tensor_32 in their raw slope forms here. - - - Subroutine computes the i-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the i-directed neutral physics tracer flux component - for Redi separately from GM, in order to diagnose GM and Redi - fluxes independent of one another. - - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the j-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the j-directed neutral physics tracer flux component - for Redi separately, in order to diagnose GM and Redi contributions - independent of one another. - - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the vertical neutral physics tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - - For diagnosing the GM and Redi pieces separately. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - - Subroutine computes GM eddy-induced velocity field for diagnostics. - Compute ustar and vstar at U-cell point, and wstar at T-cell bottom. - - Do a two-point average rather than more democratic four-point avg - in order to avoid having to call mpp_update domains on tensor_31 and - tensor_32. The 0.5 factor is due to the two-point average. - - Note that this algorithm is ad hoc. Researchers interested in this - field may wish to test alternatives. - - Function for defining effective slope in diagnostic GM velocity - calculation. Used only for diagnostic purposes. - - Send some diagnostics to diagnostics manager. - - Write out restart files registered through register_restart_file - - Write to restart. - Module ocean_nphysicsB_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysicsB_mod
- - --Contact: Stephen M. Griffies -, - Russell Fiedler - -- - -
-Reviewers: Tim Leslie - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian GM skew-diffusion. -
- - - -- This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian GM skew-diffusion. The methods here differ from - ocean_nphysicsA in the treatment of fluxes in the boundary - regions. This module is experimental, and should be used with caution. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_domains_mod
ocean_nphysics_util_mod
ocean_operators_mod
ocean_parameters_mod
ocean_sigma_transport_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysicsB_init:
- -- -nphysicsB:
- -- -neutral_blayer:
- -- -fz_terms:
- -- -fz_terms_diag:
- -- -fx_flux:
- -- -fx_flux_diag:
- -- -fy_flux:
- -- -fy_flux_diag:
- -- -fz_flux:
- -- -fz_flux_diag:
- -- -nphysics_diagnostics:
- -- -neutral_chksums:
- -- -ocean_nphysicsB_restart:
- -- -ocean_nphysicsB_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysicsB_init
--
-- -DESCRIPTION -
-- - Initialize the neutral physics module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. -
-
-
-- - -
-nphysicsB
--
-- -DESCRIPTION -
-- - This function computes the thickness weighted and density weighted - time tendency for tracer from neutral physics. Full discussion - and details are provided by Griffies (2004,2005). - - Here is a brief summary of the temporal treatment. - ----How the neutral diffusive flux components are computed: - - The vertical flux component is split into diagonal (3,3) and - off-diagonal (3,1) and (3,2) terms. The off-diagonal (3,1) and (3,2) - terms are included explicitly in time. The main contribution from the - (3,3) term to the time tendency is included implicitly in time - along with the usual contribution from diapycnal processes - (vertical mixing schemes). This is the K33_implicit term. - This approach is necessary with high vertical resolution, as - noted by Cox (1987). However, splitting the vertical flux into - an implicit and explicit piece compromises the - integrity of the vertical flux component (see Griffies et al. 1998). - So to minimize the disparity engendered by this split, the portion of - K33 that can be stably included explicitly in time is computed along - with the (3,1) and (3,2) terms. - - All other terms in the mixing tensor are included explicitly in time - using a forward time step as required for temporal stability of - numerical diffusive processes. - -
-
-
-- - -
-neutral_blayer
--
-- -DESCRIPTION -
-- - - This subroutine computes the "neutral boundary layers" based on - the formulation of Ferrari and McWilliams (2006). See full - details and discussion in Elements of MOM4p1 by Griffies (2009). - - Five vertical regions are identified by Ferrari and McWilliams: - We simplify these regimes by melding the turbulent and transition - regimes into an overall neutral boundary layer regime, within which - the streamfunction is linearly tapers to zero moving towards the - boundary. We also ignore the bottom regimes, as these are poorly - resolved in most models, and the neutral physics fluxes are - typically small at the bottom. - - (1) Surface turbulent region: - Depth ("h" in Ferrari and McWilliams notation) dominated by - 3d turbulent processes. This depth is taken from surf_blthick, - as set by the KPP scheme or another mixed layer scheme. - A minimum is set as surf_turb_thick_min and is specified - as a nml parameter in ocean_nphysicsB_nml. - - In order to use a low frequency version of the boundary layer - thickness, we damp its evolution with a damping time scale - neutral_damping_time (days). - - In the code, "h_surf"= surf_turb_thick - - (2) Surface transition region: - Thickness ("D" in Ferrari and McWilliams notation) - between the turbulent surface boundary layer and the interior. - This transition layer thickness is determined by the product of the - neutral slope and first baroclinic Rossby radius. This specification - is ad hoc, and more fundamental theories are welcome. - - In the code, "D_surf"= surf_trans_thick - - - Within a "boundary layer" region set by the sum of - surf_turb_thick plus surf_trans_thick, the eddy - induced velocity is assumed to have zero vertical shear, - which means the quasi-Stokes streamfunction is linear with - depth. The neutral diffusive fluxes are reduced to horizontal - downgradient diffusion, with "horizontal" defined according - to surfaces of constant vertical coordinate. - - - (3) Interior region: - Where neutral diffusion and GM skew-diffusion are taken - from their unmodified form. - - Only use the 31 and 32 triads for this computation since the - 13 and 23 triads require extra slope calculations, and - so will add lots of computational cost. It is felt that the - 31 and 32 triads are sufficient for this calculation, in - a similar manner that they are used for the calculation of - the non-constant diffusivities. - - Scheme coded for MOM4p1 by Stephen.Griffies - Version: March2006 - Simplified version: June2008 - -
-
-
-- - -
-fz_terms
--
-- -DESCRIPTION -
-- - Subroutine computes the tracer independent pieces of the vertical - flux component. As a result of this routine, - Array tensor_31 = x-diffusivity*slope (m^2/sec) for fz - Array tensor_32 = y-diffusivity*slope (m^2/sec) for fz - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Also will compute the squared Eady growth rate, with the maximum - slope contributing to this growth rate set by smax. -
-
-
-- - -
-fz_terms_diag
--
-- -DESCRIPTION -
-- - For saving the contributions from GM and Redi separately, it is - necessary to compute the tensor_redi component here. - - We do so here, reproducing some lines of code from fz_terms, - to reduce minimize the need to impinge on the case when NOT - using this generally expensive (memory and computational) - diagnostic. - - This routine MUST be called prior to fz_terms, since we use - tensor_31 and tensor_32 in their raw slope forms here. - -
-
-
-- - -
-fx_flux
--
-- -DESCRIPTION -
-- - Subroutine computes the i-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fx_flux_diag
--
-- -DESCRIPTION -
-- - Subroutine computes the i-directed neutral physics tracer flux component - for Redi separately from GM, in order to diagnose GM and Redi - fluxes independent of one another. - - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fy_flux
--
-- -DESCRIPTION -
-- - Subroutine computes the j-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fy_flux_diag
--
-- -DESCRIPTION -
-- - Subroutine computes the j-directed neutral physics tracer flux component - for Redi separately, in order to diagnose GM and Redi contributions - independent of one another. - - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fz_flux
--
-- -DESCRIPTION -
-- - Subroutine computes the vertical neutral physics tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - -
-
-
-- - -
-fz_flux_diag
--
-- -DESCRIPTION -
-- - For diagnosing the GM and Redi pieces separately. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - -
-
-
-- - -
-nphysics_diagnostics
--
-- -DESCRIPTION -
-- - Send some diagnostics to diagnostics manager. -
-
-
-- - -
-neutral_chksums
--
-- -DESCRIPTION -
-- - Write some checksums. -
-
-
-- - -
-ocean_nphysicsB_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_nphysicsB_end
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-
-NAMELIST
- --&ocean_nphysicsB_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For printing starting and ending checksums for restarts -
-
-[logical] -- -use_gm_skew -
-- Must be true to use GM skewsion. Set to false if wish to - incorporate the "GM-effect" through form drag, as in - ocean_form_drag module. Default use_gm_skew=.true. -
-
-[logical] -- -diffusion_all_explicit -
-- To compute all contributions from neutral diffusion explicitly in time, including - the K33 diagonal piece. This approach is available only when have small time - steps and/or running with just a single tracer. It is for testing purposes. -
-
-[logical] -- -neutral_physics_limit -
-- When tracer falls outside a specified range, revert to horizontal - diffusive fluxes at this cell. This is an ad hoc and incomplete attempt - to maintain monotonicity with the neutral physics scheme. - Default neutral_physics_limit=.true. -
-
-[logical] -- -tmask_neutral_on -
-- If .true. then this logical reduces the neutral fluxes to - horizontal/vertical diffusion next to boundaries. - This approach has been found to reduce spurious - extrema resulting from truncation of triads used to compute - a neutral flux component. Default tmask_neutral_on=.false. -
-
-[logical] -- -surf_turb_thick_min_k -
-- Minimum number of k-levels in surface turbulent boundary - layer used in the transition of the neutral physics fluxes - to the surface. Default surf_turb_thick_min_k = 2. -
-
-[integer] -- -surf_turb_thick_min -
-- Minimum thickness of surface turbulent boundary layer - used in the transition of the neutral physics fluxes - to the surface. Default surf_turb_thick_min=20m. -
-
-[real] -- -neutral_damping_time -
-- The damping time used for determining the effective surface - boundary layer thickness from other portions of - the model. Default neutral_damping_time=10days. -
-
-[real, units: days] -- -nblayer_smooth -
-- For smoothing the neutral blayer fields. This is useful - when aiming to produce a smooth quasi-stokes streamfunction - within the boundary layers. Default is nblayer_smooth=.true. -
-
-[logical] -- -vel_micom_smooth -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of neutral blayer fields. -
-
-[real, units: m/sec] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, - J.K. Dukowicz, and R.D. Smith - Isoneutral diffusion in a z-coordinate ocean model - Journal of Physical Oceanography (1998) vol 28 pages 805-830 -
-- - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
-- - R. Ferrari and J.C. McWilliams and Canuto and Dubovikov - Parameterization of eddy fluxes near oceanic boundaries - Journal of Climate (2008). -
-- - Large etal (1997), Journal of Physical Oceanography, - pages 2418-2447 -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
-- - S.M. Griffies, Elements of MOM (2012) -
-
- - -
-NOTES
- -- Revisions made for MOM4p1 in Sept 2005, Jan/Feb 2006, - and June 2008 by Stephen.Griffies. The June 2008 - revision greatly simplified the boundary layer formulation - from Ferrari and McWilliams, whereby the quadratic transition - layer is eliminated, thus removing the need to match vertical - derivatives of the streamfunction. The matching conditions - implied by the transition zone added a tremendous amount - of code that was not seen to be critical for the purpose - of producing a reasonably smooth streamfunction. --
-
- Numerical implementation of the flux components follows the triad - approach documented in the references and implemented in MOM2 and MOM3. - The MOM algorithm accounts for partial bottom cells and generalized - orthogonal horizontal coordinates. -
-
- Note: the option neutral_physics_simple is not supported in this - module. Use nphysicA for that option. -
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsB.xml b/src/mom5/ocean_param/neutral/ocean_nphysicsB.xml deleted file mode 100644 index a094227aef..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsB.xml +++ /dev/null @@ -1,269 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsC.F90 b/src/mom5/ocean_param/neutral/ocean_nphysicsC.F90 index e63a497394..cb95277a83 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsC.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysicsC.F90 @@ -514,9 +514,9 @@ module ocean_nphysicsC_mod integer :: neutralrho_nk character(len=128) :: version=& - '$Id: ocean_nphysicsC.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysicsC.F90,v 20.0 2013/12/14 00:14:40 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsC.html b/src/mom5/ocean_param/neutral/ocean_nphysicsC.html deleted file mode 100644 index 1e94c21151..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsC.html +++ /dev/null @@ -1,993 +0,0 @@ - - - - Stephen M. Griffies - Russell Fiedler - Tim Leslie - - Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian GM skew-diffusion. - - This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian GM skew-diffusion. The methods here differ from - ocean_nphysicsA in the treatment of fluxes in the boundary - regions. This module is experimental, and should be used with caution. - - S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, - J.K. Dukowicz, and R.D. Smith - Isoneutral diffusion in a z-coordinate ocean model - Journal of Physical Oceanography (1998) vol 28 pages 805-830 - - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 - - R. Ferrari and J.C. McWilliams and Canuto and Dubovikov - Parameterization of eddy fluxes near oceanic boundaries - Journal of Climate (2008). - - Large etal (1997), Journal of Physical Oceanography, - pages 2418-2447 - - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press - - S.M. Griffies, Elements of MOM (2012) - - Revisions made for MOM4p1 in Sept 2005, Jan/Feb 2006, - and June 2008 by Stephen.Griffies. The June 2008 - revision greatly simplified the boundary layer formulation - from Ferrari and McWilliams, whereby the quadratic transition - layer is eliminated, thus removing the need to match vertical - derivatives of the streamfunction. The matching conditions - implied by the transition zone added a tremendous amount - of code that was not seen to be critical for the purpose - of producing a reasonably smooth streamfunction. - - Numerical implementation of the flux components follows the triad - approach documented in the references and implemented in MOM2 and MOM3. - The MOM algorithm accounts for partial bottom cells and generalized - orthogonal horizontal coordinates. - - Note: the option neutral_physics_simple is not supported in this - module. Use nphysicA for that option. - - Must be true to use this module. Default is false. - - For printing starting and ending checksums for restarts - - Must be true to use GM skewsion. Set to false if wish to - incorporate the "GM-effect" through form drag, as in - ocean_form_drag module. Default use_gm_skew=.true. - - To compute all contributions from neutral diffusion explicitly in time, including - the K33 diagonal piece. This approach is available only when have small time - steps and/or running with just a single tracer. It is for testing purposes. - - When tracer falls outside a specified range, revert to horizontal - diffusive fluxes at this cell. This is an ad hoc and incomplete attempt - to maintain monotonicity with the neutral physics scheme. - Default neutral_physics_limit=.true. - - If .true. then this logical reduces the neutral fluxes to - horizontal/vertical diffusion next to boundaries. - This approach has been found to reduce spurious - extrema resulting from truncation of triads used to compute - a neutral flux component. Default tmask_neutral_on=.false. - - Minimum number of k-levels in surface turbulent boundary - layer used in the transition of the neutral physics fluxes - to the surface. Default surf_turb_thick_min_k = 2. - - Minimum thickness of surface turbulent boundary layer - used in the transition of the neutral physics fluxes - to the surface. Default surf_turb_thick_min=20m. - - The damping time used for determining the effective surface - boundary layer thickness from other portions of - the model. Default neutral_damping_time=10days. - - For smoothing the neutral blayer fields. This is useful - when aiming to produce a smooth quasi-stokes streamfunction - within the boundary layers. Default is nblayer_smooth=.true. - - Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of neutral blayer fields. - - Initialize the neutral physics module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. - - This function computes the thickness weighted and density weighted - time tendency for tracer from neutral physics. Full discussion - and details are provided by Griffies (2004,2005). - - Here is a brief summary of the temporal treatment. - ----How the neutral diffusive flux components are computed: - - The vertical flux component is split into diagonal (3,3) and - off-diagonal (3,1) and (3,2) terms. The off-diagonal (3,1) and (3,2) - terms are included explicitly in time. The main contribution from the - (3,3) term to the time tendency is included implicitly in time - along with the usual contribution from diapycnal processes - (vertical mixing schemes). This is the K33_implicit term. - This approach is necessary with high vertical resolution, as - noted by Cox (1987). However, splitting the vertical flux into - an implicit and explicit piece compromises the - integrity of the vertical flux component (see Griffies et al. 1998). - So to minimize the disparity engendered by this split, the portion of - K33 that can be stably included explicitly in time is computed along - with the (3,1) and (3,2) terms. - - All other terms in the mixing tensor are included explicitly in time - using a forward time step as required for temporal stability of - numerical diffusive processes. - - - - This subroutine computes the "neutral boundary layers" based on - the formulation of Ferrari and McWilliams (2006). See full - details and discussion in Elements of MOM4p1 by Griffies (2009). - - Five vertical regions are identified by Ferrari and McWilliams: - We simplify these regimes by melding the turbulent and transition - regimes into an overall neutral boundary layer regime, within which - the streamfunction is linearly tapers to zero moving towards the - boundary. We also ignore the bottom regimes, as these are poorly - resolved in most models, and the neutral physics fluxes are - typically small at the bottom. - - (1) Surface turbulent region: - Depth ("h" in Ferrari and McWilliams notation) dominated by - 3d turbulent processes. This depth is taken from surf_blthick, - as set by the KPP scheme or another mixed layer scheme. - A minimum is set as surf_turb_thick_min and is specified - as a nml parameter in ocean_nphysicsB_nml. - - In order to use a low frequency version of the boundary layer - thickness, we damp its evolution with a damping time scale - neutral_damping_time (days). - - In the code, "h_surf"= surf_turb_thick - - (2) Surface transition region: - Thickness ("D" in Ferrari and McWilliams notation) - between the turbulent surface boundary layer and the interior. - This transition layer thickness is determined by the product of the - neutral slope and first baroclinic Rossby radius. This specification - is ad hoc, and more fundamental theories are welcome. - - In the code, "D_surf"= surf_trans_thick - - - Within a "boundary layer" region set by the sum of - surf_turb_thick plus surf_trans_thick, the eddy - induced velocity is assumed to have zero vertical shear, - which means the quasi-Stokes streamfunction is linear with - depth. The neutral diffusive fluxes are reduced to horizontal - downgradient diffusion, with "horizontal" defined according - to surfaces of constant vertical coordinate. - - - (3) Interior region: - Where neutral diffusion and GM skew-diffusion are taken - from their unmodified form. - - Only use the 31 and 32 triads for this computation since the - 13 and 23 triads require extra slope calculations, and - so will add lots of computational cost. It is felt that the - 31 and 32 triads are sufficient for this calculation, in - a similar manner that they are used for the calculation of - the non-constant diffusivities. - - Scheme coded for MOM4p1 by Stephen.Griffies - Version: March2006 - Simplified version: June2008 - - - Subroutine computes the tracer independent pieces of the vertical - flux component. As a result of this routine, - Array tensor_31 = x-diffusivity*slope (m^2/sec) for fz - Array tensor_32 = y-diffusivity*slope (m^2/sec) for fz - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Also will compute the squared Eady growth rate, with the maximum - slope contributing to this growth rate set by smax. - - For saving the contributions from GM and Redi separately, it is - necessary to compute the tensor_redi component here. - - We do so here, reproducing some lines of code from fz_terms, - to reduce minimize the need to impinge on the case when NOT - using this generally expensive (memory and computational) - diagnostic. - - This routine MUST be called prior to fz_terms, since we use - tensor_31 and tensor_32 in their raw slope forms here. - - - Subroutine computes the i-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the i-directed neutral physics tracer flux component - for Redi separately from GM, in order to diagnose GM and Redi - fluxes independent of one another. - - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the j-directed neutral physics tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the j-directed neutral physics tracer flux component - for Redi separately, in order to diagnose GM and Redi contributions - independent of one another. - - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the vertical neutral physics tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - - For diagnosing the GM and Redi pieces separately. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - - Send some diagnostics to diagnostics manager. - - Write some checksums. - - Write out restart files registered through register_restart_file - - Write to restart. - Module ocean_nphysicsC_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysicsC_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian skew-diffusion. -
- - - -- This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian skew-diffusion. The algorithms for neutral diffusion - are based on mom4p0d methods. The algorithm for neutral skewsion - are based on a projection onto a few of the lowest baroclinic - modes. This module is experimental, and should be used with caution. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
time_manager_mod
ocean_density_mod
ocean_domains_mod
ocean_nphysics_util_mod
ocean_operators_mod
ocean_parameters_mod
ocean_tracer_diag_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysicsC_init:
- -- -nphysicsC:
- -- -neutral_blayer:
- -- -compute_ndiffusion:
- -- -compute_gmskewsion:
- -- -baroclinic_modes:
- -- -compute_psi_modes:
- -- -compute_psi_bvp:
- -- -fz_terms:
- -- -fx_flux_ndiffuse:
- -- -fy_flux_ndiffuse:
- -- -fz_flux_ndiffuse:
- -- -fx_flux_gm:
- -- -fy_flux_gm:
- -- -fz_flux_gm:
- -- -invtri_bvp:
- -- -compute_advect_transport:
- -- -ocean_nphysicsC_restart:
- -- -ocean_nphysicsC_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysicsC_init
--
-- -DESCRIPTION -
-- - Initialize the neutral physics module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. -
-
-
-- - -
-nphysicsC
--
-- -DESCRIPTION -
-- - This function computes the thickness weighted and density weighted - time tendency for tracer from neutral physics. Full discussion - and details are provided by Griffies (2008). - - Here is a brief summary. - ----How the neutral diffusive flux components are computed: - - The vertical flux component is split into diagonal (3,3) and - off-diagonal (3,1) and (3,2) terms. The off-diagonal (3,1) and (3,2) - terms are included explicitly in time. The main contribution from the - (3,3) term to the time tendency is included implicitly in time - along with the usual contribution from diapycnal processes - (vertical mixing schemes). This is the K33_implicit term. - This approach is necessary with high vertical resolution, as - noted by Cox (1987). However, splitting the vertical flux into - an implicit and explicit piece compromises the - integrity of the vertical flux component (see Griffies et al. 1998). - So to minimize the disparity engendered by this split, the portion of - K33 that can be stably included explicitly in time is computed along - with the (3,1) and (3,2) terms. - - All other terms in the mixing tensor are included explicitly in time - using a forward time step as required for temporal stability of - numerical diffusive processes. - - The off-diagonal terms in the horizontal flux components, and all terms - in the vertical flux component, are tapered in regions of steep neutral - slope according to the requirements of linear stability. MOM allows for - choice of two tapering schemes: - - (a) the tanh taper of Danabasoglu and McWilliams (1995) - (b) the quadratic scheme of Gerdes, Koberle, and Willebrand (1991) - - Linear stability is far less stringent on the diagonal (1,1) and (2,2) - part of the horizontal flux. Indeed, these terms in practice need - not be tapered in steep sloped regions. - ----How the skew diffusive flux components are computed: - - The skew flux components are purely off-diagonal. - They are computed based on a vector streamfunction which - is built from a sum of baroclinic modes. - It is this part of the calculation that differs from - ocean_nphysicsA and ocean_nphysicsB. -
-
-
-- - -
-neutral_blayer
--
-- -DESCRIPTION -
-- - Subroutine computes the boundary layer as determined by - 1. depth within which typical mesoscale eddies are partially outcropped - 2. depth within which vertical mixing scheme (e.g., kpp) computes a boundary layer - - Determine depth over which mesoscale eddies feel the ocean - surface. This depth is a function of the neutral slope - and the Rossby radius. This depth is called "eddy_depth". - The algorithm for computing this depth is taken from - the appendix to Large etal, 1997 JPO vol 27, 2418-2447. - - In addition to considering mesoscale eddy lengths, - include the possibility that the diabatic vertical - mixing (e.g., KPP) produces a mixed layer depth that is - deeper than the depth that mesoscale eddies feel the ocean - surface. Include this surf_blthick in the considerations so - to determine the depth of this generalized "boundary layer" - and the neutral slope at the base of the boundary layer. - - Note: Only consider surface boundary layers here. - - This subroutine is a modification of that in ocean_nphysicsA. - Here, we only compute the eddy_depth based on the - algorithm in Large etal. We do not compute an eddy - depth which is also a function of smax. that is, we - remove the ocean_nphysicsA portion of the calculation - that sits inside the neutral_linear_gm_taper if-test. - -
-
-
-- - -
-compute_ndiffusion
--
-- -DESCRIPTION -
-- - Subroutine to compute the tendency from neutral diffusion. -
-
-
-- - -
-compute_gmskewsion
--
-- -DESCRIPTION -
-- - Subroutine to compute the tracer tendency from GM skewsion. -
-
-
-- - -
-baroclinic_modes
--
-- -DESCRIPTION -
-- - Subroutine computes the baroclinic wave speeds and the dimensionless - baroclinic mode eigenfunction for the vertical velocity baroclinic - modes. These modes vanish at the surface and the bottom. We use - the Chelton etal WKB analytic formulae for the speeds and modes. - - The baroclinic modes are dimensionless, and normalized over the - depth of the ocean, from free surface to bottom. - - Units of the speeds are m/sec. - -
-
-
-- - -
-compute_psi_modes
--
-- -DESCRIPTION -
-- - Compute vector streamfunction as projection onto baroclinic modes. - - Units of psi are m^2/sec - - This method for computing the quasi-Stokes streamfunction - is not generally recommended. It remains in MOM only for - testing purposes. - -
-
-
-- - -
-compute_psi_bvp
--
-- -DESCRIPTION -
-- - Compute vector streamfunction by solving a boundary value problem. - - psi is centered on bottom of tracer cell; for example, - psi(k=1)=psi at bottom of tracer cell k=1. - psi vanishes at the ocean surface: psi(k=0)=0 - and ocean bottom: psi(k=kmt)=0. - - psix is centred on north face of tracer cell - psiy is centred on east face of tracer cell - - Solve for psi(k=1,kmt-1) using a tridiagonal solver from - Section 2.4 of Press etal 1986. - - Units of psi are m^2/sec - -
-
-
-- - -
-fz_terms
--
-- -DESCRIPTION -
-- - Subroutine computes the tracer independent pieces of the vertical - flux component. As a result of this routine, - Array tensor_31 = x-diffusivity*slope (m^2/sec) for fz - Array tensor_32 = y-diffusivity*slope (m^2/sec) for fz - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Also will compute the squared Eady growth rate, with the maximum - slope contributing to this growth rate set by smax. - - This routine is nearly the same as in ocean_nphysicsA, except - for the following changes: - 1/ the routine here removes all pieces related to GM-skewsion. - 2/ the routine here uses Thickness%depth_zwt rather than Grd%zt. - -
-
-
-- - -
-fx_flux_ndiffuse
--
-- -DESCRIPTION -
-- - Subroutine computes the zonal neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - This routine is the same as that in ocean_nphysicsA, except - for the following changes: - 1/ the routine here removes all pieces related to GM-skewsion. - 2/ the routine here uses Thickness%depth_zwt rather than Grd%zt. - 3/ ah_array is removed. - -
-
-
-- - -
-fy_flux_ndiffuse
--
-- -DESCRIPTION -
-- - Subroutine computes the meridional neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - This routine is the same as that in ocean_nphysicsA, except - for the following changes: - 1/ the routine here removes all pieces related to GM-skewsion. - 2/ the routine here uses Thickness%depth_zwt rather than Grd%zt. - 3/ ah_array is removed. - -
-
-
-- - -
-fz_flux_ndiffuse
--
-- -DESCRIPTION -
-- - Subroutine computes the vertical neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - This is nearly the same as the subroutine in ocean_nphysicsA. - -
-
-
-- - -
-fx_flux_gm
--
-- -DESCRIPTION -
-- - Subroutine computes the zonal GM tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fy_flux_gm
--
-- -DESCRIPTION -
-- - Subroutine computes the meridional GM tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
-
-
-- - -
-fz_flux_gm
--
-- -DESCRIPTION -
-- - Subroutine computes the vertical GM tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - -
-
-
-- - -
-invtri_bvp
--
-- -DESCRIPTION -
-- - Solve the vertical diffusion equation implicitly using the - method of inverting a tridiagonal matrix as described in - Numerical Recipes in Fortran, The art of Scientific Computing, - Second Edition, Press, Teukolsky, Vetterling, Flannery, 1992 - pages 42,43. - - enforce upsilon(k=kmt) = 0 via use of mask(k+1). - -
-
-
-- - -
-compute_advect_transport
--
-- -DESCRIPTION -
-- - Diagnose advective mass transport from GM. - - This routine is a diagnostic routine since generically we use the - skewsion approach for the GM scheme. However, it could form the - basis for an advective implementation of GM, which remains to be done. - - Comments on the diagnostic scheme: - - 0/ algorithm based on a similar approach used for submeso parameterization. - - 1/ psiy(k) is centred at bottom of tracer cell at zonal face. - so -(psiy(i,j,k-1)-psiy(i,j,k)) gives zonal transport through - tracer cell k. - - 2/ psix(k) is centred at bottom of tracer cell at meridional face. - so (psix(i,j,k-1)-psix(i,j,k)) gives meridional transport through - tracer cell k. - - 3/ compute vertical component from convergence of horizontal, just - as for the vertical velocity component for the Eulerian transport. - - 4/ wrho_bt_gm(:,:,k=0) = 0.0 by definition - it should be diagnosed to have zero at the ocean bottom; we should - check that this is indeed the case to verify the diagnostic algorithm. - - 5/ expand the BDX_ET and BDY_NT operators for efficiency. - -
-
-
-- - -
-ocean_nphysicsC_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_nphysicsC_end
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-
-NAMELIST
- --&ocean_nphysicsC_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For printing starting and ending checksums for restarts -
-
-[logical] -- -epsln_bv_freq -
-- Minimum buoyancy frequency accepted for the computation of - baroclinic modes. Default epsln_bv_freq=1e-10. Note there - is also a minimum drhodz set in ocean_density.F90 via the - nml epsln_drhodz in that module. We provide yet another minimum - here in case we need an extra regularization for the amplitude - of the baroclinic modes. -
-
-[real, units: kg/m4] -- -do_neutral_diffusion -
-- To compute tendency from neutral diffusion. - Default do_neutral_diffusion=.true. -
-
-[logical] -- -do_gm_skewsion -
-- To compute tendency from GM skewsion. Default do_gm_skewsion=.true. -
-
-[logical] -- -gm_skewsion_modes -
-- To compute tendency from GM skewsion using streamfunction established - by baroclinic modes. Default gm_skewsion_modes=.false. -
-
-[logical] -- -gm_skewsion_bvproblem -
-- To compute tendency from GM skewsion using streamfunction established - by a boundary value problem. Default gm_skewsion_bvproblem=.true. -
-
-[logical] -- -number_bc_modes -
-- The number of baroclinic modes used to construct the eddy induced - streamfunction. Default number_bc_modes=1. -
-
-[integer] -- -bvp_bc_mode -
-- The particular baroclinic mode used to construct the BVP streamfunction. - If bvp_bc_mode=0, then will set bc_speed=0 when computing the BVP streamfunction. - Default bvp_bc_mode=1. -
-
-[integer] -- -bvp_constant_speed -
-- For taking a constant speed to be used for the calculation - of the BVP streamfunction. Default bvp_constant_speed=.false. -
-
-[logical] -- -bvp_speed -
-- For setting the speed weighting the second order derivative operator - in the BVP streamfunction method: - c^2 = max[bvp_min_speed, (bvp_speed-c_mode)^2]. - If bvp_constant_speed, then c^2 = bvp_speed^2. - Default bvp_speed=0.0, in which case c^2 = c_mode^2. -
-
-[real, units: m/s] -- -bvp_min_speed -
-- For setting a minimum speed for use with the calculation - of the BVP streamfunction. We need bvp_min_speed>0 to ensure - that the second order derivative operator contributes to the - calculation of the streamfunction. - Default bvp_min_speed=0.1. -
-
-[real, units: m/s] -- -bv_freq_smooth_vert -
-- To smooth the buoyancy frequency for use in - computing the baroclinic modes. Generally this field has already - been smooted in ocean_density_mod, but we maintain the possibility of - further smoothing here. Default bv_freq_smooth_vert=.false. -
-
-[logical] -- -num_121_passes -
-- The number of 121 passes used to smooth buoyancy frequency when - bv_freq_smooth_vert=.true. Default num_121_passes=1. -
-
-[integer] -- -min_bc_speed -
-- The minimum speed used for computing the baroclinic modes. - Default min_bc_speed=1e-6 -
-
-[real, units: m/s] -- -smooth_bc_modes -
-- For doing a vertical 1-2-1 smoothing on the baroclinic modes - prior to normalization. This is useful to reduce noise. - Default smooth_bc_modes=.false. -
-
-[logical] -- -smooth_psi -
-- For doing a horizontal 1-2-1 smoothing on the psix and psiy fields. - This is useful to reduce noise. Default smooth_psi=.true. -
-
-[logical] -- -regularize_psi -
-- To reduce the magnitude of psi in regions of weak stratification, - using the slope = smax_psi to set the overall scale of the max allowed - for psi. Default regularize_psi=.true. -
-
-[logical] -- -smax_modes -
-- Maximum slope used for setting the overall scale of a modal - contribution to the parameterized transport. - Default smax_psi=0.1. -
-
-[real] -- -diffusion_all_explicit -
-- To compute all contributions from neutral diffusion explicitly in time, including - the K33 diagonal piece. This approach is available only when have small time - steps and/or running with just a single tracer. It is for testing purposes. -
-
-[logical] -- -neutral_physics_limit -
-- When tracer falls outside a specified range, revert to horizontal - diffusive fluxes at this cell. This is an ad hoc and incomplete attempt - to maintain monotonicity with the neutral physics scheme. - Default neutral_physics_limit=.true. -
-
-[logical] -- -tmask_neutral_on -
-- If .true. then this logical reduces the neutral diffusive fluxes to - horizontal/vertical diffusion next to boundaries. - This approach has been found to reduce spurious - extrema resulting from truncation of triads used to compute - a neutral flux component. - Default tmask_neutral_on=.false. -
-
-[logical] -- -dm_taper -
-- Set to true to use the tanh tapering scheme of Danabasoglu and McWilliams. - Default is true. -
-
-[logical] -- -gkw_taper -
-- Set to true to use the quadradic tapering scheme of Gerdes, Koberle, and Willebrand. - Default is false. -
-
-[logical] -- -neutral_eddy_depth -
-- Compute eddy_depth according to depth over which eddies feel the ocean surface. - Default neutral_eddy_depth=.true. -
-
-[logical] -- -turb_blayer_min -
-- Minimum depth of a surface turbulent boundary layer - used in the transition of the neutral diffusion fluxes - to the surface. Note that in mom4p0, - turb_blayer_min was always set to zero. -
-
-[real] -- -use_neutral_slopes_potrho -
-- To compute the neutral slopes based on globally referenced potential - density rather than locally referenced potential density. This approach - is meant solely for sensitivity studies; it is not meant for realistic - simulations. - Default use_neutral_slopes_potrho=.false. -
-
-[logical] -- -neutral_slopes_potrho_press -
-- The reference pressure used to compute neutral slopes when setting - use_neutral_slopes_potrho=.true. - Default neutral_slopes_potrho_press=2000.0 -
-
-[real, units: dbar] -- -smooth_advect_transport -
-- For doing a horizontal 1-2-1 smoothing on the diagnosed - uhrho_et_gm and vhrho_nt_gm fields. - Default smooth_advect_transport=.true. -
-
-[logical] -- -smooth_advect_transport_num -
-- Number of iterations for the smooothing of horizontal transport. - Default smooth_advect_transport_num=2. -
-
-[integer] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, - J.K. Dukowicz, and R.D. Smith - Isoneutral diffusion in a z-coordinate ocean model - Journal of Physical Oceanography (1998) vol 28 pages 805-830 -
-- - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
-- - R. Ferrari, S.M. Griffies, A.J.G. Nurser, and G.K. Vallis - A boundary value problem for the parameterized mesoscale eddy transport - Ocean Modelling, Volume 32, 2010, Pages 143-156. -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
-- - S.M. Griffies: Elements of MOM (2012) -
-- - D.B. Chelton, R.A. deSzoeke, M.G. Schlax, K.E. Naggar, N. Siwertz - Geographical Variability of the First Baroclinic Rossby Radius of Deformation - Journal of Physical Oceanography (1998) vol 28 pages 433-460 -
-- - G. Danabasoglu and J. C. McWilliams - Sensitivity of the global ocean circulation to - parameterizations of mesoscale tracer transports - Journal of Climate (1995) vol 8 pages 2967--2987 -
-- - Gerdes, Koberle, and Willebrand - The influence of numerical advection schemes on the results of ocean - general circulation models, Climate Dynamics (1991), vol. 5, - pages 211--226. -
-
- - -
-NOTES
- -- Numerical implementation of the flux components follows the triad - approach documented in the references and implemented in MOM2 and MOM3. - The MOM algorithm accounts for partial bottom cells and generalized - orthogonal horizontal coordinates and general vertical levels. --
-
- In steep neutral slope regions, neutral diffusive fluxes are tapered - to zero with the tanh taper of Danabasoglu and McWilliams (1995) or the - quadratic scheme of Gerdes, Koberle, and Willebrand. - - Traditional tapering is not required for the skew fluxes computed in - this module. -
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysicsC.xml b/src/mom5/ocean_param/neutral/ocean_nphysicsC.xml deleted file mode 100644 index 113381a221..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysicsC.xml +++ /dev/null @@ -1,410 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_diff.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_diff.F90 index c80f36f030..2e579f12a2 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_diff.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_diff.F90 @@ -75,9 +75,9 @@ module ocean_nphysics_diff_mod #include Stephen M. Griffies - Tim Leslie - - Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian skew-diffusion. - - This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian skew-diffusion. The algorithms for neutral diffusion - are based on mom4p0d methods. The algorithm for neutral skewsion - are based on a projection onto a few of the lowest baroclinic - modes. This module is experimental, and should be used with caution. - - S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, - J.K. Dukowicz, and R.D. Smith - Isoneutral diffusion in a z-coordinate ocean model - Journal of Physical Oceanography (1998) vol 28 pages 805-830 - - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 - - R. Ferrari, S.M. Griffies, A.J.G. Nurser, and G.K. Vallis - A boundary value problem for the parameterized mesoscale eddy transport - Ocean Modelling, Volume 32, 2010, Pages 143-156. - - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press - - S.M. Griffies: Elements of MOM (2012) - - D.B. Chelton, R.A. deSzoeke, M.G. Schlax, K.E. Naggar, N. Siwertz - Geographical Variability of the First Baroclinic Rossby Radius of Deformation - Journal of Physical Oceanography (1998) vol 28 pages 433-460 - - G. Danabasoglu and J. C. McWilliams - Sensitivity of the global ocean circulation to - parameterizations of mesoscale tracer transports - Journal of Climate (1995) vol 8 pages 2967--2987 - - Gerdes, Koberle, and Willebrand - The influence of numerical advection schemes on the results of ocean - general circulation models, Climate Dynamics (1991), vol. 5, - pages 211--226. - - Numerical implementation of the flux components follows the triad - approach documented in the references and implemented in MOM2 and MOM3. - The MOM algorithm accounts for partial bottom cells and generalized - orthogonal horizontal coordinates and general vertical levels. - - In steep neutral slope regions, neutral diffusive fluxes are tapered - to zero with the tanh taper of Danabasoglu and McWilliams (1995) or the - quadratic scheme of Gerdes, Koberle, and Willebrand. - - Traditional tapering is not required for the skew fluxes computed in - this module. - - Must be true to use this module. Default is false. - - For printing starting and ending checksums for restarts - - Minimum buoyancy frequency accepted for the computation of - baroclinic modes. Default epsln_bv_freq=1e-10. Note there - is also a minimum drhodz set in ocean_density.F90 via the - nml epsln_drhodz in that module. We provide yet another minimum - here in case we need an extra regularization for the amplitude - of the baroclinic modes. - - To compute tendency from neutral diffusion. - Default do_neutral_diffusion=.true. - - To compute tendency from GM skewsion. Default do_gm_skewsion=.true. - - To compute tendency from GM skewsion using streamfunction established - by baroclinic modes. Default gm_skewsion_modes=.false. - - To compute tendency from GM skewsion using streamfunction established - by a boundary value problem. Default gm_skewsion_bvproblem=.true. - - The number of baroclinic modes used to construct the eddy induced - streamfunction. Default number_bc_modes=1. - - The particular baroclinic mode used to construct the BVP streamfunction. - If bvp_bc_mode=0, then will set bc_speed=0 when computing the BVP streamfunction. - Default bvp_bc_mode=1. - - For taking a constant speed to be used for the calculation - of the BVP streamfunction. Default bvp_constant_speed=.false. - - For setting the speed weighting the second order derivative operator - in the BVP streamfunction method: - c^2 = max[bvp_min_speed, (bvp_speed-c_mode)^2]. - If bvp_constant_speed, then c^2 = bvp_speed^2. - Default bvp_speed=0.0, in which case c^2 = c_mode^2. - - For setting a minimum speed for use with the calculation - of the BVP streamfunction. We need bvp_min_speed>0 to ensure - that the second order derivative operator contributes to the - calculation of the streamfunction. - Default bvp_min_speed=0.1. - - To smooth the buoyancy frequency for use in - computing the baroclinic modes. Generally this field has already - been smooted in ocean_density_mod, but we maintain the possibility of - further smoothing here. Default bv_freq_smooth_vert=.false. - - The number of 121 passes used to smooth buoyancy frequency when - bv_freq_smooth_vert=.true. Default num_121_passes=1. - - The minimum speed used for computing the baroclinic modes. - Default min_bc_speed=1e-6 - - For doing a vertical 1-2-1 smoothing on the baroclinic modes - prior to normalization. This is useful to reduce noise. - Default smooth_bc_modes=.false. - - For doing a horizontal 1-2-1 smoothing on the psix and psiy fields. - This is useful to reduce noise. Default smooth_psi=.true. - - To reduce the magnitude of psi in regions of weak stratification, - using the slope = smax_psi to set the overall scale of the max allowed - for psi. Default regularize_psi=.true. - - Maximum slope used for setting the overall scale of a modal - contribution to the parameterized transport. - Default smax_psi=0.1. - - To compute all contributions from neutral diffusion explicitly in time, including - the K33 diagonal piece. This approach is available only when have small time - steps and/or running with just a single tracer. It is for testing purposes. - - When tracer falls outside a specified range, revert to horizontal - diffusive fluxes at this cell. This is an ad hoc and incomplete attempt - to maintain monotonicity with the neutral physics scheme. - Default neutral_physics_limit=.true. - - If .true. then this logical reduces the neutral diffusive fluxes to - horizontal/vertical diffusion next to boundaries. - This approach has been found to reduce spurious - extrema resulting from truncation of triads used to compute - a neutral flux component. - Default tmask_neutral_on=.false. - - Set to true to use the tanh tapering scheme of Danabasoglu and McWilliams. - Default is true. - - Set to true to use the quadradic tapering scheme of Gerdes, Koberle, and Willebrand. - Default is false. - - Compute eddy_depth according to depth over which eddies feel the ocean surface. - Default neutral_eddy_depth=.true. - - Minimum depth of a surface turbulent boundary layer - used in the transition of the neutral diffusion fluxes - to the surface. Note that in mom4p0, - turb_blayer_min was always set to zero. - - To compute the neutral slopes based on globally referenced potential - density rather than locally referenced potential density. This approach - is meant solely for sensitivity studies; it is not meant for realistic - simulations. - Default use_neutral_slopes_potrho=.false. - - The reference pressure used to compute neutral slopes when setting - use_neutral_slopes_potrho=.true. - Default neutral_slopes_potrho_press=2000.0 - - For doing a horizontal 1-2-1 smoothing on the diagnosed - uhrho_et_gm and vhrho_nt_gm fields. - Default smooth_advect_transport=.true. - - Number of iterations for the smooothing of horizontal transport. - Default smooth_advect_transport_num=2. - - Initialize the neutral physics module by registering fields for - diagnostic output and performing some numerical checks to see - that namelist settings are appropriate. - - This function computes the thickness weighted and density weighted - time tendency for tracer from neutral physics. Full discussion - and details are provided by Griffies (2008). - - Here is a brief summary. - ----How the neutral diffusive flux components are computed: - - The vertical flux component is split into diagonal (3,3) and - off-diagonal (3,1) and (3,2) terms. The off-diagonal (3,1) and (3,2) - terms are included explicitly in time. The main contribution from the - (3,3) term to the time tendency is included implicitly in time - along with the usual contribution from diapycnal processes - (vertical mixing schemes). This is the K33_implicit term. - This approach is necessary with high vertical resolution, as - noted by Cox (1987). However, splitting the vertical flux into - an implicit and explicit piece compromises the - integrity of the vertical flux component (see Griffies et al. 1998). - So to minimize the disparity engendered by this split, the portion of - K33 that can be stably included explicitly in time is computed along - with the (3,1) and (3,2) terms. - - All other terms in the mixing tensor are included explicitly in time - using a forward time step as required for temporal stability of - numerical diffusive processes. - - The off-diagonal terms in the horizontal flux components, and all terms - in the vertical flux component, are tapered in regions of steep neutral - slope according to the requirements of linear stability. MOM allows for - choice of two tapering schemes: - - (a) the tanh taper of Danabasoglu and McWilliams (1995) - (b) the quadratic scheme of Gerdes, Koberle, and Willebrand (1991) - - Linear stability is far less stringent on the diagonal (1,1) and (2,2) - part of the horizontal flux. Indeed, these terms in practice need - not be tapered in steep sloped regions. - ----How the skew diffusive flux components are computed: - - The skew flux components are purely off-diagonal. - They are computed based on a vector streamfunction which - is built from a sum of baroclinic modes. - It is this part of the calculation that differs from - ocean_nphysicsA and ocean_nphysicsB. - - Subroutine computes the boundary layer as determined by - 1. depth within which typical mesoscale eddies are partially outcropped - 2. depth within which vertical mixing scheme (e.g., kpp) computes a boundary layer - - Determine depth over which mesoscale eddies feel the ocean - surface. This depth is a function of the neutral slope - and the Rossby radius. This depth is called "eddy_depth". - The algorithm for computing this depth is taken from - the appendix to Large etal, 1997 JPO vol 27, 2418-2447. - - In addition to considering mesoscale eddy lengths, - include the possibility that the diabatic vertical - mixing (e.g., KPP) produces a mixed layer depth that is - deeper than the depth that mesoscale eddies feel the ocean - surface. Include this surf_blthick in the considerations so - to determine the depth of this generalized "boundary layer" - and the neutral slope at the base of the boundary layer. - - Note: Only consider surface boundary layers here. - - This subroutine is a modification of that in ocean_nphysicsA. - Here, we only compute the eddy_depth based on the - algorithm in Large etal. We do not compute an eddy - depth which is also a function of smax. that is, we - remove the ocean_nphysicsA portion of the calculation - that sits inside the neutral_linear_gm_taper if-test. - - - Subroutine to compute the tendency from neutral diffusion. - - Subroutine to compute the tracer tendency from GM skewsion. - - Subroutine computes the baroclinic wave speeds and the dimensionless - baroclinic mode eigenfunction for the vertical velocity baroclinic - modes. These modes vanish at the surface and the bottom. We use - the Chelton etal WKB analytic formulae for the speeds and modes. - - The baroclinic modes are dimensionless, and normalized over the - depth of the ocean, from free surface to bottom. - - Units of the speeds are m/sec. - - - Compute vector streamfunction as projection onto baroclinic modes. - - Units of psi are m^2/sec - - This method for computing the quasi-Stokes streamfunction - is not generally recommended. It remains in MOM only for - testing purposes. - - - Compute vector streamfunction by solving a boundary value problem. - - psi is centered on bottom of tracer cell; for example, - psi(k=1)=psi at bottom of tracer cell k=1. - psi vanishes at the ocean surface: psi(k=0)=0 - and ocean bottom: psi(k=kmt)=0. - - psix is centred on north face of tracer cell - psiy is centred on east face of tracer cell - - Solve for psi(k=1,kmt-1) using a tridiagonal solver from - Section 2.4 of Press etal 1986. - - Units of psi are m^2/sec - - - Subroutine computes the tracer independent pieces of the vertical - flux component. As a result of this routine, - Array tensor_31 = x-diffusivity*slope (m^2/sec) for fz - Array tensor_32 = y-diffusivity*slope (m^2/sec) for fz - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Also will compute the squared Eady growth rate, with the maximum - slope contributing to this growth rate set by smax. - - This routine is nearly the same as in ocean_nphysicsA, except - for the following changes: - 1/ the routine here removes all pieces related to GM-skewsion. - 2/ the routine here uses Thickness%depth_zwt rather than Grd%zt. - - - Subroutine computes the zonal neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - This routine is the same as that in ocean_nphysicsA, except - for the following changes: - 1/ the routine here removes all pieces related to GM-skewsion. - 2/ the routine here uses Thickness%depth_zwt rather than Grd%zt. - 3/ ah_array is removed. - - - Subroutine computes the meridional neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - This routine is the same as that in ocean_nphysicsA, except - for the following changes: - 1/ the routine here removes all pieces related to GM-skewsion. - 2/ the routine here uses Thickness%depth_zwt rather than Grd%zt. - 3/ ah_array is removed. - - - Subroutine computes the vertical neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - This is nearly the same as the subroutine in ocean_nphysicsA. - - - Subroutine computes the zonal GM tracer flux component. - Compute this component for all tracers at level k. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the meridional GM tracer flux component. - Compute this component for all tracers at level k. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - - - Subroutine computes the vertical GM tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - - Solve the vertical diffusion equation implicitly using the - method of inverting a tridiagonal matrix as described in - Numerical Recipes in Fortran, The art of Scientific Computing, - Second Edition, Press, Teukolsky, Vetterling, Flannery, 1992 - pages 42,43. - - enforce upsilon(k=kmt) = 0 via use of mask(k+1). - - - Diagnose advective mass transport from GM. - - This routine is a diagnostic routine since generically we use the - skewsion approach for the GM scheme. However, it could form the - basis for an advective implementation of GM, which remains to be done. - - Comments on the diagnostic scheme: - - 0/ algorithm based on a similar approach used for submeso parameterization. - - 1/ psiy(k) is centred at bottom of tracer cell at zonal face. - so -(psiy(i,j,k-1)-psiy(i,j,k)) gives zonal transport through - tracer cell k. - - 2/ psix(k) is centred at bottom of tracer cell at meridional face. - so (psix(i,j,k-1)-psix(i,j,k)) gives meridional transport through - tracer cell k. - - 3/ compute vertical component from convergence of horizontal, just - as for the vertical velocity component for the Eulerian transport. - - 4/ wrho_bt_gm(:,:,k=0) = 0.0 by definition - it should be diagnosed to have zero at the ocean bottom; we should - check that this is indeed the case to verify the diagnostic algorithm. - - 5/ expand the BDX_ET and BDY_NT operators for efficiency. - - - Write out restart files registered through register_restart_file - - Write to restart. - character(len=128) :: version=& - '$Id: ocean_nphysics_diff.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_diff.F90,v 20.0 2013/12/14 00:14:42 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_diff.html b/src/mom5/ocean_param/neutral/ocean_nphysics_diff.html deleted file mode 100644 index 52c331669e..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_diff.html +++ /dev/null @@ -1,384 +0,0 @@ - - - - Module ocean_nphysics_diff_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_diff_mod
- - - - - -
-OVERVIEW
- -- Compute the neutral diffusivity in this module. -
- - - -- This module computes the neutral diffusivity. There are many - methods available. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_nphysics_util_new_mod
ocean_operators_mod
ocean_parameters_mod
ocean_tracer_diag_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -check_nml_options:
- -- -init_globals:
- -- -register fields:
- -- -diffusivity_init:
- -- -check_stability:
- -- -compute_diffusivity:
- -- -compute_agm:
- -- -compute_raw_growth_rate:
- -- -compute_growth_rate:
- -- -vertical_average:
- -- -compute_length:
- -- -compute_bczone_radius:
- -- -compute_aredi:
- -- -apply_grid_scaling:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-check_nml_options
--
-- -DESCRIPTION -
-- - Read in the namelist parameters and ensure that valid values have been - choosen. - Also determine whether agm is z-dependent. -
-
-
-- - -
-init_globals
--
-- -DESCRIPTION -
-- - Allocate and initialise all (non-namelist) global variables in the module. -
-
-
-- - -
-register fields
--
-- -DESCRIPTION -
-- - Register diagnostic fields. -
-
-
-- - -
-diffusivity_init
--
-- -DESCRIPTION -
-- - Initialise the three diffusivity arrays. -
-
-
-- - -
-check_stability
--
-- -DESCRIPTION -
-- - Check the stability assumptions and print details of the limits of stability. -
-
-
-- - -
-compute_diffusivity
--
-- -DESCRIPTION -
-- - -
-
-
-- - -
-compute_agm
--
-- -DESCRIPTION -
-- - Compute the flow-dependent GM diffusivity. -
-
-
-- - -
-compute_raw_growth_rate
--
-- -DESCRIPTION -
-- - Compute the raw growth rate at each grid point, using either the eady - growth rate or the baroclinicity to obtain raw_growth_rate = NS -
-
-
-- - -
-compute_growth_rate
--
-- -DESCRIPTION -
-- - Take the raw growth rate and convert it to a final growth rate to be - used in the diffusivity calculations. -
-
-
-- - -
-vertical_average
--
-- -DESCRIPTION -
-- - Compute the vertical average of the given array between D_t and D_b, - as specified by agm_rate_upper_depth and agm_rate_lower_depth. -
-
-
-- - -
-compute_length
--
-- -DESCRIPTION -
-- - Compute the flow-dependent length scale involved in the GM diffusivity - calculations. -
-
-
-- - -
-compute_bczone_radius
--
-- -DESCRIPTION -
-- - Subroutine computes the radius of the baroclinic zone in a manner - suggested by the Hadley Centre approach (Malcolm Roberts, personal - communication). - - Algorithm is used in MOM3 and documented in the MOM3 Manual. -
-
-
-- - -
-compute_aredi
--
-- -DESCRIPTION -
-- - Compute the flow-dependent neutral (Redi) diffusivity. -
-
-
-- - -
-apply_grid_scaling
--
-- -DESCRIPTION -
-- - Scale the supplied array as a function of the grid length and the - Rossby radius. The scaling factor takes a value between zero and one. - - Interesting values of the scaling factor are - 1.0 if Rossby radius = 0.0 - 0.5 if Rossby radius = grid length - -> 0 as rossby radius -> inf -
-
-
-
-NAMELIST
- --&ocean_nphysics_diff_nml --
-
----
-- - -
-- -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press -
-- - S.M. Griffies, Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_diff.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_diff.xml deleted file mode 100644 index a9d9ef0fed..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_diff.xml +++ /dev/null @@ -1,61 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_flux.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_flux.F90 index 27c0646cfc..4b32d6ae58 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_flux.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_flux.F90 @@ -88,9 +88,9 @@ module ocean_nphysics_flux_mod #include Tim Leslie - Stephen M. Griffies - - Compute the neutral diffusivity in this module. - - This module computes the neutral diffusivity. There are many - methods available. - - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press - - S.M. Griffies, Elements of MOM (2012) - - - Read in the namelist parameters and ensure that valid values have been - choosen. - Also determine whether agm is z-dependent. - - Allocate and initialise all (non-namelist) global variables in the module. - - Register diagnostic fields. - - Initialise the three diffusivity arrays. - - Check the stability assumptions and print details of the limits of stability. - - - Compute the flow-dependent GM diffusivity. - - Compute the raw growth rate at each grid point, using either the eady - growth rate or the baroclinicity to obtain raw_growth_rate = NS - - Take the raw growth rate and convert it to a final growth rate to be - used in the diffusivity calculations. - - Compute the vertical average of the given array between D_t and D_b, - as specified by agm_rate_upper_depth and agm_rate_lower_depth. - - Compute the flow-dependent length scale involved in the GM diffusivity - calculations. - - Subroutine computes the radius of the baroclinic zone in a manner - suggested by the Hadley Centre approach (Malcolm Roberts, personal - communication). - - Algorithm is used in MOM3 and documented in the MOM3 Manual. - - Compute the flow-dependent neutral (Redi) diffusivity. - - Scale the supplied array as a function of the grid length and the - Rossby radius. The scaling factor takes a value between zero and one. - - Interesting values of the scaling factor are - 1.0 if Rossby radius = 0.0 - 0.5 if Rossby radius = grid length - -> 0 as rossby radius -> inf - character(len=128) :: version=& - '$Id: ocean_nphysics_flux.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_flux.F90,v 20.0 2013/12/14 00:14:44 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_flux.html b/src/mom5/ocean_param/neutral/ocean_nphysics_flux.html deleted file mode 100644 index 42c9b6e18b..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_flux.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - Module ocean_nphysics_flux_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_flux_mod
- - - - - -
-OVERVIEW
- -- Compute the neutral physics fluxes. -
- - - -- This module computes the neutral physics fluxes. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_nphysics_util_new_mod
ocean_operators_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysics_flux_init:
- -- -register fields:
- -- -flux_calculations:
- -- -compute_mass_diff:
- -- -geometric_terms:
- -- -compute_33_term:
- -- -compute_fluxes:
- -- -apply_tracer_limits:
- -- -update_tendencies:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysics_flux_init
--
-- -DESCRIPTION -
-- - Initialise namelist variables and prepare diagnostics. -
-
-
-- - -
-register fields
--
-- -DESCRIPTION -
-- - Register diagnostic fields. -
-
-
-- - -
-flux_calculations
--
-- -DESCRIPTION -
-- - This function computes the thickness weighted tendency of tracers - due to neutral physics as well as the implicit vertical diffusivity - term. -
-
-
-- - -
-compute_mass_diff
--
-- -DESCRIPTION -
-- - Subroutine computes the vertical neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - This is nearly the same as the subroutine in ocean_nphysicsA. - -
-
-
-- - -
-geometric_terms
--
-- -DESCRIPTION -
-- - Calculate the density weighted quarter cell volumes of the triads. -
-
-
-- - -
-compute_33_term
--
-- -DESCRIPTION -
-- - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. -
-
-
-- - -
-compute_fluxes
--
-- -DESCRIPTION -
-- - Computes the tracer fluxes due to neutral diffusion and skew diffusion. - Fluxes are computed at the tracer cell faces and have units of [kg*T/s]. -
-
-
-- - -
-apply_tracer_limits
--
-- -DESCRIPTION -
-- - If the neutral_physics_limit flag is set, then the flux used in regions of large - tracer gradients (as defined by T_prog(n)tmask_limit) are set to have purely - horizontal diffusion, with no vertical or skew terms. -
-
-
-- - -
-update_tendencies
--
-- -DESCRIPTION -
-- - Update the tendency for each tracer in each cell based on the total flux - flowing through each of the six cell faces. The tendency is calculated - separately for the flux due to neutral diffusion and due skew diffusion. -
-
-
-
-NAMELIST
- --&ocean_nphysics_flux_nml --
-
----
-- -diffusion_all_explicit -
-- To compute K33 explicitly in time. This setting is meant - only for debugging tests, since in general the simulation - will go unstable. - Default diffusion_all_explicit=.false. -
-
-[logical] -- -neutral_physics_limit -
-- Revert to horizontal diffusion when tracer falls outside specified range. - Default neutral_physics_limit=.true., so to keep tracers from going - too far outside of physical range. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_flux.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_flux.xml deleted file mode 100644 index c58e8ddb42..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_flux.xml +++ /dev/null @@ -1,62 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_new.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_new.F90 index 1bcb02f54f..19707be892 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_new.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_new.F90 @@ -110,9 +110,9 @@ module ocean_nphysics_new_mod #include Tim Leslie - Stephen M. Griffies - - Compute the neutral physics fluxes. - - This module computes the neutral physics fluxes. - - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press - - S.M. Griffies: Elements of MOM (2012) - - To compute K33 explicitly in time. This setting is meant - only for debugging tests, since in general the simulation - will go unstable. - Default diffusion_all_explicit=.false. - - Revert to horizontal diffusion when tracer falls outside specified range. - Default neutral_physics_limit=.true., so to keep tracers from going - too far outside of physical range. - - Initialise namelist variables and prepare diagnostics. - - Register diagnostic fields. - - This function computes the thickness weighted tendency of tracers - due to neutral physics as well as the implicit vertical diffusivity - term. - - Subroutine computes the vertical neutral diffusion tracer flux component. - Compute this component for all tracers at level k. - Surface and bottom boundary condition fz(k=0)=fz(k=kmt(i,j))=0 - - fz has physical dimensions (density*diffusivity*tracer gradient) - - This is nearly the same as the subroutine in ocean_nphysicsA. - - - Calculate the density weighted quarter cell volumes of the triads. - - K33 is the (3,3) term in small angle Redi diffusion tensor. - It is broken into an explicit in time piece and implicit - in time piece. It is weighted by density for non-Boussinesq - and rho0 for Boussinesq. - - K33 has units (kg/m^3)*m^2/sec. - - Computes the tracer fluxes due to neutral diffusion and skew diffusion. - Fluxes are computed at the tracer cell faces and have units of [kg*T/s]. - - If the neutral_physics_limit flag is set, then the flux used in regions of large - tracer gradients (as defined by T_prog(n)tmask_limit) are set to have purely - horizontal diffusion, with no vertical or skew terms. - - Update the tendency for each tracer in each cell based on the total flux - flowing through each of the six cell faces. The tendency is calculated - separately for the flux due to neutral diffusion and due skew diffusion. - character(len=128) :: version=& - '$Id: ocean_nphysics_new.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_new.F90,v 20.0 2013/12/14 00:14:46 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_new.html b/src/mom5/ocean_param/neutral/ocean_nphysics_new.html deleted file mode 100644 index 54d4af5717..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_new.html +++ /dev/null @@ -1,409 +0,0 @@ - - - - Module ocean_nphysics_new_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_new_mod
- - - - - -
-OVERVIEW
- -- Compute the effects of neutral physics processes - (neutral diffusion and neutral skew-diffusion). -
- - - -- Compute the effects of neutral physics processes - (neutral diffusion and neutral skew-diffusion). --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
fms_io_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_nphysics_util_new_mod
ocean_nphysics_flux_mod
ocean_nphysics_tensor_mod
ocean_nphysics_skew_mod
ocean_nphysics_diff_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysics_new_init:
- -- -register fields:
- -- -neutral_physics_new:
- -- -tracer_gradients:
- -- -density_calculations:
- -- -gradrho:
- -- -adjust_drhodz:
- -- -neutral_slopes:
- -- -neutral_blayer:
- -- -ocean_nphysics_new_restart:
- -- -ocean_nphysics_new_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysics_new_init
--
-- -DESCRIPTION -
-- - Initialises diagnostics, namelists and constants. -
-
-
-- - -
-register fields
--
-- -DESCRIPTION -
-- - Register diagnostic fields. -
-
-
-- - -
-neutral_physics_new
--
-- -DESCRIPTION -
-- - This public interface computes the effects of neutral physics - processes (neutral diffusion and neutral skew-diffusion). - - --Returns rossby_radius for use in lapgen_friction module. - --Returns gm_diffusivity for use in visc_form_drag module - --Updates the value of T_prog(n)%th_tendency with the explicit thickness - weighted tendency due to neutral physics and also T_prog(n)%K33_implicit - with the implicit component. -
-
-
-- - -
-tracer_gradients
--
-- -DESCRIPTION -
-- - Compute the tracer derivatives. - - G(2004) 16.58 - dTdx(i) = (T(i+1) - T(i))/dxte - dTdT(j) = (T(j+1) - T(j))/dytn - dTdz(k) = (T(k) - T(k+1))/dzwt - - Horizontal derivatives are taken along surfaces of - constant vertical coordinate (constant k-level) - - This approach ensures that when neutral physics defaults to "horizontal" physics - next to boundaries, it will do so as horizontal, defined along surfaces of constant - s-surfaces, and so will not generate spurious extrema. - - Additionally, when using generalized vertical coordinates, the neutral diffusion - slope should be computed relative to the s-surfaces. The skew diffusion slope - should ideally be computed with respect to z-surfaces, as z-surfaces define - available potential energy. However, when s and z surfaces are reasonably close, - as they are in the interior for zstar and pstar vertical coordinates, then we - choose to to dissipate thickness as defined relative to the zstar or pstar surfaces. - This should not be such a big deal, and it is certainly easier computationally than - worrying about computing two separate sets of slopes. More on this detail is - discussed in "Elements of MOM". - - NOTE: This approach is not appropriate for sigma-models. Indeed, many assumptions - in the neutral physics modules need to be rethought for terrain following vertical - coordinates. - -
-
-
-- - -
-density_calculations
--
-- -DESCRIPTION -
-- - This subroutine computes a number of values based on the density gradient. - - These are the neutral slope vector, the neutral buoyancy frequency, - gravity wave speed, Rossby radius and boundary layer depth. -
-
-
-- - -
-gradrho
--
-- -DESCRIPTION -
-- - Calculate the raw density gradients. No smoothing or limiting - applied here. -
-
-
-- - -
-adjust_drhodz
--
-- -DESCRIPTION -
-- - Comments about smoothing drhodz: - - 1/ Tests in coupled 1-degree model showed extreme sensitivity - of MOC to smoothing. GFDL users generally do NOT smooth, hence - the default drhodz_smooth_vert=drhodz_smooth_horz=.false. - - 2/ Smoothing the vertical derivative of drhodz helps - produce a regularized (i.e., well behaved) neutral slope vector. - - 3/ An attempt was made to smooth dTdz and dSdz rather - than drhodz. The resulting slope was smooth, but not as - smooth as when acting on drhodz itself. -
-
-
-- - -
-neutral_slopes
--
-- -DESCRIPTION -
-- - Compute the neutral slope vector along with its magnitude. - The neutral slope vector is defined as -grad_h(rho)/(drho/dz). -
-
-
-- - -
-neutral_blayer
--
-- -DESCRIPTION -
-- - Locate the vertical index of the neutral boundary layer. This layer is - defined as the point where the magnitude of the neutral slope vector - first drops below smax, when searching down from the surface. -
-
-
-- - -
-ocean_nphysics_new_restart
--
-- -DESCRIPTION -
-- - Write out the restart data for this module -
-
-
-- - -
-ocean_nphysics_new_end
--
-- -DESCRIPTION -
-- - Writes out the restart data. -
-
-
-
-NAMELIST
- --&ocean_nphysics_new_nml --
-
----
-- -use_this_module -
-- Must be set .true. to use this module. - Default use_this_module = .false. -
-
-[logical] -- -drhodz_smooth_vert -
-- For smoothing vertical density gradient before computing - neutral slope. Exercise caution if using this option. - Default drhodz_smooth_vert=.false. -
-
-[logical] -- -drhodz_smooth_horz -
-- For smoothing vertical density gradient before computing - neutral slope. Exercise caution if using this option. - Default drhodz_smooth_horz=.false. -
-
-[logical] -- -smax -
-- Slope maximum parameter for setting behaviour of neutral - physics. Default smax=0.01. -
-
-[real] -- -vel_micom_smooth -
-- For horizontal smoothing of drhodz before computing neutral - slopes. Default vel_micom_smooth=0.2. -
-
-[real, units: m/s] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press -
-- - S.M. Griffies, Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_new.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_new.xml deleted file mode 100644 index ef8f2ee012..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_new.xml +++ /dev/null @@ -1,109 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_skew.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_skew.F90 index 99d53c6ccc..5e8e83910d 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_skew.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_skew.F90 @@ -144,9 +144,9 @@ module ocean_nphysics_skew_mod #include Tim Leslie - Stephen M. Griffies - - Compute the effects of neutral physics processes - (neutral diffusion and neutral skew-diffusion). - - Compute the effects of neutral physics processes - (neutral diffusion and neutral skew-diffusion). - - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press - - S.M. Griffies, Elements of MOM (2012) - - Must be set .true. to use this module. - Default use_this_module = .false. - - For smoothing vertical density gradient before computing - neutral slope. Exercise caution if using this option. - Default drhodz_smooth_vert=.false. - - For smoothing vertical density gradient before computing - neutral slope. Exercise caution if using this option. - Default drhodz_smooth_horz=.false. - - Slope maximum parameter for setting behaviour of neutral - physics. Default smax=0.01. - - For horizontal smoothing of drhodz before computing neutral - slopes. Default vel_micom_smooth=0.2. - - Initialises diagnostics, namelists and constants. - - Register diagnostic fields. - - This public interface computes the effects of neutral physics - processes (neutral diffusion and neutral skew-diffusion). - - --Returns rossby_radius for use in lapgen_friction module. - --Returns gm_diffusivity for use in visc_form_drag module - --Updates the value of T_prog(n)%th_tendency with the explicit thickness - weighted tendency due to neutral physics and also T_prog(n)%K33_implicit - with the implicit component. - - Compute the tracer derivatives. - - G(2004) 16.58 - dTdx(i) = (T(i+1) - T(i))/dxte - dTdT(j) = (T(j+1) - T(j))/dytn - dTdz(k) = (T(k) - T(k+1))/dzwt - - Horizontal derivatives are taken along surfaces of - constant vertical coordinate (constant k-level) - - This approach ensures that when neutral physics defaults to "horizontal" physics - next to boundaries, it will do so as horizontal, defined along surfaces of constant - s-surfaces, and so will not generate spurious extrema. - - Additionally, when using generalized vertical coordinates, the neutral diffusion - slope should be computed relative to the s-surfaces. The skew diffusion slope - should ideally be computed with respect to z-surfaces, as z-surfaces define - available potential energy. However, when s and z surfaces are reasonably close, - as they are in the interior for zstar and pstar vertical coordinates, then we - choose to to dissipate thickness as defined relative to the zstar or pstar surfaces. - This should not be such a big deal, and it is certainly easier computationally than - worrying about computing two separate sets of slopes. More on this detail is - discussed in "Elements of MOM". - - NOTE: This approach is not appropriate for sigma-models. Indeed, many assumptions - in the neutral physics modules need to be rethought for terrain following vertical - coordinates. - - - This subroutine computes a number of values based on the density gradient. - - These are the neutral slope vector, the neutral buoyancy frequency, - gravity wave speed, Rossby radius and boundary layer depth. - - Calculate the raw density gradients. No smoothing or limiting - applied here. - - Comments about smoothing drhodz: - - 1/ Tests in coupled 1-degree model showed extreme sensitivity - of MOC to smoothing. GFDL users generally do NOT smooth, hence - the default drhodz_smooth_vert=drhodz_smooth_horz=.false. - - 2/ Smoothing the vertical derivative of drhodz helps - produce a regularized (i.e., well behaved) neutral slope vector. - - 3/ An attempt was made to smooth dTdz and dSdz rather - than drhodz. The resulting slope was smooth, but not as - smooth as when acting on drhodz itself. - - Compute the neutral slope vector along with its magnitude. - The neutral slope vector is defined as -grad_h(rho)/(drho/dz). - - Locate the vertical index of the neutral boundary layer. This layer is - defined as the point where the magnitude of the neutral slope vector - first drops below smax, when searching down from the surface. - - Write out the restart data for this module - - Writes out the restart data. - character(len=128) :: version=& - '$Id: ocean_nphysics_skew.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_skew.F90,v 20.0 2013/12/14 00:14:48 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_skew.html b/src/mom5/ocean_param/neutral/ocean_nphysics_skew.html deleted file mode 100644 index 2020f62e48..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_skew.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - Module ocean_nphysics_skew_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_skew_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian skew-diffusion. -
- - - -- This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian skew-diffusion. The algorithms for neutral diffusion - are based on mom4p0d methods. The algorithm for neutral skewsion - are based on a projection onto a few of the lowest baroclinic - modes. This module is experimental, and should be used with caution. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_mod
ocean_domains_mod
ocean_nphysics_util_new_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysics_skew_init:
- -- -register fields:
- -- -gm_tensor:
- -- -compute_transport_modes:
- -- -do_regularize_transport:
- -- -compute_transport_bvp:
- -- -invtri_bvp:
- -- -do_smooth_transport:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysics_skew_init
--
-- -DESCRIPTION -
-- - Initialization routine. -
-
-
-- - -
-register fields
--
-- -DESCRIPTION -
-- - Register diagnostic fields. -
-
-
-- - -
-gm_tensor
--
-- -DESCRIPTION -
-- - Compute the skew tensor terms using the GM method. -
-
-
-- - -
-compute_transport_modes
--
-- -DESCRIPTION -
-- - Compute transport as projection onto baroclinic modes. - - Units of upsilon are m^2/sec - - Subroutine computes the baroclinic wave speeds and the dimensionless - baroclinic mode eigenfunction for the vertical velocity baroclinic - modes. These modes vanish at the surface and the bottom. We use - the Chelton etal WKB analytic formulae for the speeds and modes. - - The baroclinic modes are dimensionless, and normalized over the - depth of the ocean, from free surface to bottom. - - The speeds are m/sec. - -
-
-
-- - -
-do_regularize_transport
--
-- -DESCRIPTION -
-- - regularize the transport to keep magnitude - under control in regions of weak vertical stratification. -
-
-
-- - -
-compute_transport_bvp
--
-- -DESCRIPTION -
-- - Compute transport by solving a boundary value problem. - - psi is centered on bottom of tracer cell; for example, - psi(k=1)=psi at bottom of tracer cell k=1. - psi vanishes at the ocean surface: psi(k=0)=0 - and ocean bottom: psi(k=kmt)=0. - - We solve for psi(k=1,kmt-1) using a tridiagonal solver from - Section 2.4 of Press etal 1986. - - Units of psi are m^2/sec - -
-
-
-- - -
-invtri_bvp
--
-- -DESCRIPTION -
-- - Solve the vertical diffusion equation implicitly using the - method of inverting a tridiagonal matrix as described in - Numerical Recipes in Fortran, The art of Scientific Computing, - Second Edition, Press, Teukolsky, Vetterling, Flannery, 1992 - pages 42,43. - - enforce upsilon(k=kmt) = 0 via use of mask(k+1). - -
-
-
-- - -
-do_smooth_transport
--
-- -DESCRIPTION -
-- - -
-
-
-
-NAMELIST
- --&ocean_nphysics_skew_nml --
-
----
-- -gm_transport -
-- To compute tendency from GM skewsion. Default gm_transport=.false. -
-
-[logical] -- -bc_modes_transport -
-- To compute tendency from GM skewsion using streamfunction established - by baroclinic modes. Default bc_modes_transport=.false. -
-
-[logical] -- -bvp_transport -
-- To compute tendency from GM skewsion using streamfunction established - by a boundary value problem. Default bvp_transport=.false. -
-
-[logical] -- -number_bc_modes -
-- The number of baroclinic modes used to construct the eddy induced - streamfunction when bc_modes_transport. Default number_bc_modes=1. -
-
-[integer] -- -min_bc_speed -
-- The minimum speed used for computing the baroclinic modes. - Default min_bc_speed=1e-6 -
-
-[real, units: m/s] -- -regularize_transport -
-- To reduce the magnitude of psi in regions of weak stratification, - using the slope = smax_psi to set the overall scale of the max allowed - for psi. Default regularize_transport=.true. -
-
-[logical] -- -smax_psi -
-- Maximum slope used for setting the overall scale of a modal - contribution to the parameterized transport. - Default smax_psi=0.1. -
-
-[real] -- -bvp_constant_speed -
-- For taking a constant speed to be used for the calculation - of the BVP streamfunction. Default bvp_constant_speed=.false. -
-
-[logical] -- -bvp_speed -
-- For setting the speed weighting the second order derivative operator - in the BVP streamfunction method: - c^2 = max[bvp_min_speed, (bvp_speed-c_mode)^2]. - If bvp_constant_speed, then c^2 = bvp_speed^2. - Default bvp_speed=0.0, in which case c^2 = c_mode^2. -
-
-[real, units: m/s] -- -bvp_bc_mode -
-- The particular baroclinic mode used to construct the BVP streamfunction. - If bvp_bc_mode=0, then will set bc_speed=0 when computing the BVP streamfunction. - Default bvp_bc_mode=1. -
-
-[integer] -- -bvp_min_speed -
-- For setting a minimum speed for use with the calculation - of the BVP streamfunction. We need bvp_min_speed>0 to ensure - that the second order derivative operator contributes to the - calculation of the streamfunction. - Default bvp_min_speed=0.1. -
-
-[real, units: m/s] -- -bv_freq_smooth_vert -
-- To smooth the buoyancy frequency for use in - computing the baroclinic modes. Generally this field has already - been smooted in ocean_density_mod, but we maintain the possibility of - further smoothing here. Default bv_freq_smooth_vert=.false. -
-
-[logical] -- -smooth_transport -
-- For doing a horizontal 1-2-1 smoothing on the psix and psiy fields. - This is useful to reduce noise. Default smooth_psi=.true. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
-- - R. Ferrari, S.M. Griffies, A.J.G. Nurser, and G.K. Vallis - A boundary value problem for the parameterized mesoscale eddy transport - Ocean Modelling, 2009. -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_skew.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_skew.xml deleted file mode 100644 index 734e023aff..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_skew.xml +++ /dev/null @@ -1,126 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.F90 index 8af4e4eeab..a7af4709b3 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.F90 @@ -71,9 +71,9 @@ module ocean_nphysics_tensor_mod #include Tim Leslie - Stephen M. Griffies - - Thickness weighted and density weighted time tendency for tracer - from Laplacian neutral diffusion + Laplacian skew-diffusion. - - This module computes the cell thickness weighted and density - weighted tracer tendency from small angle Laplacian neutral diffusion - plus Laplacian skew-diffusion. The algorithms for neutral diffusion - are based on mom4p0d methods. The algorithm for neutral skewsion - are based on a projection onto a few of the lowest baroclinic - modes. This module is experimental, and should be used with caution. - - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 - - R. Ferrari, S.M. Griffies, A.J.G. Nurser, and G.K. Vallis - A boundary value problem for the parameterized mesoscale eddy transport - Ocean Modelling, 2009. - - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press - - S.M. Griffies: Elements of MOM (2012) - - To compute tendency from GM skewsion. Default gm_transport=.false. - - To compute tendency from GM skewsion using streamfunction established - by baroclinic modes. Default bc_modes_transport=.false. - - To compute tendency from GM skewsion using streamfunction established - by a boundary value problem. Default bvp_transport=.false. - - The number of baroclinic modes used to construct the eddy induced - streamfunction when bc_modes_transport. Default number_bc_modes=1. - - The minimum speed used for computing the baroclinic modes. - Default min_bc_speed=1e-6 - - To reduce the magnitude of psi in regions of weak stratification, - using the slope = smax_psi to set the overall scale of the max allowed - for psi. Default regularize_transport=.true. - - Maximum slope used for setting the overall scale of a modal - contribution to the parameterized transport. - Default smax_psi=0.1. - - For taking a constant speed to be used for the calculation - of the BVP streamfunction. Default bvp_constant_speed=.false. - - For setting the speed weighting the second order derivative operator - in the BVP streamfunction method: - c^2 = max[bvp_min_speed, (bvp_speed-c_mode)^2]. - If bvp_constant_speed, then c^2 = bvp_speed^2. - Default bvp_speed=0.0, in which case c^2 = c_mode^2. - - The particular baroclinic mode used to construct the BVP streamfunction. - If bvp_bc_mode=0, then will set bc_speed=0 when computing the BVP streamfunction. - Default bvp_bc_mode=1. - - For setting a minimum speed for use with the calculation - of the BVP streamfunction. We need bvp_min_speed>0 to ensure - that the second order derivative operator contributes to the - calculation of the streamfunction. - Default bvp_min_speed=0.1. - - To smooth the buoyancy frequency for use in - computing the baroclinic modes. Generally this field has already - been smooted in ocean_density_mod, but we maintain the possibility of - further smoothing here. Default bv_freq_smooth_vert=.false. - - For doing a horizontal 1-2-1 smoothing on the psix and psiy fields. - This is useful to reduce noise. Default smooth_psi=.true. - - Initialization routine. - - Register diagnostic fields. - - Compute the skew tensor terms using the GM method. - - Compute transport as projection onto baroclinic modes. - - Units of upsilon are m^2/sec - - Subroutine computes the baroclinic wave speeds and the dimensionless - baroclinic mode eigenfunction for the vertical velocity baroclinic - modes. These modes vanish at the surface and the bottom. We use - the Chelton etal WKB analytic formulae for the speeds and modes. - - The baroclinic modes are dimensionless, and normalized over the - depth of the ocean, from free surface to bottom. - - The speeds are m/sec. - - - regularize the transport to keep magnitude - under control in regions of weak vertical stratification. - - Compute transport by solving a boundary value problem. - - psi is centered on bottom of tracer cell; for example, - psi(k=1)=psi at bottom of tracer cell k=1. - psi vanishes at the ocean surface: psi(k=0)=0 - and ocean bottom: psi(k=kmt)=0. - - We solve for psi(k=1,kmt-1) using a tridiagonal solver from - Section 2.4 of Press etal 1986. - - Units of psi are m^2/sec - - - Solve the vertical diffusion equation implicitly using the - method of inverting a tridiagonal matrix as described in - Numerical Recipes in Fortran, The art of Scientific Computing, - Second Edition, Press, Teukolsky, Vetterling, Flannery, 1992 - pages 42,43. - - enforce upsilon(k=kmt) = 0 via use of mask(k+1). - - - character(len=128) :: version=& - '$Id: ocean_nphysics_tensor.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_tensor.F90,v 20.0 2013/12/14 00:14:50 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.html b/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.html deleted file mode 100644 index c2f94db44e..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - Module ocean_nphysics_tensor_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_tensor_mod
- - - - - -
-OVERVIEW
- -- -
- - - -- --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_mod
ocean_domains_mod
ocean_nphysics_skew_mod
ocean_sigma_transport_mod
ocean_types_mod
ocean_util_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysics_tensor_init:
- -- -register fields:
- -- -compute_tensors:
- -- -sine_taper:
- -- -diffusion_tensor:
- -- -compute_diffusion_tapers:
- -- -compute_masked_tensor:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysics_tensor_init
--
-- -DESCRIPTION -
-- - Initialise this module. -
-
-
-- - -
-register fields
--
-- -DESCRIPTION -
-- - Register diagnostic fields. -
-
-
-- - -
-compute_tensors
--
-- -DESCRIPTION -
-- - Compute the tensor components for the diffusion and skew-diffusion tensor. -
-
-
-- - -
-sine_taper
--
-- -DESCRIPTION -
-- - Calculate a sine taper for those points shallower than the given threshold. - - The depth_function gives the depth (in metres) at each (i,j,k) point. - The threshold_depth is the depth (in metres) at each (i,j) point. - The returned taper gives a value in the range [0, 1] at each (i,j,k) point, - where those points at a depth below the threshold are set to 1.0 and those - above approach 0.0 as they approach the surface according to a sine - function. - -
-
-
-- - -
-diffusion_tensor
--
-- -DESCRIPTION -
-- - Compute the components of the neutral diffusion tensor. -
-
-
-- - -
-compute_diffusion_tapers
--
-- -DESCRIPTION -
-- - Compute the taper functions to be applied to the components of the diffusion - tensor. -
-
-
-- - -
-compute_masked_tensor
--
-- -DESCRIPTION -
-- - This function applies the boundary conditions relevent to the flags - tmask_neutral_on and tmask_sigma_on. -
-
-
-
-NAMELIST
- --&ocean_nphysics_tensor_nml --
-
----
-- - -
-- -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
-- - R. Ferrari, S.M. Griffies, A.J.G. Nurser, and G.K. Vallis - A boundary value problem for the parameterized mesoscale eddy transport - Ocean Modelling, 2009. -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
-- - S.M. Griffies: Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.xml deleted file mode 100644 index e9a0f8e326..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_tensor.xml +++ /dev/null @@ -1,47 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_util.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_util.F90 index 892999183a..6861b765bc 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_util.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_util.F90 @@ -858,9 +858,9 @@ module ocean_nphysics_util_mod !************************************* character(len=128) :: version=& - '$Id: ocean_nphysics_util.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_util.F90,v 20.0 2013/12/14 00:14:52 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_util.html b/src/mom5/ocean_param/neutral/ocean_nphysics_util.html deleted file mode 100644 index 02dfe5e400..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_util.html +++ /dev/null @@ -1,1400 +0,0 @@ - - - - Tim Leslie - Stephen M. Griffies - - - - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 - - R. Ferrari, S.M. Griffies, A.J.G. Nurser, and G.K. Vallis - A boundary value problem for the parameterized mesoscale eddy transport - Ocean Modelling, 2009. - - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press - - S.M. Griffies: Elements of MOM (2012) - - - Initialise this module. - - Register diagnostic fields. - - Compute the tensor components for the diffusion and skew-diffusion tensor. - - Calculate a sine taper for those points shallower than the given threshold. - - The depth_function gives the depth (in metres) at each (i,j,k) point. - The threshold_depth is the depth (in metres) at each (i,j) point. - The returned taper gives a value in the range [0, 1] at each (i,j,k) point, - where those points at a depth below the threshold are set to 1.0 and those - above approach 0.0 as they approach the surface according to a sine - function. - - - Compute the components of the neutral diffusion tensor. - - Compute the taper functions to be applied to the components of the diffusion - tensor. - - This function applies the boundary conditions relevent to the flags - tmask_neutral_on and tmask_sigma_on. - Module ocean_nphysics_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_util_mod
- - - - - -
-OVERVIEW
- -- Utilities for neutral physics, including the code to compute - space-time dependent diffusivities. -
- - - -- Utilities for neutral physics, including the code to compute - space-time dependent diffusivities and many diagnostics. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_mod
mpp_domains_mod
time_manager_mod
ocean_domains_mod
ocean_density_mod
ocean_operators_mod
ocean_parameters_mod
ocean_tracer_diag_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_nphysics_util_init:
- -- -cabbeling_thermob_init:
- -- -ocean_nphysics_coeff_init:
- -- -tracer_derivs:
- -- -neutral_slopes:
- -- -compute_eady_rate:
- -- -compute_baroclinicity:
- -- -compute_rossby_radius:
- -- -compute_bczone_radius:
- -- -compute_diffusivity:
- -- -transport_on_nrho_gm:
- -- -transport_on_rho_gm:
- -- -transport_on_theta_gm:
- -- -compute_eta_tend_gm90:
- -- -cabbeling_thermob_tendency:
- -- -pressure_derivs:
- -- -calc_gradx_gamma_scalar:
- -- -calc_grady_gamma_scalar:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -- -watermass_diag_ndiffuse:
- -- -watermass_diag_sdiffuse:
- -- -ocean_nphysics_util_restart:
- -- -ocean_nphysics_coeff_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_nphysics_util_init
--
-- -DESCRIPTION -
-- - Initialize the utility module for neutral physics. -
-
-
-- - -
-cabbeling_thermob_init
--
-- -DESCRIPTION -
-- - Initialize the cabbeling and thermobaricity related diagnostic - fields and register the diagnostics to the diag manager. -
-
-
-- - -
-ocean_nphysics_coeff_init
--
-- -DESCRIPTION -
-- - Initialize the diffusivities used in neutral physics. - Need to initialize them after the ocean_nphysics_util_init routine, - since need to have the domain parameters known for passing the - array size information into the ocean_nphysics_coeff_init routine. -
-
-
-- - -
-tracer_derivs
--
-- -DESCRIPTION -
-- - Compute the tracer derivatives. - - Horizontal derivatives are taken along surfaces of - constant vertical coordinate (constant k-level) - - This approach ensures that when neutral physics defaults to "horizontal" physics - next to boundaries, it will do so as horizontal, defined along surfaces of constant - s-surfaces, and so will not generate spurious extrema. - - Additionally, when using generalized vertical coordinates, the neutral diffusion - slope should be computed relative to the s-surfaces. The skew diffusion slope - should ideally be computed with respect to z-surfaces, as z-surfaces define - available potential energy. However, when s and z surfaces are reasonably close, - as they are in the interior for zstar and pstar vertical coordinates, then we - choose to to dissipate thickness as defined relative to the zstar or pstar surfaces. - This should not be such a big deal, and it is certainly easier computationally than - worrying about computing two separate sets of slopes. More on this detail is - discussed in "Elements of MOM". - - NOTE: This approach is not appropriate for sigma-models. Indeed, many assumptions - in the neutral physics modules need to be rethought for terrain following vertical - coordinates. - - Vertical neutral density derivative for use in fz_terms - and fz_flux, and for use in fx_flux and fy_flux. - Note that the derivative at k=nk vanishes by definition - since these derivatives are at the bottom of tracer cell. - also note the use of -epsln_drhodz ensures the vertical - derivative is always < 0. We also support the same - approach used in the mom4p0d code for legacy purposes. - - Comments about smoothing drhodz: - - 1/ Tests in coupled 1-degree model showed extreme sensitivity - of MOC to smoothing. GFDL users generally do NOT smooth, hence - the default drhodz_smooth_vert=drhodz_smooth_horz=.false. - - 2/ Smoothing the vertical derivative of drhodzb and drhodzh helps - is greatly needed for producing a regularized (i.e., well behaved) - neutral slope vector. - - 3/ An attempt was made to smooth dTdz and dSdz rather - than drhodz. The resulting slope was smooth, but not as - smooth as when acting on drhodz itself. - -
-
-
-- - -
-neutral_slopes
--
-- -DESCRIPTION -
-- - Subroutine computes the neutral slopes for the triads associated - with the vertical flux component. - - Array tensor_31 initially holds the x-slope used for flux component fz. - Array tensor_32 initially holds the y-slope used for flux component fz. - - In subsequent calculations, these arrays will be multipied by the - diffusivities. - - No slope tapering is applied in this routine. - - slopes are computed over k=1,nk-1, since the slope at k=nk - should be zero. - -
-
-
-- - -
-compute_eady_rate
--
-- -DESCRIPTION -
-- - Finish computing eady growth rate. -
-
-
-- - -
-compute_baroclinicity
--
-- -DESCRIPTION -
-- - Finish computing baroclinicity, which is defined to be the vertically - averaged magnitude of the horizontal density gradient. -
-
-
-- - -
-compute_rossby_radius
--
-- -DESCRIPTION -
-- - Subroutine computes the first baroclinic Rossby radius of deformation. - Employ WKB approach described by Chelton et al. In particular, - use formulae (2.2), (2.3a) and (2.3b) from their paper. - - Place a max and min value on the Rossby radius. - - Compute buoyancy frequency in terms of vertical gradient of - locally referenced potential density. Place the reference point - at the interface between the tracer cells, which is also where - the vertical derivative of neutral density is located. This amounts - to a centered difference computation similar to that used by - Chelton et al. equation (B.4). -
-
-
-- - -
-compute_bczone_radius
--
-- -DESCRIPTION -
-- - Subroutine computes the radius of the baroclinic zone in a manner - suggested by the Hadley Centre approach (Malcolm Roberts, personal - communication). - - Algorithm is used in MOM3 and documented in the MOM3 Manual. - -
-
-
-- - -
-compute_diffusivity
--
-- -DESCRIPTION -
-- - Subroutine computes flow dependent diffusivity. - Allow for an added dimensionless tuning factor as well as a - minimum and maximum diffusivity. -
-
-
-- - -
-transport_on_nrho_gm
--
-- -DESCRIPTION -
-- - Classify horizontal GM mass transport according to neutral density classes. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_nrho_gm, a remapping is - performed, rather than the binning done for trans_rho. - - Code history - 2008: algorithm based (incorrectly) on transport_on_rho - 2009: algorithm corrected to be consistent with remapping - used in tracer_on_rho algorithm -
-
-
-- - -
-transport_on_rho_gm
--
-- -DESCRIPTION -
-- - Classify horizontal GM mass transport according to potential density classes. - - Algorithm based on linear interpolation of function on s-surfaces to - function on rho-surfaces. - - Diagnostic makes sense when potrho is monotonically increasing with - depth, although the algorithm does not explicitly make this assumption. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_rho_gm, a remapping is - performed, rather than the binning done for trans_rho. - - Code history - - 2008: algorithm based (incorrectly) on transport_on_rho - 2009: algorithm corrected to be consistent with remapping - used in tracer_on_rho algorithm - -
-
-
-- - -
-transport_on_theta_gm
--
-- -DESCRIPTION -
-- - Classify horizontal GM mass transport according to potential temp classes. - - Algorithm based on linear interpolation of function on s-surfaces to - function on rho-surfaces. - - Diagnostic makes sense when potential temp is monotonically increasing - with depth, although the algorithm does not explicitly make this assumption. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_theta_gm, a remapping is - performed, rather than the binning done for trans_rho. - - Code history - - 2009: algorithm based on transport_on_rho_gm - -
-
-
-- - -
-compute_eta_tend_gm90
--
-- -DESCRIPTION -
-- - Diagnose contribution to global mean sea level evolution arising - from analytic form of Gent-McWilliams scheme. - - This routine computes the diagnostic based on an analytic form of the - GM90 contribution. The raw numerical form is computed inside the respective - nphysics modules. The raw numerical form is more accurate and thus - recomended for purposes of sea level budgets. - - Compute an averaged slope using tensor_31 and tensor_32. - Then compute the neutral divergence of this slope vector, just - as if each component of the slope was a scalar. - - To avoid stencil issues with bottom cells, mask to zero - contributions from cells next to the bottom in either of the - three directions. - - Send output to diagnostic manager. - - Subroutine history: - Feb2010 version 1.0: Stephen.Griffies - -
-
-
-- - -
-cabbeling_thermob_tendency
--
-- -DESCRIPTION -
-- - Compute tendencies from cabbeling and thermobaricity. - - To avoid stencil issues with bottom cells, mask to zero - contributions from cells next to the bottom in either of the - three directions. - - Set cabbeling and thermobaricity to zero in regions where - vertical stratification is gravitationally unstable. The idea is - that in such regions, convective mixing will wash away the impact of - along-neutral diffusion, in which case cabbeling and thermobaricity - are not relevant anyhow. - - Set the vertical stratification drho_dz to a negative number - with lower bound on its magnitude as set by epsln_drhodz_diagnostics. - - Send output to diagnostic manager. - - Subroutine history: - Jan2010 version 1.0: initial coding by Stephen.Griffies - Mar2010 version 2.0: tweaks on the division by drho_dz and strat_mask - -
-
-
-- - -
-pressure_derivs
--
-- -DESCRIPTION -
-- - Compute the pressure derivatives for use in thermobaricity diagnostic. -
-
-
-- - -
-calc_gradx_gamma_scalar
--
-- -DESCRIPTION -
-- - Subroutine computes the i-gradient along neutral surfaces - for a scalar field. For use in the cabbeling and thermobaricity - diagnostic. Thus, when slope is steep, the full derivative is - tapered, rather than just the off-diagonal term. - - We only compute neutral i-gradient for interior regions, - since will be setting thermobaricity and cabbeling to zero at - top and bottom levels; do not trust the calculation at top - and bottom boundaries due to stencil truncations. - - Algorithm slightly modified from ocean_nphysC calculation of - neutral diffusion x-flux. - -
-
-
-- - -
-calc_grady_gamma_scalar
--
-- -DESCRIPTION -
-- - Subroutine computes the y-gradient along neutral surfaces - for a scalar field. For use in the cabbeling and thermobaricity - diagnostic. Thus, when slope is steep, the full derivative is - tapered, rather than just the off-diagonal term. - - We only compute neutral y-gradient for interior regions, - since will be setting thermobaricity and cabbeling to zero at - top and bottom levels; do not trust the calculation at top - and bottom boundaries due to stencil truncations. - - Algorithm slightly modified from ocean_nphysC calculation of - neutral diffusion y-flux. - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from nphysics on the watermass transformation. - For use with nphysicsA and nphysicsB. -
-
-
-- - -
-watermass_diag_ndiffuse
--
-- -DESCRIPTION -
-- - - Diagnose watermass transformation from neutral diffusion. - For use with the nphysicsC scheme. - -
-
-
-- - -
-watermass_diag_sdiffuse
--
-- -DESCRIPTION -
-- - - Diagnose watermass transformation from skew diffusion. - For use with the neutral physics C scheme. - -
-
-
-- - -
-ocean_nphysics_util_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_nphysics_coeff_end
--
-- -DESCRIPTION -
-- - Write to restart. -
-
-
-
-NAMELIST
- --&ocean_nphysics_util_nml --
-
----
-- -debug_this_module -
-- For printing starting and ending checksums for restarts -
-
-[logical] -- -nphysics_util_zero_init -
-- For Time%init=.true. and wishing to ensure starting with a clean - suite of nphysics_util fields, even if ocean_neutral.res.nc exists. -
-
-[logical] -- -epsln_drhodz -
-- For computing drhodz used in slope calculation. - We must keep drhodz < 0 in order to maintain integrity of the - quasi-Stokes streamfunction as well as computation of buoyancy frequency. - Default epsln_drhodz=1e-30. -
-
-[real, units: kg/m^3] -- -drhodz_mom4p1 -
-- For computing the vertical deriviative of locally referenced - potrho as in the preferred MOM algorithm rather than the - earlier mom4p0 approach. Default drhodz_mom4p1=.true. -
-
-[logical] -- -drhodz_smooth_horz -
-- For horizontal laplacian smoothing the vertical derivative - of density prior to its use in computing the neutral slopes. - This smoothing helps to produce regularized slopes. - Note that this option breaks the integrity of the triads - and is thus NOT generally recommended. - Default drhodz_smooth_horz=.false. -
-
-[logical] -- -drhodz_smooth_vert -
-- For vertical 1-2-1 smoothing the vertical derivative of - density prior to its use in computing the neutral slopes. - This smoothing helps to produce regularized slopes. - Note that this option breaks the integrity of the triads - and is thus NOT generally recommended. - Default drhodz_smooth_vert=.false. -
-
-[logical] -- -vel_micom_smooth -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in smoothing of drhodzb. - Default vel_micom_smooth=0.2. -
-
-[real, units: m/sec] -- -num_121_passes -
-- For number of 1-2-1 passes through to smooth drhodz or - eady_rate in vertical. Default num_121_passes=1. -
-
-[integer] -- -aredi -
-- Neutral diffusivity used for experiments using a constant diffusivity. -
-
-[real] -- -agm -
-- GM-skew diffusivity used for experiments using a constant diffusivity. -
-
-[real] -- -aredi_equal_agm -
-- Will set aredi_array=agm_array, over-riding any other specification - of aredi_array. Default aredi_equal_agm=.true. -
-
-[logical] -- -smax -
-- Value of the maximum neutral direction slope above which the neutral fluxes are - either tapered to zero or saturated. Typical value is smax=0.01 or smaller. -
-
-[real] -- -swidth -
-- Width in slope over which use tanh with dm_taper scheme to taper fluxes in - steep sloped regions. Typical value swidth=0.1*smax -
-
-[real] -- -smax_grad_gamma_scalar -
-- For calculation of gradients of scalars along a neutral direction, then - when abs(slope) > smax_grad_gamma_scalar, will compute the gradient using - only the vertical scalar gradient, since the slopes are so large they are - effectively infinite. - Default smax_grad_gamma_scalar=.01 -
-
-[real] -- -neutral_horz_mix_bdy -
-- If .true., then use a horizontal diffusivity in the neutral boundary layer. -
-
-[logical] -- -vel_micom_bdy -
-- Velocity scale that is used for computing the MICOM horizontal diffusivity - within the neutral boundary layer. -
-
-[real, units: m/sec] -- -ah_bdy -
-- Constant horizontal diffusivity for the boundary layer. - Default ah_bdy=0.0. -
-
-[real, units: m^2/sec] -- -tracer_mix_micom -
-- If .true., then the GM-skew diffusivity is set according to a velocity scale - times the grid spacing. -
-
-[logical] -- -vel_micom -
-- Velocity scale that is used for computing the MICOM diffusivity. -
-
-[real, units: m/sec] -- -agm_lat_zones -
-- If true, will set agm_array as constant within two latitudinal zones. - The idea is that one may wish to use a larger agm in the ACC than - elsewhere. -
-
-[logical] -- -agm_lat_zones_boundary -
-- Boundary between agm in the south and north zones. -
-
-[real] -- -agm_lat_zones_ratio -
-- Ratio between the large agm used in the southern latitudinal zone - to that used in the north. - agm_array(north) = agm - agm_array(south) = agm*agm_lat_zones_ratio -
-
-[real] -- -bryan_lewis_aredi -
-- Set bryan_lewis_aredi=.true. when want to have aredi a function of depth - according to the Bryan and Lewis (1979) profile. Maintained for legacy - purposes, and not recommended for new models. -
-
-[logical] -- -ahs -
-- ahs = adjustable parameter at the surface for bryan_lewis_aredi -
-
-[real] -- -ahb -
-- ahb = adjustable parameter at the bottom for bryan_lewis_aredi -
-
-[real] -- -agm_read_restart -
-- For those cases with agm_closure=.false. where we wish to read in - the agm_array from restart files and keep the value from the restart. - This approach allows us to read in a spatially dependent agm_array - that may have been computed from another integration, but to leave - the coefficient static in time. - Default agm_read_restart=.false. -
-
-[logical] -- -agm_closure -
-- If .true. then will compute the GM-skew diffusivity as a function of the flow. - The length scale is determined by the Rossby radius and the time scale is - determined by the Eady growth rate. Diffusivities are depth independent. -
-
-[logical] -- -agm_closure_max -
-- Maximum GM diffusivity allowed when using agm_closure=.true. -
-
-[real, units: m^2/sec] -- -agm_closure_min -
-- Minimum GM diffusivity allowed when using agm_closure=.true. -
-
-[real, units: m^2/sec] -- -agm_closure_scaling -
-- Dimensionless tuning parameter for computing flow dependent diffusivities. -
-
-[logical, units: dimensionless] -- -agm_closure_upper_depth -
-- Upper depth where start the depth integration to compute the Eady - growth rate and/or baroclinicity. -
-
-[real, units: m] -- -agm_closure_lower_depth -
-- Deeper depth where finish the depth integration to compute the Eady - growth rate and/or baroclinicity. -
-
-[real, units: m] -- -agm_closure_n2_scale -
-- For computing the agm coefficient using a 3-dimensional - scaling by (N/Nref)^2, with N=buoyancy frequency and - Nref the buoyancy frequency at the base of the neutral - blayer. Default agm_closure_n2_scale=.false. -
-
-[logical] -- -agm_closure_n2_scale_coeff -
-- Coefficient setting the scale for the diffusivity computed from - agm_closure_n2_scale. - Default agm_closure_n2_scale_coeff=1e3. -
-
-[real, units: m^2/s] -- -agm_closure_n2_scale_nref_cst -
-- For taking the reference buoyancy frequency as agm_closure_buoy_freq - for the (N/Nref)^2 scaling. - Default agm_closure_n2_scale_nref_cst=.false. -
-
-[logical] -- -agm_closure_baroclinic -
-- For computing the agm coefficient using only the vertically - averaged magnitude of the horizontal density gradient - (i.e., the "baroclinicity"). -
-
-[logical] -- -agm_closure_buoy_freq -
-- For computing the agm coefficient using only the vertically - averaged horizontal density gradient, we need to specify a - buoyancy frequency, which is taken to be fixed over all space-time. -
-
-[real, units: sec^-1] -- -agm_closure_length_cap -
-- For setting a maximum length scale for the agm_closure calculation. - Default agm_closure_length_cap=.false. -
-
-[logical] -- -agm_closure_length_max -
-- Maximum length scale used for computing agm_closure. - Default agm_closure_length_max=50e3. -
-
-[real, units: metre] -- -agm_closure_length_fixed -
-- Use fixed length scale for computing agm_closure diffusivity -
-
-[logical] -- -agm_closure_length -
-- Fixed length scale for use with agm_closure_fixed_length -
-
-[real, units: meter] -- -agm_closure_length_rossby -
-- For computing the agm_closure length scale according to Rossby radius. -
-
-[logical] -- -rossby_radius_max -
-- Maximum Rossby radius used for agm_closure_length_rossby and - the neutral_sine_taper. Default = 100e3 m. -
-
-[real, units: meter] -- -rossby_radius_min -
-- Minimum Rossby Radius used for agm_closure_length_rossby and - the neutral_sine_taper. Default = 15e3 m. -
-
-[real, units: meter] -- -agm_closure_length_bczone -
-- For computing the agm_closure length scale according to radius of baroclinic zone. -
-
-[logical] -- -bczone_max_pts -
-- Max number of horizontal grid points for use in computing the baroclinic zone radius. -
-
-[integer] -- -agm_closure_bczone_crit_rate -
-- Critical growth rate for determining width of the baroclinic zone. -
-
-[real, units: sec^-1] -- -agm_closure_growth_scale -
-- Dimensionless scaling used to set a maximum for agm_growth. -
-
-[real, units: dimensionless] -- -agm_closure_eden_greatbatch -
-- For computing the agm_closure length scale according to minimum - of the Rhines scale and the Rossby radius, and using 3d Eady - growth rate. -
-
-[logical] -- -agm_closure_eden_gamma -
-- For use in regularizing the growth rate used in the eden/greatbatch approach. - Default agm_closure_eden_gamma=200. Setting to zero removes the regularization. -
-
-[real, units: dimensionless] -- -agm_closure_eden_length_const -
-- To set the length scale for agm_closure_eden_greatbatch to constant. - Default agm_closure_eden_length_const=.false. -
-
-[logical] -- -agm_closure_eden_length -
-- Length scale for use with agm_closure_eden_length_const=.true. - Default agm_closure_eden_length=10e3. -
-
-[real, units: metre] -- -agm_closure_eady_smooth_vert -
-- For vertical 1-2-1 smoothing the eady_rate - Default agm_closure_eady_smooth=.false. -
-
-[logical] -- -agm_closure_eady_smooth_horz -
-- For horizontal Laplacian smoothing of eady growth rate. - Default agm_closure_eady_smooth_horz=.false. -
-
-[logical] -- -agm_closure_eady_cap -
-- For capping the eady growth rate to avoid huge values. - Default agm_closure_eady_cap=.false. -
-
-[logical] -- -agm_closure_eady_ave_mixed -
-- To set the Eady growth rate to its average within mixed layer region. - This is used to avoid spuriously large values which often appear just - in the upper regions of the ocean mixed layer. - Default agm_closure_eady_ave_mixed=.false. -
-
-[logical] -- -agm_smooth_space -
-- For smoothing the agm diffusivity in space when nonconstant diffusivity used. - Default is agm_smooth_space=.false. -
-
-[logical] -- -agm_smooth_time -
-- For smoothing the agm diffusivity in time when nonconstant diffusivity used. - Default is agm_smooth_time=.false. -
-
-[logical] -- -agm_damping_time -
-- The damping time used for time smoothing agm_array. - Default agm_damping_time=10days. -
-
-[real, units: days] -- -agm_closure_grid_scaling -
-- For an overall scaling of the agm coefficient, according to - the relative resolution of the grid and deformation radius. - Default is agm_closure_grid_scaling=.false. -
-
-[logical] -- -agm_closure_grid_scaling_power -
-- Power used to scale the agm_closure diffusivity. - Default is agm_closure_grid_scaling_power=2.0 -
-
-[real] -- -aredi_diffusivity_grid_scaling -
-- For an overall scaling of the aredi coefficient, according to - the relative resolution of the grid and deformation radius. - This option is used only when aredi_equal_agm=.false. - Default is aredi_diffusivity_grid_scaling=.false. -
-
-[logical] -- -epsln_drhodz_diagnostics -
-- For drhodz used in calculation of dianeutral velocity component - from cabbeling and thermobaricity. - Default epsln_drhodz_diagnostics=1e-7. -
-
-[real, units: kg/m4] -- -wdianeutral_smooth -
-- For smoothing the diagnosed dianeutral velocity component using a - horizontal 1-2-1 smoother. Default is wdianeutral_smooth=.true. -
-
-[logical] -- -smooth_eta_tend_gm90 -
-- For smoothing the diagnosed contribution to steric sea level - time tendency associated with the GM90 scheme. - Default is smooth_eta_tend_gm90=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - D.B. Chelton, R.A. deSzoeke, M.G. Schlax, K.E. Naggar, N. Siwertz - Geographical Variability of the First Baroclinic Rossby Radius of Deformation - Journal of Physical Oceanography (1998) vol 28 pages 433-460 -
-- - G. Danabasoglu and J. C. McWilliams - Sensitivity of the global ocean circulation to - parameterizations of mesoscale tracer transports - Journal of Climate (1995) vol 8 pages 2967--2987 -
-- - Held and Larichev - A scaling theory for horizontally homogeneous baroclinically - unstable flow on a beta plane - Journal of Atmospheric Sciences (1996) vol 53 pages 946-952 -
-- - M. Visbeck, J.C. Marshall, T. Haine and M. Spall - Specification of eddy transfer coefficients in coarse resolution ocean - circulation models - Journal of Physical Oceanography (1997) vol 27 pages 381--402 -
-- - D. Ferreira, J. Marshall, and P. Heimbach, - Estimating eddy stresses by fitting dynamics to observations - using a residual-mean ocean circulation omdel and its adjoint. - Journal of Physical Oceanography (2005) vol 35 pages 1891-1910. -
-- - K. Eden, Eddy length scales in the North Atlantic, 2007, - Preprint. -
-- - K. Eden and R. Greatbatch, 2008: Towards a mesoscale eddy closure, - Ocean Modelling, vol. 20, pages 223-239 -
-
- - -
-NOTES
- -- Diffusivities can be determined in a number of manners - - TIME INDEPENDENT - - Various methods are available for specifying a time - independent diffusivity, either globally uniform or - with selections of spatial dependence. - - TIME DEPENDENT (as a function of the flow) - - Various methods are available for determining the - diffusivity that changes in time according to the - properties of the fluid. There are various means - for specifying the length and time scales needed - to set the diffusivity. - - LENGTH SCALES - - 1. First baroclinic Rossby radius (estimated as per Chelton etal). - Equatorial Rossby radius is used within 5deg of the equator. - - 2. Width of the baroclinic zone, as done in the Hadley Centre - model and documented in the MOM3 Manual. - - 3. Specified length scale set independent of the flow. - - TIME SCALE - - When using either of the above for the length scale, - the time scale is determined by the Eady growth rate. - - COMBINED LENGTH/TIME SCALE - - Another option, used in the GFDL CM2.X coupled climate models, - is to set the diffusivity proportional to the depth averaged - absolute value of the horizontal density gradient. --
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_util.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_util.xml deleted file mode 100644 index 00bafcff4d..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_util.xml +++ /dev/null @@ -1,534 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.F90 b/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.F90 index 806a52e23b..403ce48f4f 100644 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.F90 +++ b/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.F90 @@ -82,9 +82,9 @@ module ocean_nphysics_util_new_mod #include Stephen M. Griffies - Tim Leslie - - Utilities for neutral physics, including the code to compute - space-time dependent diffusivities. - - Utilities for neutral physics, including the code to compute - space-time dependent diffusivities and many diagnostics. - - D.B. Chelton, R.A. deSzoeke, M.G. Schlax, K.E. Naggar, N. Siwertz - Geographical Variability of the First Baroclinic Rossby Radius of Deformation - Journal of Physical Oceanography (1998) vol 28 pages 433-460 - - G. Danabasoglu and J. C. McWilliams - Sensitivity of the global ocean circulation to - parameterizations of mesoscale tracer transports - Journal of Climate (1995) vol 8 pages 2967--2987 - - Held and Larichev - A scaling theory for horizontally homogeneous baroclinically - unstable flow on a beta plane - Journal of Atmospheric Sciences (1996) vol 53 pages 946-952 - - M. Visbeck, J.C. Marshall, T. Haine and M. Spall - Specification of eddy transfer coefficients in coarse resolution ocean - circulation models - Journal of Physical Oceanography (1997) vol 27 pages 381--402 - - D. Ferreira, J. Marshall, and P. Heimbach, - Estimating eddy stresses by fitting dynamics to observations - using a residual-mean ocean circulation omdel and its adjoint. - Journal of Physical Oceanography (2005) vol 35 pages 1891-1910. - - K. Eden, Eddy length scales in the North Atlantic, 2007, - Preprint. - - K. Eden and R. Greatbatch, 2008: Towards a mesoscale eddy closure, - Ocean Modelling, vol. 20, pages 223-239 - - Diffusivities can be determined in a number of manners - - TIME INDEPENDENT - - Various methods are available for specifying a time - independent diffusivity, either globally uniform or - with selections of spatial dependence. - - TIME DEPENDENT (as a function of the flow) - - Various methods are available for determining the - diffusivity that changes in time according to the - properties of the fluid. There are various means - for specifying the length and time scales needed - to set the diffusivity. - - LENGTH SCALES - - 1. First baroclinic Rossby radius (estimated as per Chelton etal). - Equatorial Rossby radius is used within 5deg of the equator. - - 2. Width of the baroclinic zone, as done in the Hadley Centre - model and documented in the MOM3 Manual. - - 3. Specified length scale set independent of the flow. - - TIME SCALE - - When using either of the above for the length scale, - the time scale is determined by the Eady growth rate. - - COMBINED LENGTH/TIME SCALE - - Another option, used in the GFDL CM2.X coupled climate models, - is to set the diffusivity proportional to the depth averaged - absolute value of the horizontal density gradient. - - For printing starting and ending checksums for restarts - - For Time%init=.true. and wishing to ensure starting with a clean - suite of nphysics_util fields, even if ocean_neutral.res.nc exists. - - For computing drhodz used in slope calculation. - We must keep drhodz < 0 in order to maintain integrity of the - quasi-Stokes streamfunction as well as computation of buoyancy frequency. - Default epsln_drhodz=1e-30. - - For computing the vertical deriviative of locally referenced - potrho as in the preferred MOM algorithm rather than the - earlier mom4p0 approach. Default drhodz_mom4p1=.true. - - For horizontal laplacian smoothing the vertical derivative - of density prior to its use in computing the neutral slopes. - This smoothing helps to produce regularized slopes. - Note that this option breaks the integrity of the triads - and is thus NOT generally recommended. - Default drhodz_smooth_horz=.false. - - For vertical 1-2-1 smoothing the vertical derivative of - density prior to its use in computing the neutral slopes. - This smoothing helps to produce regularized slopes. - Note that this option breaks the integrity of the triads - and is thus NOT generally recommended. - Default drhodz_smooth_vert=.false. - - Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in smoothing of drhodzb. - Default vel_micom_smooth=0.2. - - For number of 1-2-1 passes through to smooth drhodz or - eady_rate in vertical. Default num_121_passes=1. - - Neutral diffusivity used for experiments using a constant diffusivity. - - GM-skew diffusivity used for experiments using a constant diffusivity. - - Will set aredi_array=agm_array, over-riding any other specification - of aredi_array. Default aredi_equal_agm=.true. - - Value of the maximum neutral direction slope above which the neutral fluxes are - either tapered to zero or saturated. Typical value is smax=0.01 or smaller. - - Width in slope over which use tanh with dm_taper scheme to taper fluxes in - steep sloped regions. Typical value swidth=0.1*smax - - For calculation of gradients of scalars along a neutral direction, then - when abs(slope) > smax_grad_gamma_scalar, will compute the gradient using - only the vertical scalar gradient, since the slopes are so large they are - effectively infinite. - Default smax_grad_gamma_scalar=.01 - - If .true., then use a horizontal diffusivity in the neutral boundary layer. - - Velocity scale that is used for computing the MICOM horizontal diffusivity - within the neutral boundary layer. - - Constant horizontal diffusivity for the boundary layer. - Default ah_bdy=0.0. - - If .true., then the GM-skew diffusivity is set according to a velocity scale - times the grid spacing. - - Velocity scale that is used for computing the MICOM diffusivity. - - If true, will set agm_array as constant within two latitudinal zones. - The idea is that one may wish to use a larger agm in the ACC than - elsewhere. - - Boundary between agm in the south and north zones. - - Ratio between the large agm used in the southern latitudinal zone - to that used in the north. - agm_array(north) = agm - agm_array(south) = agm*agm_lat_zones_ratio - - Set bryan_lewis_aredi=.true. when want to have aredi a function of depth - according to the Bryan and Lewis (1979) profile. Maintained for legacy - purposes, and not recommended for new models. - - ahs = adjustable parameter at the surface for bryan_lewis_aredi - - ahb = adjustable parameter at the bottom for bryan_lewis_aredi - - For those cases with agm_closure=.false. where we wish to read in - the agm_array from restart files and keep the value from the restart. - This approach allows us to read in a spatially dependent agm_array - that may have been computed from another integration, but to leave - the coefficient static in time. - Default agm_read_restart=.false. - - If .true. then will compute the GM-skew diffusivity as a function of the flow. - The length scale is determined by the Rossby radius and the time scale is - determined by the Eady growth rate. Diffusivities are depth independent. - - Maximum GM diffusivity allowed when using agm_closure=.true. - - Minimum GM diffusivity allowed when using agm_closure=.true. - - Dimensionless tuning parameter for computing flow dependent diffusivities. - - Upper depth where start the depth integration to compute the Eady - growth rate and/or baroclinicity. - - Deeper depth where finish the depth integration to compute the Eady - growth rate and/or baroclinicity. - - For computing the agm coefficient using a 3-dimensional - scaling by (N/Nref)^2, with N=buoyancy frequency and - Nref the buoyancy frequency at the base of the neutral - blayer. Default agm_closure_n2_scale=.false. - - Coefficient setting the scale for the diffusivity computed from - agm_closure_n2_scale. - Default agm_closure_n2_scale_coeff=1e3. - - For taking the reference buoyancy frequency as agm_closure_buoy_freq - for the (N/Nref)^2 scaling. - Default agm_closure_n2_scale_nref_cst=.false. - - For computing the agm coefficient using only the vertically - averaged magnitude of the horizontal density gradient - (i.e., the "baroclinicity"). - - For computing the agm coefficient using only the vertically - averaged horizontal density gradient, we need to specify a - buoyancy frequency, which is taken to be fixed over all space-time. - - For setting a maximum length scale for the agm_closure calculation. - Default agm_closure_length_cap=.false. - - Maximum length scale used for computing agm_closure. - Default agm_closure_length_max=50e3. - - Use fixed length scale for computing agm_closure diffusivity - - Fixed length scale for use with agm_closure_fixed_length - - For computing the agm_closure length scale according to Rossby radius. - - Maximum Rossby radius used for agm_closure_length_rossby and - the neutral_sine_taper. Default = 100e3 m. - - Minimum Rossby Radius used for agm_closure_length_rossby and - the neutral_sine_taper. Default = 15e3 m. - - For computing the agm_closure length scale according to radius of baroclinic zone. - - Max number of horizontal grid points for use in computing the baroclinic zone radius. - - Critical growth rate for determining width of the baroclinic zone. - - Dimensionless scaling used to set a maximum for agm_growth. - - For computing the agm_closure length scale according to minimum - of the Rhines scale and the Rossby radius, and using 3d Eady - growth rate. - - For use in regularizing the growth rate used in the eden/greatbatch approach. - Default agm_closure_eden_gamma=200. Setting to zero removes the regularization. - - To set the length scale for agm_closure_eden_greatbatch to constant. - Default agm_closure_eden_length_const=.false. - - Length scale for use with agm_closure_eden_length_const=.true. - Default agm_closure_eden_length=10e3. - - For vertical 1-2-1 smoothing the eady_rate - Default agm_closure_eady_smooth=.false. - - For horizontal Laplacian smoothing of eady growth rate. - Default agm_closure_eady_smooth_horz=.false. - - For capping the eady growth rate to avoid huge values. - Default agm_closure_eady_cap=.false. - - To set the Eady growth rate to its average within mixed layer region. - This is used to avoid spuriously large values which often appear just - in the upper regions of the ocean mixed layer. - Default agm_closure_eady_ave_mixed=.false. - - For smoothing the agm diffusivity in space when nonconstant diffusivity used. - Default is agm_smooth_space=.false. - - For smoothing the agm diffusivity in time when nonconstant diffusivity used. - Default is agm_smooth_time=.false. - - The damping time used for time smoothing agm_array. - Default agm_damping_time=10days. - - For an overall scaling of the agm coefficient, according to - the relative resolution of the grid and deformation radius. - Default is agm_closure_grid_scaling=.false. - - Power used to scale the agm_closure diffusivity. - Default is agm_closure_grid_scaling_power=2.0 - - For an overall scaling of the aredi coefficient, according to - the relative resolution of the grid and deformation radius. - This option is used only when aredi_equal_agm=.false. - Default is aredi_diffusivity_grid_scaling=.false. - - For drhodz used in calculation of dianeutral velocity component - from cabbeling and thermobaricity. - Default epsln_drhodz_diagnostics=1e-7. - - For smoothing the diagnosed dianeutral velocity component using a - horizontal 1-2-1 smoother. Default is wdianeutral_smooth=.true. - - For smoothing the diagnosed contribution to steric sea level - time tendency associated with the GM90 scheme. - Default is smooth_eta_tend_gm90=.false. - - Initialize the utility module for neutral physics. - - Initialize the cabbeling and thermobaricity related diagnostic - fields and register the diagnostics to the diag manager. - - Initialize the diffusivities used in neutral physics. - Need to initialize them after the ocean_nphysics_util_init routine, - since need to have the domain parameters known for passing the - array size information into the ocean_nphysics_coeff_init routine. - - Compute the tracer derivatives. - - Horizontal derivatives are taken along surfaces of - constant vertical coordinate (constant k-level) - - This approach ensures that when neutral physics defaults to "horizontal" physics - next to boundaries, it will do so as horizontal, defined along surfaces of constant - s-surfaces, and so will not generate spurious extrema. - - Additionally, when using generalized vertical coordinates, the neutral diffusion - slope should be computed relative to the s-surfaces. The skew diffusion slope - should ideally be computed with respect to z-surfaces, as z-surfaces define - available potential energy. However, when s and z surfaces are reasonably close, - as they are in the interior for zstar and pstar vertical coordinates, then we - choose to to dissipate thickness as defined relative to the zstar or pstar surfaces. - This should not be such a big deal, and it is certainly easier computationally than - worrying about computing two separate sets of slopes. More on this detail is - discussed in "Elements of MOM". - - NOTE: This approach is not appropriate for sigma-models. Indeed, many assumptions - in the neutral physics modules need to be rethought for terrain following vertical - coordinates. - - Vertical neutral density derivative for use in fz_terms - and fz_flux, and for use in fx_flux and fy_flux. - Note that the derivative at k=nk vanishes by definition - since these derivatives are at the bottom of tracer cell. - also note the use of -epsln_drhodz ensures the vertical - derivative is always < 0. We also support the same - approach used in the mom4p0d code for legacy purposes. - - Comments about smoothing drhodz: - - 1/ Tests in coupled 1-degree model showed extreme sensitivity - of MOC to smoothing. GFDL users generally do NOT smooth, hence - the default drhodz_smooth_vert=drhodz_smooth_horz=.false. - - 2/ Smoothing the vertical derivative of drhodzb and drhodzh helps - is greatly needed for producing a regularized (i.e., well behaved) - neutral slope vector. - - 3/ An attempt was made to smooth dTdz and dSdz rather - than drhodz. The resulting slope was smooth, but not as - smooth as when acting on drhodz itself. - - - Subroutine computes the neutral slopes for the triads associated - with the vertical flux component. - - Array tensor_31 initially holds the x-slope used for flux component fz. - Array tensor_32 initially holds the y-slope used for flux component fz. - - In subsequent calculations, these arrays will be multipied by the - diffusivities. - - No slope tapering is applied in this routine. - - slopes are computed over k=1,nk-1, since the slope at k=nk - should be zero. - - - Finish computing eady growth rate. - - Finish computing baroclinicity, which is defined to be the vertically - averaged magnitude of the horizontal density gradient. - - Subroutine computes the first baroclinic Rossby radius of deformation. - Employ WKB approach described by Chelton et al. In particular, - use formulae (2.2), (2.3a) and (2.3b) from their paper. - - Place a max and min value on the Rossby radius. - - Compute buoyancy frequency in terms of vertical gradient of - locally referenced potential density. Place the reference point - at the interface between the tracer cells, which is also where - the vertical derivative of neutral density is located. This amounts - to a centered difference computation similar to that used by - Chelton et al. equation (B.4). - - Subroutine computes the radius of the baroclinic zone in a manner - suggested by the Hadley Centre approach (Malcolm Roberts, personal - communication). - - Algorithm is used in MOM3 and documented in the MOM3 Manual. - - - Subroutine computes flow dependent diffusivity. - Allow for an added dimensionless tuning factor as well as a - minimum and maximum diffusivity. - - Classify horizontal GM mass transport according to neutral density classes. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_nrho_gm, a remapping is - performed, rather than the binning done for trans_rho. - - Code history - 2008: algorithm based (incorrectly) on transport_on_rho - 2009: algorithm corrected to be consistent with remapping - used in tracer_on_rho algorithm - - Classify horizontal GM mass transport according to potential density classes. - - Algorithm based on linear interpolation of function on s-surfaces to - function on rho-surfaces. - - Diagnostic makes sense when potrho is monotonically increasing with - depth, although the algorithm does not explicitly make this assumption. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_rho_gm, a remapping is - performed, rather than the binning done for trans_rho. - - Code history - - 2008: algorithm based (incorrectly) on transport_on_rho - 2009: algorithm corrected to be consistent with remapping - used in tracer_on_rho algorithm - - - Classify horizontal GM mass transport according to potential temp classes. - - Algorithm based on linear interpolation of function on s-surfaces to - function on rho-surfaces. - - Diagnostic makes sense when potential temp is monotonically increasing - with depth, although the algorithm does not explicitly make this assumption. - - NOTE: This diagnostic works with transport integrated from bottom to - a particular cell depth. To get transport_on_theta_gm, a remapping is - performed, rather than the binning done for trans_rho. - - Code history - - 2009: algorithm based on transport_on_rho_gm - - - Diagnose contribution to global mean sea level evolution arising - from analytic form of Gent-McWilliams scheme. - - This routine computes the diagnostic based on an analytic form of the - GM90 contribution. The raw numerical form is computed inside the respective - nphysics modules. The raw numerical form is more accurate and thus - recomended for purposes of sea level budgets. - - Compute an averaged slope using tensor_31 and tensor_32. - Then compute the neutral divergence of this slope vector, just - as if each component of the slope was a scalar. - - To avoid stencil issues with bottom cells, mask to zero - contributions from cells next to the bottom in either of the - three directions. - - Send output to diagnostic manager. - - Subroutine history: - Feb2010 version 1.0: Stephen.Griffies - - - Compute tendencies from cabbeling and thermobaricity. - - To avoid stencil issues with bottom cells, mask to zero - contributions from cells next to the bottom in either of the - three directions. - - Set cabbeling and thermobaricity to zero in regions where - vertical stratification is gravitationally unstable. The idea is - that in such regions, convective mixing will wash away the impact of - along-neutral diffusion, in which case cabbeling and thermobaricity - are not relevant anyhow. - - Set the vertical stratification drho_dz to a negative number - with lower bound on its magnitude as set by epsln_drhodz_diagnostics. - - Send output to diagnostic manager. - - Subroutine history: - Jan2010 version 1.0: initial coding by Stephen.Griffies - Mar2010 version 2.0: tweaks on the division by drho_dz and strat_mask - - - Compute the pressure derivatives for use in thermobaricity diagnostic. - - Subroutine computes the i-gradient along neutral surfaces - for a scalar field. For use in the cabbeling and thermobaricity - diagnostic. Thus, when slope is steep, the full derivative is - tapered, rather than just the off-diagonal term. - - We only compute neutral i-gradient for interior regions, - since will be setting thermobaricity and cabbeling to zero at - top and bottom levels; do not trust the calculation at top - and bottom boundaries due to stencil truncations. - - Algorithm slightly modified from ocean_nphysC calculation of - neutral diffusion x-flux. - - - Subroutine computes the y-gradient along neutral surfaces - for a scalar field. For use in the cabbeling and thermobaricity - diagnostic. Thus, when slope is steep, the full derivative is - tapered, rather than just the off-diagonal term. - - We only compute neutral y-gradient for interior regions, - since will be setting thermobaricity and cabbeling to zero at - top and bottom levels; do not trust the calculation at top - and bottom boundaries due to stencil truncations. - - Algorithm slightly modified from ocean_nphysC calculation of - neutral diffusion y-flux. - - - Initialization of watermass diagnostic output files. - - Diagnose effects from nphysics on the watermass transformation. - For use with nphysicsA and nphysicsB. - - - Diagnose watermass transformation from neutral diffusion. - For use with the nphysicsC scheme. - - - - Diagnose watermass transformation from skew diffusion. - For use with the neutral physics C scheme. - - - Write out restart files registered through register_restart_file - - Write to restart. - character(len=128) :: version=& - '$Id: ocean_nphysics_util_new.F90,v 1.1.2.2 2012/05/17 13:41:47 smg Exp $' + '$Id: ocean_nphysics_util_new.F90,v 20.0 2013/12/14 00:14:54 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' character(len=*), parameter :: FILENAME=& __FILE__ diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.html b/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.html deleted file mode 100644 index cf2c58d217..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - Module ocean_nphysics_util_new_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_nphysics_util_new_mod
- - - - - -
-OVERVIEW
- -- Utilities for neutral physics modules. -
- - - -- Utilities for neutral physics modules. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -stencil_centre_to_vert:
- -- -stencil_centre_to_vert:
- -- -stencil_centre_to_horiz:
- -- -vert_smooth:
- -- -horz_smooth:
- -- -compute_rossby_radius:
- -- -check_init:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-stencil_centre_to_vert
--
-- -DESCRIPTION -
-- - Initialise the grid indices and constants. -
-
-
-- - -
-stencil_centre_to_vert
--
-- -DESCRIPTION -
-- - Take an array defined over the 4 quadrants centred on a tracer cell - and shift them vertically to the four quadrants spanning the bottom - cell face. The top and bottom half cells are set to zero. - _____________ _____________ - | : | | : | - | 0,0 : 1,0 | | : | - | : ! | : | - |-----T-----| ==> |-----T-----| - | : ! | : | - | 0,1 : 1,1 ! | 0,0 : 1,0 | - |_____:_____| |_____:_____| - | : | - | 0,1 : 1,1 | - | : | - |-----o-----| - | : | - | : | - |_____:_____| -
-
-
-- - -
-stencil_centre_to_horiz
--
-- -DESCRIPTION -
-- - Take an array defined over the 4 quadrants centred on a tracer cell - and shift them horizontally to the four quadrants spanning the right hand - cell face. - _____________ _________________________ - | : | | : | : | - | 0,0 : 1,0 | | : 0,0 | 1,0 : | - | : ! | : | : | - |-----T-----| ==> |-----T-----|-----o-----| - | : ! | : | : | - | 0,1 : 1,1 ! | : 0,1 | 1,1 : | - |_____:_____| |_____:_____|_____:_____| -
-
-
-- - -
-vert_smooth
--
-- -DESCRIPTION -
-- - Apply a vertical smoothing using a weighted 3 point stencil. - - 1 - Stencil weights : 2 - 1 - - Smoothing is applied to all points in the column which admit - the full stencil (so vertical boundaries are not modified). - - The smoothing is applied multiple times, controlled by the namelist - parameter num_121_passes. -
-
-
-- - -
-horz_smooth
--
-- -DESCRIPTION -
-- - Apply a horizontal smoothing using a weighted five point stencil. - - 1 - Stencil weights : 1 4 1 - 1 - - Only active cells, as defined by the tmask, are used in the calculation. - Operates over the COMP domain. -
-
-
-- - -
-compute_rossby_radius
--
-- -DESCRIPTION -
-- - Subroutine computes the first baroclinic Rossby radius of deformation. - Employ WKB approach described by Chelton et al. In particular, - use formulae (2.2), (2.3a) and (2.3b) from their paper. -
-
-
-- - -
-check_init
--
-- -DESCRIPTION -
-- - Helper function to ensure the module is initialised when calling the - module's functions. -
-
-
-
-NAMELIST
- --&ocean_nphysics_util_new_nml --
-
----
-- -num_121_passes -
-- For number of 1-2-1 passes through to smooth drhodz or - eady_rate in vertical. Default num_121_passes=1. -
-
-[integer] -
- - - - -
-REFERENCES
- ----
-- - D.B. Chelton, R.A. deSzoeke, M.G. Schlax, K.E. Naggar, N. Siwertz - Geographical Variability of the First Baroclinic Rossby Radius of Deformation - Journal of Physical Oceanography (1998) vol 28 pages 433-460 -
-- - K. Eden and R. Greatbatch, 2008: Towards a mesoscale eddy closure, - Ocean Modelling, vol. 20, pages 223-239 -
-- - S.M. Griffies "Elements of MOM (2012) (EoM)" -
-- - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
-
- - -
-NOTES
- -- --
- -
--top -- - diff --git a/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.xml b/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.xml deleted file mode 100644 index a57be93c55..0000000000 --- a/src/mom5/ocean_param/neutral/ocean_nphysics_util_new.xml +++ /dev/null @@ -1,88 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_increment_eta.F90 b/src/mom5/ocean_param/sources/ocean_increment_eta.F90 index 89942dc921..5243ef3148 100644 --- a/src/mom5/ocean_param/sources/ocean_increment_eta.F90 +++ b/src/mom5/ocean_param/sources/ocean_increment_eta.F90 @@ -94,8 +94,8 @@ module ocean_increment_eta_mod public ocean_increment_eta_init public ocean_increment_eta_source -character(len=126) :: version = '$Id: ocean_increment_eta.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=126) :: version = '$Id: ocean_increment_eta.F90,v 20.0 2013/12/14 00:15:56 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! for diagnostics logical :: used diff --git a/src/mom5/ocean_param/sources/ocean_increment_eta.html b/src/mom5/ocean_param/sources/ocean_increment_eta.html deleted file mode 100644 index 0848088022..0000000000 --- a/src/mom5/ocean_param/sources/ocean_increment_eta.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - Tim Leslie - Stephen M. Griffies - - Utilities for neutral physics modules. - - Utilities for neutral physics modules. - - D.B. Chelton, R.A. deSzoeke, M.G. Schlax, K.E. Naggar, N. Siwertz - Geographical Variability of the First Baroclinic Rossby Radius of Deformation - Journal of Physical Oceanography (1998) vol 28 pages 433-460 - - K. Eden and R. Greatbatch, 2008: Towards a mesoscale eddy closure, - Ocean Modelling, vol. 20, pages 223-239 - - S.M. Griffies "Elements of MOM (2012) (EoM)" - - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press - - - For number of 1-2-1 passes through to smooth drhodz or - eady_rate in vertical. Default num_121_passes=1. - - Initialise the grid indices and constants. - - Take an array defined over the 4 quadrants centred on a tracer cell - and shift them vertically to the four quadrants spanning the bottom - cell face. The top and bottom half cells are set to zero. - _____________ _____________ - | : | | : | - | 0,0 : 1,0 | | : | - | : ! | : | - |-----T-----| ==> |-----T-----| - | : ! | : | - | 0,1 : 1,1 ! | 0,0 : 1,0 | - |_____:_____| |_____:_____| - | : | - | 0,1 : 1,1 | - | : | - |-----o-----| - | : | - | : | - |_____:_____| - - Take an array defined over the 4 quadrants centred on a tracer cell - and shift them horizontally to the four quadrants spanning the right hand - cell face. - _____________ _________________________ - | : | | : | : | - | 0,0 : 1,0 | | : 0,0 | 1,0 : | - | : ! | : | : | - |-----T-----| ==> |-----T-----|-----o-----| - | : ! | : | : | - | 0,1 : 1,1 ! | : 0,1 | 1,1 : | - |_____:_____| |_____:_____|_____:_____| - - Apply a vertical smoothing using a weighted 3 point stencil. - - 1 - Stencil weights : 2 - 1 - - Smoothing is applied to all points in the column which admit - the full stencil (so vertical boundaries are not modified). - - The smoothing is applied multiple times, controlled by the namelist - parameter num_121_passes. - - Apply a horizontal smoothing using a weighted five point stencil. - - 1 - Stencil weights : 1 4 1 - 1 - - Only active cells, as defined by the tmask, are used in the calculation. - Operates over the COMP domain. - - Subroutine computes the first baroclinic Rossby radius of deformation. - Employ WKB approach described by Chelton et al. In particular, - use formulae (2.2), (2.3a) and (2.3b) from their paper. - - Helper function to ensure the module is initialised when calling the - module's functions. - Module ocean_increment_eta_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_increment_eta_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted eta tendency [meter^2/sec^2] from increments. -
- - - -- - This increment module performs incremental update analysis (IUA), - an approach used in data assimilation and forecasting to reduce - spurious perturbations when correcting the model state. - IUA involves restoring to analysis increments i.e. differences between model - and analysis fields rather than actual fields (See Bloom et al., 1996). - The user can define the period that IUA is carried out - and also the fraction of the increment to be restored over that period. - - This module applies a general 2D source to eta. The sources - can occur at any location and with any distribution in the domain - An array of eta tendencies due to the increments is augmented through a - call to increment_eta_source. The array of eta tendencies must be - reset to zero between calls. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the etas are being driven. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_increment_eta_init:
- -- -ocean_increment_eta_source:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_increment_eta_init
--
-- -DESCRIPTION -
-- - This subroutine is intended to be used to initialize the increments. - Everything in this subroutine is a user prototype, and should be replacable. -
-
-
-- - -
-ocean_increment_eta_source
--
-- -DESCRIPTION -
-- - This subroutine calculates thickness weighted and density weighted - time tendencies of etas due to damping by increments. -
-
-
-
-NAMELIST
- --&ocean_increment_eta_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -fraction_increment -
-- For prescribing the fraction of the increment. - applied to the restoring period. Default fraction_increment=1.0 -
-
-[real] -- -days_to_increment -
-- For specifying the amount of days to restore. - Default days_to_increment=1 -
-
-[integer] -- -secs_to_increment -
-- For specifying the amount of seconds to restore. - Default secs_to_increment=0 -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_increment_eta.xml b/src/mom5/ocean_param/sources/ocean_increment_eta.xml deleted file mode 100644 index 81994a9c3f..0000000000 --- a/src/mom5/ocean_param/sources/ocean_increment_eta.xml +++ /dev/null @@ -1,48 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_increment_tracer.F90 b/src/mom5/ocean_param/sources/ocean_increment_tracer.F90 index c8d08d8513..5b0bb7644b 100644 --- a/src/mom5/ocean_param/sources/ocean_increment_tracer.F90 +++ b/src/mom5/ocean_param/sources/ocean_increment_tracer.F90 @@ -92,8 +92,8 @@ module ocean_increment_tracer_mod public ocean_increment_tracer_init public ocean_increment_tracer_source -character(len=126) :: version = '$Id: ocean_increment_tracer.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=126) :: version = '$Id: ocean_increment_tracer.F90,v 20.0 2013/12/14 00:15:58 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! for diagnostics logical :: used diff --git a/src/mom5/ocean_param/sources/ocean_increment_tracer.html b/src/mom5/ocean_param/sources/ocean_increment_tracer.html deleted file mode 100644 index 4dcd4bfeb6..0000000000 --- a/src/mom5/ocean_param/sources/ocean_increment_tracer.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - Russell Fiedler - Paul Sandery - - Thickness weighted eta tendency [meter^2/sec^2] from increments. - - - This increment module performs incremental update analysis (IUA), - an approach used in data assimilation and forecasting to reduce - spurious perturbations when correcting the model state. - IUA involves restoring to analysis increments i.e. differences between model - and analysis fields rather than actual fields (See Bloom et al., 1996). - The user can define the period that IUA is carried out - and also the fraction of the increment to be restored over that period. - - This module applies a general 2D source to eta. The sources - can occur at any location and with any distribution in the domain - An array of eta tendencies due to the increments is augmented through a - call to increment_eta_source. The array of eta tendencies must be - reset to zero between calls. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the etas are being driven. - - S.C. Bloom, L.L. Takacs, A.M. da Silva, and D. Ledvina - Data Assimilation Using Incremental Analysis Updates - Monthly Weather Review Volume 124, Issue 6 (June 1996) - pages 1256--1271 - - For using this module. Default use_this_module=.false. - - For prescribing the fraction of the increment. - applied to the restoring period. Default fraction_increment=1.0 - - For specifying the amount of days to restore. - Default days_to_increment=1 - - For specifying the amount of seconds to restore. - Default secs_to_increment=0 - - This subroutine is intended to be used to initialize the increments. - Everything in this subroutine is a user prototype, and should be replacable. - - This subroutine calculates thickness weighted and density weighted - time tendencies of etas due to damping by increments. - Module ocean_increment_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_increment_tracer_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted tracer tendency [tracer*meter/sec] from increments. -
- - - -- - This increment module performs incremental update analysis (IUA), - an approach used in data assimilation and forecasting to reduce - spurious perturbations when correcting the model state. - IUA involves restoring to analysis increments i.e. differences between model - and analysis fields rather than actual fields (See Bloom et al., 1996). - The user can define the period that IUA is carried out - and also the fraction of the increment to be restored over that period. - - This module applies a general 3D source to tracer. The sources - can occur at any location and with any distribution in the domain - An array of tracer tendencies due to the increments is augmented through a - call to increment_tracer_source. The array of tracer tendencies must be - reset to zero between calls. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the etas are being driven. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_increment_tracer_init:
- -- -ocean_increment_tracer_source:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_increment_tracer_init
--
-- -DESCRIPTION -
-- - This subroutine is intended to be used to initialize the increments. - Everything in this subroutine is a user prototype, and should be replacable. -
-
-
-- - -
-ocean_increment_tracer_source
--
-- -DESCRIPTION -
-- - This subroutine calculates thickness weighted and density weighted - time tendencies of tracers due to damping by increments. -
-
-
-
-NAMELIST
- --&ocean_increment_tracer_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -fraction_increment -
-- For prescribing the fraction of the increment. - applied to the restoring period. Default fraction_increment=1.0 -
-
-[real] -- -days_to_increment -
-- For specifying the amount of days to restore. - Default days_to_increment=1 -
-
-[integer] -- -secs_to_increment -
-- For specifying the amount of seconds to restore. - Default secs_to_increment=0 -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_increment_tracer.xml b/src/mom5/ocean_param/sources/ocean_increment_tracer.xml deleted file mode 100644 index 5ce1c058c3..0000000000 --- a/src/mom5/ocean_param/sources/ocean_increment_tracer.xml +++ /dev/null @@ -1,48 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_increment_velocity.F90 b/src/mom5/ocean_param/sources/ocean_increment_velocity.F90 index 498bb5a581..76303d7374 100644 --- a/src/mom5/ocean_param/sources/ocean_increment_velocity.F90 +++ b/src/mom5/ocean_param/sources/ocean_increment_velocity.F90 @@ -93,8 +93,8 @@ module ocean_increment_velocity_mod public ocean_increment_velocity_init public ocean_increment_velocity_source -character(len=126) :: version = '$Id: ocean_increment_velocity.F90,v 1.1.2.2.12.1 2012/07/27 04:47:06 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=126) :: version = '$Id: ocean_increment_velocity.F90,v 20.0 2013/12/14 00:16:00 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! for diagnostics logical :: used diff --git a/src/mom5/ocean_param/sources/ocean_increment_velocity.html b/src/mom5/ocean_param/sources/ocean_increment_velocity.html deleted file mode 100644 index 6fba3bc8f0..0000000000 --- a/src/mom5/ocean_param/sources/ocean_increment_velocity.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - Russell Fiedler - Paul Sandery - - Thickness weighted tracer tendency [tracer*meter/sec] from increments. - - - This increment module performs incremental update analysis (IUA), - an approach used in data assimilation and forecasting to reduce - spurious perturbations when correcting the model state. - IUA involves restoring to analysis increments i.e. differences between model - and analysis fields rather than actual fields (See Bloom et al., 1996). - The user can define the period that IUA is carried out - and also the fraction of the increment to be restored over that period. - - This module applies a general 3D source to tracer. The sources - can occur at any location and with any distribution in the domain - An array of tracer tendencies due to the increments is augmented through a - call to increment_tracer_source. The array of tracer tendencies must be - reset to zero between calls. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the etas are being driven. - - S.C. Bloom, L.L. Takacs, A.M. da Silva, and D. Ledvina - Data Assimilation Using Incremental Analysis Updates - Monthly Weather Review Volume 124, Issue 6 (June 1996) - pages 1256--1271 - - For using this module. Default use_this_module=.false. - - For prescribing the fraction of the increment. - applied to the restoring period. Default fraction_increment=1.0 - - For specifying the amount of days to restore. - Default days_to_increment=1 - - For specifying the amount of seconds to restore. - Default secs_to_increment=0 - - This subroutine is intended to be used to initialize the increments. - Everything in this subroutine is a user prototype, and should be replacable. - - This subroutine calculates thickness weighted and density weighted - time tendencies of tracers due to damping by increments. - Module ocean_increment_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_increment_velocity_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted velocity tendency [meter^2/sec^2] from increments. -
- - - -- - This increment module performs incremental update analysis (IUA), - an approach used in data assimilation and forecasting to reduce - spurious perturbations when correcting the model state. - IUA involves restoring to analysis increments i.e. differences between model - and analysis fields rather than actual fields (See Bloom et al., 1996). - The user can define the period that IUA is carried out - and also the fraction of the increment to be restored over that period. - - This module applies a general 3D source to velocities. The sources - can occur at any location and with any distribution in the domain - An array of velocity tendencies due to the increments is augmented through a - call to increment_velocity_source. The array of velocity tendencies must be - reset to zero between calls. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the velocitys are being driven. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_increment_velocity_init:
- -- -ocean_increment_velocity_source:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_increment_velocity_init
--
-- -DESCRIPTION -
-- - This subroutine is intended to be used to initialize the increments. - Everything in this subroutine is a user prototype, and should be replacable. -
-
-
-- - -
-ocean_increment_velocity_source
--
-- -DESCRIPTION -
-- - This subroutine calculates thickness weighted and density weighted - time tendencies of velocitys due to damping by increments. -
-
-
-
-NAMELIST
- --&ocean_increment_velocity_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -fraction_increment -
-- For prescribing the fraction of the increment. - applied to the restoring period. Default fraction_increment=1.0 -
-
-[real] -- -days_to_increment -
-- For specifying the amount of days to restore. - Default days_to_increment=1 -
-
-[integer] -- -secs_to_increment -
-- For specifying the amount of seconds to restore. - Default secs_to_increment=0 -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_increment_velocity.xml b/src/mom5/ocean_param/sources/ocean_increment_velocity.xml deleted file mode 100644 index 1c941faa28..0000000000 --- a/src/mom5/ocean_param/sources/ocean_increment_velocity.xml +++ /dev/null @@ -1,48 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_momentum_source.F90 b/src/mom5/ocean_param/sources/ocean_momentum_source.F90 index 734de70f24..a9002224e1 100644 --- a/src/mom5/ocean_param/sources/ocean_momentum_source.F90 +++ b/src/mom5/ocean_param/sources/ocean_momentum_source.F90 @@ -94,9 +94,9 @@ module ocean_momentum_source_mod integer :: id_rayleigh_drag_power=-1 character(len=128) :: version=& - '$Id: ocean_momentum_source.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' + '$Id: ocean_momentum_source.F90,v 20.0 2013/12/14 00:16:02 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk diff --git a/src/mom5/ocean_param/sources/ocean_momentum_source.html b/src/mom5/ocean_param/sources/ocean_momentum_source.html deleted file mode 100644 index a6ff08295a..0000000000 --- a/src/mom5/ocean_param/sources/ocean_momentum_source.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - Russell Fiedler - Paul Sandery - - Thickness weighted velocity tendency [meter^2/sec^2] from increments. - - - This increment module performs incremental update analysis (IUA), - an approach used in data assimilation and forecasting to reduce - spurious perturbations when correcting the model state. - IUA involves restoring to analysis increments i.e. differences between model - and analysis fields rather than actual fields (See Bloom et al., 1996). - The user can define the period that IUA is carried out - and also the fraction of the increment to be restored over that period. - - This module applies a general 3D source to velocities. The sources - can occur at any location and with any distribution in the domain - An array of velocity tendencies due to the increments is augmented through a - call to increment_velocity_source. The array of velocity tendencies must be - reset to zero between calls. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the velocitys are being driven. - - S.C. Bloom, L.L. Takacs, A.M. da Silva, and D. Ledvina - Data Assimilation Using Incremental Analysis Updates - Monthly Weather Review Volume 124, Issue 6 (June 1996) - pages 1256--1271 - - For using this module. Default use_this_module=.false. - - For prescribing the fraction of the increment. - applied to the restoring period. Default fraction_increment=1.0 - - For specifying the amount of days to restore. - Default days_to_increment=1 - - For specifying the amount of seconds to restore. - Default secs_to_increment=0 - - This subroutine is intended to be used to initialize the increments. - Everything in this subroutine is a user prototype, and should be replacable. - - This subroutine calculates thickness weighted and density weighted - time tendencies of velocitys due to damping by increments. - Module ocean_momentum_source_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_momentum_source_mod
- - - - - -
-OVERVIEW
- -- Internal momentum sources, such as sink from Rayleigh drag. -
- - - -- Compute thickness weighted and density weighted tendency - [velocity*(kg/m^3)*meter/sec] for velocity associated with - momentun sources in the interior. Primary application is to - specify Rayleigh drag (a momentum sink). --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
field_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_momentum_source_init:
- -- -momentum_source:
- -- -rayleigh_damp_table_init:
- -- -on_comp_domain:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_momentum_source_init
--
-- -DESCRIPTION -
-- - Initial set up for momentum source/sink -
-
-
-- - -
-momentum_source
--
-- -DESCRIPTION -
-- - Compute the momentum source/sink (N/m2). -
-
-
-- - -
-rayleigh_damp_table_init
--
-- -DESCRIPTION -
-- - Read in static Rayleigh drag dissipation times entered to the - table "rayleigh_damp_table". The dissipation times should be - entered in units of seconds. -
-
-
-- - -
-on_comp_domain
--
-- -DESCRIPTION -
-- - Determine if the point is in comp-domain for the processor. -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular point in a table. - -
[integer]
-
-NAMELIST
- --&ocean_momentum_source_nml --
-
----
-- -use_this_module -
-- Needs to be true in order to use this scheme. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -verbose_init -
-- For verbose initialization information. -
-
-[logical] -- -use_rayleigh_damp_table -
-- For reading in Rayleigh damping times from a table. -
-
-[logical] -- -rayleigh_damp_exp_from_bottom -
-- For computing a Rayleigh damping time with largest at bottom and - decaying towards surface. -
-
-[logical] -- -rayleigh_damp_exp_scale -
-- Exponential decay scale from bottom upwards for computing - the Rayleigh damping time. -
-
-[real, units: metre] -- -rayleigh_damp_exp_max -
-- Damping time at the bottom for rayleigh_damp_exp_from_bottom=.true. -
-
-[real, units: sec] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_momentum_source.xml b/src/mom5/ocean_param/sources/ocean_momentum_source.xml deleted file mode 100644 index c7f3a643ef..0000000000 --- a/src/mom5/ocean_param/sources/ocean_momentum_source.xml +++ /dev/null @@ -1,43 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_overexchange.F90 b/src/mom5/ocean_param/sources/ocean_overexchange.F90 index 8705e26f45..5fb753bdaf 100644 --- a/src/mom5/ocean_param/sources/ocean_overexchange.F90 +++ b/src/mom5/ocean_param/sources/ocean_overexchange.F90 @@ -195,9 +195,9 @@ module ocean_overexchange_mod character(len=128) :: version=& - '=>Using: ocean_overexchange.f90 ($Id: ocean_overexchange.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $)' + '=>Using: ocean_overexchange.f90 ($Id: ocean_overexchange.F90,v 20.0 2013/12/14 00:16:04 fms Exp $)' character (len=128) :: tagname=& - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! number of prognostic tracers integer :: num_prog_tracers=0 diff --git a/src/mom5/ocean_param/sources/ocean_overexchange.html b/src/mom5/ocean_param/sources/ocean_overexchange.html deleted file mode 100644 index fff3a4e98d..0000000000 --- a/src/mom5/ocean_param/sources/ocean_overexchange.html +++ /dev/null @@ -1,324 +0,0 @@ - - - - S.M. Griffies - - Internal momentum sources, such as sink from Rayleigh drag. - - Compute thickness weighted and density weighted tendency - [velocity*(kg/m^3)*meter/sec] for velocity associated with - momentun sources in the interior. Primary application is to - specify Rayleigh drag (a momentum sink). - - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory - - Needs to be true in order to use this scheme. Default is false. - - For debugging. - - For verbose initialization information. - - For reading in Rayleigh damping times from a table. - - For computing a Rayleigh damping time with largest at bottom and - decaying towards surface. - - Exponential decay scale from bottom upwards for computing - the Rayleigh damping time. - - Damping time at the bottom for rayleigh_damp_exp_from_bottom=.true. - - Initial set up for momentum source/sink - - Compute the momentum source/sink (N/m2). - - Read in static Rayleigh drag dissipation times entered to the - table "rayleigh_damp_table". The dissipation times should be - entered in units of seconds. - - Determine if the point is in comp-domain for the processor. - - Integer labeling the particular point in a table. - Module ocean_overexchange_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_overexchange_mod
- - - - - -
-OVERVIEW
- -- Exchange of tracer properties as dense shallow parcel discharged - into deeper water to approach the depth of neutral buoyancy. -
- - - -- Exchange of tracer properties as dense shallow parcel is discharged - into deeper water to approach the parcel's depth of neutral buoyancy. - This module can be characterized as a mixture of the approach from - Campin and Goosse (1999) and and dynamically determined xlandmix. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_overexchange_init:
- -- -overexchange:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_overexchange_init
--
-- -DESCRIPTION -
-- - Initial set up for mixing of tracers into the abyss next to topography. -
-
-
-- - -
-overexchange
--
-- -DESCRIPTION -
-- - Compute thickness and density weighted tracer source [tracer*rho*m/s] - due to exchange of tracer properties in regions where density-driven - overflows are favorable. Allow for exchanges to occur over horizontally - distant points, so long as the dense shallow parcel finds that it - will sit on the bottom of the horizontally adjacent columns. Doing - so requires a search algorithm, which requires some if-test logic - as well as extended halos. Note that the halos cannot be extended - to larger than the size of the computational domain on a processor. - This restriction limits the extent that we can search horizontally. - - This scheme can be characterized as a dynamical xlandmix based on - the scheme of Campin and Goosse. The rates for the exchange are - functions of the topographic slope and the density differences - between parcels. - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from overexchange on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_overexchange_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging -
-
-[logical] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. -
-
-[logical] -- -overexch_npts -
-- Number of points used in search for the exchange method. - Default overexch_npts=1. Note: it is not possible to have - overexch_npts greater than or equal to the computational domain - extents, as this would require updates across multiple processors. - Default overexch_npts=1. -
-
-[integer] -- -overexch_weight_far -
-- To place more weight on points further from central point. This may - be done to enhance properties getting downslope. Default is - overexch_weight_far=.false. -
-
-[logical] -- -overexch_width -
-- Width of the re-weighting function used to emphasize the points further - along in the search for exchange points. Default overexch_width=1. -
-
-[integer] -- -overexch_stability -
-- Stability factor for determining the maximum overexch_flux. - Default overexch_stability=0.25 -
-
-[real] -- -overexch_min_thickness -
-- Minimum bottom cell thickness allowed for use of this scheme. - Have found that with very thin cells, the model can become very - unstable. Default overexch_min_thickness=4.0 -
-
-[real, units: metre] -- -overexch_check_extrema -
-- Check to be sure there are no global tracer extrema formed due - to the overexch process. Note that this approach DOES NOT - conserve tracer, so it is not generally recommended. - Default overexch_check_extrema=.false. -
-
-[logical] -- -overflow_mu -
-- Dissipation rate for the bottom friction. Campin and Goosse - suggest overflow_mu=10^-4 -
-
-[real, units: sec^-1] -- -overflow_delta -
-- Fraction of a grid cell participating in the overflow process. - Campin and Goosse suggest overflow_delta=1/3. -
-
-[real, units: dimensionless] -- -overflow_umax -
-- Maximum downslope speed used for determining the exchange rate. - Default overflow_umax=1.0. -
-
-[real, units: m/s] -
- - - - -
-REFERENCES
- ----
-- - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 -
-- - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_overexchange.xml b/src/mom5/ocean_param/sources/ocean_overexchange.xml deleted file mode 100644 index 0b24385b80..0000000000 --- a/src/mom5/ocean_param/sources/ocean_overexchange.xml +++ /dev/null @@ -1,87 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_overflow.F90 b/src/mom5/ocean_param/sources/ocean_overflow.F90 index 26f40e8899..7be564ed47 100644 --- a/src/mom5/ocean_param/sources/ocean_overflow.F90 +++ b/src/mom5/ocean_param/sources/ocean_overflow.F90 @@ -165,9 +165,9 @@ module ocean_overflow_mod real :: transport_convert=1.0e-9 character(len=128) :: version=& - '=>Using: ocean_overflow.f90 ($Id: ocean_overflow.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $)' + '=>Using: ocean_overflow.f90 ($Id: ocean_overflow.F90,v 20.0 2013/12/14 00:16:06 fms Exp $)' character (len=128) :: tagname=& - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! number of prognostic tracers integer :: num_prog_tracers=0 diff --git a/src/mom5/ocean_param/sources/ocean_overflow.html b/src/mom5/ocean_param/sources/ocean_overflow.html deleted file mode 100644 index 6d8ddda0bd..0000000000 --- a/src/mom5/ocean_param/sources/ocean_overflow.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - S.M. Griffies - - Exchange of tracer properties as dense shallow parcel discharged - into deeper water to approach the depth of neutral buoyancy. - - Exchange of tracer properties as dense shallow parcel is discharged - into deeper water to approach the parcel's depth of neutral buoyancy. - This module can be characterized as a mixture of the approach from - Campin and Goosse (1999) and and dynamically determined xlandmix. - - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 - - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory - - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory - - For using this module. Default use_this_module=.false. - - For debugging - - Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. - - Number of points used in search for the exchange method. - Default overexch_npts=1. Note: it is not possible to have - overexch_npts greater than or equal to the computational domain - extents, as this would require updates across multiple processors. - Default overexch_npts=1. - - To place more weight on points further from central point. This may - be done to enhance properties getting downslope. Default is - overexch_weight_far=.false. - - Width of the re-weighting function used to emphasize the points further - along in the search for exchange points. Default overexch_width=1. - - Stability factor for determining the maximum overexch_flux. - Default overexch_stability=0.25 - - Minimum bottom cell thickness allowed for use of this scheme. - Have found that with very thin cells, the model can become very - unstable. Default overexch_min_thickness=4.0 - - Check to be sure there are no global tracer extrema formed due - to the overexch process. Note that this approach DOES NOT - conserve tracer, so it is not generally recommended. - Default overexch_check_extrema=.false. - - Dissipation rate for the bottom friction. Campin and Goosse - suggest overflow_mu=10^-4 - - Fraction of a grid cell participating in the overflow process. - Campin and Goosse suggest overflow_delta=1/3. - - Maximum downslope speed used for determining the exchange rate. - Default overflow_umax=1.0. - - Initial set up for mixing of tracers into the abyss next to topography. - - Compute thickness and density weighted tracer source [tracer*rho*m/s] - due to exchange of tracer properties in regions where density-driven - overflows are favorable. Allow for exchanges to occur over horizontally - distant points, so long as the dense shallow parcel finds that it - will sit on the bottom of the horizontally adjacent columns. Doing - so requires a search algorithm, which requires some if-test logic - as well as extended halos. Note that the halos cannot be extended - to larger than the size of the computational domain on a processor. - This restriction limits the extent that we can search horizontally. - - This scheme can be characterized as a dynamical xlandmix based on - the scheme of Campin and Goosse. The rates for the exchange are - functions of the topographic slope and the density differences - between parcels. - - - Initialization of watermass diagnostic output files. - - Diagnose effects from overexchange on the watermass transformation. - Module ocean_overflow_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_overflow_mod
- - - - - -
-OVERVIEW
- -- Tracer source from discharging dense shallow water into the abyss - at the parcel's depth of neutral buoyancy. -
- - - -- Tracer source from discharging dense shallow water into the abyss - at the parcel's depth of neutral buoyancy. Follow the approach - of Campin and Goosse (1999), as well as modifications. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_overflow_init:
- -- -overflow:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_overflow_init
--
-- -DESCRIPTION -
-- - Initial set up for mixing of tracers into the abyss next to topography. -
-
-
-- - -
-overflow
--
-- -DESCRIPTION -
-- - Compute thickness and density weighted tracer source [tracer*rho*m/s] - due to upstream tracer advection in regions where density-driven - overflows are favorable. - - The MOM implementation of the Campin and Goosse (1999) - algorithm is detailed in MOM Elements. - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from overflow on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_overflow_nml --
-
----
-- -use_this_module -
-- For using this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging -
-
-[logical] -- -overflow_mu -
-- Dissipation rate for the bottom friction. Campin and Goosse - suggest overflow_mu=10^-4 -
-
-[real, units: inverse seconds] -- -overflow_delta -
-- Fraction of a grid cell participating in the overflow process. - Campin and Goosse suggest overflow_delta=1/3. -
-
-[real, units: dimensionless] -- -overflow_umax -
-- Maximum downslope speed. -
-
-[real, units: m/s] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. -
-
-[logical] -- -no_return_flow -
-- Set true to remove the Campin and Goose return flow "piping". - Default no_return_flow=.false. to recover the standard approach from - Campin and Goose. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 -
-- - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_overflow.xml b/src/mom5/ocean_param/sources/ocean_overflow.xml deleted file mode 100644 index d8e9ca3f66..0000000000 --- a/src/mom5/ocean_param/sources/ocean_overflow.xml +++ /dev/null @@ -1,57 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_overflow_OFP.F90 b/src/mom5/ocean_param/sources/ocean_overflow_OFP.F90 index de515254ba..8f25d11105 100644 --- a/src/mom5/ocean_param/sources/ocean_overflow_OFP.F90 +++ b/src/mom5/ocean_param/sources/ocean_overflow_OFP.F90 @@ -338,9 +338,9 @@ module ocean_overflow_OFP_mod !---------------------------------------------------------------------------------- character(len=128) :: version=& - '=>Using: ocean_overflow_OFP.f90 ($Id: ocean_overflow_OFP.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $)' + '=>Using: ocean_overflow_OFP.f90 ($Id: ocean_overflow_OFP.F90,v 20.0 2013/12/14 00:16:08 fms Exp $)' character (len=128) :: tagname=& - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! number of prognostic tracers integer :: num_prog_tracers=0 @@ -1612,7 +1612,9 @@ subroutine ocean_overflow_OFP_init(Grid, Domain, Time, Dens, T_prog, Ocean_optio !-- no update domains + ! integer variables call mpp_update_domains (kmto, OFP_domain%domain2d, complete=.true.) + ! real variables call mpp_update_domains (dato, OFP_domain%domain2d, complete=.false.) call mpp_update_domains (dxto, OFP_domain%domain2d, complete=.false.) call mpp_update_domains (dyto, OFP_domain%domain2d, complete=.false.) diff --git a/src/mom5/ocean_param/sources/ocean_overflow_OFP.html b/src/mom5/ocean_param/sources/ocean_overflow_OFP.html deleted file mode 100644 index c7a4dbb28d..0000000000 --- a/src/mom5/ocean_param/sources/ocean_overflow_OFP.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - S.M. Griffies - Michael Bates - - Tracer source from discharging dense shallow water into the abyss - at the parcel's depth of neutral buoyancy. - - Tracer source from discharging dense shallow water into the abyss - at the parcel's depth of neutral buoyancy. Follow the approach - of Campin and Goosse (1999), as well as modifications. - - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 - - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory - - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory - - For using this module. Default is false. - - For debugging - - Dissipation rate for the bottom friction. Campin and Goosse - suggest overflow_mu=10^-4 - - Fraction of a grid cell participating in the overflow process. - Campin and Goosse suggest overflow_delta=1/3. - - Maximum downslope speed. - - Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is false. - - Set true to remove the Campin and Goose return flow "piping". - Default no_return_flow=.false. to recover the standard approach from - Campin and Goose. - - Initial set up for mixing of tracers into the abyss next to topography. - - Compute thickness and density weighted tracer source [tracer*rho*m/s] - due to upstream tracer advection in regions where density-driven - overflows are favorable. - - The MOM implementation of the Campin and Goosse (1999) - algorithm is detailed in MOM Elements. - - - Initialization of watermass diagnostic output files. - - Diagnose effects from overflow on the watermass transformation. - Module ocean_overflow_OFP_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_overflow_OFP_mod
- - --Contact: H.-C. Lee - -- - -
-Reviewers: S. M. Griffies -, - Z. Liang - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Modeling the physical processes of deep overflow from regional seas. -
- - - --(1) Physics of the overflow is based on the paper - of Briegleb, Danabasoglu and Large (2010) -(2) Geographic input data (I and J points) for each region - is given by user at the Field Table. -(3) Model can compute the overflow processes for - many places. There is no maximum number of overflows. -(4) Maximum production lines (or regions) in this code is ten. - To get more, code needs to be written. -(5) Main acronyms. - src:source, int:interior, ent:entrainment, prd:production - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
field_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_overflow_OFP_init:
- -- -overflow_OFP:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_overflow_OFP_init
--
-- -DESCRIPTION -
-- - Initial set up for OFP -
-
-
-- - -
-overflow_OFP
--
-- -DESCRIPTION -
-- - Compute overflow process - - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from overflow on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_overflow_OFP_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging. Default is false. -
-
-[logical] -- -crit_Fr_geo_ofp -
-- Critical geostrophic Froude number. - Set the minimum Froude number for mixing process - between source and entrainment waters - Default is 1.0 -
-
-[real] -- -crit_Fr_geo_ofp -
-- Maximum overflow speed at the source region - Default is 3.0 m/s -
-
-[real] -- -frac_exchange_src -
-- Areal fraction of the overflow exchange at the source region - Default is 1.0 -
-
-[real] -- -max_vol_trans_ofp -
-- Maximum volume transport of the overflow [m^3/s] - Default is 10.e6 -
-
-[real] -- -max_ofp_speed -
-- Maximum overflow speed [m^/s] - Default is 2.0 -
-
-[real] -- -do_mass_ofp -
-- Considering the mass source in the overflow process - Default is .true. -
-
-[logical] -- -diag_step -
-- Diagnostic time step for OFP. - Default is diag_step = -1 - The diagnostic output is saved in the ascii directory as the ascii format. -
-
-[integer] -- -do_entrainment_para_ofp -
-- Considering the parameterization of entrainment process - in the overflow process - Default is .true. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Briegleb B. P., G. Danabasoglu and W. G. Large (2010), An Overflow Parameterization - for the ocean component of the Community Climate System Model. NCAR Technical Note, - NCAR Boulder, CO. -
-- - Danabasoglu G., W. G. Large and B. P. Briegleb (2010), Climate impacts of parameterized - Nordic Sea Overflow, Journal of Geophysical Research, (submitted) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_overflow_OFP.xml b/src/mom5/ocean_param/sources/ocean_overflow_OFP.xml deleted file mode 100644 index b9da2803c9..0000000000 --- a/src/mom5/ocean_param/sources/ocean_overflow_OFP.xml +++ /dev/null @@ -1,70 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_rivermix.F90 b/src/mom5/ocean_param/sources/ocean_rivermix.F90 index e7e1a6e1d2..508ee525a4 100644 --- a/src/mom5/ocean_param/sources/ocean_rivermix.F90 +++ b/src/mom5/ocean_param/sources/ocean_rivermix.F90 @@ -347,9 +347,9 @@ module ocean_rivermix_mod integer :: index_salt=-1 character(len=128) :: version=& - '$Id: ocean_rivermix.F90,v 1.1.2.1 2012/05/15 16:05:39 smg Exp $' + '$Id: ocean_rivermix.F90,v 20.0 2013/12/14 00:16:10 fms Exp $' character (len=128) :: tagname=& - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk @@ -694,9 +694,10 @@ subroutine rivermix (Time, Thickness, Dens, T_prog, river, runoff, calving, & call diagnose_3d(Time, Grd, id_runoffmix(n), T_prog(n)%wrk1(:,:,:)*T_prog(n)%conversion) endif enddo - call watermass_diag_runoff(Time, Dens, T_prog, calving, & + call watermass_diag_runoff(Time, Dens, T_prog, runoff, & T_prog(index_temp)%wrk1(:,:,:),T_prog(index_salt)%wrk1(:,:,:)) + do n=1,num_prog_tracers T_prog(n)%wrk1(:,:,:) = 0.0 enddo @@ -718,6 +719,7 @@ subroutine rivermix (Time, Thickness, Dens, T_prog, river, runoff, calving, & call watermass_diag_calving(Time, Dens, T_prog, calving, & T_prog(index_temp)%wrk1(:,:,:),T_prog(index_salt)%wrk1(:,:,:)) + endif ! discharge_combine_runoff_calve diff --git a/src/mom5/ocean_param/sources/ocean_rivermix.html b/src/mom5/ocean_param/sources/ocean_rivermix.html deleted file mode 100644 index f484b6479a..0000000000 --- a/src/mom5/ocean_param/sources/ocean_rivermix.html +++ /dev/null @@ -1,451 +0,0 @@ - - - - H.-C. Lee - S. M. Griffies - Z. Liang - - Modeling the physical processes of deep overflow from regional seas. - -(1) Physics of the overflow is based on the paper - of Briegleb, Danabasoglu and Large (2010) -(2) Geographic input data (I and J points) for each region - is given by user at the Field Table. -(3) Model can compute the overflow processes for - many places. There is no maximum number of overflows. -(4) Maximum production lines (or regions) in this code is ten. - To get more, code needs to be written. -(5) Main acronyms. - src:source, int:interior, ent:entrainment, prd:production - - - Briegleb B. P., G. Danabasoglu and W. G. Large (2010), An Overflow Parameterization - for the ocean component of the Community Climate System Model. NCAR Technical Note, - NCAR Boulder, CO. - - Danabasoglu G., W. G. Large and B. P. Briegleb (2010), Climate impacts of parameterized - Nordic Sea Overflow, Journal of Geophysical Research, (submitted) - - For using this module. Default use_this_module=.false. - - For debugging. Default is false. - - Critical geostrophic Froude number. - Set the minimum Froude number for mixing process - between source and entrainment waters - Default is 1.0 - - Maximum overflow speed at the source region - Default is 3.0 m/s - - Areal fraction of the overflow exchange at the source region - Default is 1.0 - - Maximum volume transport of the overflow [m^3/s] - Default is 10.e6 - - Maximum overflow speed [m^/s] - Default is 2.0 - - Considering the mass source in the overflow process - Default is .true. - - Diagnostic time step for OFP. - Default is diag_step = -1 - The diagnostic output is saved in the ascii directory as the ascii format. - - Considering the parameterization of entrainment process - in the overflow process - Default is .true. - - Initial set up for OFP - - Compute overflow process - - - - Initialization of watermass diagnostic output files. - - Diagnose effects from overflow on the watermass transformation. - Module ocean_rivermix_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_rivermix_mod
- - --Contact: S.M. Griffies -, - M.J. Harrison -, - K.W. Dixon - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Tracer source from discharging river with depth or - mixing rivers with depth. -
- - - -- Compute thickness weighted tendency [tracer*rho*meter/sec] - associated with discharge of river tracer content - over a user defined column of ocean points. Points are - selected based on whether river flow into a point is nonzero. - Contribution added to tracer source array. --
- - -
-OTHER MODULES USED
- --- - - -axis_utils_mod-
constants_mod
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_rivermix_init:
- -- -rivermix:
- -- -river_discharge_tracer:
- -- -runoff_calving_discharge_tracer:
- -- -river_kappa:
- -- -watermass_diag_init:
- -- -watermass_diag_river:
- -- -watermass_diag_runoff:
- -- -watermass_diag_calving:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_rivermix_init
--
-- -DESCRIPTION -
-- - Initial set up for mixing of tracers at runoff points. -
-
-
-- - -
-rivermix
--
-- -DESCRIPTION -
-- - This subroutine computes one or all of the following: - - (1) Thickness weighted and rho weighted tracer source associated - with river tracer content discharged into a vertical column of ocean - tracer cells. This is done if river_discharge=.true. - - (2) Enhance vertical diffusivity at river mouths. - This is done if river_diffuse_temp=.true. or - river_diffuse_salt=.true. - - Doing one or both are useful for models with fine vertical - resolution, where discharging river content to top cell - is often not numerically suitable nor physically relevant. - -
-
-
-- - -
-river_discharge_tracer
--
-- -DESCRIPTION -
-- - Compute thickness weighted tracer source [tracer*m/s] - associated with the discharge of tracer from a river over - a vertical column whose thickness is set by River_insertion_thickness - and whose horizontal location is given by the river array. - - Jan 2005: converted to mass weighting for use with non-Boussinesq - pressure-like coodinates. - - This subroutine is maintained for legacy purposes. - -
-
-
-- - -
-runoff_calving_discharge_tracer
--
-- -DESCRIPTION -
-- - Compute thickness weighted tracer source [tracer*m/s] - associated with the discharge of tracer from runoff or calving over - a vertical column whose thickness is set by either runoff_insertion_thickness - or calving_insertion_thickness, and whose horizontal location is given - by the runoff or calving array. - - Jan 2005: converted to mass weighting for use with non-Boussinesq - pressure-like coodinates. - - Feb 2009: now use calving_tracer_flux and runoff_tracer_flux, as the - land model carries information about the tracer content in the - liquid and solid runoff. - -
-
-
-- - -
-river_kappa
--
-- -DESCRIPTION -
-- - This subroutine enhances the vertical diffusivity kappa over - a vertical column whose thickness is set by river_diffusion_thickness - and whose horizontal location is given by the rmask array. - Note that rmask can be > 0 even if river=0 in the case when - use virtual salt flux. - The enhanced diffusivity is maximum at the top cell and is linearly - interpolated to the normal diffusivity at the depth set by - river_diffusion_thickness -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag_river
--
-- -DESCRIPTION -
-- - watermass diagnostics for river = runoff + calving. -
-
-
-- - -
-watermass_diag_runoff
--
-- -DESCRIPTION -
-- - watermass diagnostics for liquid runoff -
-
-
-- - -
-watermass_diag_calving
--
-- -DESCRIPTION -
-- - watermass diagnostics for solid calving. -
-
-
-
-NAMELIST
- --&ocean_rivermix_nml --
-
----
-- -use_this_module -
-- Must be true to enable this module. Default=.true., since - this is the only way that tracer in river water enters the ocean. -
-
-[logical] -- -discharge_combine_runoff_calve -
-- Set discharge_combine_runoff_calve=.true. to discharge combined tracer carried - by liquid and solid runoff. This approach is sensible when ocean - assigns a tracer content to the liquid and solid runoff fields. - The alternative is to have a land model that provides information about - the tracer coming into the ocean from land water, in which case it is - preferable to set discharge_combine_runoff_calve=.false., so to do the runoff - and calving separately. - Default discharge_combine_runoff_calve=.true. -
-
-[logical] -- -river_insertion_thickness -
-- Thickness of the column over which to insert tracers from - rivers. Default river_insertion_thickness=0.0 (all in top). -
-
-[real, units: meter] -- -runoff_insertion_thickness -
-- Thickness of the column over which to insert tracers carried by - liquid runoff. Default runoff_insertion_thickness=0.0 (all in top). -
-
-[real, units: meter] -- -calving_insertion_thickness -
-- Thickness of the column over which to insert tracers carried by - solid runoff. Default calving_insertion_thickness=0.0 (all in top). -
-
-[real, units: meter] -- -river_diffusion_thickness -
-- Thickness of the column over which to diffuse tracers from - rivers. -
-
-[real, units: meter] -- -river_diffusivity -
-- Vertical diffusivity enhancement at river mouths which is applied - to a depth of river_diffusion_thickness, with linear tapering to zero - enhancement from the ocean surface to river_diffusion_thickness. -
-
-[real, units: m^2/s] -- -river_diffuse_temp -
-- Logical to determine if enhance vertical diffusion of temp at river mouths -
-
-[logical] -- -river_diffuse_salt -
-- Logical to determine if enhance vertical diffusion of salt and all other - passive tracers at river mouths -
-
-[logical] -- -do_bitwise_exact_sum -
-- Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is do_bitwise_exact_sum=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging -
-
-[logical] -- -debug_all_in_top_cell -
-- For debugging, by placing all in top cell, regardless value of - river_insertion_thickness. -
-
-[logical] -- -debug_this_module_heat -
-- For debugging, print global sum of heating rate by river water. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- - -
-NOTES
- -- Algorithm ensures total tracer is conserved. Note that volume/mass is - modified by river water within the eta-equation using the big leap-frog. --
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_rivermix.xml b/src/mom5/ocean_param/sources/ocean_rivermix.xml deleted file mode 100644 index 6349b44c15..0000000000 --- a/src/mom5/ocean_param/sources/ocean_rivermix.xml +++ /dev/null @@ -1,126 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_riverspread.F90 b/src/mom5/ocean_param/sources/ocean_riverspread.F90 index 327e46bc3d..c77a3fd7a1 100644 --- a/src/mom5/ocean_param/sources/ocean_riverspread.F90 +++ b/src/mom5/ocean_param/sources/ocean_riverspread.F90 @@ -129,9 +129,9 @@ module ocean_riverspread_mod logical, dimension(:), allocatable :: error_spread ! for checking that all spread points are OK. character(len=256) :: version=& - '$Id: ocean_riverspread.F90,v 1.1.2.2 2012/06/01 20:47:08 Stephen.Griffies Exp $)' + '$Id: ocean_riverspread.F90,v 20.0 2013/12/14 00:16:12 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk real :: dtime diff --git a/src/mom5/ocean_param/sources/ocean_riverspread.html b/src/mom5/ocean_param/sources/ocean_riverspread.html deleted file mode 100644 index e727758a07..0000000000 --- a/src/mom5/ocean_param/sources/ocean_riverspread.html +++ /dev/null @@ -1,325 +0,0 @@ - - - - S.M. Griffies - M.J. Harrison - K.W. Dixon - - Tracer source from discharging river with depth or - mixing rivers with depth. - - Compute thickness weighted tendency [tracer*rho*meter/sec] - associated with discharge of river tracer content - over a user defined column of ocean points. Points are - selected based on whether river flow into a point is nonzero. - Contribution added to tracer source array. - - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory - - Algorithm ensures total tracer is conserved. Note that volume/mass is - modified by river water within the eta-equation using the big leap-frog. - - Must be true to enable this module. Default=.true., since - this is the only way that tracer in river water enters the ocean. - - Set discharge_combine_runoff_calve=.true. to discharge combined tracer carried - by liquid and solid runoff. This approach is sensible when ocean - assigns a tracer content to the liquid and solid runoff fields. - The alternative is to have a land model that provides information about - the tracer coming into the ocean from land water, in which case it is - preferable to set discharge_combine_runoff_calve=.false., so to do the runoff - and calving separately. - Default discharge_combine_runoff_calve=.true. - - Thickness of the column over which to insert tracers from - rivers. Default river_insertion_thickness=0.0 (all in top). - - Thickness of the column over which to insert tracers carried by - liquid runoff. Default runoff_insertion_thickness=0.0 (all in top). - - Thickness of the column over which to insert tracers carried by - solid runoff. Default calving_insertion_thickness=0.0 (all in top). - - Thickness of the column over which to diffuse tracers from - rivers. - - Vertical diffusivity enhancement at river mouths which is applied - to a depth of river_diffusion_thickness, with linear tapering to zero - enhancement from the ocean surface to river_diffusion_thickness. - - Logical to determine if enhance vertical diffusion of temp at river mouths - - Logical to determine if enhance vertical diffusion of salt and all other - passive tracers at river mouths - - Set true to do bitwise exact global sum. When it is false, the global - sum will be non-bitwise_exact, but will significantly increase efficiency. - The default value is do_bitwise_exact_sum=.false. - - For debugging - - For debugging, by placing all in top cell, regardless value of - river_insertion_thickness. - - For debugging, print global sum of heating rate by river water. - - Initial set up for mixing of tracers at runoff points. - - This subroutine computes one or all of the following: - - (1) Thickness weighted and rho weighted tracer source associated - with river tracer content discharged into a vertical column of ocean - tracer cells. This is done if river_discharge=.true. - - (2) Enhance vertical diffusivity at river mouths. - This is done if river_diffuse_temp=.true. or - river_diffuse_salt=.true. - - Doing one or both are useful for models with fine vertical - resolution, where discharging river content to top cell - is often not numerically suitable nor physically relevant. - - - Compute thickness weighted tracer source [tracer*m/s] - associated with the discharge of tracer from a river over - a vertical column whose thickness is set by River_insertion_thickness - and whose horizontal location is given by the river array. - - Jan 2005: converted to mass weighting for use with non-Boussinesq - pressure-like coodinates. - - This subroutine is maintained for legacy purposes. - - - Compute thickness weighted tracer source [tracer*m/s] - associated with the discharge of tracer from runoff or calving over - a vertical column whose thickness is set by either runoff_insertion_thickness - or calving_insertion_thickness, and whose horizontal location is given - by the runoff or calving array. - - Jan 2005: converted to mass weighting for use with non-Boussinesq - pressure-like coodinates. - - Feb 2009: now use calving_tracer_flux and runoff_tracer_flux, as the - land model carries information about the tracer content in the - liquid and solid runoff. - - - This subroutine enhances the vertical diffusivity kappa over - a vertical column whose thickness is set by river_diffusion_thickness - and whose horizontal location is given by the rmask array. - Note that rmask can be > 0 even if river=0 in the case when - use virtual salt flux. - The enhanced diffusivity is maximum at the top cell and is linearly - interpolated to the normal diffusivity at the depth set by - river_diffusion_thickness - - Initialization of watermass diagnostic output files. - - watermass diagnostics for river = runoff + calving. - - watermass diagnostics for liquid runoff - - watermass diagnostics for solid calving. - Module ocean_riverspread_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_riverspread_mod
- - - - - -
-OVERVIEW
- -- Spread runoff or calving horizontally over a region determined - by a table. Also provide option to spread river runoff or calving - through a diffusive operation. -
- - - -- At some coastal ocean gridpoints, the runoff or calving flux contribution to - (p-e+r) may be very large because of local insertion to ocean. Therefore, - we may choose to spread the large river runoff over neighboring pairs - of gridpoints. Annual mean river runoff greater than 0.05 m/day is - considered to be very large. - This module allows one to spread the river using two options. - A/ by specifying river spreading table points - B/ by performing a series of diffusion operations. --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_operators_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_riverspread_init:
- -- -spread_river_horz:
- -- -riverspread_laplacian:
- -- -at_least_one_in_spread_domain:
- -- -on_comp_domain:
- -- -on_data_domain:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_riverspread_init
--
-- -DESCRIPTION -
-- - Initial set up for spreading of tracers - - A/ Table drive approach - (i,j) locations of points to be spread are set in data - statements. - - Checks are performed to ensure that the spreading - grid locations are valid according to model configuration. - - A summary of the locations of spreading points is written out. - - User specified inputs in "USER INPUT" section: - - ispread and jspread = user specified i,j grid locations of data for spreading. - - is, ie, js, je = user specified i,j grid locations of - the corners of the spreading regions. - is and ie are the east and west coord of each region, - js and je are the south and north coord of each region. - - B/ Laplacian approach requires minimal setup - -
-
-
-- - -
-spread_river_horz
--
-- -DESCRIPTION -
-- - Provide conservative spreading of river runoff field. -
-
-
-- - -
-riverspread_laplacian
--
-- -DESCRIPTION -
-- - Provide conservative spreading of river runoff field using a - Laplacian operator. -
-
-
-- - -
-at_least_one_in_spread_domain
--
-- -DESCRIPTION -
-- - Function to see if at least one of the points in the spreading region - is within the computational domain for the processor. -
-
-
-- -INPUT -
-- -
--
-- -nsp - Integer labeling the particular spreading region - -
[integer]
-- - -
-on_comp_domain
--
-- -DESCRIPTION -
-- - Determine if the point is in comp-domain for the processor -
-
-
-- - -
-on_data_domain
--
-- -DESCRIPTION -
-- - Determine if the point is in data-domain for the processor -
-
-
-
-NAMELIST
- --&ocean_riverspread_nml --
-
----
-- -use_this_module -
-- Must be true to enable this module. Default=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging. Default=.false. -
-
-[logical] -- -riverspread_diffusion -
-- For spreading river water via a Laplacian diffusion operation. - Default=.false. -
-
-[logical] -- -riverspread_diffusion_passes -
-- Number of diffusion passes applied to the runoff/calving array. - Default riverspread_diffusion_passes = 0. -
-
-[integer] -- -vel_micom_smooth -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of river water. - Default vel_micom_smooth=0.2. -
-
-[real, units: m/sec] -
- - - - -
-NOTES
- -- Spreading in a 2D lat-long field is implemented in the following manner: - - A/ Table driven spreadging - - If the spreading region lives within the halo region - (i.e., within same local_domain), - then no added mpp communication required. However, more generally - the spreading region can extend beyond the existing halo region. - In this case, spread_domain - is defined so that its halos incorporate the maximum separation - of spreading points. New tracer and grid arrays - are defined over this extended spread_domain. This added domain - size will come at some computational cost, so it is advantageous - to choose the spreading region carefully. - - B/ Laplacian diffusion spreading - - Apply Laplacian operator to the river runoff/calving array to spread - the river water abroad from the river mouth. - --
-
- The current implementation of table driven spreading has not - been tested for a spreading region that is separated by either - a zonal cyclic condition or across the tripolar fold. -
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_riverspread.xml b/src/mom5/ocean_param/sources/ocean_riverspread.xml deleted file mode 100644 index 516fcc9257..0000000000 --- a/src/mom5/ocean_param/sources/ocean_riverspread.xml +++ /dev/null @@ -1,94 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_shortwave.F90 b/src/mom5/ocean_param/sources/ocean_shortwave.F90 index c7b86d08c0..82749b5dfd 100644 --- a/src/mom5/ocean_param/sources/ocean_shortwave.F90 +++ b/src/mom5/ocean_param/sources/ocean_shortwave.F90 @@ -57,8 +57,8 @@ module ocean_shortwave_mod type(ocean_domain_type), pointer :: Dom => NULL() type(ocean_grid_type), pointer :: Grd => NULL() -character(len=128) :: version='$Id: ocean_shortwave.F90,v 1.1.2.3 2012/06/01 20:47:08 Stephen.Griffies Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version='$Id: ocean_shortwave.F90,v 20.0 2013/12/14 00:16:14 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' public ocean_shortwave_init public ocean_irradiance_init diff --git a/src/mom5/ocean_param/sources/ocean_shortwave.html b/src/mom5/ocean_param/sources/ocean_shortwave.html deleted file mode 100644 index e61799e15e..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - S.M. Griffies - - Spread runoff or calving horizontally over a region determined - by a table. Also provide option to spread river runoff or calving - through a diffusive operation. - - At some coastal ocean gridpoints, the runoff or calving flux contribution to - (p-e+r) may be very large because of local insertion to ocean. Therefore, - we may choose to spread the large river runoff over neighboring pairs - of gridpoints. Annual mean river runoff greater than 0.05 m/day is - considered to be very large. - This module allows one to spread the river using two options. - A/ by specifying river spreading table points - B/ by performing a series of diffusion operations. - - Spreading in a 2D lat-long field is implemented in the following manner: - - A/ Table driven spreadging - - If the spreading region lives within the halo region - (i.e., within same local_domain), - then no added mpp communication required. However, more generally - the spreading region can extend beyond the existing halo region. - In this case, spread_domain - is defined so that its halos incorporate the maximum separation - of spreading points. New tracer and grid arrays - are defined over this extended spread_domain. This added domain - size will come at some computational cost, so it is advantageous - to choose the spreading region carefully. - - B/ Laplacian diffusion spreading - - Apply Laplacian operator to the river runoff/calving array to spread - the river water abroad from the river mouth. - - - The current implementation of table driven spreading has not - been tested for a spreading region that is separated by either - a zonal cyclic condition or across the tripolar fold. - - Must be true to enable this module. Default=.false. - - For debugging. Default=.false. - - For spreading river water via a Laplacian diffusion operation. - Default=.false. - - Number of diffusion passes applied to the runoff/calving array. - Default riverspread_diffusion_passes = 0. - - Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of river water. - Default vel_micom_smooth=0.2. - - Initial set up for spreading of tracers - - A/ Table drive approach - (i,j) locations of points to be spread are set in data - statements. - - Checks are performed to ensure that the spreading - grid locations are valid according to model configuration. - - A summary of the locations of spreading points is written out. - - User specified inputs in "USER INPUT" section: - - ispread and jspread = user specified i,j grid locations of data for spreading. - - is, ie, js, je = user specified i,j grid locations of - the corners of the spreading regions. - is and ie are the east and west coord of each region, - js and je are the south and north coord of each region. - - B/ Laplacian approach requires minimal setup - - - Provide conservative spreading of river runoff field. - - Provide conservative spreading of river runoff field using a - Laplacian operator. - - Function to see if at least one of the points in the spreading region - is within the computational domain for the processor. - - Integer labeling the particular spreading region - - Determine if the point is in comp-domain for the processor - - Determine if the point is in data-domain for the processor - Module ocean_shortwave_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_shortwave_mod
- - - - - -
-OVERVIEW
- -- This module sets up the shortwave routines. -
- - - -- There are two shortwave routines available. The more complete one is - from GFDL, and the streamlined and simpler one is from CSIRO. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_shortwave_csiro_mod
ocean_shortwave_jerlov_mod
ocean_shortwave_gfdl_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_tpm_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_shortwave_init:
- -- -ocean_irradiance_init:
- -- -sw_source:
- -- -sw_source_ext:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_shortwave_init
--
-- -DESCRIPTION -
-- - Initialization for the shorwave module -
-
-
-- - -
-ocean_irradiance_init
--
-- -DESCRIPTION -
-- - - Initialize the irradiance diagnostic tracer. - -
-
-
-- - -
-sw_source
--
-- -DESCRIPTION -
-- - - Choose either of the GFDL, CSIRO, JERLOV or External sw_source methods. - -
-
-
-- - -
-sw_source_ext
--
-- -DESCRIPTION -
-- - - Example of a routine that applies an externally supplied shortwave - heating rate (i.e. top minus bottom radiation flux in W/m^2). Users - should modify this routine for their own purposes. - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from shortwave heating on watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_shortwave_nml --
-
----
-- -use_this_module= -
-- Must be .true. to run with module. Default is false. -
-
-[logical] -- -use_shortwave_gfdl= -
-- Must be .true. to run with the GFDL shortwave module. - Default is true. -
-
-[logical] -- -use_shortwave_csiro= -
-- Must be .true. to run with the CSIRO shortwave module. - Default is false. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_shortwave.xml b/src/mom5/ocean_param/sources/ocean_shortwave.xml deleted file mode 100644 index bcaaa567a9..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave.xml +++ /dev/null @@ -1,38 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_csiro.F90 b/src/mom5/ocean_param/sources/ocean_shortwave_csiro.F90 index 275a86dc7e..cbdd1dc642 100644 --- a/src/mom5/ocean_param/sources/ocean_shortwave_csiro.F90 +++ b/src/mom5/ocean_param/sources/ocean_shortwave_csiro.F90 @@ -6,9 +6,6 @@ module ocean_shortwave_csiro_mod ! S. M. Griffies - - This module sets up the shortwave routines. - - There are two shortwave routines available. The more complete one is - from GFDL, and the streamlined and simpler one is from CSIRO. - - Must be .true. to run with module. Default is false. - - Must be .true. to run with the GFDL shortwave module. - Default is true. - - Must be .true. to run with the CSIRO shortwave module. - Default is false. - - Initialization for the shorwave module - - - Initialize the irradiance diagnostic tracer. - - - - Choose either of the GFDL, CSIRO, JERLOV or External sw_source methods. - - - - Example of a routine that applies an externally supplied shortwave - heating rate (i.e. top minus bottom radiation flux in W/m^2). Users - should modify this routine for their own purposes. - - - Initialization of watermass diagnostic output files. - - Diagnose effects from shortwave heating on watermass transformation. - S.M. Griffies ! ! -!Alexander Pletzer -! -! !! This module returns thickness and density weighted temperature ! tendency [kg/m^3 * deg C *m/sec] from penetrative shortwave heating. @@ -125,8 +122,8 @@ module ocean_shortwave_csiro_mod type(ocean_domain_type), pointer :: Dom => NULL() type(ocean_grid_type), pointer :: Grd => NULL() -character(len=128) :: version='$Id: ocean_shortwave_csiro.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version='$Id: ocean_shortwave_csiro.F90,v 20.0 2013/12/14 00:16:16 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! F_vis is the amount of light in the shortwave verses the long wave. ! F_vis=0.54 on sunny days and F_vis=0.60 on cloudy days. diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_csiro.html b/src/mom5/ocean_param/sources/ocean_shortwave_csiro.html deleted file mode 100644 index 4fbbca3677..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave_csiro.html +++ /dev/null @@ -1,297 +0,0 @@ - - - - Module ocean_shortwave_csiro_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_shortwave_csiro_mod
- - --Contact: Russell Fiedler - -- - -
-Reviewers: S.M. Griffies -, - Alexander Pletzer - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module returns thickness and density weighted temperature - tendency [kg/m^3 * deg C *m/sec] from penetrative shortwave heating. -
- - - -- Compute thickness and density weighted tendency [deg C *m/sec *kg/m^3] - of temperature associated with penetrative shortwave heating in the upper - ocean. Generally penetration is taken as a function of monthly optical - properties of the upper ocean, where optical properties are read - in from a file of climatological data. - - This module ussumes a simple single exponential decay law. The e-folding - depth may vary spatially and temporaly. This routine is commonly - used by researchers at CSIRO Marine and Atmospheric Research in - Australia. It has been optimized for vector peformance in - June 2003 on the Australian NEC computer. --
- - -
-OTHER MODULES USED
- --- - - -axis_utils_mod-
field_manager_mod
fms_mod
mpp_mod
time_interp_external_mod
ocean_domains_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_shortwave_csiro_init:
- -- -sw_source_csiro:
- -- -sw_pen:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_shortwave_csiro_init
--
-- -DESCRIPTION -
-- - Initialization for the shortwave module -
-
-
-- - -
-sw_source_csiro
--
-- -DESCRIPTION -
-- - Add short wave penetrative heating to T_prog(index_temp)%th_tendency. - - Note that the divergence of shortwave for the first - level "div_sw(0)" is compensating for the effect of having - the shortwave component already included in the total - surface tracer flux "stf(i,j,temp)" - -
-
-
-- - -
-sw_pen
--
-- -DESCRIPTION -
-- - Absorbtion of shortwave radiation in the water assumes energy partitions - represented by a single exponential: - - The exponentialsrepresents a parameterization of the - attenuation coefficient for light between 300 um and 750 um in the following - form: - - E(z) = E(0) * exp(z/efold)) - with z < 0 the ocean depth - - The "efold" s the efolding depth of the long and short - visable and ultra violet light. - efold will vary between 30 m in oligotrophic waters and 4 m in coastal - regions. - - If the thickness of the first ocean level "dzt(1)" is 50 meters, - then shortwave penetration does not do much. However, for finer - vertical resolution, such as dzt(1) = 10 meters commonly used - in ocean climate models, the effect of shortwave heating can - be significant. This can be particularly noticable in the summer - hemisphere. - -
-
-
-
-NAMELIST
- --&ocean_shortwave_csiro_nml --
-
----
-- -use_this_module= -
-- Must be .true. to run with module. Default is false. -
-
-[logical] -- -read_depth -
-- If .true. then read in e folding depth for radiation attenuation. -
-
-[logical] -- -sw_frac_top -
-- The fraction of shortwave radiation that should be incorporated into - the sw_source array at k=1. The generic treatment in MOM is to assume - that shortwave radiation is already contained inside the - T_prog(index_temp)%stf field. Hence, to avoid - double counting, sw_frac(k=0)=sw_frac_top should=0.0. - If one removes shortwave from stf, then set sw_frac_top=1.0. -
-
-[real] -- -zmax_pen -
-- Maximum depth of penetration of shortwave radiation. - Below this depth, shortwave penetration is exponentially - small and so is ignored. -
-
-[real, units: meter] -- -depth_default -
-- Default efolding depth = 20m. -
-
-[real, units: mg/m^3] -- -enforce_sw_frac -
-- To ensure the shortwave fraction is monotonically decreasing with depth. -
-
-[logical] -- -sw_pen_fixed_depths -
-- To compute penetration assuming fixed depths via Grd%zw(k) depths. - This is strictly incorrect when have undulating free surface or - generatlized vertical coordinates. This option is here for purposes - of legacy, as this was done in MOM4.0 versions. The default is .false. -
-
-[logical] -- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Jerlov (1968) - Optical Oceanography - Elsevier Press -
-- - Morel and Antoine (1994) - Heating rate in the upper ocean in relation to its bio-optical state - Journal of Physical Oceanography vol 24 pages 1652-1664 -
-- - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 -
-- - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_csiro.xml b/src/mom5/ocean_param/sources/ocean_shortwave_csiro.xml deleted file mode 100644 index 8764292009..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave_csiro.xml +++ /dev/null @@ -1,104 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.F90 b/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.F90 index bc00e1439e..b9f314cdd1 100644 --- a/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.F90 +++ b/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.F90 @@ -214,8 +214,8 @@ module ocean_shortwave_gfdl_mod type(ocean_domain_type), pointer :: Dom => NULL() type(ocean_grid_type), pointer :: Grd => NULL() -character(len=128) :: version='$Id: ocean_shortwave_gfdl.F90,v 1.1.2.3 2012/06/01 20:47:08 Stephen.Griffies Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version='$Id: ocean_shortwave_gfdl.F90,v 20.0 2013/12/14 00:16:18 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' character(len=48), parameter :: mod_name = 'ocean_shortwave_gfdl_mod' public ocean_shortwave_gfdl_init diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.html b/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.html deleted file mode 100644 index a2666ec2c5..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.html +++ /dev/null @@ -1,440 +0,0 @@ - - - - Russell Fiedler - S.M. Griffies - Alexander Pletzer - - This module returns thickness and density weighted temperature - tendency [kg/m^3 * deg C *m/sec] from penetrative shortwave heating. - - Compute thickness and density weighted tendency [deg C *m/sec *kg/m^3] - of temperature associated with penetrative shortwave heating in the upper - ocean. Generally penetration is taken as a function of monthly optical - properties of the upper ocean, where optical properties are read - in from a file of climatological data. - - This module ussumes a simple single exponential decay law. The e-folding - depth may vary spatially and temporaly. This routine is commonly - used by researchers at CSIRO Marine and Atmospheric Research in - Australia. It has been optimized for vector peformance in - June 2003 on the Australian NEC computer. - - Jerlov (1968) - Optical Oceanography - Elsevier Press - - Morel and Antoine (1994) - Heating rate in the upper ocean in relation to its bio-optical state - Journal of Physical Oceanography vol 24 pages 1652-1664 - - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 - - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. - - Must be .true. to run with module. Default is false. - - If .true. then read in e folding depth for radiation attenuation. - - The fraction of shortwave radiation that should be incorporated into - the sw_source array at k=1. The generic treatment in MOM is to assume - that shortwave radiation is already contained inside the - T_prog(index_temp)%stf field. Hence, to avoid - double counting, sw_frac(k=0)=sw_frac_top should=0.0. - If one removes shortwave from stf, then set sw_frac_top=1.0. - - Maximum depth of penetration of shortwave radiation. - Below this depth, shortwave penetration is exponentially - small and so is ignored. - - Default efolding depth = 20m. - - To ensure the shortwave fraction is monotonically decreasing with depth. - - To compute penetration assuming fixed depths via Grd%zw(k) depths. - This is strictly incorrect when have undulating free surface or - generatlized vertical coordinates. This option is here for purposes - of legacy, as this was done in MOM4.0 versions. The default is .false. - - For debugging purposes. - - Initialization for the shortwave module - - Add short wave penetrative heating to T_prog(index_temp)%th_tendency. - - Note that the divergence of shortwave for the first - level "div_sw(0)" is compensating for the effect of having - the shortwave component already included in the total - surface tracer flux "stf(i,j,temp)" - - - Absorbtion of shortwave radiation in the water assumes energy partitions - represented by a single exponential: - - The exponentialsrepresents a parameterization of the - attenuation coefficient for light between 300 um and 750 um in the following - form: - - E(z) = E(0) * exp(z/efold)) - with z < 0 the ocean depth - - The "efold" s the efolding depth of the long and short - visable and ultra violet light. - efold will vary between 30 m in oligotrophic waters and 4 m in coastal - regions. - - If the thickness of the first ocean level "dzt(1)" is 50 meters, - then shortwave penetration does not do much. However, for finer - vertical resolution, such as dzt(1) = 10 meters commonly used - in ocean climate models, the effect of shortwave heating can - be significant. This can be particularly noticable in the summer - hemisphere. - - - The terms contributing to sw_fk(i,j) are depth independent - - Simpson and Dickey (1981) and others have argued between one and - two exponentials for light between 300 um and 750 um. - With vertical grid resolution of 5 meters or finer - for the upper 20 meters, a second exponential will make a difference. - Module ocean_shortwave_gfdl_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_shortwave_gfdl_mod
- - --Contact: A. Rosati -, - John P. Dunne -, - S. M. Griffies - -- - -
-Reviewers: Russell Fiedler - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module returns thickness weighted and density weighted - temperature tendency [deg C *m/sec *kg/m^3] from penetrative - shortwave heating. -
- - - -- Compute thickness and density weighted tendency [deg C *m/sec *kg/m^3] - of temperature associated with penetrative shortwave heating in the upper - ocean. Generally penetration is taken as a function of monthly optical - properties of the upper ocean, where optical properties are read - in from a file of climatological data or from an ecosystem model. - - Presently there is account taken only of chlorophyll-a on the optical - properties of ocean water. Other particulates can be added so to - have a more complete picture of the ocean optical properties. - --
- - -
-OTHER MODULES USED
- --- - - -axis_utils_mod-
constants_mod
diag_manager_mod
field_manager_mod
fms_mod
mpp_mod
time_interp_external_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_shortwave_gfdl_init:
- -- -sw_source_gfdl:
- -- -sw_morel:
- -- -sw_morel_mom4p0:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_shortwave_gfdl_init
--
-- -DESCRIPTION -
-- - Initialization for the shorwave module -
-
-
-- - -
-sw_source_gfdl
--
-- -DESCRIPTION -
-- - Add short wave penetrative heating to T_prog(index_temp)%th_tendency. - - Note that the divergence of shortwave for the first - level "div_sw(0)" is compensating for the effect of having - the shortwave component already included in the total - surface tracer flux "stf(i,j,temp)" - - If the shortwave penetration routine is activated but Chlorophyll - is not being read from data, then that implies that an ecological - model is being used to determine chlorophyll concentration. - In this case, the shortwave penetration is calcualted using the - algorithm of - - Manizza, M., C Le Quere, A. J. Watson, and E. T. Buitenhuis (2005) - Bio-optical feedbacks among phytoplankton, upper ocean physics and - sea-ice in a global model. Geophys. Res. Let. 32, L05603, - doi:10.1029/2004GL020778. - - This algorithm assumes that all infrared light is absorbed in the - top level. It separates visible light into equal portions of - red and blue bands, treating separately absorption by water and - chlorophyll. - - If the Chlorophyll is read from data, then we generally use the - Morel and Antoine optics scheme. Here, we take their approach - for computing a vertical profile based on the surface Chlorophyll. - However, one may also wish to use the Manizza scheme with - surface Chlorophyll data. In this case, we assume the surface - Chlorophyll concentration is the same throughout the depth. - This assumption is not generally good, but it does provide - for a simple means of using Manizza etal scheme with Chlorophyll - data. Note that GFDL scientists prefer Manizza etal for use with - prognostic 3d models. - - NOTE: Determine depths to T-points and W-points. - This code is needed in particular for GEOPOTENTIAL, since - depth_zwt and depth_zt for this coordinate do not include - the surface height undulations. For the shortwave calculation, - we wish to include the depth level undulations, unless enable - sw_morel_fixed_depths=.true. - -
-
-
-- - -
-sw_morel
--
-- -DESCRIPTION -
-- - Solar shortwave energy penetrates below the ocean surface and is aborbed - by water and organic matter (both particulate and dissolved). This - routine estimates fraction of shortwave penetration using chlorophyll-a. - Absorbtion of shortwave radiation in the water assumes energy partitions - between three exponentials: - - The first exponential is for wavelength > 0.75 um (microns) and assumes a - single attenuation of 0.267 m if the "zenith_angle" is 0. Presently the - code assumes a zero zenith angle, but this could be modified easily. - - The second and third exponentials represent a parameterization of the - attenuation coeficient for light between 300 um and 750 um in the following - form: - - E(z) = E(0) * [V1 * exp(z/efold1) + V2 * exp(z/efold2)] - with z < 0 the ocean depth - - Here, V1+V2=1 represent the partitioning between long (V1) and short (V2) - wavelengths between 300 um and 750 um. Thoughout most of the ocean V1<0.5 - and V2>0.5. The "efold1" and "efold2" are the efolding depth of the long and short - visable and ultra violet light. Throughout most of the ocean efold1 should not exceed 3 m - while the efold2 will vary between 30 m in oligotrophic waters and 4 m in coastal - regions. All of these constants are based on satellite estimates of chlorophyll a and - taken from Morel and Antoine (JPO 1994, (24) 1652-1664). - - If the thickness of the first ocean level "dzt(1)" is 50 meters, - then shortwave penetration does not do much. However, for higher - vertical resolution, such as dzt(1) = 10 meters commonly used - in ocean climate models, the effect of shortwave heating can - be significant. This can be particularly noticable in the summer - hemisphere. - -
-
-
-- - -
-sw_morel_mom4p0
--
-- -DESCRIPTION -
-- - As in sw_morel, but uses the MOM4.0 algorithm to re-compute a k-level. - The recomputation is not needed, it can be costly, and produces - no physically significant differences. This routine is - retained for legacy only and it is not otherwise recommended. -
-
-
-
-NAMELIST
- --&ocean_shortwave_gfdl_nml --
-
----
-- -use_this_module -
-- Must be .true. to run with module. Default is false. -
-
-[logical] -- -use_sw_morel_mom4p0 -
-- For backward compatibility with older simulations using - MOM4.0. The new subroutine removes some confusing and unnecessary - logic to recompute a vertical k-index. The differences - between the old and new approach are nonzero and so will - result in bitwise changes to the simulation, but these changes - are deemed to be trivial. Default use_sw_morel_mom4p0=.false. -
-
-[logical] -- -read_chl -
-- If .true. then read in climatological data of chlorophyll-a. -
-
-[logical] -- -optics_morel_antoine -
-- For using the Morel and Antoine optics. This was the default in - MOM4.0 for use with chlorophyll data. This scheme is NOT available - in MOM4p1 for use with the prognostic biology models, since it has - been improved by the Manizza scheme. - Default optics_morel_antoine=.false. -
-
-[logical] -- -optics_manizza -
-- For using the Manizza optics with chlorophyll data. Note that - when running with a prognostic biology model, GFDL scientists use the - Manizza optics. - Default optics_manizza=.false. -
-
-[logical] -- -sw_frac_top -
-- The fraction of shortwave radiation that should be incorporated into - the sw_source array at k=1. The generic treatment in MOM is to assume - that shortwave radiation is already contained inside the - T_prog(index_temp)%stf field. Hence, to avoid - double counting, sw_frac(k=0)=sw_frac_top should=0.0. - If one removes shortwave from stf, then set sw_frac_top=1.0. -
-
-[real] -- -zmax_pen -
-- Maximum depth of penetration of shortwave radiation. - Below this depth, shortwave penetration is exponentially - small and so is ignored. This option formerly was useful, - since computation of exponentials expensive. But with more - modern computers, exponentials are cheap, so the default - has been changed from 200 to 1e6, making this option irrelevant. - But the option remains both for legacy purposes, and for those - computers where exponentials are not cheap. - Default zmax_pen=1e6. -
-
-[real, units: meter] -- -chl_default -
-- Default concentration chl_default=0.08 roughly yields Jerlov Type 1A optics. -
-
-[real, units: mg/m^3] -- -enforce_sw_frac -
-- To ensure the shortwave fraction is monotonically decreasing with depth. - Applied only if optics_morel=.true. - Default enforce_sw_frac=.true. -
-
-[logical] -- -sw_morel_fixed_depths -
-- To compute penetration assuming fixed depths via Grd%zw(k) depths. - This is strictly incorrect when have undulating free surface and/or - generatlized vertical coordinates. This option is here for purposes - of legacy, as this was done in MOM4.0 versions. The default is - sw_morel_fixed_depths=.false. -
-
-[logical] -- -override_f_vis -
-- To fix the fraction of incoming shortwave assigned to the visible at 0.57. -
-
-[logical] -- -optics_for_uniform_chl -
-- To set the coefficients for optical model assuming the chlorophyll - has a uniform distribution. - Default optics_for_uniform_chl=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Jerlov (1968): Optical Oceanography, Elsevier Press -
-- - Morel and Antoine (1994), Heating rate in the upper ocean - in relation to its bio-optical state. - Journal of Physical Oceanography vol 24 pages 1652-1664 -
-- - Manizza, M., C Le Quere, A. J. Watson, and E. T. Buitenhuis (2005) - Bio-optical feedbacks among phytoplankton, upper ocean physics and - sea-ice in a global model. Geophys. Res. Let. 32, L05603, - doi:10.1029/2004GL020778 -
-- - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 -
-- - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. -
-
- - -
-NOTES
- -- Optimized for vector peformance by R. Fiedler (russell.fiedler@csiro.au) - June 2003 on the Australian NEC computer. --
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.xml b/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.xml deleted file mode 100644 index 6141709275..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave_gfdl.xml +++ /dev/null @@ -1,197 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.F90 b/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.F90 index c9522449ea..ac225422eb 100644 --- a/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.F90 +++ b/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.F90 @@ -190,8 +190,8 @@ module ocean_shortwave_jerlov_mod type(ocean_domain_type), pointer :: Dom => NULL() type(ocean_grid_type), pointer :: Grd => NULL() -character(len=128) :: version='$Id: ocean_shortwave_jerlov.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version='$Id: ocean_shortwave_jerlov.F90,v 20.0 2013/12/14 00:16:20 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' character(len=48), parameter :: mod_name = 'ocean_shortwave_jerlov_mod' real :: rpart, rscl1, rscl2, rscl_ir diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.html b/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.html deleted file mode 100644 index 5172f067fb..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - A. Rosati - John P. Dunne - S. M. Griffies - Russell Fiedler - - This module returns thickness weighted and density weighted - temperature tendency [deg C *m/sec *kg/m^3] from penetrative - shortwave heating. - - Compute thickness and density weighted tendency [deg C *m/sec *kg/m^3] - of temperature associated with penetrative shortwave heating in the upper - ocean. Generally penetration is taken as a function of monthly optical - properties of the upper ocean, where optical properties are read - in from a file of climatological data or from an ecosystem model. - - Presently there is account taken only of chlorophyll-a on the optical - properties of ocean water. Other particulates can be added so to - have a more complete picture of the ocean optical properties. - - - Jerlov (1968): Optical Oceanography, Elsevier Press - - Morel and Antoine (1994), Heating rate in the upper ocean - in relation to its bio-optical state. - Journal of Physical Oceanography vol 24 pages 1652-1664 - - Manizza, M., C Le Quere, A. J. Watson, and E. T. Buitenhuis (2005) - Bio-optical feedbacks among phytoplankton, upper ocean physics and - sea-ice in a global model. Geophys. Res. Let. 32, L05603, - doi:10.1029/2004GL020778 - - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 - - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. - - Optimized for vector peformance by R. Fiedler (russell.fiedler@csiro.au) - June 2003 on the Australian NEC computer. - - Must be .true. to run with module. Default is false. - - For backward compatibility with older simulations using - MOM4.0. The new subroutine removes some confusing and unnecessary - logic to recompute a vertical k-index. The differences - between the old and new approach are nonzero and so will - result in bitwise changes to the simulation, but these changes - are deemed to be trivial. Default use_sw_morel_mom4p0=.false. - - If .true. then read in climatological data of chlorophyll-a. - - For using the Morel and Antoine optics. This was the default in - MOM4.0 for use with chlorophyll data. This scheme is NOT available - in MOM4p1 for use with the prognostic biology models, since it has - been improved by the Manizza scheme. - Default optics_morel_antoine=.false. - - For using the Manizza optics with chlorophyll data. Note that - when running with a prognostic biology model, GFDL scientists use the - Manizza optics. - Default optics_manizza=.false. - - The fraction of shortwave radiation that should be incorporated into - the sw_source array at k=1. The generic treatment in MOM is to assume - that shortwave radiation is already contained inside the - T_prog(index_temp)%stf field. Hence, to avoid - double counting, sw_frac(k=0)=sw_frac_top should=0.0. - If one removes shortwave from stf, then set sw_frac_top=1.0. - - Maximum depth of penetration of shortwave radiation. - Below this depth, shortwave penetration is exponentially - small and so is ignored. This option formerly was useful, - since computation of exponentials expensive. But with more - modern computers, exponentials are cheap, so the default - has been changed from 200 to 1e6, making this option irrelevant. - But the option remains both for legacy purposes, and for those - computers where exponentials are not cheap. - Default zmax_pen=1e6. - - Default concentration chl_default=0.08 roughly yields Jerlov Type 1A optics. - - To ensure the shortwave fraction is monotonically decreasing with depth. - Applied only if optics_morel=.true. - Default enforce_sw_frac=.true. - - To compute penetration assuming fixed depths via Grd%zw(k) depths. - This is strictly incorrect when have undulating free surface and/or - generatlized vertical coordinates. This option is here for purposes - of legacy, as this was done in MOM4.0 versions. The default is - sw_morel_fixed_depths=.false. - - To fix the fraction of incoming shortwave assigned to the visible at 0.57. - - To set the coefficients for optical model assuming the chlorophyll - has a uniform distribution. - Default optics_for_uniform_chl=.false. - - For debugging purposes. - - Initialization for the shorwave module - - Add short wave penetrative heating to T_prog(index_temp)%th_tendency. - - Note that the divergence of shortwave for the first - level "div_sw(0)" is compensating for the effect of having - the shortwave component already included in the total - surface tracer flux "stf(i,j,temp)" - - If the shortwave penetration routine is activated but Chlorophyll - is not being read from data, then that implies that an ecological - model is being used to determine chlorophyll concentration. - In this case, the shortwave penetration is calcualted using the - algorithm of - - Manizza, M., C Le Quere, A. J. Watson, and E. T. Buitenhuis (2005) - Bio-optical feedbacks among phytoplankton, upper ocean physics and - sea-ice in a global model. Geophys. Res. Let. 32, L05603, - doi:10.1029/2004GL020778. - - This algorithm assumes that all infrared light is absorbed in the - top level. It separates visible light into equal portions of - red and blue bands, treating separately absorption by water and - chlorophyll. - - If the Chlorophyll is read from data, then we generally use the - Morel and Antoine optics scheme. Here, we take their approach - for computing a vertical profile based on the surface Chlorophyll. - However, one may also wish to use the Manizza scheme with - surface Chlorophyll data. In this case, we assume the surface - Chlorophyll concentration is the same throughout the depth. - This assumption is not generally good, but it does provide - for a simple means of using Manizza etal scheme with Chlorophyll - data. Note that GFDL scientists prefer Manizza etal for use with - prognostic 3d models. - - NOTE: Determine depths to T-points and W-points. - This code is needed in particular for GEOPOTENTIAL, since - depth_zwt and depth_zt for this coordinate do not include - the surface height undulations. For the shortwave calculation, - we wish to include the depth level undulations, unless enable - sw_morel_fixed_depths=.true. - - - Solar shortwave energy penetrates below the ocean surface and is aborbed - by water and organic matter (both particulate and dissolved). This - routine estimates fraction of shortwave penetration using chlorophyll-a. - Absorbtion of shortwave radiation in the water assumes energy partitions - between three exponentials: - - The first exponential is for wavelength > 0.75 um (microns) and assumes a - single attenuation of 0.267 m if the "zenith_angle" is 0. Presently the - code assumes a zero zenith angle, but this could be modified easily. - - The second and third exponentials represent a parameterization of the - attenuation coeficient for light between 300 um and 750 um in the following - form: - - E(z) = E(0) * [V1 * exp(z/efold1) + V2 * exp(z/efold2)] - with z < 0 the ocean depth - - Here, V1+V2=1 represent the partitioning between long (V1) and short (V2) - wavelengths between 300 um and 750 um. Thoughout most of the ocean V1<0.5 - and V2>0.5. The "efold1" and "efold2" are the efolding depth of the long and short - visable and ultra violet light. Throughout most of the ocean efold1 should not exceed 3 m - while the efold2 will vary between 30 m in oligotrophic waters and 4 m in coastal - regions. All of these constants are based on satellite estimates of chlorophyll a and - taken from Morel and Antoine (JPO 1994, (24) 1652-1664). - - If the thickness of the first ocean level "dzt(1)" is 50 meters, - then shortwave penetration does not do much. However, for higher - vertical resolution, such as dzt(1) = 10 meters commonly used - in ocean climate models, the effect of shortwave heating can - be significant. This can be particularly noticable in the summer - hemisphere. - - - The terms contributing to sw_fk(i,j) are depth independent - when chl is depth independent. However, we anticipate implementing - a biological model, whereby chl will be depth dependent. - - Simpson and Dickey (1981) and others have argued between one and - two exponentials for light between 300 um and 750 um. - With vertical grid resolution of 5 meters or finer - for the upper 20 meters, the second exponential will make a difference. - We anticipate using such resolutions, and so have implemented both - exponentials. - - As in sw_morel, but uses the MOM4.0 algorithm to re-compute a k-level. - The recomputation is not needed, it can be costly, and produces - no physically significant differences. This routine is - retained for legacy only and it is not otherwise recommended. - Module ocean_shortwave_jerlov_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_shortwave_jerlov_mod
- - - - - -
-OVERVIEW
- -- This module returns thickness and density weighted temperature - tendency [kg/m^3 * deg C *m/sec] from penetrative shortwave heating. -
- - - -- Compute thickness and density weighted tendency [deg C *m/sec *kg/m^3] - of temperature associated with penetrative shortwave heating in the upper - ocean. - - This module ussumes a simple double exponential decay law. The e-folding - depth may vary spatially and temporaly. - - The exponentials represents a parameterization of the - attenuation coefficient for light between 300 um and 750 um in the following - form: - - E(z) = E(0) * (r1*exp(-z/efold1) + (1-r1)*exp(-z/efold2)) - with z > 0 the ocean depth - - The "efold" is the efolding depth of the long and short - visable and ultra violet light. - efold will vary between 30 m in oligotrophic waters and 4 m in coastal - regions. - - If the thickness of the first ocean level "dzt(1)" is 50 meters, - then shortwave penetration does not do much. However, for finer - vertical resolution, such as dzt(1) = 10 meters commonly used - in ocean climate models, the effect of shortwave heating can - be significant. This can be particularly noticable in the summer - hemisphere. - - Radiation at the bottom is set to zero, hence the remaining radiation - at the bottom of the deepest ocean cells is totally absorbed - by these cells. This implies, that partial cells need not to - be considered explicitly. Radiation at tracer depth within these - cells is not set to zero. This differs from - ocean_shortwave_gfdl and ocean_shortwave_csiro and reduces slightly the - bouyancy forcing to the mixing layer in the kpp-scheme, if surface mixing - goes down to the bottom. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_mod
time_interp_external_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_shortwave_jerlov_init:
- -- -sw_source_jerlov:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_shortwave_jerlov_init
--
-- -DESCRIPTION -
-- - Initialization for the shortwave module -
-
-
-- - -
-sw_source_jerlov
--
-- -DESCRIPTION -
-- - Add short wave penetrative heating to T_prog(index_temp)%th_tendency. - - Note that the divergence of shortwave for the first - level "div_sw(0)" is compensating for the effect of having - the shortwave component already included in the total - surface tracer flux "stf(i,j,temp)" - -
-
-
-
-NAMELIST
- --&ocean_shortwave_jerlov_nml --
-
----
-- -use_this_module= -
-- Must be .true. to run with module. Default is false. -
-
-[logical] -- -sw_frac_top -
-- The fraction of shortwave radiation that should be incorporated into - the sw_source array at k=1. The generic treatment in MOM is to assume - that shortwave radiation is already contained inside the - T_prog(index_temp)%stf field. Hence, to avoid - double counting, sw_frac(k=0)=sw_frac_top should=0.0. - If one removes shortwave from stf, then set sw_frac_top=1.0. -
-
-[real] -- -f_vis_in -
-- F_vis is the amount of light in the shortwave versus the long wave. - F_vis=0.54 on sunny days and F_vis=0.60 on cloudy days. With - override_f_vis = .true. F_vis is defined from f_vis_in. - We believe, that this effect is in the first exponential in - Paulson and Simpson (1977). The default is f_vis_in=1., instead of .57 - but it is still possible to define this quantity. -
-
-[real] -- -rpart_in -
-- rpart_in = (0..1) -
-
-[real] -- -coef1_in -
-- -
-
-[real, units: meter] -- -coef2_in -
-- -
-
-[real, units: meter] -- -override_coeff -
-- With override_coeff = .true. rpart_in, coef1_in, coef2_in specify - the parameters for the double exponential. The default is .false.. -
-
-[logical] -- -override_f_vis -
-- With override_f_vis = .true. F_vis is defined from f_vis_in, - otherwise it is the shortwave versus the long wave amount of light. - The default is .true. -
-
-[logical] -- -zmax_pen -
-- Maximum depth of penetration of shortwave radiation. - Below this depth, shortwave penetration is exponentially - small and so is ignored. -
-
-[real, units: meter] -- -baltic_optics, jerlov_1, jerlov_2, jerlov_3, jerlov_1a, jerlov_1b -
-- Logical switch to select a watertype. Default=.false.. The model stops, if none is selected - and override_coeff=.false.. -
-
-[logical] -- -enforce_sw_frac -
-- To ensure the shortwave fraction is monotonically decreasing with depth. -
-
-[logical] -- -sw_pen_fixed_depths -
-- To compute penetration assuming fixed depths via Grd%zw(k) depths. - This is strictly incorrect when have undulating free surface or - generatlized vertical coordinates. This option is here for purposes - of legacy, as this was done in MOM4.0 versions. It saves some compute time - if the surface elevation is small compared with the upper cells' thickness. - The default is .false. -
-
-[logical] -- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Jerlov (1968) - Optical Oceanography - Elsevier Press -
-- - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 -
-- - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. -
-
- - -
-NOTES
- -- The efolding depth is depth independent. --
-
- Simpson and Dickey (1981) and others have argued between one and - two exponentials for light between 300 um and 750 um. - With vertical grid resolution of 5 meters or finer - for the upper 20 meters, a second exponential will make a difference. -
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.xml b/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.xml deleted file mode 100644 index 665a398cd0..0000000000 --- a/src/mom5/ocean_param/sources/ocean_shortwave_jerlov.xml +++ /dev/null @@ -1,119 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_sponges_eta.F90 b/src/mom5/ocean_param/sources/ocean_sponges_eta.F90 index 5f0ea0e5a6..6b9f1162f2 100644 --- a/src/mom5/ocean_param/sources/ocean_sponges_eta.F90 +++ b/src/mom5/ocean_param/sources/ocean_sponges_eta.F90 @@ -82,8 +82,8 @@ module ocean_sponges_eta_mod public ocean_sponges_eta_init public sponge_eta_source -character(len=126) :: version = '$Id: ocean_sponges_eta.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=126) :: version = '$Id: ocean_sponges_eta.F90,v 20.0 2013/12/14 00:16:22 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! for diagnostics logical :: used diff --git a/src/mom5/ocean_param/sources/ocean_sponges_eta.html b/src/mom5/ocean_param/sources/ocean_sponges_eta.html deleted file mode 100644 index 8350f9fcf9..0000000000 --- a/src/mom5/ocean_param/sources/ocean_sponges_eta.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - Martin Schmidt - S.M. Griffies - - This module returns thickness and density weighted temperature - tendency [kg/m^3 * deg C *m/sec] from penetrative shortwave heating. - - Compute thickness and density weighted tendency [deg C *m/sec *kg/m^3] - of temperature associated with penetrative shortwave heating in the upper - ocean. - - This module ussumes a simple double exponential decay law. The e-folding - depth may vary spatially and temporaly. - - The exponentials represents a parameterization of the - attenuation coefficient for light between 300 um and 750 um in the following - form: - - E(z) = E(0) * (r1*exp(-z/efold1) + (1-r1)*exp(-z/efold2)) - with z > 0 the ocean depth - - The "efold" is the efolding depth of the long and short - visable and ultra violet light. - efold will vary between 30 m in oligotrophic waters and 4 m in coastal - regions. - - If the thickness of the first ocean level "dzt(1)" is 50 meters, - then shortwave penetration does not do much. However, for finer - vertical resolution, such as dzt(1) = 10 meters commonly used - in ocean climate models, the effect of shortwave heating can - be significant. This can be particularly noticable in the summer - hemisphere. - - Radiation at the bottom is set to zero, hence the remaining radiation - at the bottom of the deepest ocean cells is totally absorbed - by these cells. This implies, that partial cells need not to - be considered explicitly. Radiation at tracer depth within these - cells is not set to zero. This differs from - ocean_shortwave_gfdl and ocean_shortwave_csiro and reduces slightly the - bouyancy forcing to the mixing layer in the kpp-scheme, if surface mixing - goes down to the bottom. - - - The efolding depth is depth independent. - - Simpson and Dickey (1981) and others have argued between one and - two exponentials for light between 300 um and 750 um. - With vertical grid resolution of 5 meters or finer - for the upper 20 meters, a second exponential will make a difference. - - Jerlov (1968) - Optical Oceanography - Elsevier Press - - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 - - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. - - Must be .true. to run with module. Default is false. - - The fraction of shortwave radiation that should be incorporated into - the sw_source array at k=1. The generic treatment in MOM is to assume - that shortwave radiation is already contained inside the - T_prog(index_temp)%stf field. Hence, to avoid - double counting, sw_frac(k=0)=sw_frac_top should=0.0. - If one removes shortwave from stf, then set sw_frac_top=1.0. - - F_vis is the amount of light in the shortwave versus the long wave. - F_vis=0.54 on sunny days and F_vis=0.60 on cloudy days. With - override_f_vis = .true. F_vis is defined from f_vis_in. - We believe, that this effect is in the first exponential in - Paulson and Simpson (1977). The default is f_vis_in=1., instead of .57 - but it is still possible to define this quantity. - - rpart_in = (0..1) - - - - With override_coeff = .true. rpart_in, coef1_in, coef2_in specify - the parameters for the double exponential. The default is .false.. - - With override_f_vis = .true. F_vis is defined from f_vis_in, - otherwise it is the shortwave versus the long wave amount of light. - The default is .true. - - Maximum depth of penetration of shortwave radiation. - Below this depth, shortwave penetration is exponentially - small and so is ignored. - - Logical switch to select a watertype. Default=.false.. The model stops, if none is selected - and override_coeff=.false.. - - To ensure the shortwave fraction is monotonically decreasing with depth. - - To compute penetration assuming fixed depths via Grd%zw(k) depths. - This is strictly incorrect when have undulating free surface or - generatlized vertical coordinates. This option is here for purposes - of legacy, as this was done in MOM4.0 versions. It saves some compute time - if the surface elevation is small compared with the upper cells' thickness. - The default is .false. - - For debugging purposes. - - Initialization for the shortwave module - - Add short wave penetrative heating to T_prog(index_temp)%th_tendency. - - Note that the divergence of shortwave for the first - level "div_sw(0)" is compensating for the effect of having - the shortwave component already included in the total - surface tracer flux "stf(i,j,temp)" - - Module ocean_sponges_eta_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_sponges_eta_mod
- - - - - -
-OVERVIEW
- -- Weighted eta tendency [meter*meter/sec] from sponges. -
- - - -- - This module applies sponge to eta. The sponges - can occur at any location and with any distribution in the domain, and - with any time step and damping rate. Sponges occur where positive - inverse restore times occur in the field passed to sponge_init. An - array of eta tendencies due to the sponges is augmented through a - call to sponge_eta_source. The array of eta tendencies must be - reset to zero between calls. - - Different damping rates can be specified by making - calls to register_sponge_rate - no sponges are applied to fields for - which uniformly zero inverse damping rates are set with a call to - register_sponge_rate. The value towards which a field is damped is - set with calls to register_sponge_field; successive calls are used to - set up linear interpolation of this restore rate. - - Sponge data and damping coefficients are 2 dimensional. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the etas are being driven. - --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_sponges_eta_init:
- -- -sponge_eta_source:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_sponges_eta_init
--
-- -DESCRIPTION -
-- - This subroutine is intended to be used to initialize the sponges. - Everything in this subroutine is a user prototype, and should be replacable. -
-
-
-- - -
-sponge_eta_source
--
-- -DESCRIPTION -
-- - This subroutine calculates thickness weighted and density weighted - time tendencies due to damping by sponges or damping through adaptive - restoring. -
-
-
-
-NAMELIST
- --&ocean_sponges_eta_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -damp_coeff_3d -
-- For case when damping coefficients are full 3d field of values. - Default damp_coeff_3d=.false., which means damping coeffs are - 2d horizontal array. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_sponges_eta.xml b/src/mom5/ocean_param/sources/ocean_sponges_eta.xml deleted file mode 100644 index a615ed28c6..0000000000 --- a/src/mom5/ocean_param/sources/ocean_sponges_eta.xml +++ /dev/null @@ -1,42 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_sponges_tracer.F90 b/src/mom5/ocean_param/sources/ocean_sponges_tracer.F90 index e24964a078..9ce6ff315f 100644 --- a/src/mom5/ocean_param/sources/ocean_sponges_tracer.F90 +++ b/src/mom5/ocean_param/sources/ocean_sponges_tracer.F90 @@ -91,8 +91,8 @@ module ocean_sponges_tracer_mod public ocean_sponges_tracer_init public sponge_tracer_source -character(len=126) :: version = '$Id: ocean_sponges_tracer.F90,v 1.1.2.3 2012/06/01 20:47:08 Stephen.Griffies Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=126) :: version = '$Id: ocean_sponges_tracer.F90,v 20.0 2013/12/14 00:16:24 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! for diagnostics logical :: used diff --git a/src/mom5/ocean_param/sources/ocean_sponges_tracer.html b/src/mom5/ocean_param/sources/ocean_sponges_tracer.html deleted file mode 100644 index bd1c39e096..0000000000 --- a/src/mom5/ocean_param/sources/ocean_sponges_tracer.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - Paul Sandery - - Weighted eta tendency [meter*meter/sec] from sponges. - - - This module applies sponge to eta. The sponges - can occur at any location and with any distribution in the domain, and - with any time step and damping rate. Sponges occur where positive - inverse restore times occur in the field passed to sponge_init. An - array of eta tendencies due to the sponges is augmented through a - call to sponge_eta_source. The array of eta tendencies must be - reset to zero between calls. - - Different damping rates can be specified by making - calls to register_sponge_rate - no sponges are applied to fields for - which uniformly zero inverse damping rates are set with a call to - register_sponge_rate. The value towards which a field is damped is - set with calls to register_sponge_field; successive calls are used to - set up linear interpolation of this restore rate. - - Sponge data and damping coefficients are 2 dimensional. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the etas are being driven. - - - For using this module. Default use_this_module=.false. - - For case when damping coefficients are full 3d field of values. - Default damp_coeff_3d=.false., which means damping coeffs are - 2d horizontal array. - - This subroutine is intended to be used to initialize the sponges. - Everything in this subroutine is a user prototype, and should be replacable. - - This subroutine calculates thickness weighted and density weighted - time tendencies due to damping by sponges or damping through adaptive - restoring. - Module ocean_sponges_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_sponges_tracer_mod
- - --Contact: Bonnie Samuels -, - R.W. Hallberg -, - M.J. Harrison -, - P. S. Swathi -, - S. M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Thickness weighted tracer tendency [tracer*meter/sec] from sponges. -
- - - -- This module applies sponges to tracers. The sponges - can occur at any location and with any distribution in the domain, and - with any time step and damping rate. Sponges occur where positive - inverse restore times occur in the field passed to sponge_init. An - array of tracer tendencies due to the sponges is augmented through a - call to sponge_tracer_source. The array of tracer tendencies must be - reset to zero between calls. - - Different damping rates can be specified for each field by making - calls to register_sponge_rate - no sponges are applied to fields for - which uniformly zero inverse damping rates are set with a call to - register_sponge_rate. The value towards which a field is damped is - set with calls to register_sponge_field; successive calls are used to - set up linear interpolation of this restore rate. - - Sponge data and damping coefficients are generally 3 dimensional. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the tracers are being driven. --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_sponges_tracer_init:
- -- -sponge_tracer_source:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_sponges_tracer_init
--
-- -DESCRIPTION -
-- - This subroutine is intended to be used to initialize the tracer sponges. - Everything in this subroutine is a user prototype, and should be replacable. -
-
-
-- - -
-sponge_tracer_source
--
-- -DESCRIPTION -
-- - This subroutine calculates thickness weighted and density weighted - time tendencies of tracers due to damping by sponges. -
-
-
-
-NAMELIST
- --&ocean_sponges_tracer_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -damp_coeff_3d -
-- For case when damping coefficients are full 3d field of values. - Default damp_coeff_3d=.false., which means damping coeffs are - 2d horizontal array. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_sponges_tracer.xml b/src/mom5/ocean_param/sources/ocean_sponges_tracer.xml deleted file mode 100644 index 7c0f7c34b3..0000000000 --- a/src/mom5/ocean_param/sources/ocean_sponges_tracer.xml +++ /dev/null @@ -1,43 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_sponges_velocity.F90 b/src/mom5/ocean_param/sources/ocean_sponges_velocity.F90 index 4bb40c5806..f69b282cd5 100644 --- a/src/mom5/ocean_param/sources/ocean_sponges_velocity.F90 +++ b/src/mom5/ocean_param/sources/ocean_sponges_velocity.F90 @@ -88,8 +88,8 @@ module ocean_sponges_velocity_mod public ocean_sponges_velocity_init public sponge_velocity_source -character(len=126) :: version = '$Id: ocean_sponges_velocity.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=126) :: version = '$Id: ocean_sponges_velocity.F90,v 20.0 2013/12/14 00:16:26 fms Exp $' +character (len=128) :: tagname = '$Name: tikal $' ! for diagnostics logical :: used diff --git a/src/mom5/ocean_param/sources/ocean_sponges_velocity.html b/src/mom5/ocean_param/sources/ocean_sponges_velocity.html deleted file mode 100644 index 6905daa09d..0000000000 --- a/src/mom5/ocean_param/sources/ocean_sponges_velocity.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - Bonnie Samuels - R.W. Hallberg - M.J. Harrison - P. S. Swathi - S. M. Griffies - - Thickness weighted tracer tendency [tracer*meter/sec] from sponges. - - This module applies sponges to tracers. The sponges - can occur at any location and with any distribution in the domain, and - with any time step and damping rate. Sponges occur where positive - inverse restore times occur in the field passed to sponge_init. An - array of tracer tendencies due to the sponges is augmented through a - call to sponge_tracer_source. The array of tracer tendencies must be - reset to zero between calls. - - Different damping rates can be specified for each field by making - calls to register_sponge_rate - no sponges are applied to fields for - which uniformly zero inverse damping rates are set with a call to - register_sponge_rate. The value towards which a field is damped is - set with calls to register_sponge_field; successive calls are used to - set up linear interpolation of this restore rate. - - Sponge data and damping coefficients are generally 3 dimensional. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the tracers are being driven. - - For using this module. Default use_this_module=.false. - - For case when damping coefficients are full 3d field of values. - Default damp_coeff_3d=.false., which means damping coeffs are - 2d horizontal array. - - This subroutine is intended to be used to initialize the tracer sponges. - Everything in this subroutine is a user prototype, and should be replacable. - - This subroutine calculates thickness weighted and density weighted - time tendencies of tracers due to damping by sponges. - Module ocean_sponges_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_sponges_velocity_mod
- - - - - -
-OVERVIEW
- -- Thickness weighted velocity tendency [meter*meter/sec*sec] from sponges. -
- - - -- - This module applies sponges to currents. The sponges - can occur at any location and with any distribution in the domain, and - with any time step and damping rate. Sponges occur where positive - inverse restore times occur in the field passed to sponge_init. An - array of tracer tendencies due to the sponges is augmented through a - call to sponge_tracer_source. The array of tracer tendencies must be - reset to zero between calls. - - Different damping rates can be specified for each field by making - calls to register_sponge_rate - no sponges are applied to fields for - which uniformly zero inverse damping rates are set with a call to - register_sponge_rate. The value towards which a field is damped is - set with calls to register_sponge_field; successive calls are used to - set up linear interpolation of this restore rate. - - Sponge data and damping coefficients are generally 3 dimensional. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the currents are being driven. - --
- - -
-OTHER MODULES USED
- --- - - -diag_manager_mod-
fms_mod
mpp_mod
time_interp_external_mod
time_manager_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_sponges_velocity_init:
- -- -sponge_velocity_source:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_sponges_velocity_init
--
-- -DESCRIPTION -
-- - This subroutine is intended to be used to initialize the sponges. - Everything in this subroutine is a user prototype, and should be replacable. -
-
-
-- - -
-sponge_velocity_source
--
-- -DESCRIPTION -
-- - This subroutine calculates thickness weighted and density weighted - time tendencies due to damping by sponges. -
-
-
-
-NAMELIST
- --&ocean_sponges_velocity_nml --
-
----
-- -use_this_module -
-- For using this module. Default use_this_module=.false. -
-
-[logical] -- -damp_coeff_3d -
-- For case when damping coefficients are full 3d field of values. - Default damp_coeff_3d=.false., which means damping coeffs are - 2d horizontal array. -
-
-[logical] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_sponges_velocity.xml b/src/mom5/ocean_param/sources/ocean_sponges_velocity.xml deleted file mode 100644 index 7e17eed8f1..0000000000 --- a/src/mom5/ocean_param/sources/ocean_sponges_velocity.xml +++ /dev/null @@ -1,41 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_xlandinsert.F90 b/src/mom5/ocean_param/sources/ocean_xlandinsert.F90 index 83ba40f2d8..2b92c87dbc 100644 --- a/src/mom5/ocean_param/sources/ocean_xlandinsert.F90 +++ b/src/mom5/ocean_param/sources/ocean_xlandinsert.F90 @@ -187,9 +187,9 @@ module ocean_xlandinsert_mod integer :: index_salt=-1 character(len=128) :: version=& - '$Id: ocean_xlandinsert.F90,v 1.1.2.1 2012/05/15 16:05:39 smg Exp $' + '$Id: ocean_xlandinsert.F90,v 20.0 2013/12/14 00:16:28 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk integer :: isg, ieg, jsg, jeg diff --git a/src/mom5/ocean_param/sources/ocean_xlandinsert.html b/src/mom5/ocean_param/sources/ocean_xlandinsert.html deleted file mode 100644 index b9135a0b23..0000000000 --- a/src/mom5/ocean_param/sources/ocean_xlandinsert.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - Paul Sandery - - Thickness weighted velocity tendency [meter*meter/sec*sec] from sponges. - - - This module applies sponges to currents. The sponges - can occur at any location and with any distribution in the domain, and - with any time step and damping rate. Sponges occur where positive - inverse restore times occur in the field passed to sponge_init. An - array of tracer tendencies due to the sponges is augmented through a - call to sponge_tracer_source. The array of tracer tendencies must be - reset to zero between calls. - - Different damping rates can be specified for each field by making - calls to register_sponge_rate - no sponges are applied to fields for - which uniformly zero inverse damping rates are set with a call to - register_sponge_rate. The value towards which a field is damped is - set with calls to register_sponge_field; successive calls are used to - set up linear interpolation of this restore rate. - - Sponge data and damping coefficients are generally 3 dimensional. - - The user is responsible for providing (and registering) the data on - the model grid of values towards which the currents are being driven. - - - For using this module. Default use_this_module=.false. - - For case when damping coefficients are full 3d field of values. - Default damp_coeff_3d=.false., which means damping coeffs are - 2d horizontal array. - - This subroutine is intended to be used to initialize the sponges. - Everything in this subroutine is a user prototype, and should be replacable. - - This subroutine calculates thickness weighted and density weighted - time tendencies due to damping by sponges. - Module ocean_xlandinsert_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_xlandinsert_mod
- - --Contact: S.M. Griffies -, - K.W. Dixon - -- - -
-Reviewers: M.J. Harrison - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Tracer and mass source from cross-land insertion. -
- - - -- Compute thickness and density weighted tendency [rho*tracer*meter/sec] - of tracer associated with cross-land insertion. Also compute - mass source from cross-land insertion. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
field_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_xlandinsert_init:
- -- -xlandinsert:
- -- -xlandinsert_mass:
- -- -at_least_one_in_comp_domain:
- -- -on_comp_domain:
- -- -on_processor:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_xlandinsert_init
--
-- -DESCRIPTION -
-- - Initial set up for crossland insertion of tracers and eta - - Checks are performed to ensure that the crossland mixing - grid locations are valid according to model configuration. - - A summary of the locations of crossland points is written out. - - User specified inputs in "USER INPUT" section: - - ixland and jxland = user specified nxland pairs of i,j grid locations - - kxland = user specified uppermost (ktop=kxland(n,1)) and - deepest (kbot=kxland(n,2)) levels over which crossland - will be done for each crossland pair. Note the for - xlandinsert, kxland(nxl,1)=1 is required, since the - aim is to move excess volume from one column to another. - - tauxland = user specified time constant (seconds) setting the rate - of transport via upwind advection. - - NOTE: for ixland, jxland, and kxland pairs, values of the - (n,1) element should be < the corresponding (n,2) value. - -
-
-
-- - -
-xlandinsert
--
-- -DESCRIPTION -
-- - Compute thickness and density weighted tracer source - [(kg/m^3)*tracer*m/s] and mass source (kg/m^3)*(m/s) - associated with discharge of tracer from surface of a - thick column into a set of boxes within a thin column. - - NOTE: - Compute rho_dzt_x as if using a geopotential model, since the - xlandinsert rates are typically first tuned with geopotential models. - also, we wish to have the transport proportional to differences in - eta_t, which for zstar and pstar are generally must larger than - differences in dzt. - - Modified by Keith.Dixon (January 2004) - - Modified by Stephen.Griffies for general - vertical coordinates January 2005 and August 2006. - -
-
-
-- - -
-xlandinsert_mass
--
-- -DESCRIPTION -
-- - Compute the mass source (kg/m^3)*meter/sec. - - Note that xlandinsert has already been called, so xland_rho_dzt - has been filled. -
-
-
-- - -
-at_least_one_in_comp_domain
--
-- -DESCRIPTION -
-- - Function to see if at least one of the two points in a crossland pair - is within the computational domain for the processor. -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular xlandinsert pair - -
[integer]
-- - -
-on_comp_domain
--
-- -DESCRIPTION -
-- - Determine if the point is in comp-domain for the processor -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular xlandinsert pair - -
[integer]- -lx - lx=1,2 labels the point within an xlandinsert pair - -
[integer]
-- - -
-on_processor
--
-- -DESCRIPTION -
-- - Determine if the point is on processor -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from xlandinsert on watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_xlandinsert_nml --
-
----
-- -use_this_module -
-- Needs to be true in order to use this scheme. Default is false. -
-
-[logical] -- -verbose_init -
-- For verbose initialization information. -
-
-[logical] -- -debug_this_module -
-- For debugging. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- - -
-NOTES
- -- Algorithm ensures both total tracer and total mass is conserved. - Algorithm sets up the insertion points as in xlandmix, and - transports between the columns as in rivermix. --
-
- 2D domain decomposition is implemented according to following - notions. If the two points in an xlandinsert pair live within halo - of each other (i.e., within same local_domain), - then no added mpp communication required. However, nore generally - the two points live further away. In this case, xland_domain - is defined so that its halos incorporate the maximum separation - of xlandinsert points. New tracer, eta, and grid arrays - are defined over this extended xland_domain. This added domain - size will come at some computational cost, so it is advantageous - to limit the separation between points within an xlandinsert pair. -
-
- The current implementation of xlandinsert has not been generalized - to allow for communication between points separated by the tripolar fold. - The problem is in the logic used to compute xland_domain. - There is nothing fundamental limiting a generalization of the - logic used to generate xland_domain. -
-
- Many of the user specified values given in USER INPUT are - model dependent since unresolved straits can become resolved - in finer mesh models. -
-
- BUG FIX 30 May 2011. - Trying to mix across the ends of the global domain results in incorrect indexing. - Local indices need to be incremented/decremented by the global extent. - Russell.Fiedler@csiro.au -
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_xlandinsert.xml b/src/mom5/ocean_param/sources/ocean_xlandinsert.xml deleted file mode 100644 index da22b3a7e8..0000000000 --- a/src/mom5/ocean_param/sources/ocean_xlandinsert.xml +++ /dev/null @@ -1,117 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/sources/ocean_xlandmix.F90 b/src/mom5/ocean_param/sources/ocean_xlandmix.F90 index 155983c61e..c70f4e661a 100644 --- a/src/mom5/ocean_param/sources/ocean_xlandmix.F90 +++ b/src/mom5/ocean_param/sources/ocean_xlandmix.F90 @@ -213,9 +213,9 @@ module ocean_xlandmix_mod integer :: index_salt=-1 character(len=128) :: version=& - '$Id: ocean_xlandmix.F90,v 1.1.2.2 2012/05/17 13:41:49 smg Exp $' + '$Id: ocean_xlandmix.F90,v 20.0 2013/12/14 00:16:30 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk integer :: isg, ieg, jsg, jeg diff --git a/src/mom5/ocean_param/sources/ocean_xlandmix.html b/src/mom5/ocean_param/sources/ocean_xlandmix.html deleted file mode 100644 index 0d4152078f..0000000000 --- a/src/mom5/ocean_param/sources/ocean_xlandmix.html +++ /dev/null @@ -1,493 +0,0 @@ - - - - S.M. Griffies - K.W. Dixon - M.J. Harrison - - Tracer and mass source from cross-land insertion. - - Compute thickness and density weighted tendency [rho*tracer*meter/sec] - of tracer associated with cross-land insertion. Also compute - mass source from cross-land insertion. - - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory - - Algorithm ensures both total tracer and total mass is conserved. - Algorithm sets up the insertion points as in xlandmix, and - transports between the columns as in rivermix. - - 2D domain decomposition is implemented according to following - notions. If the two points in an xlandinsert pair live within halo - of each other (i.e., within same local_domain), - then no added mpp communication required. However, nore generally - the two points live further away. In this case, xland_domain - is defined so that its halos incorporate the maximum separation - of xlandinsert points. New tracer, eta, and grid arrays - are defined over this extended xland_domain. This added domain - size will come at some computational cost, so it is advantageous - to limit the separation between points within an xlandinsert pair. - - The current implementation of xlandinsert has not been generalized - to allow for communication between points separated by the tripolar fold. - The problem is in the logic used to compute xland_domain. - There is nothing fundamental limiting a generalization of the - logic used to generate xland_domain. - - Many of the user specified values given in USER INPUT are - model dependent since unresolved straits can become resolved - in finer mesh models. - - BUG FIX 30 May 2011. - Trying to mix across the ends of the global domain results in incorrect indexing. - Local indices need to be incremented/decremented by the global extent. - Russell.Fiedler@csiro.au - - Needs to be true in order to use this scheme. Default is false. - - For verbose initialization information. - - For debugging. - - Initial set up for crossland insertion of tracers and eta - - Checks are performed to ensure that the crossland mixing - grid locations are valid according to model configuration. - - A summary of the locations of crossland points is written out. - - User specified inputs in "USER INPUT" section: - - ixland and jxland = user specified nxland pairs of i,j grid locations - - kxland = user specified uppermost (ktop=kxland(n,1)) and - deepest (kbot=kxland(n,2)) levels over which crossland - will be done for each crossland pair. Note the for - xlandinsert, kxland(nxl,1)=1 is required, since the - aim is to move excess volume from one column to another. - - tauxland = user specified time constant (seconds) setting the rate - of transport via upwind advection. - - NOTE: for ixland, jxland, and kxland pairs, values of the - (n,1) element should be < the corresponding (n,2) value. - - - Compute thickness and density weighted tracer source - [(kg/m^3)*tracer*m/s] and mass source (kg/m^3)*(m/s) - associated with discharge of tracer from surface of a - thick column into a set of boxes within a thin column. - - NOTE: - Compute rho_dzt_x as if using a geopotential model, since the - xlandinsert rates are typically first tuned with geopotential models. - also, we wish to have the transport proportional to differences in - eta_t, which for zstar and pstar are generally must larger than - differences in dzt. - - Modified by Keith.Dixon (January 2004) - - Modified by Stephen.Griffies for general - vertical coordinates January 2005 and August 2006. - - - Compute the mass source (kg/m^3)*meter/sec. - - Note that xlandinsert has already been called, so xland_rho_dzt - has been filled. - - Function to see if at least one of the two points in a crossland pair - is within the computational domain for the processor. - - Integer labeling the particular xlandinsert pair - - Determine if the point is in comp-domain for the processor - - Integer labeling the particular xlandinsert pair - - lx=1,2 labels the point within an xlandinsert pair - - Determine if the point is on processor - - Initialization of watermass diagnostic output files. - - Diagnose effects from xlandinsert on watermass transformation. - Module ocean_xlandmix_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_xlandmix_mod
- - --Contact: S.M. Griffies - -- - -
-Reviewers: M.J. Harrison -, - K. Dixon - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Tracer and mass source from cross-land mixing. -
- - - -- Compute thickness weighted and density weighted tendency - [tracer*(kg/m^3)*meter/sec] of tracer and mass associated with - cross-land mixing of points. - - In particular, this module provides interaction between bodies of - water separated by land in coarse models (e.g., Med-Atlantic). - Interaction consists of mixing tracer and mass between water - columns found on each side of the land barrier. - - To conserve total tracer when using xlandmix with k=1, - also need to connect mass between remote bodies of water - via xlandmix of eta. - - When connecting cells with k>1, we do not mix mass. This - is ensured by making the time tendency only a function of the - difference in tracer concentration. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
field_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_xlandmix_init:
- -- -xlandmix:
- -- -xlandmix_mass:
- -- -xland_check:
- -- -at_least_one_in_comp_domain:
- -- -both_in_local_domain:
- -- -on_comp_domain:
- -- -on_processor:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_xlandmix_init
--
-- -DESCRIPTION -
-- - Initial set up for crossland mixing of tracers - - (i,j,k) locations of crossland mixing points are set via - field table entries. - - Time invariant crossland mixing rates (in units of m**3/sec) are - set via field table entries. - - Checks are performed to ensure that the crossland mixing - grid locations are valid according to model configuration. - - A summary of the locations of crossland mixing points is written out. - - User specified inputs in "USER INPUT" section: - - ixland and jxland = user specified nxland pairs of i,j grid locations - - kxland = user specified uppermost (ktop=kxland(n,1)) and deepest - (kbot=kxland(n,2)) levels over which crossland mixing will - be done for each pair of crossland mixing points. - - vxland = user specified time invariant rates of crossland mixing (m3/sec) - Equivalent to "the flow to the east = the flow to the west" - Dynamic vxland is not available in MOM. - - NOTE: for ixland, jxland, and kxland pairs, values of the - (n,1) element should be < the corresponding (n,2) value. -
-
-
-- - -
-xlandmix
--
-- -DESCRIPTION -
-- - Compute thickness and density weighted time tendency from - xlandmix. Units of the tendency are tracer*(kg/m^3)*meter/sec. - - Logic is a bit tricky in order to allow each (i,j,k) point - to participate in an arbitrary number of xlandmix pairs. - -
-
-
-- - -
-xlandmix_mass
--
-- -DESCRIPTION -
-- - Compute the mass source kg/(m^2*sec). - Note that xlandmix has already been called, so xland_mass has been - filled. -
-
-
-- - -
-xland_check
--
-- -DESCRIPTION -
-- - Check if prescribed too much mixing - - In this routine the crossland mixing rate vxland(nxl) for - the pair of points associated with index number nxl is - converted into the fraction of the model grid boxes to be mixed - per second, and checked. These checks ensure that the rate of - crossland mixing requested is valid in that it can be realized - given the timestep length and column volumes involved. -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular xlandmix pair - -
[integer]
-- -INPUT/OUTPUT -
-- -
--
-- -error - Error flag indicates whether initialization was performed successfully. - -
[logical]
-- - -
-at_least_one_in_comp_domain
--
-- -DESCRIPTION -
-- - Function to see if at least one of the two points in a crossland pair - is within the computational domain for the processor. -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular xlandmix pair - -
[integer]
-- - -
-both_in_local_domain
--
-- -DESCRIPTION -
-- - Determine if both points in a crossland pair are within the - local domain for the processor. -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular xlandmix pair - -
[integer]
-- - -
-on_comp_domain
--
-- -DESCRIPTION -
-- - Determine if the point is in comp-domain for the processor -
-
-
-- -INPUT -
-- -
--
-- -nxl - Integer labeling the particular xlandmix pair - -
[integer]- -lx - lx=1,2 labels the point within an xlandmix pair - -
[integer]
-- - -
-on_processor
--
-- -DESCRIPTION -
-- - Determine if the point is on processor -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from xlandmix on watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_xlandmix_nml --
-
----
-- -use_this_module -
-- Needs to be true in order to use this scheme. Default is false. -
-
-[logical] -- -xlandmix_kmt -
-- To allow xlandmixing to occur at k=kmt cell. - Default is xlandmix_kmt=.false. -
-
-[logical] -- -verbose_init -
-- For verbose initialization information. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) - NOAA/Geophysical Fluid Dynamics Laboratory -
-- - S.M. Griffies: Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
-
- - -
-NOTES
- -- Algorithm ensures both total tracer and total mass is conserved. --
-
- 2D domain decomposition is implemented according to following - notions. If the two points in an xlandmix pair live within halo - of each other (i.e., within same local_domain), - then no added mpp communication required. However, more generally - the two points live further away. In this case, xland_domain - is defined so that its halos incorporate the maximum separation - of xlandmix points. New tracer, eta, and grid arrays - are defined over this extended xland_domain. This added domain - size will come at some computational cost, so it is advantageous - to limit the separation between points within an xlandmix pair. -
-
- The current implementation of xlandmix has not been generalized - to allow for communication between points separated by the tripolar fold. - The problem is in the logic used to compute xland_domain. - There is nothing fundamental limiting a generalization of the - logic used to generate xland_domain. -
-
- Many of the user specified values given in USER INPUT are - model dependent since unresolved straits can become resolved - in finer mesh models. -
-
- Algorithm originally developed by Keith Dixon (Keith.Dixon) - for rigid lid and full cells and one processor (i.e., MOM1). - Algorithm extended to free surface and partial cells and 2D - domain decomposition by S.M.Griffies (Stephen.Griffies). - Further extensions to generalized vertical coordinates by - Stephen.Griffies -
-
- BUG FIX 30 May 2011. - Trying to mix across the ends of the global domain results in incorrect indexing. - Local indices need to be incremented/decremented by the global extent. - Russell.Fiedler@csiro.au -
- -
--top -- - diff --git a/src/mom5/ocean_param/sources/ocean_xlandmix.xml b/src/mom5/ocean_param/sources/ocean_xlandmix.xml deleted file mode 100644 index 33cf44f227..0000000000 --- a/src/mom5/ocean_param/sources/ocean_xlandmix.xml +++ /dev/null @@ -1,150 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_convect.F90 b/src/mom5/ocean_param/vertical/ocean_convect.F90 index f461d26073..9802350eac 100644 --- a/src/mom5/ocean_param/vertical/ocean_convect.F90 +++ b/src/mom5/ocean_param/vertical/ocean_convect.F90 @@ -160,9 +160,9 @@ module ocean_convect_mod integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk character(len=128) :: version=& - '$Id: ocean_convect.F90,v 1.1.2.1 2012/05/15 16:06:17 smg Exp $' + '$Id: ocean_convect.F90,v 20.0 2013/12/14 00:16:32 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized=.FALSE. logical :: use_this_module =.false. diff --git a/src/mom5/ocean_param/vertical/ocean_convect.html b/src/mom5/ocean_param/vertical/ocean_convect.html deleted file mode 100644 index 5f5e8e5738..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_convect.html +++ /dev/null @@ -1,531 +0,0 @@ - - - - S.M. Griffies - M.J. Harrison - K. Dixon - - Tracer and mass source from cross-land mixing. - - Compute thickness weighted and density weighted tendency - [tracer*(kg/m^3)*meter/sec] of tracer and mass associated with - cross-land mixing of points. - - In particular, this module provides interaction between bodies of - water separated by land in coarse models (e.g., Med-Atlantic). - Interaction consists of mixing tracer and mass between water - columns found on each side of the land barrier. - - To conserve total tracer when using xlandmix with k=1, - also need to connect mass between remote bodies of water - via xlandmix of eta. - - When connecting cells with k>1, we do not mix mass. This - is ensured by making the time tendency only a function of the - difference in tracer concentration. - - - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) - NOAA/Geophysical Fluid Dynamics Laboratory - - S.M. Griffies: Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory - - Algorithm ensures both total tracer and total mass is conserved. - - 2D domain decomposition is implemented according to following - notions. If the two points in an xlandmix pair live within halo - of each other (i.e., within same local_domain), - then no added mpp communication required. However, more generally - the two points live further away. In this case, xland_domain - is defined so that its halos incorporate the maximum separation - of xlandmix points. New tracer, eta, and grid arrays - are defined over this extended xland_domain. This added domain - size will come at some computational cost, so it is advantageous - to limit the separation between points within an xlandmix pair. - - The current implementation of xlandmix has not been generalized - to allow for communication between points separated by the tripolar fold. - The problem is in the logic used to compute xland_domain. - There is nothing fundamental limiting a generalization of the - logic used to generate xland_domain. - - Many of the user specified values given in USER INPUT are - model dependent since unresolved straits can become resolved - in finer mesh models. - - Algorithm originally developed by Keith Dixon (Keith.Dixon) - for rigid lid and full cells and one processor (i.e., MOM1). - Algorithm extended to free surface and partial cells and 2D - domain decomposition by S.M.Griffies (Stephen.Griffies). - Further extensions to generalized vertical coordinates by - Stephen.Griffies - - BUG FIX 30 May 2011. - Trying to mix across the ends of the global domain results in incorrect indexing. - Local indices need to be incremented/decremented by the global extent. - Russell.Fiedler@csiro.au - - Needs to be true in order to use this scheme. Default is false. - - To allow xlandmixing to occur at k=kmt cell. - Default is xlandmix_kmt=.false. - - For verbose initialization information. - - Initial set up for crossland mixing of tracers - - (i,j,k) locations of crossland mixing points are set via - field table entries. - - Time invariant crossland mixing rates (in units of m**3/sec) are - set via field table entries. - - Checks are performed to ensure that the crossland mixing - grid locations are valid according to model configuration. - - A summary of the locations of crossland mixing points is written out. - - User specified inputs in "USER INPUT" section: - - ixland and jxland = user specified nxland pairs of i,j grid locations - - kxland = user specified uppermost (ktop=kxland(n,1)) and deepest - (kbot=kxland(n,2)) levels over which crossland mixing will - be done for each pair of crossland mixing points. - - vxland = user specified time invariant rates of crossland mixing (m3/sec) - Equivalent to "the flow to the east = the flow to the west" - Dynamic vxland is not available in MOM. - - NOTE: for ixland, jxland, and kxland pairs, values of the - (n,1) element should be < the corresponding (n,2) value. - - Compute thickness and density weighted time tendency from - xlandmix. Units of the tendency are tracer*(kg/m^3)*meter/sec. - - Logic is a bit tricky in order to allow each (i,j,k) point - to participate in an arbitrary number of xlandmix pairs. - - - Compute the mass source kg/(m^2*sec). - Note that xlandmix has already been called, so xland_mass has been - filled. - - Check if prescribed too much mixing - - In this routine the crossland mixing rate vxland(nxl) for - the pair of points associated with index number nxl is - converted into the fraction of the model grid boxes to be mixed - per second, and checked. These checks ensure that the rate of - crossland mixing requested is valid in that it can be realized - given the timestep length and column volumes involved. - - Integer labeling the particular xlandmix pair - - Error flag indicates whether initialization was performed successfully. - - Function to see if at least one of the two points in a crossland pair - is within the computational domain for the processor. - - Integer labeling the particular xlandmix pair - - Determine if both points in a crossland pair are within the - local domain for the processor. - - Integer labeling the particular xlandmix pair - - Determine if the point is in comp-domain for the processor - - Integer labeling the particular xlandmix pair - - lx=1,2 labels the point within an xlandmix pair - - Determine if the point is on processor - - Initialization of watermass diagnostic output files. - - Diagnose effects from xlandmix on watermass transformation. - Module ocean_convect_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_convect_mod
- - - - - -
-OVERVIEW
- -- Vertically adjusts gravitationally unstable columns of ocean fluid. -
- - - -- This module vertically adjusts gravitationally unstable columns of - ocean fluid. - - Three algorithms are available: - - 1. Full convection from Rahmstorf. The algorithm produces a fully - stable fluid column. Since most convection propagates downward, the - scheme looks downward first and follows any instability (upward or - downward) before checking the other direction. The routine mixes - passive tracers only after the entire instability is found. - - 2. Full convection from Rahmstorf as optimized for vector machines - by Russ Fiedler. - - 3. The Cox (1984) NCON-scheme. This scheme is recommended only - for those wishing to maintain legacy code. - - 4. Legacy (pre TEOS-10) versions now supplied. In TEOS-10 we - need to mix S_prog, fdelta first, and then compute S_A. This - approach is not the same as mixing S_A directly. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_convect_init:
- -- -convection:
- -- -convection_full_scalar:
- -- -convection_full_vector:
- -- -convection_ncon:
- -- -convection_full_scalar_preteos10:
- -- -convection_full_vector_preteos10:
- -- -convection_diag:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_convect_init
--
-- -DESCRIPTION -
-- - - Initialize the convection module. - - For the full convection module, we register two fields - for diagnostic output. -
-
- ktot = number of levels convected in a vertical column -
- kven = number of levels ventilated in a vertical column - - Note that ktot can in rare cases count some levels twice, if they - get involved in two originally separate, but then - overlapping convection areas in the water column. The field - kven is 0 on land, 1 on ocean points with no - convection, and any value up to nk on convecting points. -
-
-- - -
-convection
--
-- -DESCRIPTION -
-- - Subroutine calls one of the two possible convection schemes. -
-
-
-- - -
-convection_full_scalar
--
-- -DESCRIPTION -
-- - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on scalar - machines at GFDL. Has been found to be slow on vector machines. Use - convection_full_vector for vector machines. - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=fdelta, 4=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - - rho_salinity_mx = computed density salinity resulting from mixing of tracers. - -
-
-
-- - -
-convection_full_vector
--
-- -DESCRIPTION -
-- - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on vector - machines at CSIRO. Has been found to be faster on these machines than - convection_full_scalar. Answers differ, but not significantly. - - Code written by russell.fiedler@csiro.au - most recently modified Aug2011 - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - - rho_salinity_mx = computed density salinity resulting from mixing of tracers. - -
-
-
-- - -
-convection_ncon
--
-- -DESCRIPTION -
-- - "ncon" convection scheme - - Convectively adjust water column if gravitationally unstable. - Based on algorithm from Mike Cox used in his code from 1984. - Algorithm has well known problems with incomplete homogenization - and sensitivity to the ncon parameter. - - Coded in mom4 for legacy purposes by Stephen.Griffies - April 2001 - -
-
-
-- - -
-convection_full_scalar_preteos10
--
-- -DESCRIPTION -
-- - - This routine is a legacy version which is consistent with using the old equation of state. - - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on scalar - machines at GFDL. Has been found to be slow on vector machines. Use - convection_full_vector_preteos10 for vector machines. - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - -
-
-
-- - -
-convection_full_vector_preteos10
--
-- -DESCRIPTION -
-- - - This routine is a legacy version which is consistent with using the old equation of state. - - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on vector - machines at CSIRO. Has been found to be faster on these machines than - convection_full_scalar_preteos10. Answers differ, but not significantly. - - Code written by russell.fiedler@csiro.au - most recently modified Aug2011 - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - -
-
-
-- - -
-convection_diag
--
-- -DESCRIPTION -
-- - Some diagnostics for convection. -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from convection of - temp and salt on the watermass transformation diagnostics. - -
-
-
-
-NAMELIST
- --&ocean_convect_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -convect_ncon -
-- If true, will use the old NCON convection scheme from Cox. - Retained only for legacy purposes to reproduce very old results. -
-
-[logical] -- -ncon -
-- Number of passes through the NCON-scheme. -
-
-[integer] -- -convect_full_scalar -
-- If true, will use the full convection scheme as implemented at GFDL for scalar - machines. -
-
-[logical] -- -convect_full_vector -
-- If true, will use the full convection scheme as optimized for vector machines - by russell.fiedler@csiro.au. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Stefan Rahmstorf (Ocean Modelling, 1993 vol 101 pages 9-11) -
-
- - -
-NOTES
- -- Implementation of the full convection scheme is - based on mom2/3 code by Stefan Rahmstorf - (rahmstorf@pik-potsdam.de). But modified slightly - for efficiency purposes in mom3.1 - by M. Eby (eby@uvic.ca) in June 2000. Notably, Eby - eliminated goto statements. --
-
- The Eby code was ported to mom4 by Griffies (Stephen.Griffies). -
-
- To recover the exact same numerical values as the original - Rahmstorf code, look for the two "Rahmstorf" comments in the code. -
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_convect.xml b/src/mom5/ocean_param/vertical/ocean_convect.xml deleted file mode 100644 index 0e478ec667..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_convect.xml +++ /dev/null @@ -1,238 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_form_drag.F90 b/src/mom5/ocean_param/vertical/ocean_form_drag.F90 index 33be8594e5..0a571a7ca7 100644 --- a/src/mom5/ocean_param/vertical/ocean_form_drag.F90 +++ b/src/mom5/ocean_param/vertical/ocean_form_drag.F90 @@ -258,9 +258,9 @@ module ocean_form_drag_mod character(len=128) :: version=& - '$Id: ocean_form_drag.F90,v 1.1.2.2 2012/05/25 17:17:37 Stephen.Griffies Exp $' + '$Id: ocean_form_drag.F90,v 20.0 2013/12/14 00:16:34 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk diff --git a/src/mom5/ocean_param/vertical/ocean_form_drag.html b/src/mom5/ocean_param/vertical/ocean_form_drag.html deleted file mode 100644 index 79033f4dc7..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_form_drag.html +++ /dev/null @@ -1,474 +0,0 @@ - - - - Stephen M. Griffies - R. Fiedler - - Vertically adjusts gravitationally unstable columns of ocean fluid. - - This module vertically adjusts gravitationally unstable columns of - ocean fluid. - - Three algorithms are available: - - 1. Full convection from Rahmstorf. The algorithm produces a fully - stable fluid column. Since most convection propagates downward, the - scheme looks downward first and follows any instability (upward or - downward) before checking the other direction. The routine mixes - passive tracers only after the entire instability is found. - - 2. Full convection from Rahmstorf as optimized for vector machines - by Russ Fiedler. - - 3. The Cox (1984) NCON-scheme. This scheme is recommended only - for those wishing to maintain legacy code. - - 4. Legacy (pre TEOS-10) versions now supplied. In TEOS-10 we - need to mix S_prog, fdelta first, and then compute S_A. This - approach is not the same as mixing S_A directly. - - - Stefan Rahmstorf (Ocean Modelling, 1993 vol 101 pages 9-11) - - Implementation of the full convection scheme is - based on mom2/3 code by Stefan Rahmstorf - (rahmstorf@pik-potsdam.de). But modified slightly - for efficiency purposes in mom3.1 - by M. Eby (eby@uvic.ca) in June 2000. Notably, Eby - eliminated goto statements. - - The Eby code was ported to mom4 by Griffies (Stephen.Griffies). - - To recover the exact same numerical values as the original - Rahmstorf code, look for the two "Rahmstorf" comments in the code. - - Must be true to use this module. Default is false. - - If true, will use the old NCON convection scheme from Cox. - Retained only for legacy purposes to reproduce very old results. - - Number of passes through the NCON-scheme. - - If true, will use the full convection scheme as implemented at GFDL for scalar - machines. - - If true, will use the full convection scheme as optimized for vector machines - by russell.fiedler@csiro.au. - - - Initialize the convection module. - - For the full convection module, we register two fields - for diagnostic output. -
- ktot = number of levels convected in a vertical column -
- kven = number of levels ventilated in a vertical column - - Note that ktot can in rare cases count some levels twice, if they - get involved in two originally separate, but then - overlapping convection areas in the water column. The field - kven is 0 on land, 1 on ocean points with no - convection, and any value up to nk on convecting points. -- Subroutine calls one of the two possible convection schemes. - - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on scalar - machines at GFDL. Has been found to be slow on vector machines. Use - convection_full_vector for vector machines. - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=fdelta, 4=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - - rho_salinity_mx = computed density salinity resulting from mixing of tracers. - - - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on vector - machines at CSIRO. Has been found to be faster on these machines than - convection_full_scalar. Answers differ, but not significantly. - - Code written by russell.fiedler@csiro.au - most recently modified Aug2011 - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - - rho_salinity_mx = computed density salinity resulting from mixing of tracers. - - - "ncon" convection scheme - - Convectively adjust water column if gravitationally unstable. - Based on algorithm from Mike Cox used in his code from 1984. - Algorithm has well known problems with incomplete homogenization - and sensitivity to the ncon parameter. - - Coded in mom4 for legacy purposes by Stephen.Griffies - April 2001 - - - - This routine is a legacy version which is consistent with using the old equation of state. - - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on scalar - machines at GFDL. Has been found to be slow on vector machines. Use - convection_full_vector_preteos10 for vector machines. - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - - - - This routine is a legacy version which is consistent with using the old equation of state. - - Subroutine to vertically adjust gravitationally unstable columns of ocean fluid. - Produces updated values for all the tracers. Code implemented on vector - machines at CSIRO. Has been found to be faster on these machines than - convection_full_scalar_preteos10. Answers differ, but not significantly. - - Code written by russell.fiedler@csiro.au - most recently modified Aug2011 - - internal variables: - - chk_la = logical flag to check level above kt - - chk_lb = logical flag to check level below kb - - kb = bottom level of (potential) instability - - kbo = bottom level of ocean - - kt = top level of (potential) instability - - la = test level above kt - - lb = test level below kb - - rl = lower level density referenced to lower level - - ru = upper level density referenced to lower level - - tmx = mixed tracer (1=temp, 2=salt, 3=other) - - tsm = sum of tracers (weighted by thickness) in the instability - - zsm = total thickness of the instability - - - Some diagnostics for convection. - - Initialization of watermass diagnostic output files. - - Diagnose effects from convection of - temp and salt on the watermass transformation diagnostics. - - Module ocean_form_drag_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_form_drag_mod
- - - - - -
-OVERVIEW
- -- Compute form drag as per Greatbatch and Lamb (1990) and/or - Aiki etal (2004). -
- - - -- Compute thickness weighted and density weighted tendency - [velocity*(kg/m^3)*meter/sec] for velocity associated with - parameterized form drag. Code employs the methods described - in Greatbatch and Lamb (1990) as well as Aiki etal (2004). - - This scheme has not been updated for C-grid specific layout. - However, there is little reason to expect that shifting the - viscosity by 1/2 grid point will make sense physically for this - scheme. Indeed, one does not expect this scheme to be relevant - near boundaries anyhow. So use for both Bgrid and Cgrid should - be reasonable, though with the caveat that differences will appear - near boundaries. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_form_drag_init:
- -- -compute_visc_form_drag:
- -- -form_drag_accel:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_form_drag_init
--
-- -DESCRIPTION -
-- - Initial set up for parameterized pressure form drag. -
-
-
-- - -
-compute_visc_form_drag
--
-- -DESCRIPTION -
-- - Compute vertical viscosity arising from parameterized - form drag according to the methods from the Greatbatch TEM approach. - - Follow the method of Ferreira and Marshall (2006) - for transitioning through the diabatic surface mixed layer. - We take the surf_blthick from mixed layer schemes (e.g., KPP), and use - this to define the region where the eddy induced velocity has - zero vertical shear. Note that we do not introduce an additional - transitional layer. - - There are four methods to compute the vertical viscosity within - the interior, with one required to be chosen: - 1/ form_drag_gbatch_f2overN2 - visc = kappa*(f/N)^2, with kappa=gm-diffusivity - 2/ form_drag_gbatch_f2overNb2 - visc = kappa*(f/Nb)^2, with Nb=buoyancy freq just below surface mixed layer - 3/ form_drag_gbatch_f2overNo2 - visc = kappa*(f/No)^2, with No=constant buoyancy freq - 4/ form_drag_gbatch_alpha_f2 - visc = alpha*f^2, with alpha = constant (units of m^2*sec) - -
-
-
-- - -
-form_drag_accel
--
-- -DESCRIPTION -
-- - Compute the rho*dz weighted acceleration from the Aiki etal - form drag scheme. -
-
-
-
-NAMELIST
- --&ocean_form_drag_nml --
-
----
-- -use_this_module -
-- Needs to be true in order to use this scheme. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging. -
-
-[logical] -- -verbose_init -
-- For verbose initialization information. -
-
-[logical] -- -use_form_drag_gbatch -
-- For using the Greatbatch form drag approach, which places - the contributions from "GM" into the momentum equation. - - use_form_drag_gbatch, is the traditional transformed - Eulerian mean approach as per Greatbatch and Lamb (1990) - and Greatbatch (1998). In this approach, we modify - visc_cbu so that the the "GM-effects" occur through - vertical viscosity. - - Since thise scheme is experimental, it is not recommended - for general use, so we set default - use_form_drag_gbatch=.false. -
-
-[logical] -- -form_drag_gbatch_surf_layer -
-- Logical to enable the use of a diabatic layer over which the - eddy-induce velocity is assumed to be constant with depth. - Default form_drag_gbatch_surf_layer=.false. -
-
-[logical] -- -ksurf_blayer_min -
-- Minimum number of vertical grid points in the surface turbulent - boundary layer for use with form_drag_gbatch_surf_layer=.true. - Default ksurf_blayer_min=3. -
-
-[integer] -- -form_drag_gbatch_alpha_f2 -
-- For use of a vertical viscosity with the form_drag_gbatch that is - equal to visc = form_drag_gbatch_alpha * f^2. This form of the - vertical viscosity is used by Ferreira and Marshall, 2006. - Default form_drag_gbatch_alpha_f2=.false. -
-
-[logical] -- -form_drag_gbatch_alpha -
-- For use of a vertical viscosity with the form_drag_gbatch that is - equal to visc = form_drag_gbatch_alpha * f^2. - Default form_drag_gbatch_alpha=3e8 -
-
-[real, units: m^2*sec] -- -form_drag_gbatch_f2overN2 -
-- To compute vertical viscosity according to visc=kappa*(f/N)**2 - with kappa=gm-diffusivity, f=Coriolis, and N=buoyancy frequency. - This is the form suggested by Greatbatch and Lamb (1990). - Default form_drag_gbatch_f2overN2=.false. -
-
-[logical] -- -form_drag_gbatch_f2overNb2 -
-- To compute vertical viscosity according to visc=kappa*(f/Nb)**2 - with kappa=gm-diffusivity, f=Coriolis, and Nb=buoyancy frequency - just below the diabatic mixed layer. This is the form suggested - by Danabasoglu and Marshall (2007). - Default form_drag_gbatch_f2overNb2=.false. -
-
-[logical] -- -form_drag_gbatch_f2overNo2 -
-- To compute vertical viscosity according to visc=kappa*(f/No)**2 - with kappa=gm-diffusivity, f=Coriolis, and No=constant buoyancy - frequency set via namelist. - Default form_drag_gbatch_f2overNo2=.false. -
-
-[logical] -- -form_drag_gbatch_No -
-- To compute vertical viscosity according to visc=kappa*(f/No)**2 - with kappa=gm-diffusivity, f=Coriolis, and No=constant buoyancy - frequency. Default form_drag_gbatch_No=5e-3 -
-
-[real, units: sec^-1] -- -form_drag_gbatch_smooth_N2 -
-- For vertically smoothing the squared buoyancy frequency for - use in computing the vertical viscosity in the form drag - approach. Default form_drag_gbatch_smooth_N2=.false. -
-
-[logical] -- -num_121_passes -
-- Number of 1-2-1 passes for vertically smoothing the squared - buoyancy frequency. Default num_121_passes=1. -
-
-[integer] -- -visc_cbu_form_drag_max -
-- Maximum vertical viscosity used for the form drag contribution - to vertical friction from the Greatbatch TEM approach. - Default visc_cbu_form_drag_max=1m^2/sec. -
-
-[real, units: m^2/sec] -- -vel_form_drag_max -
-- For diagnostic purpuses, maximum form drag eddy induced velocity. - Default vel_form_drag_max=1m/sec. -
-
-[real, units: m/sec] -- -N_squared_min -
-- Minimum sequared buoyancy frequency (N^2) for use in computing - the vertical viscosity from the Greatbatch form drag scheme. - Default N_squared_min=1e-10. -
-
-[real, units: 1/sec] -- -use_form_drag_aiki -
-- For using the Aiki form drag approach. -
-
-[logical] -- -cprime_aiki -
-- Dimensionless parameters from the Aiki etal scheme. - Default cprime_aiki=0.3. -
-
-[real, units: dimensionless] -- -form_drag_aiki_scale_by_gm -
-- Compute a dimensionless scale function proportional to - the GM-diffusivity, for use with the Aiki etal form - drag scheme. Default form_drag_aiki_scale_by_gm=.false. -
-
-[logical] -- -form_drag_aiki_bottom_layer -
-- For implementing the Aiki form drag just in a selected number of - bottom layers. Will still insist that the scheme conserves - momentum, as a form drag scheme should do. - Default form_drag_aiki_bottom_layer=.false. -
-
-[logical] -- -form_drag_aiki_bottom_klevels -
-- Number of klevels above the bottom that we choose to close the - Aiki form drag scheme. Default form_drag_aiki_bottom_klevels=3. - This should ideally be less than the minimum number of klevels - in the model. -
-
-[integer] -- -form_drag_aiki_scale_by_gradH -
-- For scaling the coefficient used by the form drag scheme with - the bottom slope. -
-
-[logical] -- -form_drag_aiki_gradH_power -
-- For scaling the coefficient used by the form drag scheme with - the bottom slope raised to the power "form_drag_aiki_gradH_power". -
-
-[real] -- -form_drag_aiki_gradH_max -
-- For scaling setting the maximum of the bottom slope - for use with scaling the form drag coefficient. - Default form_drag_aiki_gradH_max=.05 -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Greatbatch and Lamb, 1990: On parameterizing vertical mixing of - momentum in non eddy-resolving ocean models. Journal of - Physical Oceanography. vol. 20, pages 1634-1637. -
-- - Greatbatch, 1998: Exploring the relationship betwen eddy-induced - transport velocity, vertical momentum transfer, and the isopycnal - flux of potential vorticity. Journal of Physical Oceanography, - vol. 28, pages 422-432. -
-- - Aiki, Jacobson, and Yamagata, 2004: Parameterizing ocean eddy transports - from surface to bottom. Geophysical Research Letters, vol. 31. -
-- - Ferreira and Marshall, 2006: Formulation and implementation of - a residual-mean ocean circulation model. Ocean Modelling, - vol. 13, pages 86--107. -
-- - Danabosaglu and Marshall, 2007: Effects of vertical variations of thickness - diffusivity in an ocean general circulation model. - Ocean Modelling, vol. 18, pages 122-141. -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_form_drag.xml b/src/mom5/ocean_param/vertical/ocean_form_drag.xml deleted file mode 100644 index 006b6c52c3..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_form_drag.xml +++ /dev/null @@ -1,172 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_chen.F90 b/src/mom5/ocean_param/vertical/ocean_vert_chen.F90 index b04d35e8be..ff1f794780 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_chen.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_chen.F90 @@ -188,9 +188,9 @@ module ocean_vert_chen_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=256) :: version=& - '$Id: ocean_vert_chen.F90,v 1.1.2.6 2012/05/25 17:17:37 Stephen.Griffies Exp $' + '$Id: ocean_vert_chen.F90,v 20.0 2013/12/14 00:16:36 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. logical :: use_this_module = .false. diff --git a/src/mom5/ocean_param/vertical/ocean_vert_chen.html b/src/mom5/ocean_param/vertical/ocean_vert_chen.html deleted file mode 100644 index eb1a82c320..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_chen.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - S.M. Griffies - - Compute form drag as per Greatbatch and Lamb (1990) and/or - Aiki etal (2004). - - Compute thickness weighted and density weighted tendency - [velocity*(kg/m^3)*meter/sec] for velocity associated with - parameterized form drag. Code employs the methods described - in Greatbatch and Lamb (1990) as well as Aiki etal (2004). - - This scheme has not been updated for C-grid specific layout. - However, there is little reason to expect that shifting the - viscosity by 1/2 grid point will make sense physically for this - scheme. Indeed, one does not expect this scheme to be relevant - near boundaries anyhow. So use for both Bgrid and Cgrid should - be reasonable, though with the caveat that differences will appear - near boundaries. - - - Greatbatch and Lamb, 1990: On parameterizing vertical mixing of - momentum in non eddy-resolving ocean models. Journal of - Physical Oceanography. vol. 20, pages 1634-1637. - - Greatbatch, 1998: Exploring the relationship betwen eddy-induced - transport velocity, vertical momentum transfer, and the isopycnal - flux of potential vorticity. Journal of Physical Oceanography, - vol. 28, pages 422-432. - - Aiki, Jacobson, and Yamagata, 2004: Parameterizing ocean eddy transports - from surface to bottom. Geophysical Research Letters, vol. 31. - - Ferreira and Marshall, 2006: Formulation and implementation of - a residual-mean ocean circulation model. Ocean Modelling, - vol. 13, pages 86--107. - - Danabosaglu and Marshall, 2007: Effects of vertical variations of thickness - diffusivity in an ocean general circulation model. - Ocean Modelling, vol. 18, pages 122-141. - - Needs to be true in order to use this scheme. Default is false. - - For debugging. - - For verbose initialization information. - - For using the Greatbatch form drag approach, which places - the contributions from "GM" into the momentum equation. - - use_form_drag_gbatch, is the traditional transformed - Eulerian mean approach as per Greatbatch and Lamb (1990) - and Greatbatch (1998). In this approach, we modify - visc_cbu so that the the "GM-effects" occur through - vertical viscosity. - - Since thise scheme is experimental, it is not recommended - for general use, so we set default - use_form_drag_gbatch=.false. - - Logical to enable the use of a diabatic layer over which the - eddy-induce velocity is assumed to be constant with depth. - Default form_drag_gbatch_surf_layer=.false. - - Minimum number of vertical grid points in the surface turbulent - boundary layer for use with form_drag_gbatch_surf_layer=.true. - Default ksurf_blayer_min=3. - - For use of a vertical viscosity with the form_drag_gbatch that is - equal to visc = form_drag_gbatch_alpha * f^2. This form of the - vertical viscosity is used by Ferreira and Marshall, 2006. - Default form_drag_gbatch_alpha_f2=.false. - - For use of a vertical viscosity with the form_drag_gbatch that is - equal to visc = form_drag_gbatch_alpha * f^2. - Default form_drag_gbatch_alpha=3e8 - - To compute vertical viscosity according to visc=kappa*(f/N)**2 - with kappa=gm-diffusivity, f=Coriolis, and N=buoyancy frequency. - This is the form suggested by Greatbatch and Lamb (1990). - Default form_drag_gbatch_f2overN2=.false. - - To compute vertical viscosity according to visc=kappa*(f/Nb)**2 - with kappa=gm-diffusivity, f=Coriolis, and Nb=buoyancy frequency - just below the diabatic mixed layer. This is the form suggested - by Danabasoglu and Marshall (2007). - Default form_drag_gbatch_f2overNb2=.false. - - To compute vertical viscosity according to visc=kappa*(f/No)**2 - with kappa=gm-diffusivity, f=Coriolis, and No=constant buoyancy - frequency set via namelist. - Default form_drag_gbatch_f2overNo2=.false. - - To compute vertical viscosity according to visc=kappa*(f/No)**2 - with kappa=gm-diffusivity, f=Coriolis, and No=constant buoyancy - frequency. Default form_drag_gbatch_No=5e-3 - - For vertically smoothing the squared buoyancy frequency for - use in computing the vertical viscosity in the form drag - approach. Default form_drag_gbatch_smooth_N2=.false. - - Number of 1-2-1 passes for vertically smoothing the squared - buoyancy frequency. Default num_121_passes=1. - - Maximum vertical viscosity used for the form drag contribution - to vertical friction from the Greatbatch TEM approach. - Default visc_cbu_form_drag_max=1m^2/sec. - - For diagnostic purpuses, maximum form drag eddy induced velocity. - Default vel_form_drag_max=1m/sec. - - Minimum sequared buoyancy frequency (N^2) for use in computing - the vertical viscosity from the Greatbatch form drag scheme. - Default N_squared_min=1e-10. - - For using the Aiki form drag approach. - - Dimensionless parameters from the Aiki etal scheme. - Default cprime_aiki=0.3. - - Compute a dimensionless scale function proportional to - the GM-diffusivity, for use with the Aiki etal form - drag scheme. Default form_drag_aiki_scale_by_gm=.false. - - For implementing the Aiki form drag just in a selected number of - bottom layers. Will still insist that the scheme conserves - momentum, as a form drag scheme should do. - Default form_drag_aiki_bottom_layer=.false. - - Number of klevels above the bottom that we choose to close the - Aiki form drag scheme. Default form_drag_aiki_bottom_klevels=3. - This should ideally be less than the minimum number of klevels - in the model. - - For scaling the coefficient used by the form drag scheme with - the bottom slope. - - For scaling the coefficient used by the form drag scheme with - the bottom slope raised to the power "form_drag_aiki_gradH_power". - - For scaling setting the maximum of the bottom slope - for use with scaling the form drag coefficient. - Default form_drag_aiki_gradH_max=.05 - - Initial set up for parameterized pressure form drag. - - Compute vertical viscosity arising from parameterized - form drag according to the methods from the Greatbatch TEM approach. - - Follow the method of Ferreira and Marshall (2006) - for transitioning through the diabatic surface mixed layer. - We take the surf_blthick from mixed layer schemes (e.g., KPP), and use - this to define the region where the eddy induced velocity has - zero vertical shear. Note that we do not introduce an additional - transitional layer. - - There are four methods to compute the vertical viscosity within - the interior, with one required to be chosen: - 1/ form_drag_gbatch_f2overN2 - visc = kappa*(f/N)^2, with kappa=gm-diffusivity - 2/ form_drag_gbatch_f2overNb2 - visc = kappa*(f/Nb)^2, with Nb=buoyancy freq just below surface mixed layer - 3/ form_drag_gbatch_f2overNo2 - visc = kappa*(f/No)^2, with No=constant buoyancy freq - 4/ form_drag_gbatch_alpha_f2 - visc = alpha*f^2, with alpha = constant (units of m^2*sec) - - - Compute the rho*dz weighted acceleration from the Aiki etal - form drag scheme. - Module ocean_vert_chen_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_chen_mod
- - - - - -
-OVERVIEW
- -- Vertical viscosity and diffusivity according Chen scheme -
- - - -- This scheme was originally developed by researchers - at the CSIRO Marine and Atmospheric Research and - Bureau of Meteorology, both in Australia. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_shortwave_csiro_mod
ocean_types_mod
ocean_util_mod
ocean_vert_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_chen_init:
- -- -vert_mix_chen:
- -- -kraus_turner:
- -- -ri_for_chen:
- -- -ocean_vert_chen_restart:
- -- -ocean_vert_chen_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_chen_init
--
-- -DESCRIPTION -
-- - Initialization for the Chen vertical mixing scheme - - input: - dzt = thickness of vertical levels (m) - km = number of vertical levels - yt = latitude of grid points (deg) - dtts = density time step (sec) - dtuv = internal mode time step (sec) - error = logical to signal problems - vmixset= logical to determine if a vertical mixing scheme was - chosen - - output: - visc_cbu_limit = visc max due to shear instability (m**2/sec) - diff_cbt_limit = diffusivity .. (m**2/sec) - visc_cbu_iw = visc background due to internal waves(m**2/sec) - diff_cbt_iw = diffusivity .. (m**2/sec) - error = true if some inconsistancy was found - -
-
-
-- - -
-vert_mix_chen
--
-- -DESCRIPTION -
-- - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the Kraus boundary layer - ("hbl") gets computed. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - set to a maximum - - inputs - - outputs - - hbl = boundary layer depth (meters) - visc_cbu = viscosity coefficient at bottom of U cells (m^2/s)
-
- diff_cbt = diffusion coefficient at bottom of T cells (m^2/s)
- -
-
-- - -
-kraus_turner
--
-- -DESCRIPTION -
-- - - Calculate the Kraus mixed layer depth - - Note: This formulation assumes a single exponential decay in the solar - shortwave penetration. - - Use smf_bgrid since this array contains the primary smf array read in from - from the coupler in ocean_core/ocean_sbc.F90, when using the FMS coupler. - - real dbloc(ij_bounds) = local delta buoyancy (m/s^2) - real ustar(ij_bounds) = surface friction velocity (m/s) - real Bo(ij_bounds) = surface turbulent buoyancy forcing(m^2/s^3) - real Bosol(ij_bounds) = radiative buoyancy forcing (m^2/s^3) - - output - real hbl(ij_bounds) ! boundary layer depth (m) - real mixmask(ij_bounds,nk) ! fraction of cell which resides in mixed layer - integer kbl(ij_bounds) ! index of first grid level below hbl - -
-
-
-- - -
-ri_for_chen
--
-- -DESCRIPTION -
-- - Compute Richardson number on tracer and velocity cell bottoms. - rit = richardson number at bottom of T cells
-
- riu = richardson number at bottom of U cells -
-
-- - -
-ocean_vert_chen_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_vert_chen_end
--
-- -DESCRIPTION -
-- - Save the Kraus boundary layer depth to start next time step. -
-
-
-
-NAMELIST
- --&ocean_vert_chen_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging. Default debug_this_module=.false. -
-
-[logical] -- -diff_cbt_iw -
-- Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. -
-
-[real, units: m^2/sec] -- -visc_cbu_iw -
-- Background vertical viscosity -
-
-[real, units: m^2/sec] -- -visc_cbu_limit -
-- Enhanced vertical viscosity due to shear instability -
-
-[real, units: m^2/sec] -- -diff_cbt_limit -
-- Enhanced vertical diffusivity due to shear instability -
-
-[real, units: m^2/sec] -- -bulk_tn -
-- Bulk turblence parameter n_0 -
-
-[real, units: ] -- -bulk_tm -
-- Bulk turblence parameter m_0 -
-
-[real, units: ] -- -hbl_growth_max -
-- Maximum growth rate of kraus mixed layer -
-
-[real, units: m/sec] -
- - - - -
-REFERENCES
- ----
-- - Chen, D., L.M. Rothstein and A.J. Busalacchi, 1994: - A hybrid vertical mixing scheme and its application - to tropical ocean models, - J. Phys. Oceanogr., 24, 2156-2179 -
-
- - -
-NOTES
- -- Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. --
-
- This module typically runs with the ocean_shortwave_csiro scheme. -
-
- Use smf_bgrid since this array contains the primary smf array read in from - from the coupler in ocean_core/ocean_sbc.F90, when using the FMS coupler. -
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_chen.xml b/src/mom5/ocean_param/vertical/ocean_vert_chen.xml deleted file mode 100644 index 7fbffabb26..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_chen.xml +++ /dev/null @@ -1,117 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_const.F90 b/src/mom5/ocean_param/vertical/ocean_vert_const.F90 index a28056d1bb..f64a8bb81e 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_const.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_const.F90 @@ -68,9 +68,9 @@ module ocean_vert_const_mod integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk character(len=256) :: version=& - '=>Using: const/ocean_vert_const.F90 ($Id: ocean_vert_const.F90,v 1.1.2.4 2012/06/08 20:33:56 Stephen.Griffies Exp $)' + '=>Using: const/ocean_vert_const.F90 ($Id: ocean_vert_const.F90,v 20.0 2013/12/14 00:16:38 fms Exp $)' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' integer :: index_temp integer :: index_salt diff --git a/src/mom5/ocean_param/vertical/ocean_vert_const.html b/src/mom5/ocean_param/vertical/ocean_vert_const.html deleted file mode 100644 index d3cbe0b3e6..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_const.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - Russell Fiedler - S.M. Griffies - - Vertical viscosity and diffusivity according Chen scheme - - This scheme was originally developed by researchers - at the CSIRO Marine and Atmospheric Research and - Bureau of Meteorology, both in Australia. - - Chen, D., L.M. Rothstein and A.J. Busalacchi, 1994: - A hybrid vertical mixing scheme and its application - to tropical ocean models, - J. Phys. Oceanogr., 24, 2156-2179 - - Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. - - This module typically runs with the ocean_shortwave_csiro scheme. - - Use smf_bgrid since this array contains the primary smf array read in from - from the coupler in ocean_core/ocean_sbc.F90, when using the FMS coupler. - - Must be true to use this module. Default is false. - - For debugging. Default debug_this_module=.false. - - Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. - - Background vertical viscosity - - Enhanced vertical viscosity due to shear instability - - Enhanced vertical diffusivity due to shear instability - - Bulk turblence parameter n_0 - - Bulk turblence parameter m_0 - - Maximum growth rate of kraus mixed layer - - Initialization for the Chen vertical mixing scheme - - input: - dzt = thickness of vertical levels (m) - km = number of vertical levels - yt = latitude of grid points (deg) - dtts = density time step (sec) - dtuv = internal mode time step (sec) - error = logical to signal problems - vmixset= logical to determine if a vertical mixing scheme was - chosen - - output: - visc_cbu_limit = visc max due to shear instability (m**2/sec) - diff_cbt_limit = diffusivity .. (m**2/sec) - visc_cbu_iw = visc background due to internal waves(m**2/sec) - diff_cbt_iw = diffusivity .. (m**2/sec) - error = true if some inconsistancy was found - - - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the Kraus boundary layer - ("hbl") gets computed. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - set to a maximum - - inputs - - outputs - - hbl = boundary layer depth (meters) - visc_cbu = viscosity coefficient at bottom of U cells (m^2/s)
- diff_cbt = diffusion coefficient at bottom of T cells (m^2/s)
-- - Calculate the Kraus mixed layer depth - - Note: This formulation assumes a single exponential decay in the solar - shortwave penetration. - - Use smf_bgrid since this array contains the primary smf array read in from - from the coupler in ocean_core/ocean_sbc.F90, when using the FMS coupler. - - real dbloc(ij_bounds) = local delta buoyancy (m/s^2) - real ustar(ij_bounds) = surface friction velocity (m/s) - real Bo(ij_bounds) = surface turbulent buoyancy forcing(m^2/s^3) - real Bosol(ij_bounds) = radiative buoyancy forcing (m^2/s^3) - - output - real hbl(ij_bounds) ! boundary layer depth (m) - real mixmask(ij_bounds,nk) ! fraction of cell which resides in mixed layer - integer kbl(ij_bounds) ! index of first grid level below hbl - - - Compute Richardson number on tracer and velocity cell bottoms. - rit = richardson number at bottom of T cells
- riu = richardson number at bottom of U cells -- Write out restart files registered through register_restart_file - - Save the Kraus boundary layer depth to start next time step. - Module ocean_vert_const_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_const_mod
- - - - - -
-OVERVIEW
- -- Compute constant vertical viscosity and diffusivity. -
- - - -- This module computes a time independent vertical viscosity and diffusivity. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_io_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_const_init:
- -- -vert_mix_const:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_const_init
--
-- -DESCRIPTION -
-- - Initialize the constant vertical diffusivity module. -
-
-
-- - -
-vert_mix_const
--
-- -DESCRIPTION -
-- - This function computes the vertical diffusivity and viscosity. - These mixing coefficients are time independent but generally - arbitrary functions of space. -
-
-
-
-NAMELIST
- --&ocean_vert_const_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -kappa_h -
-- The constant vertical diffusivity. Used for cases when wanting a space-time - independent diffusivity. The "h" is historical and stands for "heat". -
-
-[real, units: m^2/sec] -- -kappa_m -
-- The constant vertical viscosity. Used for cases when wanting a space-time - independent viscosity. -
-
-[real, units: m^2/sec] -- -diff_cbt_limit -
-- The largest allowable vertical diffusivity. Of use for cases where vertically unstable - columns are stabilized with a large vertical diffusivity. -
-
-[real, units: m^2/sec] -
- - - - -
-NOTES
- -- The numerical implementation requires no calls to mpp_update_domains. --
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_const.xml b/src/mom5/ocean_param/vertical/ocean_vert_const.xml deleted file mode 100644 index 0bdaeddf4c..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_const.xml +++ /dev/null @@ -1,28 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_gotm.F90 b/src/mom5/ocean_param/vertical/ocean_vert_gotm.F90 index f7b1ad4a74..ba16753086 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_gotm.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_gotm.F90 @@ -252,9 +252,9 @@ module ocean_vert_gotm_mod type(restart_file_type), save :: Got_restart character(len=256) :: version=& - '$Id: ocean_vert_gotm.F90,v 1.1.2.6 2012/06/03 00:41:57 Stephen.Griffies Exp $' + '$Id: ocean_vert_gotm.F90,v 20.0 2013/12/14 00:16:40 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. integer :: advection_gotm_method = 1 ! internally set: 1=upwind, 2=sweby diff --git a/src/mom5/ocean_param/vertical/ocean_vert_gotm.html b/src/mom5/ocean_param/vertical/ocean_vert_gotm.html deleted file mode 100644 index 7fbfb7876d..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_gotm.html +++ /dev/null @@ -1,429 +0,0 @@ - - - - Stephen M. Griffies - - Compute constant vertical viscosity and diffusivity. - - This module computes a time independent vertical viscosity and diffusivity. - - The numerical implementation requires no calls to mpp_update_domains. - - Must be true to use this module. Default is false. - - The constant vertical diffusivity. Used for cases when wanting a space-time - independent diffusivity. The "h" is historical and stands for "heat". - - The constant vertical viscosity. Used for cases when wanting a space-time - independent viscosity. - - The largest allowable vertical diffusivity. Of use for cases where vertically unstable - columns are stabilized with a large vertical diffusivity. - - Initialize the constant vertical diffusivity module. - - This function computes the vertical diffusivity and viscosity. - These mixing coefficients are time independent but generally - arbitrary functions of space. - Module ocean_vert_gotm_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_gotm_mod
- - --Contact: Martin Schmidt -, - Mike Herzfeld -, - Russell Fiedler -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Vertical viscosity and diffusivity according GOTM. -
- - - -- This module contains interfaces to initialize and invoke the - Generalized Ocean Turbulence Model (GOTM) parameterizations. - Full documentation of the schemes available with GOTM - can be found at www.gotm.net. - - MOM is distributed with the basic routines from the 4.0 - release of GOTM. Questions about GOTM should be directed - to the GOTM users group at www.gotm.net. - - This module assumes a twolevel time stepping scheme is used - to update the turbulence scalar fields tke and diss. - - Presently it has only been implemented assuming Bgrid. - So it needs to be updated for Cgrid layout. - - Here is a brief outline of the GOTM scheme: - - The non-conservative part of the tke - equation is P+B-diss, where P=shear production, - B=buoyancy production. The non-conservative part of - the diss equation is a linear combination of tke, - P, B and diss. - - The conservatie part of both tke and diss equations is - 3D advection. - - So vertical shear and buoyancy contribute to the - source and sinks (respectively) of tke and dissipation. - - The mixing coefficients are the product of a stability - function, sqrt(tke), and turbulence length scale (the latter - a non-linear function of tke and diss). - - In the hydro model (i.e., MOM), buoyancy fluxes are the - surface boundary conditions for vertical diffusion of temp (heat - fluxes) and salt (freshwater fluxes), which in turn determine the - density, and thus enter GOTM via the calculation of buoyancy production. - - Hence, buoyancy fluxes are NOT directly required as surface boundary - conditions for GOTM. - - Wind stress provides the surface boundary condition for vertical - momentum mixing in MOM. This information then enters GOTM - via the shear production calculation. However, wind stress - can enter the GOTM tke equation as the surface boundary - condition for vertical diffusion of tke (i.e. the prescribed, - or Dirichlet, condition). This information is typically used in - Mellor-Yamada turbulence models. An alternate no-flux (Neumann) - condition is used in the k-e models, and so do not require wind stress. - - Boundary conditions for vertical diffusion of diss involve roughness, - tke, and constants (both Neumann and Dirichlet). - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
mtridiagonal
turbulence
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_util_mod
ocean_workspace_mod
ocean_obc_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_gotm_init:
- -- -vert_mix_gotm_bgrid:
- -- -advect_gotm_compute:
- -- -advect_gotm_upwind:
- -- -advect_gotm_sweby:
- -- -ocean_vert_gotm_restart:
- -- -ocean_vert_gotm_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_gotm_init
--
-- -DESCRIPTION -
-- - Initialization for the MOM wrapper to the GOTM vertical mixing scheme. - - For restarts: - - We use twolevel time stepping scheme to update tke and diss, - so only need to read in the taup1_gotm value. - call mpp_update_domains since need tke and diss in halos for - the advection calculation. - - We need viscosity and diffusivity saved to restarts in order - to update the tke and diss fields within GOTM. - -
-
-
-- - -
-vert_mix_gotm_bgrid
--
-- -DESCRIPTION -
-- - This subroutine computes the vertical diffusivity and viscosity - according to the GOTM mixing model. - - The tke, diss, NN, and SS arrays are computed on tracer cells. - - Use smf_bgrid since this array uses the primary smf array read in from - the coupler in ocean_core/ocean_sbc.F90 when using the FMS coupler. - -
-
-
-- - -
-advect_gotm_compute
--
-- -DESCRIPTION -
-- - Wrapper for advection of GOTM scalar fields tke and diss. - - Horizontally tke and diss are on tracer cells, so advection just as if - they were tracers. - Vertically they are between tracer cells. We do not average but shift - tke and diss upward to tracer points for vertical advection. At the bottom - tke and diss are define by the Dirichlet boundary condition. - - Since use a two-level time stepping scheme for tke and diss, - it is necessary to advect these scalars with an upwind biased - advection scheme. - -
-
-
-- - -
-advect_gotm_upwind
--
-- -DESCRIPTION -
-- - First order upwind to advect GOTM scalar turbulence quantities tke and diss. -
-
-
-- - -
-advect_gotm_sweby
--
-- -DESCRIPTION -
-- - Sweby scheme to advect GOTM scalar turbulence quantities tke and diss. -
-
-
-- - -
-ocean_vert_gotm_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_vert_gotm_end
--
-- -DESCRIPTION -
-- - Save the advection term for restarting the next time step. -
-
-
-
-NAMELIST
- --&ocean_vert_gotm_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is .false. -
-
-[logical] -- -debug_this_module -
-- For debugging. Default is .false. -
-
-[logical] -- -do_turbulence_gotm -
-- For debugging. If do_turbulence_gotm=.false., then - will not invoke the GOTM scheme. Will only advect - tke and diss using 3d advection scheme. - Default is .true., so that will invoke GOTM scheme. -
-
-[logical] -- -do_advection_gotm -
-- For debugging. If do_advection_gotm=.false., then - will not invoke the advection of tke and diss. - Default is .true., so that will 3d advect tke and diss. -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -advect_gotm_method -
-- For choosing how to advect the GOTM scalar fields tke and diss. - Options are advect_gotm_method='upwind' (the default) - advect_gotm_method='sweby' -
-
-[character] -- -diff_cbt_min -
-- Background diffusivity. Default is 1.0e-5. -
-
-[real, units: m^2/sec] -- -visc_cbu_min -
-- Background viscosity. Default is 1.0e-5. -
-
-[real, units: m^2/sec] -- -z0s -
-- Surface roughness length. Default is 1m. -
-
-[real, units: m] -- -z0b -
-- Bottom roughness length. Default is .002m. -
-
-[real, units: m] -- -min_tke -
-- Minimum turbulent kinetic energy. Default=1.0e-6. -
-
-[real, units: m^2/s^2] -- -min_diss -
-- Minimum energy dissipation. Default=1.0e-10. -
-
-[real, units: m^2/s^3] -
- - - - -
-REFERENCES
- ----
-- - Burchard, H., K. Bolding and M. R. Villarreal - GOTM, a general ocean turbulence model. Theory - implementation and test cases. - European Communities, EUR 18745 EN, 1999 -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_gotm.xml b/src/mom5/ocean_param/vertical/ocean_vert_gotm.xml deleted file mode 100644 index d28024f55e..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_gotm.xml +++ /dev/null @@ -1,146 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.F90 b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.F90 index b10a2cb89a..93f57c93e0 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.F90 @@ -221,6 +221,7 @@ module ocean_vert_kpp_mom4p0_mod real, dimension(isd:ied,jsd:jed) :: bfsfc ! surface buoyancy forcing (m^2/s^3) real, dimension(isd:ied,jsd:jed) :: ws ! scalar velocity scale (m/s) real, dimension(isd:ied,jsd:jed) :: wm ! momentum velocity scale (m/s) +real, dimension(isd:ied,jsd:jed) :: Ustk2 ! magnitude of surface stokes drift velocity ^2 (m^2 / s^2) real, dimension(isd:ied,jsd:jed) :: caseA ! = 1 in case A; =0 in case B real, dimension(isd:ied,jsd:jed) :: stable ! = 1 in stable forcing; =0 in unstable real, dimension(isd:ied,jsd:jed,3) :: dkm1 ! boundary layer diff_cbt at kbl-1 level @@ -268,6 +269,7 @@ module ocean_vert_kpp_mom4p0_mod real, dimension(:,:), allocatable :: bfsfc ! surface buoyancy forcing (m^2/s^3) real, dimension(:,:), allocatable :: ws ! scalar velocity scale (m/s) real, dimension(:,:), allocatable :: wm ! momentum velocity scale (m/s) +real, dimension(:,:), allocatable :: Ustk2 ! Magnitude of surface stokes drift velocity ^2 (m^2/s^2) real, dimension(:,:), allocatable :: caseA ! = 1 in case A; =0 in case B real, dimension(:,:), allocatable :: stable ! = 1 in stable forcing; =0 in unstable real, dimension(:,:,:), allocatable :: dkm1 ! boundary layer diff_cbt at kbl-1 level @@ -336,6 +338,11 @@ module ocean_vert_kpp_mom4p0_mod real :: deltaz ! delta zehat in table real :: deltau ! delta ustar in table real :: concv = 1.8 ! constant for pure convection (eqn. 23) +real :: Lgam = 1.04 ! adjustment to non-gradient flux (McWilliam & Sullivan 2000) +real :: Cw_0 = 0.15 ! eq. (13) in Smyth et al (2002) +real :: l_smyth = 2.0 ! eq. (13) in Smyth et al (2002) +real :: LTmax = 5.0 ! maximum Langmuir turbulence enhancement factor (langmuirfactor) allowed +real :: Wstfac = 0.6 ! stability adjustment coefficient, eq. (13) in Smyth et al (2002) ! for vertical coordinate integer :: vert_coordinate @@ -399,6 +406,7 @@ module ocean_vert_kpp_mom4p0_mod logical :: non_local_kpp = .true. ! enable/disable non-local term in KPP logical :: smooth_blmc = .false. ! smooth boundary layer diffusitivies to remove grid scale noise +logical :: do_langmuir = .false. ! whether or not calculate langmuir turbulence enhancement factor logical :: coastal_tidal_mix = .false. ! add tidal speed (m/s) to Ri to increase coastal mixing real :: sigma_tide = 3.0 ! the sigma constant in the Munk-Anderson scheme @@ -426,9 +434,9 @@ module ocean_vert_kpp_mom4p0_mod integer :: num_diag_tracers=0, index_frazil character(len=256) :: version=& - '$Id: ocean_vert_kpp_mom4p0.F90,v 1.1.2.6 2012/06/03 00:41:57 Stephen.Griffies Exp $' + '$Id: ocean_vert_kpp_mom4p0.F90,v 20.0 2013/12/14 00:16:42 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. @@ -437,10 +445,11 @@ module ocean_vert_kpp_mom4p0_mod visc_cbu_limit, diff_cbt_limit, & visc_con_limit, diff_con_limit, & concv, Ricr, non_local_kpp, smooth_blmc, & + Lgam, Cw_0,l_smyth, LTmax, Wstfac, & coastal_tidal_mix, p_tide, sigma_tide, & int_tidal_mix, int_tide_zeta1, int_tide_zeta2, & int_tide_min_depth, int_tide_q, int_tide_gamma, & - wsfc_combine_runoff_calve + wsfc_combine_runoff_calve, do_langmuir contains @@ -633,6 +642,7 @@ subroutine ocean_vert_kpp_mom4p0_init (Grid, Domain, Time, Time_steps, Dens, T_p allocate (Rib(isd:ied,jsd:jed,2)) ! Bulk Richardson number allocate (wm(isd:ied,jsd:jed)) ! momentum turbulent velocity scales (m/s) allocate (ws(isd:ied,jsd:jed)) ! scalar turbulent velocity scales (m/s) + allocate (Ustk2(isd:ied,jsd:jed)) ! Magnitude of surface stokes drift velocity ^2 (m^2/s^2) allocate (gat1(isd:ied,jsd:jed,3)) allocate (dat1(isd:ied,jsd:jed,3)) allocate(sw_frac_hbl(isd:ied,jsd:jed)) @@ -652,6 +662,8 @@ subroutine ocean_vert_kpp_mom4p0_init (Grid, Domain, Time, Time_steps, Dens, T_p hblt(:,:) = 0.0 hbl(:,:) = 0.0 sw_frac_hbl(:,:) = 0.0 + Ustk2(:,:) = 0.0 + do n = 1, num_prog_tracers wsfc(n)%wsfc(:,:) = 0.0 enddo @@ -945,7 +957,7 @@ end subroutine ocean_vert_kpp_mom4p0_init ! ! subroutine vert_mix_kpp_mom4p0 (aidif, Time, Thickness, Velocity, T_prog, T_diag, Dens, & - swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth) + swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth, do_wave) real, intent(in) :: aidif type(ocean_time_type), intent(in) :: Time @@ -961,6 +973,7 @@ subroutine vert_mix_kpp_mom4p0 (aidif, Time, Thickness, Velocity, T_prog, T_diag real, dimension(isd:,jsd:), intent(inout) :: hblt_depth real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + logical, intent(in) :: do_wave real, dimension(isd:ied,jsd:jed,nk) :: dbloc1, dbsfc1 real, dimension(isd:ied,jsd:jed) :: frazil @@ -989,6 +1002,14 @@ subroutine vert_mix_kpp_mom4p0 (aidif, Time, Thickness, Velocity, T_prog, T_diag frazil(:,:) = 0.0 endif +!---------assign Ustk2 + if (do_wave) then + do j = jsd, jed + do i = isd, ied + Ustk2(i,j) = Velocity%ustoke(i,j)**2 + Velocity%vstoke(i,j)**2 + enddo + enddo + endif !----------------------------------------------------------------------- ! compute gradient Ri @@ -1182,13 +1203,13 @@ subroutine vert_mix_kpp_mom4p0 (aidif, Time, Thickness, Velocity, T_prog, T_diag ! boundary layer mixing coefficients: diagnose new b.l. depth !----------------------------------------------------------------------- - call bldepth(sw_frac_zt) + call bldepth(sw_frac_zt, do_wave) !----------------------------------------------------------------------- ! boundary layer diffusivities !----------------------------------------------------------------------- - call blmix_kpp(diff_cbt, visc_cbu) + call blmix_kpp(diff_cbt, visc_cbu, do_wave) !----------------------------------------------------------------------- ! enhance diffusivity at interface kbl - 1 @@ -1445,9 +1466,10 @@ end subroutine vert_mix_kpp_mom4p0 ! integer kbl(ij_bounds) ! index of first grid level below hbl Martin Schmidt - Mike Herzfeld - Russell Fiedler - Stephen M. Griffies - - Vertical viscosity and diffusivity according GOTM. - - This module contains interfaces to initialize and invoke the - Generalized Ocean Turbulence Model (GOTM) parameterizations. - Full documentation of the schemes available with GOTM - can be found at www.gotm.net. - - MOM is distributed with the basic routines from the 4.0 - release of GOTM. Questions about GOTM should be directed - to the GOTM users group at www.gotm.net. - - This module assumes a twolevel time stepping scheme is used - to update the turbulence scalar fields tke and diss. - - Presently it has only been implemented assuming Bgrid. - So it needs to be updated for Cgrid layout. - - Here is a brief outline of the GOTM scheme: - - The non-conservative part of the tke - equation is P+B-diss, where P=shear production, - B=buoyancy production. The non-conservative part of - the diss equation is a linear combination of tke, - P, B and diss. - - The conservatie part of both tke and diss equations is - 3D advection. - - So vertical shear and buoyancy contribute to the - source and sinks (respectively) of tke and dissipation. - - The mixing coefficients are the product of a stability - function, sqrt(tke), and turbulence length scale (the latter - a non-linear function of tke and diss). - - In the hydro model (i.e., MOM), buoyancy fluxes are the - surface boundary conditions for vertical diffusion of temp (heat - fluxes) and salt (freshwater fluxes), which in turn determine the - density, and thus enter GOTM via the calculation of buoyancy production. - - Hence, buoyancy fluxes are NOT directly required as surface boundary - conditions for GOTM. - - Wind stress provides the surface boundary condition for vertical - momentum mixing in MOM. This information then enters GOTM - via the shear production calculation. However, wind stress - can enter the GOTM tke equation as the surface boundary - condition for vertical diffusion of tke (i.e. the prescribed, - or Dirichlet, condition). This information is typically used in - Mellor-Yamada turbulence models. An alternate no-flux (Neumann) - condition is used in the k-e models, and so do not require wind stress. - - Boundary conditions for vertical diffusion of diss involve roughness, - tke, and constants (both Neumann and Dirichlet). - - - Burchard, H., K. Bolding and M. R. Villarreal - GOTM, a general ocean turbulence model. Theory - implementation and test cases. - European Communities, EUR 18745 EN, 1999 - - Must be true to use this module. Default is .false. - - For debugging. Default is .false. - - For debugging. If do_turbulence_gotm=.false., then - will not invoke the GOTM scheme. Will only advect - tke and diss using 3d advection scheme. - Default is .true., so that will invoke GOTM scheme. - - For debugging. If do_advection_gotm=.false., then - will not invoke the advection of tke and diss. - Default is .true., so that will 3d advect tke and diss. - - Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. - - For choosing how to advect the GOTM scalar fields tke and diss. - Options are advect_gotm_method='upwind' (the default) - advect_gotm_method='sweby' - - Background diffusivity. Default is 1.0e-5. - - Background viscosity. Default is 1.0e-5. - - Surface roughness length. Default is 1m. - - Bottom roughness length. Default is .002m. - - Minimum turbulent kinetic energy. Default=1.0e-6. - - Minimum energy dissipation. Default=1.0e-10. - - Initialization for the MOM wrapper to the GOTM vertical mixing scheme. - - For restarts: - - We use twolevel time stepping scheme to update tke and diss, - so only need to read in the taup1_gotm value. - call mpp_update_domains since need tke and diss in halos for - the advection calculation. - - We need viscosity and diffusivity saved to restarts in order - to update the tke and diss fields within GOTM. - - - This subroutine computes the vertical diffusivity and viscosity - according to the GOTM mixing model. - - The tke, diss, NN, and SS arrays are computed on tracer cells. - - Use smf_bgrid since this array uses the primary smf array read in from - the coupler in ocean_core/ocean_sbc.F90 when using the FMS coupler. - - - Wrapper for advection of GOTM scalar fields tke and diss. - - Horizontally tke and diss are on tracer cells, so advection just as if - they were tracers. - Vertically they are between tracer cells. We do not average but shift - tke and diss upward to tracer points for vertical advection. At the bottom - tke and diss are define by the Dirichlet boundary condition. - - Since use a two-level time stepping scheme for tke and diss, - it is necessary to advect these scalars with an upwind biased - advection scheme. - - - First order upwind to advect GOTM scalar turbulence quantities tke and diss. - - Sweby scheme to advect GOTM scalar turbulence quantities tke and diss. - - Write out restart files registered through register_restart_file - - Save the advection term for restarting the next time step. -
! ! -subroutine bldepth(sw_frac_zt) +subroutine bldepth(sw_frac_zt, do_wave) real, intent(in), dimension(isd:,jsd:,:) :: sw_frac_zt !3-D array of shortwave fract + logical, intent(in) :: do_wave real :: Ritop ! numerator of bulk Richardson Number real :: bvsq, Vtsq @@ -1504,7 +1526,7 @@ subroutine bldepth(sw_frac_zt) !----------------------------------------------------------------------- iwscale_use_hbl_eq_zt=1 - call wscale ( iwscale_use_hbl_eq_zt, Grd%zt(kl)) + call wscale ( iwscale_use_hbl_eq_zt, Grd%zt(kl), do_wave) do j=jsc,jec @@ -1671,13 +1693,14 @@ end subroutine bldepth ! ! ! -subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl) +subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl, do_wave) real, intent(in) :: zt_kl integer, intent(in) :: iwscale_use_hbl_eq_zt + logical, intent(in) :: do_wave real :: zdiff, udiff, zfrac, ufrac, fzfrac - real :: wam, wbm, was, wbs, u3 + real :: wam, wbm, was, wbs, u3, langmuirfactor, Cw_smyth real :: zehat ! = zeta * ustar**3 integer :: iz, izp1, ju, jup1 integer :: i, j @@ -1727,6 +1750,23 @@ subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl) endif enddo enddo + +!----------- if do_wave, add Langmuir turbulence enhancement factor + + if (do_wave .and. do_langmuir) then + do j=jsc,jec + do i=isc,iec + Cw_smyth=Cw_0*(ustar(i,j)*ustar(i,j)*ustar(i,j)/(ustar(i,j)*ustar(i,j)*ustar(i,j) & + + Wstfac* 0.4 *bfsfc(i,j)*hbl(i,j) + epsln))**l_smyth + langmuirfactor=sqrt(1+Cw_smyth*Ustk2(i,j)/(ustar(i,j)*ustar(i,j) + epsln)) + langmuirfactor = max(1.0, langmuirfactor) + langmuirfactor = min(LTmax, langmuirfactor) + ws(i,j)=ws(i,j)*langmuirfactor + wm(i,j)=wm(i,j)*langmuirfactor + enddo + enddo + endif + end subroutine wscale !o (eqn. 20) +! To include Langmuir turbulence effects, multiply ghats +! by a factor of Lgam (McWilliam & Sullivan 2001) !----------------------------------------------------------------------- - - ghats(i,j,ki) = (1.-stable(i,j)) * cg & + if (do_wave .and. do_langmuir) then + ghats(i,j,ki) = Lgam * (1.-stable(i,j)) * cg & + / (ws(i,j) * hbl(i,j) + epsln) + else + ghats(i,j,ki) = (1.-stable(i,j)) * cg & / (ws(i,j) * hbl(i,j) + epsln) + endif endif enddo enddo @@ -2185,7 +2233,7 @@ subroutine blmix_kpp(diff_cbt, visc_cbu) iwscale_use_hbl_eq_zt=0 zt_kl_dummy=0.0 - call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) do i = isc,iec sig = Grd%zt(kbl(i,j)-1) / (hbl(i,j)+epsln) diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.html b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.html deleted file mode 100644 index f4e661b7ef..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.html +++ /dev/null @@ -1,771 +0,0 @@ - - - - Module ocean_vert_kpp_mom4p0_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_kpp_mom4p0_mod
- - --Contact: A. Rosati - -- - -
-Reviewers: Bill Large -, - Stephen Griffies -, - M.J. Harrison -, - Hyun-Chul Lee - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Vertical viscosity and diffusivity according KPP using - code from MOM4p0, which is hard-wired for full cell - GEOPOTENTIAL vertical coordinate model. It remains part of - MOM for legacy purposes. -
- - - -- This module computes vertical viscosity and diffusivity according to - the K-profile parameterization scheme of Large, McWilliams, and - Doney (1994). It computes both local and non-local mixing. - - This module contains code that is hard-wired for GEOPOTENTIAL coordinates, - and so is NOT generally recommended. It remains part of MOM for - legacy purposes. - - This version of KPP has been implemented only for the Bgrid. - - This module also adds mixing due to barotropic tide drag - (coastal_tide_mix) and baroclinic tides (int_tide_mix). - The barotropic (coastal_tides) and baroclinic (int_tides) mixing - schemes are directly analogous to those available in the - module ocean_vert_tidal.F90. However, some of the averaging and - smoothing operations differ, and so detailed comparisons will show - differences. We retain the code here, in KPP, for legacy purposes. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_kpp_mom4p0_init:
- -- -vert_mix_kpp_mom4p0:
- -- -bldepth:
- -- -wscale:
- -- -ri_iwmix:
- -- -ddmix:
- -- -blmix_kpp:
- -- -enhance:
- -- -ri_for_kpp:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_kpp_mom4p0_init
--
-- -DESCRIPTION -
-- - Initialization for the KPP vertical mixing scheme - - input: - dzt = thickness of vertical levels (m)
-
- km = number of vertical levels
- yt = latitude of grid points (deg)
- jmt = number of latitudes
- dtxcel = time step accelerator as a function of level
- dtimet = forward time step for tracer diffusion (sec)
- dtimeu = forward time step for velcotiy friction (sec)
- error = logical to signal problems
- cifdef = array of character strings for listing enabled "ifdefs"
- ifdmax = size of "cifdef"
- nifdef = current number of enabled "ifdefs"
- vmixset= logical to determine if a vertical mixing scheme was
- chosen - - output: - shear_instability = logical switch for shear instability mixing
- double_diffusion = logical switch for double-diffusive mixing
- visc_cbu_limit = visc max due to shear instability (m**2/sec)
- diff_cbt_limit = diffusivity .. (m**2/sec)
- visc_cbu_iw = visc background due to internal waves(m**2/sec)
- diff_cbt_iw = diffusivity .. (m**2/sec)
- visc_con_limit = visc due to convective instability (m**2/sec)
- diff_con_limit = diffusivity .. (m**2/sec)
- Vtc = non-dimensional constant used in calc. bulk Ri
- cg = constant used in calc.nonlocal transport term
- wmt = turbulent velocity scale for momentum
- wst = turbulent velocity scale for scaler
- error = true if some inconsistancy was found - -
-
-- - -
-vert_mix_kpp_mom4p0
--
-- -DESCRIPTION -
-- - This subroutine computes the vertical diffusivity and viscosity according - to the KPP scheme of Large etal. In brief, the scheme does the - following: - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Mixing is enhanced in places of static instability (local Ri < 0). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Double diffusion: - Interior mixing can be enhanced by double diffusion due to salt - fingering and diffusive convection ("double_diffusion=.true."). - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the oceanic boundary layer - ("hbl") gets computed by evaluating bulk richardson numbers. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - determined by turbulent surface fluxes, and interior mixing at - the lower boundary, i.e. at hbl. - - NOTE: Use smf_bgrid since this uses the primary smf array read in from - the coupler in ocean_core/ocean_sbc.F90 when using the FMS coupler. - -
-
-
-- - -
-bldepth
--
-- -DESCRIPTION -
-- - The oceanic planetray boundary layer depth, hbl, is determined as - the shallowest depth where the bulk richardson number is - equal to the critical value, Ricr. - - Bulk Richardson numbers are evaluated by computing velocity and - buoyancy differences between values at zt(kl) and surface - reference values. - - In this configuration, the reference values are equal to the - values in the surface layer. - When using a very fine vertical grid, these values should be - computed as the vertical average of velocity and buoyancy from - the surface down to epsilon*zt(kl). - - When the bulk richardson number at k exceeds Ricr, hbl is - linearly interpolated between grid levels zt(k) and zt(k-1). - - The water column and the surface forcing are diagnosed for - stable/ustable forcing conditions, and where hbl is relative - to grid points (caseA), so that conditional branches can be - avoided in later subroutines. - - model - real zt(1:nk) = vertical grid (m)
-
- real dzt(1:nk) = layer thicknesses (m)
- - input - real dbloc(ij_bounds,nk) = local delta buoyancy (m/s^2)
- real dbsfc(ij_bounds,nk) = delta buoyancy w/ respect to sfc(m/s)^2
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real Bo(ij_bounds) = surface turbulent buoyancy forcing(m^2/s^3)
- real Bosol(ij_bounds) = radiative buoyancy forcing (m^2/s^3)
- real f(ij_bounds) = Coriolis parameter (1/s)
- integer jwtype(ij_bounds) = Jerlov water type (1 to 5)
- - output - real hbl(ij_bounds) ! boundary layer depth (m)
- real bfsfc(ij_bounds) !Bo+radiation absorbed to d=hbf*hbl(m^2/s^3)
- real stable(ij_bounds) ! =1 in stable forcing; =0 unstable
- real caseA(ij_bounds) ! =1 in case A, =0 in case B
- integer kbl(ij_bounds) ! index of first grid level below hbl
- -
-
-- - -
-wscale
--
-- -DESCRIPTION -
-- - Compute turbulent velocity scales. - Use a 2D-lookup table for wm and ws as functions of ustar and - zetahat (=vonk*sigma*hbl*bfsfc). - - Note: the lookup table is only used for unstable conditions - (zehat <= 0), in the stable domain wm (=ws) gets computed - directly. - - model - - input
-
- real sigma(ij_bounds) = normalized depth (d/hbl)
- real hbl(ij_bounds) = boundary layer depth (m)
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real bfsfc(ij_bounds) = total surface buoyancy flux (m^2/s^3)
- output
- real wm(ij_bounds),ws(ij_bounds) ! turbulent velocity scales at sigma - local
- real zehat ! = zeta * ustar**3 - -
-
-- - -
-ri_iwmix
--
-- -DESCRIPTION -
-- - Compute interior viscosity and diffusivity due - to shear instability (dependent on a local richardson number), - to background internal wave activity, and - to static instability (local richardson number < 0). - - inputs: - - nk = number of vertical levels
-
- visc_cbu_iw = background "visc_cbu" (m**2/sec) due to internal waves
- diff_cbt_iw = background "diff_cbt" (m**2/sec) due to internal waves
- visc_cbu_limit = largest "visc_cbu" in regions of gravitational
- instability (m**2/sec)
- diff_cbt_limit = largest "diff_cbt" in regions of gravitational
- instability (m**2/sec) - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
- -
-
-- - -
-ddmix
--
-- -DESCRIPTION -
-- - Rrho dependent interior flux parameterization. - Add double-diffusion diffusivities to Ri-mix values at blending - interface and below. salt fingering code modified july 2003 - by stephen.griffies based on NCAR CCSM2.x - - inputs: - - nk = number of vertical levels
-
- real talpha(imt,km,jmw) ! d(rho)/ d(pot.temperature) (kg/m^3/C)
- real sbeta(imt,km,jmw) ! d(rho)/ d(salinity) (kg/m^3/PSU) - - outputs: - - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - - local - - real alphaDT(imt,km,jmw) ! alpha * DT across interfaces
- real betaDS(imt,km,jmw) ! beta * DS across interfaces
- - -
-
-- - -
-blmix_kpp
--
-- -DESCRIPTION -
-- - Mixing coefficients within boundary layer depend on surface - forcing and the magnitude and gradient of interior mixing below - the boundary layer ("matching"). - - CAUTION: if mixing bottoms out at hbl = zt(nk) then - fictitious layer at nk+1 is needed with small but finite width - dzt(nk+1) (eg. epsln = 1.e-20). - - inputs: - - real ustar(ij_bounds) ! surface friction velocity (m/s)
-
- real bfsfc(ij_bounds) ! surface buoyancy forcing (m^2/s^3)
- real hbl(ij_bounds) ! boundary layer depth (m)
- real stable(ij_bounds) ! = 1 in stable forcing
- real caseA(ij_bounds) ! = 1 in case A
- integer kbl(ij_bounds) ! index of first grid level below hbl - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
- - real dkm1(ij_bounds,3) = boundary layer diff_cbt at kbl-1 level
- real blmc(ij_bounds,nk,3) = boundary layer mixing coeff.(m**2/s)
- real ghats(ij_bounds,nk) = nonlocal scalar transport
- - local: - - real gat1(ij_bounds,3)
- real dat1(ij_bounds,3)
- real sigma(ij_bounds) = normalized depth (d / hbl)
- real ws(ij_bounds), wm(ij_bounds) = turbulent velocity scales (m/s) - -
-
-- - -
-enhance
--
-- -DESCRIPTION -
-- - Enhance the diffusivity at the kbl-.5 interface - - input - integer kbl(ij_bounds) = grid above hbl
-
- real hbl(ij_bounds) = boundary layer depth (m)
- real dkm1(ij_bounds,3) = bl diffusivity at kbl-1 grid level
- real caseA(ij_bounds) = 1 in caseA, = 0 in case B - - input/output - real ghats(ij_bounds,nk) = nonlocal transport (s/m**2)
- modified ghats at kbl(i)-1 interface - output - real blmc(ij_bounds,nk,3) = enhanced boundary layer mixing coefficient - - local - real delta = fraction hbl lies beteen zt neighbors - -
-
-- - -
-ri_for_kpp
--
-- -DESCRIPTION -
-- - Compute Richardson number on tracer and velocity cell bottoms. - rit = richardson number at bottom of T cells
-
- riu = richardson number at bottom of U cells -
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from KPP nonlocal on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_vert_kpp_mom4p0_nml --
-
----
-- -use_this_module -
-- Logical switch to enable kpp diffusion. Default is false. -
-
-[logical] -- -shear_instability -
-- logical switch for shear instability mixing. - Default shear_instability=.true. -
-
-[logical] -- -double_diffusion -
-- Logical switch for double-diffusive mixing. - Default double_diffusion=.true. -
-
-[logical] -- -diff_cbt_iw -
-- Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. -
-
-[real, units: m^2/sec] -- -visc_cbu_iw -
-- Background vertical viscosity -
-
-[real, units: m^2/sec] -- -visc_cbu_limit -
-- Enhanced vertical viscosity due to shear instability -
-
-[real, units: m^2/sec] -- -diff_cbt_limit -
-- Enhanced vertical diffusivity due to shear instability -
-
-[real, units: m^2/sec] -- -visc_con_limit -
-- Enhanced vertical viscosity in regions of convection -
-
-[real, units: m^2/sec] -- -diff_con_limit -
-- Enhanced vertical diffusivity in regions of convection -
-
-[real, units: m^2/sec] -- -concv -
-- constant for pure convection (eqn. 23 of Large etal) -
-
-[real, units: dimensionless] -- -Ricr -
-- Critical bulk Richardson number. Default from NCAR is - 0.3, though this number has a large uncertainty and some - find that 1.0 can be of use. -
-
-[real, units: dimensionless] -- -non_local_kpp -
-- logical switch for enabling the non-local mixing aspect of kpp. - Default is .true. as this is what the original KPP scheme suggests. -
-
-[logical] -- -smooth_blmc -
-- Smooth boundary layer diffusitivies to remove grid scale noise. - Such noise is apparent in the diagnosed mixed layer depth as well - as the SST, especially when running coupled models where forcing - has high temporal frequency. -
-
-[logical] -- -coastal_tidal_mix -
-- For adding an extra vertical shear associated with tidal mixing. - This method has found to be of use for mixing near shelves. -
-
-[logical] -- -p_tide -
-- The p constant in the Munk-Anderson scheme - Default p_tide=-0.25 -
-
-[real] -- -sigma_tide -
-- The sigma constant in the Munk-Anderson scheme - Default sigma_tide=3.0 -
-
-[real] -- -int_tidal_mix -
-- For adding an internal tidal mixing over rough topography. - This method has found to be of use for mixing in the rough topography in open ocean. - Default int_tidal_mix=.false. -
-
-[logical] -- -int_tide_zeta1 -
-- Shallow depth for computation of internal tide. - Default int_tide_zeta1=300.0 -
-
-[real, units: metre] -- -int_tide_zeta2 -
-- Deeper depth for computation of internal tide. - Default int_tide_zeta2=1800.0 -
-
-[real, units: metre] -- -int_tide_min_depth -
-- Minimum depth for internal tide mixing to be computed. - Default int_tide_min_depth=100.0 -
-
-[real, units: metre] -- -int_tide_q -
-- Fraction of internal tide energy locally dissipated. - Default int_tide_q=.33333 -
-
-[real, units: dimensionless] -- -int_tide_gamma -
-- Dimensionless efficiency for converting energy dissipation to diffusivity. - Default int_tide_gamma=0.2 -
-
-[real, units: dimensionless] -- -wsfc_combine_runoff_calve -
-- For computing wsfc as in the mom4p0d code, where we combine - the runoff+calving into a single field called river. - The alternative keeps the fields separate, as would be appropriate - for a land model that separately tracks the tracer content in the - calving and runoff. - Default wsfc_combine_runoff_calve=.true., as this will recover - the previous behaviour, to the bit. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - W.G. Large and J.C. McWilliams and S.C. Doney - Oceanic vertical mixing: A review and a model with - a nonlocal boundary layer parameterization - Reviews of Geophysics (1994) vol 32 pages 363-403 -
-- - Hyun-Chul Lee, A. Rosati, and M.J. Spelman - Barotropic tidal mixing impact in a coupled climate model: - ocean condition and meridional overturning circulation - in the northern Atlantic - Ocean Modelling, vol 11, pages 464--477 -
-
- - -
-NOTES
- -- Original numerical algorithm by Bill Large at NCAR June 6, 1994 --
-
- Equation numbers in the code refer to the Large etal paper. -
-
- Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. -
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.xml b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.xml deleted file mode 100644 index 08b9b5ff8c..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p0.xml +++ /dev/null @@ -1,349 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.F90 b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.F90 index d7d08d2d31..ab205e2456 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.F90 @@ -287,6 +287,7 @@ module ocean_vert_kpp_mom4p1_mod real, dimension(isd:ied,jsd:jed) :: bfsfc ! surface buoyancy forcing (m^2/s^3) real, dimension(isd:ied,jsd:jed) :: ws ! scalar velocity scale (m/s) real, dimension(isd:ied,jsd:jed) :: wm ! momentum velocity scale (m/s) +real, dimension(isd:ied,jsd:jed) :: Ustk2 ! magnitude of surface stokes drift velocity ^2 (m^2 / s^2) real, dimension(isd:ied,jsd:jed) :: caseA ! = 1 in case A; =0 in case B real, dimension(isd:ied,jsd:jed) :: stable ! = 1 in stable forcing; =0 in unstable real, dimension(isd:ied,jsd:jed,3) :: dkm1 ! boundary layer diff_cbt at kbl-1 level @@ -324,6 +325,7 @@ module ocean_vert_kpp_mom4p1_mod real, dimension(:,:), allocatable :: bfsfc ! surface buoyancy forcing (m^2/s^3) real, dimension(:,:), allocatable :: ws ! scalar velocity scale (m/s) real, dimension(:,:), allocatable :: wm ! momentum velocity scale (m/s) +real, dimension(:,:), allocatable :: Ustk2 ! Magnitude of surface stokes drift velocity ^2 (m^2/s^2) real, dimension(:,:), allocatable :: caseA ! = 1 in case A; =0 in case B real, dimension(:,:), allocatable :: stable ! = 1 in stable forcing; =0 in unstable real, dimension(:,:,:), allocatable :: dkm1 ! boundary layer diff_cbt at kbl-1 level @@ -383,6 +385,12 @@ module ocean_vert_kpp_mom4p1_mod real :: concv = 1.8 ! constant for pure convection (eqn. 23) real :: concv_r ! inverse concv real :: vtc_flag = 0.0 ! default to the older approach. +real :: Lgam = 1.04 ! adjustment to non-gradient flux (McWilliam & Sullivan 2000) +real :: Cw_0 = 0.15 ! eq. (13) in Smyth et al (2002) +real :: l_smyth = 2.0 ! eq. (13) in Smyth et al (2002) +real :: LTmax = 5.0 ! maximum Langmuir turbulence enhancement factor (langmuirfactor) allowed +real :: Wstfac = 0.6 ! stability adjustment coefficient, eq. (13) in Smyth et al (2002) + ! for global area normalization real :: cellarea_r @@ -460,6 +468,7 @@ module ocean_vert_kpp_mom4p1_mod logical :: non_local_kpp = .true. ! enable/disable non-local term in KPP logical :: smooth_blmc = .false. ! smooth boundary layer diffusitivies to remove grid scale noise +logical :: do_langmuir = .false. ! whether or not calcualte langmuir turbulence enhance factor integer, parameter :: nni = 890 ! number of values for zehat in the look up table integer, parameter :: nnj = 480 ! number of values for ustar in the look up table @@ -476,9 +485,9 @@ module ocean_vert_kpp_mom4p1_mod integer :: kbl_max=2 ! helps to limit vertikal loops character(len=256) :: version=& - '$Id: ocean_vert_kpp_mom4p1.F90,v 1.1.2.4.4.1 2012/06/17 12:31:36 smg Exp $' + '$Id: ocean_vert_kpp_mom4p1.F90,v 20.0 2013/12/14 00:16:44 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. logical :: debug_this_module = .FALSE. @@ -488,12 +497,14 @@ module ocean_vert_kpp_mom4p1_mod visc_cbu_limit, diff_cbt_limit, & visc_con_limit, diff_con_limit, & concv, Ricr, non_local_kpp, smooth_blmc, & + Lgam, Cw_0,l_smyth, LTmax, Wstfac, & kl_min, kbl_standard_method, debug_this_module, & limit_with_hekman, limit_ghats, hbl_with_rit, & radiation_large, radiation_zero, radiation_iow, & use_sbl_bottom_flux, wsfc_combine_runoff_calve, & - bvf_from_below, variable_vtc, use_max_shear, & - linear_hbl, calc_visc_on_cgrid, smooth_ri_kmax_eq_kmu + bvf_from_below, variable_vtc, use_max_shear, & + linear_hbl, calc_visc_on_cgrid, smooth_ri_kmax_eq_kmu, & + do_langmuir contains @@ -743,6 +754,7 @@ subroutine ocean_vert_kpp_mom4p1_init (Grid, Domain, Time, Time_steps, Dens, T_p allocate (Rib(isd:ied,jsd:jed,rib_dim)) ! Bulk Richardson number allocate (wm(isd:ied,jsd:jed)) ! momentum turbulent velocity scales (m/s) allocate (ws(isd:ied,jsd:jed)) ! scalar turbulent velocity scales (m/s) + allocate (Ustk2(isd:ied,jsd:jed)) ! Magnitude of surface stokes drift velocity ^2 (m^2/s^2) allocate (gat1(isd:ied,jsd:jed,3)) allocate (dat1(isd:ied,jsd:jed,3)) allocate(sw_frac_hbl(isd:ied,jsd:jed)) @@ -756,6 +768,8 @@ subroutine ocean_vert_kpp_mom4p1_init (Grid, Domain, Time, Time_steps, Dens, T_p hblt(:,:) = 0.0 hbl(:,:) = 0.0 sw_frac_hbl(:,:) = 0.0 + Ustk2(:,:) = 0.0 + do n = 1, num_prog_tracers wsfc(n)%wsfc(:,:) = 0.0 enddo @@ -927,7 +941,7 @@ end subroutine ocean_vert_kpp_mom4p1_init ! ! subroutine vert_mix_kpp_mom4p1 (aidif, Time, Thickness, Velocity, T_prog, T_diag, Dens, & - swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth) + swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth, do_wave) real, intent(in) :: aidif type(ocean_time_type), intent(in) :: Time @@ -943,6 +957,8 @@ subroutine vert_mix_kpp_mom4p1 (aidif, Time, Thickness, Velocity, T_prog, T_diag real, dimension(isd:,jsd:), intent(inout) :: hblt_depth real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + logical, intent(in) :: do_wave + real, dimension(isd:ied,jsd:jed,nk) :: dbloc1, dbsfc1 real, dimension(isd:ied,jsd:jed) :: frazil @@ -972,6 +988,14 @@ subroutine vert_mix_kpp_mom4p1 (aidif, Time, Thickness, Velocity, T_prog, T_diag frazil(:,:) = 0.0 endif +!---------issign Ustk2 + if (do_wave) then + do j = jsd, jed + do i = isd, ied + Ustk2(i,j) = Velocity%ustoke(i,j)**2 + Velocity%vstoke(i,j)**2 + enddo + enddo + endif !----------------------------------------------------------------------- ! compute gradient Ri @@ -1181,13 +1205,13 @@ subroutine vert_mix_kpp_mom4p1 (aidif, Time, Thickness, Velocity, T_prog, T_diag ! boundary layer mixing coefficients: diagnose new b.l. depth !----------------------------------------------------------------------- - call bldepth(Thickness, sw_frac_zt) + call bldepth(Thickness, sw_frac_zt, do_wave) !----------------------------------------------------------------------- ! boundary layer diffusivities !----------------------------------------------------------------------- - call blmix_kpp(Thickness, diff_cbt, visc_cbu) + call blmix_kpp(Thickness, diff_cbt, visc_cbu, do_wave) call diagnose_3d(Time, Grd, id_ws, wrk1(:,:,:)) !----------------------------------------------------------------------- @@ -1544,10 +1568,11 @@ end subroutine vert_mix_kpp_mom4p1 ! integer kbl(ij_bounds) ! index of first grid level below hbl A. Rosati - Bill Large - Stephen Griffies - M.J. Harrison - Hyun-Chul Lee - - Vertical viscosity and diffusivity according KPP using - code from MOM4p0, which is hard-wired for full cell - GEOPOTENTIAL vertical coordinate model. It remains part of - MOM for legacy purposes. - - This module computes vertical viscosity and diffusivity according to - the K-profile parameterization scheme of Large, McWilliams, and - Doney (1994). It computes both local and non-local mixing. - - This module contains code that is hard-wired for GEOPOTENTIAL coordinates, - and so is NOT generally recommended. It remains part of MOM for - legacy purposes. - - This version of KPP has been implemented only for the Bgrid. - - This module also adds mixing due to barotropic tide drag - (coastal_tide_mix) and baroclinic tides (int_tide_mix). - The barotropic (coastal_tides) and baroclinic (int_tides) mixing - schemes are directly analogous to those available in the - module ocean_vert_tidal.F90. However, some of the averaging and - smoothing operations differ, and so detailed comparisons will show - differences. We retain the code here, in KPP, for legacy purposes. - - W.G. Large and J.C. McWilliams and S.C. Doney - Oceanic vertical mixing: A review and a model with - a nonlocal boundary layer parameterization - Reviews of Geophysics (1994) vol 32 pages 363-403 - - Hyun-Chul Lee, A. Rosati, and M.J. Spelman - Barotropic tidal mixing impact in a coupled climate model: - ocean condition and meridional overturning circulation - in the northern Atlantic - Ocean Modelling, vol 11, pages 464--477 - - Original numerical algorithm by Bill Large at NCAR June 6, 1994 - - Equation numbers in the code refer to the Large etal paper. - - Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. - - Logical switch to enable kpp diffusion. Default is false. - - logical switch for shear instability mixing. - Default shear_instability=.true. - - Logical switch for double-diffusive mixing. - Default double_diffusion=.true. - - Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. - - Background vertical viscosity - - Enhanced vertical viscosity due to shear instability - - Enhanced vertical diffusivity due to shear instability - - Enhanced vertical viscosity in regions of convection - - Enhanced vertical diffusivity in regions of convection - - constant for pure convection (eqn. 23 of Large etal) - - Critical bulk Richardson number. Default from NCAR is - 0.3, though this number has a large uncertainty and some - find that 1.0 can be of use. - - logical switch for enabling the non-local mixing aspect of kpp. - Default is .true. as this is what the original KPP scheme suggests. - - Smooth boundary layer diffusitivies to remove grid scale noise. - Such noise is apparent in the diagnosed mixed layer depth as well - as the SST, especially when running coupled models where forcing - has high temporal frequency. - - For adding an extra vertical shear associated with tidal mixing. - This method has found to be of use for mixing near shelves. - - The p constant in the Munk-Anderson scheme - Default p_tide=-0.25 - - The sigma constant in the Munk-Anderson scheme - Default sigma_tide=3.0 - - For adding an internal tidal mixing over rough topography. - This method has found to be of use for mixing in the rough topography in open ocean. - Default int_tidal_mix=.false. - - Shallow depth for computation of internal tide. - Default int_tide_zeta1=300.0 - - Deeper depth for computation of internal tide. - Default int_tide_zeta2=1800.0 - - Minimum depth for internal tide mixing to be computed. - Default int_tide_min_depth=100.0 - - Fraction of internal tide energy locally dissipated. - Default int_tide_q=.33333 - - Dimensionless efficiency for converting energy dissipation to diffusivity. - Default int_tide_gamma=0.2 - - For computing wsfc as in the mom4p0d code, where we combine - the runoff+calving into a single field called river. - The alternative keeps the fields separate, as would be appropriate - for a land model that separately tracks the tracer content in the - calving and runoff. - Default wsfc_combine_runoff_calve=.true., as this will recover - the previous behaviour, to the bit. - - Initialization for the KPP vertical mixing scheme - - input: - dzt = thickness of vertical levels (m)
- km = number of vertical levels
- yt = latitude of grid points (deg)
- jmt = number of latitudes
- dtxcel = time step accelerator as a function of level
- dtimet = forward time step for tracer diffusion (sec)
- dtimeu = forward time step for velcotiy friction (sec)
- error = logical to signal problems
- cifdef = array of character strings for listing enabled "ifdefs"
- ifdmax = size of "cifdef"
- nifdef = current number of enabled "ifdefs"
- vmixset= logical to determine if a vertical mixing scheme was
- chosen - - output: - shear_instability = logical switch for shear instability mixing
- double_diffusion = logical switch for double-diffusive mixing
- visc_cbu_limit = visc max due to shear instability (m**2/sec)
- diff_cbt_limit = diffusivity .. (m**2/sec)
- visc_cbu_iw = visc background due to internal waves(m**2/sec)
- diff_cbt_iw = diffusivity .. (m**2/sec)
- visc_con_limit = visc due to convective instability (m**2/sec)
- diff_con_limit = diffusivity .. (m**2/sec)
- Vtc = non-dimensional constant used in calc. bulk Ri
- cg = constant used in calc.nonlocal transport term
- wmt = turbulent velocity scale for momentum
- wst = turbulent velocity scale for scaler
- error = true if some inconsistancy was found - -- This subroutine computes the vertical diffusivity and viscosity according - to the KPP scheme of Large etal. In brief, the scheme does the - following: - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Mixing is enhanced in places of static instability (local Ri < 0). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Double diffusion: - Interior mixing can be enhanced by double diffusion due to salt - fingering and diffusive convection ("double_diffusion=.true."). - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the oceanic boundary layer - ("hbl") gets computed by evaluating bulk richardson numbers. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - determined by turbulent surface fluxes, and interior mixing at - the lower boundary, i.e. at hbl. - - NOTE: Use smf_bgrid since this uses the primary smf array read in from - the coupler in ocean_core/ocean_sbc.F90 when using the FMS coupler. - - - The oceanic planetray boundary layer depth, hbl, is determined as - the shallowest depth where the bulk richardson number is - equal to the critical value, Ricr. - - Bulk Richardson numbers are evaluated by computing velocity and - buoyancy differences between values at zt(kl) and surface - reference values. - - In this configuration, the reference values are equal to the - values in the surface layer. - When using a very fine vertical grid, these values should be - computed as the vertical average of velocity and buoyancy from - the surface down to epsilon*zt(kl). - - When the bulk richardson number at k exceeds Ricr, hbl is - linearly interpolated between grid levels zt(k) and zt(k-1). - - The water column and the surface forcing are diagnosed for - stable/ustable forcing conditions, and where hbl is relative - to grid points (caseA), so that conditional branches can be - avoided in later subroutines. - - model - real zt(1:nk) = vertical grid (m)
- real dzt(1:nk) = layer thicknesses (m)
- - input - real dbloc(ij_bounds,nk) = local delta buoyancy (m/s^2)
- real dbsfc(ij_bounds,nk) = delta buoyancy w/ respect to sfc(m/s)^2
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real Bo(ij_bounds) = surface turbulent buoyancy forcing(m^2/s^3)
- real Bosol(ij_bounds) = radiative buoyancy forcing (m^2/s^3)
- real f(ij_bounds) = Coriolis parameter (1/s)
- integer jwtype(ij_bounds) = Jerlov water type (1 to 5)
- - output - real hbl(ij_bounds) ! boundary layer depth (m)
- real bfsfc(ij_bounds) !Bo+radiation absorbed to d=hbf*hbl(m^2/s^3)
- real stable(ij_bounds) ! =1 in stable forcing; =0 unstable
- real caseA(ij_bounds) ! =1 in case A, =0 in case B
- integer kbl(ij_bounds) ! index of first grid level below hbl
-- Compute turbulent velocity scales. - Use a 2D-lookup table for wm and ws as functions of ustar and - zetahat (=vonk*sigma*hbl*bfsfc). - - Note: the lookup table is only used for unstable conditions - (zehat <= 0), in the stable domain wm (=ws) gets computed - directly. - - model - - input
- real sigma(ij_bounds) = normalized depth (d/hbl)
- real hbl(ij_bounds) = boundary layer depth (m)
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real bfsfc(ij_bounds) = total surface buoyancy flux (m^2/s^3)
- output
- real wm(ij_bounds),ws(ij_bounds) ! turbulent velocity scales at sigma - local
- real zehat ! = zeta * ustar**3 - -- Compute interior viscosity and diffusivity due - to shear instability (dependent on a local richardson number), - to background internal wave activity, and - to static instability (local richardson number < 0). - - inputs: - - nk = number of vertical levels
- visc_cbu_iw = background "visc_cbu" (m**2/sec) due to internal waves
- diff_cbt_iw = background "diff_cbt" (m**2/sec) due to internal waves
- visc_cbu_limit = largest "visc_cbu" in regions of gravitational
- instability (m**2/sec)
- diff_cbt_limit = largest "diff_cbt" in regions of gravitational
- instability (m**2/sec) - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
-- Rrho dependent interior flux parameterization. - Add double-diffusion diffusivities to Ri-mix values at blending - interface and below. salt fingering code modified july 2003 - by stephen.griffies based on NCAR CCSM2.x - - inputs: - - nk = number of vertical levels
- real talpha(imt,km,jmw) ! d(rho)/ d(pot.temperature) (kg/m^3/C)
- real sbeta(imt,km,jmw) ! d(rho)/ d(salinity) (kg/m^3/PSU) - - outputs: - - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - - local - - real alphaDT(imt,km,jmw) ! alpha * DT across interfaces
- real betaDS(imt,km,jmw) ! beta * DS across interfaces
- -- Mixing coefficients within boundary layer depend on surface - forcing and the magnitude and gradient of interior mixing below - the boundary layer ("matching"). - - CAUTION: if mixing bottoms out at hbl = zt(nk) then - fictitious layer at nk+1 is needed with small but finite width - dzt(nk+1) (eg. epsln = 1.e-20). - - inputs: - - real ustar(ij_bounds) ! surface friction velocity (m/s)
- real bfsfc(ij_bounds) ! surface buoyancy forcing (m^2/s^3)
- real hbl(ij_bounds) ! boundary layer depth (m)
- real stable(ij_bounds) ! = 1 in stable forcing
- real caseA(ij_bounds) ! = 1 in case A
- integer kbl(ij_bounds) ! index of first grid level below hbl - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
- - real dkm1(ij_bounds,3) = boundary layer diff_cbt at kbl-1 level
- real blmc(ij_bounds,nk,3) = boundary layer mixing coeff.(m**2/s)
- real ghats(ij_bounds,nk) = nonlocal scalar transport
- - local: - - real gat1(ij_bounds,3)
- real dat1(ij_bounds,3)
- real sigma(ij_bounds) = normalized depth (d / hbl)
- real ws(ij_bounds), wm(ij_bounds) = turbulent velocity scales (m/s) - -- Enhance the diffusivity at the kbl-.5 interface - - input - integer kbl(ij_bounds) = grid above hbl
- real hbl(ij_bounds) = boundary layer depth (m)
- real dkm1(ij_bounds,3) = bl diffusivity at kbl-1 grid level
- real caseA(ij_bounds) = 1 in caseA, = 0 in case B - - input/output - real ghats(ij_bounds,nk) = nonlocal transport (s/m**2)
- modified ghats at kbl(i)-1 interface - output - real blmc(ij_bounds,nk,3) = enhanced boundary layer mixing coefficient - - local - real delta = fraction hbl lies beteen zt neighbors - -- Compute Richardson number on tracer and velocity cell bottoms. - rit = richardson number at bottom of T cells
- riu = richardson number at bottom of U cells -- Initialization of watermass diagnostic output files. - - Diagnose effects from KPP nonlocal on the watermass transformation. -
! ! -subroutine bldepth(Thickness, sw_frac_zt) +subroutine bldepth(Thickness, sw_frac_zt, do_wave) type(ocean_thickness_type), intent(in) :: Thickness real, dimension(isd:,jsd:,:), intent(in) :: sw_frac_zt !3-D array of shortwave fract + logical, intent(in) :: do_wave real :: Ritop ! numerator of bulk Richardson Number real :: bvfr, Vtsq @@ -1614,7 +1639,7 @@ subroutine bldepth(Thickness, sw_frac_zt) ! compute velocity scales at sigma, for hbl = zt(kl): iwscale_use_hbl_eq_zt=1 - call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl)) + call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl), do_wave) do j=jsc,jec do i=isc,iec @@ -1716,7 +1741,7 @@ subroutine bldepth(Thickness, sw_frac_zt) ! compute velocity scales at sigma, for hbl = zt(kl): iwscale_use_hbl_eq_zt=1 - call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl)) + call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl), do_wave) do j=jsc,jec do i=isc,iec @@ -1970,13 +1995,14 @@ end subroutine bldepth ! Speed gain was observed at the SX-6. ! Later compiler versions may do better. ! -subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl) +subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl, do_wave) integer, intent(in) :: iwscale_use_hbl_eq_zt real, dimension(isd:,jsd:), intent(in) :: zt_kl + logical, intent(in) :: do_wave real :: zdiff, udiff, zfrac, ufrac, fzfrac - real :: wam, wbm, was, wbs, u3 + real :: wam, wbm, was, wbs, u3, langmuirfactor, Cw_smyth real :: zehat ! = zeta * ustar**3 integer :: iz, izp1, ju, jup1 integer :: i, j @@ -2070,6 +2096,22 @@ subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl) endif +!----------- if do_wave, add Langmuir turbulence enhancement factor + + if (do_wave .and. do_langmuir) then + do j=jsc,jec + do i=isc,iec + Cw_smyth=Cw_0*(ustar(i,j)*ustar(i,j)*ustar(i,j)/(ustar(i,j)*ustar(i,j)*ustar(i,j) & + + Wstfac*von_karman*bfsfc(i,j)*hbl(i,j) + epsln))**l_smyth + langmuirfactor=sqrt(1+Cw_smyth*Ustk2(i,j)/(ustar(i,j)*ustar(i,j) + epsln)) + langmuirfactor = max(1.0, langmuirfactor) + langmuirfactor = min(LTmax, langmuirfactor) + ws(i,j)=ws(i,j)*langmuirfactor + wm(i,j)=wm(i,j)*langmuirfactor + enddo + enddo + endif + end subroutine wscale !o (eqn. 20) +! To include Langmuir turbulence effects, multiply ghats +! by a factor of Lgam (McWilliam & Sullivan 2001) !----------------------------------------------------------------------- - - ghats(i,j,ki) = (1.-stable(i,j)) * cg & + if (do_wave .and. do_langmuir) then + ghats(i,j,ki) = Lgam * (1.-stable(i,j)) * cg & + / (ws(i,j) * hbl(i,j) + epsln) + else + ghats(i,j,ki) = (1.-stable(i,j)) * cg & / (ws(i,j) * hbl(i,j) + epsln) + endif endif enddo enddo @@ -2534,7 +2583,7 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbu) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy(:,:) = 0.0 - call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) do j=jsc,jec do i = isc,iec diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.html b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.html deleted file mode 100644 index 26eb495b23..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.html +++ /dev/null @@ -1,825 +0,0 @@ - - - - Module ocean_vert_kpp_mom4p1_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_kpp_mom4p1_mod
- - --Contact: A. Rosati -, - Martin Schmidt - -- - -
-Reviewers: Bill Large -, - Stephen Griffies -, - M.J. Harrison -, - Hyun-Chul Lee - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Vertical viscosity and diffusivity according KPP. - This module has extra code options to handle regions of extremely fresh water. - This particular version of the KPP module is frozen based on its use in MOM4p1 - at GFDL for the IPCC AR5 climate model ESM2M. -
- - - -- This module computes vertical viscosity and diffusivity according to - the K-profile parameterization scheme of Large, McWilliams, and - Doney (1994). It computes both local and non-local mixing. - The code has been updated to MOM4p1, so that vertical grid increments - are suitable for generalized vertical coordinate models. When run - as geopotential model, there will be some differences, since the - MOM4.0 code (available in ocean_vert_kpp_mom4p0.F90) incorrectly - ignored the free surface undulations affecting the top model grid - cell thickness. - - This version of KPP has been implemented only for the Bgrid. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_kpp_mom4p1_init:
- -- -vert_mix_kpp_mom4p1:
- -- -bldepth:
- -- -wscale:
- -- -ri_iwmix:
- -- -ddmix:
- -- -blmix_kpp:
- -- -enhance:
- -- -ri_for_kpp:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_kpp_mom4p1_init
--
-- -DESCRIPTION -
-- - Initialization for the KPP vertical mixing scheme -
-
-
-- - -
-vert_mix_kpp_mom4p1
--
-- -DESCRIPTION -
-- - This subroutine computes the vertical diffusivity and viscosity according - to the KPP scheme of Large etal. In brief, the scheme does the - following: - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Mixing is enhanced in places of static instability (local Ri < 0). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Double diffusion: - Interior mixing can be enhanced by double diffusion due to salt - fingering and diffusive convection ("double_diffusion=.true."). - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the oceanic boundary layer - ("hbl") gets computed by evaluating bulk richardson numbers. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - determined by turbulent surface fluxes, and interior mixing at - the lower boundary, i.e. at hbl. - -
-
-
-- - -
-bldepth
--
-- -DESCRIPTION -
-- - The oceanic planetray boundary layer depth, hbl, is determined as - the shallowest depth where the bulk richardson number is - equal to the critical value, Ricr. - - Bulk Richardson numbers are evaluated by computing velocity and - buoyancy differences between values at zt(kl) and surface - reference values. - - In this configuration, the reference values are equal to the - values in the surface layer. - When using a very fine vertical grid, these values should be - computed as the vertical average of velocity and buoyancy from - the surface down to epsilon*zt(kl). - - When the bulk richardson number at k exceeds Ricr, hbl is - linearly interpolated between grid levels zt(k) and zt(k-1). - - The water column and the surface forcing are diagnosed for - stable/ustable forcing conditions, and where hbl is relative - to grid points (caseA), so that conditional branches can be - avoided in later subroutines. - - model - real zt(1:nk) = vertical grid (m)
-
- real dzt(1:nk) = layer thicknesses (m)
- - input - real dbloc(ij_bounds,nk) = local delta buoyancy (m/s^2)
- real dbsfc(ij_bounds,nk) = delta buoyancy w/ respect to sfc(m/s)^2
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real Bo(ij_bounds) = surface turbulent buoyancy forcing(m^2/s^3)
- real Bosol(ij_bounds) = radiative buoyancy forcing (m^2/s^3)
- real f(ij_bounds) = Coriolis parameter (1/s)
- integer jwtype(ij_bounds) = Jerlov water type (1 to 5)
- - output - real hbl(ij_bounds) ! boundary layer depth (m)
- real bfsfc(ij_bounds) !Bo+radiation absorbed to d=hbf*hbl(m^2/s^3)
- real stable(ij_bounds) ! =1 in stable forcing; =0 unstable
- real caseA(ij_bounds) ! =1 in case A, =0 in case B
- integer kbl(ij_bounds) ! index of first grid level below hbl
- -
-
-- - -
-wscale
--
-- -DESCRIPTION -
-- - Compute turbulent velocity scales. - Use a 2D-lookup table for wm and ws as functions of ustar and - zetahat (=von_karman*sigma*hbl*bfsfc). - - Note: the lookup table is only used for unstable conditions - (zehat <= 0), in the stable domain wm (=ws) gets computed - directly. - - model - - input
-
- real sigma(ij_bounds) = normalized depth (d/hbl)
- real hbl(ij_bounds) = boundary layer depth (m)
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real bfsfc(ij_bounds) = total surface buoyancy flux (m^2/s^3)
- output
- real wm(ij_bounds),ws(ij_bounds) ! turbulent velocity scales at sigma - local
- real zehat ! = zeta * ustar**3 - -
-
-- - -
-ri_iwmix
--
-- -DESCRIPTION -
-- - Compute interior viscosity and diffusivity due - to shear instability (dependent on a local richardson number), - to background internal wave activity, and - to static instability (local richardson number < 0). - - inputs: - - nk = number of vertical levels
-
- visc_cbu_iw = background "visc_cbu" (m**2/sec) due to internal waves
- diff_cbt_iw = background "diff_cbt" (m**2/sec) due to internal waves
- visc_cbu_limit = largest "visc_cbu" in regions of gravitational
- instability (m**2/sec)
- diff_cbt_limit = largest "diff_cbt" in regions of gravitational
- instability (m**2/sec) - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
- -
-
-- - -
-ddmix
--
-- -DESCRIPTION -
-- - Rrho dependent interior flux parameterization. - Add double-diffusion diffusivities to Ri-mix values at blending - interface and below. salt fingering code modified july 2003 - by stephen.griffies based on NCAR CCSM2.x - - inputs: - - nk = number of vertical levels
-
- real talpha(imt,km,jmw) ! d(rho)/ d(pot.temperature) (kg/m^3/C)
- real sbeta(imt,km,jmw) ! d(rho)/ d(salinity) (kg/m^3/PSU) - - outputs: - - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - - local - - real alphaDT(imt,km,jmw) ! alpha * DT across interfaces
- real betaDS(imt,km,jmw) ! beta * DS across interfaces
- - -
-
-- - -
-blmix_kpp
--
-- -DESCRIPTION -
-- - Mixing coefficients within boundary layer depend on surface - forcing and the magnitude and gradient of interior mixing below - the boundary layer ("matching"). - - CAUTION: if mixing bottoms out at hbl = zt(nk) then - fictitious layer at nk+1 is needed with small but finite width - dzt(nk+1) (eg. epsln = 1.e-20). - - inputs: - - real ustar(ij_bounds) ! surface friction velocity (m/s)
-
- real bfsfc(ij_bounds) ! surface buoyancy forcing (m^2/s^3)
- real hbl(ij_bounds) ! boundary layer depth (m)
- real stable(ij_bounds) ! = 1 in stable forcing
- real caseA(ij_bounds) ! = 1 in case A
- integer kbl(ij_bounds) ! index of first grid level below hbl - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
- - real dkm1(ij_bounds,3) = boundary layer diff_cbt at kbl-1 level
- real blmc(ij_bounds,nk,3) = boundary layer mixing coeff.(m**2/s)
- real ghats(ij_bounds,nk) = nonlocal scalar transport
- - local: - - real gat1(ij_bounds,3)
- real dat1(ij_bounds,3)
- real sigma(ij_bounds) = normalized depth (d / hbl)
- real ws(ij_bounds), wm(ij_bounds) = turbulent velocity scales (m/s) - -
-
-- - -
-enhance
--
-- -DESCRIPTION -
-- - Enhance the diffusivity at the kbl-.5 interface - - input - integer kbl(ij_bounds) = grid above hbl
-
- real hbl(ij_bounds) = boundary layer depth (m)
- real dkm1(ij_bounds,3) = bl diffusivity at kbl-1 grid level
- real caseA(ij_bounds) = 1 in caseA, = 0 in case B - - input/output - real ghats(ij_bounds,nk) = nonlocal transport (s/m**2)
- modified ghats at kbl(i)-1 interface - output - real blmc(ij_bounds,nk,3) = enhanced boundary layer mixing coefficient - - local - real delta = fraction hbl lies beteen zt neighbors - -
-
-- - -
-ri_for_kpp
--
-- -DESCRIPTION -
-- - Compute Richardson number on tracer and velocity cell bottoms. - rit = richardson number at bottom of T cells
-
- riu = richardson number at bottom of U cells -
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from KPP nonlocal on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_vert_kpp_mom4p1_nml --
-
----
-- -use_this_module -
-- Logical switch to enable kpp diffusion. Default is false. -
-
-[logical] -- -debug_this_module -
-- Logical switch for debugging. Default debug_this_module=.false. -
-
-[logical] -- -shear_instability -
-- logical switch for shear instability mixing. - Default shear_instability=.true. -
-
-[logical] -- -double_diffusion -
-- Logical switch for double-diffusive mixing. - Default double_diffusion=.true. -
-
-[logical] -- -diff_cbt_iw -
-- Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. -
-
-[real, units: m^2/sec] -- -visc_cbu_iw -
-- Background vertical viscosity -
-
-[real, units: m^2/sec] -- -visc_cbu_limit -
-- Enhanced vertical viscosity due to shear instability -
-
-[real, units: m^2/sec] -- -diff_cbt_limit -
-- Enhanced vertical diffusivity due to shear instability -
-
-[real, units: m^2/sec] -- -visc_con_limit -
-- Enhanced vertical viscosity in regions of convection -
-
-[real, units: m^2/sec] -- -diff_con_limit -
-- Enhanced vertical diffusivity in regions of convection -
-
-[real, units: m^2/sec] -- -concv -
-- constant for pure convection (eqn. 23 of Large etal) -
-
-[real, units: dimensionless] -- -Ricr -
-- Critical bulk Richardson number. Default from NCAR is - 0.3, though this number has a large uncertainty and some - find that 1.0 can be of use. -
-
-[real, units: dimensionless] -- -non_local_kpp -
-- logical switch for enabling the non-local mixing aspect of kpp. - Default is .true. as this is what the original KPP scheme suggests. -
-
-[logical] -- -smooth_blmc -
-- Smooth boundary layer diffusitivies to remove grid scale noise. - Such noise is apparent in the diagnosed mixed layer depth as well - as the SST, especially when running coupled models where forcing - has high temporal frequency. - Default smooth_blmc=.false. - - Warning: This smoother can cause some problems with ghat in regions - of zero surface forcing. To understand details, one needs - the paper of Large et al. Vertical diffusion has the general form - <wx> = K(x_z - ghats) - In the surface layer a vertical scale function ws is estimated. - We have K ~ ws and ghats ~1/ws. If wind stress is zero the vertical - scale ws becomes zero too. Hence, ghats is very large - (something finite, since it is divided by ws+epsln). Now it may happen, - that the bouyancy flux becomes negative (~ -10-30). This enables - the nonlocal scheme. Because the mixing coefficient in the - surface boundary layer scales with ws the corresponding - time tendency should be of the order (1/ws * ws = finite). However, - if smooth_blmc is enabled, it may happen, that from neighbouring - points with different mixing depth a finite value for - the mixing coefficient leaks in. In this case - the tracer time tendency from the nonlocal scheme becomes huge - and the model fails. - - The smoother destroys the consistency between ghats and diff_cbt. - In most cases this should not matter, but the example shows, - that sudden model failure is possible under otherwise - stable and smooth conditions. - -
-
-[logical] -- -kl_min -
-- Lower loop index for finding new kbl. Needed for use with certain - tests of OBC, where kl_min=1 needed, whereas default in original - implementation has kl_min=2. Default in MOM is kl_min=2. -
-
-[integer] -- -kbl_standard_method -
-- For computing kbl as in the MOM4p0d code, which is taken from - the original NCAR scheme. If false, then will slightly modify - the logic. The modified logic has been found necessary when running - with as few as two grid cells in the vertical. - Default kbl_standard_method=.true. -
-
-[logical] -- -limit_with_hekman -
-- Limiting the boundary layer depth with the Ekman depth may result in a - shallow boundary layer. In this case the internal values of the vertical - mixing and viscosity coefficients may be large. This results in - unrealistically large non-local vertical mixing - Default limit_with_hekman=.true. -
-
-[logical] -- -limit_ghats -
-- Limits the non-local vertical tracer flux to the value of the tracer - surface flux. - Default limit_ghats=.false. -
-
-[logical] -- -hbl_with_rit -
-- The default method for determination of the boundary layer depth may fail - if the water column is instable (negative Richardson number) below or above - the layer that contains the diagnosed hbl. - With hbl_with_rit=.true. the search for the boundary layer depth is continued - downward in this case even if the bulk Richardson number exceeds the - critical value. This removes a lot of noise from the boundary layer depth. - Default hbl_with_rit=.false. -
-
-[logical] -- -radiation_large -
-- Remove the shortwave radiation leaving the boundary layer to the ocean interior - (hence, not absorbed in the boundary layer) from non-local vertical heat flux - Default radiation_large=.false. -
-
-[logical] -- -radiation_zero -
-- Remove the all shortwave radiation from non-local vertical heat flux. - Default radiation_zero=.false. -
-
-[logical] -- -radiation_iow -
-- Keep only the shortwave radiation absorbed between the surface and a certain level - in non-local vertical heat flux through this level. - Default radiation_iow=.false. -
-
-[logical] -- -bvf_from_below -
-- Use BV-freq. at the cell bottom instead of the cell top - as in Danabasoglu et al. (2006). - Default bvf_from_below=.false., as this will recover - older behaviour. -
-
-[logical] -- -variable_vtc -
-- Make vtc dependent on BV-freq. as in Danabasoglu et al. (2006). - Default variable_vtc=.false., as this will recover - older behaviour. -
-
-[logical] -- -use_max_shear -
-- Use maximum shear instead of 4-point average - (as in Danabasoglu et al. (2006)). - Default use_max_shear=.false., as this will recover - older behaviour. -
-
-[logical] -- -linear_hbl -
-- Use linear interpolation to find the position of hbl. - If set to false, then use the quadratic interpolation - as in Danabasoglu et al. (2006). The quadratic approach - generally yields a slightly deeper surface boundary layer. - Default linear_hbl=.true., as this will recover - older behaviour. -
-
-[logical] -- -wsfc_combine_runoff_calve -
-- For computing wsfc as in the MOM4p0d code, where we combine - the runoff+calving into a single field called river. - The alternative keeps the fields separate, as would be appropriate - for a land model that separately tracks the tracer content in the - calving and runoff. - Default wsfc_combine_runoff_calve=.true., as this will recover - the previous behaviour, to the bit. -
-
-[logical] -- -smooth_ri_kmax_eq_kmu -
-- When smoothing the Richardson number, we do so over a vertical - column with max k-levels set by either kmt or kmu. The proper - approach is kmu, since we are smoothing riu. But for backwards - compatibility, we default to smooth_ri_kmax_eq_kmu=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - W.G. Large and J.C. McWilliams and S.C. Doney - Oceanic vertical mixing: A review and a model with - a nonlocal boundary layer parameterization - Reviews of Geophysics (1994) vol 32 pages 363-403 -
-- - Danabasoglu etal (2006) - Diurnal coupling in the tropical oceans of CCSM3 - Journal of Climate (2006) vol 19 pages 2347--2365 -
-
- - -
-NOTES
- -- Original numerical algorithm by Bill Large at NCAR June 6, 1994 --
-
- Equation numbers in the code refer to the Large etal paper. -
-
- Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. -
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.xml b/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.xml deleted file mode 100644 index b79fc13ee4..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_mom4p1.xml +++ /dev/null @@ -1,372 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.F90 b/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.F90 index 21ade14ac5..433113dd8b 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.F90 @@ -291,6 +291,7 @@ module ocean_vert_kpp_test_mod real, dimension(isd:ied,jsd:jed) :: bfsfc ! surface buoyancy forcing (m^2/s^3) real, dimension(isd:ied,jsd:jed) :: ws ! scalar velocity scale (m/s) real, dimension(isd:ied,jsd:jed) :: wm ! momentum velocity scale (m/s) +real, dimension(isd:ied,jsd:jed) :: Ustk2 ! magnitude of surface stokes drift velocity ^2 (m^2 / s^2) real, dimension(isd:ied,jsd:jed) :: caseA ! = 1 in case A; =0 in case B real, dimension(isd:ied,jsd:jed) :: stable ! = 1 in stable forcing; =0 in unstable real, dimension(isd:ied,jsd:jed,3) :: dkm1 ! boundary layer diff_cbt at kbl-1 level @@ -328,6 +329,7 @@ module ocean_vert_kpp_test_mod real, dimension(:,:), allocatable :: bfsfc ! surface buoyancy forcing (m^2/s^3) real, dimension(:,:), allocatable :: ws ! scalar velocity scale (m/s) real, dimension(:,:), allocatable :: wm ! momentum velocity scale (m/s) +real, dimension(:,:), allocatable :: Ustk2 ! Magnitude of surface stokes drift velocity ^2 (m^2/s^2) real, dimension(:,:), allocatable :: caseA ! = 1 in case A; =0 in case B real, dimension(:,:), allocatable :: stable ! = 1 in stable forcing; =0 in unstable real, dimension(:,:,:), allocatable :: dkm1 ! boundary layer diff_cbt at kbl-1 level @@ -388,6 +390,11 @@ module ocean_vert_kpp_test_mod real :: concv = 1.8 ! constant for pure convection (eqn. 23) real :: concv_r ! inverse concv real :: vtc_flag = 0.0 ! default to the older approach. +real :: Lgam = 1.04 ! adjustment to non-gradient flux (McWilliam & Sullivan 2000) +real :: Cw_0 = 0.15 ! eq. (13) in Smyth et al (2002) +real :: l_smyth = 2.0 ! eq. (13) in Smyth et al (2002) +real :: LTmax = 5.0 ! maximum Langmuir turbulence enhancement factor (langmuirfactor) allowed +real :: Wstfac = 0.6 ! stability adjustment coefficient, eq. (13) in Smyth et al (2002) ! for global area normalization real :: cellarea_r @@ -470,6 +477,7 @@ module ocean_vert_kpp_test_mod logical :: non_local_kpp = .true. ! enable/disable non-local term in KPP logical :: smooth_blmc = .false. ! smooth boundary layer diffusitivies to remove grid scale noise +logical :: do_langmuir = .false. ! whether or not calcualate langmuir turbulence enhancement factor integer, parameter :: nni = 890 ! number of values for zehat in the look up table integer, parameter :: nnj = 480 ! number of values for ustar in the look up table @@ -485,9 +493,9 @@ module ocean_vert_kpp_test_mod integer :: num_diag_tracers=0, index_frazil character(len=256) :: version=& - '$Id: ocean_vert_kpp_test.F90,v 1.1.2.4 2012/05/25 12:49:59 Stephen.Griffies Exp $' + '$Id: ocean_vert_kpp_test.F90,v 20.0 2013/12/14 00:16:46 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .FALSE. logical :: debug_this_module = .FALSE. @@ -497,12 +505,13 @@ module ocean_vert_kpp_test_mod visc_cbu_limit, diff_cbt_limit, & visc_con_limit, diff_con_limit, & concv, Ricr, non_local_kpp, smooth_blmc, & + Lgam, Cw_0,l_smyth, LTmax, Wstfac, & kl_min, kbl_standard_method, debug_this_module, & limit_with_hekman, limit_ghats, hbl_with_rit, & radiation_large, radiation_zero, radiation_iow, & use_sbl_bottom_flux, wsfc_combine_runoff_calve, & - bvf_from_below, variable_vtc, use_max_shear, & - linear_hbl, smooth_ri_kmax_eq_kmu + bvf_from_below, variable_vtc, use_max_shear, & + linear_hbl, smooth_ri_kmax_eq_kmu, do_langmuir contains @@ -759,6 +768,7 @@ subroutine ocean_vert_kpp_test_init (Grid, Domain, Time, Time_steps, Dens, T_pro allocate (Rib(isd:ied,jsd:jed,rib_dim)) ! Bulk Richardson number allocate (wm(isd:ied,jsd:jed)) ! momentum turbulent velocity scales (m/s) allocate (ws(isd:ied,jsd:jed)) ! scalar turbulent velocity scales (m/s) + allocate (Ustk2(isd:ied,jsd:jed)) ! Magnitude of surface stokes drift velocity ^2 (m^2/s^2) allocate (gat1(isd:ied,jsd:jed,3)) allocate (dat1(isd:ied,jsd:jed,3)) allocate(sw_frac_hbl(isd:ied,jsd:jed)) @@ -772,6 +782,8 @@ subroutine ocean_vert_kpp_test_init (Grid, Domain, Time, Time_steps, Dens, T_pro hblt(:,:) = 0.0 hbl(:,:) = 0.0 sw_frac_hbl(:,:) = 0.0 + Ustk2(:,:) = 0.0 + do n = 1, num_prog_tracers wsfc(n)%wsfc(:,:) = 0.0 enddo @@ -952,9 +964,10 @@ end subroutine ocean_vert_kpp_test_init ! ! ! -subroutine vert_mix_kpp_test (Time, Thickness, Velocity, T_prog, T_diag, Dens, & - swflx, sw_frac_zt, pme, river, visc_cbu, visc_cbt, diff_cbt, hblt_depth) +subroutine vert_mix_kpp_test (aidif, Time, Thickness, Velocity, T_prog, T_diag, Dens, & + swflx, sw_frac_zt, pme, river, visc_cbu, visc_cbt, diff_cbt, hblt_depth, do_wave) + real, intent(in) :: aidif type(ocean_time_type), intent(in) :: Time type(ocean_thickness_type), intent(in) :: Thickness type(ocean_velocity_type), intent(in) :: Velocity @@ -969,6 +982,7 @@ subroutine vert_mix_kpp_test (Time, Thickness, Velocity, T_prog, T_diag, Dens, & real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + logical, intent(in) :: do_wave real, dimension(isd:ied,jsd:jed,nk) :: dbloc1, dbsfc1 real, dimension(isd:ied,jsd:jed) :: frazil @@ -999,6 +1013,15 @@ subroutine vert_mix_kpp_test (Time, Thickness, Velocity, T_prog, T_diag, Dens, & frazil(:,:) = 0.0 endif +!---------assign Ustk2 + if (do_wave) then + do j = jsd, jed + do i = isd, ied + Ustk2(i,j) = Velocity%ustoke(i,j)**2 + Velocity%vstoke(i,j)**2 + enddo + enddo + endif + !----------------------------------------------------------------------- ! compute gradient Ri and dVsq !----------------------------------------------------------------------- @@ -1228,11 +1251,11 @@ subroutine vert_mix_kpp_test (Time, Thickness, Velocity, T_prog, T_diag, Dens, & ! boundary layer mixing coefficients: diagnose new bldepth - call bldepth(Thickness, sw_frac_zt) + call bldepth(Thickness, sw_frac_zt, do_wave) ! boundary layer diffusivities - call blmix_kpp(Thickness, diff_cbt, visc_cbt) + call blmix_kpp(Thickness, diff_cbt, visc_cbt, do_wave) call diagnose_3d(Time, Grd, id_ws, wrk1(:,:,:)) @@ -1598,10 +1621,11 @@ end subroutine vert_mix_kpp_test ! ! ! -subroutine bldepth(Thickness, sw_frac_zt) +subroutine bldepth(Thickness, sw_frac_zt, do_wave) type(ocean_thickness_type), intent(in) :: Thickness real, dimension(isd:,jsd:,:), intent(in) :: sw_frac_zt !3-D array of shortwave fract + logical, intent(in) :: do_wave real :: Ritop ! numerator of bulk Richardson Number real :: bvfr, Vtsq @@ -1668,7 +1692,7 @@ subroutine bldepth(Thickness, sw_frac_zt) ! compute velocity scales at sigma, for hbl = zt(kl): iwscale_use_hbl_eq_zt=1 - call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl)) + call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl), do_wave) do j=jsc,jec do i=isc,iec @@ -1770,7 +1794,7 @@ subroutine bldepth(Thickness, sw_frac_zt) ! compute velocity scales at sigma, for hbl = zt(kl): iwscale_use_hbl_eq_zt=1 - call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl)) + call wscale (iwscale_use_hbl_eq_zt, Thickness%depth_zt(:,:,kl), do_wave) do j=jsc,jec do i=isc,iec @@ -1819,7 +1843,7 @@ subroutine bldepth(Thickness, sw_frac_zt) if(((rit(i,j,kl-1).lt.0).or.(rit(i,j,kl).lt.0)).and.hbl_with_rit) then ! Rib(i,j,ku) is not relevant, because locally unstable - Rib(i,j,kdn) = Ricr*0.1 + Rib(i,j,kdn) = Ricr*0.1 else @@ -1841,8 +1865,8 @@ subroutine bldepth(Thickness, sw_frac_zt) else hbl(i,j) = (-b_co + sqrt(sqrt_arg)) / (c2*a_co) endif - - kbl(i,j) = kl + + kbl(i,j) = kl iwet = iwet - 1 endif @@ -2024,13 +2048,14 @@ end subroutine bldepth ! ! ! -subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl) +subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl, do_wave) integer, intent(in) :: iwscale_use_hbl_eq_zt real, dimension(isd:,jsd:), intent(in) :: zt_kl + logical, intent(in) :: do_wave real :: zdiff, udiff, zfrac, ufrac, fzfrac - real :: wam, wbm, was, wbs, u3 + real :: wam, wbm, was, wbs, u3, langmuirfactor, Cw_smyth real :: zehat ! = zeta * ustar**3 integer :: iz, izp1, ju, jup1 integer :: i, j @@ -2124,6 +2149,22 @@ subroutine wscale(iwscale_use_hbl_eq_zt, zt_kl) endif +!----------- if do_wave, add Langmuir turbulence enhancement factor + + if (do_wave .and. do_langmuir) then + do j=jsc,jec + do i=isc,iec + Cw_smyth=Cw_0*(ustar(i,j)*ustar(i,j)*ustar(i,j)/(ustar(i,j)*ustar(i,j)*ustar(i,j) & + + Wstfac*von_karman*bfsfc(i,j)*hbl(i,j) + epsln))**l_smyth + langmuirfactor=sqrt(1+Cw_smyth*Ustk2(i,j)/(ustar(i,j)*ustar(i,j) + epsln)) + langmuirfactor = max(1.0, langmuirfactor) + langmuirfactor = min(LTmax, langmuirfactor) + ws(i,j)=ws(i,j)*langmuirfactor + wm(i,j)=wm(i,j)*langmuirfactor + enddo + enddo + endif + end subroutine wscale ! NAME="wscale" @@ -2345,11 +2386,12 @@ end subroutine ddmix ! ! ! -subroutine blmix_kpp(Thickness, diff_cbt, visc_cbt) +subroutine blmix_kpp(Thickness, diff_cbt, visc_cbt, do_wave) type(ocean_thickness_type), intent(in) :: Thickness real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt real, dimension(isd:,jsd:,:) , intent(inout) :: visc_cbt + logical, intent(in) :: do_wave real, dimension(isd:ied,jsd:jed) :: zt_kl_dummy @@ -2373,7 +2415,7 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbt) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy(:,:) = 0.0 - call wscale (iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale (iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) do j=jsc,jec do i = isc,iec @@ -2443,7 +2485,7 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbt) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy(:,:) = 0.0 - call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) !----------------------------------------------------------------------- ! compute the dimensionless shape functions at the interfaces @@ -2479,9 +2521,16 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbt) !----------------------------------------------------------------------- ! nonlocal transport term = ghats * A. Rosati - Martin Schmidt - Bill Large - Stephen Griffies - M.J. Harrison - Hyun-Chul Lee - - Vertical viscosity and diffusivity according KPP. - This module has extra code options to handle regions of extremely fresh water. - This particular version of the KPP module is frozen based on its use in MOM4p1 - at GFDL for the IPCC AR5 climate model ESM2M. - - This module computes vertical viscosity and diffusivity according to - the K-profile parameterization scheme of Large, McWilliams, and - Doney (1994). It computes both local and non-local mixing. - The code has been updated to MOM4p1, so that vertical grid increments - are suitable for generalized vertical coordinate models. When run - as geopotential model, there will be some differences, since the - MOM4.0 code (available in ocean_vert_kpp_mom4p0.F90) incorrectly - ignored the free surface undulations affecting the top model grid - cell thickness. - - This version of KPP has been implemented only for the Bgrid. - - W.G. Large and J.C. McWilliams and S.C. Doney - Oceanic vertical mixing: A review and a model with - a nonlocal boundary layer parameterization - Reviews of Geophysics (1994) vol 32 pages 363-403 - - Danabasoglu etal (2006) - Diurnal coupling in the tropical oceans of CCSM3 - Journal of Climate (2006) vol 19 pages 2347--2365 - - Original numerical algorithm by Bill Large at NCAR June 6, 1994 - - Equation numbers in the code refer to the Large etal paper. - - Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. - - Logical switch to enable kpp diffusion. Default is false. - - Logical switch for debugging. Default debug_this_module=.false. - - logical switch for shear instability mixing. - Default shear_instability=.true. - - Logical switch for double-diffusive mixing. - Default double_diffusion=.true. - - Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. - - Background vertical viscosity - - Enhanced vertical viscosity due to shear instability - - Enhanced vertical diffusivity due to shear instability - - Enhanced vertical viscosity in regions of convection - - Enhanced vertical diffusivity in regions of convection - - constant for pure convection (eqn. 23 of Large etal) - - Critical bulk Richardson number. Default from NCAR is - 0.3, though this number has a large uncertainty and some - find that 1.0 can be of use. - - logical switch for enabling the non-local mixing aspect of kpp. - Default is .true. as this is what the original KPP scheme suggests. - - Smooth boundary layer diffusitivies to remove grid scale noise. - Such noise is apparent in the diagnosed mixed layer depth as well - as the SST, especially when running coupled models where forcing - has high temporal frequency. - Default smooth_blmc=.false. - - Warning: This smoother can cause some problems with ghat in regions - of zero surface forcing. To understand details, one needs - the paper of Large et al. Vertical diffusion has the general form - <wx> = K(x_z - ghats) - In the surface layer a vertical scale function ws is estimated. - We have K ~ ws and ghats ~1/ws. If wind stress is zero the vertical - scale ws becomes zero too. Hence, ghats is very large - (something finite, since it is divided by ws+epsln). Now it may happen, - that the bouyancy flux becomes negative (~ -10-30). This enables - the nonlocal scheme. Because the mixing coefficient in the - surface boundary layer scales with ws the corresponding - time tendency should be of the order (1/ws * ws = finite). However, - if smooth_blmc is enabled, it may happen, that from neighbouring - points with different mixing depth a finite value for - the mixing coefficient leaks in. In this case - the tracer time tendency from the nonlocal scheme becomes huge - and the model fails. - - The smoother destroys the consistency between ghats and diff_cbt. - In most cases this should not matter, but the example shows, - that sudden model failure is possible under otherwise - stable and smooth conditions. - - - Lower loop index for finding new kbl. Needed for use with certain - tests of OBC, where kl_min=1 needed, whereas default in original - implementation has kl_min=2. Default in MOM is kl_min=2. - - For computing kbl as in the MOM4p0d code, which is taken from - the original NCAR scheme. If false, then will slightly modify - the logic. The modified logic has been found necessary when running - with as few as two grid cells in the vertical. - Default kbl_standard_method=.true. - - Limiting the boundary layer depth with the Ekman depth may result in a - shallow boundary layer. In this case the internal values of the vertical - mixing and viscosity coefficients may be large. This results in - unrealistically large non-local vertical mixing - Default limit_with_hekman=.true. - - Limits the non-local vertical tracer flux to the value of the tracer - surface flux. - Default limit_ghats=.false. - - The default method for determination of the boundary layer depth may fail - if the water column is instable (negative Richardson number) below or above - the layer that contains the diagnosed hbl. - With hbl_with_rit=.true. the search for the boundary layer depth is continued - downward in this case even if the bulk Richardson number exceeds the - critical value. This removes a lot of noise from the boundary layer depth. - Default hbl_with_rit=.false. - - Remove the shortwave radiation leaving the boundary layer to the ocean interior - (hence, not absorbed in the boundary layer) from non-local vertical heat flux - Default radiation_large=.false. - - Remove the all shortwave radiation from non-local vertical heat flux. - Default radiation_zero=.false. - - Keep only the shortwave radiation absorbed between the surface and a certain level - in non-local vertical heat flux through this level. - Default radiation_iow=.false. - - Use BV-freq. at the cell bottom instead of the cell top - as in Danabasoglu et al. (2006). - Default bvf_from_below=.false., as this will recover - older behaviour. - - Make vtc dependent on BV-freq. as in Danabasoglu et al. (2006). - Default variable_vtc=.false., as this will recover - older behaviour. - - Use maximum shear instead of 4-point average - (as in Danabasoglu et al. (2006)). - Default use_max_shear=.false., as this will recover - older behaviour. - - Use linear interpolation to find the position of hbl. - If set to false, then use the quadratic interpolation - as in Danabasoglu et al. (2006). The quadratic approach - generally yields a slightly deeper surface boundary layer. - Default linear_hbl=.true., as this will recover - older behaviour. - - For computing wsfc as in the MOM4p0d code, where we combine - the runoff+calving into a single field called river. - The alternative keeps the fields separate, as would be appropriate - for a land model that separately tracks the tracer content in the - calving and runoff. - Default wsfc_combine_runoff_calve=.true., as this will recover - the previous behaviour, to the bit. - - When smoothing the Richardson number, we do so over a vertical - column with max k-levels set by either kmt or kmu. The proper - approach is kmu, since we are smoothing riu. But for backwards - compatibility, we default to smooth_ri_kmax_eq_kmu=.false. - - Initialization for the KPP vertical mixing scheme - - This subroutine computes the vertical diffusivity and viscosity according - to the KPP scheme of Large etal. In brief, the scheme does the - following: - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Mixing is enhanced in places of static instability (local Ri < 0). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Double diffusion: - Interior mixing can be enhanced by double diffusion due to salt - fingering and diffusive convection ("double_diffusion=.true."). - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the oceanic boundary layer - ("hbl") gets computed by evaluating bulk richardson numbers. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - determined by turbulent surface fluxes, and interior mixing at - the lower boundary, i.e. at hbl. - - - The oceanic planetray boundary layer depth, hbl, is determined as - the shallowest depth where the bulk richardson number is - equal to the critical value, Ricr. - - Bulk Richardson numbers are evaluated by computing velocity and - buoyancy differences between values at zt(kl) and surface - reference values. - - In this configuration, the reference values are equal to the - values in the surface layer. - When using a very fine vertical grid, these values should be - computed as the vertical average of velocity and buoyancy from - the surface down to epsilon*zt(kl). - - When the bulk richardson number at k exceeds Ricr, hbl is - linearly interpolated between grid levels zt(k) and zt(k-1). - - The water column and the surface forcing are diagnosed for - stable/ustable forcing conditions, and where hbl is relative - to grid points (caseA), so that conditional branches can be - avoided in later subroutines. - - model - real zt(1:nk) = vertical grid (m)
- real dzt(1:nk) = layer thicknesses (m)
- - input - real dbloc(ij_bounds,nk) = local delta buoyancy (m/s^2)
- real dbsfc(ij_bounds,nk) = delta buoyancy w/ respect to sfc(m/s)^2
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real Bo(ij_bounds) = surface turbulent buoyancy forcing(m^2/s^3)
- real Bosol(ij_bounds) = radiative buoyancy forcing (m^2/s^3)
- real f(ij_bounds) = Coriolis parameter (1/s)
- integer jwtype(ij_bounds) = Jerlov water type (1 to 5)
- - output - real hbl(ij_bounds) ! boundary layer depth (m)
- real bfsfc(ij_bounds) !Bo+radiation absorbed to d=hbf*hbl(m^2/s^3)
- real stable(ij_bounds) ! =1 in stable forcing; =0 unstable
- real caseA(ij_bounds) ! =1 in case A, =0 in case B
- integer kbl(ij_bounds) ! index of first grid level below hbl
-- Compute turbulent velocity scales. - Use a 2D-lookup table for wm and ws as functions of ustar and - zetahat (=von_karman*sigma*hbl*bfsfc). - - Note: the lookup table is only used for unstable conditions - (zehat <= 0), in the stable domain wm (=ws) gets computed - directly. - - model - - input
- real sigma(ij_bounds) = normalized depth (d/hbl)
- real hbl(ij_bounds) = boundary layer depth (m)
- real ustar(ij_bounds) = surface friction velocity (m/s)
- real bfsfc(ij_bounds) = total surface buoyancy flux (m^2/s^3)
- output
- real wm(ij_bounds),ws(ij_bounds) ! turbulent velocity scales at sigma - local
- real zehat ! = zeta * ustar**3 - -- Compute interior viscosity and diffusivity due - to shear instability (dependent on a local richardson number), - to background internal wave activity, and - to static instability (local richardson number < 0). - - inputs: - - nk = number of vertical levels
- visc_cbu_iw = background "visc_cbu" (m**2/sec) due to internal waves
- diff_cbt_iw = background "diff_cbt" (m**2/sec) due to internal waves
- visc_cbu_limit = largest "visc_cbu" in regions of gravitational
- instability (m**2/sec)
- diff_cbt_limit = largest "diff_cbt" in regions of gravitational
- instability (m**2/sec) - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
-- Rrho dependent interior flux parameterization. - Add double-diffusion diffusivities to Ri-mix values at blending - interface and below. salt fingering code modified july 2003 - by stephen.griffies based on NCAR CCSM2.x - - inputs: - - nk = number of vertical levels
- real talpha(imt,km,jmw) ! d(rho)/ d(pot.temperature) (kg/m^3/C)
- real sbeta(imt,km,jmw) ! d(rho)/ d(salinity) (kg/m^3/PSU) - - outputs: - - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - - local - - real alphaDT(imt,km,jmw) ! alpha * DT across interfaces
- real betaDS(imt,km,jmw) ! beta * DS across interfaces
- -- Mixing coefficients within boundary layer depend on surface - forcing and the magnitude and gradient of interior mixing below - the boundary layer ("matching"). - - CAUTION: if mixing bottoms out at hbl = zt(nk) then - fictitious layer at nk+1 is needed with small but finite width - dzt(nk+1) (eg. epsln = 1.e-20). - - inputs: - - real ustar(ij_bounds) ! surface friction velocity (m/s)
- real bfsfc(ij_bounds) ! surface buoyancy forcing (m^2/s^3)
- real hbl(ij_bounds) ! boundary layer depth (m)
- real stable(ij_bounds) ! = 1 in stable forcing
- real caseA(ij_bounds) ! = 1 in case A
- integer kbl(ij_bounds) ! index of first grid level below hbl - - outputs: - - visc_cbu = viscosity coefficient at bottom of "u" cells (m**2/s)
- diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s)
- - real dkm1(ij_bounds,3) = boundary layer diff_cbt at kbl-1 level
- real blmc(ij_bounds,nk,3) = boundary layer mixing coeff.(m**2/s)
- real ghats(ij_bounds,nk) = nonlocal scalar transport
- - local: - - real gat1(ij_bounds,3)
- real dat1(ij_bounds,3)
- real sigma(ij_bounds) = normalized depth (d / hbl)
- real ws(ij_bounds), wm(ij_bounds) = turbulent velocity scales (m/s) - -- Enhance the diffusivity at the kbl-.5 interface - - input - integer kbl(ij_bounds) = grid above hbl
- real hbl(ij_bounds) = boundary layer depth (m)
- real dkm1(ij_bounds,3) = bl diffusivity at kbl-1 grid level
- real caseA(ij_bounds) = 1 in caseA, = 0 in case B - - input/output - real ghats(ij_bounds,nk) = nonlocal transport (s/m**2)
- modified ghats at kbl(i)-1 interface - output - real blmc(ij_bounds,nk,3) = enhanced boundary layer mixing coefficient - - local - real delta = fraction hbl lies beteen zt neighbors - -- Compute Richardson number on tracer and velocity cell bottoms. - rit = richardson number at bottom of T cells
- riu = richardson number at bottom of U cells -- Initialization of watermass diagnostic output files. - - Diagnose effects from KPP nonlocal on the watermass transformation. - o (eqn. 20) +! To include Langmuir turbulence effects, multiply ghats +! by a factor of Lgam (McWilliam & Sullivan 2001) !----------------------------------------------------------------------- - - ghats(i,j,ki) = (1.-stable(i,j)) * cg / (ws(i,j) * hbl(i,j) + epsln) + if (do_wave .and. do_langmuir) then + ghats(i,j,ki) = Lgam * (1.-stable(i,j)) * cg & + / (ws(i,j) * hbl(i,j) + epsln) + else + ghats(i,j,ki) = (1.-stable(i,j)) * cg & + / (ws(i,j) * hbl(i,j) + epsln) + endif endif enddo enddo @@ -2503,7 +2552,7 @@ subroutine blmix_kpp(Thickness, diff_cbt, visc_cbt) iwscale_use_hbl_eq_zt = 0 zt_kl_dummy(:,:) = 0.0 - call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy) + call wscale(iwscale_use_hbl_eq_zt, zt_kl_dummy, do_wave) do j=jsc,jec do i = isc,iec diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.html b/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.html deleted file mode 100644 index 56dcc4e2b2..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.html +++ /dev/null @@ -1,790 +0,0 @@ - - - - Module ocean_vert_kpp_test_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_kpp_test_mod
- - --Contact: A. Rosati -, - Martin Schmidt - -- - -
-Reviewers: Bill Large -, - Stephen Griffies -, - M.J. Harrison - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Vertical viscosity and diffusivity according KPP. - - This module has extra code options to handle regions of extremely fresh water. - - It also has options for both the Cgrid and Bgrid. - - It is undergoing further development in collaboration with NCAR scientists. - So it will undergo significant change during 2012. - -
- - - -- This module computes vertical viscosity and diffusivity according to - the K-profile parameterization scheme of Large, McWilliams, and - Doney (1994). It computes both local and non-local mixing. - The code has been updated to MOM4p1, so that vertical grid increments - are suitable for generalized vertical coordinate models. When run - as geopotential model, there will be some differences, since the - MOM4.0 code (available in ocean_vert_kpp_mom4p0.F90) incorrectly - ignored the free surface undulations affecting the top model grid - cell thickness. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_vert_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_kpp_test_init:
- -- -vert_mix_kpp_test:
- -- -bldepth:
- -- -wscale:
- -- -ri_iwmix:
- -- -ddmix:
- -- -blmix_kpp:
- -- -enhance:
- -- -watermass_diag_init:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_kpp_test_init
--
-- -DESCRIPTION -
-- - Initialization for the KPP vertical mixing scheme -
-
-
-- - -
-vert_mix_kpp_test
--
-- -DESCRIPTION -
-- - This subroutine computes the vertical diffusivity and viscosity according - to the KPP scheme of Large etal. In brief, the scheme does the - following: - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Mixing is enhanced in places of static instability (local Ri < 0). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Double diffusion: - Interior mixing can be enhanced by double diffusion due to salt - fingering and diffusive convection ("double_diffusion=.true."). - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the oceanic boundary layer - ("hbl") gets computed by evaluating bulk richardson numbers. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - determined by turbulent surface fluxes, and interior mixing at - the lower boundary, i.e. at hbl. - - NOTE: Use smf_bgrid since this uses the primary smf array read in from - the coupler in ocean_core/ocean_sbc.F90 when using the FMS coupler. - -
-
-
-- - -
-bldepth
--
-- -DESCRIPTION -
-- - The oceanic planetray boundary layer depth, hbl, is determined as - the shallowest depth where the bulk richardson number is - equal to the critical value, Ricr. - - Bulk Richardson numbers are evaluated by computing velocity and - buoyancy differences between values at zt(kl) and surface - reference values. - - In this configuration, the reference values are equal to the - values in the surface layer. - - When using a very fine vertical grid, these values should be - computed as the vertical average of velocity and buoyancy from - the surface down to epsilon*zt(kl). - - When the bulk richardson number at k exceeds Ricr, hbl is - linearly interpolated between grid levels zt(k) and zt(k-1). - - The water column and the surface forcing are diagnosed for - stable/ustable forcing conditions, and where hbl is relative - to grid points (caseA), so that conditional branches can be - avoided in later subroutines. - - input - real dbloc = local delta buoyancy (m/s^2) - real dbsfc = delta buoyancy w/ respect to sfc(m/s)^2 - real ustar = surface friction velocity (m/s) - real Bo = surface turbulent buoyancy forcing(m^2/s^3) - real Bosol = radiative buoyancy forcing (m^2/s^3) - real f = Coriolis parameter (1/s) - - output - real hbl ! boundary layer depth (m) - real bfsfc !Bo+radiation absorbed to d=hbf*hbl(m^2/s^3) - real stable ! =1 in stable forcing; =0 unstable - real caseA ! =1 in case A, =0 in case B - integer kbl ! index of first grid level below hbl - -
-
-
-- - -
-wscale
--
-- -DESCRIPTION -
-- - Compute turbulent velocity scales. - Use a 2D-lookup table for wm and ws as functions of ustar and - zetahat (=von_karman*sigma*hbl*bfsfc). - - Note: the lookup table is only used for unstable conditions - (zehat <= 0), in the stable domain wm (=ws) gets computed - directly. - - Note: the loop has been doubled to allow NEC compilers for vectorisation. - Speed gain was observed at the SX-6. - Later compiler versions may do better. - - - input
-
- real sigma = normalized depth (d/hbl)
- real hbl = boundary layer depth (m)
- real ustar = surface friction velocity (m/s)
- real bfsfc = total surface buoyancy flux (m^2/s^3)
- output
- real wm,ws ! turbulent velocity scales at sigma - local
- real zehat ! = zeta * ustar**3 - -
-
-- - -
-ri_iwmix
--
-- -DESCRIPTION -
-- - Compute interior viscosity and diffusivity due - to shear instability (dependent on a local richardson number), - to background internal wave activity, and - to static instability (local richardson number < 0). - - Diffusion and viscosity coefficients are on bottom - of T-cells. - -
-
-
-- - -
-ddmix
--
-- -DESCRIPTION -
-- - Rrho dependent interior flux parameterization. - Add double-diffusion diffusivities to Ri-mix values at blending - interface and below. salt fingering code modified july 2003 - by stephen.griffies based on NCAR CCSM2.x - - real talpha ! d(rho)/ d(pot.temperature) (kg/m^3/C)
-
- real sbeta ! d(rho)/ d(salinity) (kg/m^3/PSU) - - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - local - real alphaDT ! alpha * DT across interfaces - real betaDS ! beta * DS across interfaces - -
-
-- - -
-blmix_kpp
--
-- -DESCRIPTION -
-- - Mixing coefficients within boundary layer depend on surface - forcing and the magnitude and gradient of interior mixing below - the boundary layer ("matching"). - - CAUTION: if mixing bottoms out at hbl = zt(nk) then - fictitious layer at nk+1 is needed with small but finite width - dzt(nk+1) (eg. epsln = 1.e-20). - - inputs: - - real ustar ! surface friction velocity (m/s) - real bfsfc ! surface buoyancy forcing (m^2/s^3) - real hbl ! boundary layer depth (m) - real stable ! = 1 in stable forcing - real caseA ! = 1 in case A - integer kbl ! index of first grid level below hbl - - outputs: - - visc_cbt = viscosity coefficient at bottom of "t" cells (m**2/s) - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - real dkm1(,3) = boundary layer diff_cbt at kbl-1 level - real blmc(,nk,3) = boundary layer mixing coeff.(m**2/s) - real ghats(,nk) = nonlocal scalar transport - - local: - - real gat1(,3) - real dat1(,3) - real sigma() = normalized depth (d / hbl) - real ws(), wm() = turbulent velocity scales (m/s) - -
-
-
-- - -
-enhance
--
-- -DESCRIPTION -
-- - Enhance the diffusivity at the kbl-.5 interface - - input - integer kbl = grid above hbl - real hbl = boundary layer depth (m) - real dkm1 = bl diffusivity at kbl-1 grid level - real caseA = 1 in caseA, = 0 in case B - - input/output - real ghats = nonlocal transport (s/m**2) - modified ghats at kbl(i)-1 interface - output - real blmc = enhanced boundary layer mixing coefficient - - local - real delta = fraction hbl lies beteen zt neighbors - -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from KPP nonlocal on the watermass transformation. -
-
-
-
-NAMELIST
- --&ocean_vert_kpp_test_nml --
-
----
-- -use_this_module -
-- Logical switch to enable kpp diffusion. Default is false. -
-
-[logical] -- -debug_this_module -
-- Logical switch for debugging. Default debug_this_module=.false. -
-
-[logical] -- -shear_instability -
-- logical switch for shear instability mixing. - Default shear_instability=.true. -
-
-[logical] -- -double_diffusion -
-- Logical switch for double-diffusive mixing. - Default double_diffusion=.true. -
-
-[logical] -- -diff_cbt_iw -
-- Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. -
-
-[real, units: m^2/sec] -- -visc_cbu_iw -
-- Background vertical viscosity -
-
-[real, units: m^2/sec] -- -visc_cbu_limit -
-- Enhanced vertical viscosity due to shear instability -
-
-[real, units: m^2/sec] -- -diff_cbt_limit -
-- Enhanced vertical diffusivity due to shear instability -
-
-[real, units: m^2/sec] -- -visc_con_limit -
-- Enhanced vertical viscosity in regions of convection -
-
-[real, units: m^2/sec] -- -diff_con_limit -
-- Enhanced vertical diffusivity in regions of convection -
-
-[real, units: m^2/sec] -- -concv -
-- constant for pure convection (eqn. 23 of Large etal) -
-
-[real, units: dimensionless] -- -Ricr -
-- Critical bulk Richardson number. Default from NCAR is - 0.3, though this number has a large uncertainty and some - find that 1.0 can be of use. -
-
-[real, units: dimensionless] -- -non_local_kpp -
-- logical switch for enabling the non-local mixing aspect of kpp. - Default is .true. as this is what the original KPP scheme suggests. -
-
-[logical] -- -smooth_blmc -
-- Smooth boundary layer diffusitivies to remove grid scale noise. - Such noise is apparent in the diagnosed mixed layer depth as well - as the SST, especially when running coupled models where forcing - has high temporal frequency. - Default smooth_blmc=.false. - - Warning: This smoother can cause some problems with ghat in regions - of zero surface forcing. To understand details, one needs - the paper of Large et al. Vertical diffusion has the general form - <wx> = K(x_z - ghats) - In the surface layer a vertical scale function ws is estimated. - We have K ~ ws and ghats ~1/ws. If wind stress is zero the vertical - scale ws becomes zero too. Hence, ghats is very large - (something finite, since it is divided by ws+epsln). Now it may happen, - that the bouyancy flux becomes negative (~ -10-30). This enables - the nonlocal scheme. Because the mixing coefficient in the - surface boundary layer scales with ws the corresponding - time tendency should be of the order (1/ws * ws = finite). However, - if smooth_blmc is enabled, it may happen, that from neighbouring - points with different mixing depth a finite value for - the mixing coefficient leaks in. In this case - the tracer time tendency from the nonlocal scheme becomes huge - and the model fails. - - The smoother destroys the consistency between ghats and diff_cbt. - In most cases this should not matter, but the example shows, - that sudden model failure is possible under otherwise - stable and smooth conditions. - -
-
-[logical] -- -kl_min -
-- Lower loop index for finding new kbl. Needed for use with certain - tests of OBC, where kl_min=1 needed, whereas default in original - implementation has kl_min=2. Default in MOM is kl_min=2. -
-
-[integer] -- -kbl_standard_method -
-- For computing kbl as in the MOM4p0d code, which is taken from - the original NCAR scheme. If false, then will slightly modify - the logic. The modified logic has been found necessary when running - with as few as two grid cells in the vertical. - Default kbl_standard_method=.true. -
-
-[logical] -- -limit_with_hekman -
-- Limiting the boundary layer depth with the Ekman depth may result in a - shallow boundary layer. In this case the internal values of the vertical - mixing and viscosity coefficients may be large. This results in - unrealistically large non-local vertical mixing - Default limit_with_hekman=.true. -
-
-[logical] -- -limit_ghats -
-- Limits the non-local vertical tracer flux to the value of the tracer - surface flux. - Default limit_ghats=.false. -
-
-[logical] -- -hbl_with_rit -
-- The default method for determination of the boundary layer depth may fail - if the water column is instable (negative Richardson number) below or above - the layer that contains the diagnosed hbl. - With hbl_with_rit=.true. the search for the boundary layer depth is continued - downward in this case even if the bulk Richardson number exceeds the - critical value. This removes a lot of noise from the boundary layer depth. - Default hbl_with_rit=.false. -
-
-[logical] -- -radiation_large -
-- Remove the shortwave radiation leaving the boundary layer to the ocean interior - (hence, not absorbed in the boundary layer) from non-local vertical heat flux - Default radiation_large=.false. -
-
-[logical] -- -radiation_zero -
-- Remove the all shortwave radiation from non-local vertical heat flux. - Default radiation_zero=.false. -
-
-[logical] -- -radiation_iow -
-- Keep only the shortwave radiation absorbed between the surface and a certain level - in non-local vertical heat flux through this level. - Default radiation_iow=.false. -
-
-[logical] -- -bvf_from_below -
-- Use BV-freq. at the cell bottom instead of the cell top - as in Danabasoglu et al. (2006). - Default bvf_from_below=.false., as this will recover - older behaviour. -
-
-[logical] -- -variable_vtc -
-- Make vtc dependent on BV-freq. as in Danabasoglu et al. (2006). - Default variable_vtc=.false., as this will recover - older behaviour. -
-
-[logical] -- -use_max_shear -
-- Use maximum shear instead of 4-point average - (as in Danabasoglu et al. (2006)). - Default use_max_shear=.false., as this will recover - legacy behaviour. -
-
-[logical] -- -linear_hbl -
-- Use linear interpolation to find the position of hbl. - If set to false, then use the quadratic interpolation - as in Danabasoglu et al. (2006). The quadratic approach - generally yields a slightly deeper surface boundary layer. - Default linear_hbl=.true., as this will recover - older behaviour. -
-
-[logical] -- -wsfc_combine_runoff_calve -
-- For computing wsfc as in the MOM4p0d code, where we combine - the runoff+calving into a single field called river. - The alternative keeps the fields separate, as would be appropriate - for a land model that separately tracks the tracer content in the - calving and runoff. - Default wsfc_combine_runoff_calve=.true., as this will recover - the previous behaviour, to the bit. -
-
-[logical] -- -smooth_ri_kmax_eq_kmu -
-- When smoothing the Richardson number, we do so over a vertical - column with max k-levels set by either kmt or kmu. The proper - approach is kmu, since we are smoothing riu. But for backwards - compatibility, we default to smooth_ri_kmax_eq_kmu=.false. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - W.G. Large and J.C. McWilliams and S.C. Doney - Oceanic vertical mixing: A review and a model with - a nonlocal boundary layer parameterization - Reviews of Geophysics (1994) vol 32 pages 363-403 -
-- - Danabasoglu etal (2006) - Diurnal coupling in the tropical oceans of CCSM3 - Journal of Climate (2006) vol 19 pages 2347--2365 -
-
- - -
-NOTES
- -- Original numerical algorithm by Bill Large at NCAR June 6, 1994 --
-
- Equation numbers in the code refer to the Large etal paper. -
-
- Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. -
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.xml b/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.xml deleted file mode 100644 index 1716547fa4..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_kpp_test.xml +++ /dev/null @@ -1,356 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_mix.F90 b/src/mom5/ocean_param/vertical/ocean_vert_mix.F90 index 1aae09dc0a..9a457866df 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_mix.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_mix.F90 @@ -1,10 +1,10 @@ module ocean_vert_mix_mod #define COMP isc:iec,jsc:jec ! -! A. Rosati - Martin Schmidt - Bill Large - Stephen Griffies - M.J. Harrison - - Vertical viscosity and diffusivity according KPP. - - This module has extra code options to handle regions of extremely fresh water. - - It also has options for both the Cgrid and Bgrid. - - It is undergoing further development in collaboration with NCAR scientists. - So it will undergo significant change during 2012. - - - This module computes vertical viscosity and diffusivity according to - the K-profile parameterization scheme of Large, McWilliams, and - Doney (1994). It computes both local and non-local mixing. - The code has been updated to MOM4p1, so that vertical grid increments - are suitable for generalized vertical coordinate models. When run - as geopotential model, there will be some differences, since the - MOM4.0 code (available in ocean_vert_kpp_mom4p0.F90) incorrectly - ignored the free surface undulations affecting the top model grid - cell thickness. - - - W.G. Large and J.C. McWilliams and S.C. Doney - Oceanic vertical mixing: A review and a model with - a nonlocal boundary layer parameterization - Reviews of Geophysics (1994) vol 32 pages 363-403 - - Danabasoglu etal (2006) - Diurnal coupling in the tropical oceans of CCSM3 - Journal of Climate (2006) vol 19 pages 2347--2365 - - Original numerical algorithm by Bill Large at NCAR June 6, 1994 - - Equation numbers in the code refer to the Large etal paper. - - Surface fresh water contributes to surface buoyancy via conversion to - a locally implied salt flux. - - Logical switch to enable kpp diffusion. Default is false. - - Logical switch for debugging. Default debug_this_module=.false. - - logical switch for shear instability mixing. - Default shear_instability=.true. - - Logical switch for double-diffusive mixing. - Default double_diffusion=.true. - - Background vertical diffusivity. Note that if using Bryan-Lewis as a - background diffusivity, then should set diff_cbt_iw=0.0. - - Background vertical viscosity - - Enhanced vertical viscosity due to shear instability - - Enhanced vertical diffusivity due to shear instability - - Enhanced vertical viscosity in regions of convection - - Enhanced vertical diffusivity in regions of convection - - constant for pure convection (eqn. 23 of Large etal) - - Critical bulk Richardson number. Default from NCAR is - 0.3, though this number has a large uncertainty and some - find that 1.0 can be of use. - - logical switch for enabling the non-local mixing aspect of kpp. - Default is .true. as this is what the original KPP scheme suggests. - - Smooth boundary layer diffusitivies to remove grid scale noise. - Such noise is apparent in the diagnosed mixed layer depth as well - as the SST, especially when running coupled models where forcing - has high temporal frequency. - Default smooth_blmc=.false. - - Warning: This smoother can cause some problems with ghat in regions - of zero surface forcing. To understand details, one needs - the paper of Large et al. Vertical diffusion has the general form - <wx> = K(x_z - ghats) - In the surface layer a vertical scale function ws is estimated. - We have K ~ ws and ghats ~1/ws. If wind stress is zero the vertical - scale ws becomes zero too. Hence, ghats is very large - (something finite, since it is divided by ws+epsln). Now it may happen, - that the bouyancy flux becomes negative (~ -10-30). This enables - the nonlocal scheme. Because the mixing coefficient in the - surface boundary layer scales with ws the corresponding - time tendency should be of the order (1/ws * ws = finite). However, - if smooth_blmc is enabled, it may happen, that from neighbouring - points with different mixing depth a finite value for - the mixing coefficient leaks in. In this case - the tracer time tendency from the nonlocal scheme becomes huge - and the model fails. - - The smoother destroys the consistency between ghats and diff_cbt. - In most cases this should not matter, but the example shows, - that sudden model failure is possible under otherwise - stable and smooth conditions. - - - Lower loop index for finding new kbl. Needed for use with certain - tests of OBC, where kl_min=1 needed, whereas default in original - implementation has kl_min=2. Default in MOM is kl_min=2. - - For computing kbl as in the MOM4p0d code, which is taken from - the original NCAR scheme. If false, then will slightly modify - the logic. The modified logic has been found necessary when running - with as few as two grid cells in the vertical. - Default kbl_standard_method=.true. - - Limiting the boundary layer depth with the Ekman depth may result in a - shallow boundary layer. In this case the internal values of the vertical - mixing and viscosity coefficients may be large. This results in - unrealistically large non-local vertical mixing - Default limit_with_hekman=.true. - - Limits the non-local vertical tracer flux to the value of the tracer - surface flux. - Default limit_ghats=.false. - - The default method for determination of the boundary layer depth may fail - if the water column is instable (negative Richardson number) below or above - the layer that contains the diagnosed hbl. - With hbl_with_rit=.true. the search for the boundary layer depth is continued - downward in this case even if the bulk Richardson number exceeds the - critical value. This removes a lot of noise from the boundary layer depth. - Default hbl_with_rit=.false. - - Remove the shortwave radiation leaving the boundary layer to the ocean interior - (hence, not absorbed in the boundary layer) from non-local vertical heat flux - Default radiation_large=.false. - - Remove the all shortwave radiation from non-local vertical heat flux. - Default radiation_zero=.false. - - Keep only the shortwave radiation absorbed between the surface and a certain level - in non-local vertical heat flux through this level. - Default radiation_iow=.false. - - Use BV-freq. at the cell bottom instead of the cell top - as in Danabasoglu et al. (2006). - Default bvf_from_below=.false., as this will recover - older behaviour. - - Make vtc dependent on BV-freq. as in Danabasoglu et al. (2006). - Default variable_vtc=.false., as this will recover - older behaviour. - - Use maximum shear instead of 4-point average - (as in Danabasoglu et al. (2006)). - Default use_max_shear=.false., as this will recover - legacy behaviour. - - Use linear interpolation to find the position of hbl. - If set to false, then use the quadratic interpolation - as in Danabasoglu et al. (2006). The quadratic approach - generally yields a slightly deeper surface boundary layer. - Default linear_hbl=.true., as this will recover - older behaviour. - - For computing wsfc as in the MOM4p0d code, where we combine - the runoff+calving into a single field called river. - The alternative keeps the fields separate, as would be appropriate - for a land model that separately tracks the tracer content in the - calving and runoff. - Default wsfc_combine_runoff_calve=.true., as this will recover - the previous behaviour, to the bit. - - When smoothing the Richardson number, we do so over a vertical - column with max k-levels set by either kmt or kmu. The proper - approach is kmu, since we are smoothing riu. But for backwards - compatibility, we default to smooth_ri_kmax_eq_kmu=.false. - - Initialization for the KPP vertical mixing scheme - - This subroutine computes the vertical diffusivity and viscosity according - to the KPP scheme of Large etal. In brief, the scheme does the - following: - - --Compute interior mixing everywhere: - interior mixing gets computed at all cell interfaces due to constant - internal wave background activity ("visc_cbu_iw" and "diff_cbt_iw"). - Mixing is enhanced in places of static instability (local Ri < 0). - Additionally, mixing can be enhanced by contribution from shear - instability which is a function of the local Ri. - - --Double diffusion: - Interior mixing can be enhanced by double diffusion due to salt - fingering and diffusive convection ("double_diffusion=.true."). - - --Boundary layer: - - (A) Boundary layer depth: - at every gridpoint the depth of the oceanic boundary layer - ("hbl") gets computed by evaluating bulk richardson numbers. - - (B) Boundary layer mixing: - within the boundary layer, above hbl, vertical mixing is - determined by turbulent surface fluxes, and interior mixing at - the lower boundary, i.e. at hbl. - - NOTE: Use smf_bgrid since this uses the primary smf array read in from - the coupler in ocean_core/ocean_sbc.F90 when using the FMS coupler. - - - The oceanic planetray boundary layer depth, hbl, is determined as - the shallowest depth where the bulk richardson number is - equal to the critical value, Ricr. - - Bulk Richardson numbers are evaluated by computing velocity and - buoyancy differences between values at zt(kl) and surface - reference values. - - In this configuration, the reference values are equal to the - values in the surface layer. - - When using a very fine vertical grid, these values should be - computed as the vertical average of velocity and buoyancy from - the surface down to epsilon*zt(kl). - - When the bulk richardson number at k exceeds Ricr, hbl is - linearly interpolated between grid levels zt(k) and zt(k-1). - - The water column and the surface forcing are diagnosed for - stable/ustable forcing conditions, and where hbl is relative - to grid points (caseA), so that conditional branches can be - avoided in later subroutines. - - input - real dbloc = local delta buoyancy (m/s^2) - real dbsfc = delta buoyancy w/ respect to sfc(m/s)^2 - real ustar = surface friction velocity (m/s) - real Bo = surface turbulent buoyancy forcing(m^2/s^3) - real Bosol = radiative buoyancy forcing (m^2/s^3) - real f = Coriolis parameter (1/s) - - output - real hbl ! boundary layer depth (m) - real bfsfc !Bo+radiation absorbed to d=hbf*hbl(m^2/s^3) - real stable ! =1 in stable forcing; =0 unstable - real caseA ! =1 in case A, =0 in case B - integer kbl ! index of first grid level below hbl - - - Compute turbulent velocity scales. - Use a 2D-lookup table for wm and ws as functions of ustar and - zetahat (=von_karman*sigma*hbl*bfsfc). - - Note: the lookup table is only used for unstable conditions - (zehat <= 0), in the stable domain wm (=ws) gets computed - directly. - - Note: the loop has been doubled to allow NEC compilers for vectorisation. - Speed gain was observed at the SX-6. - Later compiler versions may do better. - - - input
- real sigma = normalized depth (d/hbl)
- real hbl = boundary layer depth (m)
- real ustar = surface friction velocity (m/s)
- real bfsfc = total surface buoyancy flux (m^2/s^3)
- output
- real wm,ws ! turbulent velocity scales at sigma - local
- real zehat ! = zeta * ustar**3 - -- Compute interior viscosity and diffusivity due - to shear instability (dependent on a local richardson number), - to background internal wave activity, and - to static instability (local richardson number < 0). - - Diffusion and viscosity coefficients are on bottom - of T-cells. - - - Rrho dependent interior flux parameterization. - Add double-diffusion diffusivities to Ri-mix values at blending - interface and below. salt fingering code modified july 2003 - by stephen.griffies based on NCAR CCSM2.x - - real talpha ! d(rho)/ d(pot.temperature) (kg/m^3/C)
- real sbeta ! d(rho)/ d(salinity) (kg/m^3/PSU) - - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - local - real alphaDT ! alpha * DT across interfaces - real betaDS ! beta * DS across interfaces - -- Mixing coefficients within boundary layer depend on surface - forcing and the magnitude and gradient of interior mixing below - the boundary layer ("matching"). - - CAUTION: if mixing bottoms out at hbl = zt(nk) then - fictitious layer at nk+1 is needed with small but finite width - dzt(nk+1) (eg. epsln = 1.e-20). - - inputs: - - real ustar ! surface friction velocity (m/s) - real bfsfc ! surface buoyancy forcing (m^2/s^3) - real hbl ! boundary layer depth (m) - real stable ! = 1 in stable forcing - real caseA ! = 1 in case A - integer kbl ! index of first grid level below hbl - - outputs: - - visc_cbt = viscosity coefficient at bottom of "t" cells (m**2/s) - diff_cbt = diffusion coefficient at bottom of "t" cells (m**2/s) - - real dkm1(,3) = boundary layer diff_cbt at kbl-1 level - real blmc(,nk,3) = boundary layer mixing coeff.(m**2/s) - real ghats(,nk) = nonlocal scalar transport - - local: - - real gat1(,3) - real dat1(,3) - real sigma() = normalized depth (d / hbl) - real ws(), wm() = turbulent velocity scales (m/s) - - - Enhance the diffusivity at the kbl-.5 interface - - input - integer kbl = grid above hbl - real hbl = boundary layer depth (m) - real dkm1 = bl diffusivity at kbl-1 grid level - real caseA = 1 in caseA, = 0 in case B - - input/output - real ghats = nonlocal transport (s/m**2) - modified ghats at kbl(i)-1 interface - output - real blmc = enhanced boundary layer mixing coefficient - - local - real delta = fraction hbl lies beteen zt neighbors - - - Initialization of watermass diagnostic output files. - - Diagnose effects from KPP nonlocal on the watermass transformation. - S.M. Griffies +! S.M. Griffies ! ! -!A. Rosati +! A. Rosati ! ! !@@ -661,9 +661,9 @@ module ocean_vert_mix_mod real, dimension(:,:,:), allocatable :: flux_z character(len=128) :: version = & - '$Id: ocean_vert_mix.F90,v 1.1.2.19 2012/06/08 20:33:57 Stephen.Griffies Exp $' + '$Id: ocean_vert_mix.F90,v 20.0 2013/12/14 00:16:48 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' logical :: module_is_initialized = .false. logical :: debug_this_module = .false. @@ -2784,7 +2784,7 @@ end subroutine watermass_diag_init ! subroutine vert_mix_coeff(Time, Thickness, Velocity, T_prog, & T_diag, Dens, swflx, sw_frac_zt, pme,& - river, visc_cbu, visc_cbt, diff_cbt, hblt_depth) + river, visc_cbu, visc_cbt, diff_cbt, hblt_depth, do_wave) type(ocean_time_type), intent(in) :: Time type(ocean_thickness_type), intent(in) :: Thickness @@ -2800,9 +2800,12 @@ subroutine vert_mix_coeff(Time, Thickness, Velocity, T_prog, & real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt real, dimension(isd:,jsd:), intent(inout) :: hblt_depth + logical, intent(in) :: do_wave - integer :: i,j,k,kp1,tau - real :: tmp + integer :: i,j,k,kp1,n,tau + real :: tmp, rescale + real :: dnu_dtheta_dz, dnu_dsalinity_dz, dtheta_dz, dsalinity_dz + real :: global_mean tau = Time%tau @@ -2826,7 +2829,7 @@ subroutine vert_mix_coeff(Time, Thickness, Velocity, T_prog, & elseif(MIX_SCHEME == VERTMIX_KPP_MOM4P0) then call mpp_clock_begin(id_clock_vert_kpp_mom4p0) call vert_mix_kpp_mom4p0(aidif, Time, Thickness, Velocity, T_prog, T_diag, Dens, & - swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth) + swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth, do_wave) ! since this scheme is frozen, we do not compute visc_cbt. ! for vertical reynolds diagnostics, we set visc_cbt = visc_cbu @@ -2835,7 +2838,7 @@ subroutine vert_mix_coeff(Time, Thickness, Velocity, T_prog, & elseif(MIX_SCHEME == VERTMIX_KPP_MOM4P1) then call mpp_clock_begin(id_clock_vert_kpp_mom4p1) call vert_mix_kpp_mom4p1(aidif, Time, Thickness, Velocity, T_prog, T_diag, Dens, & - swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth) + swflx, sw_frac_zt, pme, river, visc_cbu, diff_cbt, hblt_depth, do_wave) ! since this scheme is frozen, we do not compute visc_cbt. ! for vertical reynolds diagnostics, we set visc_cbt = visc_cbu @@ -2843,8 +2846,8 @@ subroutine vert_mix_coeff(Time, Thickness, Velocity, T_prog, & elseif(MIX_SCHEME == VERTMIX_KPP_TEST) then call mpp_clock_begin(id_clock_vert_kpp_test) - call vert_mix_kpp_test(Time, Thickness, Velocity, T_prog, T_diag, Dens, & - swflx, sw_frac_zt, pme, river, visc_cbu, visc_cbt, diff_cbt, hblt_depth) + call vert_mix_kpp_test(aidif, Time, Thickness, Velocity, T_prog, T_diag, Dens, & + swflx, sw_frac_zt, pme, river, visc_cbu, visc_cbt, diff_cbt, hblt_depth, do_wave) call mpp_clock_end(id_clock_vert_kpp_test) elseif(MIX_SCHEME == VERTMIX_PP) then diff --git a/src/mom5/ocean_param/vertical/ocean_vert_mix.html b/src/mom5/ocean_param/vertical/ocean_vert_mix.html deleted file mode 100644 index d2e137eef7..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_mix.html +++ /dev/null @@ -1,1084 +0,0 @@ - - - - Module ocean_vert_mix_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_mix_mod
- - - - - -
-OVERVIEW
- -- Time tendency from vertical mixing -
- - - -- This module does the following: - - --computes the vertical mixing coefficients for tracer and velocity, - --computes thickness weighted and density weighted - time tendency for tracer due to vertical diffusion processes, - --computes the thickness weighted and density weighted - acceleration for velocity due to vertical friction processes. - - Account is taken of the differences between Bgrid and Cgrid - implementations of MOM. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
field_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_util_mod
ocean_vert_const_mod
ocean_vert_chen_mod
ocean_vert_gotm_mod
ocean_vert_kpp_test_mod
ocean_vert_kpp_mom4p0_mod
ocean_vert_kpp_mom4p1_mod
ocean_vert_pp_mod
ocean_vert_tidal_mod
ocean_vert_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_mix_init:
- -- -diff_cbt_table_init:
- -- -bryan_lewis_init:
- -- -hwf_init:
- -- -diff_cbt_tanh_init:
- -- -vert_friction_init:
- -- -watermass_diag_init:
- -- -vert_mix_coeff:
- -- -vert_diffuse:
- -- -vert_diffuse_implicit:
- -- -vert_friction_bgrid:
- -- -vert_friction_cgrid:
- -- -vert_friction_implicit_bgrid:
- -- -vert_friction_implicit_cgrid:
- -- -on_comp_domain:
- -- -invcosh:
- -- -vmix_min_dissipation:
- -- -watermass_diag:
- -- -vert_diffuse_implicit_diag:
- -- -vert_diffuse_watermass_diag:
- -- -ocean_vert_mix_restart:
- -- -ocean_vert_mix_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_mix_init
--
-- -DESCRIPTION -
-- - Initialization for the vertical mixing module. -
-
-
-- - -
-diff_cbt_table_init
--
-- -DESCRIPTION -
-- - Read in static diffusivities that have been entered to the diff_cbt_table. -
-
-
-- - -
-bryan_lewis_init
--
-- -DESCRIPTION -
-- - Initialize the Bryan-Lewis static background diffusivities. -
-
-
-- - -
-hwf_init
--
-- -DESCRIPTION -
-- - Initialize the HWF static background diffusivity. - - Two forms are available: - - 1/ Depth dependent form, meant to emulate the Bryan-Lewis approach. - This form is not generally used at GFDL. - - 2/ Depth independent form motivated by use in the CM2G isopycnal - ocean climate model at GFDL. - -
-
-
-- - -
-diff_cbt_tanh_init
--
-- -DESCRIPTION -
-- - Initialize the tanh background diffusivity. -
-
-
-- - -
-vert_friction_init
--
-- -DESCRIPTION -
-- - Initialize vertical friction portion of ocean_vert_mix_mod -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialization of watermass diagnostic output files. - Also determine the logical compute_watermass_diag. -
-
-
-- - -
-vert_mix_coeff
--
-- -DESCRIPTION -
-- - This subroutine calls the relevant scheme to compute vertical - diffusivity and vertical viscosity. Background values are - also incorporated here. -
-
-
-- - -
-vert_diffuse
--
-- -DESCRIPTION -
-- - This subroutine computes the thickness weighted and density - weighted time tendency for tracer associated with vertical diffusion - based on explicit time update of the vertical diffusion equation. - - MOM only supports aidif==0.0 or aidif==1.0. - MOM does not support cases with 0.0 < aidif < 1.0. - - The watermass diagnostics have not been ported to this subroutine - since aidif=0 is rarely used, even in idealized studies. - -
-
-
-- - -
-vert_diffuse_implicit
--
-- -DESCRIPTION -
-- - Contributions to thickness weighted and density weighted time - tendency from time-implicit vertical diffusion. -
-
-
-- - -
-vert_friction_bgrid
--
-- -DESCRIPTION -
-- - This subroutine computes the thickness weighted and density weighted - acceleration (kg/m^3)*(m^2/s^2) associated with vertical friction. - - Assumes here that the horizontal grid is B-grid. - - For aidif=1.0, this module does nothing since all vertical friction - is in this case handled implicitly in time, and this is computed - elswewhere. - - MOM only supports aidif==0.0 or aidif==1.0. - MOM does not support cases with 0.0 < aidif < 1.0. - - Note that smf and bmf have units (kg/m^3)*(m^2/s^2) - So the vertical diffusive fluxes must be in these units - too. For this purpose, we multiply the viscosity by - rho0. This is an approximation consistent with the - Boussinesq approximation. For non-Boussinesq, we - should be using the in situ rho. But to the level of - accuracy that we know the vertical viscosity, and to - the extent that the ocean density is close to rho0, - our use of rho0 for the non-Boussinesq case is of - minor consequence for vertical friction calculation. - - Note: the form drag contribution to vertical viscosity - must be handled within aidif=1.0 implicit vertical - mixing. It is ignored in this routine, as its - contribution would generally cause the model to be - unstable. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - -
-
-
-- - -
-vert_friction_cgrid
--
-- -DESCRIPTION -
-- - This subroutine computes the thickness weighted and density weighted - acceleration (kg/m^3)*(m^2/s^2) associated with vertical friction. - Assumes horizontal grid is C-grid. - - For aidif=1.0, this module does nothing since all vertical friction - is instead handled implicitly in time, and this is computed in the - velocity module. - - MOM only supports aidif==0.0 or aidif==1.0. - MOM does not support cases with 0.0 < aidif < 1.0. - - Note that smf and bmf have units (kg/m^3)*(m^2/s^2) - So the vertical diffusive fluxes must be in these units - too. For this purpose, we multiply the viscosity by - rho0. This is an approximation consistent with the - Boussinesq approximation. For non-Boussinesq, we - should be using the in situ rho. But to the level of - accuracy that we know the vertical viscosity, and to - the extent that the ocean density is close to rho0, - our use of rho0 for the non-Boussinesq case is of - minor consequence for vertical friction calculation. - - Note: use visc_cbt for both C-grid velocity components, - even though the velocity components sit at different - sides of the tracer cell. This choice is for simplicity. - It also acknowledges that the alternative of introducing - distinct visc_cbt_u and visc_cbt_v would presume knowledge - of subgrid scale features that we really do not have. - So again, visc_cbt is used for both u,v C-grid velocity - components. - - Note: the form drag contribution to vertical viscosity - must be handled within aidif=1.0 implicit vertical - mixing. It is ignored in this routine, as its - contribution would generally cause the model to be - unstable. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - -
-
-
-- - -
-vert_friction_implicit_bgrid
--
-- -DESCRIPTION -
-- - Contributions to thickness weighted and density weighted acceleration - from implicit vertical friction. - - Assume that the horizontal grid is B-grid. - - Note that smf and bmf have units N/m^2. These are the natural units - for surface stress. To include these stresses as boundary terms in the - call to invtri, it is necessary to use vertical viscosities with units - (kg/m^3)*(m2^/s) = N/m^2. This is achieved by multiplying visc_cbu - by rho0 when sent to invtri. For depth-like vertical coordinates, this - is cancelled exactly by the rho0 in rho_dzu. For pressure-like - vertical coordinates, the rho0*visc_cbu introduces a negligible - change in the vertical viscosity that is well within uncertainty - in this coefficient. - - Include visc_cbu_form_drag to each of the velocity components - vertical friction. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - -
-
-
-- - -
-vert_friction_implicit_cgrid
--
-- -DESCRIPTION -
-- - Contributions to thickness weighted and density weighted acceleration - from implicit vertical friction. - - Assume that the horizontal grid is C-grid. - - Note that smf and bmf have units N/m^2. These are the natural units - for surface stress. To include these stresses as boundary terms in the - call to invtri, it is necessary to use vertical viscosities with units - (kg/m^3)*(m2^/s) = N/m^2. This is achieved by multiplying visc_cbu - by rho0 when sent to invtri. For depth-like vertical coordinates, this - is cancelled exactly by the rho0 in rho_dzu. For pressure-like - vertical coordinates, the rho0*visc_cbu introduces a negligible - change in the vertical viscosity that is well within uncertainty - in this coefficient. - - Include visc_cbu_form_drag to each of the velocity components - vertical friction. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - - Note: use visc_cbt for both C-grid velocity components, - even though the velocity components sit at different - sides of the tracer cell. This choice is for simplicity. - It also acknowledges that the alternative of introducing - distinct visc_cbt_u and visc_cbt_v would presume knowledge - of subgrid scale features that we really do not have. - So again, visc_cbt is used for both u,v C-grid velocity - components. - -
-
-
-- - -
-on_comp_domain
--
-- -DESCRIPTION -
-- - Determine if the point is in comp-domain for the processor. -
-
-
-- - -
-invcosh
--
-- -DESCRIPTION -
-- - Inverse cosh function. Argument must be >=1. -
-
-
-- - -
-vmix_min_dissipation
--
-- -DESCRIPTION -
-- - Impose a floor to the dissipation arising from vertical tracer diffusion. -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose watermass transformation diagnostics for - --sbc - --bbc - --vmix = diff_cbt + K33-implicit neutral diffusion - Estimations of the contributions from diff_cbt alone, and - from K33-implicit alone, are computed in vert_diffuse_watermass_diag. - - The diagnostic for vdiffuse computes all processes in one - invtri call, which is actually how the model prognostically - updates tracers from vertical diffusion. - - The sum of the sbc + bbc + vmix should equal to the - full vdiffuse diagnostic, so that, for example, - - neut_rho_vdiffuse = neut_rho_sbc + neut_rho_bbc + neut_rho_vmix - - Additionally, we should have - - neut_rho_vmix = neut_rho_diff_cbt + neut_rho_k33 - - with the terms neut_rho_diff_cbt and neut_rho_k33 computed - in routine vert_diffuse_watermass_diag. - - watermass_diag is called prior to implicit update of the tracer - fields, so that the initial taup1 value contains only explicit - in-time tendencies. The incremental tendencies are diagnosed - in this routine by various calls to invtri using same methods - as for the prognostic calculation. - - This routine requires the logical compute_watermass_diag=.true., - which is determined inside watermass_diag_init. - -
-
-
-- - -
-vert_diffuse_implicit_diag
--
-- -DESCRIPTION -
-- - Diagnose contributions from time-implicit vertical diffusion. - - We perform the diagnostics using the taup1 value of the tracer - concentration, obtained after performing the invtri step. - The fluxes are diagnosed as if we are performing an explicit-time - update, but using the taup1 values of the tracer concentrations. - - This diagnostic suffers from time truncation errors relative to the - prognostic calculation, since the prognostic time update is performed using - an invtri calculation. However, the errors are small. The alternative - method, which is to separate the combined invtri step into individual - physical mixing processes is not an option, since this step is not equivalent - algorithmically to the single invtri mixing step. - It is for this reason that we perform the diagnostic step using this - "explicit flux computed with time-implicit computed concentration" approach. - - In contrast to the interior mixing, the boundary fluxes can be diagnostically - split from the invtri step, as these fluxes are determined prior to the - vert_diffuse_implicit routine. Hence, the boundary flux contributions can - be diagnosed either by calling an invtri step passing just the stf and btf - terms, or by using the even simpler methods in this subroutine. - -
-
-
-- - -
-vert_diffuse_watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose contributions from time-implicit vertical diffusion - acting on watermasses from diff_cbt and k33. - - We perform the diagnostics using the taup1 value of the tracer - concentration, obtained after performing the invtri step. - The fluxes are diagnosed as if we are performing an explicit-time - update, but using the taup1 values of the tracer concentrations. - - This diagnostic suffers from time truncation errors relative to the - prognostic calculation, since the prognostic time update is performed using - an invtri calculation. However, the errors are small. The alternative - method, which is to separate the combined invtri step into individual - physical mixing processes is not an option, since this step is not equivalent - algorithmically to the single invtri mixing step. - It is for this reason that we perform the diagnostic step using this - "explicit flux computed with time-implicit computed concentration" approach. - -
-
-
-- - -
-ocean_vert_mix_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_vert_mix_end
--
-- -DESCRIPTION -
-- - Chen Scheme requires output of Krauss mixed layer for - reproducible results. - - GOTM requires fields for advection tendency. - -
-
-
-
-NAMELIST
- --&ocean_vert_mix_nml --
-
----
-- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -- -aidif -
-- aidif=1 for implicit in time solution of the vertical mixing equation. - aidif=0 for explicit in time solution of the vertical mixing equation. - semi-implicit method with 0 < aidif < 1 is not fully supported in MOM. -
-
-[real] -- -use_explicit_vert_diffuse -
-- Must be true to use time-explicit vertical tracer diffusion. -
-
-[logical] -- -verbose_init -
-- For verbose writes during initialization. -
-
-[logical] -- -vert_mix_scheme -
-- To determine the vertical mixing scheme: - "const", "kpp", "kpp_mom4p0","kpp_mom4p1", "chen", "pp", or "gotm". -
-
-[character] -- -vert_diff_back_via_max -
-- If .true. then include a static background diffusivity - via the max function, as used in mom4p0d. The alternative - is via simply adding the background to the diffusivity - obtained via other approaches. This option remains for - legacy. Default is vert_diff_back_via_max=.true. -
-
-[logical] -- -vert_visc_back -
-- If .true. then include a static depth dependent vertical - viscosity which is used only if running w/ constant - vertical viscosity scheme. Standard application is when - have a model with fine vertical resolution, yet no mixed - layer scheme. Wind stress must be spread deeper than the - top cell, or the model may go unstable, or at the least it - will produce spuriously large vertical shears. -
-
-[logical] -- -visc_cbu_back_max -
-- For use in setting background vertical viscosity. -
-
-[real, units: m^2/sec] -- -visc_cbu_back_min -
-- For use in setting background vertical viscosity. -
-
-[real, units: m^2/sec] -- -visc_cbu_back_zmid -
-- Mid-point of tanh function used to define background vertical viscosity. -
-
-[real, units: m] -- -visc_cbu_back_zwid -
-- Width of tanh function used to define background vertical viscosity. -
-
-[real, units: m] -- -diff_cbt_tanh -
-- For enabling tanh background vertical diffusivity profile. - Default diff_cbt_tanh=.false. -
-
-[logical] -- -diff_cbt_tanh_max -
-- For use in setting background vertical diffusivity. - Default diff_cbt_tanh_max=1e-3. -
-
-[real, units: m^2/sec] -- -diff_cbt_tanh_min -
-- For use in setting background vertical diffusivity. - Default diff_cbt_tanh_min=2e-5. -
-
-[real, units: m^2/sec] -- -diff_cbt_tanh_zmid -
-- Mid-point of tanh function used to define background vertical diffusivity. - Default diff_cbt_tanh_zmid=150.0. -
-
-[real, units: m] -- -diff_cbt_tanh_zwid -
-- Width of tanh function used to define background vertical diffusivity. - Default diff_cbt_tanh_zwid=30.0. -
-
-[real, units: m] -- -hwf_diffusivity -
-- 3D background diffusivity which gets smaller in equatorial region. - Based on the work of Henyey etal (1986). - This scheme should NOT be used if Bryan-Lewis is used. - Default hwf_diffusivity=.false. -
-
-[logical] -- -hwf_diffusivity_3d -
-- 3D background diffusivity which gets smaller in equatorial region. - Based on the work of Henyey etal (1986). - This form has not been used much at GFDL, with preference given to - a simpler two-dimensional (depth independent) form assessed with the - default hwf_diffusivity_3d=.false. -
-
-[logical] -- -hwf_depth_transition -
-- Depth of transition for hwf scheme. The HWF method actually has - no depth dependence. But we include the atan depth dependency - from Bryan-Lewis, for those cases where we wish to replace - Bryan-Lewis with the HWF scheme. To get the usual Bryan-Lewis - transition, set hwf_depth_transition=2500.0. However, since - we often use hwf in the presence of tide mixing, we do not wish to - have any depth dependence, in which case the default is - hwf_depth_transition=2500.0e4. -
-
-[real, units: m] -- -hwf_min_diffusivity -
-- Minimum diffusivity for the HWF scheme. - Default hwf_min_diffusivity=2e-6. -
-
-[real, units: m^2/sec] -- -hwf_30_diffusivity -
-- Diffusivity at 30deg latitude for the HWF scheme. - Default hwf_30_diffusivity=2e-5. -
-
-[real, units: m^2/sec] -- -hwf_N0_2Omega -
-- Ratio of the typical Buoyancy frequency to - twice the earth's rotation period. - Default hwf_N0_2Omega=20.0. -
-
-[real, units: dimensionless] -- -bryan_lewis_diffusivity -
-- If .true. then add a Bryan-Lewis background to the - diffusivity. This background is a time-independent function - of depth. This diffusivity is NOT used when have - use_pp_vert_mix_coeff=.true. - This scheme should NOT be used if HWF is used. -
-
-[logical] -- -bryan_lewis_lat_depend -
-- If .true. then allow for Bryan-Lewis background to be different - outside of a tropical band than inside the band. -
-
-[logical] -- -bryan_lewis_lat_transition -
-- North/South latitude where transition from Bryan-Lewis values - in the tropic to those in the higher latitudes. -
-
-[real] -- -afkph_90, dfkph_90, sfkph_90, zfkph_90 -
-- Parameters setting the Bryan-Lewis vertical diffusivity profile. - When use bryan_lewis_lat_depend, these are the values used in the pole. -
-
-[real, units: dimensionless] -- -afkph_00, dfkph_00, sfkph_00, zfkph_00 -
-- Parameters setting the Bryan-Lewis vertical diffusivity profile in the tropics. - When use bryan_lewis_lat_depend=.true. , these are the values used in the tropics. - When use bryan_lewis_lat_depend=.false., these are the values used globally. -
-
-[real, units: dimensionless] -- -use_diff_cbt_table -
-- If .true., then read in a table that specifies (i,j,ktop-->kbottom) - and the diffusivity. This method is useful when aiming to mix vertically - at points where do cross-land insertion or where may wish to enhance - mixing at river mouths. -
-
-[logical] -- -linear_taper_diff_cbt_table -
-- If .true., then linear taper the diff_cbt_table value from - so that it gets smaller with depth. -
-
-[logical] -- -vmix_rescale_nonbouss -
-- To rescale the vertical mixing coefficients by rho0/rho - in order to bring the effects from vertical diffusion - in a non-Boussinesq model more in line with that from a - Boussinesq model. - Default vmix_rescale_nonbouss=.false. -
-
-[logical] -- -vmix_set_min_dissipation -
-- To set a minimum dissipation rate. This scheme will compute the - dissipation from the full diffusivity. If the resulting dissipation - is smaller than a specified dissipation, then the diffusivity will - be locally increased so that the min dissipation is maintained. - Default vmix_set_min_dissipation=.false. -
-
-[logical] -- -vmix_min_diss_const -
-- Minimum dissipation rate as a constant. - Default vmix_min_diss_const=1e-7. -
-
-[real, units: W/m^3] -- -vmix_min_diss_bvfreq_scale -
-- Scaling use to set the minimum dissipation rate as determined by the - local stratification. - Default vmix_min_diss_bvfreq_scale=6e-4. -
-
-[real, units: J/m^3] -- -vmix_min_diss_flux_ri_max -
-- Maximum flux Richardson number for computation of diffusivity from dissipation. - Default vmix_min_diss_flux_ri_max=0.2. -
-
-[real, units: dimensionless] -
- - - - -
-REFERENCES
- ----
-- - Kirk Bryan and L.J. Lewis - A water mass model of the world ocean - Journal of Geophysical Research (1979) vol 84, pages 2503--2517 -
-- - Elements of MOM (2012) - S.M. Griffies -
-- - Henyey, F.S., J. Wright, and S.M. Flatte, 1986: Energy and - action flow through the internal wave field: an eikonal approach. - Journal of Geophysical Research, {\bf 91}, Issue C7, 8487--8496. -
-
- - -
-NOTES
- -- The Bryan-Lewis vertical diffusivity is small in the upper ocean and - increases with depth according to an inverse tangent profile. The default - values are from roughly 0.05e-5 m^2/sec to roughly 1.0e-4 m^2/sec. - Latitudinally dependent Bryan-Lewis values are available. --
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_mix.xml b/src/mom5/ocean_param/vertical/ocean_vert_mix.xml deleted file mode 100644 index fa85381c77..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_mix.xml +++ /dev/null @@ -1,438 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_pp.F90 b/src/mom5/ocean_param/vertical/ocean_vert_pp.F90 index 88a2746f0a..cd48bbf737 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_pp.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_pp.F90 @@ -97,10 +97,10 @@ module ocean_vert_pp_mod integer :: horz_grid character(len=128) :: version = & - '$Id: ocean_vert_pp.F90,v 1.1.2.4 2012/06/03 00:41:57 Stephen.Griffies Exp $' + '$Id: ocean_vert_pp.F90,v 20.0 2013/12/14 00:16:50 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' ! for diagnostics integer :: id_diff_cbt_pp= -1 diff --git a/src/mom5/ocean_param/vertical/ocean_vert_pp.html b/src/mom5/ocean_param/vertical/ocean_vert_pp.html deleted file mode 100644 index 7ca2f7be93..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_pp.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - S.M. Griffies - A. Rosati - - Time tendency from vertical mixing - - This module does the following: - - --computes the vertical mixing coefficients for tracer and velocity, - --computes thickness weighted and density weighted - time tendency for tracer due to vertical diffusion processes, - --computes the thickness weighted and density weighted - acceleration for velocity due to vertical friction processes. - - Account is taken of the differences between Bgrid and Cgrid - implementations of MOM. - - - Kirk Bryan and L.J. Lewis - A water mass model of the world ocean - Journal of Geophysical Research (1979) vol 84, pages 2503--2517 - - Elements of MOM (2012) - S.M. Griffies - - Henyey, F.S., J. Wright, and S.M. Flatte, 1986: Energy and - action flow through the internal wave field: an eikonal approach. - Journal of Geophysical Research, {\bf 91}, Issue C7, 8487--8496. - - The Bryan-Lewis vertical diffusivity is small in the upper ocean and - increases with depth according to an inverse tangent profile. The default - values are from roughly 0.05e-5 m^2/sec to roughly 1.0e-4 m^2/sec. - Latitudinally dependent Bryan-Lewis values are available. - - For debugging purposes. - - aidif=1 for implicit in time solution of the vertical mixing equation. - aidif=0 for explicit in time solution of the vertical mixing equation. - semi-implicit method with 0 < aidif < 1 is not fully supported in MOM. - - Must be true to use time-explicit vertical tracer diffusion. - - For verbose writes during initialization. - - To determine the vertical mixing scheme: - "const", "kpp", "kpp_mom4p0","kpp_mom4p1", "chen", "pp", or "gotm". - - If .true. then include a static background diffusivity - via the max function, as used in mom4p0d. The alternative - is via simply adding the background to the diffusivity - obtained via other approaches. This option remains for - legacy. Default is vert_diff_back_via_max=.true. - - If .true. then include a static depth dependent vertical - viscosity which is used only if running w/ constant - vertical viscosity scheme. Standard application is when - have a model with fine vertical resolution, yet no mixed - layer scheme. Wind stress must be spread deeper than the - top cell, or the model may go unstable, or at the least it - will produce spuriously large vertical shears. - - For use in setting background vertical viscosity. - - For use in setting background vertical viscosity. - - Mid-point of tanh function used to define background vertical viscosity. - - Width of tanh function used to define background vertical viscosity. - - For enabling tanh background vertical diffusivity profile. - Default diff_cbt_tanh=.false. - - For use in setting background vertical diffusivity. - Default diff_cbt_tanh_max=1e-3. - - For use in setting background vertical diffusivity. - Default diff_cbt_tanh_min=2e-5. - - Mid-point of tanh function used to define background vertical diffusivity. - Default diff_cbt_tanh_zmid=150.0. - - Width of tanh function used to define background vertical diffusivity. - Default diff_cbt_tanh_zwid=30.0. - - 3D background diffusivity which gets smaller in equatorial region. - Based on the work of Henyey etal (1986). - This scheme should NOT be used if Bryan-Lewis is used. - Default hwf_diffusivity=.false. - - 3D background diffusivity which gets smaller in equatorial region. - Based on the work of Henyey etal (1986). - This form has not been used much at GFDL, with preference given to - a simpler two-dimensional (depth independent) form assessed with the - default hwf_diffusivity_3d=.false. - - Depth of transition for hwf scheme. The HWF method actually has - no depth dependence. But we include the atan depth dependency - from Bryan-Lewis, for those cases where we wish to replace - Bryan-Lewis with the HWF scheme. To get the usual Bryan-Lewis - transition, set hwf_depth_transition=2500.0. However, since - we often use hwf in the presence of tide mixing, we do not wish to - have any depth dependence, in which case the default is - hwf_depth_transition=2500.0e4. - - Minimum diffusivity for the HWF scheme. - Default hwf_min_diffusivity=2e-6. - - Diffusivity at 30deg latitude for the HWF scheme. - Default hwf_30_diffusivity=2e-5. - - Ratio of the typical Buoyancy frequency to - twice the earth's rotation period. - Default hwf_N0_2Omega=20.0. - - If .true. then add a Bryan-Lewis background to the - diffusivity. This background is a time-independent function - of depth. This diffusivity is NOT used when have - use_pp_vert_mix_coeff=.true. - This scheme should NOT be used if HWF is used. - - If .true. then allow for Bryan-Lewis background to be different - outside of a tropical band than inside the band. - - North/South latitude where transition from Bryan-Lewis values - in the tropic to those in the higher latitudes. - - Parameters setting the Bryan-Lewis vertical diffusivity profile. - When use bryan_lewis_lat_depend, these are the values used in the pole. - - Parameters setting the Bryan-Lewis vertical diffusivity profile in the tropics. - When use bryan_lewis_lat_depend=.true. , these are the values used in the tropics. - When use bryan_lewis_lat_depend=.false., these are the values used globally. - - If .true., then read in a table that specifies (i,j,ktop-->kbottom) - and the diffusivity. This method is useful when aiming to mix vertically - at points where do cross-land insertion or where may wish to enhance - mixing at river mouths. - - If .true., then linear taper the diff_cbt_table value from - so that it gets smaller with depth. - - To rescale the vertical mixing coefficients by rho0/rho - in order to bring the effects from vertical diffusion - in a non-Boussinesq model more in line with that from a - Boussinesq model. - Default vmix_rescale_nonbouss=.false. - - To set a minimum dissipation rate. This scheme will compute the - dissipation from the full diffusivity. If the resulting dissipation - is smaller than a specified dissipation, then the diffusivity will - be locally increased so that the min dissipation is maintained. - Default vmix_set_min_dissipation=.false. - - Minimum dissipation rate as a constant. - Default vmix_min_diss_const=1e-7. - - Scaling use to set the minimum dissipation rate as determined by the - local stratification. - Default vmix_min_diss_bvfreq_scale=6e-4. - - Maximum flux Richardson number for computation of diffusivity from dissipation. - Default vmix_min_diss_flux_ri_max=0.2. - - Initialization for the vertical mixing module. - - Read in static diffusivities that have been entered to the diff_cbt_table. - - Initialize the Bryan-Lewis static background diffusivities. - - Initialize the HWF static background diffusivity. - - Two forms are available: - - 1/ Depth dependent form, meant to emulate the Bryan-Lewis approach. - This form is not generally used at GFDL. - - 2/ Depth independent form motivated by use in the CM2G isopycnal - ocean climate model at GFDL. - - - Initialize the tanh background diffusivity. - - Initialize vertical friction portion of ocean_vert_mix_mod - - Initialization of watermass diagnostic output files. - Also determine the logical compute_watermass_diag. - - This subroutine calls the relevant scheme to compute vertical - diffusivity and vertical viscosity. Background values are - also incorporated here. - - This subroutine computes the thickness weighted and density - weighted time tendency for tracer associated with vertical diffusion - based on explicit time update of the vertical diffusion equation. - - MOM only supports aidif==0.0 or aidif==1.0. - MOM does not support cases with 0.0 < aidif < 1.0. - - The watermass diagnostics have not been ported to this subroutine - since aidif=0 is rarely used, even in idealized studies. - - - Contributions to thickness weighted and density weighted time - tendency from time-implicit vertical diffusion. - - This subroutine computes the thickness weighted and density weighted - acceleration (kg/m^3)*(m^2/s^2) associated with vertical friction. - - Assumes here that the horizontal grid is B-grid. - - For aidif=1.0, this module does nothing since all vertical friction - is in this case handled implicitly in time, and this is computed - elswewhere. - - MOM only supports aidif==0.0 or aidif==1.0. - MOM does not support cases with 0.0 < aidif < 1.0. - - Note that smf and bmf have units (kg/m^3)*(m^2/s^2) - So the vertical diffusive fluxes must be in these units - too. For this purpose, we multiply the viscosity by - rho0. This is an approximation consistent with the - Boussinesq approximation. For non-Boussinesq, we - should be using the in situ rho. But to the level of - accuracy that we know the vertical viscosity, and to - the extent that the ocean density is close to rho0, - our use of rho0 for the non-Boussinesq case is of - minor consequence for vertical friction calculation. - - Note: the form drag contribution to vertical viscosity - must be handled within aidif=1.0 implicit vertical - mixing. It is ignored in this routine, as its - contribution would generally cause the model to be - unstable. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - - - This subroutine computes the thickness weighted and density weighted - acceleration (kg/m^3)*(m^2/s^2) associated with vertical friction. - Assumes horizontal grid is C-grid. - - For aidif=1.0, this module does nothing since all vertical friction - is instead handled implicitly in time, and this is computed in the - velocity module. - - MOM only supports aidif==0.0 or aidif==1.0. - MOM does not support cases with 0.0 < aidif < 1.0. - - Note that smf and bmf have units (kg/m^3)*(m^2/s^2) - So the vertical diffusive fluxes must be in these units - too. For this purpose, we multiply the viscosity by - rho0. This is an approximation consistent with the - Boussinesq approximation. For non-Boussinesq, we - should be using the in situ rho. But to the level of - accuracy that we know the vertical viscosity, and to - the extent that the ocean density is close to rho0, - our use of rho0 for the non-Boussinesq case is of - minor consequence for vertical friction calculation. - - Note: use visc_cbt for both C-grid velocity components, - even though the velocity components sit at different - sides of the tracer cell. This choice is for simplicity. - It also acknowledges that the alternative of introducing - distinct visc_cbt_u and visc_cbt_v would presume knowledge - of subgrid scale features that we really do not have. - So again, visc_cbt is used for both u,v C-grid velocity - components. - - Note: the form drag contribution to vertical viscosity - must be handled within aidif=1.0 implicit vertical - mixing. It is ignored in this routine, as its - contribution would generally cause the model to be - unstable. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - - - Contributions to thickness weighted and density weighted acceleration - from implicit vertical friction. - - Assume that the horizontal grid is B-grid. - - Note that smf and bmf have units N/m^2. These are the natural units - for surface stress. To include these stresses as boundary terms in the - call to invtri, it is necessary to use vertical viscosities with units - (kg/m^3)*(m2^/s) = N/m^2. This is achieved by multiplying visc_cbu - by rho0 when sent to invtri. For depth-like vertical coordinates, this - is cancelled exactly by the rho0 in rho_dzu. For pressure-like - vertical coordinates, the rho0*visc_cbu introduces a negligible - change in the vertical viscosity that is well within uncertainty - in this coefficient. - - Include visc_cbu_form_drag to each of the velocity components - vertical friction. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - - - Contributions to thickness weighted and density weighted acceleration - from implicit vertical friction. - - Assume that the horizontal grid is C-grid. - - Note that smf and bmf have units N/m^2. These are the natural units - for surface stress. To include these stresses as boundary terms in the - call to invtri, it is necessary to use vertical viscosities with units - (kg/m^3)*(m2^/s) = N/m^2. This is achieved by multiplying visc_cbu - by rho0 when sent to invtri. For depth-like vertical coordinates, this - is cancelled exactly by the rho0 in rho_dzu. For pressure-like - vertical coordinates, the rho0*visc_cbu introduces a negligible - change in the vertical viscosity that is well within uncertainty - in this coefficient. - - Include visc_cbu_form_drag to each of the velocity components - vertical friction. - - Note: if try to merge this routine with vert_friction_cgrid - some machines and compilers will change bits by the mere - introduction of extra if-test logic into the calculation. - So we define the separate routines to maintain bit-wise - agreement with older results, with bit-wise agreement a - useful means to check for errors as the model evolves. - - Note: use visc_cbt for both C-grid velocity components, - even though the velocity components sit at different - sides of the tracer cell. This choice is for simplicity. - It also acknowledges that the alternative of introducing - distinct visc_cbt_u and visc_cbt_v would presume knowledge - of subgrid scale features that we really do not have. - So again, visc_cbt is used for both u,v C-grid velocity - components. - - - Determine if the point is in comp-domain for the processor. - - Inverse cosh function. Argument must be >=1. - - Impose a floor to the dissipation arising from vertical tracer diffusion. - - Diagnose watermass transformation diagnostics for - --sbc - --bbc - --vmix = diff_cbt + K33-implicit neutral diffusion - Estimations of the contributions from diff_cbt alone, and - from K33-implicit alone, are computed in vert_diffuse_watermass_diag. - - The diagnostic for vdiffuse computes all processes in one - invtri call, which is actually how the model prognostically - updates tracers from vertical diffusion. - - The sum of the sbc + bbc + vmix should equal to the - full vdiffuse diagnostic, so that, for example, - - neut_rho_vdiffuse = neut_rho_sbc + neut_rho_bbc + neut_rho_vmix - - Additionally, we should have - - neut_rho_vmix = neut_rho_diff_cbt + neut_rho_k33 - - with the terms neut_rho_diff_cbt and neut_rho_k33 computed - in routine vert_diffuse_watermass_diag. - - watermass_diag is called prior to implicit update of the tracer - fields, so that the initial taup1 value contains only explicit - in-time tendencies. The incremental tendencies are diagnosed - in this routine by various calls to invtri using same methods - as for the prognostic calculation. - - This routine requires the logical compute_watermass_diag=.true., - which is determined inside watermass_diag_init. - - - Diagnose contributions from time-implicit vertical diffusion. - - We perform the diagnostics using the taup1 value of the tracer - concentration, obtained after performing the invtri step. - The fluxes are diagnosed as if we are performing an explicit-time - update, but using the taup1 values of the tracer concentrations. - - This diagnostic suffers from time truncation errors relative to the - prognostic calculation, since the prognostic time update is performed using - an invtri calculation. However, the errors are small. The alternative - method, which is to separate the combined invtri step into individual - physical mixing processes is not an option, since this step is not equivalent - algorithmically to the single invtri mixing step. - It is for this reason that we perform the diagnostic step using this - "explicit flux computed with time-implicit computed concentration" approach. - - In contrast to the interior mixing, the boundary fluxes can be diagnostically - split from the invtri step, as these fluxes are determined prior to the - vert_diffuse_implicit routine. Hence, the boundary flux contributions can - be diagnosed either by calling an invtri step passing just the stf and btf - terms, or by using the even simpler methods in this subroutine. - - - Diagnose contributions from time-implicit vertical diffusion - acting on watermasses from diff_cbt and k33. - - We perform the diagnostics using the taup1 value of the tracer - concentration, obtained after performing the invtri step. - The fluxes are diagnosed as if we are performing an explicit-time - update, but using the taup1 values of the tracer concentrations. - - This diagnostic suffers from time truncation errors relative to the - prognostic calculation, since the prognostic time update is performed using - an invtri calculation. However, the errors are small. The alternative - method, which is to separate the combined invtri step into individual - physical mixing processes is not an option, since this step is not equivalent - algorithmically to the single invtri mixing step. - It is for this reason that we perform the diagnostic step using this - "explicit flux computed with time-implicit computed concentration" approach. - - - Write out restart files registered through register_restart_file - - Chen Scheme requires output of Krauss mixed layer for - reproducible results. - - GOTM requires fields for advection tendency. - - Module ocean_vert_pp_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_pp_mod
- - - - - -
-OVERVIEW
- -- Vertical viscosity and diffusivity according Pacanowski and Philander (1981) -
- - - -- This module computes vertical viscosity and diffusivity according to - Pacanowski and Philander (1981). This scheme is most effective for - studies of the tropical circulation. It computes the vertical mixing - coefficient based on the Richardson number. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_vert_util_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_pp_init:
- -- -vert_mix_pp:
- -- -ri_for_pp:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_pp_init
--
-- -DESCRIPTION -
-- - Initialization for the Pacanowski/Philander vertical mixing scheme - - input: - - dzt = thickness of vertical levels (m) - - nk = number of vertical levels - - yt = latitude of grid points (deg) - - nj = number of latitudes - - error = logical to signal problems - - output: - - wndmix = min value for mixing at surface to simulate high freq - - wind mixing (if absent in forcing). (m^2/sec) - - fricmx = maximum mixing (m^2/sec) - - diff_cbt_back_pp = background "diff_cbt" (m^2/sec) - - visc_cbu_back_pp = background "visc_cbu" (m^2/sec) - - diff_cbt_limit = largest "diff_cbt" (m^2/sec) - - visc_cbu_limit = largest "visc_cbu" (m^2/sec) - - error = true if some inconsistency was found - -
-
-
-- - -
-vert_mix_pp
--
-- -DESCRIPTION -
-- - This subroutine computes the vertical diffusivity and viscosity - according to the Pacanowski and Philander scheme. Mixing coefficients - are space and time dependent. - - inputs: - - nk = number of vertical levels - grav = gravity (m/sec^2) - fricmx = max viscosity (m^2/sec) - wndmix = min viscosity at bottom of 1st level to simulate - missing high frequency windstress components (m^2/sec) - visc_cbu_back_pp = background "visc_cbu" (m^2/sec) - diff_cbt_back_pp = background "diff_cbt" (m^2/sec) - visc_cbu_limit = largest "visc_cbu" in regions of gravitational - instability (m^2/sec) - diff_cbt_limit = largest "diff_cbt" in regions of gravitational - instability (m^2/sec) - riu = richardson number at bottom of U cells - rit = richardson number at bottom of T cells - - outputs: - - visc_cbu = viscosity at bottom of U cells (m^2/s) - visc_cbt = viscosity at bottom of T cells (m^2/s) - diff_cbt = diffusion at bottom of T cells (m^2/s) - -
-
-
-- - -
-ri_for_pp
--
-- -DESCRIPTION -
-- - Compute richardson number for the pp scheme -
-
-
-
-NAMELIST
- --&ocean_vert_pp_nml --
-
----
-- -use_this_module -
-- Must be true to use this module. Default is false. -
-
-[logical] -- -wndmix -
-- Minimum viscosity at bottom of 1st level to simulate - missing high frequency windstress components. -
-
-[real, units: m^2/sec] -- -fricmx -
-- Maximum mixing -
-
-[real, units: m^2/sec] -- -diff_cbt_back_pp -
-- Space-time independent background vertical diffusivity - thought to be that arising from internal waves. Note that - if using Bryan-Lewis background diffusivity, then should - set diff_cbt_back_pp=0.0. -
-
-[real, units: m^2/sec] -- -visc_cbu_back_pp -
-- Background vertical viscosity -
-
-[real, units: m^2/sec] -
- - - - -
-REFERENCES
- ----
-- - R.C. Pacanowski and G. Philander - Parametrization of vertical mixing in numerical models of the tropical ocean - Journal of Physical Oceanography (1981) vol 11, pages 1442--1451 -
-
- - -
-NOTES
- -- This parameterization was designed for equatorial models - and may not do a good job in mid or high latitudes. Simulations - in these regions (where vertical shear is small) are improved with - the addition of solar short wave penetration into the ocean which - reduces buoyancy and enhances vertical mixing. --
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_pp.xml b/src/mom5/ocean_param/vertical/ocean_vert_pp.xml deleted file mode 100644 index 51f88e3c89..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_pp.xml +++ /dev/null @@ -1,98 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_tidal.F90 b/src/mom5/ocean_param/vertical/ocean_vert_tidal.F90 index 6caf12c91a..28fe3a7b32 100644 --- a/src/mom5/ocean_param/vertical/ocean_vert_tidal.F90 +++ b/src/mom5/ocean_param/vertical/ocean_vert_tidal.F90 @@ -409,7 +409,7 @@ module ocean_vert_tidal_mod type(ocean_grid_type), pointer :: Grd => NULL() character(len=128) :: version='$$' -character (len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character (len=128) :: tagname = '$Name: tikal $' public vert_mix_tidal public ocean_vert_tidal_init diff --git a/src/mom5/ocean_param/vertical/ocean_vert_tidal.html b/src/mom5/ocean_param/vertical/ocean_vert_tidal.html deleted file mode 100644 index 4e873a68e3..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_tidal.html +++ /dev/null @@ -1,852 +0,0 @@ - - - - Stephen Griffies - - Vertical viscosity and diffusivity according Pacanowski and Philander (1981) - - This module computes vertical viscosity and diffusivity according to - Pacanowski and Philander (1981). This scheme is most effective for - studies of the tropical circulation. It computes the vertical mixing - coefficient based on the Richardson number. - - R.C. Pacanowski and G. Philander - Parametrization of vertical mixing in numerical models of the tropical ocean - Journal of Physical Oceanography (1981) vol 11, pages 1442--1451 - - This parameterization was designed for equatorial models - and may not do a good job in mid or high latitudes. Simulations - in these regions (where vertical shear is small) are improved with - the addition of solar short wave penetration into the ocean which - reduces buoyancy and enhances vertical mixing. - - Must be true to use this module. Default is false. - - Minimum viscosity at bottom of 1st level to simulate - missing high frequency windstress components. - - Maximum mixing - - Space-time independent background vertical diffusivity - thought to be that arising from internal waves. Note that - if using Bryan-Lewis background diffusivity, then should - set diff_cbt_back_pp=0.0. - - Background vertical viscosity - - Initialization for the Pacanowski/Philander vertical mixing scheme - - input: - - dzt = thickness of vertical levels (m) - - nk = number of vertical levels - - yt = latitude of grid points (deg) - - nj = number of latitudes - - error = logical to signal problems - - output: - - wndmix = min value for mixing at surface to simulate high freq - - wind mixing (if absent in forcing). (m^2/sec) - - fricmx = maximum mixing (m^2/sec) - - diff_cbt_back_pp = background "diff_cbt" (m^2/sec) - - visc_cbu_back_pp = background "visc_cbu" (m^2/sec) - - diff_cbt_limit = largest "diff_cbt" (m^2/sec) - - visc_cbu_limit = largest "visc_cbu" (m^2/sec) - - error = true if some inconsistency was found - - - This subroutine computes the vertical diffusivity and viscosity - according to the Pacanowski and Philander scheme. Mixing coefficients - are space and time dependent. - - inputs: - - nk = number of vertical levels - grav = gravity (m/sec^2) - fricmx = max viscosity (m^2/sec) - wndmix = min viscosity at bottom of 1st level to simulate - missing high frequency windstress components (m^2/sec) - visc_cbu_back_pp = background "visc_cbu" (m^2/sec) - diff_cbt_back_pp = background "diff_cbt" (m^2/sec) - visc_cbu_limit = largest "visc_cbu" in regions of gravitational - instability (m^2/sec) - diff_cbt_limit = largest "diff_cbt" in regions of gravitational - instability (m^2/sec) - riu = richardson number at bottom of U cells - rit = richardson number at bottom of T cells - - outputs: - - visc_cbu = viscosity at bottom of U cells (m^2/s) - visc_cbt = viscosity at bottom of T cells (m^2/s) - diff_cbt = diffusion at bottom of T cells (m^2/s) - - - Compute richardson number for the pp scheme - Module ocean_vert_tidal_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_tidal_mod
- - --Contact: S. M. Griffies - -- - -
-Reviewers: Harper Simmons -, - Hyun-Chul Lee - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module computes a vertical diffusivity and vertical - viscosity deduced from barotropic and baroclinic tidal - dissipation. Assume Prandtl number unity. -
- - - -- This module computes a vertical diffusivity and vertical - viscosity deduced from barotropic and baroclinic tidal - dissipation. For the baroclinic dissipation, we follow - Simmons etal, and for the barotropic dissipation we follow - Lee etal. Assume Prandtl number unity. - - This code is more general than that in the ocean_vert_kpp_mom4p0_mod. - The KPP_mom4p0 code remains part of MOM for legacy purposes. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_operators_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_tidal_init:
- -- -vert_mix_tidal:
- -- -compute_bvfreq:
- -- -vert_mix_wave:
- -- -vert_mix_drag_bgrid:
- -- -vert_mix_drag_cgrid:
- -- -compute_bvfreq_legacy:
- -- -vert_mix_wave_legacy:
- -- -vert_mix_drag_legacy:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_tidal_init
--
-- -DESCRIPTION -
-- - Initialization for the ocean_vert_tidal module. -
-
-
-- - -
-vert_mix_tidal
--
-- -DESCRIPTION -
-- - This subroutine computes vertical tracer diffusivity and viscosity - based on one or both of the following dissipation mechanisms: - - 1. internal wave breaking as parameterized by Simmons etal. - - 2. barotropic tides feeling the bottom drag, as parameterized by - Lee etal. - -
-
-
-- - -
-compute_bvfreq
--
-- -DESCRIPTION -
-- - This subroutine computes the absolute value of rho*N^2 and abs of - N^2, with N^2 the squared Brunt-Vaisala (or buoyancy) frequency. - -
-
-
-- - -
-vert_mix_wave
--
-- -DESCRIPTION -
-- - This subroutine computes dia-surface tracer diffusivity based on the - methods of Simmons et al., which consider dissipation from breaking - internal gravity waves and their conversion into local dia-surface - mixing, which is parameterized as diffusion. - - Also compute a prototype parameterization of mixing due to - breaking leewaves from Nikurashin. - - We assume a unit Prandtl number. - - Note that if umask(i,j,k) is 1.0, then so is - tmask(i,j,k), tmask(i+1,j,k), tmask(i,j+1,k), and tmask(i+1,j+1,k). - So there is no need to compute the "active_cells" when doing the - space average to go from t-cell to u-cell to compute visc_cbu. - -
-
-
-- - -
-vert_mix_drag_bgrid
--
-- -DESCRIPTION -
-- - This subroutine computes dia-surface tracer diffusivity based on the - methods of Lee etal., which consider the dissipation from barotropic tides - rubbing against the ocean bottom. - - We assume B-grid layout for the velocity - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - We perform various averages here in order to smooth Richardson number. - - 1. compute Richardson number on U-cell by averaging bvfreq from T-cell - 2. average U-cell Richardson number to then get T-cell diffusivity - 3. average T-cell diffusivity to get U-cell viscosity. - - Note that if umask(i,j,k)==1.0, then so is tmask(i,j,k), tmask(i+1,j,k), - tmask(i,j+1,k), and tmask(i+1,j+1,k). So there is no need to compute - active_cells when averaging from T-cell to U-cell. - -
-
-
-- - -
-vert_mix_drag_cgrid
--
-- -DESCRIPTION -
-- - This subroutine computes dia-surface tracer diffusivity based on the - methods of Lee etal., which consider the dissipation from barotropic tides - rubbing against the ocean bottom. - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - We assume C-grid layout for the velocity, which renders slight - distinctions for the calculation of Richardson number. Otherwise, the - calculations are the same as the Bgrid. We introduce this separate - routine, however, to enable easier bitwise agreement with older - model results. Also, further development of this scheme may lead - to more distinctions from the Bgrid. - -
-
-
-- - -
-compute_bvfreq_legacy
--
-- -DESCRIPTION -
-- - This subroutine computes the absolute value of rho*N^2 and abs of - N^2, with N^2 the squared Brunt-Vaisala (or buoyancy) frequency. - - This routine employs a legacy approach, which is not recommended. - It remains solely to allow exact reproduction of older results. - -
-
-
-- - -
-vert_mix_wave_legacy
--
-- -DESCRIPTION -
-- - - Legacy routine maintained only to exactly reproduce older results. - It is not recommended for new experiments, as it uses some obsolete - methods. - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Simmons etal., which consider the dissipation from breaking - internal gravity waves and their conversion into local dia-surface - diffusion. - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - Note that if umask(i,j,k) is 1.0, then so is - tmask(i,j,k), tmask(i+1,j,k), tmask(i,j+1,k), and tmask(i+1,j+1,k). - So there is no need to compute the "active_cells" when doing the - space average to go from t-cell to u-cell to compute viscosity. - -
-
-
-- - -
-vert_mix_drag_legacy
--
-- -DESCRIPTION -
-- - - Legacy routine maintained only to exactly reproduce older results. - It is not recommended for new experiments, as it uses some obsolete - methods. - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Lee etal., which consider the dissipation from barotropic tides - rubbing against the ocean bottom. - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - We perform various averages here in order to smooth Richardson number. - - 1. compute Richardson number on U-cell by averaging bvfreq from T-cell - 2. average U-cell Richardson number to then get T-cell diffusivity - 3. average T-cell diffusivity to get U-cell viscosity. - - Note that if umask(i,j,k)==1.0, then so is tmask(i,j,k), tmask(i+1,j,k), - tmask(i,j+1,k), and tmask(i+1,j+1,k). So there is no need to compute - active_cells when averaging from T-cell to U-cell. - -
-
-
-
-NAMELIST
- --&ocean_vert_tidal_nml --
-
----
-- -use_this_module= -
-- Must be .true. to use this module. Default is false. -
-
-[logical] -- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -- -use_wave_dissipation= -
-- Set to .true. for using the Simmons etal scheme for - obtaining a diffusivity and viscosity based on internal - wave breaking. This is a general form of the KPP - scheme "int_tidal_mix". - Default use_wave_dissipation=.false. -
-
-[logical] -- -use_drag_dissipation= -
-- Set to .true. for using the Lee etal scheme for - obtaining a diffusivity and viscosity based on drag - of barotropic tides on bottom. This is a general - form of the KPP scheme "coastal_tidal_mix". - Default use_drag_dissipation=.false. -
-
-[logical] -- -use_leewave_dissipation= -
-- Set to .true. for using a prototype Nikurashin scheme for - obtaining a diffusivity and viscosity based on breaking - leewaves. This scheme is not related to tides, but it - is incorporated to the baroclinic tide parameterization scheme - as a prototype. It will be placed into ts own module when - the parameterization matures. - Default use_leewave_dissipation=.false. -
-
-[logical] -- -read_leewave_dissipation -
-- If .true. then read in leewave dissipation from a file. - Default read_leewave_dissipation=.false. -
-
-[logical] -- -read_wave_dissipation -
-- If .true. then read in wave dissipation computed from - Jayne and St.Laurent (2001) tide model (or another model). - Default read_wave_dissipation=.false. -
-
-[logical] -- -fixed_wave_dissipation -
-- If .true. then fix the wave dissipation from that - read in by the tide model, such as Jayne and St.Laurent (2001). - This power dissipation will be employed - for computing wave induced mixing. - Default fixed_wave_dissipation=.false. -
-
-[logical] -- -read_roughness -
-- If .true. then read in bottom roughness amplitude h, - where roughness_length = kappa*h^2, with kappa a - representative roughness wavelength and h a - representative topographic amplitude. This information is - used for the Simmons etal wave dissipation parameterization. -
-
-[logical] -- -reading_roughness_length -
-- If .true., then the field in the roughness file is - roughness_length = kappa*h^2, with kappa a - representative roughness wavelength and h a - representative topographic amplitude. This information is - used for the Simmons etal wave dissipation parameterization. - Default reading_roughness_length=.false. -
-
-[logical] -- -reading_roughness_amp -
-- If .true., then the field in the roughness file is - roughness_amp=h, where roughness_length=kappa*h^2. - This information is used for the Simmons etal wave - dissipation parameterization. - Default reading_roughness_amp=.false. -
-
-[logical] -- -default_roughness_length -
-- Default value for kappa*h^2 = roughness length for use - in the absence of a roughness length dataset. MOM default - is default_roughness_length=25.0m. -
-
-[real, units: m] -- -read_tide_speed -
-- If .true. then read in tidal speed (m/s) from a tidal model. - This information is used for the computing the energy dissipation - from tides. - scheme. -
-
-[logical] -- -tide_speed_data_on_t_grid -
-- To set the input tide speed data on T-grid, set to true. - Otherwise, set to false. - Default tide_speed_data_on_t_grid=.true. -
-
-[logical] -- -roughness_scale -
-- Scale for the roughness that characterizes the roughness - affecting the tidal dissipation process. Used for setting - roughness_length via roughness_length = kappa*h^2, with - kappa = 2pi/(roughness_scale) and h=topography amplitude. - Default roughness_scale=1e4 as in Jayne and St. Laurent (2001) -
-
-[real, units: m] -- -default_tide_speed -
-- Default value for tidal speed for use in the absence of a - value from a tidal model. -
-
-[real, units: m/s] -- -speed_min -
-- For the drag scheme, we set the diffusivity as well as the - Richardson number to zero if the tide speed is less than - speed_min. This serves two purposes: 1/ to reduce overflows - in some of the diagnostics; 2/ to set the drag induced diffusivity - to zero in regions where the tide speed is small. Default - speed_min=5e-3m/s. -
-
-[real, units: m/s] -- -shelf_depth_cutoff -
-- For use in defining a mask for the Simmons scheme, with depths - shallower than shelf_depth_cutoff removed from the scheme. - shelf_depth_cutoff=1000m in Simmons etal. - Default shelf_depth_cutoff=-1000m so there is no cutoff. -
-
-[real, units: m] -- -decay_scale -
-- In the Simmons etal vertical profile function, the exponential decay - scale is determined by this parameter. Default = 500m as in Simmons - etal (2004). This vertical profile determines how to deposit the - internal wave energy within a vertical column. -
-
-[real, units: m] -- -tidal_diss_efficiency -
-- Fraction of barotropic tidal energy that is dissipated locally, as - opposed to that which propagates away. Default=1/3 as in - Simmons etal (2004). -
-
-[real, units: dimensionless] -- -mixing_efficiency -
-- Fraction of energy that is dissipated which is converted into dianeutral - diffusion of tracer. Default=0.2 based on Osborn (1980). -
-
-[real, units: dimensionless] -- -mixing_efficiency_n2depend -
-- Allow for mixing efficiency to be a function of - N^2/(N^2+Omega^2), which is close to unity except in - regions where N is very small. - Default mixing_efficiency_n2depend=.false. -
-
-[logical] -- -wave_energy_flux_max -
-- The maximum mechanical energy from internal tides that is - provided for mixing. Default wave_energy_flux_max=0.1Watt/m^2. -
-
-[real, units: W/m2] -- -wave_diffusivity_monotonic -
-- Enforce a monotonic decay of the wave dissipation diffusivity, - with largest values near bottom and smaller as move to shallower - water. This behaviour is not guaranteed in general, since the - division by the buoyancy frequency can give non-monotone diffusivities. - Default wave_diffusivity_monotonic=.true. -
-
-[logical] -- -munk_anderson_p -
-- The p constant in the Munk-Anderson scheme employed by Lee etal. - This parameter is minus the "p_tide" parameter in the KPP schemes. - Default munk_anderson_p=0.25 -
-
-[real, units: dimensionless] -- -munk_anderson_sigma -
-- The sigma constant in the Munk-Anderson scheme employed by Lee etal. - This parameter is called "sigma_tide" in the KPP schemes. - Default munk_anderson_sigma=3.0 -
-
-[real, units: dimensionless] -- -drag_dissipation_use_cdbot -
-- For using the cdbot_array computed from ocean_bbc.F90 module. - Default drag_dissipation_use_cdbot=.false., as this is consistent - with earlier simulations. -
-
-[logical] -- -bottom_drag_cd -
-- Bottom drag coefficient from Lee etal. Default bottom_drag_cd=2.4e-3 -
-
-[real, units: dimensionless] -- -background_diffusivity -
-- Background vertical diffusivity not accounted for by the tidal schemes - nor any other scheme such as KPP. Default=0.1e-4. -
-
-[real, units: m^2/s] -- -background_viscosity -
-- Background vertical viscosity not accounted for by the tidal schemes - nor any other scheme such as KPP. Default=0.1e-4. -
-
-[real, units: m^2/s] -- -max_wave_diffusivity -
-- Maximum tracer diffusivity deduced from the wave dissipation - scheme from Simmons etal. Default = 5.e-3 m^2/sec. -
-
-[real, units: m^2/s] -- -max_drag_diffusivity -
-- Maximum tracer diffusivity deduced from the drag dissipation scheme - from Lee etal. Default = 5.e-3 m^2/sec. -
-
-[real, units: m^2/s] -- -drag_dissipation_efold -
-- For setting an efolding whereby the drag dissipation diffusivity - exponentially decreases as move upward in the water column. - There are good reasons to set this logical to true, as the scheme - can produce unreasonably large diffusivities far from the bottom, if - there are tides in the deep ocean. - Default drag_dissipation_efold=.true. -
-
-[logical] -- -drag_dissipation_tide_period -
-- Characteristic tide period for use in computing efolding depth for - the tide drag scheme. Default = 12*60*60 = 12hours for semi-diurnal tide. -
-
-[real, units: s] -- -drag_mask_deep -
-- For masking out the deep ocean regions for the drag dissipation - scheme. This scheme is meant to apply only in shallow shelves, - so it is physically relevant to mask it out. We apply a mask as - determined by the ratio of the frictional tide depth scale and the - total ocean depth. - Default drag_mask_deep=.true. -
-
-[logical] -- -drag_mask_deep_ratio -
-- For determining the drag dissipation mask. - The mask = 0 in regions where - tide_depth/total_depth < drag_mask_deep_ratio - Default drag_mask_deep_ratio=0.1 -
-
-[real] -- -smooth_ri_drag_cgrid -
-- For smoothing the raw C-grid Richardson number computed for - the drag scheme on the Cgrid. Default smooth_ri_drag_cgrid=.true. -
-
-[logical] -- -use_legacy_methods -
-- To compute all mixing coefficients using legacy methods. - There are good reasons to prefer the newer approaches, which motivates - setting the default use_legacy_methods=.false. -
-
-[logical] -- -drhodz_min -
-- Minimum absolute value for the drhodz used to compute N^2 and rhoN2. - This value is needed in order to regularize the diffusivity computed - from the tide mixing schemes. Default is drhodz_min=1e-10, which - is much smaller than the (N^2)min = 10^-8 sec^-2 used by Simmons - etal. There is some sensitivity to the choice of drhodz_min, with - larger values leading to reduced deep diffusivities, due to the - N^-2 dependence in the diffusivity calculation. -
-
-[real, units: kg/m^3] -- -smooth_bvfreq_bottom -
-- For smoothing the buoyancy frequency at the bottom. - Default smooth_bvfreq_bottom=.true. -
-
-[logical] -- -vel_micom_smooth -
-- Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of diffusivities. - Default vel_micom_smooth=0.2. -
-
-[real, units: m/sec] -- -smooth_rho_N2 -
-- For smoothing the rho_N2 field via a 1-2-1 filter in - vertical. This is useful to produce smoother diffusivities. - Default is smooth_rho_N2=.true. -
-
-[logical] -- -num_121_passes -
-- Number of passes of 1-2-1 filter in vertical for - smoothing the rho_N2 field. Default num_121_passes=1. -
-
-[integer] -
- - - - -
-REFERENCES
- ----
-- - Simmons, Jayne, St. Laurent, and Weaver, 2004: - Tidally driven mixing in a numerical model of the ocean - general circulation. Ocean Modelling, vol. 6, - pages 245-263. -
-- - Jayne and St. Laurent, 2001: - Parameterizing tidal dissipation over rough topography. - Geophysical Research Letters, vol. 28, pages 811-814. -
-- - Hyun-Chul Lee, A. Rosati, and M.J. Spelman, 2006: - Barotropic tidal mixing effects in a coupled climate model: - ocean conditions in the northern Atlantic - Ocean Modelling, vol 11, pages 464--477 -
-- - Osborn, T.R., 1980: Estimates of the local rate of vertical diffusion - from dissipation measurements. JPO, vol. 10, pages 83-89. -
-- - Munk and Anderson, 1948: Notes on a theory of the thermocline. - Journal of Marine Research, vol 3. pages 276-295. -
-- - S.M. Griffies, Elements of MOM (2012) -
-
- -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_tidal.xml b/src/mom5/ocean_param/vertical/ocean_vert_tidal.xml deleted file mode 100644 index 02cb84e533..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_tidal.xml +++ /dev/null @@ -1,350 +0,0 @@ - - -diff --git a/src/mom5/ocean_param/vertical/ocean_vert_tidal_test.F90 b/src/mom5/ocean_param/vertical/ocean_vert_tidal_test.F90 new file mode 100644 index 0000000000..00bd2ad64a --- /dev/null +++ b/src/mom5/ocean_param/vertical/ocean_vert_tidal_test.F90 @@ -0,0 +1,2529 @@ +module ocean_vert_tidal_test_mod +! +! S. M. Griffies - Harper Simmons - Hyun-Chul Lee - - This module computes a vertical diffusivity and vertical - viscosity deduced from barotropic and baroclinic tidal - dissipation. Assume Prandtl number unity. - - This module computes a vertical diffusivity and vertical - viscosity deduced from barotropic and baroclinic tidal - dissipation. For the baroclinic dissipation, we follow - Simmons etal, and for the barotropic dissipation we follow - Lee etal. Assume Prandtl number unity. - - This code is more general than that in the ocean_vert_kpp_mom4p0_mod. - The KPP_mom4p0 code remains part of MOM for legacy purposes. - - Simmons, Jayne, St. Laurent, and Weaver, 2004: - Tidally driven mixing in a numerical model of the ocean - general circulation. Ocean Modelling, vol. 6, - pages 245-263. - - Jayne and St. Laurent, 2001: - Parameterizing tidal dissipation over rough topography. - Geophysical Research Letters, vol. 28, pages 811-814. - - Hyun-Chul Lee, A. Rosati, and M.J. Spelman, 2006: - Barotropic tidal mixing effects in a coupled climate model: - ocean conditions in the northern Atlantic - Ocean Modelling, vol 11, pages 464--477 - - Osborn, T.R., 1980: Estimates of the local rate of vertical diffusion - from dissipation measurements. JPO, vol. 10, pages 83-89. - - Munk and Anderson, 1948: Notes on a theory of the thermocline. - Journal of Marine Research, vol 3. pages 276-295. - - S.M. Griffies, Elements of MOM (2012) - - Must be .true. to use this module. Default is false. - - For debugging purposes. - - Set to .true. for using the Simmons etal scheme for - obtaining a diffusivity and viscosity based on internal - wave breaking. This is a general form of the KPP - scheme "int_tidal_mix". - Default use_wave_dissipation=.false. - - Set to .true. for using the Lee etal scheme for - obtaining a diffusivity and viscosity based on drag - of barotropic tides on bottom. This is a general - form of the KPP scheme "coastal_tidal_mix". - Default use_drag_dissipation=.false. - - Set to .true. for using a prototype Nikurashin scheme for - obtaining a diffusivity and viscosity based on breaking - leewaves. This scheme is not related to tides, but it - is incorporated to the baroclinic tide parameterization scheme - as a prototype. It will be placed into ts own module when - the parameterization matures. - Default use_leewave_dissipation=.false. - - If .true. then read in leewave dissipation from a file. - Default read_leewave_dissipation=.false. - - If .true. then read in wave dissipation computed from - Jayne and St.Laurent (2001) tide model (or another model). - Default read_wave_dissipation=.false. - - If .true. then fix the wave dissipation from that - read in by the tide model, such as Jayne and St.Laurent (2001). - This power dissipation will be employed - for computing wave induced mixing. - Default fixed_wave_dissipation=.false. - - If .true. then read in bottom roughness amplitude h, - where roughness_length = kappa*h^2, with kappa a - representative roughness wavelength and h a - representative topographic amplitude. This information is - used for the Simmons etal wave dissipation parameterization. - - If .true., then the field in the roughness file is - roughness_length = kappa*h^2, with kappa a - representative roughness wavelength and h a - representative topographic amplitude. This information is - used for the Simmons etal wave dissipation parameterization. - Default reading_roughness_length=.false. - - If .true., then the field in the roughness file is - roughness_amp=h, where roughness_length=kappa*h^2. - This information is used for the Simmons etal wave - dissipation parameterization. - Default reading_roughness_amp=.false. - - Default value for kappa*h^2 = roughness length for use - in the absence of a roughness length dataset. MOM default - is default_roughness_length=25.0m. - - If .true. then read in tidal speed (m/s) from a tidal model. - This information is used for the computing the energy dissipation - from tides. - scheme. - - To set the input tide speed data on T-grid, set to true. - Otherwise, set to false. - Default tide_speed_data_on_t_grid=.true. - - Scale for the roughness that characterizes the roughness - affecting the tidal dissipation process. Used for setting - roughness_length via roughness_length = kappa*h^2, with - kappa = 2pi/(roughness_scale) and h=topography amplitude. - Default roughness_scale=1e4 as in Jayne and St. Laurent (2001) - - Default value for tidal speed for use in the absence of a - value from a tidal model. - - For the drag scheme, we set the diffusivity as well as the - Richardson number to zero if the tide speed is less than - speed_min. This serves two purposes: 1/ to reduce overflows - in some of the diagnostics; 2/ to set the drag induced diffusivity - to zero in regions where the tide speed is small. Default - speed_min=5e-3m/s. - - For use in defining a mask for the Simmons scheme, with depths - shallower than shelf_depth_cutoff removed from the scheme. - shelf_depth_cutoff=1000m in Simmons etal. - Default shelf_depth_cutoff=-1000m so there is no cutoff. - - In the Simmons etal vertical profile function, the exponential decay - scale is determined by this parameter. Default = 500m as in Simmons - etal (2004). This vertical profile determines how to deposit the - internal wave energy within a vertical column. - - Fraction of barotropic tidal energy that is dissipated locally, as - opposed to that which propagates away. Default=1/3 as in - Simmons etal (2004). - - Fraction of energy that is dissipated which is converted into dianeutral - diffusion of tracer. Default=0.2 based on Osborn (1980). - - Allow for mixing efficiency to be a function of - N^2/(N^2+Omega^2), which is close to unity except in - regions where N is very small. - Default mixing_efficiency_n2depend=.false. - - The maximum mechanical energy from internal tides that is - provided for mixing. Default wave_energy_flux_max=0.1Watt/m^2. - - Enforce a monotonic decay of the wave dissipation diffusivity, - with largest values near bottom and smaller as move to shallower - water. This behaviour is not guaranteed in general, since the - division by the buoyancy frequency can give non-monotone diffusivities. - Default wave_diffusivity_monotonic=.true. - - The p constant in the Munk-Anderson scheme employed by Lee etal. - This parameter is minus the "p_tide" parameter in the KPP schemes. - Default munk_anderson_p=0.25 - - The sigma constant in the Munk-Anderson scheme employed by Lee etal. - This parameter is called "sigma_tide" in the KPP schemes. - Default munk_anderson_sigma=3.0 - - For using the cdbot_array computed from ocean_bbc.F90 module. - Default drag_dissipation_use_cdbot=.false., as this is consistent - with earlier simulations. - - Bottom drag coefficient from Lee etal. Default bottom_drag_cd=2.4e-3 - - Background vertical diffusivity not accounted for by the tidal schemes - nor any other scheme such as KPP. Default=0.1e-4. - - Background vertical viscosity not accounted for by the tidal schemes - nor any other scheme such as KPP. Default=0.1e-4. - - Maximum tracer diffusivity deduced from the wave dissipation - scheme from Simmons etal. Default = 5.e-3 m^2/sec. - - Maximum tracer diffusivity deduced from the drag dissipation scheme - from Lee etal. Default = 5.e-3 m^2/sec. - - For setting an efolding whereby the drag dissipation diffusivity - exponentially decreases as move upward in the water column. - There are good reasons to set this logical to true, as the scheme - can produce unreasonably large diffusivities far from the bottom, if - there are tides in the deep ocean. - Default drag_dissipation_efold=.true. - - Characteristic tide period for use in computing efolding depth for - the tide drag scheme. Default = 12*60*60 = 12hours for semi-diurnal tide. - - For masking out the deep ocean regions for the drag dissipation - scheme. This scheme is meant to apply only in shallow shelves, - so it is physically relevant to mask it out. We apply a mask as - determined by the ratio of the frictional tide depth scale and the - total ocean depth. - Default drag_mask_deep=.true. - - For determining the drag dissipation mask. - The mask = 0 in regions where - tide_depth/total_depth < drag_mask_deep_ratio - Default drag_mask_deep_ratio=0.1 - - For smoothing the raw C-grid Richardson number computed for - the drag scheme on the Cgrid. Default smooth_ri_drag_cgrid=.true. - - To compute all mixing coefficients using legacy methods. - There are good reasons to prefer the newer approaches, which motivates - setting the default use_legacy_methods=.false. - - Minimum absolute value for the drhodz used to compute N^2 and rhoN2. - This value is needed in order to regularize the diffusivity computed - from the tide mixing schemes. Default is drhodz_min=1e-10, which - is much smaller than the (N^2)min = 10^-8 sec^-2 used by Simmons - etal. There is some sensitivity to the choice of drhodz_min, with - larger values leading to reduced deep diffusivities, due to the - N^-2 dependence in the diffusivity calculation. - - For smoothing the buoyancy frequency at the bottom. - Default smooth_bvfreq_bottom=.true. - - Velocity scale that is used for computing the MICOM Laplacian mixing - coefficient used in the Laplacian smoothing of diffusivities. - Default vel_micom_smooth=0.2. - - For smoothing the rho_N2 field via a 1-2-1 filter in - vertical. This is useful to produce smoother diffusivities. - Default is smooth_rho_N2=.true. - - Number of passes of 1-2-1 filter in vertical for - smoothing the rho_N2 field. Default num_121_passes=1. - - Initialization for the ocean_vert_tidal module. - - This subroutine computes vertical tracer diffusivity and viscosity - based on one or both of the following dissipation mechanisms: - - 1. internal wave breaking as parameterized by Simmons etal. - - 2. barotropic tides feeling the bottom drag, as parameterized by - Lee etal. - - - This subroutine computes the absolute value of rho*N^2 and abs of - N^2, with N^2 the squared Brunt-Vaisala (or buoyancy) frequency. - - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Simmons et al., which consider dissipation from breaking - internal gravity waves and their conversion into local dia-surface - mixing, which is parameterized as diffusion. - - Also compute a prototype parameterization of mixing due to - breaking leewaves from Nikurashin. - - We assume a unit Prandtl number. - - Note that if umask(i,j,k) is 1.0, then so is - tmask(i,j,k), tmask(i+1,j,k), tmask(i,j+1,k), and tmask(i+1,j+1,k). - So there is no need to compute the "active_cells" when doing the - space average to go from t-cell to u-cell to compute visc_cbu. - - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Lee etal., which consider the dissipation from barotropic tides - rubbing against the ocean bottom. - - We assume B-grid layout for the velocity - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - We perform various averages here in order to smooth Richardson number. - - 1. compute Richardson number on U-cell by averaging bvfreq from T-cell - 2. average U-cell Richardson number to then get T-cell diffusivity - 3. average T-cell diffusivity to get U-cell viscosity. - - Note that if umask(i,j,k)==1.0, then so is tmask(i,j,k), tmask(i+1,j,k), - tmask(i,j+1,k), and tmask(i+1,j+1,k). So there is no need to compute - active_cells when averaging from T-cell to U-cell. - - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Lee etal., which consider the dissipation from barotropic tides - rubbing against the ocean bottom. - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - We assume C-grid layout for the velocity, which renders slight - distinctions for the calculation of Richardson number. Otherwise, the - calculations are the same as the Bgrid. We introduce this separate - routine, however, to enable easier bitwise agreement with older - model results. Also, further development of this scheme may lead - to more distinctions from the Bgrid. - - - This subroutine computes the absolute value of rho*N^2 and abs of - N^2, with N^2 the squared Brunt-Vaisala (or buoyancy) frequency. - - This routine employs a legacy approach, which is not recommended. - It remains solely to allow exact reproduction of older results. - - - - Legacy routine maintained only to exactly reproduce older results. - It is not recommended for new experiments, as it uses some obsolete - methods. - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Simmons etal., which consider the dissipation from breaking - internal gravity waves and their conversion into local dia-surface - diffusion. - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - Note that if umask(i,j,k) is 1.0, then so is - tmask(i,j,k), tmask(i+1,j,k), tmask(i,j+1,k), and tmask(i+1,j+1,k). - So there is no need to compute the "active_cells" when doing the - space average to go from t-cell to u-cell to compute viscosity. - - - - Legacy routine maintained only to exactly reproduce older results. - It is not recommended for new experiments, as it uses some obsolete - methods. - - This subroutine computes dia-surface tracer diffusivity based on the - methods of Lee etal., which consider the dissipation from barotropic tides - rubbing against the ocean bottom. - - We assume a unit Prandtl number, so compute the viscosity as a four-point - average of the diffusivity. - - We perform various averages here in order to smooth Richardson number. - - 1. compute Richardson number on U-cell by averaging bvfreq from T-cell - 2. average U-cell Richardson number to then get T-cell diffusivity - 3. average T-cell diffusivity to get U-cell viscosity. - - Note that if umask(i,j,k)==1.0, then so is tmask(i,j,k), tmask(i+1,j,k), - tmask(i,j+1,k), and tmask(i+1,j+1,k). So there is no need to compute - active_cells when averaging from T-cell to U-cell. - - S. M. Griffies +! +! +!Harper Simmons +! +! +!Hyun-Chul Lee +! +! +!+! This module computes a vertical diffusivity and vertical +! viscosity deduced from barotropic and baroclinic tidal +! dissipation. Assume Prandtl number unity. +! +! +!+! This module computes a vertical diffusivity and vertical +! viscosity deduced from barotropic and baroclinic tidal +! dissipation. For the baroclinic dissipation, we follow +! Simmons etal, and for the barotropic dissipation we follow +! Lee etal. Assume Prandtl number unity. +! +! This code is more general than that in the ocean_vert_kpp_mom4p0_mod. +! The KPP_mom4p0 code remains part of MOM for legacy purposes. +! +! There are some testing routines in this module that remain exploratory +! at GFDL. +! +! +! +!+! +! +! +!+! Simmons, Jayne, St. Laurent, and Weaver, 2004: +! Tidally driven mixing in a numerical model of the ocean +! general circulation. Ocean Modelling, vol. 6, +! pages 245-263. +! +! +!+! Jayne and St. Laurent, 2001: +! Parameterizing tidal dissipation over rough topography. +! Geophysical Research Letters, vol. 28, pages 811-814. +! +! +!+! Hyun-Chul Lee, A. Rosati, and M.J. Spelman, 2006: +! Barotropic tidal mixing effects in a coupled climate model: +! ocean conditions in the northern Atlantic +! Ocean Modelling, vol 11, pages 464--477 +! +! +!+! Osborn, T.R., 1980: Estimates of the local rate of vertical diffusion +! from dissipation measurements. JPO, vol. 10, pages 83-89. +! +! +!+! Munk and Anderson, 1948: Notes on a theory of the thermocline. +! Journal of Marine Research, vol 3. pages 276-295. +! +! +!+! S.M. Griffies, Elements of MOM (2012) +! +! +!+! +! Must be .true. to use this module. Default is false. +! +! +! For debugging purposes. +! +! +! +! Set to .true. for using the Simmons etal scheme for +! obtaining a diffusivity and viscosity based on internal +! wave breaking. This is a general form of the KPP +! scheme "int_tidal_mix". +! Default use_wave_dissipation=.false. +! +! +! Set to .true. for using the Lee etal scheme for +! obtaining a diffusivity and viscosity based on drag +! of barotropic tides on bottom. This is a general +! form of the KPP scheme "coastal_tidal_mix". +! Default use_drag_dissipation=.false. +! +! +! Set to .true. for using a prototype Nikurashin scheme for +! obtaining a diffusivity and viscosity based on breaking +! leewaves. This scheme is not related to tides, but it +! is incorporated to the baroclinic tide parameterization scheme +! as a prototype. It will be placed into ts own module when +! the parameterization matures. +! Default use_leewave_dissipation=.false. +! +! +! +! If .true. then read in leewave dissipation from a file. +! Default read_leewave_dissipation=.false. +! +! +! +! If .true. then read in wave dissipation computed from +! Jayne and St.Laurent (2001) tide model (or another model). +! Default read_wave_dissipation=.false. +! +! +! If .true. then fix the wave dissipation from that +! read in by the tide model, such as Jayne and St.Laurent (2001). +! This power dissipation will be employed +! for computing wave induced mixing. +! Default fixed_wave_dissipation=.false. +! +! +! +! If .true. then read in bottom roughness amplitude h, +! where roughness_length = kappa*h^2, with kappa a +! representative roughness wavelength and h a +! representative topographic amplitude. This information is +! used for the Simmons etal wave dissipation parameterization. +! +! +! If .true., then the field in the roughness file is +! roughness_length = kappa*h^2, with kappa a +! representative roughness wavelength and h a +! representative topographic amplitude. This information is +! used for the Simmons etal wave dissipation parameterization. +! Default reading_roughness_length=.false. +! +! +! If .true., then the field in the roughness file is +! roughness_amp=h, where roughness_length=kappa*h^2. +! This information is used for the Simmons etal wave +! dissipation parameterization. +! Default reading_roughness_amp=.false. +! +! +! Default value for kappa*h^2 = roughness length for use +! in the absence of a roughness length dataset. MOM default +! is default_roughness_length=25.0m. +! +! +! +! If .true. then read in tidal speed (m/s) from a tidal model. +! This information is used for the computing the energy dissipation +! from tides. +! scheme. +! +! +! To set the input tide speed data on T-grid, set to true. +! Otherwise, set to false. +! Default tide_speed_data_on_t_grid=.true. +! +! +! +! Scale for the roughness that characterizes the roughness +! affecting the tidal dissipation process. Used for setting +! roughness_length via roughness_length = kappa*h^2, with +! kappa = 2pi/(roughness_scale) and h=topography amplitude. +! Default roughness_scale=1e4 as in Jayne and St. Laurent (2001) +! +! +! Default value for tidal speed for use in the absence of a +! value from a tidal model. +! +! +! For the drag scheme, we set the diffusivity as well as the +! Richardson number to zero if the tide speed is less than +! speed_min. This serves two purposes: 1/ to reduce overflows +! in some of the diagnostics; 2/ to set the drag induced diffusivity +! to zero in regions where the tide speed is small. Default +! speed_min=5e-3m/s. +! +! +! +! For use in defining a mask for the Simmons scheme, with depths +! shallower than shelf_depth_cutoff removed from the scheme. +! shelf_depth_cutoff=1000m in Simmons etal. +! Default shelf_depth_cutoff=-1000m so there is no cutoff. +! +! +! +! In the Simmons etal vertical profile function, the exponential decay +! scale is determined by this parameter. Default = 500m as in Simmons +! etal (2004). This vertical profile determines how to deposit the +! internal wave energy within a vertical column. +! +! +! +! Fraction of barotropic tidal energy that is dissipated locally, as +! opposed to that which propagates away. Default=1/3 as in +! Simmons etal (2004). +! +! +! +! Fraction of energy that is dissipated which is converted into dianeutral +! diffusion of tracer. Default=0.2 based on Osborn (1980). +! +! +! Allow for mixing efficiency to be a function of +! N^2/(N^2+Omega^2), which is close to unity except in +! regions where N is very small. +! Default mixing_efficiency_n2depend=.false. +! +! +! +! The maximum mechanical energy from internal tides that is +! provided for mixing. Default wave_energy_flux_max=0.1Watt/m^2. +! +! +! +! Enforce a monotonic decay of the wave dissipation diffusivity, +! with largest values near bottom and smaller as move to shallower +! water. This behaviour is not guaranteed in general, since the +! division by the buoyancy frequency can give non-monotone diffusivities. +! Default wave_diffusivity_monotonic=.true. +! +! +! +! The p constant in the Munk-Anderson scheme employed by Lee etal. +! This parameter is minus the "p_tide" parameter in the KPP schemes. +! Default munk_anderson_p=0.25 +! +! +! The sigma constant in the Munk-Anderson scheme employed by Lee etal. +! This parameter is called "sigma_tide" in the KPP schemes. +! Default munk_anderson_sigma=3.0 +! +! +! For using the cdbot_array computed from ocean_bbc.F90 module. +! Default drag_dissipation_use_cdbot=.false., as this is consistent +! with earlier simulations. +! +! +! Bottom drag coefficient from Lee etal. Default bottom_drag_cd=2.4e-3 +! +! +! +! Background vertical diffusivity not accounted for by the tidal schemes +! nor any other scheme such as KPP. Default=0.1e-4. +! +! +! Background vertical viscosity not accounted for by the tidal schemes +! nor any other scheme such as KPP. Default=0.1e-4. +! +! +! Maximum tracer diffusivity deduced from the wave dissipation +! scheme from Simmons etal. Default = 5.e-3 m^2/sec. +! +! +! +! Maximum tracer diffusivity deduced from the drag dissipation scheme +! from Lee etal. Default = 5.e-3 m^2/sec. +! +! +! For setting an efolding whereby the drag dissipation diffusivity +! exponentially decreases as move upward in the water column. +! There are good reasons to set this logical to true, as the scheme +! can produce unreasonably large diffusivities far from the bottom, if +! there are tides in the deep ocean. +! Default drag_dissipation_efold=.true. +! +! +! Characteristic tide period for use in computing efolding depth for +! the tide drag scheme. Default = 12*60*60 = 12hours for semi-diurnal tide. +! +! +! For masking out the deep ocean regions for the drag dissipation +! scheme. This scheme is meant to apply only in shallow shelves, +! so it is physically relevant to mask it out. We apply a mask as +! determined by the ratio of the frictional tide depth scale and the +! total ocean depth. +! Default drag_mask_deep=.true. +! +! +! For determining the drag dissipation mask. +! The mask = 0 in regions where +! tide_depth/total_depth < drag_mask_deep_ratio +! Default drag_mask_deep_ratio=0.1 +! +! +! For smoothing the raw C-grid Richardson number computed for +! the drag scheme on the Cgrid. Default smooth_ri_drag_cgrid=.true. +! +! +! +! To compute all mixing coefficients using legacy methods. +! There are good reasons to prefer the newer approaches, which motivates +! setting the default use_legacy_methods=.false. +! +! +! Minimum absolute value for the drhodz used to compute N^2 and rhoN2. +! This value is needed in order to regularize the diffusivity computed +! from the tide mixing schemes. Default is drhodz_min=1e-10, which +! is much smaller than the (N^2)min = 10^-8 sec^-2 used by Simmons +! etal. There is some sensitivity to the choice of drhodz_min, with +! larger values leading to reduced deep diffusivities, due to the +! N^-2 dependence in the diffusivity calculation. +! +! +! For smoothing the buoyancy frequency at the bottom. +! Default smooth_bvfreq_bottom=.true. +! +! +! Velocity scale that is used for computing the MICOM Laplacian mixing +! coefficient used in the Laplacian smoothing of diffusivities. +! Default vel_micom_smooth=0.2. +! +! +! +! For smoothing the rho_N2 field via a 1-2-1 filter in +! vertical. This is useful to produce smoother diffusivities. +! Default is smooth_rho_N2=.true. +! +! +! Number of passes of 1-2-1 filter in vertical for +! smoothing the rho_N2 field. Default num_121_passes=1. +! +! +! +! for reproduce legacy results with constant cdbot. +! To reproduce the previous results, set; +! drag_dissipation_use_cdbot=.false., repro_legacy_const_cdbot=.true. +! If drag_dissipation_use_cdbot=.true., then results are reproduciable. +! Default repro_legacy_const_cdbot= .false. +! +! +! + +! + +use constants_mod, only: pi, epsln +use diag_manager_mod, only: register_diag_field, register_static_field, send_data +use fms_mod, only: write_version_number, open_namelist_file, close_file, check_nml_error +use fms_mod, only: stdout, stdlog, read_data, NOTE, FATAL, WARNING +use mpp_domains_mod, only: mpp_update_domains +use mpp_mod, only: input_nml_file, mpp_error + +use ocean_domains_mod, only: get_local_indices +use ocean_operators_mod, only: LAP_T +use ocean_parameters_mod, only: MOM_BGRID, MOM_CGRID +use ocean_parameters_mod, only: missing_value, onehalf, onefourth +use ocean_parameters_mod, only: von_karman, rho0, rho0r, omega_earth, grav +use ocean_types_mod, only: ocean_time_type, ocean_domain_type, ocean_grid_type, ocean_options_type +use ocean_types_mod, only: ocean_prog_tracer_type, ocean_thickness_type, ocean_density_type, ocean_velocity_type +use ocean_workspace_mod, only: wrk1, wrk2, wrk3, wrk1_2d + +implicit none + +private + +! for diagnostics +integer :: id_tide_speed_wave =-1 +integer :: id_tide_speed_drag =-1 +integer :: id_tide_speed_mask =-1 +integer :: id_tide_rescspeed_mask=-1 +integer :: id_tide_deepspeed_mask=-1 +integer :: id_roughness_length =-1 +integer :: id_roughness_amp =-1 +integer :: id_roughness_klevel =-1 +integer :: id_energy_flux =-1 +integer :: id_power_waves =-1 +integer :: id_leewave_dissipation=-1 +integer :: id_power_diss_wave =-1 +integer :: id_power_diss_drag =-1 +integer :: id_power_diss_tides =-1 +integer :: id_power_diss_leewave =-1 +integer :: id_rinumber_drag =-1 +integer :: id_drag_dissipation =-1 +integer :: id_bvfreq_bottom =-1 +integer :: id_mix_efficiency =-1 +integer :: id_bvfreq =-1 +integer :: id_diff_cbt_wave =-1 +integer :: id_diff_cbt_drag =-1 +integer :: id_diff_cbt_leewave =-1 +integer :: id_diff_cbt_tides =-1 +integer :: id_visc_cbt_wave =-1 +integer :: id_visc_cbt_drag =-1 +integer :: id_visc_cbt_leewave =-1 +integer :: id_visc_cbt_tides =-1 +integer :: id_visc_cbu_wave =-1 +integer :: id_visc_cbu_leewave =-1 +integer :: id_visc_cbu_drag =-1 +integer :: id_visc_cbu_tides =-1 +integer :: id_drag_diss_efold =-1 +integer :: id_tide_diff_cbt_back =-1 +integer :: id_tide_visc_cbu_back =-1 +logical :: used + +#include+ +real, private, dimension(:,:), allocatable :: smooth_lap !2D array of micom diffusivities (m^2/sec) for smoothing +real, private, dimension(:,:), allocatable :: roughness_amp ! roughness amplitude (m) from topography +real, private, dimension(:,:), allocatable :: roughness_length ! roughness length (m) from topography +real, private, dimension(:,:), allocatable :: wave_dissipation ! wave dissipation (W/m2) from tide model +real, private, dimension(:,:), allocatable :: leewave_dissipation ! leewave dissipation (W/m2) +real, private, dimension(:,:), allocatable :: tide_speed_t ! T-cell speed (m/s) from barotropic tide model +real, private, dimension(:,:), allocatable :: tide_speed_u ! U-cell speed (m/s) from barotropic tide model +real, private, dimension(:,:), allocatable :: tide_speed_mask ! U-cell mask for rescaled speed, only for legacy +real, private, dimension(:,:), allocatable :: tide_rescspeed_mask ! U-cell mask for rescaled speed +real, private, dimension(:,:), allocatable :: tide_deepspeed_mask ! U-cell mask for deep ocean region +real, private, dimension(:,:), allocatable :: rescaled_speed_u ! U-cell speed (m/s) for Lee etal calculation of Ri +real, private, dimension(:,:), allocatable :: rescaled_speed_t ! T-cell speed (m/s) for Lee etal calculation of Ri +real, private, dimension(:,:), allocatable :: efold_depth_r ! T-cell inverse efold depth (1/m) for Lee etal +real, private, dimension(:,:), allocatable :: energy_flux ! energy flux (W/m^2) out of ext-tide to int-tide +real, private, dimension(:,:), allocatable :: wave_term ! static term in wave energy flux calculation +real, private, dimension(:,:), allocatable :: bvfreq_bottom ! buoyancy frequency (sec^-1) at ocean bottom + +real, private, dimension(:,:,:), allocatable :: mix_efficiency ! dimensionless mixing efficiency +real, private, dimension(:,:,:), allocatable :: bvfreq ! buoyancy frequency (sec^-1) +real, private, dimension(:,:,:), allocatable :: rho_N2 ! rho*squared buoyancy frequency (kg/m^3)*(sec^-2) +real, private, dimension(:,:,:), allocatable :: drhodT ! partial rho / partial temperature +real, private, dimension(:,:,:), allocatable :: drhodS ! partial rho / partial salinity +real, private, dimension(:,:,:), allocatable :: diff_drag ! diffusivity (m^2/sec) from drag mixing scheme +real, private, dimension(:,:,:), allocatable :: diff_wave ! diffusivity (m^2/sec) from wave mixing scheme +real, private, dimension(:,:,:), allocatable :: diff_leewave ! diffusivity (m^2/sec) from leewave mixing scheme +real, private, dimension(:,:), allocatable :: tmask_deep ! nonzero for points deeper than shelf_depth_cutoff + +type(ocean_domain_type), pointer :: Dom => NULL() +type(ocean_grid_type), pointer :: Grd => NULL() + +character(len=128) :: version='$$' +character (len=128) :: tagname = '$Name: tikal $' + +public vert_mix_tidal_test +public ocean_vert_tidal_test_init + +private vert_mix_wave +private vert_mix_drag_bgrid +private vert_mix_drag_cgrid +private vert_mix_drag_legacy +private compute_bvfreq + +integer :: index_temp=-1 +integer :: index_salt=-1 + +! for Bgrid or Cgrid +integer :: horz_grid + +real :: p5rho0 +real :: decay_scale_inv +real :: sqrt_cd +real :: von_karman_inv +real :: dtime +real :: roughness_kappa +real :: omega_earth2 + +logical :: module_is_initialized = .false. + +! nml parameters + +logical :: use_this_module = .false. +logical :: use_legacy_methods = .false. +logical :: debug_this_module = .false. +logical :: use_wave_dissipation = .false. +logical :: use_drag_dissipation = .false. +logical :: use_leewave_dissipation = .false. +logical :: read_roughness = .false. +logical :: read_wave_dissipation = .false. +logical :: read_leewave_dissipation = .false. +logical :: reading_roughness_amp = .false. +logical :: reading_roughness_length = .false. +logical :: read_tide_speed = .false. +logical :: wave_diffusivity_monotonic = .true. +logical :: tide_speed_data_on_t_grid = .true. +logical :: fixed_wave_dissipation = .false. +logical :: mixing_efficiency_n2depend = .false. +logical :: drag_dissipation_efold = .true. +logical :: smooth_bvfreq_bottom = .true. +logical :: drag_mask_deep = .true. +logical :: smooth_ri_drag_cgrid = .true. + +logical :: smooth_rho_N2 = .true. ! for smoothing the rho_N2 field in vertical with 1-2-1 +integer :: num_121_passes = 1 ! number of 1-2-1 passes + +real :: drag_mask_deep_ratio = 0.1 +real :: roughness_scale = 85e3 ! (metre) +real :: default_roughness_length = 25.0 ! (metre) +real :: default_tide_speed = .01 ! (m/s) +real :: shelf_depth_cutoff = -1000.0 ! (metre) +real :: decay_scale = 500.0 ! (metre) +real :: tidal_diss_efficiency = 0.33333 ! (dimensionless) from Simmons etal +real :: mixing_efficiency = 0.2 ! (dimensionless) from Osborne +real :: munk_anderson_p = 0.25 ! (dimensionless) from Munk and Anderson +real :: munk_anderson_sigma = 3.0 ! (dimensionless) from Munk and Anderson +real :: bottom_drag_cd = 2.4e-3 ! (dimensionless) bottom drag from Lee etal +real :: background_diffusivity = 0.1e-4 ! (m^2/sec) +real :: background_viscosity = 0.1e-4 ! (m^2/sec) +real :: max_wave_diffusivity = 5.0e-3 ! (m^2/sec) +real :: max_drag_diffusivity = 5.0e-3 ! (m^2/sec) +real :: drhodz_min = 1.e-10 ! (kg/m^4) minimum abs(drhodz) used to compute N^2 +real :: speed_min = 5.e-3 ! (m/s) below which set a mask=0 for drag mixing diffusivity +real :: wave_energy_flux_max = 0.1 ! (W/m^2) +real :: drag_dissipation_tide_period = 43200. ! seconds +real :: vel_micom_smooth = 0.2 ! m/sec for smoothing +logical :: drag_dissipation_use_cdbot = .false. ! for using cdbot_array from ocean_bbc +logical :: repro_legacy_const_cdbot = .false. ! for reproduce legacy results with constant cdbot + + +namelist /ocean_vert_tidal_test_nml/ use_this_module, use_legacy_methods, debug_this_module, & + use_wave_dissipation, use_drag_dissipation, & + read_roughness, read_tide_speed, & + default_roughness_length, default_tide_speed, & + shelf_depth_cutoff, decay_scale, roughness_scale, & + tidal_diss_efficiency, mixing_efficiency, & + mixing_efficiency_n2depend, & + munk_anderson_p, munk_anderson_sigma, & + drag_dissipation_efold, drag_dissipation_tide_period, & + drag_mask_deep, drag_mask_deep_ratio, & + bottom_drag_cd, drhodz_min, speed_min, & + background_diffusivity, background_viscosity, & + max_wave_diffusivity, max_drag_diffusivity, & + smooth_bvfreq_bottom, vel_micom_smooth, & + smooth_rho_N2, num_121_passes, wave_diffusivity_monotonic, & + tide_speed_data_on_t_grid, & + reading_roughness_amp, reading_roughness_length, & + read_wave_dissipation, fixed_wave_dissipation, & + wave_energy_flux_max, & + use_leewave_dissipation, read_leewave_dissipation, & + drag_dissipation_use_cdbot, repro_legacy_const_cdbot + +contains + + +!####################################################################### +! +! +! NAME="ocean_vert_tidal_test_init" + + +!####################################################################### +!+! Initialization for the ocean_vert_tidal module. +! + subroutine ocean_vert_tidal_test_init(Grid, Domain, Time, T_prog, Velocity, Ocean_options, dtime_t, vert_mix_scheme, hor_grid) + + type(ocean_grid_type), intent(in), target :: Grid + type(ocean_domain_type), intent(in), target :: Domain + type(ocean_time_type), intent(in) :: Time + type(ocean_prog_tracer_type), intent(in) :: T_prog(:) + type(ocean_velocity_type), intent(in) :: Velocity + type(ocean_options_type), intent(inout) :: Ocean_options + real, intent(in) :: dtime_t + character(len=10), intent(in) :: vert_mix_scheme + integer, intent(in) :: hor_grid + + real :: active_cells, temporary + integer :: unit, io_status, ierr + integer :: i,j,n + integer :: roughness_has_been_read=0 + + integer :: stdoutunit,stdlogunit + stdoutunit=stdout();stdlogunit=stdlog() + + if ( module_is_initialized ) then + call mpp_error(FATAL,& + '==>Error from ocean_vert_tidal_test_mod (ocean_vert_tidal_test_init) module already initialized') + endif + + module_is_initialized = .TRUE. + + call write_version_number( version, tagname ) + +#ifdef INTERNAL_FILE_NML +read (input_nml_file, nml=ocean_vert_tidal_test_nml, iostat=io_status) +!ierr = check_nml_error(io_status,'ocean_vert_tidal_test_nml') +#else + unit = open_namelist_file() + read(unit, ocean_vert_tidal_test_nml,iostat=io_status) +! ierr = check_nml_error(io_status, 'ocean_vert_tidal_test_nml') + call close_file(unit) +#endif + write (stdoutunit,'(/)') + write (stdoutunit,ocean_vert_tidal_test_nml) + write (stdlogunit,ocean_vert_tidal_test_nml) + + Dom => Domain + Grd => Grid + dtime = dtime_t + +#ifndef MOM_STATIC_ARRAYS + call get_local_indices(Domain, isd, ied, jsd, jed, isc, iec, jsc, jec) + nk = Grid%nk +#endif + + if(use_this_module) then + call mpp_error(NOTE, '==>Note: USING ocean_vert_tidal_test_mod') + else + call mpp_error(NOTE, '==>Note: NOT using ocean_vert_tidal_test_mod') + Ocean_options%tidal_wave_mix = 'Did NOT use tidal wave mixing option for vertical mixing.' + Ocean_options%tidal_drag_mix = 'Did NOT use tidal drag mixing option for vertical mixing.' + return + endif + + decay_scale_inv = 1.0/decay_scale + p5rho0 = 0.5*rho0 + sqrt_cd = sqrt(bottom_drag_cd) + von_karman_inv = 1.0/von_karman + roughness_kappa = 2.0*pi/roughness_scale + omega_earth2 = omega_earth**2 + horz_grid = hor_grid + + do n=1, size(T_prog(:)) + if (T_prog(n)%name == 'temp') index_temp = n + if (T_prog(n)%name == 'salt') index_salt = n + enddo + + ! allocate arrays needed for buoyancy frequency + allocate (mix_efficiency(isd:ied,jsd:jed,nk)) + allocate (bvfreq_bottom(isd:ied,jsd:jed)) + allocate (bvfreq(isd:ied,jsd:jed,nk)) + allocate (rho_N2(isd:ied,jsd:jed,nk)) + allocate (drhodT(isd:ied,jsd:jed,nk)) + allocate (drhodS(isd:ied,jsd:jed,nk)) + allocate (diff_drag(isd:ied,jsd:jed,nk)) + allocate (diff_wave(isd:ied,jsd:jed,nk)) + allocate (diff_leewave(isd:ied,jsd:jed,nk)) + allocate (tmask_deep(isd:ied,jsd:jed)) + mix_efficiency = 0.0 + bvfreq_bottom = 0.0 + bvfreq = 0.0 + rho_N2 = 0.0 + drhodT = 0.0 + drhodS = 0.0 + diff_drag = 0.0 + diff_wave = 0.0 + diff_leewave = 0.0 + tmask_deep(:,:) = Grd%tmask(:,:,1) + + allocate (smooth_lap(isd:ied,jsd:jed)) + allocate (wave_term(isd:ied,jsd:jed)) + allocate (energy_flux(isd:ied,jsd:jed)) + allocate (wave_dissipation(isd:ied,jsd:jed)) + allocate (leewave_dissipation(isd:ied,jsd:jed)) + allocate (roughness_length(isd:ied,jsd:jed)) + allocate (roughness_amp(isd:ied,jsd:jed)) + allocate (tide_speed_t(isd:ied,jsd:jed)) + allocate (tide_speed_u(isd:ied,jsd:jed)) + allocate (tide_speed_mask(isd:ied,jsd:jed)) + allocate (tide_rescspeed_mask(isd:ied,jsd:jed)) + allocate (tide_deepspeed_mask(isd:ied,jsd:jed)) + allocate (rescaled_speed_u(isd:ied,jsd:jed)) + allocate (rescaled_speed_t(isd:ied,jsd:jed)) + allocate (efold_depth_r(isd:ied,jsd:jed)) + smooth_lap(:,:) = Grd%tmask(:,:,1)*vel_micom_smooth*2.0*Grd%dxt(:,:)*Grd%dyt(:,:)/(Grd%dxt(:,:)+Grd%dyt(:,:)) + roughness_length(:,:) = Grd%tmask(:,:,1)*default_roughness_length + roughness_amp(:,:) = sqrt(Grd%tmask(:,:,1)/roughness_kappa) + tide_speed_t(:,:) = Grd%tmask(:,:,1)*default_tide_speed + tide_speed_u(:,:) = Grd%umask(:,:,1)*default_tide_speed + tide_speed_mask(:,:) = 0.0 + tide_rescspeed_mask(:,:) = 0.0 + tide_deepspeed_mask(:,:) = 0.0 + rescaled_speed_u(:,:) = 0.0 + rescaled_speed_t(:,:) = 0.0 + efold_depth_r(:,:) = 0.0 + wave_term(:,:) = 0.0 + energy_flux(:,:) = 0.0 + wave_dissipation(:,:) = 0.0 + leewave_dissipation(:,:) = 0.0 + + if(use_wave_dissipation) then + write (stdoutunit,'(a)') & + 'Using Simmons etal scheme to compute dia-surface diffusivity and viscosity based on internal wave breaking.' + Ocean_options%tidal_wave_mix = 'Used tidal wave mixing option for vertical mixing.' + else + write(stdoutunit,'(a)') 'NOT using Simmons etal scheme for dia-surface diffusivity and viscosity.' + Ocean_options%tidal_wave_mix = 'Did NOT use tidal wave mixing option for vertical mixing.' + endif + + if(use_drag_dissipation) then + write (stdoutunit,'(a)') & + 'Using Lee etal scheme to compute dia-surface diffusivity and viscosity based on barotropic tide drag on bottom.' + Ocean_options%tidal_drag_mix = 'Used tidal drag mixing option for vertical mixing.' + if(vert_mix_scheme == 'kpp_mom4p0') then + write (stdoutunit,'(a)') & + '===>WARNING: Using kpp_mom4p0, where Lee etal scheme can be enabled. Be sure not to double count!!!' + endif + else + write(stdoutunit,'(a)') 'NOT using Lee etal scheme from ocean_vert_tidal_test_mod for dia-surface mixing.' + Ocean_options%tidal_drag_mix = 'Did NOT use tidal drag mixing option for vertical mixing.' + endif + + if(use_leewave_dissipation) then + write (stdoutunit,'(a)') & + 'Using prototype for Nikurashin scheme to compute dia-surface diff and visc from breaking leewaves.' + Ocean_options%leewave_mix = 'Using prototype for leewave mixing option for vertical mixing.' + else + write(stdoutunit,'(a)') 'NOT using Nikurashin scheme for dia-surface diffusivity and viscosity.' + Ocean_options%leewave_mix = 'Did NOT use prototype breaking leewave paramaterization of vertical mixing.' + endif + + if(.not. use_drag_dissipation .and. .not. use_wave_dissipation) then + call mpp_error(WARNING, & + '==>ocean_vert_tidal_test: No dissipation mechanism is set to determine dia-surface mixing.') + endif + + if(.not. use_wave_dissipation .and. use_leewave_dissipation) then + call mpp_error(WARNING, & + '==>ocean_vert_tidal_test: The prototype leewave mixing scheme must run with use_wave_dissipation=.true.') + endif + + ! read in topographic amplitude ("h" in "kappa*h^2" from Simmons etal 2004) on T-grid + if(read_roughness) then + if(reading_roughness_length) then + roughness_has_been_read=roughness_has_been_read+1 + call read_data('INPUT/roughness_length.nc','roughness_length', roughness_length, Domain%domain2d) + write (stdoutunit,*) '==>ocean_vert_tidal_test_mod: Completed read of topographic roughness length on T-grid.' + call mpp_update_domains(roughness_length(:,:), Dom%domain2d) + roughness_amp(:,:) = sqrt(roughness_length(:,:)/roughness_kappa) + endif + if(reading_roughness_amp) then + roughness_has_been_read=roughness_has_been_read+1 + call read_data('INPUT/roughness_amp.nc','roughness_amp', roughness_amp, Domain%domain2d) + write (stdoutunit,*) '==>ocean_vert_tidal_test_mod: Completed read of topographic roughness amplitude on T-grid.' + call mpp_update_domains(roughness_amp(:,:), Dom%domain2d) + roughness_length(:,:) = roughness_kappa*roughness_amp(:,:)*roughness_amp(:,:) + endif + if(roughness_has_been_read > 1) then + call mpp_error(FATAL, & + '==>ocean_vert_tidal_test_mod: Read in both roughness_amp & roughness_length. Check to be sure what you wish.') + endif + if(roughness_has_been_read==0) then + call mpp_error(FATAL, & + '==>ocean_vert_tidal_test_mod: To read roughness, reading_roughness_amp or reading_roughness_length must be true.') + endif + else + write(stdoutunit,'(a)') & + '==>Note: NOT reading topographic roughness_length for ocean_vert_tidal_test_mod.' + endif + + if(read_wave_dissipation) then + call read_data('INPUT/wave_dissipation.nc','wave_dissipation', wave_dissipation, Domain%domain2d) + write (stdoutunit,*) '==>ocean_vert_tidal_test_mod: Completed read of wave dissipation (W/m^2) on T-grid.' + call mpp_update_domains(wave_dissipation(:,:), Dom%domain2d) + else + write(stdoutunit,'(a)') & + '==>Note: NOT reading wave dissipation for ocean_vert_tidal_test_mod.' + endif + + if(read_leewave_dissipation) then + call read_data('INPUT/leewave_dissipation.nc','leewave_dissipation', leewave_dissipation, Domain%domain2d) + write (stdoutunit,*) '==>ocean_vert_tidal_test_mod: Completed read of leewave dissipation (W/m^2) on T-grid.' + call mpp_update_domains(leewave_dissipation(:,:), Dom%domain2d) + else + write(stdoutunit,'(a)') & + '==>Note: NOT reading leewave dissipation for ocean_vert_tidal_test_mod.' + endif + + ! read tidal speed (m/s) from a tide model, such as the + ! Global Inverse Solution TPX06.0 created by OSU. + if(read_tide_speed) then + if(tide_speed_data_on_t_grid) then + call read_data('INPUT/tideamp.nc','tideamp', tide_speed_t, Domain%domain2d) + write (stdoutunit,*) '==>ocean_vert_tidal_test_mod: Completed read of tide_speed on T-grid.' + call mpp_update_domains(tide_speed_t(:,:), Dom%domain2d) + else + call read_data('INPUT/tideamp.nc','tideamp', tide_speed_u, Domain%domain2d) + write (stdoutunit,*) '==>ocean_vert_tidal_test_mod: Completed read of tide_speed on U-grid.' + call mpp_update_domains(tide_speed_u(:,:), Dom%domain2d) + endif + else + write(stdoutunit,'(a)') & + '==>Note: NOT reading tide_speed for ocean_vert_tidal_test_mod.' + call mpp_error(NOTE, & + '==>ocean_vert_tidal_test_mod: Setting tide_speed to default value.') + endif + + ! map tide speed onto U-cell by 4-point average + if(tide_speed_data_on_t_grid) then + do j=jsc,jec + do i=isc,iec + tide_speed_u(i,j) = onefourth*Grd%umask(i,j,1) & + *(tide_speed_t(i,j) + tide_speed_t(i+1,j) & + +tide_speed_t(i,j+1) + tide_speed_t(i+1,j+1)) + enddo + enddo + call mpp_update_domains(tide_speed_u(:,:), Dom%domain2d) + endif + + + + ! note for the bottom drag coefficient + if(drag_dissipation_use_cdbot) then + + write(stdoutunit,'(a)') & + '==>Note from ocean_vert_tidal_test: using cdbot_array(i,j) for tide drag_dissipation scheme.' + + else !if(drag_dissipation_use_cdbot) + + write(stdoutunit,'(a)') & + '==>Note from ocean_vert_tidal_test: using constant bottom drag coefficient for tide drag_dissipation scheme.' + + do j=jsd,jed + do i=isd,ied + rescaled_speed_u(i,j) = sqrt_cd*von_karman_inv*tide_speed_u(i,j) + rescaled_speed_t(i,j) = sqrt_cd*von_karman_inv*tide_speed_t(i,j) + tide_rescspeed_mask(i,j) = 0.0 + if(rescaled_speed_u(i,j) > speed_min) then + tide_rescspeed_mask(i,j) = 1.0 + endif + enddo + enddo + + call mpp_update_domains(tide_rescspeed_mask(:,:), Dom%domain2d) + + + ! compute efolding depth scale for use in Lee etal scheme. + ! efold depth set as rescaled_speed/(radial tide frequency). + ! Choose default radial tide frequency as 2pi/12hrs for semi-diurnal tide. + ! let this efolding hold whether using Bgrid or Cgrid. + wrk1_2d(:,:) = 0.0 + do j=jsc,jec + do i=isc,iec + active_cells = Grd%umask(i,j,1) + Grd%umask(i-1,j,1) & + + Grd%umask(i,j-1,1) + Grd%umask(i-1,j-1,1) + epsln + temporary = (rescaled_speed_u(i,j) + rescaled_speed_u(i-1,j) + & + rescaled_speed_u(i,j-1) + rescaled_speed_u(i-1,j-1))/active_cells + wrk1_2d(i,j) = Grd%tmask(i,j,1)*temporary*drag_dissipation_tide_period/(2.0*pi) + efold_depth_r(i,j) = Grd%tmask(i,j,1)/(wrk1_2d(i,j) + epsln) + enddo + enddo + + endif !if(drag_dissipation_use_cdbot) + + + ! mask out the deep ocean regions for the drag scheme. + if(drag_mask_deep .and. .not. use_legacy_methods) then + ! only to reproduce the previous results with const cdbot + if (repro_legacy_const_cdbot .and. .not. drag_dissipation_use_cdbot) then + do j=jsc,jec + do i=isc,iec + if(Grd%tmask(i,j,1) == 1.0) then + temporary = wrk1_2d(i,j)/(epsln+Grd%ht(i,j)) + if(temporary > drag_mask_deep_ratio) then + tide_deepspeed_mask(i,j) = 1.0 + else + tide_deepspeed_mask(i,j) = 0.0 + endif + endif + enddo + enddo + else + do j=jsc,jec + do i=isc,iec + if(Grd%tmask(i,j,1) == 1.0) then + if(Grd%ht(i,j) <= shelf_depth_cutoff) tide_deepspeed_mask(i,j) = 1.0 + endif + enddo + enddo + endif + else + tide_deepspeed_mask(:,:) = 1.0 + endif + + call mpp_update_domains(tide_deepspeed_mask(:,:), Dom%domain2d) + + + + + if(use_legacy_methods) then + + if(drag_dissipation_use_cdbot) then + write(stdoutunit,'(a)') & + '==>Note from ocean_vert_tidal_test: using cdbot_array(i,j) for tide drag_dissipation scheme.' + do j=jsd,jed + do i=isd,ied + rescaled_speed_u(i,j) = sqrt(Velocity%cdbot_array(i,j))*von_karman_inv*tide_speed_u(i,j) + rescaled_speed_t(i,j) = sqrt(Velocity%cdbot_array(i,j))*von_karman_inv*tide_speed_t(i,j) + tide_speed_mask(i,j) = 0.0 + if(rescaled_speed_u(i,j) > speed_min) then + tide_speed_mask(i,j) = 1.0 + endif + enddo + enddo + else + write(stdoutunit,'(a)') & + '==>Note from ocean_vert_tidal_test: using constant bottom drag coefficient for tide drag_dissipation scheme.' + + do j=jsd,jed + do i=isd,ied + rescaled_speed_u(i,j) = sqrt_cd*von_karman_inv*tide_speed_u(i,j) + rescaled_speed_t(i,j) = sqrt_cd*von_karman_inv*tide_speed_t(i,j) + tide_speed_mask(i,j) = 0.0 + if(rescaled_speed_u(i,j) > speed_min) then + tide_speed_mask(i,j) = 1.0 + endif + enddo + enddo + endif !if(drag_dissipation_use_cdbot) + + endif !if(use_legacy_methods) + + + ! compute static piece of the energy flux on T-grid for wave diffusivity + do j=jsd,jed + do i=isd,ied + wave_term(i,j) = Grd%tmask(i,j,1)*p5rho0*roughness_length(i,j)*tide_speed_t(i,j)**2 + enddo + enddo + + + + ! diagnostics + + id_tide_diff_cbt_back = -1 + id_tide_diff_cbt_back = register_static_field ('ocean_model', 'tide_diff_cbt_back', & + Grid%tracer_axes(1:3), 'static background diff_cbt set in tide module',& + 'm^2/s',missing_value=missing_value, range=(/-10.0,1e6/)) + if (id_tide_diff_cbt_back > 0) then + wrk1(:,:,:) = background_diffusivity*Grid%tmask(:,:,:) + used = send_data (id_tide_diff_cbt_back, wrk1(isc:iec,jsc:jec,:), & + Time%model_time, rmask=Grid%tmask(isc:iec,jsc:jec,:)) + endif + + id_tide_visc_cbu_back = -1 + id_tide_visc_cbu_back = register_static_field ('ocean_model', 'tide_visc_cbu_back', & + Grid%vel_axes_wu(1:3), 'static background visc_cbu set in tide module',& + 'm^2/s',missing_value=missing_value, range=(/-10.0,1e6/)) + if (id_tide_visc_cbu_back > 0) then + wrk1(:,:,:) = background_viscosity*Grid%umask(:,:,:) + used = send_data (id_tide_visc_cbu_back, wrk1(isc:iec,jsc:jec,:), & + Time%model_time, rmask=Grid%umask(isc:iec,jsc:jec,:)) + endif + + ! e-folding depth for drag dissipation scheme + id_drag_diss_efold = register_static_field ('ocean_model', 'drag_diss_efold',& + Grid%tracer_axes(1:2), 'e-folding depth for drag dissipation scheme', & + 'm', missing_value=missing_value, range=(/-1.0,1e10/)) + + id_tide_rescspeed_mask = register_diag_field ('ocean_model', 'tide_rescspeed_mask', & + Grid%vel_axes_uv(1:2), Time%model_time, 'mask based on tide_speed_drag for barotropic drag mixing', & + 'dimensionless', missing_value=missing_value, range=(/-1e1,1e1/)) + + id_tide_deepspeed_mask = register_diag_field ('ocean_model', 'tide_deepspeed_mask', & + Grid%vel_axes_uv(1:2), Time%model_time, 'mask based on tide_speed_drag for deep ocean region', & + 'dimensionless', missing_value=missing_value, range=(/-1e1,1e1/)) + + if(.not. drag_dissipation_use_cdbot) then + if (id_tide_rescspeed_mask > 0) then + used = send_data (id_tide_rescspeed_mask, tide_rescspeed_mask(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_drag_diss_efold > 0) then + used = send_data (id_drag_diss_efold, wrk1_2d(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + endif !if(drag_dissipation_use_cdbot) + + if (id_tide_deepspeed_mask > 0) then + used = send_data (id_tide_deepspeed_mask, tide_deepspeed_mask(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + + ! static input of leewave breaking from Nikurashin + id_leewave_dissipation = register_static_field ('ocean_model', 'leewave_dissipation',& + Grid%tracer_axes(1:2), 'specified energy flux input from breaking leewaves', & + 'W/m^2', missing_value=missing_value, range=(/-1e1,1e15/)) + if (id_leewave_dissipation > 0) then + used = send_data (id_leewave_dissipation, leewave_dissipation(:,:),& + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + + ! tide speed for breaking internal wave dissipation scheme + id_tide_speed_wave = register_static_field ('ocean_model', 'tide_speed_wave', & + Grid%tracer_axes(1:2), 'tide speed from tide model for breaking internal wave mixing scheme',& + 'm/s', missing_value=missing_value, range=(/-1e1,1e9/)) + if (id_tide_speed_wave > 0) then + used = send_data (id_tide_speed_wave, tide_speed_t(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + + ! tide speed scale for barotropic bottom drag dissipation scheme + id_tide_speed_drag = register_static_field ('ocean_model', 'tide_speed_drag', & + Grid%vel_axes_uv(1:2), 'tide speed from tide model for barotropic drag mixing scheme',& + 'm/s', missing_value=missing_value, range=(/-1e1,1e9/)) + if (id_tide_speed_drag > 0) then + used = send_data (id_tide_speed_drag, rescaled_speed_u(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + + id_roughness_amp = register_static_field ('ocean_model', 'roughness_amp', & + Grid%tracer_axes(1:2), 'roughness amplitude for breaking internal wave mixing scheme',& + 'metre', missing_value=missing_value, range=(/-1e1,1e9/)) + if (id_roughness_amp > 0) then + used = send_data (id_roughness_amp, roughness_amp(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + + ! static roughness length + id_roughness_length = register_static_field ('ocean_model', 'roughness_length', & + Grid%tracer_axes(1:2), 'roughness length for breaking internal wave mixing scheme',& + 'metre', missing_value=missing_value, range=(/-1e1,1e9/)) + if (id_roughness_length > 0) then + used = send_data (id_roughness_length, roughness_length(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + + + id_roughness_klevel = register_diag_field ('ocean_model', 'roughness_klevel', & + Grid%tracer_axes(1:2), Time%model_time, & + 'klevel at top of the bottom layer defined by roughness amplitude for internal tide mixing',& + 'dimensionless', missing_value=missing_value, range=(/-1.0,1.e10/)) + id_energy_flux = register_diag_field ('ocean_model', 'energy_flux', & + Grid%tracer_axes(1:2), Time%model_time, & + 'energy flux out of barotropic tides for use w/ internal tide mixing',& + 'W/m^2', missing_value=missing_value, range=(/-1e9,1e9/)) + id_power_waves = register_diag_field ('ocean_model', 'power_waves', & + Grid%tracer_axes(1:2), Time%model_time, 'power from barotropic tides to internal tides', & + 'Watt', missing_value=missing_value, range=(/-1e15,1e15/)) + + id_power_diss_leewave = register_diag_field ('ocean_model', 'power_diss_leewave', & + Grid%tracer_axes(1:3), Time%model_time, 'power dissipation from mixing due to breaking leewaves',& + 'W/m^2', missing_value=missing_value, range=(/-1e15,1e15/)) + id_power_diss_wave = register_diag_field ('ocean_model', 'power_diss_wave', & + Grid%tracer_axes(1:3), Time%model_time, 'power dissipation from internal wave induced mixing', & + 'W/m^2', missing_value=missing_value, range=(/-1e15,1e15/)) + id_power_diss_drag = register_diag_field ('ocean_model', 'power_diss_drag', & + Grid%tracer_axes(1:3), Time%model_time, 'power dissipation from barotropic tide drag', & + 'W/m^2', missing_value=missing_value, range=(/-1e15,1e15/)) + id_power_diss_tides = register_diag_field ('ocean_model', 'power_diss_tides',& + Grid%tracer_axes(1:3), Time%model_time, & + 'power dissipation from barotropic tide drag and baroclinic wave drag', & + 'W/m^2', missing_value=missing_value, range=(/-1e15,1e15/), & + standard_name='tendency_of_ocean_potential_energy_content_due_to_tides') + + id_mix_efficiency = register_diag_field ('ocean_model', 'mix_efficiency', & + Grid%tracer_axes(1:3), Time%model_time, 'efficiency of internal wave dissipation going to mix tracer',& + 'dimensionless', missing_value=missing_value, range=(/-1e5,1e5/)) + id_bvfreq_bottom = register_diag_field ('ocean_model', 'bvfreq_bottom', & + Grid%tracer_axes(1:2), Time%model_time, 'absolute Brunt-Vaisala freq at ocean bottom', & + 's^-1', missing_value=missing_value, range=(/-1e1,1e9/)) + id_bvfreq = register_diag_field ('ocean_model', 'bvfreq', & + Grid%tracer_axes(1:3), Time%model_time, 'absolute Brunt-Vaisala freq at tracer cell bottom', & + 's^-1', missing_value=missing_value, range=(/-1e1,1e9/)) + id_rinumber_drag = register_diag_field ('ocean_model', 'rinumber_drag', & + Grid%tracer_axes(1:3), Time%model_time, 'Richardson number from Lee etal', & + 'dimensionless', missing_value=missing_value, range=(/-1e1,1e18/)) + id_diff_cbt_wave = register_diag_field ('ocean_model', 'diff_cbt_wave', & + Grid%tracer_axes(1:3), Time%model_time, 'diffusivity from breaking internal wave dissipation', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_diff_cbt_leewave = register_diag_field ('ocean_model', 'diff_cbt_leewave', & + Grid%tracer_axes(1:3), Time%model_time, 'diffusivity from breaking leewaves', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_diff_cbt_drag = register_diag_field ('ocean_model', 'diff_cbt_drag', & + Grid%tracer_axes(1:3), Time%model_time, 'diffusivity from drag of barotropic tides on bottom', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + + id_visc_cbt_wave = register_diag_field ('ocean_model', 'visc_cbt_wave', & + Grid%tracer_axes(1:3), Time%model_time, 'viscosity from breaking internal wave dissipation', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_visc_cbt_leewave = register_diag_field ('ocean_model', 'visc_cbt_leewave', & + Grid%tracer_axes(1:3), Time%model_time, 'viscosity from breaking leewaves', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_visc_cbt_drag = register_diag_field ('ocean_model', 'visc_cbt_drag', & + Grid%tracer_axes(1:3), Time%model_time, 'viscosity from drag of barotropic tides on bottom', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + + id_visc_cbu_wave = register_diag_field ('ocean_model', 'visc_cbu_wave', & + Grid%vel_axes_uv(1:3), Time%model_time, 'viscosity from breaking internal wave dissipation', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_visc_cbu_leewave = register_diag_field ('ocean_model', 'visc_cbu_leewave', & + Grid%vel_axes_uv(1:3), Time%model_time, 'viscosity from breaking leewaves ', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_visc_cbu_drag = register_diag_field ('ocean_model', 'visc_cbu_drag', & + Grid%vel_axes_uv(1:3), Time%model_time, 'viscosity from drag of barotropic tides on bottom', & + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/)) + id_diff_cbt_tides = register_diag_field ('ocean_model', 'diff_cbt_tides', & + Grid%tracer_axes(1:3), Time%model_time, 'diffusivity from drag of barotropic tides on bottom + wave drag',& + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/), & + standard_name='ocean_vertical_tracer_diffusivity_due_to_tides') + id_visc_cbt_tides = register_diag_field ('ocean_model', 'visc_cbt_tides', & + Grid%tracer_axes(1:3), Time%model_time, 'viscosity from drag of barotropic tides on bottom + wave drag',& + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/), & + standard_name='ocean_vertical_tracer_diffusivity_due_to_tides') + + id_visc_cbu_tides = register_diag_field ('ocean_model', 'visc_cbu_tides', & + Grid%vel_axes_uv(1:3), Time%model_time, 'viscosity from drag of barotropic tides on bottom + wave drag',& + 'm^2/sec', missing_value=missing_value, range=(/-1.0,1e6/), & + standard_name='ocean_vertical_momentum_diffusivity_due_to_tides') + + +end subroutine ocean_vert_tidal_test_init +!+! +! NAME="vert_mix_tidal_test" + + + +!####################################################################### +!+! This subroutine computes vertical tracer diffusivity and viscosity +! based on one or both of the following dissipation mechanisms: +! +! 1. internal wave breaking as parameterized by Simmons etal. +! +! 2. barotropic tides feeling the bottom drag, as parameterized by +! Lee etal. +! +! +! + subroutine vert_mix_tidal_test(Time, Thickness, Velocity, T_prog, Dens, diff_cbt, visc_cbu, visc_cbt, & + diff_cbt_wave, diff_cbt_leewave, diff_cbt_drag) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + type(ocean_velocity_type), intent(in) :: Velocity + type(ocean_prog_tracer_type), intent(in) :: T_prog(:) + type(ocean_density_type), intent(in) :: Dens + real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_wave + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_leewave + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_drag + + integer :: i, j, k, kp1 + real :: tmp + + if(.not. use_this_module) return + + if(use_legacy_methods) then + + call compute_bvfreq_legacy(Time, Thickness, T_prog, Dens) + if(use_wave_dissipation) then + call vert_mix_wave_legacy(Time, Thickness, diff_cbt, visc_cbu, visc_cbt, diff_cbt_wave) + endif + if(use_drag_dissipation) then + call vert_mix_drag_legacy(Time, Thickness, diff_cbt, visc_cbu, visc_cbt, diff_cbt_drag) + endif + diff_cbt_leewave(:,:,:) = 0.0 + diff_leewave(:,:,:) = 0.0 + + else + + call compute_bvfreq(Time, Thickness, T_prog, Dens) + if(use_wave_dissipation) then + call vert_mix_wave(Time, Thickness, Dens, diff_cbt, visc_cbu, visc_cbt, diff_cbt_wave, diff_cbt_leewave) + endif + if(use_drag_dissipation .and. horz_grid == MOM_BGRID) then + call vert_mix_drag_bgrid(Time, Thickness, Velocity, diff_cbt, visc_cbu, visc_cbt, diff_cbt_drag) + endif + if(use_drag_dissipation .and. horz_grid == MOM_CGRID) then + call vert_mix_drag_cgrid(Time, Thickness, Velocity, diff_cbt, visc_cbu, visc_cbt, diff_cbt_drag) + endif + + endif + + ! add the background diffusivity and viscosity + do k=1,nk + kp1 = min(k+1,nk) + do j=jsc,jec + do i=isc,iec + diff_cbt(i,j,k,1) = Grd%tmask(i,j,kp1)*(diff_cbt(i,j,k,1) + background_diffusivity) + diff_cbt(i,j,k,2) = Grd%tmask(i,j,kp1)*(diff_cbt(i,j,k,2) + background_diffusivity) + visc_cbt(i,j,k) = Grd%tmask(i,j,kp1)*(visc_cbt(i,j,k) + background_viscosity) + visc_cbu(i,j,k) = Grd%umask(i,j,kp1)*(visc_cbu(i,j,k) + background_viscosity) + enddo + enddo + enddo + + ! compute power dissipated by mixing against stratification + if(id_power_diss_wave > 0 .or. id_power_diss_drag > 0 .or. & + id_power_diss_tides > 0 .or. id_power_diss_leewave > 0 ) then + wrk1(:,:,:) = 0.0 + wrk2(:,:,:) = 0.0 + wrk3(:,:,:) = 0.0 + do k=1,nk + do j=jsc,jec + do i=isc,iec + tmp = Thickness%dzt(i,j,k)*rho_N2(i,j,k)*Grd%tmask(i,j,k) + wrk1(i,j,k) = tmp*diff_wave(i,j,k) + wrk2(i,j,k) = tmp*diff_drag(i,j,k) + wrk3(i,j,k) = tmp*diff_leewave(i,j,k) + enddo + enddo + enddo + if (id_power_diss_wave > 0) then + used = send_data (id_power_diss_wave, wrk1(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_power_diss_drag > 0) then + used = send_data (id_power_diss_drag, wrk2(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_power_diss_leewave > 0) then + used = send_data (id_power_diss_leewave, wrk3(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_power_diss_tides > 0) then + used = send_data (id_power_diss_tides, wrk1(:,:,:)+wrk2(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + endif + + if (id_diff_cbt_tides > 0) then + used = send_data (id_diff_cbt_tides, diff_cbt_wave(:,:,:)+diff_cbt_drag(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + + ! recall unit Prandtl number + if (id_visc_cbt_tides > 0) then + used = send_data (id_visc_cbt_tides, diff_cbt_wave(:,:,:)+diff_cbt_drag(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + + if (id_visc_cbu_tides > 0) then + wrk1=0.0 + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + wrk1(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_cbt_wave(i,j,k) +diff_cbt_wave(i+1,j,k) & + +diff_cbt_wave(i,j+1,k)+diff_cbt_wave(i+1,j+1,k)& + +diff_cbt_drag(i,j,k) +diff_cbt_drag(i+1,j,k) & + +diff_cbt_drag(i,j+1,k)+diff_cbt_drag(i+1,j+1,k)) + enddo + enddo + enddo + used = send_data (id_visc_cbu_tides, wrk1(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + + +end subroutine vert_mix_tidal_test +!+! +! NAME="compute_bvfreq" + + + +!####################################################################### +!+! This subroutine computes the absolute value of rho*N^2 and abs of +! N^2, with N^2 the squared Brunt-Vaisala (or buoyancy) frequency. +! +! +! + subroutine compute_bvfreq(Time, Thickness, T_prog, Dens) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + type(ocean_prog_tracer_type), intent(in) :: T_prog(:) + type(ocean_density_type), intent(in) :: Dens + + real :: rho_inv, drhodz, bottom + real :: tmp, rho_N2_prev, rho_tmp + integer :: i, j, k, m, kp1, kbot + integer :: tau + real, dimension(isd:ied,jsd:jed) :: roughness_klevel + + tau = Time%tau + wrk1(:,:,:) = 0.0 + wrk2(:,:,:) = 0.0 + bvfreq_bottom(:,:) = 0.0 + + + ! absolute(rho*N^2) computed from ocean_density module calculation. + ! use the value at T-cell centre as this produces a smoother and + ! better behaved bvfreq near the bottom, than does drhodz_wt. + do k=1,nk + do j=jsd,jed + do i=isd,ied + rho_N2(i,j,k) = max(0.0,-grav*Dens%drhodz_zt(i,j,k)*Grd%tmask(i,j,k)) + enddo + enddo + enddo + + ! smooth rho_N2 in the vertical using a 1-2-1 filter + if (smooth_rho_N2) then + do m=1,num_121_passes + do j=jsd,jed + do i=isd,ied + rho_N2_prev = onefourth*rho_N2(i,j,1) + kbot=Grd%kmt(i,j) + if (kbot>3) then + do k=2,kbot-2 + tmp = rho_N2(i,j,k) + rho_N2(i,j,k) = rho_N2_prev + onehalf*rho_N2(i,j,k) + onefourth*rho_N2(i,j,k+1) + rho_N2_prev = onefourth*tmp + enddo + endif + enddo + enddo + enddo + endif + + ! compute absolute value of buoyancy frequency, + ! using rho0r as an approximation to 1/rho. + do k=1,nk + do j=jsd,jed + do i=isd,ied + bvfreq(i,j,k) = sqrt(rho0r*rho_N2(i,j,k)) + enddo + enddo + enddo + + ! determine k-level at top of the bottom roughness boundary layer + wrk1_2d(:,:) = 0.0 + do j=jsd,jed + do i=isd,ied + kbot = Grd%kmt(i,j) + roughness_klevel(:,:) = kbot + if(kbot > 1) then + bottom = Thickness%depth_zwt(i,j,kbot) + kloop: do k=kbot,1,-1 + tmp = Thickness%depth_zwt(i,j,k) + roughness_amp(i,j) + if(tmp <= bottom) then + wrk1_2d(i,j) = k + roughness_klevel(i,j) = k + exit kloop + endif + enddo kloop + endif + enddo + enddo + + + ! set bvfreq in bottom equal to value at kmt-1 + do j=jsd,jed + do i=isd,ied + bvfreq_bottom(i,j) = 0.0 + if(Grd%kmt(i,j) > 1) then + kbot=Grd%kmt(i,j)-1 + bvfreq_bottom(i,j) = bvfreq(i,j,kbot) + endif + enddo + enddo + + ! horizontal laplacian smoothing on the bottom bvfreq + if(smooth_bvfreq_bottom) then + bvfreq_bottom(:,:) = bvfreq_bottom(:,:) + dtime*LAP_T(bvfreq_bottom(:,:),smooth_lap(:,:)) + call mpp_update_domains(bvfreq_bottom(:,:), Dom%domain2d) + endif + + + ! diagnostics + + if (id_roughness_klevel > 0) then + used = send_data (id_roughness_klevel, wrk1_2d(:,:),& + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_bvfreq_bottom > 0) then + used = send_data (id_bvfreq_bottom, bvfreq_bottom(:,:),& + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_bvfreq > 0) then + used = send_data (id_bvfreq, bvfreq(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + + +end subroutine compute_bvfreq +!+! +! NAME="vert_mix_wave" + + +!####################################################################### +!+! This subroutine computes dia-surface tracer diffusivity based on the +! methods of Simmons et al., which consider dissipation from breaking +! internal gravity waves and their conversion into local dia-surface +! mixing, which is parameterized as diffusion. +! +! Also compute a prototype parameterization of mixing due to +! breaking leewaves from Nikurashin. +! +! We assume a unit Prandtl number. +! +! Note that if umask(i,j,k) is 1.0, then so is +! tmask(i,j,k), tmask(i+1,j,k), tmask(i,j+1,k), and tmask(i+1,j+1,k). +! So there is no need to compute the "active_cells" when doing the +! space average to go from t-cell to u-cell to compute visc_cbu. +! +! +! + subroutine vert_mix_wave(Time, Thickness, Dens, diff_cbt, visc_cbu, visc_cbt, diff_cbt_wave, diff_cbt_leewave) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + type(ocean_density_type), intent(in) :: Dens + real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_wave + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_leewave + + integer :: i, j, k, kbot, kp1, tau + real :: deposition, factor, tmp, rho_tmp + + tau = Time%tau + diff_wave(:,:,:) = 0.0 ! diffusivity from wave scheme + diff_leewave(:,:,:) = 0.0 ! diffusivity from leewave scheme + wrk1(:,:,:) = 0.0 ! viscosity from wave scheme + wrk2(:,:,:) = 0.0 ! mix_efficiency / rho_N2 + + ! compute mask for regions that are deemed too shallow for this scheme + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + tmask_deep(i,j) = 0.0 + if(kbot > 1) then + if(Thickness%depth_zwt(i,j,kbot) > shelf_depth_cutoff) tmask_deep(i,j) = 1.0 + endif + enddo + enddo + + ! energy flux array (W/m2) (Simmons etal equation (1)) + if(fixed_wave_dissipation) then + do j=jsd,jed + do i=isd,ied + energy_flux(i,j) = min(wave_energy_flux_max, wave_dissipation(i,j)*tmask_deep(i,j)) + enddo + enddo + else + do j=jsd,jed + do i=isd,ied + energy_flux(i,j) = min(wave_energy_flux_max, wave_term(i,j)*bvfreq_bottom(i,j)*tmask_deep(i,j)) + enddo + enddo + endif + + ! compute mixing efficiency function + if(mixing_efficiency_n2depend) then + do k=1,nk + do j=jsd,jed + do i=isd,ied + rho_tmp = Dens%rho(i,j,k,tau) + epsln + mix_efficiency(i,j,k) = mixing_efficiency*Grd%tmask(i,j,k) & + *rho_N2(i,j,k)/(rho_N2(i,j,k) + rho_tmp*omega_earth2) + wrk2(i,j,k) = mixing_efficiency*Grd%tmask(i,j,k) & + /(rho_N2(i,j,k) + rho_tmp*omega_earth2) + enddo + enddo + enddo + else + do k=1,nk + do j=jsd,jed + do i=isd,ied + mix_efficiency(i,j,k) = mixing_efficiency*Grd%tmask(i,j,k) + wrk2(i,j,k) = mixing_efficiency*Grd%tmask(i,j,k) & + /(rho_N2(i,j,k) + epsln) + enddo + enddo + enddo + endif + + + ! diffusivity calculation (Simmons etal equation (3)) + do j=jsd,jed + do i=isd,ied + + kbot=Grd%kmt(i,j) + if(kbot > 1) then + + ! normalization of vertical structure function. + ! Ensure it integrates to unity on the discrete grid. + ! "factor" approx decay_scale_inv/(exp[(H+eta)*decay_scale_inv]-1.0) + factor = 0.0 + do k=1,kbot-1 + factor = factor + Thickness%dzt(i,j,k)*exp(decay_scale_inv*Thickness%depth_zwt(i,j,k)) + enddo + factor = 1.0/factor + + do k=1,kbot-1 + deposition = factor*exp(decay_scale_inv*Thickness%depth_zwt(i,j,k)) + tmp = Grd%tmask(i,j,k+1)*wrk2(i,j,k)*tidal_diss_efficiency*deposition + diff_wave(i,j,k) = tmp*energy_flux(i,j) + diff_leewave(i,j,k) = tmp*leewave_dissipation(i,j) + diff_wave(i,j,k) = min(diff_wave(i,j,k),max_wave_diffusivity) + diff_leewave(i,j,k) = min(diff_leewave(i,j,k),max_wave_diffusivity) + enddo + + endif + + enddo + enddo + + + ! ensure diffusivity monotonically decreases as move upward in column. + ! recall that diff_wave(i,j,k) is the diffusivity at the bottom of cell-k, + ! where diff_wave(i,j,kbot)=0.0 by definition. This prompts the kbot-2,1,-1 + ! loop limits. + if(wave_diffusivity_monotonic) then + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + if(kbot > 1) then + do k=kbot-2,1,-1 + diff_wave(i,j,k) = min(diff_wave(i,j,k),diff_wave(i,j,k+1)) + diff_leewave(i,j,k) = min(diff_leewave(i,j,k),diff_leewave(i,j,k+1)) + enddo + endif + enddo + enddo + endif + + ! add wave induced diffusivity and viscosity to diff_cbt and visc_cbu + wrk1(:,:,:) = 0.0 + wrk2(:,:,:) = 0.0 + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_cbt_wave(i,j,k) = diff_wave(i,j,k) + diff_cbt_leewave(i,j,k) = diff_leewave(i,j,k) + diff_cbt(i,j,k,1) = diff_cbt(i,j,k,1) + diff_wave(i,j,k) + diff_leewave(i,j,k) + diff_cbt(i,j,k,2) = diff_cbt(i,j,k,2) + diff_wave(i,j,k) + diff_leewave(i,j,k) + visc_cbt(i,j,k) = visc_cbt(i,j,k) + diff_wave(i,j,k) + diff_leewave(i,j,k) + wrk1(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_wave(i,j,k) +diff_wave(i+1,j,k) & + +diff_wave(i,j+1,k) +diff_wave(i+1,j+1,k)) + wrk2(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_leewave(i,j,k) +diff_leewave(i+1,j,k) & + +diff_leewave(i,j+1,k)+diff_leewave(i+1,j+1,k)) + visc_cbu(i,j,k) = visc_cbu(i,j,k) + wrk1(i,j,k) + wrk2(i,j,k) + enddo + enddo + enddo + + + ! send some diagnostics + + if (id_mix_efficiency > 0) then + used = send_data (id_mix_efficiency, mix_efficiency(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_energy_flux > 0) then + used = send_data (id_energy_flux, energy_flux(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_power_waves > 0) then + used = send_data (id_power_waves, Grd%dat(:,:)*energy_flux(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_diff_cbt_wave > 0) then + used = send_data (id_diff_cbt_wave, diff_wave(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_diff_cbt_leewave > 0) then + used = send_data (id_diff_cbt_leewave, diff_leewave(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbt_wave > 0) then + used = send_data (id_visc_cbt_wave, diff_wave(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbt_leewave > 0) then + used = send_data (id_visc_cbt_leewave, diff_leewave(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbu_wave > 0) then + used = send_data (id_visc_cbu_wave, wrk1(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbu_leewave > 0) then + used = send_data (id_visc_cbu_leewave, wrk2(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + + +end subroutine vert_mix_wave +!+! +! NAME="vert_mix_drag_bgrid" + + +!####################################################################### +!+! This subroutine computes dia-surface tracer diffusivity based on the +! methods of Lee etal., which consider the dissipation from barotropic tides +! rubbing against the ocean bottom. +! +! We assume B-grid layout for the velocity +! +! We assume a unit Prandtl number, so compute the viscosity as a four-point +! average of the diffusivity. +! +! We perform various averages here in order to smooth Richardson number. +! +! 1. compute Richardson number on U-cell by averaging bvfreq from T-cell +! 2. average U-cell Richardson number to then get T-cell diffusivity +! 3. average T-cell diffusivity to get U-cell viscosity. +! +! Note that if umask(i,j,k)==1.0, then so is tmask(i,j,k), tmask(i+1,j,k), +! tmask(i,j+1,k), and tmask(i+1,j+1,k). So there is no need to compute +! active_cells when averaging from T-cell to U-cell. +! +! +! + subroutine vert_mix_drag_bgrid(Time, Thickness, Velocity, diff_cbt, visc_cbu, visc_cbt, diff_cbt_drag) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + type(ocean_velocity_type), intent(in) :: Velocity + real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_drag + + integer :: i, j, k, kbot, kp1 + real :: height, bottom, efold + real :: bvfreq_u, speedr, active_cells, temporary + + integer :: stdoutunit,stdlogunit + stdoutunit=stdout();stdlogunit=stdlog() + + wrk1(:,:,:) =0.0 ! Richardson number on U-cell + wrk2(:,:,:) =0.0 ! Richardson number on T-cell + wrk3(:,:,:) =0.0 ! viscosity from drag scheme + diff_drag(:,:,:) =0.0 ! diffusivity from drag scheme + + + ! speed scale for tides rubbing against bottom + ! (defined following eq. (3) in Lee etal) + if(drag_dissipation_use_cdbot) then + do j=jsd,jed + do i=isd,ied + rescaled_speed_u(i,j) = sqrt(Velocity%cdbot_array(i,j))*von_karman_inv*tide_speed_u(i,j) + rescaled_speed_t(i,j) = sqrt(Velocity%cdbot_array(i,j))*von_karman_inv*tide_speed_t(i,j) + tide_rescspeed_mask(i,j) = 0.0 + if(rescaled_speed_u(i,j) > speed_min) then + tide_rescspeed_mask(i,j) = 1.0 + endif + enddo + enddo + + + ! compute efolding depth scale for use in Lee etal scheme. + ! efold depth set as rescaled_speed/(radial tide frequency). + ! Choose default radial tide frequency as 2pi/12hrs for semi-diurnal tide. + ! let this efolding hold whether using Bgrid or Cgrid. + wrk1_2d(:,:) = 0.0 + do j=jsc,jec + do i=isc,iec + active_cells = Grd%umask(i,j,1) + Grd%umask(i-1,j,1) & + + Grd%umask(i,j-1,1) + Grd%umask(i-1,j-1,1) + epsln + temporary = (rescaled_speed_u(i,j) + rescaled_speed_u(i-1,j) + & + rescaled_speed_u(i,j-1) + rescaled_speed_u(i-1,j-1))/active_cells + wrk1_2d(i,j) = Grd%tmask(i,j,1)*temporary*drag_dissipation_tide_period/(2.0*pi) + efold_depth_r(i,j) = Grd%tmask(i,j,1)/(wrk1_2d(i,j) + epsln) + enddo + enddo + + endif ! if(drag_dissipation_use_cdbot) + + + ! Richardson number on U-cell. + ! perform a 4-point average of T-cell bvfreq + ! and then divide by the U-cell tidal speed term. + ! tide_speed_mask is useful to reduce overflows + ! in later calculation of the diffusivity. + + +if(drag_mask_deep .and. .not. use_legacy_methods) then +! only to reproduce the previous results with const cdbot +! tide_deepspeed_mask(i,j) is the same as tide_speed_mask(i,j) of the previous + do j=jsd,jed-1 + do i=isd,ied-1 + kbot=Grd%kmu(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwu(i,j,kbot) + speedr = tide_deepspeed_mask(i,j)/(epsln+rescaled_speed_u(i,j)) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwu(i,j,k) + bvfreq_u = onefourth*(bvfreq(i,j,k)+bvfreq(i+1,j,k)+bvfreq(i,j+1,k)+bvfreq(i+1,j+1,k)) + wrk1(i,j,k) = 2.0*Grd%umask(i,j,kp1)*(bvfreq_u*height*speedr)**2 + enddo + endif + enddo + enddo +else + do j=jsd,jed-1 + do i=isd,ied-1 + kbot=Grd%kmu(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwu(i,j,kbot) + speedr = tide_rescspeed_mask(i,j)*tide_deepspeed_mask(i,j)/(epsln+rescaled_speed_u(i,j)) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwu(i,j,k) + bvfreq_u = onefourth*(bvfreq(i,j,k)+bvfreq(i+1,j,k)+bvfreq(i,j+1,k)+bvfreq(i+1,j+1,k)) + wrk1(i,j,k) = 2.0*Grd%umask(i,j,kp1)*(bvfreq_u*height*speedr)**2 + enddo + endif + enddo + enddo +endif + + ! Richardson number on bottom of T-cells. + ! need active_cells for averaging operation. + do k=1,nk-1 + do j=jsc,jec + do i=isc,iec + active_cells = Grd%umask(i,j,k) + Grd%umask(i-1,j,k) & + + Grd%umask(i,j-1,k) + Grd%umask(i-1,j-1,k) + epsln + wrk2(i,j,k) = (wrk1(i,j,k) + wrk1(i-1,j,k) + wrk1(i,j-1,k) + wrk1(i-1,j-1,k))/active_cells + enddo + enddo + enddo + + + ! compute drag induced diffusivity + ! (Lee etal equations (1), (2), and (3)) + ! Multiply by tide_speed_mask so to zero out + ! regions with tiny tide speeds, which are regions + ! where we do not wish to have any enhanced mixing + ! arising from the barotropic tide mixing parameterization + ! anyhow. + +if(drag_mask_deep .and. .not. use_legacy_methods) then +! only to reproduce the previous results with const cdbot +! tide_deepspeed_mask(i,j) is the same as tide_speed_mask(i,j) of the previous + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_drag(i,j,k) = Grd%tmask(i,j,kp1)*tide_deepspeed_mask(i,j) & + *max_drag_diffusivity*(1.0 + munk_anderson_sigma*wrk2(i,j,k))**(-munk_anderson_p) + enddo + enddo + enddo + +else + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_drag(i,j,k) = Grd%tmask(i,j,kp1)*tide_rescspeed_mask(i,j)*tide_deepspeed_mask(i,j) & + *max_drag_diffusivity*(1.0 + munk_anderson_sigma*wrk2(i,j,k))**(-munk_anderson_p) + enddo + enddo + enddo +endif + + + if(drag_dissipation_efold) then + do j=jsc,jec + do i=isc,iec + kbot=Grd%kmt(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwt(i,j,kbot) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwt(i,j,k) + diff_drag(i,j,k) = diff_drag(i,j,k)*exp(-height*efold_depth_r(i,j)) + enddo + endif + enddo + enddo + endif + + call mpp_update_domains(diff_drag(:,:,:), Dom%domain2d) + + + ! add drag induced diffusivity and viscosity to diff_cbt and visc_cbu. + ! average t-cell diffusivities to get u-cell viscosity. + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_cbt_drag(i,j,k) = diff_drag(i,j,k) + diff_cbt(i,j,k,1) = diff_cbt(i,j,k,1) + diff_drag(i,j,k) + diff_cbt(i,j,k,2) = diff_cbt(i,j,k,2) + diff_drag(i,j,k) + visc_cbt(i,j,k) = visc_cbt(i,j,k) + diff_drag(i,j,k) + wrk3(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_drag(i,j,k) +diff_drag(i+1,j,k) & + +diff_drag(i,j+1,k)+diff_drag(i+1,j+1,k)) + visc_cbu(i,j,k) = visc_cbu(i,j,k) + wrk3(i,j,k) + enddo + enddo + enddo + + + if (id_rinumber_drag > 0) then + used = send_data (id_rinumber_drag, wrk2(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_diff_cbt_drag > 0) then + used = send_data (id_diff_cbt_drag, diff_drag(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbu_drag > 0) then + used = send_data (id_visc_cbu_drag, wrk3(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + +if(drag_dissipation_use_cdbot) then + if (id_tide_rescspeed_mask > 0) then + used = send_data (id_tide_rescspeed_mask, tide_rescspeed_mask(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_drag_diss_efold > 0) then + used = send_data (id_drag_diss_efold, wrk1_2d(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif +endif !if(drag_dissipation_use_cdbot) + + +end subroutine vert_mix_drag_bgrid +!+! +! NAME="vert_mix_drag_cgrid" + + +!####################################################################### +!+! This subroutine computes dia-surface tracer diffusivity based on the +! methods of Lee etal., which consider the dissipation from barotropic tides +! rubbing against the ocean bottom. +! +! We assume a unit Prandtl number, so compute the viscosity as a four-point +! average of the diffusivity. +! +! We assume C-grid layout for the velocity, which renders slight +! distinctions for the calculation of Richardson number. Otherwise, the +! calculations are the same as the Bgrid. We introduce this separate +! routine, however, to enable easier bitwise agreement with older +! model results. Also, further development of this scheme may lead +! to more distinctions from the Bgrid. +! +! +! + subroutine vert_mix_drag_cgrid(Time, Thickness, Velocity, diff_cbt, visc_cbu, visc_cbt, diff_cbt_drag) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + type(ocean_velocity_type), intent(in) :: Velocity + real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_drag + + integer :: i, j, k, kbot, kp1 + real :: height, bottom, efold + real :: bvfreq_u, speedr, active_cells, temporary + + integer :: stdoutunit,stdlogunit + stdoutunit=stdout();stdlogunit=stdlog() + + wrk1(:,:,:) = 0.0 ! raw Richardson number on T-cell + wrk2(:,:,:) = 0.0 ! smoothed Richardson number on T-cell + wrk3(:,:,:) = 0.0 ! visc_cbu from drag scheme + diff_drag(:,:,:) = 0.0 ! diffusivity from drag scheme + + + ! speed scale for tides rubbing against bottom + ! (defined following eq. (3) in Lee etal) + + if(drag_dissipation_use_cdbot) then + do j=jsd,jed + do i=isd,ied + rescaled_speed_u(i,j) = sqrt(Velocity%cdbot_array(i,j))*von_karman_inv*tide_speed_u(i,j) + rescaled_speed_t(i,j) = sqrt(Velocity%cdbot_array(i,j))*von_karman_inv*tide_speed_t(i,j) + tide_rescspeed_mask(i,j) = 0.0 + if(rescaled_speed_u(i,j) > speed_min) then + tide_rescspeed_mask(i,j) = 1.0 + endif + enddo + enddo +! call mpp_update_domains(tide_rescspeed_mask(:,:), Dom%domain2d) + + ! compute efolding depth scale for use in Lee etal scheme. + ! efold depth set as rescaled_speed/(radial tide frequency). + ! Choose default radial tide frequency as 2pi/12hrs for semi-diurnal tide. + ! let this efolding hold whether using Bgrid or Cgrid. + + wrk1_2d(:,:) = 0.0 + do j=jsc,jec + do i=isc,iec + active_cells = Grd%umask(i,j,1) + Grd%umask(i-1,j,1) & + + Grd%umask(i,j-1,1) + Grd%umask(i-1,j-1,1) + epsln + temporary = (rescaled_speed_u(i,j) + rescaled_speed_u(i-1,j) + & + rescaled_speed_u(i,j-1) + rescaled_speed_u(i-1,j-1))/active_cells + wrk1_2d(i,j) = Grd%tmask(i,j,1)*temporary*drag_dissipation_tide_period/(2.0*pi) + efold_depth_r(i,j) = Grd%tmask(i,j,1)/(wrk1_2d(i,j) + epsln) + enddo + enddo + + + endif !if(drag_dissipation_use_cdbot) + + ! Richardson number on T-cell. +if(drag_mask_deep .and. .not. use_legacy_methods) then +! only to reproduce the previous results with const cdbot +! tide_deepspeed_mask(i,j) is the same as tide_speed_mask(i,j) of the previous + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwt(i,j,kbot) + speedr = tide_deepspeed_mask(i,j)/(epsln+rescaled_speed_t(i,j)) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwt(i,j,k) + wrk1(i,j,k) = 2.0*Grd%tmask(i,j,kp1)*(bvfreq(i,j,k)*height*speedr)**2 + wrk2(i,j,k) = wrk1(i,j,k) + enddo + endif + enddo + enddo +else + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwt(i,j,kbot) + speedr = tide_rescspeed_mask(i,j)*tide_deepspeed_mask(i,j)/(epsln+rescaled_speed_t(i,j)) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwt(i,j,k) + wrk1(i,j,k) = 2.0*Grd%tmask(i,j,kp1)*(bvfreq(i,j,k)*height*speedr)**2 + wrk2(i,j,k) = wrk1(i,j,k) + enddo + endif + enddo + enddo +endif + + + ! perform 9point average to smooth, and to be more consistent + ! with the Bgrid approach. + ! need active_cells for averaging operation. + if(smooth_ri_drag_cgrid) then + do k=1,nk-1 + do j=jsc,jec + do i=isc,iec + active_cells = Grd%tmask(i-1,j-1,k) + Grd%tmask(i,j-1,k) + Grd%tmask(i+1,j-1,k) & + + Grd%tmask(i,j-1,k) + Grd%tmask(i,j,k) + Grd%tmask(i+1,j,k) & + + Grd%tmask(i-1,j+1,k) + Grd%tmask(i,j+1,k) + Grd%tmask(i+1,j+1,k) & + + epsln + wrk2(i,j,k) = ( wrk1(i-1,j-1,k) + wrk1(i,j-1,k) + wrk1(i+1,j-1,k) & + + wrk1(i,j-1,k) + wrk1(i,j,k) + wrk1(i+1,j,k) & + + wrk1(i-1,j+1,k) + wrk1(i,j+1,k) + wrk1(i+1,j+1,k)) / active_cells + enddo + enddo + enddo + endif + + + ! compute drag induced diffusivity + ! (Lee etal equations (1), (2), and (3)) + ! Multiply by tide_speed_mask so to zero out + ! regions with tiny tide speeds, which are regions + ! where we do not wish to have any enhanced mixing + ! arising from the barotropic tide mixing parameterization + ! anyhow. + +if(drag_mask_deep .and. .not. use_legacy_methods) then +! only to reproduce the previous results with const cdbot +! tide_deepspeed_mask(i,j) is the same as tide_speed_mask(i,j) of the previous + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_drag(i,j,k) = Grd%tmask(i,j,kp1)*tide_deepspeed_mask(i,j) & + *max_drag_diffusivity*(1.0 + munk_anderson_sigma*wrk2(i,j,k))**(-munk_anderson_p) + enddo + enddo + enddo + +else + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_drag(i,j,k) = Grd%tmask(i,j,kp1)*tide_rescspeed_mask(i,j)*tide_deepspeed_mask(i,j) & + *max_drag_diffusivity*(1.0 + munk_anderson_sigma*wrk2(i,j,k))**(-munk_anderson_p) + enddo + enddo + enddo +endif + + if(drag_dissipation_efold) then + do j=jsc,jec + do i=isc,iec + kbot=Grd%kmt(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwt(i,j,kbot) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwt(i,j,k) + diff_drag(i,j,k) = diff_drag(i,j,k)*exp(-height*efold_depth_r(i,j)) + enddo + endif + enddo + enddo + endif + + call mpp_update_domains(diff_drag(:,:,:), Dom%domain2d) + + + ! add drag induced diffusivity and viscosity to diff_cbt and visc_cbu. + ! average t-cell diffusivities to get u-cell viscosity. + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_cbt_drag(i,j,k) = diff_drag(i,j,k) + diff_cbt(i,j,k,1) = diff_cbt(i,j,k,1) + diff_drag(i,j,k) + diff_cbt(i,j,k,2) = diff_cbt(i,j,k,2) + diff_drag(i,j,k) + visc_cbt(i,j,k) = visc_cbt(i,j,k) + diff_drag(i,j,k) + wrk3(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_drag(i,j,k) +diff_drag(i+1,j,k) & + +diff_drag(i,j+1,k)+diff_drag(i+1,j+1,k)) + visc_cbu(i,j,k) = visc_cbu(i,j,k) + wrk3(i,j,k) + enddo + enddo + enddo + + + if (id_rinumber_drag > 0) then + used = send_data (id_rinumber_drag, wrk2(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_diff_cbt_drag > 0) then + used = send_data (id_diff_cbt_drag, diff_drag(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbu_drag > 0) then + used = send_data (id_visc_cbu_drag, wrk3(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + +if(drag_dissipation_use_cdbot) then + if (id_tide_rescspeed_mask > 0) then + used = send_data (id_tide_rescspeed_mask, tide_rescspeed_mask(:,:), & + Time%model_time, rmask=Grd%umask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_drag_diss_efold > 0) then + used = send_data (id_drag_diss_efold, wrk1_2d(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif +endif !if(drag_dissipation_use_cdbot) + + +end subroutine vert_mix_drag_cgrid +!+! +! NAME="compute_bvfreq_legacy" + + +!####################################################################### +!+! This subroutine computes the absolute value of rho*N^2 and abs of +! N^2, with N^2 the squared Brunt-Vaisala (or buoyancy) frequency. +! +! This routine employs a legacy approach, which is not recommended. +! It remains solely to allow exact reproduction of older results. +! +! +! + subroutine compute_bvfreq_legacy(Time, Thickness, T_prog, Dens) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + type(ocean_prog_tracer_type), intent(in) :: T_prog(:) + type(ocean_density_type), intent(in) :: Dens + + real :: rho_inv, drhodz + real :: tmp, rho_N2_prev, rho_tmp + integer :: i, j, k, m, kp1, kbot + integer :: tau + + tau = Time%tau + wrk1(:,:,:) = 0.0 + wrk2(:,:,:) = 0.0 + + ! partial derivatives of density wrt to temperature and salinity + do k=1,nk + do j=jsd,jed + do i=isd,ied + drhodT(i,j,k) = Dens%drhodT(i,j,k) + drhodS(i,j,k) = Dens%drhodS(i,j,k) + enddo + enddo + enddo + + + ! vertical derivative of temperature and salinity at bottom of tracer cells + do k=1,nk + kp1=min(k+1,nk) + do j=jsd,jed + do i=isd,ied + tmp = Grd%tmask(i,j,kp1)/Thickness%dzwt(i,j,k) + wrk1(i,j,k) = tmp*(T_prog(index_temp)%field(i,j,k,tau)-T_prog(index_temp)%field(i,j,kp1,tau)) + wrk2(i,j,k) = tmp*(Dens%rho_salinity(i,j,k,tau)-Dens%rho_salinity(i,j,kp1,tau)) + enddo + enddo + enddo + + ! absolute(rho*N^2) computed from vertical derivative of "neutral density" + do k=1,nk + kp1 = min(k+1,nk) + do j=jsd,jed + do i=isd,ied + drhodz = onehalf*( (drhodT(i,j,k)+drhodT(i,j,kp1))*wrk1(i,j,k) & + +(drhodS(i,j,k)+drhodS(i,j,kp1))*wrk2(i,j,k) ) + drhodz = min(drhodz,-drhodz_min)*Grd%tmask(i,j,kp1) + rho_N2(i,j,k) = -grav*drhodz + enddo + enddo + enddo + + ! smooth rho_N2 in the vertical using a 1-2-1 filter + if (smooth_rho_N2) then + do m=1,num_121_passes + do j=jsd,jed + do i=isd,ied + rho_N2_prev = onefourth*rho_N2(i,j,1) + kbot=Grd%kmt(i,j) + if (kbot>3) then + do k=2,kbot-2 + tmp = rho_N2(i,j,k) + rho_N2(i,j,k) = rho_N2_prev + onehalf*rho_N2(i,j,k) + onefourth*rho_N2(i,j,k+1) + rho_N2_prev = onefourth*tmp + enddo + endif + enddo + enddo + enddo + endif + + ! compute buoyancy frequency + do k=1,nk + kp1 = min(k+1,nk) + do j=jsd,jed + do i=isd,ied + rho_inv = 2.0/(epsln + Dens%rho(i,j,k,tau) + Dens%rho(i,j,kp1,tau)) + bvfreq(i,j,k) = sqrt(rho_inv*rho_N2(i,j,k)) + enddo + enddo + enddo + + ! bvfreq at the bottom. + ! set kbot=kmt-1 rather than kbot=kmt, since N^2=0 + ! at bottom of bottom-most tracer cell, by definition. + do j=jsd,jed + do i=isd,ied + bvfreq_bottom(i,j) = 0.0 + if(Grd%kmt(i,j) > 1) then + kbot=Grd%kmt(i,j)-1 + bvfreq_bottom(i,j) = bvfreq(i,j,kbot) + endif + enddo + enddo + + ! horizontal laplacian smoothing on the bottom bvfreq to reduce noise + if(smooth_bvfreq_bottom) then + bvfreq_bottom(:,:) = bvfreq_bottom(:,:) + dtime*LAP_T(bvfreq_bottom(:,:),smooth_lap(:,:)) + call mpp_update_domains(bvfreq_bottom(:,:), Dom%domain2d) + endif + + ! compute mixing efficiency + mix_efficiency(:,:,:) = mixing_efficiency + if(mixing_efficiency_n2depend) then + do k=1,nk + do j=jsd,jed + do i=isd,ied + rho_tmp = Dens%rho(i,j,k,tau) + epsln + mix_efficiency(i,j,k) = mixing_efficiency*rho_N2(i,j,k)/(rho_N2(i,j,k) + rho_tmp*omega_earth2) + enddo + enddo + enddo + endif + + if (id_bvfreq_bottom > 0) then + used = send_data (id_bvfreq_bottom, bvfreq_bottom(:,:),& + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_bvfreq > 0) then + used = send_data (id_bvfreq, bvfreq(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_mix_efficiency > 0) then + used = send_data (id_mix_efficiency, mix_efficiency(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + +end subroutine compute_bvfreq_legacy +!+! +! NAME="vert_mix_wave_legacy" + + + +!####################################################################### +!+! +! Legacy routine maintained only to exactly reproduce older results. +! It is not recommended for new experiments, as it uses some obsolete +! methods. +! +! This subroutine computes dia-surface tracer diffusivity based on the +! methods of Simmons etal., which consider the dissipation from breaking +! internal gravity waves and their conversion into local dia-surface +! diffusion. +! +! We assume a unit Prandtl number, so compute the viscosity as a four-point +! average of the diffusivity. +! +! Note that if umask(i,j,k) is 1.0, then so is +! tmask(i,j,k), tmask(i+1,j,k), tmask(i,j+1,k), and tmask(i+1,j+1,k). +! So there is no need to compute the "active_cells" when doing the +! space average to go from t-cell to u-cell to compute viscosity. +! +! +! + subroutine vert_mix_wave_legacy(Time, Thickness, diff_cbt, visc_cbu, visc_cbt, diff_cbt_wave) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_wave + + integer :: i, j, k, kbot, kp1 + real :: deposition, factor + + diff_wave(:,:,:) = 0.0 ! diffusivity from wave scheme + wrk1(:,:,:) = 0.0 ! viscosity from wave scheme + + ! compute mask for regions that are too shallow for this scheme + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + tmask_deep(i,j) = 0.0 + if(kbot > 1) then + if(Thickness%depth_zwt(i,j,kbot) > shelf_depth_cutoff) tmask_deep(i,j) = 1.0 + endif + enddo + enddo + + ! compute the wave energy flux array (W/m2) and save for diagnostics + ! (Simmons etal equation (1)) + if(fixed_wave_dissipation) then + do j=jsd,jed + do i=isd,ied + energy_flux(i,j) = min(wave_energy_flux_max, wave_dissipation(i,j)*tmask_deep(i,j)) + enddo + enddo + else + do j=jsd,jed + do i=isd,ied + energy_flux(i,j) = min(wave_energy_flux_max, wave_term(i,j)*bvfreq_bottom(i,j)*tmask_deep(i,j)) + enddo + enddo + endif + + ! compute wave induced diffusivity + ! (Simmons etal equation (3)) + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + if(kbot > 1) then + + ! normalization of vertical structure function...ensure it + ! integrates to unity on the discrete grid. + factor = 0.0 + do k=1,kbot-1 + factor = factor + Thickness%dzt(i,j,k)*exp(decay_scale_inv*Thickness%depth_zwt(i,j,k)) + enddo + factor = 1.0/factor + + ! calculate diffusivity + do k=1,kbot-1 + deposition = factor*exp(decay_scale_inv*Thickness%depth_zwt(i,j,k)) + diff_wave(i,j,k) = Grd%tmask(i,j,k+1)*mix_efficiency(i,j,k)*tidal_diss_efficiency & + *energy_flux(i,j)*deposition/(epsln+rho_N2(i,j,k)) + diff_wave(i,j,k) = min(diff_wave(i,j,k),max_wave_diffusivity) + enddo + + endif + enddo + enddo + + ! ensure diffusivity monotonically decreases as move upward in column. + ! recall that diff_wave(i,j,k) is the diffusivity at the bottom of cell-k, + ! where diff_wave(i,j,kbot)=0.0 by definition. This prompts the kbot-2,1,-1 + ! loop limits. + if(wave_diffusivity_monotonic) then + do j=jsd,jed + do i=isd,ied + kbot=Grd%kmt(i,j) + if(kbot > 1) then + do k=kbot-2,1,-1 + diff_wave(i,j,k) = min(diff_wave(i,j,k),diff_wave(i,j,k+1)) + enddo + endif + enddo + enddo + endif + + ! add wave induced diffusivity and viscosity to diff_cbt and visc_cbu + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_cbt_wave(i,j,k) = diff_wave(i,j,k) + diff_cbt(i,j,k,1) = diff_cbt(i,j,k,1) + diff_wave(i,j,k) + diff_cbt(i,j,k,2) = diff_cbt(i,j,k,2) + diff_wave(i,j,k) + visc_cbt(i,j,k) = visc_cbt(i,j,k) + diff_wave(i,j,k) + wrk1(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_wave(i,j,k) +diff_wave(i+1,j,k) & + +diff_wave(i,j+1,k)+diff_wave(i+1,j+1,k)) + visc_cbu(i,j,k) = visc_cbu(i,j,k) + wrk1(i,j,k) + enddo + enddo + enddo + + if (id_energy_flux > 0) then + used = send_data (id_energy_flux, energy_flux(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_power_waves > 0) then + used = send_data (id_power_waves, Grd%dat(:,:)*energy_flux(:,:), & + Time%model_time, rmask=Grd%tmask(:,:,1), & + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif + if (id_diff_cbt_wave > 0) then + used = send_data (id_diff_cbt_wave, diff_wave(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbt_wave > 0) then + used = send_data (id_visc_cbt_wave, diff_wave(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbu_wave > 0) then + used = send_data (id_visc_cbu_wave, wrk1(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + + +end subroutine vert_mix_wave_legacy +!+! +! NAME="vert_mix_drag_legacy" + + +end module ocean_vert_tidal_test_mod diff --git a/src/mom5/ocean_param/vertical/ocean_vert_util.html b/src/mom5/ocean_param/vertical/ocean_vert_util.html deleted file mode 100644 index f5ca06838e..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_util.html +++ /dev/null @@ -1,218 +0,0 @@ - - - -+! +! Legacy routine maintained only to exactly reproduce older results. +! It is not recommended for new experiments, as it uses some obsolete +! methods. +! +! This subroutine computes dia-surface tracer diffusivity based on the +! methods of Lee etal., which consider the dissipation from barotropic tides +! rubbing against the ocean bottom. +! +! We assume a unit Prandtl number, so compute the viscosity as a four-point +! average of the diffusivity. +! +! We perform various averages here in order to smooth Richardson number. +! +! 1. compute Richardson number on U-cell by averaging bvfreq from T-cell +! 2. average U-cell Richardson number to then get T-cell diffusivity +! 3. average T-cell diffusivity to get U-cell viscosity. +! +! Note that if umask(i,j,k)==1.0, then so is tmask(i,j,k), tmask(i+1,j,k), +! tmask(i,j+1,k), and tmask(i+1,j+1,k). So there is no need to compute +! active_cells when averaging from T-cell to U-cell. +! +! +! + subroutine vert_mix_drag_legacy(Time, Thickness, diff_cbt, visc_cbu, visc_cbt, diff_cbt_drag) + + type(ocean_time_type), intent(in) :: Time + type(ocean_thickness_type), intent(in) :: Thickness + + real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbu + real, dimension(isd:,jsd:,:), intent(inout) :: visc_cbt + real, dimension(isd:,jsd:,:), intent(inout) :: diff_cbt_drag + + integer :: i, j, k, kbot, kp1 + real :: height, bottom, bvfreq_u, speedr, active_cells + + wrk1(:,:,:) =0.0 ! Richardson number on U-cell + wrk2(:,:,:) =0.0 ! Richardson number on T-cell + wrk3(:,:,:) =0.0 ! viscosity from drag scheme + diff_drag(:,:,:) =0.0 ! diffusivity from drag scheme + + ! Richardson number on U-cell. + ! perform a 4-point average of T-cell bvfreq + ! and then divide by the U-cell tidal speed term. + ! tide_speed_mask is useful to reduce overflows + ! in later calculation of the diffusivity. + do j=jsd,jed-1 + do i=isd,ied-1 + kbot=Grd%kmu(i,j) + if(kbot>1) then + bottom = Thickness%depth_zwu(i,j,kbot) + speedr = tide_speed_mask(i,j)/(epsln+rescaled_speed_u(i,j)) + do k=1,kbot-1 + kp1=k+1 + height = bottom-Thickness%depth_zwu(i,j,k) + bvfreq_u = onefourth*(bvfreq(i,j,k)+bvfreq(i+1,j,k)+bvfreq(i,j+1,k)+bvfreq(i+1,j+1,k)) + wrk1(i,j,k) = 2.0*Grd%umask(i,j,kp1)*(bvfreq_u*height*speedr)**2 + enddo + endif + enddo + enddo + + ! Richardson number on bottom of T-cells. + ! need active_cells for averaging operation. + do k=1,nk-1 + do j=jsc,jec + do i=isc,iec + active_cells = Grd%umask(i,j,k) + Grd%umask(i-1,j,k) & + + Grd%umask(i,j-1,k) + Grd%umask(i-1,j-1,k) + epsln + wrk2(i,j,k) = (wrk1(i,j,k) + wrk1(i-1,j,k) + wrk1(i,j-1,k) + wrk1(i-1,j-1,k))/active_cells + enddo + enddo + enddo + + ! compute drag induced diffusivity + ! (Lee etal equations (1), (2), and (3)) + ! Multiply by tide_speed_mask so to zero out + ! regions with tiny tide speeds, which are regions + ! where we do not wish to have any enhanced mixing + ! arising from the barotropic tide mixing parameterization + ! anyhow. + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_drag(i,j,k) = Grd%tmask(i,j,kp1)*tide_speed_mask(i,j)*max_drag_diffusivity & + *(1.0 + munk_anderson_sigma*wrk2(i,j,k))**(-munk_anderson_p) + enddo + enddo + enddo + call mpp_update_domains(diff_drag(:,:,:), Dom%domain2d) + + + ! add drag induced diffusivity and viscosity to diff_cbt and visc_cbu. + ! average t-cell diffusivities to get u-cell viscosity. + do k=1,nk-1 + kp1=k+1 + do j=jsc,jec + do i=isc,iec + diff_cbt_drag(i,j,k) = diff_drag(i,j,k) + diff_cbt(i,j,k,1) = diff_cbt(i,j,k,1) + diff_drag(i,j,k) + diff_cbt(i,j,k,2) = diff_cbt(i,j,k,2) + diff_drag(i,j,k) + visc_cbt(i,j,k) = visc_cbt(i,j,k) + diff_drag(i,j,k) + wrk3(i,j,k) = Grd%umask(i,j,kp1)*onefourth & + *(diff_drag(i,j,k) +diff_drag(i+1,j,k) & + +diff_drag(i,j+1,k)+diff_drag(i+1,j+1,k)) + visc_cbu(i,j,k) = visc_cbu(i,j,k) + wrk3(i,j,k) + enddo + enddo + enddo + + + if (id_rinumber_drag > 0) then + used = send_data (id_rinumber_drag, wrk2(:,:,:),& + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_diff_cbt_drag > 0) then + used = send_data (id_diff_cbt_drag, diff_drag(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbt_drag > 0) then + used = send_data (id_visc_cbt_drag, diff_drag(:,:,:), & + Time%model_time, rmask=Grd%tmask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + if (id_visc_cbu_drag > 0) then + used = send_data (id_visc_cbu_drag, wrk3(:,:,:), & + Time%model_time, rmask=Grd%umask(:,:,:), & + is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk) + endif + +end subroutine vert_mix_drag_legacy +!Module ocean_vert_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_vert_util_mod
- - - - - -
-OVERVIEW
- -- This module contains routines for use in vertical mixing. -
- - - -- Routines for vertical mixing schemes. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
ocean_density_mod
ocean_domains_mod
ocean_parameters_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_vert_util_init:
- -- -ri_for_bgrid:
- -- -ri_for_cgrid:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_vert_util_init
--
-- -DESCRIPTION -
-- - Initialize vertical mixing utilities. -
-
-
-- - -
-ri_for_bgrid
--
-- -DESCRIPTION -
-- - - Compute Richardson number assuming horizontal B-grid layout. - - Richardson number rit is centered at T-cell. - Richardson number riu is centered at U-cell. - - This calculation differs from that in ocean_vert_kpp_mom4p1 - since here we compute N^2 using locally referenced potential density, - as done for tide mixing scheme and as done in ri_for_cgrid. Other - features of the calculation, such as the horizontal averaging, - agree with ocean_vert_kpp_mom4p1. - -
-
-
-- - -
-ri_for_cgrid
--
-- -DESCRIPTION -
-- - - Compute Richardson number assuming horizontal C-grid layout. - - Richardson number rit is centered at T-cell. - Richardson number riu is set equal to rit, as there is no - separate "U-cell" when working with a Cgrid. - - This calculation differs from that in ocean_vert_kpp_mom4p1 - since here we compute N^2 using locally referenced potential density, - as done for tide mixing scheme and as done in ri_for_cgrid. - -
-
-
-
-NAMELIST
- --&ocean_tracer_util_nml --
-
----
-- -debug_this_module -
-- For debugging purposes. -
-
-[logical] -- -smooth_n2 -
-- For vertical smoothing the N2 calculation for Richardson number. - Default smooth_n2 = .true. -
-
-[logical] -- -num_n2_smooth -
-- For vertical smoothing N2 for Richardson number. - Default num_n2_smooth = 1. -
-
-[integer] -- -smooth_ri_number -
-- For vertical smoothing richardson number. - Default smooth_ri_number = .true. -
-
-[logical] -- -num_ri_smooth -
-- For vertical smoothing richardson number. - Default num_ri_smooth = 1. -
-
-[integer] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_param/vertical/ocean_vert_util.xml b/src/mom5/ocean_param/vertical/ocean_vert_util.xml deleted file mode 100644 index 3ea877b2ab..0000000000 --- a/src/mom5/ocean_param/vertical/ocean_vert_util.xml +++ /dev/null @@ -1,50 +0,0 @@ - - -diff --git a/src/mom5/ocean_tracers/ocean_age_tracer.F90 b/src/mom5/ocean_tracers/ocean_age_tracer.F90 index 7cbbe23724..4f11ad7559 100644 --- a/src/mom5/ocean_tracers/ocean_age_tracer.F90 +++ b/src/mom5/ocean_tracers/ocean_age_tracer.F90 @@ -32,7 +32,7 @@ module ocean_age_tracer_mod !{ ! ! ! -! $Id: ocean_age_tracer.F90,v 1.1.2.1 2012/05/15 16:48:03 smg Exp $ +! $Id: ocean_age_tracer.F90,v 20.0 2013/12/14 00:16:58 fms Exp $ ! ! diff --git a/src/mom5/ocean_tracers/ocean_age_tracer.html b/src/mom5/ocean_tracers/ocean_age_tracer.html deleted file mode 100644 index adb07ebd41..0000000000 --- a/src/mom5/ocean_tracers/ocean_age_tracer.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - S. M. Griffies - - This module contains routines for use in vertical mixing. - - Routines for vertical mixing schemes. - - For debugging purposes. - - For vertical smoothing the N2 calculation for Richardson number. - Default smooth_n2 = .true. - - For vertical smoothing N2 for Richardson number. - Default num_n2_smooth = 1. - - For vertical smoothing richardson number. - Default smooth_ri_number = .true. - - For vertical smoothing richardson number. - Default num_ri_smooth = 1. - - Initialize vertical mixing utilities. - - - Compute Richardson number assuming horizontal B-grid layout. - - Richardson number rit is centered at T-cell. - Richardson number riu is centered at U-cell. - - This calculation differs from that in ocean_vert_kpp_mom4p1 - since here we compute N^2 using locally referenced potential density, - as done for tide mixing scheme and as done in ri_for_cgrid. Other - features of the calculation, such as the horizontal averaging, - agree with ocean_vert_kpp_mom4p1. - - - - Compute Richardson number assuming horizontal C-grid layout. - - Richardson number rit is centered at T-cell. - Richardson number riu is set equal to rit, as there is no - separate "U-cell" when working with a Cgrid. - - This calculation differs from that in ocean_vert_kpp_mom4p1 - since here we compute N^2 using locally referenced potential density, - as done for tide mixing scheme and as done in ri_for_cgrid. - - Module ocean_age_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_age_tracer_mod
- - --Contact: Richard D. Slater - -- - -
-Reviewers: John P. Dunne -, - Stephen M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean age tracer module -
- - - -- This module will perform the necessary operations to handle - a series of ocean age tracers. The following types are allowed: - - normal: the age of the designated surface area is fixed at - 0, while all other grid points increase in age. - Therefore, the resultant age is the length of time - since that water has been in contact with the - designated area of surface. (This is the default type.) - - Note that the tracer "concentration" known as "age" is - in units of years, hence the multiplier "secs_in_year_r" - applied to t_prog(index)%source. This multiplier IS NOT - needed for any other terms, since they all have units with - meter/sec, and this is multiplied by dtime(secs) when - time stepping. - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
mpp_mod
time_manager_mod
ocean_tpm_util_mod
fm_util_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_age_tracer_end:
- -- -ocean_age_tracer_init:
- -- -ocean_age_tracer_source:
- -- -ocean_age_tracer_start:
- -- -ocean_age_tracer_tracer:
- -- -set_array:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_age_tracer_end
--
-- -DESCRIPTION -
-- - Finish up calculations for the tracer packages, - possibly writing out non-field restart information -
-
-
-- - -
-ocean_age_tracer_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
-
-
-- - -
-ocean_age_tracer_source
--
-- -DESCRIPTION -
-- - Calculate the source arrays for the tracer packages -
-
-
-- - -
-ocean_age_tracer_start
--
-- -DESCRIPTION -
-- - Start the ocean age tracer package - - Age tracer surface area specification - - wlon : western longitude of surface age - region - elon : eastern longitude of surface age - region - slat : southern latitude of surface age - region - nlat : northern latitude of surface age - region - coastal_only : if true, then only apply the changes in - coastal boxes - t_mask : logical array controlling whether to apply - the following inhibitions and depletions to - each month (true means set the masks, - false means use the defaults everywhere) - - - To set the surface areas, a number of namelists are read, - each containing the above values. You may specify up to - num_region rectangles bounded by (wlon,elon,nlat,slat). - Any grid box whose center is in one of these rectangles will - be considered to be part of the surface area where the - age is reset to zero every time-step. - - These masks may be time-dependent by specifying t_mask. - For any month that t_mask is true (1=Jan), the rectangular - regions will be set, otherwise they will be skipped. - - nlat may not equal slat, and wlon may not equal elon - - If slat > nlat, then nothing will be done for that rectangle - - The initial surface area is empty, with the default rectangle - setting the surface area to be empty - - More than num_regions rectangles may be used to specify - the area by using more than one namelist -
-
-
-- - -
-ocean_age_tracer_tracer
--
-- -DESCRIPTION -
-- - Subroutine to do calculations needed every time-step after - the continuity equation has been integrated -
-
-
-- - -
-set_array
--
-- -DESCRIPTION -
-- - Set up an array covering the model domain with a user-specified - value, in user-specified regions. There are a given number of - 2-d regions specified by the values slat, nlat, wlon and elon. - The longitudes are for a cyclic domain, and if wlon and elon - are on opposite sides of the cut, the correct thing will - be done. Elon is considered to be east of wlon, so if elon is - less than wlon, then the region east of elon to the cut will be - filled, and the region from the cut to wlon will be filled. - - After setting up the array in this routine, it may prove useful - to allow fine-tuning the settings via an array in a namelist. - - Arguments: - Input: - num_regions number of user-specified regions which will be filled - wlon 1-d array of western (starting) longitudes for the - rectangular regions - elon 1-d array of eastern (ending) longitudes for the - rectangular regions - slat 1-d array of southern (starting) latitudes for the - rectangular regions - nlat 1-d array of northern (ending) latitudes for the - rectangular regions - Note: if slat >= nlat, then nothing is done - for that region - set_value the value to assign to array in the user-specified - regions - unset_value the value to assign to array outside of the - user-specified regions - name character variable used in informative messages - coastal_only true to limit changes only to coastal points (i.e., - at least one bordering point is land) - - Output: - array 2-d array which will contain the set- and unset- - values. The array is assumed to have a border - one unit wide on all edges, ala MOM. A cyclic - boundary condition will be set if requested. -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_frazil.F90 b/src/mom5/ocean_tracers/ocean_frazil.F90 index b4b4ad7967..915d47bdc5 100644 --- a/src/mom5/ocean_tracers/ocean_frazil.F90 +++ b/src/mom5/ocean_tracers/ocean_frazil.F90 @@ -137,7 +137,7 @@ module ocean_frazil_mod logical :: module_initialized = .false. character(len=256) :: version='CVS $$' -character(len=256) :: tagname='Tag $Name: mom5_siena_08jun2012_smg $' +character(len=256) :: tagname='Tag $Name: tikal $' type(ocean_grid_type), pointer :: Grd =>NULL() type(ocean_domain_type), pointer :: Dom =>NULL() @@ -168,29 +168,29 @@ module ocean_frazil_mod real :: c1, c2 ! for TEOS10 freezing temperature -real,parameter :: v0 = 0.017947064327968736 -real,parameter :: v1 = -6.076099099929818 -real,parameter :: v2 = 4.883198653547851 -real,parameter :: v3 = -11.88081601230542 -real,parameter :: v4 = 13.34658511480257 -real,parameter :: v5 = -8.722761043208607 -real,parameter :: v6 = 2.082038908808201 -real,parameter :: v7 = -7.389420998107497 -real,parameter :: v8 = -2.110913185058476 -real,parameter :: v9 = 0.2295491578006229 -real,parameter :: v10 = -0.9891538123307282 -real,parameter :: v11 = -0.08987150128406496 -real,parameter :: v12 = 0.3831132432071728 -real,parameter :: v13 = 1.054318231187074 -real,parameter :: v14 = 1.065556599652796 -real,parameter :: v15 = -0.7997496801694032 -real,parameter :: v16 = 0.3850133554097069 -real,parameter :: v17 = -2.078616693017569 -real,parameter :: v18 = 0.8756340772729538 -real,parameter :: v19 = -2.079022768390933 -real,parameter :: v20 = 1.596435439942262 -real,parameter :: v21 = 0.1338002171109174 -real,parameter :: v22 = 1.242891021876471 +real,parameter :: v0 = 0.017947064327968736d0 +real,parameter :: v1 = -6.076099099929818d0 +real,parameter :: v2 = 4.883198653547851d0 +real,parameter :: v3 = -11.88081601230542d0 +real,parameter :: v4 = 13.34658511480257d0 +real,parameter :: v5 = -8.722761043208607d0 +real,parameter :: v6 = 2.082038908808201d0 +real,parameter :: v7 = -7.389420998107497d0 +real,parameter :: v8 = -2.110913185058476d0 +real,parameter :: v9 = 0.2295491578006229d0 +real,parameter :: v10 = -0.9891538123307282d0 +real,parameter :: v11 = -0.08987150128406496d0 +real,parameter :: v12 = 0.3831132432071728d0 +real,parameter :: v13 = 1.054318231187074d0 +real,parameter :: v14 = 1.065556599652796d0 +real,parameter :: v15 = -0.7997496801694032d0 +real,parameter :: v16 = 0.3850133554097069d0 +real,parameter :: v17 = -2.078616693017569d0 +real,parameter :: v18 = 0.8756340772729538d0 +real,parameter :: v19 = -2.079022768390933d0 +real,parameter :: v20 = 1.596435439942262d0 +real,parameter :: v21 = 0.1338002171109174d0 +real,parameter :: v22 = 1.242891021876471d0 public compute_frazil_heating @@ -394,8 +394,8 @@ subroutine ocean_frazil_init (Domain, Grid, Time, Time_steps, Ocean_options, & c2 = 1.428571428571429e-05 tfreeze_check = -2.076426227617581 elseif(freezing_temp_teos10) then - c1 = 0.014289763856964 - c2 = 0.05700064989972 + c1 = 0.014289763856964d0 + c2 = 0.05700064989972d0 tfreeze_check = -2.062635500704721 endif else @@ -430,7 +430,7 @@ subroutine ocean_frazil_init (Domain, Grid, Time, Time_steps, Ocean_options, & + press*(v7 + press*(v8 + v9*press)) & + s*press*(v10 + press*(v12 + press*(v15 + v21*s)) + s*(v13 + v17*press+ v19*s) & + sqrts*(v11 + press*(v14 + v18*press) + s*(v16 + v20*press+ v22*s))) & - - saturation_fraction*(1e-3)*(2.4 - c1*s)*(1 + c2*(1. - s/35.16504)) + - saturation_fraction*(1e-3)*(2.4 - c1*s)*(1 + c2*(1d0 - s/35.16504d0)) write(stdoutunit,'(a,e24.16)')'Check value for freezing temperature(C) at (35psu,200dbar) = ',tfreeze write(stdoutunit,'(a,e24.16)')'This value differs from published check value by ', tfreeze-tfreeze_check endif @@ -562,11 +562,11 @@ subroutine compute_frazil_heating (Time, Thickness, Dens, T_prog, T_diag) do i=isc,iec T_diag(index_frazil)%field(i,j,k) = 0.0 if(Grd%tmask(i,j,k) > 0.0) then - s = 1.e-2*Dens%rho_salinity(i,j,k,taup1) + s = 1.d-2*Dens%rho_salinity(i,j,k,taup1) sqrts = sqrt(s) tfreeze = v0 & + s*(v1 + sqrts*(v2 + sqrts*(v3 + sqrts*(v4 + sqrts*(v5 + v6*sqrts))))) & - - saturation_fraction*(1e-3)*(2.4 - c1*s)*(1 + c2*(1. - s/35.16504)) + - saturation_fraction*(1e-3)*(2.4 - c1*s)*(1 + c2*(1.d0 - s/35.16504d0)) if(T_prog(index_temp)%field(i,j,k,taup1) < tfreeze) then T_diag(index_frazil)%field(i,j,k) = & (tfreeze-T_prog(index_temp)%field(i,j,k,taup1)) & @@ -584,7 +584,7 @@ subroutine compute_frazil_heating (Time, Thickness, Dens, T_prog, T_diag) do i=isc,iec T_diag(index_frazil)%field(i,j,k) = 0.0 if(Grd%tmask(i,j,k) > 0.0) then - s = 1.e-2*Dens%rho_salinity(i,j,k,taup1) + s = 1.d-2*Dens%rho_salinity(i,j,k,taup1) sqrts = sqrt(s) press = Dens%pressure_at_depth(i,j,k) tfreeze = v0 & @@ -592,7 +592,7 @@ subroutine compute_frazil_heating (Time, Thickness, Dens, T_prog, T_diag) + press*(v7 + press*(v8 + v9*press)) & + s*press*(v10 + press*(v12 + press*(v15 + v21*s)) + s*(v13 + v17*press+ v19*s) & + sqrts*(v11 + press*(v14 + v18*press) + s*(v16 + v20*press+ v22*s))) & - - saturation_fraction*(1e-3)*(2.4 - c1*s)*(1 + c2*(1. - s/35.16504)) + - saturation_fraction*(1e-3)*(2.4 - c1*s)*(1 + c2*(1d0 - s/35.16504d0)) if(T_prog(index_temp)%field(i,j,k,taup1) < tfreeze) then T_diag(index_frazil)%field(i,j,k) = & (tfreeze-T_prog(index_temp)%field(i,j,k,taup1)) & diff --git a/src/mom5/ocean_tracers/ocean_frazil.html b/src/mom5/ocean_tracers/ocean_frazil.html deleted file mode 100644 index 55ecae93aa..0000000000 --- a/src/mom5/ocean_tracers/ocean_frazil.html +++ /dev/null @@ -1,271 +0,0 @@ - - - -Module ocean_frazil_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_frazil_mod
- - --Contact: Stephen Griffies -, - R.A.S. Fiedler -, - David Jackett - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module computes the heating of seawater due to - frazil ice formation. -
- - - -- Frazil can generally form at any vertical level, although - it is common for climate models to assume it is formed - only at k=1. In this case, pressure is assumed to be - atmospheric for purposes of computing the freezing - temperature of seawater. - - The freezing temperature of seawater is computed one of two - possible ways: - - (1) simple way uses a linear function of salinity - and assumes zero (i.e. atmospheric) pressure, - - tfreeze(deg C) = a1*salinity(psu) - with a1 = -0.054 - - (2) accurate way uses a nonlinear function of - salinity(psu) and gauge pressure(dbar), where - gauge pressure=absolute pressure - 10.1325 dbar. - - tfreeze (deg C) = tf_num/tf_den - tf_num = a0 + s*(a1 + sqrt(s)*(a2 + sqrt(s)*a3)) + p*(a4 + p*(a5 + s*a6)) - tf_dem = b0 + p*(b1 + p*b2) + s*s*sqrt(s)*b3 - - check value : fp_theta(35,200,'air-sat') = -2.076426227617581 deg C - fp_theta(35,200,'air-free') = -2.074408175943127 deg C - - This method results in a more accurate freezing - temperature than the simpler approach. It is also - important for ice-shelf modelling to include a - pressure dependence when the shelf penetrates - into the water column. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
mpp_domains_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tpm_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_frazil_init:
- -- -compute_frazil_heating:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_frazil_init
--
-- -DESCRIPTION -
-- - Initialization code for the frazil diagnostic tracer. -
-
-
-- - -
-compute_frazil_heating
--
-- -DESCRIPTION -
-- - Compute ocean heating due to formation of frazil-ice (Joules/m^2) - - Note that "frazil_factor" accounts for possibly different time - stepping used in ocean model and the sea ice model. With MOM - using a leap-frog, and the GFDL ocean model SIS using forward, - then frazil_factor=0.5. If use recommended tendency=twolevel - in MOM, then frazil_factor=1.0 - -
-
-
-
-NAMELIST
- --&ocean_frazil_nml --
-
----
-- -use_this_module -
-- If true, then compute frazil heating. -
-
-[logical] -- -debug_this_module -
-- For debugging this module -
-
-[logical] -- -frazil_factor -
-- This factor accounts for possibly different time stepping used - in the sea ice model relative to the ocean model. If sea-ice - and ocean use same time stepping schemes, then frazil_factor=1.0. - If sea-ice uses a twolevel scheme and ocean a threelevel leap-frog, - then frazil_factor=0.5. Default is 1.0 since the GFDL sea ice model - SIS uses a two-level time stepping scheme and MOM defaults to - a staggered two-level scheme. -
-
-[real, units: dimensionless] -- -freezing_temp_simple -
-- To use the simplified freezing point temperature of seawater, - as used in MOM4.0. -
-
-[logical] -- -freezing_temp_accurate_preteos10 -
-- To use the accurate freezing point temperature of seawater, - which is a nonlinear function of salinity and pressure. -
-
-[logical] -- -freezing_temp_accurate_teos10 -
-- To use the accurate freezing point temperature of seawater - according to TEOS-10, which is a nonlinear function of - salinity and pressure. - This equation is recommended for use with ice-shelf modelling. -
-
-[logical] -- -frazil_only_in_surface -
-- For typical case where compute frazil heating only in - the surface grid cell. Will assume the gauge - pressure is zero in this case when computing freezing - temperature. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of - seawater - 2010: Calculation and use of thermodynamic properties. - Intergovernmental Oceanographic Commission, Manuals and Guides No. 56, - UNESCO (English), 196 pp. Available from http://www.TEOS-10.org. - See sections 3.33 and 3.34 of this TEOS-10 Manual. -
-- - "Updated algorithms for density, potential temperature, - conservative temperature and freezing temperature of - seawater", Jackett, McDougall, Feistel, Wright, and Griffies - Journal of Atmospheric and Oceanic Technology, in press 2005. -
-
- -
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_passive.F90 b/src/mom5/ocean_tracers/ocean_passive.F90 index 837668f1c5..6ca1f46e3a 100644 --- a/src/mom5/ocean_tracers/ocean_passive.F90 +++ b/src/mom5/ocean_tracers/ocean_passive.F90 @@ -183,9 +183,9 @@ module ocean_passive_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=128) :: version=& - '$Id: ocean_passive.F90,v 1.1.2.3 2012/05/22 13:28:07 smg Exp $' + '$Id: ocean_passive.F90,v 20.0 2013/12/14 00:17:02 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' public ocean_passive_init public passive_tracer_init diff --git a/src/mom5/ocean_tracers/ocean_passive.html b/src/mom5/ocean_tracers/ocean_passive.html deleted file mode 100644 index c2b51ae53e..0000000000 --- a/src/mom5/ocean_tracers/ocean_passive.html +++ /dev/null @@ -1,536 +0,0 @@ - - - -Module ocean_passive_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_passive_mod
- - --Contact: Stephen M. Griffies -, - Alistair Adcroft - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Set up for idealized passive tracers. -
- - - -- This module setups various passive tracer configurations. - Some idealized initial conditions are provided. - - These tracers are used for various idealized purposes, - such as tracing water mass transports, testing - advection schemes, etc. - - These passive tracers are always initialized within - this module with an idealized profile. - No preprocessing step is required. To define a common initial condition - for all passive tracers use the namelist "ocean_passive_nml" - - This setting can be overwritten for each tracer by the namelist feature of the tracer field_table. - For example - - "namelists","ocean_mod","ocean_passive/patch" - restore = f - init_condition = temp_sq_init - - init_condition is one of :: 'level', 'wall','patch', 'patch_'klevel, with "klevel" an integer - for the k-level that will place the patch. - 'exponential', 'shelfbowl', 'rho_surface', 'temp_sq_init', 'salt_sq_init' - Default is 'patch' - - With rho_surface' a density surface can be selected, the density value - is defined in the field table namelist, for example - - init_surface = 1025 - - However, if an initial file exists for a passive tracer, - then ocean_tracer_mod will overwrite the passive tracer - with the tracer concentration in the initial file. In this - way, we can, for example, initialize a passive tracer with - some profile that is not readily determined via a simple - algorithmic procedure. - - If restoring of a passive tracer to its initial value is enabled by - setting in the field table - - restore = t - - the initial field is used only to find the grid cells where to restore the - passive tracer to the initial tracer field. Restoring is done where the tracer - concentration exceeds 0.00001. The inital value of passive tracers with restoring - is always set to '1'. With the field_table namelist - - init_value = some_real - - this can be changed to another but also constant value. - - All passive tracers in this module are dimensionless and are - treated the same internally to this module. However, they can - generally have different initial conditions and can use - different advection schemes. Indeed, one motivation for - developing this module is to test advection schemes, with - the same initial condition used for each of the tracers, - but different advection schemes. In this way we can readily - determine the difference between advection schemes on various - profiles within MOM. - - Sample passive tracers are setup here. The user can modify - code in a straightforward manner to change the number of - passive tracers and/or the initial profiles. - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
field_manager_mod
fm_util_mod
fms_mod
mpp_mod
ocean_domains_mod
ocean_tpm_util_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_passive_init:
- -- -passive_tracer_init:
- -- -ocean_passive_tracer_init:
- -- -surface_init:
- -- -layer_init:
- -- -wall_init:
- -- -patch_init:
- -- -patch_init_klevel:
- -- -exponential_init:
- -- -shelfbowl_init:
- -- -update_tracer_passive:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_passive_init
--
-- -DESCRIPTION -
-- - Initialize the indices for passive tracer fields. - This routine is called by ocean_model.F90. -
-
-
-- - -
-passive_tracer_init
--
-- -DESCRIPTION -
-- - Initialize profiles for the passive tracers. - This routine is called by ocean_tracer.F90. -
-
-
-- - -
-ocean_passive_tracer_init
--
-- -DESCRIPTION -
-- - Initialize restoring to initial values for the passive tracers. - - or - Initialize profiles for the passive tracers which are tagged with - specific values of the temperature field or potential density field. - - or - Initialize profiles for the passive tracers which are defined - as the temperature or salinity squared. These tracers are used - for diagnosing the level of spurious mixing associated with - PSOM advection. -
-
-
-- - -
-surface_init
--
-- -DESCRIPTION -
-- - Initialize passive tracer according to a particular iso-surface. -
-
-
-- - -
-layer_init
--
-- -DESCRIPTION -
-- - - Initialize tracer inside a depth layer to have a value, and - zero outside the layer. - -
-
-
-- - -
-wall_init
--
-- -DESCRIPTION -
-- - - Initialize tracer inside an (i,k) wall to have a value, and - zero outside the wall. - -
-
-
-- - -
-patch_init
--
-- -DESCRIPTION -
-- - - Initialize tracer with simple shapes based on vertical layer: - Level k=1, square pill box - Level k=2, circular pill box (cylinder) - Level k=3, circular cone - Level k=4, cosine bell - Level k=5, Gaussian bell - Levels k>5, square patch based on i,j coordinates (original "patch"). - -
-
-
-- - -
-patch_init_klevel
--
-- -DESCRIPTION -
-- - Initialize tracer with gaussian patch or constant on a level, - both on a single k-level -
-
-
-- - -
-exponential_init
--
-- -DESCRIPTION -
-- - - Initialize tracer with a vertical exponential profile. - -
-
-
-- - -
-shelfbowl_init
--
-- -DESCRIPTION -
-- - - Initialize tracer as in the shelfbowl topography of use for studying - idealized overflow problems, as in Winton etal (1998). - -
-
-
-- - -
-update_tracer_passive
--
-- -DESCRIPTION -
-- - Update the squared tracer. - Restore passive tracers. -
-
-
-
-NAMELIST
- --&ocean_passive_nml --
-
----
-- -debug_this_module -
-- For debugging the module. -
-
-[logical] -- -common_init_condition -
-- Default for the tracer initial conditions. - - Options are the following: - common_init_condition='level' - common_init_condition='wall' - common_init_condition='patch' - common_init_condition='patch_'klevel, with "klevel" an integer - for the k-level that will place the patch. - common_init_condition='exponential' - common_init_condition='shelfbowl' - common_init_condition='rho_surface' - common_init_condition='temp_sq_init' - common_init_condition='salt_sq_init' - Default=common_init_condition='patch' -
-
-[character] -- -layer_value -
-- Value of tracer concentration within the layer. - Default=1.0. -
-
-[real] -- -layer_ztop -
-- Depth at the top of the tracer layer. -
-
-[real] -- -layer_zbot -
-- Depth at the bottom of the tracer layer. -
-
-[real] -- -patch_init_klevel_gaussian -
-- To initialize on the klevel with a gaussian region. - Default=patch_init_klevel_gaussian=.false. -
-
-[logical] -- -wall_value -
-- Value of tracer concentration within the wall. - Default=1.0. -
-
-[real] -- -wall_ratio_south -
-- Ratio of the full j-range, northward of which - we place the wall. -
-
-[real] -- -wall_ratio_north -
-- Ratio of the full j-range, southward of which - we place the wall. -
-
-[real] -- -patch_value -
-- Value of the tracer concentration within a patch. - Default=1.0. -
-
-[real] -- -patch_ztop -
-- Depth at the top of the tracer patch. -
-
-[real] -- -patch_zbot -
-- Depth at the bottom of the tracer patch. -
-
-[real] -- -patch_ratio1 -
-- For setting position of tracer patch. -
-
-[real] -- -patch_ratio2 -
-- For setting position of tracer patch. -
-
-[real] -- -efold_depth -
-- The efolding depth used for exponential tracer profile. - Default=1000.0. -
-
-[real, units: metre] -- -exponential_value -
-- The tracer value at zero depth when choosing the exponential profile. - Default=1.0. -
-
-[real, units: dimensionless] -
- - - - -
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_residency.F90 b/src/mom5/ocean_tracers/ocean_residency.F90 index 896e4370e5..d67d37a463 100644 --- a/src/mom5/ocean_tracers/ocean_residency.F90 +++ b/src/mom5/ocean_tracers/ocean_residency.F90 @@ -260,7 +260,7 @@ module ocean_residency_mod !{ ! ! ! -! $Id: ocean_residency.F90,v 1.1.2.1 2012/05/15 16:48:03 smg Exp $ +! $Id: ocean_residency.F90,v 20.0 2013/12/14 00:17:04 fms Exp $ ! ! diff --git a/src/mom5/ocean_tracers/ocean_residency.html b/src/mom5/ocean_tracers/ocean_residency.html deleted file mode 100644 index 158e8add26..0000000000 --- a/src/mom5/ocean_tracers/ocean_residency.html +++ /dev/null @@ -1,431 +0,0 @@ - - - -Module ocean_residency_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_residency_mod
- - --Contact: Richard D. Slater - -- - -
-Reviewers: Stephen M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean residency module -
- - - -- - This module is a superset of the ocean age tracer module. It may - be used to reproduce the age tracer, but it can also do much - more. Unlike the ocean age tracer module, here you may specify - a 3-d field by specifying a series of "rectangular prisms". - The grid cells which occupy this field may vary with time due - to the variations in the thickness of the surface layer. - - You may also specify a 3-d field by choosing one of three mixed-layers - (KPP, density-derived or buoyancy-derived). You may also specify a - region based on a a range of a prognostic or diagnostic ocean - tracer (such as all points with a temperature of 10-20 degrees). - - You may specify either the mixed-layer method or the tracer range along - with the geographic specification. If multiple methods are used, then - the resultant field is the intersection of the two methods. In fact, the - geographic method is always in use, and defaults to the whole ocean. - - There is an option of using the inverse of any method. This is sometimes - easier to use than explicitly specifying the inverse. For instance, - to get the temperatures outside of the range 10-20 degrees, one could - specify the 10-20 degree range and set <swap> to true, or, specify two - different regions, one less than 10 degrees and one greater than 20 degrees. - - By default, the values inside the specified region are set to a - specified value each time-step (default is 0), and outside of this region - the field is integrated over time in units of years (integrand is - 1/(365.25*86400) by default, but this value can be changed. The inner region - can be forced to be 0 (or the user-specified inner value) at each time-step - (the default), or it can be restored to this value at a user-specified - rate (given in days), or, it can be left alone (not integrated or set to - any value). - - Finally, since we are just integrating a specified field by a constant value - (by default), it is simple to make that field a simple function of another - tracer. This is the final option. You may specify a prognostic or diagnostic - variable to be the integrand, and have it scaled by a constant. One case - which has been done is to integrate irradiance in the mixed-layer. - - This module is split into several different modules. This particular module - is the only one called from outside, and it makes appropriate calls to - the other modules to implement its features. This was done so that it would - be easier to expand the features of the ocean residency, without cluttering - the code too much. Ideally, this could all be done with classes, but there - is currently no support for classes in Fortran (pre-F2003). The current - modules are: - - ocean_residency.F90 This module, the control center, and also does the - integrations and resetting in the inner regions. - ocean_residency_meta.F90 Has specifications of the ocean_residency type - and other utility routines. This is separate - to stop circular references - ocean_residency_ml.F90 Handles setting mixed-layer masks - ocean_residency_range.F90 Handles setting the masks for the tracer ranges - ocean_residency_integrand.F90 Handles setting the integrand to a non-constant - value - - field_table namelist inputs: - - The following 6 arrays specify the bounds of boxes, the intersection of which - will define the region where the integrand is set to restore_region_value. ALl arrays - must have the same number of elements. If none are specified, then no region will - be used, unless swap is true, which is a quick way of selecting the entire ocean. - This may be useful when one really wants to use one of the other methods of selecting, - such as mixed layer depth, or tracer range. - - Longitudes will be shifted to lie in the range 0-360 degrees. If the eastern side is - greater than the western, then the selected region will consist of those grid cells from - the eastern value to 360, and 0 to the western value. If the northern value is less than - the southern value, or if the top depth is greater than the bottom depth, then - an error occurs, and the model stops. - - Three special cases exist for the depth (which currently must be in meters). - If the bottom value is less than or equal to zero, then the top box is selected. - If the top value is greater than the maximum depth, then the bottom box is selected. - If the top value is negative, then grid cells within "the absolute value of the top value" - from the bottom are selected. - - Note that the geographic specification is used for all residency tracers, so either - values for these 6 arrays must be given so as to select a region, or else swap must - be set to true and no arrays given. - - east_bnd: array of boundary points of the eastern side of the box, - in degrees longitude (default: NULL) - north_bnd: array of boundary points of the northern side of the box, - in degrees latitude (default: NULL) - south_bnd: array of boundary points of the southern side of the box, - in degrees latitude (default: NULL) - west_bnd: array of boundary points of the western side of the box, - in degrees longitude (default: NULL) - top_bnd: array of boundary points of the top side of the box, - in meters (default: NULL) - bottom_bnd: array of boundary points of the bottom side of the box, - in meters (default: NULL) - - swap: if true, then select the inverse of the specified geographic region, - otherwise, just use the specified region (default: false) - restore: restoring value for values in the defined regions - negative => do nothing, 0 => force to integrate_region_value, - positive => time scale in days to force to integrate_region_value - (default: 0.0) - restore_region_value: value to set the mask to for grid cells within - the specified region (default: 0.0) - integrate_region_value: value to set the mask to for grid cells outside - the specified region (default: secs_in_year_r) - swap_module: if true, then select the inverse of the region from the specified module, - otherwise, just use the specified region (default: false) - module_name: if set, then it will be used to select the alternate - method of selecting the region (default: ' ' -- only geographic - selection is used) - - For the following arrays, see the different extra modules for required and - possible values for the module selected. - - params: an array of real parameters which may be used for the method - being used for selection (default: NULL) - flags: an array of real parameters which may be used for the method - being used for selection (default: NULL) - strings: an array of real parameters which may be used for the method - being used for selection (default: NULL) - - For the following arrays, see the different extra modules for required and - possible values for the module selected to specify the integrand. - int_module_name: if set, then the name of the module used to set - the integrand (default: ' ' -- integrate time, in years) - int_params: an array of real parameters which may be used for the integrand - (default: NULL) - int_flags: an array of real parameters which may be used for the integrand - (default: NULL) - int_strings: an array of real parameters which may be used for the integrand - (default: NULL) - ----------------------------------------------------------------------------------------- - - Sample field table entries: - --------------------------- - - "tracer_packages","ocean_mod","ocean_residency" - names = age_surface, age_bottom_inv, kppbl_nil, kppbl_14d, kppbl_frc, kppbl_irr_14d, temp_15_20 - horizontal-advection-scheme = mdppm - vertical-advection-scheme = mdppm - units = yr - min_tracer_limit=0.0 - / - - This is the same as the old age tracer with all surface - values forced to zero - - "namelists","ocean_mod","ocean_residency/age_surface" - south_bnd = -90.0 - north_bnd = 90.0 - west_bnd = 0.0 - east_bnd = 360.0 - top_bnd = 0.0 - bottom_bnd = 0.0 - / - - This integrates the age in the bottom box and forces to - zero everywhere else (note that swap is true) - - "namelists","ocean_mod","ocean_residency/age_bottom_inv" - south_bnd = -90.0 - north_bnd = 90.0 - west_bnd = 0.0 - east_bnd = 360.0 - top_bnd = 10000.0 - bottom_bnd = 10000.0 - swap = t - / - - This integrates the age of the water in the KPP - boundary layer, but lets the age outside of this region - keep its value until it again mixes with the boundary layer. - The module_name is set, and strings is set to pick the - type of mixed layer desired - (note that the global geographic area is explicitly specified, - and that the restoring time scale is negative) - - "namelists","ocean_mod","ocean_residency/kppbl_nil" - south_bnd = -90.0 - north_bnd = 90.0 - west_bnd = 0.0 - east_bnd = 360.0 - top_bnd = 0.0 - bottom_bnd = 10000.0 - restore = -1.0 - module_name = ocean_residency_ml - strings = kpp_bl - swap_module = t - / - - This is the same as above, but forces the age outside - the boundary layer to 0 with a 14 day time scale - (note that the global geographic region is specified by - setting swap to true, also note the value of restore) - - "namelists","ocean_mod","ocean_residency/kppbl_14d" - swap = t - restore = 14.0 - module_name = ocean_residency_ml - strings = kpp_bl - swap_module = t - / - - This is the same as above, but forces age to zero outside - the boundary layer (note that restore did not need to - be explicitly specified, as the default is zero) - - "namelists","ocean_mod","ocean_residency/kppbl_frc" - swap = t - restore = 0.0 - module_name = ocean_residency_ml - strings = kpp_bl - swap_module = t - / - - The following integrates irradiance in the boundary - layer (note that the units needed to be changed for - netCDF output purposes) - - "prog_tracers","ocean_mod","residency_kppbl_irr_14d" - units = W-yr/m^2 - / - - "namelists","ocean_mod","ocean_residency/kppbl_irr_14d" - swap = t - restore = 14.0 - module_name = ocean_residency_ml - strings = kpp_bl - swap_module = t - int_module_name = ocean_residency_integrand - int_strings = irr - / - - This specifies the region as the area with - a temperature range of between 15 and 20 degrees - (note that the params holds the variable - range) - - "namelists","ocean_mod","ocean_residency/temp_15_20" - swap = t - module_name = ocean_residency_range - strings = tracer_range, temp - params = 15.0, 20.0 - / - --
- - -
-OTHER MODULES USED
- --- - - -time_manager_mod-
field_manager_mod
mpp_mod
diag_manager_mod
ocean_tpm_util_mod
fm_util_mod
ocean_types_mod
ocean_residency_meta_mod
ocean_residency_ml_mod
ocean_residency_range_mod
ocean_residency_integrand_mod
-PUBLIC INTERFACE
----
-- -ocean_residency_init:
- -- -ocean_residency_source:
- -- -ocean_residency_start:
- -- -ocean_residency_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_residency_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages -
-
-
-- - -
-ocean_residency_source
--
-- -DESCRIPTION -
-- - Calculate the source arrays for the tracer packages -
-
-
-- - -
-ocean_residency_start
--
-- -DESCRIPTION -
-- - Start the ocean residency package - - Residency surface area specification - - west_bnd : western longitude of residency region - east_bnd : eastern longitude of residency region - south_bnd : southern latitude of residency region - north_bnd : northern latitude of residency region - top_bnd : top depth of residency region - bottom_bnd : bottom depth of residency region - - To set the volumes, a number of namelists are read, - each containing the above values. You may specify up to - num_geog_region rectangular cubes bounded by - (west_bnd, east_bnd, north_bnd, south_bnd, top_bnd, bottom_bnd). - Any grid box whose center is in one of these volumes will - be considered to be part of the volume where the - residency is reset to zero every time-step. - - north_bnd may not equal south_bnd, and west_bnd may not equal east_bnd - - top_depth may equal bottom_depth. In that case, then whatever vertical - box contains that depth will define the vertical range for the box - - If south_bnd > north_bnd, then nothing will be done for that rectangle - - The initial surface area is empty, with the default rectangle - setting the surface area to be empty - - More than num_geog_regions rectanglar volumes may be used to specify - the volume by using more than one namelist -
-
-
-- - -
-ocean_residency_tracer
--
-- -DESCRIPTION -
-- - Subroutine to do calculations needed every time-step after - the continuity equation has been integrated -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_residency_integrand.F90 b/src/mom5/ocean_tracers/ocean_residency_integrand.F90 index a5197264a0..054c899806 100644 --- a/src/mom5/ocean_tracers/ocean_residency_integrand.F90 +++ b/src/mom5/ocean_tracers/ocean_residency_integrand.F90 @@ -31,7 +31,7 @@ module ocean_residency_integrand_mod !{ ! ! ! -! $Id: ocean_residency_integrand.F90,v 1.1.2.1 2012/05/15 16:48:03 smg Exp $ +! $Id: ocean_residency_integrand.F90,v 20.0 2013/12/14 00:17:06 fms Exp $ ! ! diff --git a/src/mom5/ocean_tracers/ocean_residency_integrand.html b/src/mom5/ocean_tracers/ocean_residency_integrand.html deleted file mode 100644 index e8503f956b..0000000000 --- a/src/mom5/ocean_tracers/ocean_residency_integrand.html +++ /dev/null @@ -1,145 +0,0 @@ - - - -Module ocean_residency_integrand_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_residency_integrand_mod
- - --Contact: Richard D. Slater - -- - -
-Reviewers: Stephen M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean age tracer module -
- - - -- This module contains the subroutines to set up fields other - than reciprocal time over which to integrate. - - To use this module, in the field table namelist, you must do the following: - - 1) set "module_name_int" to "ocean_residency_integrand" - 2) "int_strings" should have one or two values, the first is - the name of a prognostic or diagnostic variable to use as the integrand, - and if the second value is given and is "average", then the array is assumed - to be defined at the top of the grid cells, and the average of the top - and bottom will be used for each grid cell (top of bottommost grid cell), - otherwise the value at each level will be used - 3) "int_params" may be set to a single value to scale the integrand, - at most one value may be set - 4) no "int_flags" should be set - - For an overview of the ocean residency modules, see ocean_residency.F90. - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
mpp_mod
fms_mod
ocean_residency_meta_mod
ocean_types_mod
-PUBLIC INTERFACE
-- --
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_residency_integrand_source
--
-- -DESCRIPTION -
-- - Set the selected integrand field to be used in the "integrate_region" - as defined in ocean_residency.F90. The selected prognostic - or diagnostic variable will be multiplied by the residency mask - (which is usually either 1 or 0, but is not so required) and a - user-selected scale factor (default of 1). The variable may be either - the average of the surrounding points ( C(k) = (C(k) + C(k+1))/2 ) - or just the same indexical value. -
-
-
-- - -
-ocean_residency_integrand_start
--
-- -DESCRIPTION -
-- - Start the ocean residency integrand package - -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_residency_meta.F90 b/src/mom5/ocean_tracers/ocean_residency_meta.F90 index 40a4126dbe..a952b34cde 100644 --- a/src/mom5/ocean_tracers/ocean_residency_meta.F90 +++ b/src/mom5/ocean_tracers/ocean_residency_meta.F90 @@ -20,7 +20,7 @@ module ocean_residency_meta_mod !{ ! ! ! -! $Id: ocean_residency_meta.F90,v 1.1.2.1 2012/05/15 16:48:03 smg Exp $ +! $Id: ocean_residency_meta.F90,v 20.0 2013/12/14 00:17:08 fms Exp $ ! ! diff --git a/src/mom5/ocean_tracers/ocean_residency_meta.html b/src/mom5/ocean_tracers/ocean_residency_meta.html deleted file mode 100644 index 40905bb372..0000000000 --- a/src/mom5/ocean_tracers/ocean_residency_meta.html +++ /dev/null @@ -1,290 +0,0 @@ - - - -Module ocean_residency_meta_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_residency_meta_mod
- - --Contact: Richard D. Slater - -- - -
-Reviewers: Stephen M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean residency module -
- - - -- This module contains the meta definitions, subroutines and functions - to use in the ocean residency package. These routines are used by all - of the ocean residency modules and need to be defined in a separate - module so that there are no circular references between the modules. - - For an overview of the ocean residency modules, see ocean_residency.F90. - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
fm_util_mod
mpp_mod
-PUBLIC INTERFACE
-- --
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_residency_get_instances
--
-- -DESCRIPTION -
-- - Return an array of instances which have the given module_name - This is used by modules, such as the mixed layer module, to obtain - a list of instances which use that module. Then, the module - needs only to loop over those instance to perform its required tasks. -
-
-
-- - -
-ocean_residency_set_region_2d
--
-- -DESCRIPTION -
-- - Given a 2-d field of depths, determine the grid cells which fall inside (above) and - outside of that range, then set the mask appropriately, as to whether - we are interested in those points inside (swap=false) or outside (swap=true) of the region. - - Note: if the output array is not initialized, then it is assumed that it is already - filled with a region, and the resulting region will be the intersection of the - existing region and the newly specified region. - - Arguments: - - Input: - - isd: low dimension of first index - ied: high dimension of first index - jsd: low dimension of second index - jed: high dimension of second index - nk: dimension of third index - control: array of depths that specifies the region - depth_zwt: depth of bottom of grid cell - restore_region_value: if supplied, the value to assign to array in the user-specified - regions (default: 0.0) - integrate_region_value: if supplied, the value to assign to array outside of the - user-specified regions (default: secs_in_year_r) - swap: if supplied and true then change the invert the defined region (default: true) - initialize: if supplied and true, then initialize the region to the integrate_region_value (default: false) - caller: if supplied, use for traceback of error messages (default: fm_default_caller) - - Input/Output: - array: 3-d array which will contain the restore_region- and integrate_region- - values. - -
-
-
-- - -
-ocean_residency_set_region_geog
--
-- -DESCRIPTION -
-- - Set up an array covering the model domain with a user-specified - value, in user-specified regions. There are a given number of - 3-d regions specified by the values south_bnd, north_bnd, west_bnd, - east_bnd, top_bnd and bottom_bnd. - The longitudes are for a cyclic domain, and if west_bnd and east_bnd - are on opposite sides of the cut, the correct thing will - be done. east_bnd is considered to be east of west_bnd, so if east_bnd is - less than west_bnd, then the region east of east_bnd to the cut will be - filled, and the region from the cut to west_bnd will be filled. - - If the bottom bound is less than or equal to zero, then the top model box - will be chosen. If the top bound is greater than or equal to the maximum - model depth, then the bottom box will be chosed. Otherwise, if the grid - cell center depth falls between top bound and bottom bound, then those cells - shall be chosen. - - For longitude and latitude, if the grid cell center lies within the - rectabgle defined by (west_bnd,south_bnd) and (east_bnd,north_bnd), then - the whole grid cell is inside the region. - - Arrays of coordinates may be specified for irregular regions. - The final region is the union of the multiple sets - of coordinates. If swap is true, then the inverse of the defined - region will be set. - - Note: if the output array is not initialized, then it is assumed that it is already - filled with a region, and the resulting region will be the intersection of the - existing region and the newly specified region. - - Arguments: - - Input: - - isd: low dimension of first index - ied: high dimension of first index - jsd: low dimension of second index - jed: high dimension of second index - nk: dimension of third index - grid_xt: array of coordinates in the x-direction (typically longitude) - grid_yt: array of coordinates in the y-direction (typically latitude) - max_depth: maximum depth of the model - depth_zt: depth of center of grid cell - depth_zwt: depth of bottom of grid cell - num_geog_regions: number of user-specified regions which will be filled - west_bnd_in: 1-d array of western (starting) longitudes for the regions - east_bnd_in: 1-d array of eastern (ending) longitudes for the regions - south_bnd: 1-d array of southern (starting) latitudes for the regions - north_bnd: 1-d array of northern (ending) latitudes for the regions - top_bnd: 1-d array of southern (starting) depths for the regions - bottom_bnd: 1-d array of northern (ending) depths for the regions - Note: if south_bnd >= north_bnd, then nothing is done - for that region - kmt: array of indices for bottom grid cells - name: character variable used in informative messages - restore_region_value: if supplied, the value to assign to array in the user-specified - regions (default: 0.0) - integrate_region_value: if supplied, the value to assign to array outside of the - user-specified regions (default: secs_in_year_r) - swap: if supplied and true then change the invert the defined region (default: true) - - Input/Output: - array: 3-d array which will contain the restore_region- and integrate_region- - values. -
-
-
-- - -
-ocean_residency_set_region_3d
--
-- -DESCRIPTION -
-- - Set up an array where the a grid box is in the region if the value - of the specified property (temperature, say) is within the given bounds. - Multiple values for the range may be given, and the resulting mask - will be the union of the multiple regions. If swap is true, then the - inverse of the selected region will be set. - - Note: if the output array is not initialized, then it is assumed that it is already - filled with a region, and the resulting region will be the intersection of the - existing region and the newly specified region. - - Arguments: - - Input: - - isd: low dimension of first index - ied: high dimension of first index - jsd: low dimension of second index - jed: high dimension of second index - nk: dimension of third index - num_geog_regions: number of user-specified regions which will be filled - bounds: 1-d array of pairs of bounding values. The first value in - the pair must be less than the second value - kmt: array of indices for bottom grid cells - name: character variable used in informative messages - restore_region_value: if supplied, the value to assign to array in the user-specified - regions (default: 0.0) - integrate_region_value: if supplied, the value to assign to array outside of the - user-specified regions (default: secs_in_year_r) - swap: if supplied and true then change the invert the defined region (default: true) - initialize: if supplied and true, then initialize the region to the integrate_region_value (default: false) - caller: if supplied, use for traceback of error messages (default: fm_default_caller) - - Input/Output: - array: 3-d array which will contain the restore_region- and integrate_region- - values. -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_residency_ml.F90 b/src/mom5/ocean_tracers/ocean_residency_ml.F90 index 8c7cdf3ae4..e0ce491e4a 100644 --- a/src/mom5/ocean_tracers/ocean_residency_ml.F90 +++ b/src/mom5/ocean_tracers/ocean_residency_ml.F90 @@ -37,7 +37,7 @@ module ocean_residency_ml_mod !{ ! ! ! -! $Id: ocean_residency_ml.F90,v 1.1.2.1 2012/05/15 16:48:03 smg Exp $ +! $Id: ocean_residency_ml.F90,v 20.0 2013/12/14 00:17:10 fms Exp $ ! ! diff --git a/src/mom5/ocean_tracers/ocean_residency_ml.html b/src/mom5/ocean_tracers/ocean_residency_ml.html deleted file mode 100644 index 61222ad7cd..0000000000 --- a/src/mom5/ocean_tracers/ocean_residency_ml.html +++ /dev/null @@ -1,162 +0,0 @@ - - - -Module ocean_residency_ml_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_residency_ml_mod
- - --Contact: Richard D. Slater - -- - -
-Reviewers: Stephen M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean age tracer module -
- - - -- This module handles the case where the specified region is determined - by a 2-d array of depths, typically mixed layer depths. - - To use this module, in the field table namelist, you must do the following: - - 1) set "module_name" to "ocean_residency_ml" - 2) "strings" should have one value: one of "kpp_bl", "mld_buoyancy", or - "mld_potrho" - 3) no "params" should be set - 4) no "flags" should be set - - Currently, the following mixed layers are supported: - - kpp_bl: KPP mixed layer - mld_buoyancy: mixed layer defined by a change in buoyancy - (mld in diagnostic output) - mld_potrho: mixed layer defined by a change in potential density - (depth_of_potrho in diagnostic output) - - There should be no "params" or "flags" set, and only one element of - "strings". - - For an overview of the ocean residency modules, see ocean_residency.F90. - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
mpp_mod
ocean_residency_meta_mod
ocean_types_mod
ocean_tracer_diag_mod
-PUBLIC INTERFACE
----
-- -ocean_residency_ml_source:
- -- -ocean_residency_ml_start:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_residency_ml_source
--
-- -DESCRIPTION -
-- - Calculate the mask for the mixed layer. - - Arguments: - - Input: - - isd: low dimension of first index - ied: high dimension of first index - jsd: low dimension of second index - jed: high dimension of second index - nk: dimension of third index - T_prog: array of ocean prognostic types - T_diag: array of ocean diagnostic types - Time: ocean time type - Thickness: ocean thickness type - Dens: ocean density type - depth_zwt: depth of bottom of grid cell - hblt_depth: array of depths of KPP boundary layer -
-
-
-- - -
-ocean_residency_ml_start
--
-- -DESCRIPTION -
-- - Start the ocean residency mixed layer package - -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_residency_range.F90 b/src/mom5/ocean_tracers/ocean_residency_range.F90 index 847bd65053..91e18b1a16 100644 --- a/src/mom5/ocean_tracers/ocean_residency_range.F90 +++ b/src/mom5/ocean_tracers/ocean_residency_range.F90 @@ -40,7 +40,7 @@ module ocean_residency_range_mod !{ ! ! ! -! $Id: ocean_residency_range.F90,v 1.1.2.1 2012/05/15 16:48:03 smg Exp $ +! $Id: ocean_residency_range.F90,v 20.0 2013/12/14 00:17:12 fms Exp $ ! ! diff --git a/src/mom5/ocean_tracers/ocean_residency_range.html b/src/mom5/ocean_tracers/ocean_residency_range.html deleted file mode 100644 index 6bd8975ca5..0000000000 --- a/src/mom5/ocean_tracers/ocean_residency_range.html +++ /dev/null @@ -1,160 +0,0 @@ - - - -Module ocean_residency_range_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_residency_range_mod
- - --Contact: Richard D. Slater - -- - -
-Reviewers: Stephen M. Griffies - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Ocean age tracer module -
- - - -- This module handles the case where the specified region is determined - from a range of another tracer. Any tracer, either prognostic or - diagnostic, may be used. The tracer field, mutiplied by an optional - scaling factor, will be multiplied by the current value in residency - mask array. - - To use this module, in the field table namelist, you must do the following: - - 1) set "module_name" to "ocean_residency_range" - 2) "strings" should have two values, the first is "tracer_range", and the - second to the name of a prognostic or diagnostic variable - 3) set "params" to pairs of points defining the range of the variable - to select. For each pair of values, the first value must be less than - the second value. The grid cells will satisfy the union of all of the - grid cells which satisfy - "low value" < "cell value" <= "high value" - for at least one pair of points - 4) no "flags" should be set - - Any prognostic or diagnostic variable may be used. If you wish to allow - another variable to be used, you can just create a diagnostic variable - for it. - - For an overview of the ocean residency modules, see ocean_residency.F90. - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
mpp_mod
ocean_residency_meta_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -ocean_residency_range_source:
- -- -ocean_residency_range_start:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-ocean_residency_range_source
--
-- -DESCRIPTION -
-- - Calculate the mask for the tracer range(s) - - Arguments: - - Input: - - isd: low dimension of first index - ied: high dimension of first index - jsd: low dimension of second index - jed: high dimension of second index - nk: dimension of third index - taum1: tau-1 time level index - T_prog: array of ocean prognostic types - T_diag: array of ocean diagnostic types - grid_kmt: indices of the bottom grid cell -
-
-
-- - -
-ocean_residency_range_start
--
-- -DESCRIPTION -
-- - Start the ocean residency tracer range package - -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_tempsalt.F90 b/src/mom5/ocean_tracers/ocean_tempsalt.F90 index 25131b3103..6ed05208ca 100644 --- a/src/mom5/ocean_tracers/ocean_tempsalt.F90 +++ b/src/mom5/ocean_tracers/ocean_tempsalt.F90 @@ -159,9 +159,9 @@ module ocean_tempsalt_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=128) :: version=& - '$Id: ocean_tempsalt.F90,v 1.1.2.2 2012/05/17 13:41:54 smg Exp $' + '$Id: ocean_tempsalt.F90,v 20.0 2013/12/14 00:17:14 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' private dentropy_dtheta interface dentropy_dtheta @@ -468,44 +468,44 @@ subroutine ocean_tempsalt_init(Domain, Grid, Ocean_options, itemp, isalt, debug) if (teos10) then - sfac = 9.95306702338459e-01 + sfac = 9.95306702338459d-01 else sfac = 1.0 endif ! TEOS10 coefficients for CT from PT and salinity - v0 = 2.50509288068125e-04 ! v0=1/cp_ocean - v1 = 61.01362420681071 - v2 = 168776.46138048015 - v3 = -2735.2785605119625 - v4 = 2574.2164453821433 - v5 = -1536.6644434977543 - v6 = 545.7340497931629 - v7 = -50.91091728474331 - v8 = -18.30489878927802 - - v9 = 268.5520265845071 - v10 = -12019.028203559312 - v11 = 3734.858026725145 - v12 = -2046.7671145057618 - v13 = 465.28655623826234 - v14 = -0.6370820302376359 - v15 = -10.650848542359153 - v16 = 937.2099110620707 - v17 = 588.1802812170108 - v18 = 248.39476522971285 - v19 = -3.871557904936333 - v20 = -2.6268019854268356 - v21 = -1687.914374187449 - v22 = 246.9598888781377 - v23 = 123.59576582457964 - v24 = -48.5891069025409 - v25 = 936.3206544460336 - v26 = -942.7827304544439 - v27 = 369.4389437509002 - v28 = -33.83664947895248 - v29 = -9.987880382780322 + v0 = 2.50509288068125d-04 ! v0=1/cp_ocean + v1 = 61.01362420681071d0 + v2 = 168776.46138048015d0 + v3 = -2735.2785605119625d0 + v4 = 2574.2164453821433d0 + v5 = -1536.6644434977543d0 + v6 = 545.7340497931629d0 + v7 = -50.91091728474331d0 + v8 = -18.30489878927802d0 + + v9 = 268.5520265845071d0 + v10 = -12019.028203559312d0 + v11 = 3734.858026725145d0 + v12 = -2046.7671145057618d0 + v13 = 465.28655623826234d0 + v14 = -0.6370820302376359d0 + v15 = -10.650848542359153d0 + v16 = 937.2099110620707d0 + v17 = 588.1802812170108d0 + v18 = 248.39476522971285d0 + v19 = -3.871557904936333d0 + v20 = -2.6268019854268356d0 + v21 = -1687.914374187449d0 + v22 = 246.9598888781377d0 + v23 = 123.59576582457964d0 + v24 = -48.5891069025409d0 + v25 = 936.3206544460336d0 + v26 = -942.7827304544439d0 + v27 = 369.4389437509002d0 + v28 = -33.83664947895248d0 + v29 = -9.987880382780322d0 ! preTEOS10 coefficients for CT from PT and salinity c0 = 2.50494524832013e-4 ! c0=1/cp_ocean diff --git a/src/mom5/ocean_tracers/ocean_tempsalt.html b/src/mom5/ocean_tracers/ocean_tempsalt.html deleted file mode 100644 index 3d8e2ed6ed..0000000000 --- a/src/mom5/ocean_tracers/ocean_tempsalt.html +++ /dev/null @@ -1,591 +0,0 @@ - - - -Module ocean_tempsalt_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_tempsalt_mod
- - --Contact: R.A.S. Fiedler -, - David Jackett -, - Stephen M. Griffies - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Setup the temperature and salinity tracer fields. - Convert between potential temperature and conservative temperature. -
- - - -- - This routine sets up the temperature and salinity tracer fields. - It also performs a converstion between potential temperature and - conservative temperature, with the conversion valid over most - large-scale oceanographically relevant ranges. - - 0psu <= salinity <= 40 psu - - -3C <= theta <= 40C (theta=conservative temperature or potential temperature) - - 0dbar <= pressure <= 8000dbar - - Input variables are the following: - - salinity - - potential temperature (theta) in deg C - OR - conservative temperature (theta) in deg C - --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
fms_mod
mpp_mod
ocean_domains_mod
ocean_parameters_mod
ocean_tpm_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_tempsalt_init:
- -- -ocean_tempsalt_ideal_reinit:
- -- -contemp_from_pottemp_field:
- -- -contemp_from_pottemp_level:
- -- -contemp_from_pottemp_point:
- -- -pottemp_from_contemp_field:
- -- -pottemp_from_contemp_level:
- -- -pottemp_from_contemp_point:
- -- -dentropy_dtheta_field:
- -- -dentropy_dtheta_level:
- -- -dentropy_dtheta_point:
- -- -tempsalt_check_range:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_tempsalt_init
--
-- -DESCRIPTION -
-- - Initialize the temperature/salinity module. -
-
-
-- - -
-ocean_tempsalt_ideal_reinit
--
-- -DESCRIPTION -
-- - Reinitialize the temperature/salinity fields with internally generated - idealized profile. - - This routine can be called at any time within a model integration. - The main application is to allow for there to be a nontrivial - Thickness established, and then to reinitialize the temperature - and salinity to be functions of the depth_st array. When - s=zstar, this approach will produce a flat initialization in - zstar space, but nontrivial initialization in depth space. - - User can customize a profile. - - One example given here assumes profile is a function of depth_st, - with the assumption that s=geopotential OR s=zstar. - To use this approach with pressure coordinate, need to alter the - reinit_ts_with_ideal_efold value, since depth_st is in MKS, not dbar. - -
-
-
-- - -
-contemp_from_pottemp_field
--
-- -DESCRIPTION -
-- - - Compute conservative temperature for all grid points. - Input is potential temperature (C) and salinity(psu or g/kg). - - contemp = potential_enthalpy(s,theta)/cp_ocean - -
-
-
-- - -
-contemp_from_pottemp_level
--
-- -DESCRIPTION -
-- - - Compute conservative temperature for one k-level. - Input is potential temperature (C) and salinity(psu or g/kg). - - contemp = potential_enthalpy(s,theta)/cp_ocean - -
-
-
-- - -
-contemp_from_pottemp_point
--
-- -DESCRIPTION -
-- - - Compute conservative temperature for one grid point. - Input is potential temperature (C) and salinity(psu or g/kg). - - contemp = potential_enthalpy(s,theta)/cp_ocean - -
-
-
-- - -
-pottemp_from_contemp_field
--
-- -DESCRIPTION -
-- - - Compute potential temperature from conservative temperature - for all grid points. Perform one extra iteration to get - precision to near computer precision. - - Input is salinity (psu) and conservative temperature (C). - - Use wrk1, wrk2, and wrk3 so to not take 3-d arrays from stack. - -
-
-
-- - -
-pottemp_from_contemp_level
--
-- -DESCRIPTION -
-- - - Compute potential temperature from conservative temperature - over a k-level. Perform one extra iteration to get - precision to near computer precision. - - Input is salinity (psu) and conservative temperature (C). - -
-
-
-- - -
-pottemp_from_contemp_point
--
-- -DESCRIPTION -
-- - - Compute potential temperature from conservative temperature at a point. - Perform one extra iteration to get precision to near computer precision. - - Input is salinity (psu) and conservative temperature (C). - -
-
-
-- - -
-dentropy_dtheta_field
--
-- -DESCRIPTION -
-- - - d(entropy)/d(pottemp) at each grid point from twice differentiating - the Gibbs potential in Feistel (2003), Prog. Ocean. 58, 43-114. - (pressure=0 since use potential temperature) - - salinity : salinity (psu) - theta : potential temperature (deg C, ITS-90) - dentropy_dtheta : d(entropy)/d(pottemp) J/(kg degC^2) - - check value: dentropy_dtheta(35,20) = 13.63256369213874 - -
-
-
-- - -
-dentropy_dtheta_level
--
-- -DESCRIPTION -
-- - - d(entropy)/d(pottemp) at k-level from twice differentiating - the Gibbs potential in Feistel (2003), Prog. Ocean. 58, 43-114. - (pressure=0 since use potential temperature) - - salinity : salinity (psu) - theta : potential temperature (deg C, ITS-90) - dentropy_dtheta : d(entropy)/d(pottemp) J/(kg degC^2) - - check value: dentropy_dtheta(35,20) = 13.63256369213874 - -
-
-
-- - -
-dentropy_dtheta_point
--
-- -DESCRIPTION -
-- - - d(entropy)/d(pottemp) at an (i,j,k) point from twice differentiating - the Gibbs potential in Feistel (2003), Prog. Ocean. 58, 43-114. - (pressure=0 since use potential temperature) - - salinity : salinity (psu) - theta : potential temperature (deg C, ITS-90) - dentropy_dtheta : d(entropy)/d(pottemp) J/(kg degC^2) - - check value: dentropy_dtheta(35,20) = 13.63256369213874 - -
-
-
-- - -
-tempsalt_check_range
--
-- -DESCRIPTION -
-- - - Check to see that temperature and salinity are within preset - range. If outside of the range, then bring the model down. - - This check is particularly useful to ensure that the equation - of state is evaluated with physically sensible values of temp - and salinity. - -
-
-
-
-NAMELIST
- --&ocean_tempsalt_nml --
-
----
-- -teos10 -
-- For choosing whether to use the TEOS-10 equation of state. - This usage requires conservative temperature as the temperature variable, - and two salinity variables: Preformed Salinity and Absolute Salinity - anomaly. Default teos10=.false. -
-
-[logical] -- -temperature_variable -
-- For choosing the temperature variable used in the model. - Choices are 'conservative_temp' and 'potential_temp'. - Since conservative temperature is more accurate, it is the default. -
-
-[character] -- -pottemp_equal_contemp -
-- For certain idealized cases where the difference between potential - temperature and conservative temperature is irrelevant. Default=.false. -
-
-[logical] -- -pottemp_2nd_iteration -
-- For taking extra iteration in computation of potential temperature - from conservative temperature and salinity. Default is true. -
-
-[logical] -- -reinit_ts_with_ideal -
-- For setting up an ideal temperature and salinity profile - that is generated in the model. This profile can be - generated after the model has already been running, hence - the name "reinit" for "reinitialize." -
-
-[logical] -- -reinit_ts_with_ideal_efold -
-- For setting efolding of reinitialized temp and salinity profile. - Default reinit_ts_with_ideal_efold=1000. -
-
-[real, units: metre] -- -reinit_ts_with_ideal_tvalue -
-- For setting the reinitialized temperature value using the - ideal profile. Default reinit_ts_with_ideal_tvalue = 10.0 -
-
-[real, units: C] -- -reinit_ts_with_ideal_svalue -
-- For setting the reinitialized temperature value using the - ideal profile. Default reinit_ts_with_ideal_svalue = 30.0 -
-
-[real, units: psu] -- -t_min -
-- Minimum potential/conservative temperature below which we gracefully bring down the model. -
-
-[real, units: deg C] -- -t_max -
-- Maximum potential/conservative temperature above which we gracefully bring down the model. -
-
-[real, units: deg C] -- -s_min -
-- Minimum salinity below which we gracefully bring down the model. -
-
-[real, units: ppt] -- -s_max -
-- Maximum salinity below which we gracefully bring down the model. -
-
-[real, units: ppt] -- -t_min_limit -
-- Minimum potential/conservative temperature below which will employ upwind advection - instead of quicker, and horizontal diffusion instead of neutral physics. -
-
-[real, units: deg C] -- -t_max_limit -
-- Maximum potential/conservative temperature above which will employ upwind advection - instead of quicker, and horizontal diffusion instead of neutral physics. -
-
-[real, units: deg C] -- -s_min_limit -
-- Minimum salinity below which will employ upwind advection instead - of quicker, and horizontal diffusion instead of neutral physics. -
-
-[real, units: psu] -- -s_max_limit -
-- Maximum salinity below which will employ upwind advection instead - of quicker, and horizontal diffusion instead of neutral physics. -
-
-[real, units: psu] -- -debug_this_module -
-- For debugging the module. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - Feistel (2003) - A new extended Gibbs thermodynamic potential of seawater - Progress in Oceanography. vol 58, pages 43-114. -
-- - Jackett, McDougall, Feistel, Wright, and Griffies (2005) - Algorithms for density, potential temperature, - conservative temperature, and freezing temperature of - seawater. Journal of Atmospheric and Oceanic - Technology, 2005 submitted. -
-
- -
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_tpm.F90 b/src/mom5/ocean_tracers/ocean_tpm.F90 index 67ba8fdbc5..26b9026850 100644 --- a/src/mom5/ocean_tracers/ocean_tpm.F90 +++ b/src/mom5/ocean_tracers/ocean_tpm.F90 @@ -284,8 +284,8 @@ module ocean_tpm_mod !{ ! Private variables ! -character(len=128) :: version = '$Id: ocean_tpm.F90,v 1.1.2.1 2012/05/15 16:48:04 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocean_tpm.F90,v 20.0 2013/12/14 00:17:16 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' integer :: imonth integer :: iyear diff --git a/src/mom5/ocean_tracers/ocean_tpm.html b/src/mom5/ocean_tracers/ocean_tpm.html deleted file mode 100644 index 5fb339ed98..0000000000 --- a/src/mom5/ocean_tracers/ocean_tpm.html +++ /dev/null @@ -1,419 +0,0 @@ - - - -Module ocean_tpm_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_tpm_mod
- - - - - -
-OVERVIEW
- -- Ocean tracer package module -
- - - -- Currently this module only works for the ocean model, - but it could be extended (or generalized) to work with other - models. - - This module consists of eight subroutines, three are called as - the model is intialized, four are called every time-step, and - one is called at model ending. The subroutines are called in - the following order. - - These routines are called once at model startup in the - ocean_tracer_init routine: - - ocean_tpm_init: This routine saves pointers to "global" model - structures, such as Grid and Domain. Also this - routine will call specified routines to set default - values for each tracer for such things as advection - scheme, tracer name, etc. - - ocean_tpm_flux_init: this routine initalizes field elements - relating to the ocean-atmosphere gas fluxes - - ocean_tpm_start: This routine calls specified routines to - allocate appropriate storage for the tracer packages, - perform pre-processing and initialization (possibly - from extra restart information) and set parameters, - either via namelist or via the field manager. - - These routines are called each time-step from - update_ocean_tracer (one before integration and one after): - - ocean_tpm_sbc: Calls specified routines to handle surface - coundary condition calculations. Some or all of - this functionality may be moved into a new, generalized - boundary condition manager. - - ocean_tpm_bbc: Calls specified routines to handle bottom - coundary condition calculations. - - ocean_tpm_source: Calls specified routines to calculate the - source array for each tracer in the tracer packages. - - ocean_tpm_tracer: For those packages which need to do - post-processing after the continuity equation has - been integrated, calls may be placed here. This - could be for global, annual means, for instance. - - This routine is called once at the end of the run from - ocean_tracer_end: - - ocean_tpm_end: Call routines to finish up any loose ends, such - as saving extra restart fields. - - The following routines are called in relation to tying in to - the FMS coupler to calculate fluxes for the additional - tracers: - - ocean_tpm_init_sfc: Allocate arrays for the accumulation of - data to be used by the coupler - - ocean_tpm_sum_sfc: Accumulate data for the coupler - - ocean_tpm_avg_sfc: Take the time-mean of the fields for the coupler - - ocean_tpm_zero_sfc: Zero out the fields for the coupler to allow - for accumulation for the next time period - - ocean_tpm_sfc_end: Save out fields for the restart. - --
- - -
-OTHER MODULES USED
- --- - - -mpp_mod-
mpp_domains_mod
ocean_types_mod
ocean_age_tracer_mod
ocean_residency_mod
ocean_pert_co2_mod
ocmip2_abiotic_mod
ocmip2_cfc_mod
ocmip2_biotic_mod
ocean_bgc_restore_mod
ocmip2_he_mod
ocean_po4_pre_mod
ocean_ibgc_mod
ocean_generic_mod
ocean_frazil_mod
ocean_tempsalt_mod
ocean_passive_mod
transport_matrix_mod
time_manager_mod
coupler_types_mod
-PUBLIC INTERFACE
----
-- -do_time_calc:
- -- -ocean_tpm_bbc:
- -- -ocean_tpm_restart:
- -- -ocean_tpm_end:
- -- -ocean_tpm_init_sfc:
- -- -ocean_tpm_sum_sfc:
- -- -ocean_tpm_avg_sfc:
- -- -ocean_tpm_zero_sfc:
- -- -ocean_tpm_sfc_end:
- -- -ocean_tpm_sbc:
- -- -ocean_tpm_init:
- -- -ocean_tpm_flux_init:
- -- -ocean_tpm_source:
- -- -ocean_tpm_start:
- -- -ocean_tpm_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-do_time_calc
--
-- -DESCRIPTION -
-- - call subroutines to perform time calculations -
-
-
-- - -
-ocean_tpm_bbc
--
-- -DESCRIPTION -
-- - call subroutines to perform bottom boundary condition - calculations -
-
-
-- - -
-ocean_tpm_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_tpm_end
--
-- -DESCRIPTION -
-- - Finish up calculations for the tracer packages, - possibly writing out non-field restart information -
-
-
-- - -
-ocean_tpm_init_sfc
--
-- -DESCRIPTION -
-- - call subroutines to perform surface coupler initializations - - Note: this subroutine should be merged into ocean_tpm_start -
-
-
-- - -
-ocean_tpm_sum_sfc
--
-- -DESCRIPTION -
-- - call subroutines to perform surface coupler initializations -
-
-
-- - -
-ocean_tpm_avg_sfc
--
-- -DESCRIPTION -
-- - call subroutines to perform surface coupler initializations -
-
-
-- - -
-ocean_tpm_zero_sfc
--
-- -DESCRIPTION -
-- - call subroutines to perform surface coupler initializations -
-
-
-- - -
-ocean_tpm_sfc_end
--
-- -DESCRIPTION -
-- - call subroutines to perform surface coupler initializations -
-
-
-- - -
-ocean_tpm_sbc
--
-- -DESCRIPTION -
-- - call subroutines to perform surface boundary condition - calculations -
-
-
-- - -
-ocean_tpm_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Ocean, Grid and Domains. -
-
-
-- - -
-ocean_tpm_flux_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
-
-
-- - -
-ocean_tpm_source
--
-- -DESCRIPTION -
-- - Calculate the source arrays for the tracer packages -
-
-
-- - -
-ocean_tpm_start
--
-- -DESCRIPTION -
-- - Start the tracer packages. - This could include reading in extra restart information, - processing namelists or doing initial calculations -
-
-
-- - -
-ocean_tpm_tracer
--
-- -DESCRIPTION -
-- - Subroutine to do calculations needed every time-step after - the continuity equation has been integrated -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_tpm_util.F90 b/src/mom5/ocean_tracers/ocean_tpm_util.F90 index 781c3795fe..2c14435e75 100644 --- a/src/mom5/ocean_tracers/ocean_tpm_util.F90 +++ b/src/mom5/ocean_tracers/ocean_tpm_util.F90 @@ -92,8 +92,8 @@ module ocean_tpm_util_mod !{ ! Private variables ! -character(len=128) :: version = '$Id: ocean_tpm_util.F90,v 1.1.2.1 2012/05/15 16:48:04 smg Exp $' -character(len=128) :: tagname = '$Name: mom5_siena_08jun2012_smg $' +character(len=128) :: version = '$Id: ocean_tpm_util.F90,v 20.0 2013/12/14 00:17:18 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' ! ! Interface definitions for overloaded routines diff --git a/src/mom5/ocean_tracers/ocean_tpm_util.html b/src/mom5/ocean_tracers/ocean_tpm_util.html deleted file mode 100644 index 3d11e5b6b4..0000000000 --- a/src/mom5/ocean_tracers/ocean_tpm_util.html +++ /dev/null @@ -1,224 +0,0 @@ - - - -Module ocean_tpm_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module ocean_tpm_util_mod
- - - - - -
-OVERVIEW
- -- Ocean tracer package module pointers module -
- - - -- This module allocates a suite of variables used in ocean_tpm --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
fms_mod
mpp_mod
fm_util_mod
-PUBLIC INTERFACE
----
-- -check_ocean_mod:
- -- -otpm_set_tracer_package:
- -- -set_prog_value_integer:
- -- -set_prog_value_logical:
- -- -set_prog_value_real:
- -- -set_prog_value_string:
- -- -otpm_set_prog_tracer:
- -- -otpm_set_diag_tracer:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-check_ocean_mod
--
-- -DESCRIPTION -
-- - Be sure that the /ocean_mod hierarchy has been initialized. -
-
-
-- - -
-otpm_set_tracer_package
--
-- -DESCRIPTION -
-- - Set the values for a tracer package and return its index (0 on error) - -
-
-
-- - -
-set_prog_value_integer
--
-- -DESCRIPTION -
-- - Set an integer value for a prognostic tracer element in the Field Manager tree. -
-
-
-- - -
-set_prog_value_logical
--
-- -DESCRIPTION -
-- - Set a logical value for a prognostic tracer element in the Field Manager tree. -
-
-
-- - -
-set_prog_value_real
--
-- -DESCRIPTION -
-- - Set a real value for a prognostic tracer element in the Field Manager tree. -
-
-
-- - -
-set_prog_value_string
--
-- -DESCRIPTION -
-- - Set a string value for a prognostic tracer element in the Field Manager tree. -
-
-
-- - -
-otpm_set_prog_tracer
--
-- -DESCRIPTION -
-- - Set the values for a prog tracer and return its index (0 on error) -
-
-
-- - -
-otpm_set_diag_tracer
--
-- -DESCRIPTION -
-- - Set the values for a diag tracer and return its index (0 on error) -
-
-
-
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_tracer.F90 b/src/mom5/ocean_tracers/ocean_tracer.F90 index 50906f30e5..689107083c 100644 --- a/src/mom5/ocean_tracers/ocean_tracer.F90 +++ b/src/mom5/ocean_tracers/ocean_tracer.F90 @@ -184,6 +184,7 @@ module ocean_tracer_mod #ifdef USE_OCEAN_BGC use ocean_generic_mod, only: ocean_generic_get_field, ocean_generic_get_field_pointer +use ocean_generic_mod, only: ocean_generic_set_pointer #endif use ocean_lap_tracer_mod, only: lap_tracer @@ -226,8 +227,8 @@ module ocean_tracer_mod logical :: prog_module_initialized = .false. logical :: diag_module_initialized = .false. -character(len=256) :: version='CVS $Id: ocean_tracer.F90,v 1.1.2.7 2012/06/04 00:20:31 smg Exp $' -character(len=256) :: tagname='Tag $Name: mom5_siena_08jun2012_smg $' +character(len=256) :: version='CVS $Id: ocean_tracer.F90,v 20.0 2013/12/14 00:17:20 fms Exp $' +character(len=256) :: tagname='Tag $Name: tikal $' character(len=48), parameter :: mod_name = 'ocean_tracer_mod' integer :: num_tracers =0 @@ -1559,11 +1560,13 @@ function ocean_prog_tracer_init (Grid, Thickness, Ocean_options, Domain, Time, T endif #ifdef USE_OCEAN_BGC - !Get the %filed for "generic" tracers as it might have already been set. - !nnz: find a way to use their already allocated field pointer directly. + !Point the %field4d_ptr and %tendency for "generic" tracers to the corresponding T_prog(n)%field and T_prog(n)%K33_implicit + !to utilize the already allocated memory in MOM and to avoid copying the arrays back and forth between generic tracers and MOM do n=1,num_prog_tracers if(T_prog(n)%type .eq. 'generic') then - call ocean_generic_get_field(T_prog(n)%name,T_prog(n)%field) + call ocean_generic_set_pointer(T_prog(n)%name, 'field', T_prog(n)%field, isd, jsd) + !T_prog(n)%K33_implicit is used in vertdiff method below for calculating vertical diffusivity + call ocean_generic_set_pointer(T_prog(n)%name, 'tendency', T_prog(n)%K33_implicit, isd, jsd) endif enddo #endif @@ -2015,7 +2018,8 @@ function ocean_diag_tracer_init (Time, Thickness, vert_coordinate_type, num_diag if (num_diag_tracers .gt. 0 ) then do n=1,num_diag_tracers if(T_diag(n)%type .eq. 'generic') then - call ocean_generic_get_field(T_diag(n)%name,T_diag(n)%field) + !call ocean_generic_get_field(T_diag(n)%name,T_diag(n)%field) + call ocean_generic_set_pointer(T_diag(n)%name, 'field', T_diag(n)%field, isd, jsd) !nnz: find a way to use their already allocated field pointer directly. !#ifndef MOM_STATIC_ARRAYS diff --git a/src/mom5/ocean_tracers/ocean_tracer.html b/src/mom5/ocean_tracers/ocean_tracer.html deleted file mode 100644 index 411b543692..0000000000 --- a/src/mom5/ocean_tracers/ocean_tracer.html +++ /dev/null @@ -1,595 +0,0 @@ - - - -Module ocean_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_tracer_mod
- - --Contact: Stephen Griffies -, - Matt Harrison -, - Richard D. Slater (initialization) - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module time steps the tracer fields. -
- - - -- This module time steps the tracer fields. - Initialization for the tracer packages is done as well. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
field_manager_mod
fms_mod
fms_io_mod
fm_util_mod
mpp_domains_mod
mpp_io_mod
mpp_mod
platform_mod
time_manager_mod
transport_matrix_mod
ocean_blob_mod
ocean_convect_mod
ocean_domains_mod
ocean_density_mod
ocean_frazil_mod
ocean_bih_tracer_mod
ocean_generic_mod
ocean_lap_tracer_mod
ocean_obc_mod
ocean_parameters_mod
ocean_passive_mod
ocean_shortwave_mod
ocean_tempsalt_mod
ocean_tpm_mod
ocean_tpm_util_mod
ocean_tracer_advect_mod
ocean_tracer_diag_mod
ocean_tracer_util_mod
ocean_thickness_mod
ocean_types_mod
ocean_util_mod
ocean_vert_mix_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_prog_tracer_init:
- -- -ocean_diag_tracer_init:
- -- -update_ocean_tracer:
- -- -update_advection_only:
- -- -ocean_tracer_restart:
- -- -ocean_tracer_end:
- -- -compute_tmask_limit:
- -- -remap_s_to_depth:
- -- -remap_depth_to_s:
- -- -inflow_nboundary_init:
- -- -ocean_tracer_diagnostics_init:
- -- -send_tracer_diagnostics:
- -- -watermass_diag:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_prog_tracer_init
--
-- -DESCRIPTION -
-- - Initialization code for prognostic tracers, returning a pointer to - the T_prog array. -
-
-
-- - -
-ocean_diag_tracer_init
--
-- -DESCRIPTION -
-- - Initialization code for diagnostic tracers, returning a pointer to the T_diag array -
-
-
-- - -
-update_ocean_tracer
--
-- -DESCRIPTION -
-- - Update value of tracer concentration to time taup1. - - Note that T_prog(n)%source is added at the very end - of the time step, after the rho_dzt factor has been - divided. -
-
-
-- - -
-update_advection_only
--
-- -DESCRIPTION -
-- - - Redo tracer updates for those that use only advection--nothing else. - This method is useful for testing advection schemes. - - T_prog(n)%use_only_advection==.true. ignores all boundary forcing - and sources, so if T_prog(n)%stf or pme, rivers, sources - are nonzero, tracer diagnostics will spuriously indicate - non-conservation. - - Assume for these tests that - (1) vertical advection is done fully explictly in time - (2) pme, rivers, stf, btf, and other sources are zero - (3) do not use advect_sweby_all - -
-
-
-- - -
-ocean_tracer_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_tracer_end
--
-- -DESCRIPTION -
-- - Write ocean tracer restarts -
-
-
-- - -
-compute_tmask_limit
--
-- -DESCRIPTION -
-- - Provide for possibility that quicker advection reverts to - first order upwind when tracer is outside a specified range. - Likewise, may wish to revert neutral physics to horizontal diffusion. - - For this purpose, we define a mask which is set to unity where - fluxes revert to first order upwind advection - (if using quicker) and horizontal diffusion (if using neutral). - - This method is very ad hoc. What is preferred for advection is to use - a monotonic scheme, such as mdfl_sweby or mdppm. For neutral physics, - no analogous monotonic scheme has been implemented. Such could be - useful, especially for passive tracers. In the meantime, tmask_limit - provides a very rough limiter for neutral physics to help keep tracers - within specified bounds. - -
-
-
-- - -
-remap_s_to_depth
--
-- -DESCRIPTION -
-- - - Remap in the vertical from s-coordinate to depth and then send to - diagnostic manager. - - This routine is mostly of use for terrain following vertical - coordinates, which generally deviate a lot from depth or pressure - coordinates. The zstar and pstar coordinates are very similar - to z or pressure, so there is no need to do the remapping for - purposes of visualization. - - The routine needs to be made more general and faster. - It also has been found to be problematic, so it is NOT - recommended. It remains here as a template for a better algorithm. - Remapping methods in Ferret are much better. - - Use rho_dzt weighting to account for nonBoussinesq. - - Author: Stephen.Griffies - -
-
-
-- - -
-remap_depth_to_s
--
-- -DESCRIPTION -
-- - - Remap in the vertical from depth to s-coordinate. This routine is - used for initializing terrain following coordinate models given an - initial tracer field generated assuming depth-like vertical coordinate. - - This routine is of use for terrain following vertical coordinates, - which generally deviate a lot from z, zstar, pressure, or pstar - coordinates. - - Algorithm is very rudimentary and can be made better. - - Author: Stephen.Griffies - -
-
-
-- - -
-inflow_nboundary_init
--
-- -DESCRIPTION -
-- - Initialize the mask, temp, and salt values at the northern boundary - where we are specifying values for an inflow boundary condition. - -
-
-
-- - -
-ocean_tracer_diagnostics_init
--
-- -DESCRIPTION -
-- - Do some initialization required for diagnostics. - Density must already be initialized for this routine to be used. - Hence, this routine is called from ocean_model.F90. -
-
-
-- - -
-send_tracer_diagnostics
--
-- -DESCRIPTION -
-- - - For sending some tracer diagnostics - -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Diagnose effects from interior ocean vertical mixing of - temp and salt on the watermass transformation diagnostics. - - This routine is called prior to implicit update of the tracer - fields, so that taup1 value contains only explicit in-time - tendencies. The implicit in-time tendencies are diagnosed - in this routine by various calls to invtri using same methods - as for the prognostic calculation. - -
-
-
-
-NAMELIST
- --&ocean_tracer_nml --
-
----
-- -zero_tendency -
-- If true, then will freeze the tracer fields. -
-
-[logical] -- -zero_tracer_source -
-- To remove the T_prog%source contribution to tracer - evolution. For debugging purposes. Default - zero_tracer_source=.false. -
-
-[logical] -- -limit_age_tracer -
-- Limit the values of age tracer to be less than - total run time and greater than zero. - Default limit_age_tracer=.false. -
-
-[logical] -- -age_tracer_max_init -
-- Initial maximum age tracer. This nml provides the ability to - start an integration with an age tracer that is not initialized - to zero, say if we took an age tracer from another spin-up. - Default age_tracer_max_init=0.0. -
-
-[real, units: years] -- -remap_depth_to_s_init -
-- For remapping initial tracer distributions, generally determined - according to depth vertical coordinates using the mom preprocessing - schemes, onto s-coordinates. This method is of use for initializing - terrain following coordinate simulations with mom. -
-
-[logical] -- -frazil_heating_before_vphysics -
-- For computing frazil heating before the implicit vertical physics - (which includes boundary fluxes), and before vertical convection. - This is the order that CM2.0 and CM2.1 performed their calculations - of frazil. It is arguable that one should NOT do frazil until the - end of a time step, after vertical physics and after surface - boundary fluxes. - Default frazil_heating_before_vphysics=.false. -
-
-[logical] -- -frazil_heating_after_vphysics -
-- For computing frazil heating after the implicit vertical physics - (which includes boundary fluxes), and after vertical convection. - This is the recommended method. - Default frazil_heating_after_vphysics=.false. -
-
-[logical] -- -tmask_limit_ts_same -
-- tmask_limit is derived separately for the tracers. However, - it may be appropriate to have the mask be the same for temp - and salinity, in which case the neutral physics fluxes are - self-consistent. But for some cases, such as when running with - linear eos, may not wish to have the temp and salinity coupled - when computing the mask. -
-
-[logical] -- -compute_tmask_limit_on -
-- For updating the tmaks_limit array. This calculation is - recommended for the following physics and advection schemes: - 1/ quicker advection - 2/ neutral physics - 3/ submesoscale closure. - The default is compute_tmask_limit_on=.true., but if none - of the above schemes is used, then some time savings can be - realized by setting compute_tmask_limit_on=.false. -
-
-[logical] -- -debug_this_module -
-- For debugging the tracer module -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -interpolate_tprog_to_pbott -
-- To linear interpolate the initial conditions for prognostic - tracers to the partial bottom cells. Default - interpolate_tprog_to_pbott=.true. -
-
-[logical] -- -interpolate_tdiag_to_pbott -
-- To linear interpolate the initial conditions for diagnostic - tracers to the partial bottom cells. Default - interpolate_tdiag_to_pbott=.false. -
-
-[logical] -- -inflow_nboundary -
-- For adding an inflow transport from the northern boundary - which brings in temp and salinity according to inflow data - files. Default is inflow_nboundary=.false. -
-
-[logical] -- -ocean_tpm_debug -
-- For debugging ocean tracer package manager. -
-
-[logical] -- -use_tempsalt_check_range -
-- To call a check to see that temperature and salinity - are within their pre-selected range. - Default use_tempsalt_check_range=.false. since this - check may incur some cost that users should be aware of. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
-- - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) -
-- - S.M. Griffies, Fundamentals of ocean climate models (2004) -
-
- -
--top -- - diff --git a/src/mom5/ocean_tracers/ocean_tracer_advect.F90 b/src/mom5/ocean_tracers/ocean_tracer_advect.F90 index 10dab2a4d6..e633bcef7c 100644 --- a/src/mom5/ocean_tracers/ocean_tracer_advect.F90 +++ b/src/mom5/ocean_tracers/ocean_tracer_advect.F90 @@ -330,8 +330,8 @@ module ocean_tracer_advect_mod integer :: index_temp_sq=-1 integer :: index_salt_sq=-1 -character(len=256) :: version='CVS $Id: ocean_tracer_advect.F90,v 1.1.2.3 2012/06/01 20:47:08 Stephen.Griffies Exp $' -character(len=256) :: tagname='Tag $Name: mom5_siena_08jun2012_smg $' +character(len=256) :: version='CVS $Id: ocean_tracer_advect.F90,v 20.0 2013/12/14 00:17:22 fms Exp $' +character(len=256) :: tagname='Tag $Name: tikal $' type(ocean_domain_type), pointer :: Dom =>NULL() diff --git a/src/mom5/ocean_tracers/ocean_tracer_advect.html b/src/mom5/ocean_tracers/ocean_tracer_advect.html deleted file mode 100644 index 55c8a963db..0000000000 --- a/src/mom5/ocean_tracers/ocean_tracer_advect.html +++ /dev/null @@ -1,1373 +0,0 @@ - - - -Module ocean_tracer_advect_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_tracer_advect_mod
- - --Contact: Matt Harrison -, - S. M. Griffies -, - John Dunne -, - Alistair Adcroft - -- - -
-Reviewers: -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module computes thickness weighted tracer advection tendencies. -
- - - -- This module computes thickness weighted tracer advection tendencies - using a variety of advection schemes. --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
fms_io_mod
mpp_domains_mod
mpp_mod
ocean_domains_mod
ocean_obc_mod
ocean_parameters_mod
ocean_topog_mod
ocean_tracer_util_mod
ocean_types_mod
ocean_workspace_mod
-PUBLIC INTERFACE
----
-- -ocean_tracer_advect_init:
- -- -advection_diag_init:
- -- -watermass_diag_init:
- -- -gyre_overturn_diagnose_init:
- -- -quicker_init:
- -- -fourth_sixth_init:
- -- -mdfl_init:
- -- -mdppm_init:
- -- -mdmdt_init:
- -- -psom_init:
- -- -horz_advect_tracer:
- -- -vert_advect_tracer:
- -- -horz_advect_tracer_upwind:
- -- -horz_advect_tracer_2nd_order:
- -- -horz_advect_tracer_4th_order:
- -- -horz_advect_tracer_6th_order:
- -- -horz_advect_tracer_quicker:
- -- -horz_advect_tracer_quickmom3:
- -- -vert_advect_tracer_upwind:
- -- -vert_advect_tracer_2nd_order:
- -- -vert_advect_tracer_4th_order:
- -- -vert_advect_tracer_6th_order:
- -- -vert_advect_tracer_quicker:
- -- -vert_advect_tracer_quickmom3:
- -- -advect_tracer_mdfl_sup_b:
- -- -advect_tracer_mdfl_sweby_test:
- -- -advect_tracer_mdfl_sweby:
- -- -advect_tracer_sweby_all:
- -- -advect_tracer_psom:
- -- -psom_x:
- -- -psom_y:
- -- -psom_z:
- -- -advect_tracer_mdppm_test:
- -- -advect_tracer_mdppm:
- -- -ppm_limit_cw84:
- -- -ppm_limit_ifc:
- -- -ppm_limit_sh:
- -- -advect_tracer_mdmdt_test:
- -- -gyre_overturn_diagnose:
- -- -watermass_diag:
- -- -compute_adv_diss:
- -- -get_tracer_stats:
- -- -tracer_stats:
- -- -ocean_tracer_advect_restart:
- -- -ocean_tracer_advect_end:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_tracer_advect_init
--
-- -DESCRIPTION -
-- - Initialize the tracer advection module. -
-
-
-- - -
-advection_diag_init
--
-- -DESCRIPTION -
-- - Initialize the main tracer advection diagnostics. -
-
-
-- - -
-watermass_diag_init
--
-- -DESCRIPTION -
-- - Initialize the watermass diagnostics. -
-
-
-- - -
-gyre_overturn_diagnose_init
--
-- -DESCRIPTION -
-- - Initialize diagnostics and fields for gyre/overturning. - - March 2012 for faster approach: - russell.fiedler@csiro.au - - Some reorganization - Stephen.Griffies - -
-
-
-- - -
-quicker_init
--
-- -DESCRIPTION -
-- - Initialize quicker specific fields. -
-
-
-- - -
-fourth_sixth_init
--
-- -DESCRIPTION -
-- - Initialize the fourth order and sixth order advection fields. -
-
-
-- - -
-mdfl_init
--
-- -DESCRIPTION -
-- - Initialize mdfl and dst_linear specific fields. -
-
-
-- - -
-mdppm_init
--
-- -DESCRIPTION -
-- - Initialize mdppm specific fields. -
-
-
-- - -
-mdmdt_init
--
-- -DESCRIPTION -
-- - Initialize mdmdt specific fields. -
-
-
-- - -
-psom_init
--
-- -DESCRIPTION -
-- - Read restart or initialize moments for prather advection -
-
-
-- - -
-horz_advect_tracer
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers -
-
-
-- - -
-vert_advect_tracer
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers for case - with advect_sweby_all=.false. -
-
-
-- - -
-horz_advect_tracer_upwind
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers from first order upwind. - This scheme is positive definite but very diffusive. -
-
-
-- - -
-horz_advect_tracer_2nd_order
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers from second order - centered differences. -
-
-
-- - -
-horz_advect_tracer_4th_order
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers from fourth order centered - differences. - - WARNING: This code does NOT account for non-uniform grids. - -
-
-
-- - -
-horz_advect_tracer_6th_order
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers from sixth order centered - differences. - - WARNING: this code does NOT account for non-uniform grids. - -
-
-
-- - -
-horz_advect_tracer_quicker
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers from quicker. -
-
-
-- - -
-horz_advect_tracer_quickmom3
--
-- -DESCRIPTION -
-- - Compute horizontal advection of tracers from quicker using MOM3 masking. - This method has proven useful for reproducing MOM3 results with later MOM. -
-
-
-- - -
-vert_advect_tracer_upwind
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers from first order upwind. - This scheme is positive definite, but very diffusive. -
-
-
-- - -
-vert_advect_tracer_2nd_order
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers from second order centered - differences. -
-
-
-- - -
-vert_advect_tracer_4th_order
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers from fourth order centered - differences. NOTE: this code does not account for non-uniform grids. -
-
-
-- - -
-vert_advect_tracer_6th_order
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers from sixth order centered - differences. NOTE: this code does not account for non-uniform grids. -
-
-
-- - -
-vert_advect_tracer_quicker
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers from quicker. -
-
-
-- - -
-vert_advect_tracer_quickmom3
--
-- -DESCRIPTION -
-- - Compute vertical advection of tracers from quicker using MOM3 masking. - This method has proven useful for reproducing MOM3 results with later MOM. -
-
-
-- - -
-advect_tracer_mdfl_sup_b
--
-- -DESCRIPTION -
-- -------- - NOTE: This is legacy code. It may exhibit problems with limiters - that are improperly implemented in the case of generalized vertical level - coordinates of MOM. Under certain circumstances, the resulting tracer - concentration can exhibit non-monotonic behaviour (i.e., produce extrema). - - Sept 2011 - Stephen.Griffies - Alistair.Adcroft -------- - - Compute tendency due to 3D advection of tracers using a - multi-dimensional flux-limited method. This method differs from - other MOM advection methods in the following ways: - - 1) Horizontal and vertical advection are combined - 2) Calculations of the three coordinates (Z, X, Y) are performed sequentially as updates - to the tracer, so that the advection components for X and Y depend on Z and Z,Y - respectively. This helps limit the flux. - 3) During the update for each direction, the 2nd order Super-B flux limiter is applied. - 4) Flux divergence is included within the calculation to also help limit the flux: - - During the update for each direction, the divergence in each direction is added. - - During the overall tendency calculated, the divergence in all three directions - is removed. - 5) All fluxes are functions of the tracer field at the taum1 time step. This - means that this method is ideally suited for the twolevel time stepping scheme, - in which "taum1=tau", thus enabling twice the tracer time step available for the - threelevel scheme. - -The calculation proceeds as follows: - - IMPORTANT NOTE: If this scheme is used at all, it must be used as the option for BOTH - horizontal and vertical advection. In the the tracer tendency, it is applied as the - horizontal term, but applies to vertical as well, for which case the vertical term in - the tracer tendency equation is set to zero. - - This scheme was ported to mom4 from the MIT-GCM by John Dunne and Alistair Adcroft - during Summer 2003 - -
-
-
-- - -
-advect_tracer_mdfl_sweby_test
--
-- -DESCRIPTION -
-- - Compute tendency due to 3D advection of tracers using a multi-dimensional flux-limited - method. This method differs from other methods in the following ways: - - 1) Horizontal and vertical advection are combined - 2) Calculations of the three coordinates (Z, X, Y) are performed sequentially as updates - to the tracer, so that the advection components for X and Y depend on Z and Z,Y - respectively... This helps limit the flux. - 3) During the update for each direction, the 3rd order Sweby flux limiter is applied. - 4) Flux divergence is included within the calculation to also help limit the flux: - - During the update for each direction, the divergence in each direction is added. - - During the overall tendency calculated, the divergence in all three directions - is removed. - 5) All fluxes are functions of the tracer field at the taum1 time step. This - means that this method is ideally suited for the twolevel time stepping scheme, - in which "taum1=tau", thus enabling twice the tracer time step available for the - threelevel scheme. - - The calculation proceeds as follows: - - IMPORTANT NOTE: If this scheme is used at all, it must be used as the option for BOTH - horizontal and vertical advection. In the tracer tendency, it is applied as the - horizontal term, but applies to vertical as well, for which case the vertical term in - the tracer tendency equation is set to zero. - - This scheme was ported to mom4 from the MIT-GCM by John Dunne and Alistair Adcroft - during Summer 2003 - - Griffies: 5/27/04 - Optimized by filling 3d arrays prior to sending for mpp_update_domains - - 07/11/2007 by Stephen.Griffies - When the nonlinear limiters are removed (sweby_limiter=0.0), - this scheme reduces to a linear direct space-time method - (ADVECT_DST_LINEAR). - - This is a test version of the mdfl_sweby scheme. It is not supported for - general use. - -
-
-
-- - -
-advect_tracer_mdfl_sweby
--
-- -DESCRIPTION -
-- - -------- - NOTE: This is a legacy version of the advect_tracer_mdfl_sweby routine. - This version may have problems with limiters that are improperly implemented - in the case of generalized vertical level coordinates of MOM. Consequently, - under certain circumstances, the resulting tracer concentration can - exhibit non-monotonic behaviour (i.e., produce extrema). - This routine was used in various GFDL model configurations. - - Sept 2011 - Stephen.Griffies - Alistair.Adcroft -------- - - Compute tendency due to 3D advection of tracers using a multi-dimensional flux-limited - method. This method differs from other methods in the following ways: - - 1) Horizontal and vertical advection are combined - 2) Calculations of the three coordinates (Z, X, Y) are performed sequentially as updates - to the tracer, so that the advection components for X and Y depend on Z and Z,Y - respectively... This helps limit the flux. - 3) During the update for each direction, the 3rd order Sweby flux limiter is applied. - 4) Flux divergence is included within the calculation to also help limit the flux: - - During the update for each direction, the divergence in each direction is added. - - During the overall tendency calculated, the divergence in all three directions - is removed. - 5) All fluxes are functions of the tracer field at the taum1 time step. This - means that this method is ideally suited for the twolevel time stepping scheme, - in which "taum1=tau", thus enabling twice the tracer time step available for the - threelevel scheme. - - The calculation proceeds as follows: - - IMPORTANT NOTE: If this scheme is used at all, it must be used as the option for BOTH - horizontal and vertical advection. In the tracer tendency, it is applied as the - horizontal term, but applies to vertical as well, for which case the vertical term in - the tracer tendency equation is set to zero. - - This scheme was ported to mom4 from the MIT-GCM by John Dunne and Alistair Adcroft - during Summer 2003 - - Griffies: 5/27/04 - Optimized by filling 3d arrays prior to sending for mpp_update_domains - - 07/11/2007 by Stephen.Griffies - When the nonlinear limiters are removed (sweby_limiter=0.0), - this scheme reduces to a linear direct space-time method - (ADVECT_DST_LINEAR). - -
-
-
-- - -
-advect_tracer_sweby_all
--
-- -DESCRIPTION -
-- - -------- - NOTE: This is routine suffers from the same problems as the - advect_tracer_mdfl_sweby routine. Namely, it has problems - with limiters that are improperly implemented in the case of generalized - vertical level coordinates of MOM. Consequently, - under certain circumstances, the resulting tracer concentration can - exhibit non-monotonic behaviour (i.e., produce extrema). - This routine was used in various GFDL model configurations. It is retained - solely to provide bitwise reproducing those earlier configurations. - - Sept 2011 - Stephen.Griffies - Alistair.Adcroft -------- - - Sweby scheme optimized by doing all tracers at once, so - can send larger packet to mpp_update_domains. - - This scheme is available ONLY when advecting all tracers with the - sweby scheme. - - This scheme CANNOT be called from compute_adv_diss. - - Stephen.Griffies - June 2004 - -
-
-
-- - -
-advect_tracer_psom
--
-- -DESCRIPTION -
-- - - Compute advective tendency of dzt*rho*tracer concentration using - Prather's second order moment method (SOM): - - Prather, M. J.,"Numerical Advection by Conservation of Second-Order Moments" - JGR, Vol 91, NO. D6, p 6671-6681, May 20, 1986 - - Merryfield and Holloway (2003), "Application of an accurate advection - algorithm to sea-ice modelling". Ocean Modelling, Vol 5, p 1-15. - - MOM 3 code by M. Hofmann and M. A. M. Maqueda - Ported to mom4p0 by Ronald.Pacanowski - Ported to mom4p1 by Stephen.Griffies - - The preferred limiters are taken from Merryfield and Holloway, - and generalized by Bill Merryfield for non-constant grid spacing. - - IMPORTANT NOTE: This scheme must be used for BOTH horizontal and - vertical advection. In the tracer tendency, it is applied as the - horizontal term, but applies to vertical as well, for which case the - vertical term in the tracer tendency equation is set to zero. - - NOTE: When using psom_limit_prather=.true., the tracer has a lower - bound of zero. So this limiter IS NOT appropriate for temperature - when measured in degrees C. The preferred, and default, limiter - is from Merryfield and Holloway. - -
-
-
-- - -
-psom_x
--
-- -DESCRIPTION -
-- - Compute i-advective flux using Prather's SOM. -
-
-
-- - -
-psom_y
--
-- -DESCRIPTION -
-- - Computes j-advective flux using Prather's SOM. -
-
-
-- - -
-psom_z
--
-- -DESCRIPTION -
-- - Computes k-advective flux using Prather's SOM. -
-
-
-- - -
-advect_tracer_mdppm_test
--
-- -DESCRIPTION -
-- - - Compute advective tendency of dzt*rho*tracer concentration using - multi-dimensional piecewise parabolic method. - - Controlling parameters: - Tracer%ppm_hlimiter=0 -> No limiting in the horizontal - ppm_hlimiter=1 -> Full constraint (Colella and Woodward, 1984) - ppm_hlimiter=2 -> Improved full constraint (Lin, 2004) - ppm_hlimiter=3 -> Huynh limiter (Huynh, 1996) - - ppm_vlimiter=* -> as for ppm_hlimit but for the vertical - - Coded by Alistair.Adcroft - Jan/Feb 2006 - - Updated with controlling parameters, April 2006 - - This is an unsupported test version of the MDPPM scheme. It is not - meant for general use. - -
-
-
-- - -
-advect_tracer_mdppm
--
-- -DESCRIPTION -
-- - -------- - NOTE: This is routine may suffer from same problems as the - advect_tracer_mdfl_sweby routine. Namely, it has problems - with limiters that are improperly implemented in the case of generalized - vertical level coordinates of MOM. Consequently, - under certain circumstances, the resulting tracer concentration can - exhibit non-monotonic behaviour (i.e., produce extrema). - - Sept 2011 - Stephen.Griffies - Alistair.Adcroft -------- - - Compute advective tendency of dzt*rho*tracer concentration using - multi-dimensional piecewise parabolic method. - - Controlling parameters: - Tracer%ppm_hlimiter=0 -> No limiting in the horizontal - ppm_hlimiter=1 -> Full constraint (Colella and Woodward, 1984) - ppm_hlimiter=2 -> Improved full constraint (Lin, 2004) - ppm_hlimiter=3 -> Huynh limiter (Huynh, 1996) - - ppm_vlimiter=* -> as for ppm_hlimit but for the vertical - - Coded by Alistair.Adcroft - Jan/Feb 2006 - - Updated with controlling parameters, April 2006 - -
-
-
-- - -
-ppm_limit_cw84
--
-- -DESCRIPTION -
-- - - Kernel to limit the edge values for PPM following Colella and Woodward, 1984 - - Coded by Alistair.Adcroft - Apr 2006 - -
-
-
-- - -
-ppm_limit_ifc
--
-- -DESCRIPTION -
-- - - Kernel to limit the edge values for PPM using the Improved Full Constraint - (IFC) of Lin, 2004. - - Coded by Alistair.Adcroft - Apr 2006 - -
-
-
-- - -
-ppm_limit_sh
--
-- -DESCRIPTION -
-- - - Kernel to limit the edge values for PPM following the monotonicity- - preserving approach of Suresh and Huynh, 1997. - - Coded by Alistair.Adcroft - Apr 2006 - -
-
-
-- -NOTE -
-- - About efficiency: ppm_limit_sh() is not as efficient as it would be if - we wrote a s/r for each direction. The pre-calculation of d1m, d1p, d1mm and - d1pp duplicates operations and would be much faster if d1m was replaced - by d1p(i+1). However, in order to re-use this limiter for the all directions - (to simplify debugging) I have opted for the less efficient form for now. - AJA -
-
-
-- - -
-advect_tracer_mdmdt_test
--
-- -DESCRIPTION -
-- - - Compute advective tendency of dzt*rho*tracer concentration using - multi-dimensional piecewise parabolic method. - - Controlling parameters: - Tracer%mdt_scheme=0 -> 7th order FV, unlimited (Daru & Tenaud, 2004) - mdt_scheme=1 -> 7th order FV, TVD limiter - mdt_scheme=2 -> 7th order FV, MP limiter - mdt_scheme=3 -> 7th order MP, 4th order TVD, FCT combination (Adcroft, 2011) - - Coded by Alistair.Adcroft - Aug/Sep 2011 - - This code is unsupported test code, which is not meant for general use. - -
-
-
-- - -
-gyre_overturn_diagnose
--
-- -DESCRIPTION -
-- - Diagnose tracer transport according to zonal mean and - deviations from zonal mean. - - We allow for the use of a basin mask so that the zonal means - are performed over the global domain and each of five other - basins. If no basin mask is read, then assume global domain - used to define the zonal means. - - []=zonal mean; *=deviation from zonal mean - - V = rho_dzt dxt T, with rho=rho0 for Boussinesq - - int [V T] = total advective - int [V][T] = overturning - int V* T* = gyre - - This routine is much faster than the older routine gyre_overturn_diagnose_old. - - In this version, we compute partial zonal sums locally and then perform - a "global" sum over a restricted set of pes. - This approach results in slightly different answers at the - REAL(8) level. However, differences should be negligible for diagnostic - purposes at the REAL(4) level. - - We require no global arrays here, and redundant computation is eliminated. - - Note that if advect_sweby_all is used we cannot do this calculation since we - don not have flux_y, except for the last tracer computed. - The zonal mean could be computed within the routine or flux_y itself could - be stored in a 3D arrays. - - original approach - Stephen.Griffies - May 2007 - - optimization by removing global arrays - russell.fiedler@csiro.au - March 2012 - -
-
-
-- - -
-watermass_diag
--
-- -DESCRIPTION -
-- - Compute watermass diagnostics associated with resolved flow - advection of temperature and salinity. -
-
-
-- - -
-compute_adv_diss
--
-- -DESCRIPTION -
-- - - Compute the dissipation due to advection truncation errors. - This diagnostic requires computation of advection operator acting - on the squared tracer concentration. - - NOTE: This scheme isolates the dissipation from trucation errors - in advection ONLY for the following vertical coordinates: - 1/ geopotential: for all k-levels, except for k=1 - (due to undulating surface height) - 2/ pressure: for all k-levels, except for k=kmt - (due to undulating bottom pressure) - - NOTE: For the Quicker advection scheme, we assume the preferred - two_level time scheme is used here, so that taum1=tau. - - NOTE: If PSOM is used for temp or salt, then we MUST also enable - a new passive tracer in the field table, with name - passive_temp_sq and passive_salt_sq. This extra tracer is - used for diagnostics alone, and is required due to the extra - moment fields used for computing the PSOM tendency. - If PSOM is used for another tracer besides temp or salt, then - some extra code needs to be written inside ocean_passive.F90, - emulating the work done for temp and salt. - -
-
-
-- - -
-get_tracer_stats
--
-- -DESCRIPTION -
-- - Compute the upper/lower values of a 3D field, returning values via arguments -
-
-
-- - -
-tracer_stats
--
-- -DESCRIPTION -
-- - Check the upper/lower values of a 3D field fall between speficied bounds - reporting points that fall outside. Bring model down uncleanly if bounds are - exceeded. - - NOTE: This is a debugging tool and not for normal use. - -
-
-
-- - -
-ocean_tracer_advect_restart
--
-- -DESCRIPTION -
-- - Write out restart files registered through register_restart_file -
-
-
-- - -
-ocean_tracer_advect_end
--
-- -DESCRIPTION -
-- - Write the PSOM moments for restarts. -
-
-
-
-NAMELIST
- --&ocean_tracer_advect_nml --
-
----
-- -limit_with_upwind -
-- If true, will compute tracer fluxes entering a cell using upwind - if the tracer value is outside a specified range. Implemented - only for quick at this time. This is an ad hoc and incomplete attempt - to maintain monotonicity with the quicker scheme. -
-
-[logical] -- -advect_sweby_all -
-- For running all tracers with sweby, thereby utilizing a bitwise same - routine that reorganizes loops and can be faster for certain configurations. - Default advect_sweby_all=.false. -
-
-[logical] -- -zero_tracer_advect_horz -
-- For debugging. Set to .true. to turn off horizontal advection. -
-
-[logical] -- -zero_tracer_advect_vert -
-- For debugging. Set to .true. to turn off vertical advection. -
-
-[logical] -- -psom_limit_prather -
-- For running with the original Prather limiter for the PSOM scheme. - The limiter is positive definite, but not monotonic. This limiter - is NOT recommended for most applications. The default is - psom_limit_prather=.false., since we prefer to use the limiter - from Merryfield and Holloway (2003). -
-
-[logical] -- -debug_this_module -
-- For debugging -
-
-[logical] -- -write_a_restart -
-- Set true to write a restart. False setting only for rare - cases where wish to benchmark model without measuring the cost - of writing restarts and associated chksums. - Default is write_a_restart=.true. -
-
-[logical] -- -read_basin_mask -
-- For reading in a mask that selects regions of the domain - for performing gyre and overturning diagnostics. - The basin-mask convention used at GFDL has - Southern=1.0,Atlantic=2.0,Pacific=3.0,Arctic=4.0,Indian=5.0 - Default read_basin_mask=.false., whereby basin_mask - is set to tmask(k=1). -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - S.-J. Lin - A "Vertically Lagrangian" Finite-Volume Dynamical Core for Global Models - Month. Weather Rev. (2004) 132, 2293-2307 - (Appendix B) -
-- - H.T. Huynh - Schemes and Constraints for advection - 15th Intern. Conf. on Numeric. Meth. in Fluid Mech., Springer (1997) -
-- - Colella P. and P.R. Woodward - The piecewise parabloic method (PPM) for gasdynamical simulations - J. Comput. Phys. (1984) 54, 174-201 -
-- - A. Suresh and H.T. Huynh - Accurate Monotonicity-Preserving Schemes with Runge-Kutta Time Splitting - J. Comput. Phys. (1997) 136, 83-99 -
-- - V. Daru and C. Tenaud - High order one-step monotonicity-preserving schemes for unsteady - compressible flow calculations. - J. Comp. Phys. (2004) 193, 563-594 -
-- - R.C. Easter - Two modified versions of Botts positive-definite numerical advection scheme. - Month. Weath. Rev. (1993) 121, 297-304 -
-- - Prather, M. J.,"Numerical Advection by Conservation of Second-Order Moments" - JGR, Vol 91, NO. D6, p 6671-6681, May 20, 1986 -
-- - Merryfield and Holloway (2003), "Application of an accurate advection - algorithm to sea-ice modelling". Ocean Modelling, Vol 5, p 1-15. -
-- - Hundsdorder and Trompert (1994), "Method of lines and - direct discretization: a comparison for linear - advection", Applied Numerical Mathematics, - pages 469--490. -
-- - Sweby (1984): "High-resolution schemes using flux - limiters for hyperbolic conservation laws", - SIAM Journal of Numerical Analysis, vol. 21 - pages 995-1011. -
-
- -
--top -- - diff --git a/src/mom5/ocean_tracers/transport_matrix.F90 b/src/mom5/ocean_tracers/transport_matrix.F90 index b08d87ed48..ef0f570972 100644 --- a/src/mom5/ocean_tracers/transport_matrix.F90 +++ b/src/mom5/ocean_tracers/transport_matrix.F90 @@ -155,7 +155,7 @@ module transport_matrix_mod !{ ! ! ! -! $Id: transport_matrix.F90,v 1.1.2.1 2012/05/15 16:48:04 smg Exp $ +! $Id: transport_matrix.F90,v 20.0 2013/12/14 00:17:24 fms Exp $ ! use field_manager_mod, only: fm_string_len, fm_path_name_len, fm_field_name_len diff --git a/src/mom5/ocean_tracers/transport_matrix.html b/src/mom5/ocean_tracers/transport_matrix.html deleted file mode 100644 index b52eb4cab0..0000000000 --- a/src/mom5/ocean_tracers/transport_matrix.html +++ /dev/null @@ -1,300 +0,0 @@ - - - -Module transport_matrix_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module transport_matrix_mod
- - --Contact: Samar Khatiwala - -- - -
-Reviewers: Rick Slater -, - Stephen M. Griffies -, - Jennifer Simeon - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- Transport Matrix Method -
- - - -- Transport Matrix Method, for use in finding an approximate steady - state of tracers. - - Ported to MOM4p0d by Samar Khatiwala spk@ldeo.columbia.edu - June-July 2007 - - Ported to MOM4p1 by Stephen.Griffies - July 2007 - - Some code clean-up; increased conformity to tracer module standard - jes.13JUN08 - - further code cleanup by Richard.Slater Jan2009. - - **Preliminary testing only. - - This module saves out the components of the explicit and implicit - transport matrix. spk uses the output from the transport matrix module - to assemble the actual transport matrix with his matlab code. - - In conjunction with the Newton-Krylov (NK) solver, the transport matrix - is used to do an accelerated forward model in an iterative manner - which allows the NK solver to reach solution convergence with greater - efficiency. - - To create the transport matrix building blocks, passive, prognostic - "tracers" are simulated. These "tracers" are, in practice, dye - tracers initialized to 1 at one or more grid points and initialized - to 0 elsewhere. Since the "area of influence" of - a tracer at a particular grid point is determined by the advection scheme, - it becomes more practical to introduce a number of dye tracers at other - grid points, such that the "tracers" are staggered and will have - non-overlapping areas of influence. These non-overlapping regions are - called by spk, "tiles". The total number of dye tracers - needed is independent of the horizontal grid resolution, but - rather dependent upon the advection scheme's area of influence, i.e. - the total number of grid points contained in a "tile". For a - simple linear advection scheme, the number of tracers needed is about - 10 x (number of vertical levels). - spk has some special matlab code that generates the initial condition - for the "tracers", given the grid_spec of the model. - - The behavior of the tracers' advection and diffusion is averaged over - time (which the user may specify) and is saved out as a component - of the later-to-be-assembled transport matrix. - - To run the transport_matrix module, an initial condition - must be created by spk. - - Include the transport_matrix field_table and diag_table entries - for the xml. Examples of these follow. - - Sample field table. - ------------------------------------------------- - "tracer_packages","ocean_mod","transport_matrix" - - names = '01', '02', '03' - horizontal-advection-scheme = mdfl_sweby - vertical-advection-scheme = mdfl_sweby - / - - -------------------------------------------------- - - Sample diag table entry: enter as many "tracers" as you need - with the naming convention exp_tm_# and imp_tm_# - where # is a string as given abaove in "names" - -------------------------------------------------- -"transport_matrix","exp_tm_01", "exp_tm_01" ,"ocean_transport_matrix","all",.false.,"none",1 -"transport_matrix","imp_tm_01", "imp_tm_01" ,"ocean_transport_matrix","all",.false.,"none",1 -"transport_matrix","exp_tm_02", "exp_tm_02" ,"ocean_transport_matrix","all",.false.,"none",1 -"transport_matrix","imp_tm_02", "imp_tm_02" ,"ocean_transport_matrix","all",.false.,"none",1 -"transport_matrix","exp_tm_03", "exp_tm_03" ,"ocean_transport_matrix","all",.false.,"none",1 -"transport_matrix","imp_tm_03", "imp_tm_03" ,"ocean_transport_matrix","all",.false.,"none",1 - -------------------------------------------------- - - - SPK NOTES: - 1) The calling sequence is as follows: - Top level driver (e.g., ocean_solo) - -> S/R ocean_model_init(Ocean, Time_init, Time_in, Time_step_ocean, ensemble_ocean) - Time%init = Time_in .eq. Time_init - Time%Time_init = Time_init - Time%Time_step = Time_step_ocean - Time%model_time = Time_in - Time%itt = 0 - -> S/R ocean_prog_tracer_init - -> S/R ocean_tpm_init - -> S/R transport_matrix_init - -> S/R ocean_tpm_start - -> S/R transport_matrix_start - Start time stepping loop - do nc=1, num_cpld_calls - do no=1, num_ocean_calls - ocean_seg_start = ( no .eq. 1 ) - ocean_seg_end = ( no .eq. num_ocean_calls ) - -> S/R update_ocean_model(Ice_ocean_boundary, Ocean_sfc, & - ocean_seg_start, ocean_seg_end, num_ocean_calls) - Time%model_time = Time%model_time + Time%Time_step - Time%itt = Time%itt+1 - -> S/R ocean_tracer, S/R update_ocean_tracer - do explicit transport - -> S/R transport_matrix_store_explicit - (accumulate explicit matrix and reset tracer field to initial condition) - do implicit transport - -> S/R ocean_tpm_tracer - -> S/R transport_matrix_store_implicit - (accumulate implicit matrix and reset tracer field to initial condition) - -> S/R transport_matrix_write(.FALSE.) (time average and write matrices) - Time = Time + Time_step_ocean - enddo - enddo - -> S/R ocean_model_end - -> S/R ocean_tpm_end - -> S/R transport_matrix_end - -> S/R transport_matrix_write(.TRUE.) - (time average and write matrices for multi year runs) - - 2) Time counters are incremented BEFORE calling S/R update_ocean_tracer, so the first time - transport_matrix_store_explicit is called, itt (and hence myIter) will be 1. - The namelist parameter matrixStoreStartIter indicating the iteration number to begin - accumulating matrices at should be RELATIVE to the current model run start (unlike - in the MIT GCM where it refers to an absolute counter. - I am not entirely certain this is handled correctly below. Things might be off by - 1 time step. - - - --
- - -
-OTHER MODULES USED
- --- - - -field_manager_mod-
mpp_mod
diag_manager_mod
ocean_tpm_util_mod
ocean_types_mod
-PUBLIC INTERFACE
----
-- -transport_matrix_init:
- -- -transport_matrix_start:
- -- -transport_matrix_store_explicit:
- -- -transport_matrix_store_implicit:
- -
- - -
-PUBLIC ROUTINES
- --
- - - - - - -- - -
-transport_matrix_init
--
-- -DESCRIPTION -
-- - Set up any extra fields needed by tracer package manager -
-
-
-- - -
-transport_matrix_start
--
-- -DESCRIPTION -
-- - - -
-
-
-- - -
-transport_matrix_store_explicit
--
-- -DESCRIPTION -
-- - For the time explicit tendencies. -
-
-
-- - -
-transport_matrix_store_implicit
--
-- -DESCRIPTION -
-- - For the time implicit tendencies. -
-
-
-
-REFERENCES
- ----
-- - Khatiwala, S., M. Visbeck, M.A. Cane, 2005. - Accelerated simulation of passive tracers in ocean circulation models. - Ocean Modelling, 9, 51-69. -
-
- -
--top -- - diff --git a/src/mom5/ocean_wave/ocean_wave.F90 b/src/mom5/ocean_wave/ocean_wave.F90 index 5d9b6b93e4..bef0520c2a 100644 --- a/src/mom5/ocean_wave/ocean_wave.F90 +++ b/src/mom5/ocean_wave/ocean_wave.F90 @@ -75,9 +75,9 @@ module ocean_wave_mod type(ocean_grid_type), pointer :: Grd =>NULL() character(len=128) :: & - version='$Id: ocean_wave.F90,v 1.1.2.2 2012/05/17 13:41:56 smg Exp $' + version='$Id: ocean_wave.F90,v 20.0 2013/12/14 00:17:26 fms Exp $' character (len=128) :: tagname = & - '$Name: mom5_siena_08jun2012_smg $' + '$Name: tikal $' real,parameter:: gtpi=grav/2.0/pi, epsln=1e-20 real,parameter:: sqrt_2 = sqrt(2.) diff --git a/src/mom5/ocean_wave/ocean_wave.html b/src/mom5/ocean_wave/ocean_wave.html deleted file mode 100644 index a924719b0b..0000000000 --- a/src/mom5/ocean_wave/ocean_wave.html +++ /dev/null @@ -1,328 +0,0 @@ - - - -Module ocean_wave_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module ocean_wave_mod
- - - - - -
-OVERVIEW
- -- Idealized wave model for delivering wave number and wave height - for coupled current-wave action on sediment. -
- - - -- This idealized wave model delivers wave number and wave height - for calculation of the coupled current-wave action on sediment. - Swell is not included in this model. - - All fields are defined at tracer grid, for later use in sediment dynamics - in such modules as ocean_shared/generic_tracers/generic_ERGOM.F90 --
- - -
-OTHER MODULES USED
- --- - - -constants_mod-
diag_manager_mod
fms_mod
mpp_mod
fms_io_mod
ocean_domains_mod
mpp_domains_mod
ocean_types_mod
ocean_parameters_mod
ocean_workspace_mod
ocean_util_mod
wave_types_mod
data_override_mod
-PUBLIC INTERFACE
----
-- -ocean_wave_init:
- -- -ocean_wave_model:
- -- -ocean_wave_prop:
- -- -ocean_wave_diag:
- -- -ocean_wave_filter:
- -- -read_wave:
- -- -ocean_wave_restart:
- -- -ocean_wave_end:
- -- -wave_chksum:
- -- -wave_model_is_initialised:
-- - Returns .true. if the wave model is initialised -
-
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-ocean_wave_init
--
-- -DESCRIPTION -
-- - Initialize the wave module -
-
-
-- - -
-ocean_wave_model
--
-- -DESCRIPTION -
-- - time step the wave model -
-
-
-- - -
-ocean_wave_prop
--
-- -DESCRIPTION -
-- - wave propagation -
-
-
-- - -
-ocean_wave_diag
--
-- -DESCRIPTION -
-- - wave diagnostics -
-
-
-- - -
-ocean_wave_filter
--
-- -DESCRIPTION -
-- - wave filter -
-
-
-- - -
-read_wave
--
-- -DESCRIPTION -
-- - Read wave restart information. -
-
-
-- - -
-ocean_wave_restart
--
-- -DESCRIPTION -
-- - Save wave restart information. -
-
-
-- - -
-ocean_wave_end
--
-- -DESCRIPTION -
-- - Write out external mode fields to restart file. -
-
-
-- - -
-wave_chksum
--
-- -DESCRIPTION -
-- - Compute checksum for external mode fields. -
-
-
-- - -
-wave_model_is_initialised
-use ocean_wave_mod, only: wave_model_is_initialised if (wave_model_is_initialised() ) then--
-- -DESCRIPTION -
-- - This function returns .true. if the wave model is initialised - It is needed, because the wave model may be initialised after some module that requires a wave model -
-
-
-- -INPUT -
-- -
--
-- -- No inputs needed. - -
[]
-- -OUTPUT -
-- -
--
-- -- This function returns a logical. - -
[logical]
-
-NAMELIST
- --& --
-
----
- - - - -
-REFERENCES
- ----
-- - P.C. Liu, D.J. Schwab and J.R. Bennett, - Journ. of Phys. Oceanography 14, 1514 (1984). - D.J. Schwab, J.R. Bennett, P.C. Liu and M.A. Donelan, - Journ. of Geophysical Research 89 (C3), 3586 (1984). -
-- - Hughes, S. A. 1984. "TMA Shallow-Water Spectrum: - Description and Application," Technical Report CERC-84-7, - US Army Engineer Waterways Experiment Station, Vicksburg, Miss. -
-
- -
--top -- - diff --git a/src/mom5/ocean_wave/ocean_wave_type.html b/src/mom5/ocean_wave/ocean_wave_type.html deleted file mode 100644 index 2871628819..0000000000 --- a/src/mom5/ocean_wave/ocean_wave_type.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module wave_types_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
-Module wave_types_mod
- - - - - -
-OVERVIEW
- - - - - - -
- - -
-OTHER MODULES USED
- -- -- - - -
-PUBLIC INTERFACE
----
- - -
-PUBLIC ROUTINES
- -- - - - - - -
--top -- - diff --git a/src/ocean_shared/generic_tracers/FMS_ocmip2_co2calc.F90 b/src/ocean_shared/generic_tracers/FMS_ocmip2_co2calc.F90 index 4e4ab0d43c..0738193a35 100644 --- a/src/ocean_shared/generic_tracers/FMS_ocmip2_co2calc.F90 +++ b/src/ocean_shared/generic_tracers/FMS_ocmip2_co2calc.F90 @@ -39,15 +39,17 @@ module FMS_ocmip2_co2calc_mod !{ !------------------------------------------------------------------ ! +use mpp_mod, only: mpp_error, WARNING + implicit none private -public :: FMS_ocmip2_co2calc, CO2_dope_vector +public :: FMS_ocmip2_co2calc, FMS_ocmip2_co2calc_old, CO2_dope_vector public :: FMS_ocmip2_co2_alpha -character(len=128) :: version = '$Id: FMS_ocmip2_co2calc.F90,v 17.0 2009/07/21 03:18:07 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: FMS_ocmip2_co2calc.F90,v 20.0 2013/12/14 00:18:00 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' type CO2_dope_vector integer :: isc, iec, jsc, jec @@ -63,7 +65,6 @@ module FMS_ocmip2_co2calc_mod !{ contains - !####################################################################### !! @@ -401,7 +402,6 @@ subroutine FMS_ocmip2_co2calc(dope_vec, mask, & end subroutine FMS_ocmip2_co2calc !} ! NAME="FMS_ocmip2_co2calc" - !####################################################################### !! @@ -410,7 +410,7 @@ end subroutine FMS_ocmip2_co2calc !} ! function drtsafe(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & - bt, dic, ft, pt, sit, st, ta, x1, x2, x, xacc) !{ + bt, dic, ft, pt, sit, st, ta, x1_in, x2_in, x, xacc) !{ implicit none @@ -421,7 +421,7 @@ function drtsafe(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & real :: k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf real :: bt, dic, ft, pt, sit, st, ta real :: drtsafe -real :: x1, x2, x, xacc +real :: x1_in, x2_in, x, xacc ! ! local parameters @@ -435,6 +435,9 @@ function drtsafe(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & integer :: j real :: fl, df, fh, swap, xl, xh, dxold, dx, f, temp +real :: x1 +real :: x2 +logical :: bracketed drtsafe=x call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & @@ -445,10 +448,28 @@ function drtsafe(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & return endif -call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & - bt, dic, ft, pt, sit, st, ta, x1, fl, temp) -call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & - bt, dic, ft, pt, sit, st, ta, x2, fh, temp) +bracketed = .false. +x1 = x +x2 = x + +do j = 1, 10 + + x1 = x1 * 0.1 + x2 = x2 * 10.0 + call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, x1, fl, temp) + call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, x2, fh, temp) + if (fl*fh .lt. 0.0) then + bracketed = .true. + exit + endif + +enddo + +if (.not. bracketed) then + call mpp_error(WARNING, 'drtsafe: root not bracketed') +endif if(fl .lt. 0.0) then xl=x1 @@ -463,7 +484,8 @@ function drtsafe(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & drtsafe=0.5*(x1+x2) dxold=abs(x2-x1) dx=dxold - +call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, drtsafe, f, df) do j=1,maxit !{ if (((drtsafe-xh)*df-f)*((drtsafe-xl)*df-f) .ge. 0.0 .or. & abs(2.0*f) .gt. abs(dxold*df)) then @@ -499,12 +521,13 @@ function drtsafe(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & end if enddo !} j +! should have an error condition here for not converging? + return end function drtsafe !} ! NAME="drtsafe" - !####################################################################### !! @@ -567,7 +590,7 @@ subroutine ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & ! - st/(1. + (c ks)/x) - ft/(1. + kf/x) fn = - ta + kw/x - c*x & - +dic*(k1*x+2.0*k12)*bm1 & + + dic*(k1*x+2.0*k12)*bm1 & + pt*(-x3+k12p*x+2.0*k123p)*am1 & + bt *kb *xpkbm1 & + sit*ksi*xpksim1 & @@ -649,6 +672,7 @@ subroutine FMS_ocmip2_co2_alpha(dope_vec, t, s, mask, alpha, scale) !{ integer :: i integer :: j +integer :: k real :: log100 real :: tk real :: tk100 @@ -728,4 +752,446 @@ end subroutine FMS_ocmip2_co2_alpha !} ! NAME="ocmip2_co2_alpha" + +!####################################################################### +!+! +! NAME="FMS_ocmip2_co2calc_old" + + +!####################################################################### +!+! Calculate co2* from total alkalinity and total CO2 at +! temperature (t) and salinity (s). +! It is assumed that init_ocmip2_co2calc has already been called with +! the T and S to calculate the various coefficients. +! +! INPUT +! +! dope_vec = an array of indices corresponding to the compute +! and data domain boundaries. +! +! mask = land mask array (0.0 = land) +! +! dic_in = total inorganic carbon (mol/kg) +! where 1 T = 1 metric ton = 1000 kg +! +! ta_in = total alkalinity (eq/kg) +! +! pt_in = inorganic phosphate (mol/kg) +! +! sit_in = inorganic silicate (mol/kg) +! +! htotallo = lower limit of htotal range +! +! htotalhi = upper limit of htotal range +! +! htotal = H+ concentration (mol/kg) +! +! OUTPUT +! co2star = CO2*water, or H2CO3 concentration (mol/kg) +! alpha = Solubility of CO2 for air (mol/kg/atm) +! pco2surf = oceanic pCO2 (ppmv) +! co3_ion = Carbonate ion, or CO3-- concentration (mol/kg) +! +! FILES and PROGRAMS NEEDED: drtsafe_old, ta_iter_1 +! +! IMPORTANT: co2star and alpha need to be multiplied by rho before being +! passed to the atmosphere. +! +! + +subroutine FMS_ocmip2_co2calc_old(dope_vec, mask, & + t_in, s_in, dic_in, pt_in, sit_in, ta_in, htotallo, & + htotalhi, htotal, co2star, alpha, pCO2surf, co3_ion) !{ + +implicit none + +! +! local parameters +! + +real, parameter :: permeg = 1.e-6 +real, parameter :: xacc = 1.0e-10 + +! +! arguments +! +type(CO2_dope_vector), intent(in) :: dope_vec +real, dimension(dope_vec%isd:dope_vec%ied,dope_vec%jsd:dope_vec%jed), & + intent(in):: mask, & + t_in, & + s_in, & + dic_in, & + pt_in, & + sit_in, & + ta_in, & + htotallo, & + htotalhi +real, dimension(dope_vec%isd:dope_vec%ied,dope_vec%jsd:dope_vec%jed), & + intent(inout) :: htotal +real, dimension(dope_vec%isd:dope_vec%ied,dope_vec%jsd:dope_vec%jed), & + intent(out), optional :: alpha, & + pCO2surf, & + co2star, & + co3_ion +! +! local variables +! +integer :: isc, iec, jsc, jec +integer :: i,j +real :: alpha_internal +real :: bt +real :: co2star_internal +real :: dlogtk +real :: ft +real :: htotal2 +real :: invtk +real :: is +real :: is2 +real :: k1 +real :: k2 +real :: k1p +real :: k2p +real :: k3p +real :: kb +real :: kf +real :: ks +real :: ksi +real :: kw +real :: log100 +real :: s2 +real :: scl +real :: sqrtis +real :: sqrts +real :: st +real :: tk +real :: tk100 +real :: tk1002 +real :: logf_of_s + +! Set the loop indices. + isc = dope_vec%isc ; iec = dope_vec%iec + jsc = dope_vec%jsc ; jec = dope_vec%jec + +! +! Initialize the module +! + log100 = log(100.0) + + do j = jsc, jec !{ + do i = isc, iec !{ + if (mask(i,j) .gt. 0.0) then !{ +! +!--------------------------------------------------------------------- +! +!*********************************************************************** +! Calculate all constants needed to convert between various measured +! carbon species. References for each equation are noted in the code. +! Once calculated, the constants are stored and passed in the common +! block "const". The original version of this code was based on +! the code by Dickson in Version 2 of "Handbook of Methods for the +! Analysis of the Various Parameters of the Carbon Dioxide System +! in Seawater", DOE, 1994 (SOP No. 3, p25-26). + tk = 273.15 + t_in(i,j) + tk100 = tk / 100.0 + tk1002 = tk100**2 + invtk = 1.0 / tk + dlogtk = log(tk) + is = 19.924 * s_in(i,j) /(1000.0 -1.005 * s_in(i,j)) + is2 = is * is + sqrtis = sqrt(max(0.0,is)) + s2 = s_in(i,j) * s_in(i,j) + sqrts = sqrt(max(0.0,s_in(i,j))) + scl = s_in(i,j) / 1.80655 + logf_of_s = log(1.0 - 0.001005 * s_in(i,j)) +! +! k0 from Weiss 1974 +! +! +! k0 = exp(93.4517/tk100 - 60.2409 + 23.3585 * log(tk100) + & +! s_in(i,j) * (0.023517 - 0.023656 * tk100 + & +! 0.0047036 * tk1002)) +! +! k1 = [H][HCO3]/[H2CO3] +! k2 = [H][CO3]/[HCO3] +! +! Millero p.664 (1995) using Mehrbach et al. data on seawater scale +! + + k1 = 10.0**(-(3670.7 * invtk - 62.008 + 9.7944 * dlogtk - & + 0.0118 * s_in(i,j) + 0.000116 * s2)) + k2 = 10.0**(-(1394.7 * invtk + 4.777 - & + 0.0184 * s_in(i,j) + 0.000118 * s2)) +! +! kb = [H][BO2]/[HBO2] +! +! Millero p.669 (1995) using data from Dickson (1990) +! + + kb = exp((-8966.90 - 2890.53 * sqrts - 77.942 * s_in(i,j) + & + 1.728 * sqrts**3 - 0.0996 * s2) * invtk + (148.0248 + & + 137.1942 * sqrts + 1.62142 * s_in(i,j)) + (-24.4344 - & + 25.085 * sqrts - 0.2474 * s_in(i,j)) * dlogtk + & + 0.053105 * sqrts * tk) +! +! k1p = [H][H2PO4]/[H3PO4] +! +! DOE(1994) eq 7.2.20 with footnote using data from Millero (1974) +! + + k1p = exp(-4576.752 * invtk + 115.525 - 18.453 * dlogtk + & + (-106.736 * invtk + 0.69171) * sqrts + (-0.65643 * & + invtk - 0.01844) * s_in(i,j)) +! +! k2p = [H][HPO4]/[H2PO4] +! +! DOE(1994) eq 7.2.23 with footnote using data from Millero (1974)) +! + + k2p = exp(-8814.715 * invtk + 172.0883 - 27.927 * (-160.340 * & + invtk + 1.3566) * sqrts + (0.37335 * invtk - & + 0.05778) * s_in(i,j)) +! +!----------------------------------------------------------------------- +! k3p = [H][PO4]/[HPO4] +! +! DOE(1994) eq 7.2.26 with footnote using data from Millero (1974) +! + + k3p = exp(-3070.75 * invtk - 18.141 +(17.27039 * invtk + & + 2.81197) * sqrts + (-44.99486 * invtk - 0.09984) * & + s_in(i,j)) +! +!----------------------------------------------------------------------- +! ksi = [H][SiO(OH)3]/[Si(OH)4] +! +! Millero p.671 (1995) using data from Yao and Millero (1995) +! + ksi = exp(-8904.2 * invtk + 117.385 - 19.334 * dlogtk + & + (-458.79 * invtk + 3.5913) * sqrtis + (188.74 * & + invtk - 1.5998) * is + (-12.1652 * invtk + 0.07871) * & + is2 + logf_of_s) +! +!----------------------------------------------------------------------- +! kw = [H][OH] +! +! Millero p.670 (1995) using composite data +! + + kw = exp(-13847.26 * invtk + 148.9652 - 23.6521 * dlogtk + & + (118.67 * invtk - 5.977 + 1.0495 * dlogtk) * sqrts - & + 0.01615 * s_in(i,j)) +! +!----------------------------------------------------------------------- +! ks = [H][SO4]/[HSO4] +! +! Dickson (1990, J. chem. Thermodynamics 22, 113) +! + ks = exp(-4276.1 * invtk + 141.328 - 23.093 * dlogtk + & + (-13856.0 * invtk + 324.57 - 47.986 * dlogtk) * & + sqrtis + (35474.0 * invtk - 771.54 + 114.723 * & + dlogtk) * is - 2698.0 * invtk * sqrtis**3 + & + 1776.0 * invtk * is2 + logf_of_s) +! +!----------------------------------------------------------------------- +! kf = [H][F]/[HF] +! +! Dickson and Riley (1979) -- change pH scale to total +! + kf = exp(1590.2 * invtk - 12.641 + 1.525 * sqrtis + logf_of_s + & + log(1.0 + (0.1400 / 96.062) * scl / ks)) +! +!----------------------------------------------------------------------- +! Calculate concentrations for borate, sulfate, and fluoride +! +! Uppstrom (1974) +! + bt = 0.000232 / 10.811 * scl +! +! Morris & Riley (1966) +! + st = 0.14 / 96.062 * scl +! +! Riley (1965) +! + ft = 0.000067 / 18.9984 * scl +! +!*********************************************************************** +! +! Calculate [H+] total when DIC and TA are known at T, S and 1 atm. +! The solution converges to err of xacc. The solution must be within +! the range x1 to x2. +! +! If DIC and TA are known then either a root finding or iterative method +! must be used to calculate htotal. In this case we use the +! Newton-Raphson "safe" method taken from "Numerical Recipes" +! (function "rtsafe.f" with error trapping removed). +! +! As currently set, this procedure iterates about 12 times. The x1 +! and x2 values set below will accomodate ANY oceanographic values. +! If an initial guess of the pH is known, then the number of +! iterations can be reduced to about 5 by narrowing the gap between +! x1 and x2. It is recommended that the first few time steps be run +! with x1 and x2 set as below. After that, set x1 and x2 to the +! previous value of the pH +/- ~0.5. The current setting of xacc will +! result in co2star accurate to 3 significant figures (xx.y). Making +! xacc bigger will result in faster convergence also, but this is not +! recommended (xacc of 10**-9 drops precision to 2 significant +! figures). +! + + htotal(i,j) = drtsafe_old( k1, k2, kb, k1p, k2p, k3p, ksi, kw, & + ks, kf, bt, dic_in(i,j), ft, pt_in(i,j),& + sit_in(i,j), st, ta_in(i,j), & + htotalhi(i,j), htotallo(i,j),htotal(i,j), xacc) +! +! Calculate [CO2*] as defined in DOE Methods Handbook 1994 Ver.2, +! ORNL/CDIAC-74, Dickson and Goyet, eds. (Ch 2 p 10, Eq A.49) +! + htotal2 = htotal(i,j) * htotal(i,j) + co2star_internal = dic_in(i,j) * htotal2 / (htotal2 + & + k1 * htotal(i,j) + k1 * k2) + if (present(co2star)) co2star(i,j) = co2star_internal + if (present(co3_ion)) co3_ion(i,j) = co2star_internal * k1 * k2 / htotal2 +! +! Weiss & Price (1980, Mar. Chem., 8, 347-359; Eq 13 with table 6 +! values) +! + if (present(alpha) .or. present(pCO2surf)) then + alpha_internal = exp(-162.8301 + 218.2968 / tk100 + 90.9241 * & + (dlogtk -log100) - 1.47696 * tk1002 + & + s_in(i,j) * (0.025695 - 0.025225 * tk100 + & + 0.0049867 * tk1002)) + endif + if (present(alpha)) alpha(i,j) = alpha_internal + if (present(pCO2surf)) then + pCO2surf(i,j) = co2star_internal / (alpha_internal * permeg) + endif + + else !}{mask(i,j)=0.0 + + if (present(co3_ion)) then + co3_ion(i,j) = 0.0 + endif + if (present(co2star)) then + co2star(i,j) = 0.0 + endif + if (present(alpha)) then !{ + alpha(i,j) = 0.0 + endif !} + if (present(pco2surf)) then !{ + pCO2surf(i,j) = 0.0 + endif !} + + endif !}mask + + enddo !} i + enddo !} j + +return + +end subroutine FMS_ocmip2_co2calc_old !} +!+! +! NAME="drtsafe_old" + end module FMS_ocmip2_co2calc_mod !} diff --git a/src/ocean_shared/generic_tracers/generic_BLING.F90 b/src/ocean_shared/generic_tracers/generic_BLING.F90 index 40d24fdee4..54f8091cf4 100644 --- a/src/ocean_shared/generic_tracers/generic_BLING.F90 +++ b/src/ocean_shared/generic_tracers/generic_BLING.F90 @@ -114,7 +114,7 @@ module generic_BLING use coupler_types_mod, only: coupler_2d_bc_type use field_manager_mod, only: fm_string_len, fm_path_name_len use mpp_mod, only: input_nml_file, mpp_error, stdlog, NOTE, WARNING, FATAL, stdout, mpp_chksum - use fms_mod, only: open_namelist_file, check_nml_error, close_file + use fms_mod, only: write_version_number, open_namelist_file, check_nml_error, close_file use fms_mod, only: field_exist, file_exist use time_manager_mod, only: time_type use fm_util_mod, only: fm_util_start_namelist, fm_util_end_namelist @@ -132,6 +132,9 @@ module generic_BLING implicit none ; private + character(len=128) :: version = '$Id: generic_BLING.F90,v 20.0 2013/12/14 00:18:02 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' + character(len=fm_string_len), parameter :: mod_name = 'generic_BLING' character(len=fm_string_len), parameter :: package_name = 'generic_bling' @@ -526,6 +529,8 @@ subroutine generic_BLING_register(tracer_list) character(len=fm_string_len), parameter :: sub_name = 'generic_bling_register' character(len=256), parameter :: error_header = & '==>Error from ' // trim(mod_name) // '(' // trim(sub_name) // '): ' +character(len=256), parameter :: warn_header = & + '==>Warning from ' // trim(mod_name) // '(' // trim(sub_name) // '): ' character(len=256), parameter :: note_header = & '==>Note from ' // trim(mod_name) // '(' // trim(sub_name) // '): ' @@ -542,13 +547,14 @@ subroutine generic_BLING_register(tracer_list) #else ioun = open_namelist_file() read (ioun, generic_bling_nml,iostat=io_status) -write (stdoutunit,'(/)') -write (stdoutunit, generic_bling_nml) -write (stdlogunit, generic_bling_nml) ierr = check_nml_error(io_status,'generic_bling_nml') call close_file (ioun) #endif +write (stdoutunit,'(/)') +write (stdoutunit, generic_bling_nml) +write (stdlogunit, generic_bling_nml) + if ((do_14c) .and. (do_carbon)) then write (stdoutunit,*) trim(note_header), 'Simulating radiocarbon' else if ((do_14c) .and. .not. (do_carbon)) then @@ -600,6 +606,8 @@ end subroutine generic_BLING_register subroutine generic_BLING_init(tracer_list) type(g_tracer_type), pointer :: tracer_list + call write_version_number( version, tagname ) + !Specify and initialize all parameters used by this package call user_add_params @@ -1228,7 +1236,7 @@ subroutine user_add_params ! call g_tracer_add_param('tracer_debug', bling%tracer_debug, .false.) ! - call g_tracer_end_param_list() + call g_tracer_end_param_list(package_name) !=========== !Block Ends: g_tracer_add_param !=========== @@ -1242,6 +1250,7 @@ end subroutine user_add_params ! subroutine user_add_tracers(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'user_add_tracers' !Add here only the parameters that are required at the time of registeration !(to make flux exchanging Ocean tracers known for all PE's) @@ -1252,7 +1261,7 @@ subroutine user_add_tracers(tracer_list) call g_tracer_add_param('ocean_restart_file' , bling%ocean_restart_file, 'ocean_bling.res.nc') call g_tracer_add_param('IC_file' , bling%IC_file , '') - call g_tracer_end_param_list() + call g_tracer_end_param_list(package_name) ! Set Restart files call g_tracer_set_files(ice_restart_file = bling%ice_restart_file,& @@ -1551,6 +1560,7 @@ end subroutine user_add_tracers subroutine generic_BLING_update_from_coupler(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_update_from_coupler' end subroutine generic_BLING_update_from_coupler !####################################################################### @@ -1652,6 +1662,7 @@ subroutine generic_BLING_update_from_source(tracer_list,Temp,Salt,& real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band + character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_update_from_source' integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau, i, j, k , kblt,n real, dimension(:,:,:) ,pointer :: grid_tmask integer, dimension(:,:),pointer :: mask_coast,grid_kmt @@ -3028,6 +3039,7 @@ subroutine generic_BLING_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau real, dimension(:,:,:,:), pointer :: o2_field real, dimension(:,:), ALLOCATABLE :: co2_alpha,co2_csurf,o2_alpha,o2_csurf real, dimension(:,:), ALLOCATABLE :: co2_sat_alpha,co2_sat_csurf,c14o2_alpha,c14o2_csurf + character(len=fm_string_len), parameter :: sub_name = 'generic_BLING_set_boundary_values' !Get the necessary properties call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask) @@ -3097,17 +3109,16 @@ subroutine generic_BLING_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau grid_tmask(i,j,1) sc_no_term = sqrt(660.0 / (sc_o2 + epsln)) - o2_alpha(i,j) = o2_saturation * sc_no_term + o2_alpha(i,j) = o2_saturation * sc_no_term * bling%Rho_0 o2_csurf(i,j) = o2_field(i,j,1,tau) * sc_no_term * bling%Rho_0 !nnz: MOM has rho(i,j,1,tau) + enddo; enddo ! !Set %csurf and %alpha for these tracers. This will mark them for sending fluxes to coupler ! call g_tracer_set_values(tracer_list,'o2_b', 'alpha',o2_alpha, isd,jsd) call g_tracer_set_values(tracer_list,'o2_b', 'csurf',o2_csurf, isd,jsd) - enddo; enddo - if (do_carbon) then !<+! File taken from Numerical Recipes. Modified R. M. Key 4/94 +! + +function drtsafe_old(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, x1, x2, x, xacc) !{ + +implicit none + +! +! arguments +! + +real :: k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf +real :: bt, dic, ft, pt, sit, st, ta +real :: drtsafe_old +real :: x1, x2, x, xacc + +! +! local parameters +! + +integer, parameter :: maxit = 100 + +! +! local variables +! + +integer :: j +real :: fl, df, fh, swap, xl, xh, dxold, dx, f, temp + +drtsafe_old=x +call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, drtsafe_old, f, df) +dx=f/df +if (abs(dx) .lt. xacc) then +! write (6,*) 'Exiting drtsafe_old at C on iteration ', j, ', ph = ', -log10(drtsafe) + return +endif + +call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, x1, fl, temp) +call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, x2, fh, temp) + +if(fl .lt. 0.0) then + xl=x1 + xh=x2 +else + xh=x1 + xl=x2 + swap=fl + fl=fh + fh=swap +end if +drtsafe_old=0.5*(x1+x2) +dxold=abs(x2-x1) +dx=dxold + +do j=1,maxit !{ + if (((drtsafe_old-xh)*df-f)*((drtsafe_old-xl)*df-f) .ge. 0.0 .or. & + abs(2.0*f) .gt. abs(dxold*df)) then + dxold=dx + dx=0.5*(xh-xl) + drtsafe_old=xl+dx + if (xl .eq. drtsafe_old) then +! write (6,*) 'Exiting drtsafe_old at A on iteration ', j, ', ph = ', -log10(drtsafe) + return + endif + else + dxold=dx + dx=f/df + temp=drtsafe_old + drtsafe_old=drtsafe_old-dx + if (temp .eq. drtsafe_old) then +! write (6,*) 'Exiting drtsafe_old at B on iteration ', j, ', ph = ', -log10(drtsafe) + return + endif + end if + if (abs(dx) .lt. xacc) then +! write (6,*) 'Exiting drtsafe_old at C on iteration ', j, ', ph = ', -log10(drtsafe) + return + endif + call ta_iter_1(k1, k2, kb, k1p, k2p, k3p, ksi, kw, ks, kf, & + bt, dic, ft, pt, sit, st, ta, drtsafe_old, f, df) + if(f .lt. 0.0) then + xl=drtsafe_old + fl=f + else + xh=drtsafe_old + fh=f + end if +enddo !} j + + +return + +end function drtsafe_old !} +!- - - Module generic_BLING - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
-Module generic_BLING
- - --Contact: Eric D. Galbraith - , - John P. Dunne - , - Anand Gnanandesikan - , - Niki Zadeh - -- - -
-Reviewers: Rick Slater - -
-Change History: WebCVS Log -
-
-
-OVERVIEW
- -- This module contains the generic version of BLING. - It is designed so that both GFDL Ocean models, GOLD and MOM, can use it. - - WARNING: although the core components of the model (PO4, Fed, DOP, O2) - have been quite well tested, the other components should be viewed as - developmental at this point. There may still be some bugs, particularly - in the CaCO3 burial scheme. EDG June 4, 2009 - -
- - - -- Biogeochemistry with Light, Iron, Nutrient and Gas (BLING) includes an - implicit ecological model of growth limitation by light, - temperature, phosphate and iron, along with dissolved organic - phosphorus and O2 pools. - Food web processing in the euphotic zone and remineralization/ - dissolution through the ocean interior are handled as in Dunne et al. - (2005). O2 equilibria and gas exchange follow OCMIP2 protocols. - Additional functionality comes from an optional carbon cycle that is - non-interactive, i.e. does not change the core BLING behaviour, as - well as tracers for radiocarbon (14c), a decomposition of carbon - components by gas exchange and remineralization (carbon_pre), and a - decomposition of phosphate as preformed and remineralized (po4_pre). --
- - -
-OTHER MODULES USED
- --- - - -coupler_types_mod-
field_manager_mod
mpp_mod
fms_mod
time_manager_mod
fm_util_mod
diag_manager_mod
constants_mod
g_tracer_utils
FMS_ocmip2_co2calc_mod
-PUBLIC INTERFACE
----
-- -generic_BLING_init:
-- - Initialize the generic BLING module -
-- -generic_BLING_update_from_coupler:
-- - Modify the values obtained from the coupler if necessary. -
-- -generic_BLING_update_from_bottom:
-- - Set values of bottom fluxes and reservoirs -
-- -generic_BLING_update_from_source:
-- - Update tracer concentration fields due to the source/sink contributions. -
-- -generic_BLING_set_boundary_values:
-- - Calculate and set coupler values at the surface / bottom -
-- -generic_BLING_end:
-- - End the module. -
-
- - -
-PUBLIC ROUTINES
- --
- - - - -- - -
-generic_BLING_init
--call generic_BLING_init (tracer_list)--
-- -DESCRIPTION -
-- - This subroutine: - Adds all the BLING Tracers to the list of generic Tracers passed - to it via utility subroutine g_tracer_add(). Adds all the parameters - used by this module via utility subroutine g_tracer_add_param(). - Allocates all work arrays used in the module. -
-
-
-- -INPUT -
-- -
--
-- -tracer_list - Pointer to the head of generic tracer list. - -
[type(g_tracer_type), pointer]
-- - -
-generic_BLING_update_from_coupler
--call generic_BLING_update_from_coupler (tracer_list)--
-- -DESCRIPTION -
-- - Some tracer fields could be modified after values are obtained from the - coupler. This subroutine is the place for specific tracer manipulations. - BLING currently does not use this. -
-
-
-- -INPUT -
-- -
--
-- -tracer_list - Pointer to the head of generic tracer list. - -
[type(g_tracer_type), pointer]
-- - -
-generic_BLING_update_from_bottom
--call generic_BLING_update_from_bottom (tracer_list,dt, tau)--
-- -DESCRIPTION -
-- - Some tracers could have bottom fluxes and reservoirs. - This subroutine is the place for specific tracer manipulations. - BLING currently does not use this. -
-
-
-- -INPUT -
-- -
--
-- -tracer_list - Pointer to the head of generic tracer list. - -
[type(g_tracer_type), pointer]- -dt - Time step increment - -
[real]- -tau - Time step index to be used for %field - -
[integer]
-- - -
-generic_BLING_update_from_source
--call generic_BLING_update_from_source (tracer_list,Temp,Salt,dzt,hblt_depth,& ilb,jlb,tau,dt, grid_dat,sw_pen,opacity)--
-- -DESCRIPTION -
-- - This is the subroutine to contain most of the biogeochemistry for calculating the - interaction of tracers with each other and with outside forcings. -
-
-
-- -INPUT -
-- -
--
-- -tracer_list - Pointer to the head of generic tracer list. - -
[type(g_tracer_type), pointer]- -ilb,jlb - Lower bounds of x and y extents of input arrays on data domain - -
[integer]- -Temp - Ocean temperature - -
[real, dimension(ilb:,jlb:,:)]- -Salt - Ocean salinity - -
[real, dimension(ilb:,jlb:,:)]- -dzt - Ocean layer thickness (meters) - -
[real, dimension(ilb:,jlb:,:)]- -opacity - Ocean opacity - -
[real, dimension(ilb:,jlb:,:)]- -sw_pen - Shortwave peneteration - -
[real, dimension(ilb:,jlb:)]- -hblt_depth - - - -
[real, dimension(ilb:,jlb:)]- -grid_dat - Grid area - -
[real, dimension(ilb:,jlb:)]- -tau - Time step index of %field - -
[integer]- -dt - Time step increment - -
[real]
-- - -
-generic_BLING_set_boundary_values
--call generic_BLING_set_boundary_values (tracer_list,SST,SSS,rho,ilb,jlb,tau)--
-- -DESCRIPTION -
-- - - -
-
-
-- -INPUT -
-- -
--
-- -tracer_list - Pointer to the head of generic tracer list. - -
[type(g_tracer_type), pointer]- -ilb,jlb - Lower bounds of x and y extents of input arrays on data domain - -
[integer]- -SST - Sea Surface Temperature - -
[real, dimension(ilb:,jlb:)]- -SSS - Sea Surface Salinity - -
[real, dimension(ilb:,jlb:)]- -rho - Ocean density - -
[real, dimension(ilb:,jlb:,:,:)]- -tau - Time step index of %field - -
[integer]
-- - -
-generic_BLING_end
--call generic_BLING_end ---
-- -DESCRIPTION -
-- - Deallocate all work arrays -
-
-
-
-NAMELIST
- --&generic_bling_nml --
-
----
-- -do_14c -
-- If true, then simulate radiocarbon. Includes 2 prognostic tracers, DI14C - and DO14C. Requires that do_carbon = .true. Note that 14C is not taken up - by CaCO3 at the current time, but cycles only through the soft tissue. - This is a mistake that will be fixed later. -
-
-[logical] -- -do_carbon -
-- If true, then simulate the carbon cycle based on strict stoichiometry - of C:P. Includes 1 prognostic tracer, DIC. -
-
-[logical] -- -do_carbon_pre -
-- If true, then simulate the carbon cycle based on strict stoichiometry - of C:P. Includes 3 prognostic tracers, DIC, ALK and ALK_pre. Requires - that do_carbon = .true. -
-
-[logical] -- -do_po4_pre -
-- If true, then simulate preformed PO4, a useful theoretical construct - equal to PO4 in the surface layer and subject only to passive transport - everywhere else. 1 prognostic tracer, PO4_pre. -
-
-[logical] -- -bury_caco3 -
-- If true, then allow CaCO3 to be buried in sediments as a function - of sinking CaCO3 flux and bottom water saturation state, and allow - a river input of alkalinity to compensate. Caution: this will cause - the alkalinity to have a long term drift, which will produce a long - term drift in the carbon cycle. Should be considered highly - experimental at this point. Requires that do_carbon=.true. -
-
-[logical] -- -use_bling_chl -
-- If true, names the BLING diagnostic chlorophyll field 'chl'. Thus, - if read_chl=.false. in the shortwave namelist, BLING chlorophyll will - be used to calculate sw absorption. Set this to false in order to - have the chlorophyll field named chl_b, preventing conflict with the - TOPAZ chlorophyll field, so that the two modules can run - simultaneously. -
-
-[logical] -
- - - - -
-REFERENCES
- ----
-- - This model is available for public use. - The current version is BLING.0. The version number refers to the core - model behaviour; additional tracers exist in different iterations of the - module. In publications it should be referenced as: - Galbraith, E.D., Gnanadesikan, A., Dunne, J. and Hiscock, M. 2009. - Regional impacts of iron-light colimitation in a global - biogeochemical model. Biogeosciences Discussions, 6, 1-47. - - All parameter values are as described in this paper. - Note that this reference is only for the core model components, and - does not include any of the additional functionalities, which remain - undocumented. Please contact Eric Galbraith (eric.galbraith@mcgill.ca) - for more information. -
-
- -
--top -- -