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 "Documentation in current working directory" > $ou echo "

Documentation in current working directory

" >> $outdoc sort -u $doc | awk '{print "

" $1 ""}' >> $outdoc echo '


This file was automatically generated by list_paths.' >> $outdoc -echo '$Revision: 10.1 $ $Date: 2010/05/19 18:42:43 $' >> $outdoc +echo '$Revision: 1.1.2.1 $ $Date: 2013/12/18 17:47:54 $' >> $outdoc rm -f $doc $src diff --git a/bin/mkmf b/bin/mkmf index 792a4b35bd..75f3cd58c2 100755 --- a/bin/mkmf +++ b/bin/mkmf @@ -37,7 +37,7 @@ sub ensureTrailingSlash { local $/ = '/'; chomp @_[0]; @_[0] .= '/'; } -my $version = '$Id: mkmf,v 16.1 2010/05/19 18:49:19 fms Exp $ '; +my $version = '$Id: mkmf,v 1.1.2.1 2013/12/18 17:47:54 Niki.Zadeh Exp $ '; # initialize variables: use getopts for these getopts( 'a:I:c:dfm:o:l:p:t:vx' ) || die "\aSyntax: $0 [-a abspath] [-c cppdefs] [-d] [-f] [-m makefile] [-o otherflags] ][-p program] [-t template] [-v] [-x] [-I \"space separated include dirs\"] [targets]\n"; @@ -106,8 +106,8 @@ if ( $opt_c ) { $cppdefs_xlf =~ s/,/\\,/g; # escape any commas already there $cppdefs_xlf =~ s/\s+/,/g; # replace whitespace with commas &print_formatted_list("CPPDEFS_XLF = $cppdefs_xlf"); - $compile_cmd{'.F'} = q/$(FC) $(CPPDEFS_XLF) $(FFLAGS) -c/; - $compile_cmd{'.F90'} = q/$(FC) $(CPPDEFS_XLF) $(FFLAGS) -c/; + $compile_cmd{'.F'} = q/$(FC) $(CPPDEFS_XLF) $(FFLAGS) $(OTHERFLAGS) -c/; + $compile_cmd{'.F90'} = q/$(FC) $(CPPDEFS_XLF) $(FFLAGS) $(OTHERFLAGS) -c/; } &print_formatted_list("CPPDEFS = $opt_c") if $opt_c; } diff --git a/bin/mkmf.html b/bin/mkmf.html index 82b261b636..007db3b14b 100644 --- a/bin/mkmf.html +++ b/bin/mkmf.html @@ -1,4 +1,4 @@ - + @@ -286,7 +286,7 @@

mkmf - a tool for making makefiles

following Makefile:

-# 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
-
-!#######################################################################
-
-!#######################################################################
-! 
-!
-! 
-!  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
-!  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 
 ! 
 !  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
-
-!######################################################################
-
-!#######################################################################
-! 
-!
-! 
-!  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
-!  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 $
 
 !
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 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 ( qstarqc_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 ( n0. ) 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 
-
-!#######################################################################
-! 
-!
-! 
-!   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
-!  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.
 
 ! 
 !  
@@ -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
 ! 
 ! 
 !
-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
-! 
-!   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
-
-! 
-!  
-!   
-!  
-!  
-!   
-!  
-!  
-! 
-!
-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
-
-
-!#################################################################
-
-
-!---------------------------------------------------------------------
-
-! 
-!  
-!    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.
-!   
-!  
-!  
-!  
-! 
-!  
-!  
-! 
-!  
-!  
-! 
-!  
-!  
-! 
-!  
-!  
-! 
-!  
-! 
-!
-
-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 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
-
-!#############################################################################      
-
-!#######################################################################
-! 
-!
-! 
-!   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
-! 
-
-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
 !
 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 @@
-
-
-
-Program coupler_main
-
-
-
-
-PUBLIC INTERFACE 
-
-          ~ PUBLIC ROUTINES 
-	    ~ NAMELIST 
-	    ~ ERROR MESSAGES 
-
-

Program coupler_main

- - -
-Contact:  Bruce Wyman ,  - V. Balaji -
-Reviewers:  -
-Change History: WebCVS Log -
-
-
- - -
-

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

    - -
      -
    1. - -

      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]
      -
      -
      -
      -
    2. -
    3. - -

      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]
      -
      -
      -
      -
    4. -
    5. - -

      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]
      -
      -
      -
      -
    6. -
    7. - -

      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]
      -
      -
      -
      -
    8. -
    9. - -

      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]
      -
      -
      -
      -
    10. -
    11. - -

      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]
      -
      -
      -
      -
    12. -
    13. - -

      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. -
      -
      -
      -
      -
    14. -
    15. - -

      flux_init_stocks

      -
      -
      -DESCRIPTION -
      -
      - This will call the various component stock_pe routines to store the - the initial stock values. -
      -
      -
      -
      -
    16. -
    17. - -

      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]
      -
      -
      -
      -
    18. -
    19. - -

      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]
      -
      -
      -
      -
    20. -
    21. - -

      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]
      -
      -
      -
      -
    22. -
    23. - -

      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 - -
      -
      -
      -
      -
    24. -
    - - - - -
    -

    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

    - -
      -
    1. - -

      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]
      -
      -
      -
      -
    2. -
    - - - - -
    -

    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 -!####################################################################### -! -! -! -! 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. -! - -! - -! -! 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 -! - -!####################################################################### -! -! -! -! Print checksums of the various fields in the land_data_type. -! - -! -! Routine to print checksums of the various fields in the land_data_type. -! - -! - -! -! 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 -! - - 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 (glac0)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_lo0) 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)%T0 .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)%T0 .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 (tetime_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 ! -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 @@ - - - -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

      - - - - - -
      -

      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. +! +! +! +! +! +!
        +!     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. 
        +!     
        +!
        +! + 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 @@ - - - -Module ocean_bgc_restore_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
        -

        Module ocean_bgc_restore_mod

        - - -
        -Contact:  Richard D. Slater - -
        -Reviewers:  John P. Dunne - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          ocean_bgc_restore_bbc

          -
          -
          -DESCRIPTION -
          -
          - calculate the surface boundary conditions -
          -
          -
          -
          -
        6. -
        7. - -

          ocean_bgc_restore_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various BIOTIC quantities for this run. -
          -
          -
          -
          -
        8. -
        9. - -

          ocean_bgc_restore_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        10. -
        11. - -

          ocean_bgc_restore_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions -
          -
          -
          -
          -
        12. -
        13. - -

          ocean_bgc_restore_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        14. -
        15. - -

          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. -
          -
          -
          -
          -
        16. -
        17. - -

          ocean_bgc_restore_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocean_bgc_restore_start -
          -
          -
          -
          -
        18. -
        19. - -

          ocean_bgc_restore_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_bgc_restore_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        22. -
        23. - -

          ocean_bgc_restore_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        24. -
        25. - -

          ocean_bgc_restore_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations -
          -
          -
          -
          -
        26. -
        27. - -

          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) -
          -
          -
          -
          -
        28. -
        29. - -

          ocean_bgc_restore_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants for a given run - and allocate diagnostic arrays -
          -
          -
          -
          -
        30. -
        31. - -

          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. -
          -
          -
          -
          -
        32. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Biotic/HOWTO-Biotic.html -
        2. -
        3. - Press, W. H., S. A. Teukosky, W. T. Vetterling, B. P. Flannery, 1992. - Numerical Recipes in FORTRAN, Second Edition, Cambridge University Press. -
        4. -
        5. - 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. -
        6. -
        -
        -
        - -
        -
        -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 + ! ! ! 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

        - - -
        -Contact:  Niki Zadeh - -
        -Reviewers:  William Cooke - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
          -
        1. - -

          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) -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          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. -
          -
          -
          -
          -
        6. -
        7. - -

          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. -
          -
          -
          -
          -
        8. -
        9. - -

          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. -
          -
          -
          -
          -
        10. -
        11. - -

          ocean_generic_end

          -
          -call ocean_generic_end 
          -
          -
          -
          -DESCRIPTION -
          -
          - Call the end for generic tracer module and deallocate all temp arrays -
          -
          -
          -
          -
        12. -
        - - - - - - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays for quantities with unknown dimensions. - These are arrays that only exist temporarily. -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          ocean_ibgc_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various quantities for this run. This includes writing out - additional information to ensure reproduction across restarts. -
          -
          -
          -
          -
        6. -
        7. - -

          ocean_ibgc_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        8. -
        9. - -

          ocean_ibgc_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions. This includes things - like gas exchange, atmospheric deposition, and riverine inputs. -
          -
          -
          -
          -
        10. -
        11. - -

          ocean_ibgc_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        12. -
        13. - -

          ocean_ibgc_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
          -
          -
          -
          -
        14. -
        15. - -

          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. -
          -
          -
          -
          -
        16. -
        17. - -

          ocean_ibgc_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations. -
          -
          -
          -
          -
        18. -
        19. - -

          ocean_ibgc_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations. -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_ibgc_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations. -
          -
          -
          -
          -
        22. -
        23. - -

          ocean_ibgc_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Finish up stuff for surface fields for flux calculations. -
          -
          -
          -
          -
        24. -
        25. - -

          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) -
          -
          -
          -
          -
        26. -
        27. - -

          ocean_ibgc_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants for a given run - and allocate diagnostic arrays -
          -
          -
          -
          -
        28. -
        29. - -

          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. - -
          -
          -
          -
          -
        30. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - 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. -
        2. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  Richard D. Slater - -
        -Reviewers:  John P. Dunne - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_pert_co2_bbc

          -
          -
          -DESCRIPTION -
          -
          - calculate the surface boundary conditions -
          -
          -
          -
          -
        4. -
        5. - -

          ocean_pert_co2_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various quantities for this run. -
          -
          -
          -
          -
        6. -
        7. - -

          ocean_pert_co2_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions -
          -
          -
          -
          -
        8. -
        9. - -

          ocean_pert_co2_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          ocean_pert_co2_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocean_pert_co2_start -
          -
          -
          -
          -
        14. -
        15. - -

          ocean_pert_co2_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        16. -
        17. - -

          ocean_pert_co2_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        18. -
        19. - -

          ocean_pert_co2_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_pert_co2_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations -
          -
          -
          -
          -
        22. -
        23. - -

          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) -
          -
          -
          -
          -
        24. -
        25. - -

          ocean_pert_co2_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
          -
          -
          -
          -
        26. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - 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. -
        2. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  Jennifer Simeon - -
        -Reviewers:  Eric Galbraith - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_po4_pre_bbc

          -
          -
          -DESCRIPTION -
          -
          - calculate the surface boundary conditions -
          -
          -
          -
          -
        4. -
        5. - -

          ocean_po4_pre_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various PO4_PRE quantities for this run. -
          -
          -
          -
          -
        6. -
        7. - -

          ocean_po4_pre_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions -
          -
          -
          -
          -
        8. -
        9. - -

          ocean_po4_pre_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          ocean_po4_pre_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocean_po4_pre_start -
          -
          -
          -
          -
        14. -
        15. - -

          ocean_po4_pre_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        16. -
        17. - -

          ocean_po4_pre_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        18. -
        19. - -

          ocean_po4_pre_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_po4_pre_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Finish up stuff for surface fields for flux calculations -
          -
          -
          -
          -
        22. -
        23. - -

          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) -
          -
          -
          -
          -
        24. -
        25. - -

          ocean_po4_pre_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants for a given run - and allocate diagnostic arrays -
          -
          -
          -
          -
        26. -
        27. - -

          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 -
          -
          -
          -
          -
        28. -
        29. - -

          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. -
          -
          -
          -
          -
        30. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - No reference yet. -
        2. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  Richard D. Slater - -
        -Reviewers:  John P. Dunne - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          ocmip2_abiotic_bbc

          -
          -
          -DESCRIPTION -
          -
          - calculate the surface boundary conditions -
          -
          -
          -
          -
        4. -
        5. - -

          ocmip2_abiotic_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various ABIOTIC quantities for this run. -
          -
          -
          -
          -
        6. -
        7. - -

          ocmip2_abiotic_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        8. -
        9. - -

          ocmip2_abiotic_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions -
          -
          -
          -
          -
        10. -
        11. - -

          ocmip2_abiotic_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        12. -
        13. - -

          ocmip2_abiotic_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
          -
          -
          -
          -
        14. -
        15. - -

          ocmip2_abiotic_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocmip2_abiotic_start -
          -
          -
          -
          -
        16. -
        17. - -

          ocmip2_abiotic_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        18. -
        19. - -

          ocmip2_abiotic_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        20. -
        21. - -

          ocmip2_abiotic_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        22. -
        23. - -

          ocmip2_abiotic_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations -
          -
          -
          -
          -
        24. -
        25. - -

          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) -
          -
          -
          -
          -
        26. -
        27. - -

          ocmip2_abiotic_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
          -
          -
          -
          -
        28. -
        29. - -

          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 -
          -
          -
          -
          -
        30. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Abiotic/HOWTO-Abiotic.html -
        2. -
        3. - Press, W. H., S. A. Teukosky, W. T. Vetterling, B. P. Flannery, 1992. - Numerical Recipes in FORTRAN, Second Edition, Cambridge University Press. -
        4. -
        5. - 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. -
        6. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  Richard D. Slater - -
        -Reviewers:  John P. Dunne - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          ocmip2_biotic_bbc

          -
          -
          -DESCRIPTION -
          -
          - calculate the surface boundary conditions -
          -
          -
          -
          -
        6. -
        7. - -

          ocmip2_biotic_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various BIOTIC quantities for this run. -
          -
          -
          -
          -
        8. -
        9. - -

          ocmip2_biotic_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        10. -
        11. - -

          ocmip2_biotic_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions -
          -
          -
          -
          -
        12. -
        13. - -

          ocmip2_biotic_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        14. -
        15. - -

          ocmip2_biotic_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
          -
          -
          -
          -
        16. -
        17. - -

          ocmip2_biotic_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocmip2_biotic_start -
          -
          -
          -
          -
        18. -
        19. - -

          ocmip2_biotic_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        20. -
        21. - -

          ocmip2_biotic_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        22. -
        23. - -

          ocmip2_biotic_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        24. -
        25. - -

          ocmip2_biotic_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations -
          -
          -
          -
          -
        26. -
        27. - -

          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) -
          -
          -
          -
          -
        28. -
        29. - -

          ocmip2_biotic_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
          -
          -
          -
          -
        30. -
        31. - -

          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. -
          -
          -
          -
          -
        32. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Biotic/HOWTO-Biotic.html -
        2. -
        3. - Press, W. H., S. A. Teukosky, W. T. Vetterling, B. P. Flannery, 1992. - Numerical Recipes in FORTRAN, Second Edition, Cambridge University Press. -
        4. -
        5. - 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. -
        6. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  Richard D. Slater - -
        -Reviewers:  John P. Dunne - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          ocmip2_cfc_bbc

          -
          -
          -DESCRIPTION -
          -
          - calculate the surface boundary conditions -
          -
          -
          -
          -
        4. -
        5. - -

          ocmip2_cfc_end

          -
          -
          -DESCRIPTION -
          -
          - Clean up various CFC quantities for this run. -
          -
          -
          -
          -
        6. -
        7. - -

          ocmip2_cfc_sbc

          -
          -
          -DESCRIPTION -
          -
          - Calculate the surface boundary conditions -
          -
          -
          -
          -
        8. -
        9. - -

          ocmip2_cfc_flux_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
          -
          -
          -
          -
        10. -
        11. - -

          ocmip2_cfc_init

          -
          -
          -DESCRIPTION -
          -
          - Set up any extra fields needed by the tracer packages - - Save pointers to various "types", such as Grid and Domains. -
          -
          -
          -
          -
        12. -
        13. - -

          ocmip2_cfc_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations - - Note: this subroutine should be merged into ocmip2_cfc_start -
          -
          -
          -
          -
        14. -
        15. - -

          ocmip2_cfc_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        16. -
        17. - -

          ocmip2_cfc_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        18. -
        19. - -

          ocmip2_cfc_avg_sfc

          -
          -
          -DESCRIPTION -
          -
          - Sum surface fields for flux calculations -
          -
          -
          -
          -
        20. -
        21. - -

          ocmip2_cfc_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Initialize surface fields for flux calculations -
          -
          -
          -
          -
        22. -
        23. - -

          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) -
          -
          -
          -
          -
        24. -
        25. - -

          ocmip2_cfc_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
          -
          -
          -
          -
        26. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/CFC/HOWTO-CFC.html -
        2. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  Richard D. Slater - -
        -Reviewers:  John P. Dunne - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
          -
        1. - -

          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. - -
          -
          -
          -
          -
        2. -
        3. - -

          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. - -
          -
          -
          -
          -
        4. -
        5. - -

          drtsafe

          -
          -
          -DESCRIPTION -
          -
          - File taken from Numerical Recipes. Modified R. M. Key 4/94 -
          -
          -
          -
          -
        6. -
        7. - -

          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 -
          -
          -
          -
          -
        8. -
        - - - - - - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          allocate_arrays

          -
          -
          -DESCRIPTION -
          -
          - Dynamically allocate arrays -
          -
          -
          -
          -
        2. -
        3. - -

          ocmip2_he_bbc

          -
          -
          -DESCRIPTION -
          -
          - Called each time-step - calculate the bottom boundary conditions -
          -
          -
          -
          -
        4. -
        5. - -

          ocmip2_he_end

          -
          -
          -DESCRIPTION -
          -
          - Called once at the end of the run - Clean up various HE quantities for this run. -
          -
          -
          -
          -
        6. -
        7. - -

          ocmip2_he_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        8. -
        9. - -

          ocmip2_he_sbc

          -
          -
          -DESCRIPTION -
          -
          - Called each time-step - Calculate the surface boundary conditions -
          -
          -
          -
          -
        10. -
        11. - -

          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 -
          -
          -
          -
          -
        12. -
        13. - -

          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. -
          -
          -
          -
          -
        14. -
        15. - -

          ocmip2_he_init_sfc

          -
          -
          -DESCRIPTION -
          -
          - Called once at the beginning of the run - Initialize surface fields for flux calculations - -
          -
          -
          -
          -
        16. -
        17. - -

          ocmip2_he_sum_sfc

          -
          -
          -DESCRIPTION -
          -
          - Called for FMS coupler - ocean_tpm_sum_sfc: Accumulate data for the coupler - Sum surface fields for flux calculations -
          -
          -
          -
          -
        18. -
        19. - -

          ocmip2_he_zero_sfc

          -
          -
          -DESCRIPTION -
          -
          - Zero out the fields for the coupler to allow - for accumulation for the next time period -
          -
          -
          -
          -
        20. -
        21. - -

          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 -
          -
          -
          -
          -
        22. -
        23. - -

          ocmip2_he_sfc_end

          -
          -
          -DESCRIPTION -
          -
          - Called for FMS coupler - ocean_tpm_sfc_end: Save out fields for the restart. -
          -
          -
          -
          -
        24. -
        25. - -

          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. -
          -
          -
          -
          -
        26. -
        27. - -

          ocmip2_he_start

          -
          -
          -DESCRIPTION -
          -
          - Initialize variables, read in namelists, calculate constants - for a given run and allocate diagnostic arrays -
          -
          -
          -
          -
        28. -
        29. - -

          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 -
          -
          -
          -
          -
        30. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/Helium/HOWTO-Helium.html -
        2. -
        -
        -
        - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          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. -
          -
          -
          -
          -
        2. -
        3. - -

          init_blob_thickness

          -
          -
          -DESCRIPTION -
          -
          - Initialises the L_system thickness, based on the existing blobs -
          -
          -
          -
          -
        4. -
        5. - -

          ocean_blob_update

          -
          -
          -DESCRIPTION -
          -
          - Updates the Lagrangian blobs by calling routines that run during the - explicit in time part of the time step. -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          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. -
          -
          -
          -
          -
        10. -
        11. - -

          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. - -
          -
          -
          -
          -
        12. -
        13. - -

          ocean_blob_implicit

          -
          -
          -DESCRIPTION -
          -
          - Updates the Lagrangian blobs by calling routines that run during the - implicit in time part of the time step. -
          -
          -
          -
          -
        14. -
        15. - -

          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. -
          -
          -
          -
          -
        16. -
        17. - -

          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. -
          -
          -
          -
          -
        18. -
        19. - -

          ocean_blob_end

          -
          -
          -DESCRIPTION -
          -
          - Writes restarts and do checksums for the blobs at the end of a run. -
          -
          -
          -
          -
        20. -
        21. - -

          write_all_blobs

          -
          -
          -DESCRIPTION -
          -
          - A convenient subroutine for debugging that dumps blob details from - every list -
          -
          -
          -
          -
        22. -
        23. - -

          entrainment_checksum

          -
          -
          -DESCRIPTION -
          -
          - Do the entrainment checksums -
          -
          -
          -
          -
        24. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - S.M. Griffies, Elements of MOM4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory -
        2. -
        -
        -
        - -
        -
        -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 @@ - - - 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 - 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 @@ - - - -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_blob_diag_init

          -
          -
          -DESCRIPTION -
          -
          - Initialises the blob diagnostic module. -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          varid

          -
          -
          -DESCRIPTION -
          -
          - Reads the variable id of a netcdf file. -
          -
          -
          -
          -
        6. -
        7. - -

          blob_diag_end

          -
          -
          -DESCRIPTION -
          -
          - -
          -
          -
          -
          -
        8. -
        9. - -

          write_blobs

          -
          -
          -DESCRIPTION -
          -
          - Write the diagnostics of individual blobs. -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          create_netcdf_file

          -
          -
          -DESCRIPTION -
          -
          - Creates a new netcdf file. -
          -
          -
          -
          -
        14. -
        15. - -

          open_netcdf_file

          -
          -
          -DESCRIPTION -
          -
          - Opens an existing netcdf file. -
          -
          -
          -
          -
        16. -
        17. - -

          close_netcdf_file

          -
          -
          -DESCRIPTION -
          -
          - Closes an existing netcdf file. -
          -
          -
          -
          -
        18. -
        - - - - - - -
        -
        -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 @@ - - - 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. - 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 @@ - - - -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          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. -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          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. -
          -
          -
          -
          -
        6. -
        7. - -

          transfer_free_to_bottom

          -
          -
          -DESCRIPTION -
          -
          - Takes free blobs that have interacted with topography and turns them - into bottom blobs. -
          -
          -
          -
          -
        8. -
        9. - -

          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. -
          -
          -
          -
          -
        10. -
        11. - -

          blob_dynamic_bottom_end

          -
          -
          -DESCRIPTION -
          -
          - Clears memory to give a nice clean ending to the run. -
          -
          -
          -
          -
        12. -
        13. - -

          packbuffer

          -
          -
          -DESCRIPTION -
          -
          - Packs a buffer with all the information needed to send a blob from - one PE to another. -
          -
          -
          -
          -
        14. -
        15. - -

          unpackbuffer

          -
          -
          -DESCRIPTION -
          -
          - Unpacks a received buffer. -
          -
          -
          -
          -
        16. -
        17. - -

          increase_buffer

          -
          -
          -DESCRIPTION -
          -
          - Increases the buffer size for sending blobs from one PE to another. -
          -
          -
          -
          -
        18. -
        19. - -

          send_buffer

          -
          -
          -DESCRIPTION -
          -
          - Sends a buffer to an adjoining PE -
          -
          -
          -
          -
        20. -
        21. - -

          receive_buffer

          -
          -
          -DESCRIPTION -
          -
          - Receives a buffer from an adjoining PE -
          -
          -
          -
          -
        22. -
        23. - -

          clear_buffer

          -
          -
          -DESCRIPTION -
          -
          - Clears the contents of a buffer -
          -
          -
          -
          -
        24. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - Price, J.F., Baringer, M.O'N. (1994) Outflows and deep water production - by marginal seas. Progress in Oceanography 33(3), 161-200. -
        2. -
        3. - 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. -
        4. -
        5. - Bogacki, P., Shampine, L.F. (1989) A 3(2) pair of Runge-Kutta formulas. - Applied Mathematical Letters 2(4), 321-325. -
        6. -
        7. - 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. -
        8. -
        -
        -
        - -
        -
        -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 @@ - - - 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 - 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 @@ - - - -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          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. -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          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. -
          -
          -
          -
          -
        6. -
        7. - -

          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. -
          -
          -
          -
          -
        8. -
        9. - -

          transfer_bottom_to_free

          -
          -
          -DESCRIPTION -
          -
          - Takes bottom blobs that have separated from the bottom boundary and - turns it into a free blob. -
          -
          -
          -
          -
        10. -
        11. - -

          blob_dynamic_free_end

          -
          -
          -DESCRIPTION -
          -
          - Clears memory to give a nice clean ending to the run. -
          -
          -
          -
          -
        12. -
        13. - -

          packbuffer

          -
          -
          -DESCRIPTION -
          -
          - Packs a buffer with all the information needed to send a blob from - one PE to another. -
          -
          -
          -
          -
        14. -
        15. - -

          unpackbuffer

          -
          -
          -DESCRIPTION -
          -
          - Unpacks a received buffer. -
          -
          -
          -
          -
        16. -
        17. - -

          increase_buffer

          -
          -
          -DESCRIPTION -
          -
          - Increases the buffer size for sending blobs from one PE to another. -
          -
          -
          -
          -
        18. -
        19. - -

          send_buffer

          -
          -
          -DESCRIPTION -
          -
          - Sends a buffer to an adjoining PE -
          -
          -
          -
          -
        20. -
        21. - -

          receive_buffer

          -
          -
          -DESCRIPTION -
          -
          - Receives a buffer from an adjoining PE -
          -
          -
          -
          -
        22. -
        23. - -

          clear_buffer

          -
          -
          -DESCRIPTION -
          -
          - Clears the contents of a buffer -
          -
          -
          -
          -
        24. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - Bogacki, P., Shampine, L.F., (1989) A 3(2) pair of Runge-Kutta formulas. - Applied Mathematical Letters 2(4), 321-325. -
        2. -
        3. - 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. -
        4. -
        5. - 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. -
        6. -
        7. - Marshall, J., Schott, F. (1999) Open-ocean convection: Observations, theory, - and models. Reviews of Geophysics 37(1), 1-64. -
        8. -
        -
        -
        - -
        -
        -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 @@ - - - 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 - 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 @@ - - - -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          blob_static_bottom_init

          -
          -
          -DESCRIPTION -
          -
          - Initialises the static bottom blob module. -
          -
          -
          -
          -
        2. -
        3. - -

          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). -
          -
          -
          -
          -
        4. -
        5. - -

          blob_static_bottom_end

          -
          -
          -DESCRIPTION -
          -
          - Does what is necessary to finish the run. -
          -
          -
          -
          -
        6. -
        7. - -

          allocate_buffer

          -
          -
          -DESCRIPTION -
          -
          - Increases the buffer size for sending blobs from one PE to another. -
          -
          -
          -
          -
        8. -
        9. - -

          increase_buffer

          -
          -
          -DESCRIPTION -
          -
          - Increases the buffer size for sending blobs from one PE to another. -
          -
          -
          -
          -
        10. -
        11. - -

          send_buffer

          -
          -
          -DESCRIPTION -
          -
          - Sends a buffer to an adjoining PE -
          -
          -
          -
          -
        12. -
        13. - -

          receive_buffer

          -
          -
          -DESCRIPTION -
          -
          - Receives a buffer from an adjoining PE -
          -
          -
          -
          -
        14. -
        15. - -

          clear_buffer

          -
          -
          -DESCRIPTION -
          -
          - Clears the contents of a buffer -
          -
          -
          -
          -
        16. -
        17. - -

          deallocate_buffer

          -
          -
          -DESCRIPTION -
          -
          - Deallocates memory from a buffer (usually at the end of a run). -
          -
          -
          -
          -
        18. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - 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. -
        2. -
        3. - S.M. Griffies, Elements of mom4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory -
        4. -
        5. - 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 -
        6. -
        -
        -
        - -
        -
        -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 @@ - - - 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). - 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 @@ - - - -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          blob_static_free_init

          -
          -
          -DESCRIPTION -
          -
          - Initialises the free static schemes. -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          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. -
          -
          -
          -
          -
        6. -
        7. - -

          blob_static_free_end

          -
          -
          -DESCRIPTION -
          -
          - Ends the free static module. -
          -
          -
          -
          -
        8. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - S.M. Griffies, Elements of mom4p1 (2009) - NOAA/Geophysical Fluid Dynamics Laboratory -
        2. -
        3. - Cox, M.D., 1984, A Primitive Equation, 3-Dimensional Model of the - Ocean. NOAA/Geophysical Fluid Dynamics Laboratory -
        4. -
        -
        -
        - -
        -
        -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 @@ - - - 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. - 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 @@ - - - -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          blob_util_init

          -
          -
          -DESCRIPTION -
          -
          - Initialises this module. -
          -
          -
          -
          -
        2. -
        3. - -

          blob_chksum

          -
          -
          -DESCRIPTION -
          -
          - Performs global sums and checksums for all blob types (for diagnostic - purposes). -
          -
          -
          -
          -
        4. -
        5. - -

          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. - -
          -
          -
          -
          -
        6. -
        7. - -

          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. -
          -
          -
          -
          -
        8. -
        9. - -

          write_blobs

          -
          -
          -DESCRIPTION -
          -
          - Dumps most of the information carried around by blobs, for all blobs - in a particular list. Useful for debugging. -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          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. -
          -
          -
          -
          -
        14. -
        15. - -

          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. -
          -
          -
          -
          -
        16. -
        17. - -

          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. -
          -
          -
          -
          -
        18. -
        19. - -

          put_att

          -
          -
          -DESCRIPTION -
          -
          - Writes an attribute to a netcdf file. -
          -
          -
          -
          -
        20. -
        21. - -

          inq_var

          -
          -
          -DESCRIPTION -
          -
          - Gets the variable identifier from a netcdf file. -
          -
          -
          -
          -
        22. -
        23. - -

          get_double

          -
          -
          -DESCRIPTION -
          -
          - Gets the value of a "double" variable from a netcdf file -
          -
          -
          -
          -
        24. -
        25. - -

          get_int

          -
          -
          -DESCRIPTION -
          -
          - Gets the value of an integer variable from a netcdf file -
          -
          -
          -
          -
        26. -
        27. - -

          put_double

          -
          -
          -DESCRIPTION -
          -
          - Writes the value of a "double" variable to a netcdf file -
          -
          -
          -
          -
        28. -
        29. - -

          put_int

          -
          -
          -DESCRIPTION -
          -
          - Writes the value of an integer variable to a netcdf file -
          -
          -
          -
          -
        30. -
        31. - -

          def_var

          -
          -
          -DESCRIPTION -
          -
          - Defines a netcdf variable -
          -
          -
          -
          -
        32. -
        33. - -

          give_error_code

          -
          -
          -DESCRIPTION -
          -
          - Gives error descriptions for netcdf calls. -
          -
          -
          -
          -
        34. -
        35. - -

          hashfun

          -
          -
          -DESCRIPTION -
          -
          - Calculates the hash -
          -
          -
          -
          -
        36. -
        37. - -

          blob_util_end

          -
          -
          -DESCRIPTION -
          -
          - Does what is necessary to shut down the module. -
          -
          -
          -
          -
        38. -
        39. - -

          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). -
          -
          -
          -
          -
        40. -
        41. - -

          check_kcell

          -
          -
          -DESCRIPTION -
          -
          - Searches for which (vertical) grid cell a blob resides in). -
          -
          -
          -
          -
        42. -
        43. - -

          kill_blob

          -
          -
          -DESCRIPTION -
          -
          - Kills a blob by returning all of its remaining properties to the E - system. -
          -
          -
          -
          -
        44. -
        45. - -

          free_blob_memory

          -
          -
          -DESCRIPTION -
          -
          - Frees the heap memory taken up by a blob. -
          -
          -
          -
          -
        46. -
        47. - -

          allocate_interaction_memory

          -
          -
          -DESCRIPTION -
          -
          - Allocates the history arrays for a blob (only used when - bitwise_reproduction=.true. in the ocean_blob_nml). -
          -
          -
          -
          -
        48. -
        49. - -

          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. -
          -
          -
          -
          -
        50. -
        51. - -

          interp_tcoeff

          -
          -
          -DESCRIPTION -
          -
          - Used for the horizontal interpolation of T grid variables. The - routine returns coefficients required for inverse distance - weighting (Shephard, 1968). -
          -
          -
          -
          -
        52. -
        53. - -

          interp_ucoeff

          -
          -
          -DESCRIPTION -
          -
          - Used for the horizontal interpolation of U grid variables. The - routine returns coefficients required for inverse distance - weighting (Shephard, 1968). -
          -
          -
          -
          -
        54. -
        55. - -

          check_cyclic

          -
          -
          -DESCRIPTION -
          -
          - Checks and adjusts blob position and grid cell index - for cylclic/periodic domains, as well as - the Murray (1996) tripolar grid. -
          -
          -
          -
          -
        56. -
        - - - - - - -
        -

        REFERENCES

        - -
        -
          -
        1. - Cormen, T. H, Leiserson, C. E. Rivest, R. L., Stein, C. (2001) Introduction - to Algorithms. The MIT Press. -
        2. -
        3. - 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. -
        4. -
        5. - Murray, R. J. (1996) Explicit generation of orthogonal grids for - ocean models. Journal of Computational Physics 126, 251-273. -
        6. -
        -
        -
        - -
        -
        -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 @@ - - - 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. - 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 @@ - - - -Module ocean_advection_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
        -

        Module ocean_advection_velocity_mod

        - - -
        -Contact:  S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_advection_velocity_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the advection velocity module -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_advection_velocity

          -
          -
          -DESCRIPTION -
          -
          - Compute thickness weighted and density weighted advection velocity - components for the B-grid on the T-cells and U-cells. -
          -
          -
          -
          -
        4. -
        5. - -

          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. -
          -
          -
          -
          -
        6. -
        7. - -

          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. -
          -
          -
          -
          -
        8. -
        9. - -

          inflow_nboundary_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the advection velocity used for specifying a nonzero - southward inflow introduced to the domain from the northern boundary. - -
          -
          -
          -
          -
        10. -
        11. - -

          ocean_advection_velocity_end

          -
          -
          -DESCRIPTION -
          -
          - Write a restart if necessary - -
          -
          -
          -
          -
        12. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
        2. -
        3. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
        4. -
        5. - S.M. Griffies: Elements of MOM (2012) -
        6. -
        -
        -
        - - -
        -

        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

        - - - - - -
        -

        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

        - -
          -
        1. - -

          ocean_barotropic_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the barotropic module -
          -
          -
          -
          -
        2. -
        3. - -

          barotropic_diag_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize diagnostic indices for the module. - - Diagnose the static arrays. -
          -
          -
          -
          -
        4. -
        5. - -

          eta_terms_diagnose_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize diagnostic indices for the eta_terms related diagnostics. -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          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. - -
          -
          -
          -
          -
        10. -
        11. - -

          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. - -
          -
          -
          -
          -
        12. -
        13. - -

          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. - -
          -
          -
          -
          -
        14. -
        15. - -

          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. - -
          -
          -
          -
          -
        16. -
        17. - -

          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. - -
          -
          -
          -
          -
        18. -
        19. - -

          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. - -
          -
          -
          -
          -
        20. -
        21. - -

          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. - -
          -
          -
          -
          -
        22. -
        23. - -

          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. - -
          -
          -
          -
          -
        24. -
        25. - -

          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. - -
          -
          -
          -
          -
        26. -
        27. - -

          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. -
          -
          -
          -
          -
        28. -
        29. - -

          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. - -
          -
          -
          -
          -
        30. -
        31. - -

          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. - -
          -
          -
          -
          -
        32. -
        33. - -

          barotropic_integrals

          -
          -
          -DESCRIPTION -
          -
          - Compute area averaged fresh water and surface height and ocean mass. -
          -
          -
          -
          -
        34. -
        35. - -

          barotropic_energy

          -
          -
          -DESCRIPTION -
          -
          - Compute energetics of vertically integrated flow. -
          -
          -
          -
          -
        36. -
        37. - -

          read_barotropic

          -
          -
          -DESCRIPTION -
          -
          - Read in external mode fields from restart file. -
          -
          -
          -
          -
        38. -
        39. - -

          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. - -
          -
          -
          -
          -
        40. -
        41. - -

          ocean_barotropic_end

          -
          -
          -DESCRIPTION -
          -
          - Write out external mode fields to restart file. -
          -
          -
          -
          -
        42. -
        43. - -

          maximum_convrhoud

          -
          -
          -DESCRIPTION -
          -
          - Compute maximum convergence(rho_ud,rho_vd). -
          -
          -
          -
          -
        44. -
        45. - -

          barotropic_chksum

          -
          -
          -DESCRIPTION -
          -
          - Compute checksum for external mode fields. -
          -
          -
          -
          -
        46. -
        47. - -

          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. - -
          -
          -
          -
          -
        48. -
        49. - -

          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. - -
          -
          -
          -
          -
        50. -
        51. - -

          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. - -
          -
          -
          -
          -
        52. -
        53. - -

          eta_check

          -
          -
          -DESCRIPTION -
          -
          - Perform diagnostic check on top cell thickness. Useful when - when use GEOPOTENTIAL vertical coordinate. - -
          -
          -
          -
          -
        54. -
        55. - -

          tidal_forcing_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize fields needed for lunar and solar tidal forcing. -
          -
          -
          -
          -
        56. -
        57. - -

          geoid_forcing_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize fields needed for modifying the geoid, relative to the - standard geoid. -
          -
          -
          -
          -
        58. -
        59. - -

          get_tidal_forcing

          -
          -
          -DESCRIPTION -
          -
          - Compute equilibrium tidal forcing. -
          -
          -
          -
          -
        60. -
        61. - -

          ideal_initialize_eta

          -
          -
          -DESCRIPTION -
          -
          - Idealized initial condition for eta. -
          -
          -
          -
          -
        62. -
        63. - -

          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. -
          -
          -
          -
          -
        64. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - 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 -
        2. -
        3. - S.M. Griffies - Fundamentals of Ocean Climate Models - Princeton University Press (2004) -
        4. -
        5. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) -
        6. -
        7. - S.M. Griffies: Elements of MOM (2012) -
        8. -
        -
        -
        - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_bbc_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the bottom boundary condition module -
          -
          -
          -
          -
        2. -
        3. - -

          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. - -
          -
          -
          -
          -
        4. -
        5. - -

          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 - -
          -
          -
          -
          -
        6. -
        7. - -

          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 - -
          -
          -
          -
          -
        8. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
        2. -
        3. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
        4. -
        5. - S.M. Griffies, 2012: Elements of MOM -
        6. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  A. Rosati -,  - S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_coriolis_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the Coriolis module. -
          -
          -
          -
          -
        2. -
        3. - -

          coriolis_force_bgrid

          -
          -
          -DESCRIPTION -
          -
          - Compute thickness and density weighted acceleration due to Coriolis - force on a B-grid. -
          -
          -
          -
          -
        4. -
        5. - -

          coriolis_force_bgrid_implicit

          -
          -
          -DESCRIPTION -
          -
          - Contributions to thickness weighted and density weighted - acceleration from time-implicit Coriolis force. -
          -
          -
          -
          -
        6. -
        7. - -

          coriolis_force_cgrid

          -
          -
          -DESCRIPTION -
          -
          - - Compute thickness and density weighted acceleration due to Coriolis - force on a C-grid. - -
          -
          -
          -
          -
        8. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
        2. -
        3. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
        4. -
        5. - S.M. Griffies: Elements of MOM (2012) -
        6. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  S.M. Griffies -,  - Russell Fiedler - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_density_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the density module -
          -
          -
          -
          -
        2. -
        3. - -

          density_diagnostics_init

          -
          -
          -DESCRIPTION -
          -
          - Register the diagnostic fields. -
          -
          -
          -
          -
        4. -
        5. - -

          density_coeffs_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the EOS coefficients, and write some test values. -
          -
          -
          -
          -
        6. -
        7. - -

          ocean_density_diag

          -
          -
          -DESCRIPTION -
          -
          - Diagnostic ocean density fields: neutral density and potential density. - Also send some diagnostics to diagnostic manager. -
          -
          -
          -
          -
        8. -
        9. - -

          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. - -
          -
          -
          -
          -
        10. -
        11. - -

          update_ocean_density

          -
          -
          -DESCRIPTION -
          -
          - Diagnose pressure_at_depth and ocean density. - Also send some diagnostics to diagnostic manager. -
          -
          -
          -
          -
        12. -
        13. - -

          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). - -
          -
          -
          -
          -
        14. -
        15. - -

          density_level

          -
          -
          -DESCRIPTION -
          -
          - Compute density at a particular k-level. - - Note that pressure here is - - sea pressure = absolute pressure - press_standard (dbars) - -
          -
          -
          -
          -
        16. -
        17. - -

          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 - -
          -
          -
          -
          -
        18. -
        19. - -

          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. - -
          -
          -
          -
          -
        20. -
        21. - -

          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. - -
          -
          -
          -
          -
        22. -
        23. - -

          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. - -
          -
          -
          -
          -
        24. -
        25. - -

          compute_density_diagnostics

          -
          -
          -DESCRIPTION -
          -
          - Diagnostics related to density. -
          -
          -
          -
          -
        26. -
        27. - -

          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. - -
          -
          -
          -
          -
        28. -
        29. - -

          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 -
          -
          -
          -
          -
        30. -
        31. - -

          density_point

          -
          -
          -DESCRIPTION -
          -
          - Compute density at a single model grid point. - - Note that pressure here is - - sea pressure = absolute pressure - press_standard (dbars) - -
          -
          -
          -
          -
        32. -
        33. - -

          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) - -
          -
          -
          -
          -
        34. -
        35. - -

          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 - -
          -
          -
          -
          -
        36. -
        37. - -

          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) - -
          -
          -
          -
          -
        38. -
        39. - -

          cabbeling_thermobaricity

          -
          -
          -DESCRIPTION -
          -
          - Diagnostic sends for cabbeling and thermobaricity parameters. - - Pressure here is - sea pressure = absolute press - press_standard (dbars) - -
          -
          -
          -
          -
        40. -
        41. - -

          calc_cabbeling_thermobaricity

          -
          -
          -DESCRIPTION -
          -
          - Compute cabbeling and thermobaricity parameters, as defined in - McDougall (1987). - - Pressure here is - sea pressure = absolute press - press_standard (dbars) - -
          -
          -
          -
          -
        42. -
        43. - -

          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. -
          -
          -
          -
          -
        44. -
        45. - -

          density_delta_sfc

          -
          -
          -DESCRIPTION -
          -
          - rho(1)-rho(k+1) for all i,j. - - Of use for KPP scheme. -
          -
          -
          -
          -
        46. -
        47. - -

          ocean_density_end

          -
          -
          -DESCRIPTION -
          -
          - - Write density and pressure_at_depth to a restart. - -
          -
          -
          -
          -
        48. -
        49. - -

          ocean_density_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        50. -
        51. - -

          ocean_density_chksum

          -
          -
          -DESCRIPTION -
          -
          - Compute checksums for density. -
          -
          -
          -
          -
        52. -
        53. - -

          compute_buoyfreq

          -
          -
          -DESCRIPTION -
          -
          - - Diagnose the buoyancy frequency, both at T-points and at - vertical interfaces of T-cells. - - Author: Stephen.Griffies - -
          -
          -
          -
          -
        54. -
        55. - -

          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 -
          -
          -
          -
          -
        56. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - 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. -
        2. -
        3. - 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. -
        4. -
        5. - 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. -
        6. -
        7. - 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. -
        8. -
        9. - McDougall and Jackett (2005) - The material derivative of neutral density - Journal of Marine Research, vol 63, pages 159-185. -
        10. -
        11. - Feistel (2003), A new extended Gibbs thermodynamic potential - of seawater. Progress in Oceanography. vol 58, pages 43-114. -
        12. -
        13. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
        14. -
        15. - 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 -
        16. -
        17. - T. McDougall (1987) - Cabbeling, Thermobaricity, and water mass conversion - JGR vol 92, pages 5448-5464 -
        18. -
        -
        -
        - - -
        -

        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

        - - -
        -Contact:  Matthew Harrison - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_domain_init

          -
          -
          -DESCRIPTION -
          -
          - Initialise the domain module. -
          -
          -
          -
          -
        2. -
        3. - -

          set_ocean_domain

          -
          -
          -DESCRIPTION -
          -
          - For setting the ocean domain layout and associated parameters. -
          -
          -
          -
          -
        4. -
        5. - -

          get_local_indices

          -
          -
          -DESCRIPTION -
          -
          - For getting local indices from domain derived type. -
          -
          -
          -
          -
        6. -
        7. - -

          get_domain_offsets

          -
          -
          -DESCRIPTION -
          -
          - For getting domain offsets from domain derived type. -
          -
          -
          -
          -
        8. -
        9. - -

          get_active_indices

          -
          -
          -DESCRIPTION -
          -
          - For getting active domain indices from domain derived type. -
          -
          -
          -
          -
        10. -
        11. - -

          get_global_indices

          -
          -
          -DESCRIPTION -
          -
          - For getting global indices from domain derived type. -
          -
          -
          -
          -
        12. -
        13. - -

          reduce_active_domain

          -
          -
          -DESCRIPTION -
          -
          - For getting reducing the active domain -
          -
          -
          -
          -
        14. -
        15. - -

          get_halo_sizes

          -
          -
          -DESCRIPTION -
          -
          - For getting halo sizes from domain derived type. -
          -
          -
          -
          -
        16. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) -
        2. -
        -
        -
        - -
        -
        -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="set_ocean_vgrid_arrays" +!####################################################################### +! +! +! +! 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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_grids_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the grids module. -
          -
          -
          -
          -
        2. -
        3. - -

          set_ocean_grid_size

          -
          -
          -DESCRIPTION -
          -
          - Set the ocean grid size. Model expects the grid specification file - to be called grid_spec.nc. -
          -
          -
          -
          -
        4. -
        5. - -

          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 - -
          -
          -
          -
          -
        6. -
        7. - -

          set_ocean_vgrid_arrays

          -
          -
          -DESCRIPTION -
          -
          - Compute vertical (and some horizontal) grids for ocean model. - Also compute axes information for diagnostic manager. -
          -
          -
          -
          -
        8. -
        9. - -

          axes_info

          -
          -
          -DESCRIPTION -
          -
          - Set up axes definitions. -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - S.M. Griffies, M.J. Harrison, A. Rosati, and R.C. Pacanowski - A Technical Guide to MOM4 (2003) -
        2. -
        -
        -
        - -
        -
        -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

        - -
          -
        1. - -

          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. -
          -
          -
          -
          -
        2. -
        3. - -

          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. -
          -
          -
          -
          -
        4. -
        5. - -

          get_ocean_grid_size

          -
          -
          -DESCRIPTION -
          -
          - Obtain the ocean grid size. -
          -
          -
          -
          -
        6. -
        7. - -

          get_ocean_domain

          -
          -
          -DESCRIPTION -
          -
          - Obtain the ocean domain size. -
          -
          -
          -
          -
        8. -
        9. - -

          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. -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          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. -
          -
          -
          -
          -
        14. -
        15. - -

          ocean_model_restart

          -
          -
          -DESCRIPTION -
          -
          - write out restart file. -
          -
          -
          -
          -
        16. -
        17. - -

          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. - -
          -
          -
          -
          -
        18. -
        19. - -

          mom4_get_Tsurf

          -
          -
          -DESCRIPTION -
          -
          - Return the surface temperature in degrees K -
          -
          -
          -
          -
        20. -
        21. - -

          mom4_get_Ssurf

          -
          -
          -DESCRIPTION -
          -
          - Return the surface salinity in psu -
          -
          -
          -
          -
        22. -
        23. - -

          mom4_get_thickness

          -
          -
          -DESCRIPTION -
          -
          - Return thickness (in meters) of each layer. -
          -
          -
          -
          -
        24. -
        25. - -

          mom4_get_density

          -
          -
          -DESCRIPTION -
          -
          - Return density (in kg/m^3). -
          -
          -
          -
          -
        26. -
        27. - -

          mom4_get_prog_tracer

          -
          -
          -DESCRIPTION -
          -
          - Return prognostic tracer data. -
          -
          -
          -
          -
        28. -
        29. - -

          mom4_get_temperature_index

          -
          -
          -DESCRIPTION -
          -
          - Return temperature index from prognostic tracer table, which can - then be used to extract data. -
          -
          -
          -
          -
        30. -
        31. - -

          mom4_get_salinity_index

          -
          -
          -DESCRIPTION -
          -
          - Return salt index from prognostic tracer table, which can - then be used to extract data. -
          -
          -
          -
          -
        32. -
        33. - -

          mom4_get_dimensions

          -
          -
          -DESCRIPTION -
          -
          - Return dimensions of data in compute domain -
          -
          -
          -
          -
        34. -
        35. - -

          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. -
          -
          -
          -
          -
        36. -
        37. - -

          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. -
          -
          -
          -
          -
        38. -
        39. - -

          mom4_U_to_T_2d

          -
          -
          -DESCRIPTION -
          -
          - Interpolate (u,v) velocity components from U (B-grid) to - T points (A-grid). -
          -
          -
          -
          -
        40. -
        41. - -

          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]
          -
          -
          -
          -
        42. -
        43. - -

          mom4_get_diag_axes

          -
          -
          -DESCRIPTION -
          -
          - Return axes indices for diag manager. -
          -
          -
          -
          -
        44. -
        45. - -

          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]
          -
          -
          -
          -
        46. -
        47. - -

          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]
          -
          -
          -
          -
        48. -
        49. - -

          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]
          -
          -
          -
          -
        50. -
        51. - -

          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]
          -
          -
          -
          -
        52. -
        - - - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          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(:,:,:,:)]
          -
          -
          -
          -
        2. -
        3. - -

          obc_zero_boundary

          -
          -
          -
          -
          -DESCRIPTION -
          -
          - set field at open boundaries to zero. -
          -
          -
          -
          -INPUT/OUTPUT -
          -
          - - - - -
          field    - field to be set to zero on the boundary -
          -
          -
          -
          -
        4. -
        5. - -

          ocean_obc_enhance_visc_back

          -
          -
          -
          -
          -DESCRIPTION -
          -
          - enhance viscosity near open boundaries -
          -
          -
          -
          -
        6. -
        7. - -

          ocean_obc_enhance_diff_back

          -
          -
          -
          -
          -DESCRIPTION -
          -
          - enhance diffusion near open boundaries -
          -
          -
          -
          -
        8. -
        9. - -

          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]
          -
          -
          -
          -
        10. -
        11. - -

          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]
          -
          -
          -
          -
        12. -
        13. - -

          ocean_obc_prepare

          -
            subroutine ocean_obc_prepare(Time, Thickness, Ext_mode, T_prog)
          -
          -
          -DESCRIPTION -
          -
          - Prepares OBC - -
          -
          -
          -
          -
        14. -
        15. - -

          -
            subroutine ocean_obc_surface_height(Time, Ext_mode, dtime)
          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        16. -
        17. - -

          ocean_obc_adjust_divud

          -
            subroutine ocean_obc_adjust_divud(divud)
          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -INPUT/OUTPUT -
          -
          - - - - -
          divud    -
             [real, dimension(isd:,jsd:)]
          -
          -
          -
          -
        18. -
        19. - -

          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)]
          -
          -
          -
          -
        20. -
        21. - -

          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]
          -
          -
          -
          -
        22. -
        23. - -

          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]
          -
          -
          -
          -
        24. -
        25. - -

          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]
          -
          -
          -
          -
        26. -
        27. - -

          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]
          -
          -
          -
          -
        28. -
        29. - -

          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]
          -
          -
          -
          -
        30. -
        31. - -

          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]
          -
          -
          -
          -
        32. -
        33. - -

          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:,:,:)]
          -
          -
          -
          -
        34. -
        35. - -

          ocean_obc_check_topog

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        36. -
        37. - -

          ocean_obc_set_mask

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        38. -
        39. - -

          ocean_obc_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        40. -
        41. - -

          ocean_obc_end

          -
          -
          -DESCRIPTION -
          -
          - Destructor routine. Release memory. -
          -
          -
          -
          -OUTPUT -
          -
          - - - - -
          have_obc    - Contains open boundary information -
             [logical]
          -
          -
          -
          -
        42. -
        43. - -

          ocean_obc_mass_flux

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        44. -
        45. - -

          ocean_obc_tracer_flux

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        46. -
        47. - -

          store_ocean_obc_tracer_flux

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        48. -
        49. - -

          store_ocean_obc_pressure_grad

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        50. -
        51. - -

          check_eta_OBC

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        52. -
        - - - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          obc_update_boundary

          -
          -
          -
          -
          -DESCRIPTION -
          -
          - update field on the halo points at the global boundaries. -
          -
          -
          -
          -INPUT/OUTPUT -
          -
          - - - - -
          field    - field to be update on the boundary -
          -
          -
          -
          -
        2. -
        3. - -

          obc_zero_boundary

          -
          -
          -
          -
          -DESCRIPTION -
          -
          - set field at open boundaries to zero. -
          -
          -
          -
          -INPUT/OUTPUT -
          -
          - - - - -
          field    - field to be set to zero on the boundary -
          -
          -
          -
          -
        4. -
        5. - -

          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]
          -
          -
          -
          -
        6. -
        7. - -

          -
            function ocean_obc_check_for_update()
          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        8. -
        9. - -

          ocean_obc_prepare

          -
            subroutine ocean_obc_prepare(Time, Ext_mode)
          -
          -
          -DESCRIPTION -
          -
          - Prepares OBC - -
          -
          -
          -
          -
        10. -
        11. - -

          ocean_obc_adjust_divud

          -
            subroutine ocean_obc_adjust_divud(divud)
          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -INPUT/OUTPUT -
          -
          - - - - -
          divud    -
             [real, dimension(isd:,jsd:)]
          -
          -
          -
          -
        12. -
        13. - -

          ocean_obc_damp_newton

          -
            subroutine ocean_obc_damp_newton(udrho_bt,forcing)
          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        14. -
        15. - -

          ocean_obc_ud

          -
            subroutine ocean_obc_ud(eta_t, udrho)
          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        16. -
        17. - -

          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:,:)]
          -
          -
          -
          -
        18. -
        19. - -

          ocean_obc_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_obc_end

          -
          -
          -DESCRIPTION -
          -
          - Destructor routine. Release memory. -
          -
          -
          -
          -OUTPUT -
          -
          - - - - -
          have_obc    - Contains open boundary information -
             [logical]
          -
          -
          -
          -
        22. -
        23. - -

          phase_speed_IOW

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        24. -
        25. - -

          phase_speed_ORLANS

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        26. -
        27. - -

          phase_speed_GRAVTY

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        28. -
        29. - -

          phase_speed_MILLER

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        30. -
        31. - -

          phase_speed_RAYMND

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        32. -
        33. - -

          boundary_average

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        34. -
        35. - -

          check_eta_OBC

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        36. -
        37. - -

          mpp_update_domains_obc

          -
          -
          -DESCRIPTION -
          -
          -
          -
          -
          -
        38. -
        - - - - -
        -

        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

        - -
          -
        1. - -

          ocean_operators_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the operator module -
          -
          -
          -
          -
        2. -
        3. - -

          set_barotropic_domain

          -
          -
          -DESCRIPTION -
          -
          - Set the barotropic domain used in barotropic time step. -
          -
          -
          -
          -INPUT -
          -
          - - - - -
          Domain_in    - Store the barotropic domain. -
             [type(ocean_domain_type)]
          -
          -
          -
          -
        4. -
        5. - -

          get_use_legacy_DIV_UD

          -
          -
          -DESCRIPTION -
          -
          - Return the value of ocean_operators_nml variable use_legacy_DIV_UD -
          -
          -
          -
          -
        6. -
        7. - -

          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)]
          -
          -
          -
          -
        8. -
        9. - -

          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)]
          -
          -
          -
          -
        10. -
        11. - -

          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)]
          -
          -
          -
          -
        12. -
        13. - -

          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(:,:)) - -
          -
          -
          -
          -
        14. -
        15. - -

          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(:,:))) -
          -
          -
          -
          -
        16. -
        17. - -

          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)]
          -
          -
          -
          -
        18. -
        19. - -

          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. - -
          -
          -
          -
          -
        20. -
        21. - -

          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)]
          -
          -
          -
          -
        22. -
        23. - -

          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)]
          -
          -
          -
          -
        24. -
        25. - -

          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)]
          -
          -
          -
          -
        26. -
        27. - -

          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)]
          -
          -
          -
          -
        28. -
        29. - -

          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)]
          -
          -
          -
          -
        30. -
        31. - -

          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)]
          -
          -
          -
          -
        32. -
        33. - -

          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)]
          -
          -
          -
          -
        34. -
        35. - -

          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]
          -
          -
          -
          -
        36. -
        37. - -

          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)]
          -
          -
          -
          -
        38. -
        39. - -

          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]
          -
          -
          -
          -
        40. -
        41. - -

          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)]
          -
          -
          -
          -
        42. -
        43. - -

          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)]
          -
          -
          -
          -
        44. -
        45. - -

          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)]
          -
          -
          -
          -
        46. -
        47. - -

          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)]
          -
          -
          -
          -
        48. -
        49. - -

          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)]
          -
          -
          -
          -
        50. -
        51. - -

          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)]
          -
          -
          -
          -
        52. -
        53. - -

          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]
          -
          -
          -
          -
        54. -
        55. - -

          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)]
          -
          -
          -
          -
        56. -
        57. - -

          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)]
          -
          -
          -
          -
        58. -
        - - - - -
        -

        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

        - - -
        -Contact:  - S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          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. - -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_parameters_end

          -
          -
          -DESCRIPTION -
          -
          - Summarize the basic physical parameters used in the simulation. -
          -
          -
          -
          -
        4. -
        - - - - -
        -

        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

        - - -
        -Contact:  - S.M. Griffies - -
        -Reviewers:  - A. Rosati - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_pressure_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the pressure module -
          -
          -
          -
          -
        2. -
        3. - -

          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. - -
          -
          -
          -
          -
        4. -
        5. - -

          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. - -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          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. - -
          -
          -
          -
          -
        10. -
        11. - -

          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. - -
          -
          -
          -
          -
        12. -
        13. - -

          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. - -
          -
          -
          -
          -
        14. -
        15. - -

          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. - -
          -
          -
          -
          -
        16. -
        17. - -

          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. - -
          -
          -
          -
          -
        18. -
        19. - -

          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. -
          -
          -
          -
          -
        20. -
        21. - -

          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. - -
          -
          -
          -
          -
        22. -
        23. - -

          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. - -
          -
          -
          -
          -
        24. -
        25. - -

          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. - -
          -
          -
          -
          -
        26. -
        27. - -

          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. - -
          -
          -
          -
          -
        28. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - S.M. Griffies, 2012: Elements of MOM -
        2. -
        -
        -
        - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_sbc_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the ocean sbc module. -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_sbc_diag_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the ocean sbc diagnostics. - Send some static diagnostics to diagnostic manager. -
          -
          -
          -
          -
        4. -
        5. - -

          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. - -
          -
          -
          -
          -
        6. -
        7. - -

          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). - -
          -
          -
          -
          -
        8. -
        9. - -

          zero_ocean_sfc

          -
          -
          -DESCRIPTION -
          -
          - Zero the elements of the Ocean_sfc derived type. -
          -
          -
          -
          -
        10. -
        11. - -

          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). - -
          -
          -
          -
          -
        12. -
        13. - -

          ocean_sfc_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        14. -
        15. - -

          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. -
          -
          -
          -
          -
        16. -
        17. - -

          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 - -
          -
          -
          -
          -
        18. -
        19. - -

          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. - -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_sbc_diag

          -
          -
          -DESCRIPTION -
          -
          - Compute and send diagnostics from get_ocean_sbc. -
          -
          -
          -
          -
        22. -
        23. - -

          -
          -
          -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. -
          -
          -
          -
          -
        24. -
        25. - -

          -
          -
          -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. - -
          -
          -
          -
          -
        26. -
        - - - - -
        -

        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

        - - -
        -Contact:  S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_thickness_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the thickness type. - - For pressure-based vertical coordinates, this initialization here - is preliminary. -
          -
          -
          -
          -
        2. -
        3. - -

          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. - -
          -
          -
          -
          -
        4. -
        5. - -

          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. - -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          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. -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          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. - -
          -
          -
          -
          -
        14. -
        15. - -

          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 -
          -
          -
          -
          -
        16. -
        17. - -

          rho_dzt_tendency

          -
          -
          -DESCRIPTION -
          -
          - Compute tendency for rho_dzt. This tendency is a function of the - vertical coordinate. -
          -
          -
          -
          -
        18. -
        19. - -

          thickness_chksum

          -
          -
          -DESCRIPTION -
          -
          - - Compute checksum for thickness components . - Only print checksums for fields that should agree across restarts. - -
          -
          -
          -
          -
        20. -
        21. - -

          thickness_details

          -
          -
          -DESCRIPTION -
          -
          - - For debugging, we print here some details of the grid at a particular - (i,j) point. - -
          -
          -
          -
          -
        22. -
        23. - -

          ocean_thickness_restart

          -
          -
          -DESCRIPTION -
          -
          - Write out restart files registered through register_restart_file -
          -
          -
          -
          -
        24. -
        25. - -

          ocean_thickness_end

          -
          -
          -DESCRIPTION -
          -
          - Write basic elements of thickness derived type to restart -
          -
          -
          -
          -
        26. -
        27. - -

          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. -
          -
          -
          -
          -
        28. -
        29. - -

          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. -
          -
          -
          -
          -
        30. -
        31. - -

          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 -
          -
          -
          -
          -
        32. -
        33. - -

          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. -
          -
          -
          -
          -
        34. -
        35. - -

          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. - -
          -
          -
          -
          -
        36. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - S.M. Griffies, Elements of MOM (2012) -
        2. -
        -
        -
        - -
        -
        -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 $' #include diff --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

        - - -
        -Contact:  Matt Harrison -,  - S. M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
          -
        1. - -

          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. - -
          -
          -
          -
          -
        2. -
        - - - - -
        -

        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

        - - -
        -Contact:  Matt Harrison -,  - - S. M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
          -
        1. - -

          ocean_types_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the ocean types. -
          -
          -
          -
          -
        2. -
        - - - - - - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_util_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize MOM utilities. -
          -
          -
          -
          -
        2. -
        3. - -

          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 - -
          -
          -
          -
          -
        4. -
        5. - -

          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 - -
          -
          -
          -
          -
        6. -
        7. - -

          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" - -
          -
          -
          -
          -
        8. -
        9. - -

          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 - -
          -
          -
          -
          -
        10. -
        11. - -

          write_timestamp

          -
          -
          -DESCRIPTION -
          -
          - Write the time stamp. -
          -
          -
          -
          -
        12. -
        13. - -

          write_chksum_header

          -
          -
          -DESCRIPTION -
          -
          - Write the checksum header. -
          -
          -
          -
          -
        14. -
        15. - -

          write_note

          -
          -
          -DESCRIPTION -
          -
          - Write a note. -
          -
          -
          -
          -
        16. -
        17. - -

          write_warning

          -
          -
          -DESCRIPTION -
          -
          - Write a warning. -
          -
          -
          -
          -
        18. -
        19. - -

          write_line

          -
          -
          -DESCRIPTION -
          -
          - Write a message. -
          -
          -
          -
          -
        20. -
        21. - -

          write_chksum_3d

          -
          -
          -DESCRIPTION -
          -
          - Write a 3d checksum. -
          -
          -
          -
          -
        22. -
        23. - -

          write_chksum_2d

          -
          -
          -DESCRIPTION -
          -
          - Write a 2d checksum. -
          -
          -
          -
          -
        24. -
        25. - -

          write_chksum_2d_int

          -
          -
          -DESCRIPTION -
          -
          - Write a 2d integer checksum. -
          -
          -
          -
          -
        26. -
        27. - -

          check_restart

          -
          -
          -DESCRIPTION -
          -
          - Write a note regarding the restart setup. -
          -
          -
          -
          -
        28. -
        29. - -

          write_summary

          -
          -
          -DESCRIPTION -
          -
          - Write a summary note. -
          -
          -
          -
          -
        30. -
        31. - -

          diagnose_3d

          -
          -
          -DESCRIPTION -
          -
          - Helper function for diagnosting 3D data using the grid tmask. -
          -
          -
          -
          -
        32. -
        33. - -

          diagnose_2d

          -
          -
          -DESCRIPTION -
          -
          - Helper function for diagnosting 2D data using the grid tmask. -
          -
          -
          -
          -
        34. -
        35. - -

          diagnose_2d_int

          -
          -
          -DESCRIPTION -
          -
          - Helper function for diagnosting 2D data using the grid tmask. -
          -
          -
          -
          -
        36. -
        37. - -

          diagnose_3d_int

          -
          -
          -DESCRIPTION -
          -
          - Helper function for diagnosting 3D data using the grid tmask. -
          -
          -
          -
          -
        38. -
        - - - - - - -
        -
        -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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_velocity_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize terms for the velocity equation. -
          -
          -
          -
          -
        2. -
        3. - -

          check_gravity_wave_cfl

          -
          -
          -DESCRIPTION -
          -
          - Check CFL for internal gravity waves. -
          -
          -
          -
          -
        4. -
        5. - -

          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. - -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          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. - -
          -
          -
          -
          -
        10. -
        11. - -

          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. - -
          -
          -
          -
          -
        12. -
        13. - -

          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). - -
          -
          -
          -
          -
        14. -
        15. - -

          ocean_velocity_restart

          -
          -
          -DESCRIPTION -
          -
          - - Write out restart files registered through register_restart_file - -
          -
          -
          -
          -
        16. -
        17. - -

          ocean_velocity_end

          -
          -
          -DESCRIPTION -
          -
          - - Write velocity field to a restart - -
          -
          -
          -
          -
        18. -
        19. - -

          velocity_truncate

          -
          -
          -DESCRIPTION -
          -
          - Truncate velocity so that either component - has magnitude no larger than nml specified value. - -
          -
          -
          -
          -
        20. -
        21. - -

          ocean_velocity_chksum

          -
          -
          -DESCRIPTION -
          -
          - Compute checksum for velocity components -
          -
          -
          -
          -
        22. -
        23. - -

          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 - -
          -
          -
          -
          -
        24. -
        25. - -

          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). - -
          -
          -
          -
          -
        26. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - Durran, Numerical Methods for Wave Equations in Geophysical - Fluid Dynamics (1999). -
        2. -
        3. - R.C. Pacanowski and S.M. Griffies, The MOM3 Manual (1999). - NOAA/Geophysical Fluid Dynamics Laboratory -
        4. -
        5. - 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 -
        6. -
        7. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and - A. Rosati, A Technical Guide to MOM4 (2004). - NOAA/Geophysical Fluid Dynamics Laboratory -
        8. -
        9. - S.M. Griffies, Fundamentals of Ocean Climate Models (2004). - Princeton University Press. -
        10. -
        11. - S.M. Griffies (2012), Elements of MOM -
        12. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_velocity_advect_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the velocity advection module. -
          -
          -
          -
          -
        2. -
        3. - -

          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. - -
          -
          -
          -
          -
        4. -
        5. - -

          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. - -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          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. - -
          -
          -
          -
          -
        10. -
        11. - -

          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. - -
          -
          -
          -
          -
        12. -
        13. - -

          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. - -
          -
          -
          -
          -
        14. -
        - - - - -
        -

        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

        - -
        -
          -
        1. - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
        2. -
        3. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) -
        4. -
        5. - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
        6. -
        7. - S.M. Griffies: Elements of MOM (2012) -
        8. -
        9. - Hundsdorder and Trompert (1994), "Method of lines and - direct discretization: a comparison for linear - advection", Applied Numerical Mathematics, - pages 469--490. -
        10. -
        -
        -
        - -
        -
        -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

        - - -
        -Contact:  - M.J. Harrison - -
        -Reviewers:  - S.M. Griffies - -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_workspace_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize MOM workspace module. -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_workspace_end

          -
          -
          -DESCRIPTION -
          -
          - End MOM workspace. -
          -
          -
          -
          -
        4. -
        - - - - - - -
        -
        -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

        - - -
        -Contact:  Matt Harrison - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        -
        -
        -
        -init_oda:
        -
        -
        -oda:
        -
        -
        -
        -
        - - -
        -

        PUBLIC DATA

        - -
        - - - - - - - -
        Name Type Value Units Description
        use_this_module logical --- --- - use the oda module -
        -
        -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          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]
          -
          -
          -
          -
        2. -
        3. - -

          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]
          -
          -
          -
          -
        4. -
        - - - - -
        -

        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

        - - -
        -Contact:  S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_adv_vel_diag_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the ocean_adv_vel_diag module containing subroutines - diagnosing advection velocity related properties of the simulation. -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_adv_vel_diagnostics

          -
          -
          -DESCRIPTION -
          -
          - Call diagnostics related to the velocity. -
          -
          -
          -
          -
        4. -
        5. - -

          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. -
          -
          -
          -
          -
        6. -
        7. - -

          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. - -
          -
          -
          -
          -
        8. -
        9. - -

          cfl_check2

          -
          -
          -DESCRIPTION -
          -
          - Perform the second of two vertical CFL checks. - - Bring the model down if too many large Courant numbers detected. -
          -
          -
          -
          -
        10. -
        11. - -

          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. -
          -
          -
          -
          -
        12. -
        13. - -

          max_continuity_error

          -
          -
          -DESCRIPTION -
          -
          - Compute continuity error. Should be roundoff if all is working well. -
          -
          -
          -
          -
        14. -
        15. - -

          transport_on_s

          -
          -
          -DESCRIPTION -
          -
          - Compute transports on s-levels (defined by same k-level) - and send to diag_manager. -
          -
          -
          -
          -
        16. -
        17. - -

          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. - -
          -
          -
          -
          -
        18. -
        19. - -

          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. - -
          -
          -
          -
          -
        20. -
        21. - -

          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. - -
          -
          -
          -
          -
        22. -
        23. - -

          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. -
          -
          -
          -
          -
        24. -
        - - - - -
        -

        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

        - - -
        -Contact:  S.M. Griffies - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

        - -
        - - -
        -

        PUBLIC ROUTINES

        - -
          -
        1. - -

          ocean_diag_init

          -
          -
          -DESCRIPTION -
          -
          - Initialize the ocean_diag module. -
          -
          -
          -
          -
        2. -
        3. - -

          ocean_diagnostics

          -
          -
          -DESCRIPTION -
          -
          - Call some ocean numerical diagnostics -
          -
          -
          -
          -
        4. -
        - - - - - - -
        -
        -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

        - - -
        -Contact:  Matt Harrison - -
        -Reviewers:  -
        -Change History: WebCVS Log -
        -
        -
        - - -
        -

        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

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_tracer_diagnostics

            -
            -
            -DESCRIPTION -
            -
            - Call diagnostics related to the tracer fields. -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          9. - -

            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 - -
            -
            -
            -
            -
          10. -
          11. - -

            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 -
            -
            -
            -
            -
          12. -
          13. - -

            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. - -
            -
            -
            -
            -
          14. -
          15. - -

            total_tracer

            -
            -
            -DESCRIPTION -
            -
            - Compute integrated tracer in model. -
            -
            -
            -
            -
          16. -
          17. - -

            klevel_total_tracer

            -
            -
            -DESCRIPTION -
            -
            - Compute integrated tracer on a k-level. -
            -
            -
            -
            -
          18. -
          19. - -

            total_mass

            -
            -
            -DESCRIPTION -
            -
            - Compute total ocean tracer cell mass. For Boussinesq fluid, - mass is determined using rho0 for density. -
            -
            -
            -
            -
          20. -
          21. - -

            total_volume

            -
            -
            -DESCRIPTION -
            -
            - Compute total ocean tracer cell volume. -
            -
            -
            -
            -
          22. -
          23. - -

            klevel_total_mass

            -
            -
            -DESCRIPTION -
            -
            - Compute ocean tracer cell mass in a k-level. For Boussinesq fluid, - mass is determined using rho0 for density. -
            -
            -
            -
            -
          24. -
          25. - -

            tracer_integrals

            -
            -
            -DESCRIPTION -
            -
            - Compute some integrated tracer diagnostics. -
            -
            -
            -
            -
          26. -
          27. - -

            tracer_land_cell_check

            -
            -
            -DESCRIPTION -
            -
            - Check to be sure ocean tracer is zero over land -
            -
            -
            -
            -
          28. -
          29. - -

            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 - -
            -
            -
            -
            -
          30. -
          31. - -

            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. - -
            -
            -
            -
            -
          32. -
          33. - -

            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 - -
            -
            -
            -
            -
          34. -
          35. - -

            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. - -
            -
            -
            -
            -
          36. -
          37. - -

            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 -
            -
            -
            -
            -
          38. -
          39. - -

            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 -
            -
            -
            -
            -
          40. -
          41. - -

            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 - -
            -
            -
            -
            -
          42. -
          43. - -

            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 - -
            -
            -
            -
            -
          44. -
          45. - -

            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. - -
            -
            -
            -
            -
          46. -
          47. - -

            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. - -
            -
            -
            -
            -
          48. -
          49. - -

            send_total_mass

            -
            -
            -DESCRIPTION -
            -
            - Send total liquid seawater mass to diagnostic manager. -
            -
            -
            -
            -
          50. -
          51. - -

            send_total_volume

            -
            -
            -DESCRIPTION -
            -
            - Send total liquid seawater mass to diagnostic manager. -
            -
            -
            -
            -
          52. -
          53. - -

            send_total_tracer

            -
            -
            -DESCRIPTION -
            -
            - Send total tracer to diagnostic manager. -
            -
            -
            -
            -
          54. -
          55. - -

            send_global_ave_tracer

            -
            -
            -DESCRIPTION -
            -
            - Send global averaged tracer to diagnostic manager. -
            -
            -
            -
            -
          56. -
          57. - -

            send_global_ave_pressure

            -
            -
            -DESCRIPTION -
            -
            - Send global averaged pressure to diagnostic manager. -
            -
            -
            -
            -
          58. -
          59. - -

            send_surface_ave_tracer

            -
            -
            -DESCRIPTION -
            -
            - Send global averaged surface tracer to diagnostic manager. - Note the presence of a rho_dzt weighting here... -
            -
            -
            -
            -
          60. -
          61. - -

            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. -
            -
            -
            -
            -
          62. -
          63. - -

            send_tracer_variance

            -
            -
            -DESCRIPTION -
            -
            - - Compute the global and k-level tracer variance. - -
            -
            -
            -
            -
          64. -
          65. - -

            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 - -
            -
            -
            -
            -
          66. -
          - - - - -
          -

          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

          - - -
          -Contact:  - S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_tracer_util_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize MOM tracer utilities. -
            -
            -
            -
            -
          2. -
          3. - -

            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) - -
            -
            -
            -
            -
          4. -
          5. - -

            dzt_min_max

            -
            -
            -DESCRIPTION -
            -
            - Compute the global min and max for dzt. - - Modified by Stephen.Griffies from subroutine tracer_min_max - -
            -
            -
            -
            -
          6. -
          7. - -

            tracer_prog_chksum

            -
            -
            -DESCRIPTION -
            -
            - Compute checksums for prognostic tracers -
            -
            -
            -
            -
          8. -
          9. - -

            tracer_diag_chksum

            -
            -
            -DESCRIPTION -
            -
            - Compute checksums for diagnostic tracers -
            -
            -
            -
            -
          10. -
          11. - -

            tracer_psom_chksum

            -
            -
            -DESCRIPTION -
            -
            - Compute checksums for PSOM advection second order moments. -
            -
            -
            -
            -
          12. -
          13. - -

            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 - -
            -
            -
            -
            -
          14. -
          15. - -

            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 - -
            -
            -
            -
            -
          16. -
          17. - -

            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. - -
            -
            -
            -
            -
          18. -
          19. - -

            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 - -
            -
            -
            -
            -
          20. -
          21. - -

            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. - -
            -
            -
            -
            -
          22. -
          - - - - -
          -

          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

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_velocity_diagnostics

            -
            -
            -DESCRIPTION -
            -
            - Call diagnostics related to the velocity. -
            -
            -
            -
            -
          4. -
          5. - -

            potential_energy

            -
            -
            -DESCRIPTION -
            -
            - - Compute gravitational potential energy (Joules) relative to z=0 - taken with respect to the value at the initial time step. - -
            -
            -
            -
            -
          6. -
          7. - -

            kinetic_energy

            -
            -
            -DESCRIPTION -
            -
            - Compute global integrated horizontal kinetic energy. -
            -
            -
            -
            -
          8. -
          9. - -

            velocity_land_cell_check

            -
            -
            -DESCRIPTION -
            -
            - See if there are any points over land with nonzero ocean velocity -
            -
            -
            -
            -
          10. -
          11. - -

            velocity_change

            -
            -
            -DESCRIPTION -
            -
            - Determine the number of points that have large single-time step - changes in the absolute value of the velocity. -
            -
            -
            -
            -
          12. -
          13. - -

            compute_topostrophy

            -
            -
            -DESCRIPTION -
            -
            - - Diagnose topostrophy as per Greg Holloway. - - Stephen.Griffies - March 2012 - -
            -
            -
            -
            -
          14. -
          15. - -

            compute_vorticity

            -
            -
            -DESCRIPTION -
            -
            - Compute z-component to vorticity. -
            -
            -
            -
            -
          16. -
          17. - -

            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. - -
            -
            -
            -
            -
          18. -
          19. - -

            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. - -
            -
            -
            -
            -
          20. -
          21. - -

            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. - -
            -
            -
            -
            -
          22. -
          23. - -

            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. - -
            -
            -
            -
            -
          24. -
          25. - -

            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. -
            -
            -
            -
            -
          26. -
          27. - -

            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. - -
            -
            -
            -
            -
          28. -
          29. - -

            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. - -
            -
            -
            -
            -
          30. -
          31. - -

            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. -
            -
            -
            -
            -
          32. -
          33. - -

            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. -
            -
            -
            -
            -
          34. -
          - - - - -
          -

          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

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_bih_friction_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the horizontal biharmonic friction module. -
            -
            -
            -
            -
          2. -
          3. - -

            bih_friction

            -
            -
            -DESCRIPTION -
            -
            - Compute the thickness weighted and density weighted accel due to - lateral biharmonic friction. Add this contribution to Velocity%accel. -
            -
            -
            -
            -
          4. -
          5. - -

            bih_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - To check that the viscosity is not too large. -
            -
            -
            -
            -
          6. -
          7. - -

            bih_reynolds_check

            -
            -
            -DESCRIPTION -
            -
            - To check that the Reynolds number is not too large. -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            ocean_bih_friction_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          12. -
          13. - -

            ocean_bih_friction_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart of the vertically averaged viscosity. -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_bih_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_bih_tracer_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            bih_tracer

            -
            -
            -DESCRIPTION -
            -
            - This function computes the thickness weighted and density weighted - time tendency for tracer from biharmonic mixing. -
            -
            -
            -
            -
          4. -
          5. - -

            delsq_tracer

            -
            -
            -DESCRIPTION -
            -
            - Subroutine computes the laplacian operator acting on tracer with unit - diffusivity. Units of del2_tracer are tracer/length^2 -
            -
            -
            -
            -
          6. -
          - - - - -
          -

          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 @@ - - - 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 - 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 @@ - - - -Module ocean_bihcgrid_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_bihcgrid_friction_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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). - -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            bihcgrid_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. -
            -
            -
            -
            -
          10. -
          11. - -

            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. -
            -
            -
            -
            -
          12. -
          13. - -

            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 - -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
          4. -
          5. - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
          6. -
          7. - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
          8. -
          9. - Griffies: Elements of MOM (2012) -
          10. -
          -
          -
          - - -
          -

          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 @@ - - - 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 - - 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 @@ - - - -Module ocean_bihcst_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_bihcst_friction_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            bihcst_friction

            -
            -
            -DESCRIPTION -
            -
            - This subroutine computes the thickness weighted acceleration on - horizontal velocity arising from horizontal biharmonic friction. -
            -
            -
            -
            -
          4. -
          5. - -

            delsq_velocity

            -
            -
            -DESCRIPTION -
            -
            - Subroutine computes the laplacian operator acting on velocity. -
            -
            -
            -
            -
          6. -
          7. - -

            bihcst_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. -
            -
            -
            -
            -
          8. -
          9. - -

            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. -
            -
            -
            -
            -
          10. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - Elements of MOM (2012), S.M. Griffies -
          4. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_bihgen_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_bihgen_friction_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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). - -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            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)]
            -
            -
            -
            -
          10. -
          11. - -

            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)]
            -
            -
            -
            -
          12. -
          13. - -

            bihgen_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to perform linear stability check for the biharmonic - operator given a value for the horizontal biharmonic viscosity. -
            -
            -
            -
            -
          14. -
          15. - -

            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. -
            -
            -
            -
            -
          16. -
          17. - -

            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 - -
            -
            -
            -
            -
          18. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - R.D. Smith and J.C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
          4. -
          5. - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
          6. -
          7. - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
          8. -
          9. - S.M. Griffies, 2004: - Fundamentals of Ocean Climate Models - Princeton University Press -
          10. -
          11. - Griffies, Elements of MOM (2012) -
          12. -
          -
          -
          - - -
          -

          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 @@ - - - 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 - -
          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 @@ - - - -Module ocean_lap_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_lap_friction_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_lap_friction_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the horizontal Laplacian friction module. -
            -
            -
            -
            -
          2. -
          3. - -

            lap_friction

            -
            -
            -DESCRIPTION -
            -
            - Compute the thickness weighted and density weighted accel due to - lateral laplacian friction. Add this contribution to Velocity%accel. -
            -
            -
            -
            -
          4. -
          5. - -

            lap_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - To check that the viscosity is not too large. -
            -
            -
            -
            -
          6. -
          7. - -

            lap_reynolds_check

            -
            -
            -DESCRIPTION -
            -
            - To check that the Reynolds number is not too large. -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            ocean_lap_friction_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          12. -
          13. - -

            ocean_lap_friction_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart of the vertically averaged viscosity. -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_lap_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_lap_tracer_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            lap_tracer

            -
            -
            -DESCRIPTION -
            -
            - This function computes the thickness weighted and density weighted - time tendency for tracer from lateral laplacian diffusion. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_lapcgrid_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_lapcgrid_friction_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            lapcgrid_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to perform linear stability check for the Laplacian - operator given a value for the horizontal biharmonic viscosity. -
            -
            -
            -
            -
          6. -
          7. - -

            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)]
            -
            -
            -
            -
          8. -
          9. - -

            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 - -
            -
            -
            -
            -
          10. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
          4. -
          5. - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
          6. -
          7. - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
          8. -
          9. - Griffies: Elements of MOM (2012) -
          10. -
          -
          -
          - - -
          -

          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 @@ - - - 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 - - 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 @@ - - - -Module ocean_lapcst_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_lapcst_friction_mod

          - - -
          -Contact:  -
          -Reviewers:  Stephen M. Griffies - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            lapcst_friction

            -
            -
            -DESCRIPTION -
            -
            - This routine computes the rho*thickness weighted time tendency for - horizontal velocity from horizontal Laplacian friction. -
            -
            -
            -
            -
          4. -
          5. - -

            lapcst_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - Perform linear stability check for the Laplacian operator - given a value for the horizontal laplacian viscosity. -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - S.M. Griffies, Elements of MOM (2012) -
          4. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_lapgen_friction_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_lapgen_friction_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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)]
            -
            -
            -
            -
          6. -
          7. - -

            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)]
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            lapgen_viscosity_check

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to perform linear stability check for the Laplacian - operator given a value for the horizontal biharmonic viscosity. -
            -
            -
            -
            -
          12. -
          13. - -

            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)]
            -
            -
            -
            -
          14. -
          15. - -

            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) - -
            -
            -
            -
            -
          16. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - R. D. Smith and J. C. McWilliams, 2003: - Anisotropic horizontal viscosity for ocean models, - Ocean Modelling, vol. 5, pages 129-156. -
          4. -
          5. - Maltrud and Holloway, 2008: Implementing biharmonic neptune in a - global eddying ocean model, Ocean Modelling, vol. 21, pages 22-34. -
          6. -
          7. - Deremble, Hogg, Berloff, and Dewar, 2011: - On the application of no-slip lateral boundary conditions to coarsely - resolved ocean models, Ocean Modelling. -
          8. -
          9. - Griffies: Elements of MOM (2012) -
          10. -
          -
          -
          - - -
          -

          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 @@ - - - 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) - -
          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 @@ - - - -Module ocean_mixdownslope_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_mixdownslope_mod

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_mixdownslope_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for mixing of tracers into the abyss next to topography. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          6. -
          7. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from mixdownslope on the watermass transformation. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 -
          2. -
          3. - S.M. Griffies: Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
          4. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -Module ocean_sigma_transport_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_sigma_transport_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            ocean_sigma_transport_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          6. -
          7. - -

            ocean_sigma_transport_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          8. -
          9. - -

            advect_sigma_upwind

            -
            -
            -DESCRIPTION -
            -
            - First order upwind to advect tracers in sigma layer. -
            -
            -
            -
            -
          10. -
          11. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          12. -
          13. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from sigma transport on the watermass transformation. -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - 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 -
          4. -
          5. - Campin and Goosse 1999: Parameterization of density-driven downsloping - flow for a coarse-resolution model in z-coordinate", Tellus 51A, - pages 412-430. -
          6. -
          7. - S.M. Griffies: Elements of MOM (2012) -
          8. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -Module ocean_submesoscale_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_submesoscale_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_submesoscale_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the ocean_submesoscale module. -
            -
            -
            -
            -
          2. -
          3. - -

            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. -
            -
            -
            -
            -
          4. -
          5. - -

            compute_bldepth

            -
            -
            -DESCRIPTION -
            -
            - Compute the boundary layer depth and kblt. -
            -
            -
            -
            -
          6. -
          7. - -

            tracer_derivs

            -
            -
            -DESCRIPTION -
            -
            - Compute the tracer derivatives, with the - lateral derivatives computed along constant k-level. -
            -
            -
            -
            -
          8. -
          9. - -

            salinity_derivs

            -
            -
            -DESCRIPTION -
            -
            - Compute the density-salinity derivatives, with lateral - derivative computed on constant k-level. -
            -
            -
            -
            -
          10. -
          11. - -

            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. - -
            -
            -
            -
            -
          12. -
          13. - -

            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 - -
            -
            -
            -
            -
          14. -
          15. - -

            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. - -
            -
            -
            -
            -
          16. -
          17. - -

            compute_submeso_skewsion

            -
            -
            -DESCRIPTION -
            -
            - Compute tendency from submeso skewsion. -
            -
            -
            -
            -
          18. -
          19. - -

            compute_flux_x

            -
            -
            -DESCRIPTION -
            -
            - - Subroutine computes the zonal submesoscale tracer skew flux component. - - fx has physical dimensions (area*diffusivity*density*tracer gradient) - -
            -
            -
            -
            -
          20. -
          21. - -

            compute_flux_y

            -
            -
            -DESCRIPTION -
            -
            - - Subroutine computes the meridional submesoscale tracer skew flux component. - - fy has physical dimensions (area*diffusivity*density*tracer gradient) - -
            -
            -
            -
            -
          22. -
          23. - -

            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) - -
            -
            -
            -
            -
          24. -
          25. - -

            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. - -
            -
            -
            -
            -
          26. -
          27. - -

            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. - -
            -
            -
            -
            -
          28. -
          29. - -

            compute_submeso_diffusion

            -
            -
            -DESCRIPTION -
            -
            - Compute tendency from submeso horizontal diffusion. -
            -
            -
            -
            -
          30. -
          31. - -

            maximum_bottom_w_general

            -
            -
            -DESCRIPTION -
            -
            - Compute maximum vertical velocity from submeso. -
            -
            -
            -
            -
          32. -
          33. - -

            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. -
            -
            -
            -
            -
          34. -
          35. - -

            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. - -
            -
            -
            -
            -
          36. -
          37. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          38. -
          39. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from submesoscale on watermass transformation. -
            -
            -
            -
            -
          40. -
          41. - -

            watermass_diag_diffusion

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from submesoscale horizontal diffusion - on watermass transformation. -
            -
            -
            -
            -
          42. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - Fox-Kemper, Danabasoglu, Ferrari, and Hallberg 2008: - Parameterizing submesoscale physics in global models. - Clivar Exchanges, vol 13, no.1, Jan2008. pages 3-5. -
          4. -
          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. -
          6. -
          7. - Griffies, 2012: Elements of MOM -
          8. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 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

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  Tim Leslie - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_nphysics_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the neutral physics module. -
            -
            -
            -
            -
          2. -
          3. - -

            neutral_physics

            -
            -
            -DESCRIPTION -
            -
            - - Call the relevant neutral physics scheme. - -
            -
            -
            -
            -
          4. -
          5. - -

            ocean_nphysics_restart

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          6. -
          7. - -

            ocean_nphysics_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            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) - -
            -
            -
            -
            -
          12. -
          13. - -

            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) - -
            -
            -
            -
            -
          14. -
          15. - -

            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) - -
            -
            -
            -
            -
          16. -
          17. - -

            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) - -
            -
            -
            -
            -
          18. -
          19. - -

            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) - -
            -
            -
            -
            -
          20. -
          21. - -

            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) - -
            -
            -
            -
            -
          22. -
          23. - -

            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. -
            -
            -
            -
            -
          24. -
          25. - -

            slope_function_gm

            -
            -
            -DESCRIPTION -
            -
            - Function for defining effective slope in diagnostic GM velocity - calculation. Used only for diagnostic purposes. -
            -
            -
            -
            -
          26. -
          27. - -

            nphysics_diagnostics

            -
            -
            -DESCRIPTION -
            -
            - Send some diagnostics to diagnostics manager. -
            -
            -
            -
            -
          28. -
          29. - -

            ocean_nphysicsA_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          30. -
          31. - -

            ocean_nphysicsA_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          32. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
          4. -
          5. - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
          6. -
          7. - S.M. Griffies, Elements of MOM (2012) -
          8. -
          9. - 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 -
          10. -
          11. - 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. -
          12. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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 - -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            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) - -
            -
            -
            -
            -
          12. -
          13. - -

            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) - -
            -
            -
            -
            -
          14. -
          15. - -

            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) - -
            -
            -
            -
            -
          16. -
          17. - -

            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) - -
            -
            -
            -
            -
          18. -
          19. - -

            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) - -
            -
            -
            -
            -
          20. -
          21. - -

            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) - -
            -
            -
            -
            -
          22. -
          23. - -

            nphysics_diagnostics

            -
            -
            -DESCRIPTION -
            -
            - Send some diagnostics to diagnostics manager. -
            -
            -
            -
            -
          24. -
          25. - -

            neutral_chksums

            -
            -
            -DESCRIPTION -
            -
            - Write some checksums. -
            -
            -
            -
            -
          26. -
          27. - -

            ocean_nphysicsB_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          28. -
          29. - -

            ocean_nphysicsB_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          30. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
          4. -
          5. - R. Ferrari and J.C. McWilliams and Canuto and Dubovikov - Parameterization of eddy fluxes near oceanic boundaries - Journal of Climate (2008). -
          6. -
          7. - Large etal (1997), Journal of Physical Oceanography, - pages 2418-2447 -
          8. -
          9. - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
          10. -
          11. - S.M. Griffies, Elements of MOM (2012) -
          12. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_nphysicsC_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_nphysicsC_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  Tim Leslie - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            compute_ndiffusion

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to compute the tendency from neutral diffusion. -
            -
            -
            -
            -
          8. -
          9. - -

            compute_gmskewsion

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to compute the tracer tendency from GM skewsion. -
            -
            -
            -
            -
          10. -
          11. - -

            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. - -
            -
            -
            -
            -
          12. -
          13. - -

            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. - -
            -
            -
            -
            -
          14. -
          15. - -

            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 - -
            -
            -
            -
            -
          16. -
          17. - -

            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. - -
            -
            -
            -
            -
          18. -
          19. - -

            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. - -
            -
            -
            -
            -
          20. -
          21. - -

            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. - -
            -
            -
            -
            -
          22. -
          23. - -

            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. - -
            -
            -
            -
            -
          24. -
          25. - -

            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) - -
            -
            -
            -
            -
          26. -
          27. - -

            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) - -
            -
            -
            -
            -
          28. -
          29. - -

            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) - -
            -
            -
            -
            -
          30. -
          31. - -

            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). - -
            -
            -
            -
            -
          32. -
          33. - -

            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. - -
            -
            -
            -
            -
          34. -
          35. - -

            ocean_nphysicsC_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          36. -
          37. - -

            ocean_nphysicsC_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          38. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
          4. -
          5. - 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. -
          6. -
          7. - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
          8. -
          9. - S.M. Griffies: Elements of MOM (2012) -
          10. -
          11. - 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 -
          12. -
          13. - 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 -
          14. -
          15. - 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. -
          16. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 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

          - - -
          -Contact:  Tim Leslie -,  - Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            check_nml_options

            -
            -
            -DESCRIPTION -
            -
            - Read in the namelist parameters and ensure that valid values have been - choosen. - Also determine whether agm is z-dependent. -
            -
            -
            -
            -
          2. -
          3. - -

            init_globals

            -
            -
            -DESCRIPTION -
            -
            - Allocate and initialise all (non-namelist) global variables in the module. -
            -
            -
            -
            -
          4. -
          5. - -

            register fields

            -
            -
            -DESCRIPTION -
            -
            - Register diagnostic fields. -
            -
            -
            -
            -
          6. -
          7. - -

            diffusivity_init

            -
            -
            -DESCRIPTION -
            -
            - Initialise the three diffusivity arrays. -
            -
            -
            -
            -
          8. -
          9. - -

            check_stability

            -
            -
            -DESCRIPTION -
            -
            - Check the stability assumptions and print details of the limits of stability. -
            -
            -
            -
            -
          10. -
          11. - -

            compute_diffusivity

            -
            -
            -DESCRIPTION -
            -
            - -
            -
            -
            -
            -
          12. -
          13. - -

            compute_agm

            -
            -
            -DESCRIPTION -
            -
            - Compute the flow-dependent GM diffusivity. -
            -
            -
            -
            -
          14. -
          15. - -

            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 -
            -
            -
            -
            -
          16. -
          17. - -

            compute_growth_rate

            -
            -
            -DESCRIPTION -
            -
            - Take the raw growth rate and convert it to a final growth rate to be - used in the diffusivity calculations. -
            -
            -
            -
            -
          18. -
          19. - -

            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. -
            -
            -
            -
            -
          20. -
          21. - -

            compute_length

            -
            -
            -DESCRIPTION -
            -
            - Compute the flow-dependent length scale involved in the GM diffusivity - calculations. -
            -
            -
            -
            -
          22. -
          23. - -

            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. -
            -
            -
            -
            -
          24. -
          25. - -

            compute_aredi

            -
            -
            -DESCRIPTION -
            -
            - Compute the flow-dependent neutral (Redi) diffusivity. -
            -
            -
            -
            -
          26. -
          27. - -

            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 -
            -
            -
            -
            -
          28. -
          - - - - -
          -

          NAMELIST

          - -
          -&ocean_nphysics_diff_nml -
          -
          -
          -
          -
          - -
          -
          - -
          -[logical] -
          -
          -
          -
          -
          - - - - -
          -

          REFERENCES

          - -
          -
            -
          1. - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press -
          2. -
          3. - S.M. Griffies, Elements of MOM (2012) -
          4. -
          -
          -
          - -
          -
          -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 @@ - - - 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 - 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 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

          - - -
          -Contact:  Tim Leslie -,  - Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_nphysics_flux_init

            -
            -
            -DESCRIPTION -
            -
            - Initialise namelist variables and prepare diagnostics. -
            -
            -
            -
            -
          2. -
          3. - -

            register fields

            -
            -
            -DESCRIPTION -
            -
            - Register diagnostic fields. -
            -
            -
            -
            -
          4. -
          5. - -

            flux_calculations

            -
            -
            -DESCRIPTION -
            -
            - This function computes the thickness weighted tendency of tracers - due to neutral physics as well as the implicit vertical diffusivity - term. -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            geometric_terms

            -
            -
            -DESCRIPTION -
            -
            - Calculate the density weighted quarter cell volumes of the triads. -
            -
            -
            -
            -
          10. -
          11. - -

            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. -
            -
            -
            -
            -
          12. -
          13. - -

            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]. -
            -
            -
            -
            -
          14. -
          15. - -

            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. -
            -
            -
            -
            -
          16. -
          17. - -

            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. -
            -
            -
            -
            -
          18. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press -
          2. -
          3. - S.M. Griffies: Elements of MOM (2012) -
          4. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 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

          - - -
          -Contact:  Tim Leslie -,  - Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_nphysics_new_init

            -
            -
            -DESCRIPTION -
            -
            - Initialises diagnostics, namelists and constants. -
            -
            -
            -
            -
          2. -
          3. - -

            register fields

            -
            -
            -DESCRIPTION -
            -
            - Register diagnostic fields. -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            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. -
            -
            -
            -
            -
          10. -
          11. - -

            gradrho

            -
            -
            -DESCRIPTION -
            -
            - Calculate the raw density gradients. No smoothing or limiting - applied here. -
            -
            -
            -
            -
          12. -
          13. - -

            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. -
            -
            -
            -
            -
          14. -
          15. - -

            neutral_slopes

            -
            -
            -DESCRIPTION -
            -
            - Compute the neutral slope vector along with its magnitude. - The neutral slope vector is defined as -grad_h(rho)/(drho/dz). -
            -
            -
            -
            -
          16. -
          17. - -

            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. -
            -
            -
            -
            -
          18. -
          19. - -

            ocean_nphysics_new_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out the restart data for this module -
            -
            -
            -
            -
          20. -
          21. - -

            ocean_nphysics_new_end

            -
            -
            -DESCRIPTION -
            -
            - Writes out the restart data. -
            -
            -
            -
            -
          22. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies - Fundamentals of Ocean Climate Models (FOCM) (2004) - Princeton University Press -
          2. -
          3. - S.M. Griffies, Elements of MOM (2012) -
          4. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 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

          - - -
          -Contact:  Tim Leslie -,  - Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_nphysics_skew_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization routine. -
            -
            -
            -
            -
          2. -
          3. - -

            register fields

            -
            -
            -DESCRIPTION -
            -
            - Register diagnostic fields. -
            -
            -
            -
            -
          4. -
          5. - -

            gm_tensor

            -
            -
            -DESCRIPTION -
            -
            - Compute the skew tensor terms using the GM method. -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            do_regularize_transport

            -
            -
            -DESCRIPTION -
            -
            - regularize the transport to keep magnitude - under control in regions of weak vertical stratification. -
            -
            -
            -
            -
          10. -
          11. - -

            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 - -
            -
            -
            -
            -
          12. -
          13. - -

            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). - -
            -
            -
            -
            -
          14. -
          15. - -

            do_smooth_transport

            -
            -
            -DESCRIPTION -
            -
            - -
            -
            -
            -
            -
          16. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
          2. -
          3. - 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. -
          4. -
          5. - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
          6. -
          7. - S.M. Griffies: Elements of MOM (2012) -
          8. -
          -
          -
          - -
          -
          -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 @@ - - - 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). - - - 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 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

          - - -
          -Contact:  Tim Leslie -,  - Stephen M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_nphysics_tensor_init

            -
            -
            -DESCRIPTION -
            -
            - Initialise this module. -
            -
            -
            -
            -
          2. -
          3. - -

            register fields

            -
            -
            -DESCRIPTION -
            -
            - Register diagnostic fields. -
            -
            -
            -
            -
          4. -
          5. - -

            compute_tensors

            -
            -
            -DESCRIPTION -
            -
            - Compute the tensor components for the diffusion and skew-diffusion tensor. -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            diffusion_tensor

            -
            -
            -DESCRIPTION -
            -
            - Compute the components of the neutral diffusion tensor. -
            -
            -
            -
            -
          10. -
          11. - -

            compute_diffusion_tapers

            -
            -
            -DESCRIPTION -
            -
            - Compute the taper functions to be applied to the components of the diffusion - tensor. -
            -
            -
            -
            -
          12. -
          13. - -

            compute_masked_tensor

            -
            -
            -DESCRIPTION -
            -
            - This function applies the boundary conditions relevent to the flags - tmask_neutral_on and tmask_sigma_on. -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          NAMELIST

          - -
          -&ocean_nphysics_tensor_nml -
          -
          -
          -
          -
          - -
          -
          - -
          -[logical] -
          -
          -
          -
          -
          - - - - -
          -

          REFERENCES

          - -
          -
            -
          1. - S.M. Griffies - The Gent-McWilliams Skew-flux - Journal of Physical Oceanography (1998) vol 28 pages 831-841 -
          2. -
          3. - 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. -
          4. -
          5. - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
          6. -
          7. - S.M. Griffies: Elements of MOM (2012) -
          8. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -Module ocean_nphysics_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_nphysics_util_mod

          - - -
          -Contact:  Stephen M. Griffies - -
          -Reviewers:  Tim Leslie - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_nphysics_util_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the utility module for neutral physics. -
            -
            -
            -
            -
          2. -
          3. - -

            cabbeling_thermob_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the cabbeling and thermobaricity related diagnostic - fields and register the diagnostics to the diag manager. -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            compute_eady_rate

            -
            -
            -DESCRIPTION -
            -
            - Finish computing eady growth rate. -
            -
            -
            -
            -
          12. -
          13. - -

            compute_baroclinicity

            -
            -
            -DESCRIPTION -
            -
            - Finish computing baroclinicity, which is defined to be the vertically - averaged magnitude of the horizontal density gradient. -
            -
            -
            -
            -
          14. -
          15. - -

            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). -
            -
            -
            -
            -
          16. -
          17. - -

            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. - -
            -
            -
            -
            -
          18. -
          19. - -

            compute_diffusivity

            -
            -
            -DESCRIPTION -
            -
            - Subroutine computes flow dependent diffusivity. - Allow for an added dimensionless tuning factor as well as a - minimum and maximum diffusivity. -
            -
            -
            -
            -
          20. -
          21. - -

            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 -
            -
            -
            -
            -
          22. -
          23. - -

            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 - -
            -
            -
            -
            -
          24. -
          25. - -

            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 - -
            -
            -
            -
            -
          26. -
          27. - -

            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 - -
            -
            -
            -
            -
          28. -
          29. - -

            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 - -
            -
            -
            -
            -
          30. -
          31. - -

            pressure_derivs

            -
            -
            -DESCRIPTION -
            -
            - Compute the pressure derivatives for use in thermobaricity diagnostic. -
            -
            -
            -
            -
          32. -
          33. - -

            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. - -
            -
            -
            -
            -
          34. -
          35. - -

            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. - -
            -
            -
            -
            -
          36. -
          37. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          38. -
          39. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from nphysics on the watermass transformation. - For use with nphysicsA and nphysicsB. -
            -
            -
            -
            -
          40. -
          41. - -

            watermass_diag_ndiffuse

            -
            -
            -DESCRIPTION -
            -
            - - Diagnose watermass transformation from neutral diffusion. - For use with the nphysicsC scheme. - -
            -
            -
            -
            -
          42. -
          43. - -

            watermass_diag_sdiffuse

            -
            -
            -DESCRIPTION -
            -
            - - Diagnose watermass transformation from skew diffusion. - For use with the neutral physics C scheme. - -
            -
            -
            -
            -
          44. -
          45. - -

            ocean_nphysics_util_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          46. -
          47. - -

            ocean_nphysics_coeff_end

            -
            -
            -DESCRIPTION -
            -
            - Write to restart. -
            -
            -
            -
            -
          48. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - 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 -
          4. -
          5. - 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 -
          6. -
          7. - 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 -
          8. -
          9. - 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. -
          10. -
          11. - K. Eden, Eddy length scales in the North Atlantic, 2007, - Preprint. -
          12. -
          13. - K. Eden and R. Greatbatch, 2008: Towards a mesoscale eddy closure, - Ocean Modelling, vol. 20, pages 223-239 -
          14. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 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

          - - -
          -Contact:  Tim Leslie - -
          -Reviewers:  Stephen M. Griffies - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            stencil_centre_to_vert

            -
            -
            -DESCRIPTION -
            -
            - Initialise the grid indices and constants. -
            -
            -
            -
            -
          2. -
          3. - -

            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-----| - | : | - | : | - |_____:_____| -
            -
            -
            -
            -
          4. -
          5. - -

            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 : | - |_____:_____| |_____:_____|_____:_____| -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          9. - -

            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. -
            -
            -
            -
            -
          10. -
          11. - -

            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. -
            -
            -
            -
            -
          12. -
          13. - -

            check_init

            -
            -
            -DESCRIPTION -
            -
            - Helper function to ensure the module is initialised when calling the - module's functions. -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - K. Eden and R. Greatbatch, 2008: Towards a mesoscale eddy closure, - Ocean Modelling, vol. 20, pages 223-239 -
          4. -
          5. - S.M. Griffies "Elements of MOM (2012) (EoM)" -
          6. -
          7. - S.M. Griffies - Fundamentals of Ocean Climate Models (2004) - Princeton University Press -
          8. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_increment_eta_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_increment_eta_mod

          - - -
          -Contact:  Russell Fiedler -,  - Paul Sandery - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_increment_eta_source

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calculates thickness weighted and density weighted - time tendencies of etas due to damping by increments. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_increment_tracer_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_increment_tracer_mod

          - - -
          -Contact:  Russell Fiedler -,  - Paul Sandery - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_increment_tracer_source

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calculates thickness weighted and density weighted - time tendencies of tracers due to damping by increments. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_increment_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_increment_velocity_mod

          - - -
          -Contact:  Russell Fiedler -,  - Paul Sandery - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_increment_velocity_source

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calculates thickness weighted and density weighted - time tendencies of velocitys due to damping by increments. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_momentum_source_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_momentum_source_mod

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_momentum_source_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for momentum source/sink -
            -
            -
            -
            -
          2. -
          3. - -

            momentum_source

            -
            -
            -DESCRIPTION -
            -
            - Compute the momentum source/sink (N/m2). -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            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]
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
          2. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -Module ocean_overexchange_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_overexchange_mod

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_overexchange_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for mixing of tracers into the abyss next to topography. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          6. -
          7. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from overexchange on the watermass transformation. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 -
          2. -
          3. - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
          4. -
          5. - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
          6. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -Module ocean_overflow_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_overflow_mod

          - - -
          -Contact:  S.M. Griffies -,  - Michael Bates - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_overflow_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for mixing of tracers into the abyss next to topography. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          6. -
          7. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from overflow on the watermass transformation. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Campin and Goosse (1999): Parameterization of density-driven downsloping flow - for a coarse-resolution model in z-coordinate", Tellus 51A, pages 412-430 -
          2. -
          3. - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
          4. -
          5. - S.M. Griffies, Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
          6. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_overflow_OFP_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for OFP -
            -
            -
            -
            -
          2. -
          3. - -

            overflow_OFP

            -
            -
            -DESCRIPTION -
            -
            - Compute overflow process - - -
            -
            -
            -
            -
          4. -
          5. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          6. -
          7. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from overflow on the watermass transformation. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - Danabasoglu G., W. G. Large and B. P. Briegleb (2010), Climate impacts of parameterized - Nordic Sea Overflow, Journal of Geophysical Research, (submitted) -
          4. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_rivermix_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for mixing of tracers at runoff points. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            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 -
            -
            -
            -
            -
          10. -
          11. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          12. -
          13. - -

            watermass_diag_river

            -
            -
            -DESCRIPTION -
            -
            - watermass diagnostics for river = runoff + calving. -
            -
            -
            -
            -
          14. -
          15. - -

            watermass_diag_runoff

            -
            -
            -DESCRIPTION -
            -
            - watermass diagnostics for liquid runoff -
            -
            -
            -
            -
          16. -
          17. - -

            watermass_diag_calving

            -
            -
            -DESCRIPTION -
            -
            - watermass diagnostics for solid calving. -
            -
            -
            -
            -
          18. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
          2. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_riverspread_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_riverspread_mod

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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 - -
            -
            -
            -
            -
          2. -
          3. - -

            spread_river_horz

            -
            -
            -DESCRIPTION -
            -
            - Provide conservative spreading of river runoff field. -
            -
            -
            -
            -
          4. -
          5. - -

            riverspread_laplacian

            -
            -
            -DESCRIPTION -
            -
            - Provide conservative spreading of river runoff field using a - Laplacian operator. -
            -
            -
            -
            -
          6. -
          7. - -

            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]
            -
            -
            -
            -
          8. -
          9. - -

            on_comp_domain

            -
            -
            -DESCRIPTION -
            -
            - Determine if the point is in comp-domain for the processor -
            -
            -
            -
            -
          10. -
          11. - -

            on_data_domain

            -
            -
            -DESCRIPTION -
            -
            - Determine if the point is in data-domain for the processor -
            -
            -
            -
            -
          12. -
          - - - - -
          -

          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 @@ - - - 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 - 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 @@ - - - -Module ocean_shortwave_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_shortwave_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_shortwave_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the shorwave module -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_irradiance_init

            -
            -
            -DESCRIPTION -
            -
            - - Initialize the irradiance diagnostic tracer. - -
            -
            -
            -
            -
          4. -
          5. - -

            sw_source

            -
            -
            -DESCRIPTION -
            -
            - - Choose either of the GFDL, CSIRO, JERLOV or External sw_source methods. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          10. -
          11. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from shortwave heating on watermass transformation. -
            -
            -
            -
            -
          12. -
          - - - - -
          -

          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 @@ - - - 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. - 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 ! ! -! 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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_shortwave_csiro_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the shortwave module -
            -
            -
            -
            -
          2. -
          3. - -

            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)" - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Jerlov (1968) - Optical Oceanography - Elsevier Press -
          2. -
          3. - 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 -
          4. -
          5. - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 -
          6. -
          7. - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. -
          8. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_shortwave_gfdl_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the shorwave module -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Jerlov (1968): Optical Oceanography, Elsevier Press -
          2. -
          3. - 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 -
          4. -
          5. - 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 -
          6. -
          7. - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 -
          8. -
          9. - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. -
          10. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_shortwave_jerlov_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_shortwave_jerlov_mod

          - - -
          -Contact:  Martin Schmidt - -
          -Reviewers:  S.M. Griffies - -
          -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. - - 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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_shortwave_jerlov_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the shortwave module -
            -
            -
            -
            -
          2. -
          3. - -

            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)" - -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Jerlov (1968) - Optical Oceanography - Elsevier Press -
          2. -
          3. - Paulson and Simpson (1977) - Irradiance measurements in the upper ocean - Journal of Physical Oceanography vol 7 pages 952-956 -
          4. -
          5. - Rosati and Miyakoda (1988) - A General Circulation Model for Upper Ocean Simulation - Journal of Physical Oceanography vol 18 pages 1601-1626. -
          6. -
          -
          -
          - - -
          -

          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 @@ - - - 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)" - - 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 @@ - - - -Module ocean_sponges_eta_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_sponges_eta_mod

          - - -
          -Contact:  Paul Sandery - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            sponge_eta_source

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calculates thickness weighted and density weighted - time tendencies due to damping by sponges or damping through adaptive - restoring. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            sponge_tracer_source

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calculates thickness weighted and density weighted - time tendencies of tracers due to damping by sponges. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_sponges_velocity_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_sponges_velocity_mod

          - - -
          -Contact:  Paul Sandery - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            sponge_velocity_source

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calculates thickness weighted and density weighted - time tendencies due to damping by sponges. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. - -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            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]
            -
            -
            -
            -
          8. -
          9. - -

            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]
            -
            -
            -
            -
          10. -
          11. - -

            on_processor

            -
            -
            -DESCRIPTION -
            -
            - Determine if the point is on processor -
            -
            -
            -
            -
          12. -
          13. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          14. -
          15. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from xlandinsert on watermass transformation. -
            -
            -
            -
            -
          16. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2003) - NOAA/Geophysical Fluid Dynamics Laboratory -
          2. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            xlandmix_mass

            -
            -
            -DESCRIPTION -
            -
            - Compute the mass source kg/(m^2*sec). - Note that xlandmix has already been called, so xland_mass has been - filled. -
            -
            -
            -
            -
          6. -
          7. - -

            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]
            -
            -
            -
            -
          8. -
          9. - -

            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]
            -
            -
            -
            -
          10. -
          11. - -

            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]
            -
            -
            -
            -
          12. -
          13. - -

            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]
            -
            -
            -
            -
          14. -
          15. - -

            on_processor

            -
            -
            -DESCRIPTION -
            -
            - Determine if the point is on processor -
            -
            -
            -
            -
          16. -
          17. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          18. -
          19. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from xlandmix on watermass transformation. -
            -
            -
            -
            -
          20. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) - NOAA/Geophysical Fluid Dynamics Laboratory -
          2. -
          3. - S.M. Griffies: Elements of MOM (2012) - NOAA/Geophysical Fluid Dynamics Laboratory -
          4. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -Module ocean_convect_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_convect_mod

          - - -
          -Contact:  Stephen M. Griffies -,  - R. Fiedler - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            convection

            -
            -
            -DESCRIPTION -
            -
            - Subroutine calls one of the two possible convection schemes. -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            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 - -
            -
            -
            -
            -
          10. -
          11. - -

            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 - -
            -
            -
            -
            -
          12. -
          13. - -

            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 - -
            -
            -
            -
            -
          14. -
          15. - -

            convection_diag

            -
            -
            -DESCRIPTION -
            -
            - Some diagnostics for convection. -
            -
            -
            -
            -
          16. -
          17. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          18. -
          19. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from convection of - temp and salt on the watermass transformation diagnostics. - -
            -
            -
            -
            -
          20. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Stefan Rahmstorf (Ocean Modelling, 1993 vol 101 pages 9-11) -
          2. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - -
          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 @@ - - - -Module ocean_form_drag_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_form_drag_mod

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_form_drag_init

            -
            -
            -DESCRIPTION -
            -
            - Initial set up for parameterized pressure form drag. -
            -
            -
            -
            -
          2. -
          3. - -

            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) - -
            -
            -
            -
            -
          4. -
          5. - -

            form_drag_accel

            -
            -
            -DESCRIPTION -
            -
            - Compute the rho*dz weighted acceleration from the Aiki etal - form drag scheme. -
            -
            -
            -
            -
          6. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - 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. -
          4. -
          5. - Aiki, Jacobson, and Yamagata, 2004: Parameterizing ocean eddy transports - from surface to bottom. Geophysical Research Letters, vol. 31. -
          6. -
          7. - Ferreira and Marshall, 2006: Formulation and implementation of - a residual-mean ocean circulation model. Ocean Modelling, - vol. 13, pages 86--107. -
          8. -
          9. - Danabosaglu and Marshall, 2007: Effects of vertical variations of thickness - diffusivity in an ocean general circulation model. - Ocean Modelling, vol. 18, pages 122-141. -
          10. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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 @@ - - - -Module ocean_vert_chen_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_vert_chen_mod

          - - -
          -Contact:  Russell Fiedler - -
          -Reviewers:  S.M. Griffies - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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 - -
            -
            -
            -
            -
          2. -
          3. - -

            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)
            - -
            -
            -
            -
            -
          4. -
          5. - -

            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 - -
            -
            -
            -
            -
          6. -
          7. - -

            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 -
            -
            -
            -
            -
          8. -
          9. - -

            ocean_vert_chen_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          10. -
          11. - -

            ocean_vert_chen_end

            -
            -
            -DESCRIPTION -
            -
            - Save the Kraus boundary layer depth to start next time step. -
            -
            -
            -
            -
          12. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          -
          -
          - - -
          -

          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 @@ - - - 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. -
          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 @@ - - - -Module ocean_vert_const_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_vert_const_mod

          - - -
          -Contact:  -
          -Reviewers:  Stephen M. Griffies - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_vert_const_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the constant vertical diffusivity module. -
            -
            -
            -
            -
          2. -
          3. - -

            vert_mix_const

            -
            -
            -DESCRIPTION -
            -
            - This function computes the vertical diffusivity and viscosity. - These mixing coefficients are time independent but generally - arbitrary functions of space. -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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 @@ - - - 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. - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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. - -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            advect_gotm_upwind

            -
            -
            -DESCRIPTION -
            -
            - First order upwind to advect GOTM scalar turbulence quantities tke and diss. -
            -
            -
            -
            -
          8. -
          9. - -

            advect_gotm_sweby

            -
            -
            -DESCRIPTION -
            -
            - Sweby scheme to advect GOTM scalar turbulence quantities tke and diss. -
            -
            -
            -
            -
          10. -
          11. - -

            ocean_vert_gotm_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          12. -
          13. - -

            ocean_vert_gotm_end

            -
            -
            -DESCRIPTION -
            -
            - Save the advection term for restarting the next time step. -
            -
            -
            -
            -
          14. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - 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
          ! ! -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 !
          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 * 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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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 - -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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
            - -
            -
            -
            -
            -
          6. -
          7. - -

            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 - -
            -
            -
            -
            -
          8. -
          9. - -

            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)
            - -
            -
            -
            -
            -
          10. -
          11. - -

            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
            - - -
            -
            -
            -
            -
          12. -
          13. - -

            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) - -
            -
            -
            -
            -
          14. -
          15. - -

            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 - -
            -
            -
            -
            -
          16. -
          17. - -

            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 -
            -
            -
            -
            -
          18. -
          19. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          20. -
          21. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from KPP nonlocal on the watermass transformation. -
            -
            -
            -
            -
          22. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - 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 -
          4. -
          -
          -
          - - -
          -

          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 @@ - - - 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. -
          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
          ! ! -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 !
          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 * 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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_vert_kpp_mom4p1_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the KPP vertical mixing scheme -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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
            - -
            -
            -
            -
            -
          6. -
          7. - -

            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 - -
            -
            -
            -
            -
          8. -
          9. - -

            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)
            - -
            -
            -
            -
            -
          10. -
          11. - -

            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
            - - -
            -
            -
            -
            -
          12. -
          13. - -

            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) - -
            -
            -
            -
            -
          14. -
          15. - -

            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 - -
            -
            -
            -
            -
          16. -
          17. - -

            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 -
            -
            -
            -
            -
          18. -
          19. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          20. -
          21. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from KPP nonlocal on the watermass transformation. -
            -
            -
            -
            -
          22. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - Danabasoglu etal (2006) - Diurnal coupling in the tropical oceans of CCSM3 - Journal of Climate (2006) vol 19 pages 2347--2365 -
          4. -
          -
          -
          - - -
          -

          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 @@ - - - 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. -
          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 * 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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_vert_kpp_test_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the KPP vertical mixing scheme -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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 - -
            -
            -
            -
            -
          6. -
          7. - -

            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 - -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            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 - -
            -
            -
            -
            -
          12. -
          13. - -

            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) - -
            -
            -
            -
            -
          14. -
          15. - -

            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 - -
            -
            -
            -
            -
          16. -
          17. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. -
            -
            -
            -
            -
          18. -
          19. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Diagnose effects from KPP nonlocal on the watermass transformation. -
            -
            -
            -
            -
          20. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          3. - Danabasoglu etal (2006) - Diurnal coupling in the tropical oceans of CCSM3 - Journal of Climate (2006) vol 19 pages 2347--2365 -
          4. -
          -
          -
          - - -
          -

          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 @@ - - - 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. -
          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 ! -! 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

          - - -
          -Contact:  S.M. Griffies - -
          -Reviewers:  A. Rosati - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_vert_mix_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the vertical mixing module. -
            -
            -
            -
            -
          2. -
          3. - -

            diff_cbt_table_init

            -
            -
            -DESCRIPTION -
            -
            - Read in static diffusivities that have been entered to the diff_cbt_table. -
            -
            -
            -
            -
          4. -
          5. - -

            bryan_lewis_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the Bryan-Lewis static background diffusivities. -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            diff_cbt_tanh_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the tanh background diffusivity. -
            -
            -
            -
            -
          10. -
          11. - -

            vert_friction_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize vertical friction portion of ocean_vert_mix_mod -
            -
            -
            -
            -
          12. -
          13. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization of watermass diagnostic output files. - Also determine the logical compute_watermass_diag. -
            -
            -
            -
            -
          14. -
          15. - -

            vert_mix_coeff

            -
            -
            -DESCRIPTION -
            -
            - This subroutine calls the relevant scheme to compute vertical - diffusivity and vertical viscosity. Background values are - also incorporated here. -
            -
            -
            -
            -
          16. -
          17. - -

            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. - -
            -
            -
            -
            -
          18. -
          19. - -

            vert_diffuse_implicit

            -
            -
            -DESCRIPTION -
            -
            - Contributions to thickness weighted and density weighted time - tendency from time-implicit vertical diffusion. -
            -
            -
            -
            -
          20. -
          21. - -

            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. - -
            -
            -
            -
            -
          22. -
          23. - -

            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. - -
            -
            -
            -
            -
          24. -
          25. - -

            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. - -
            -
            -
            -
            -
          26. -
          27. - -

            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. - -
            -
            -
            -
            -
          28. -
          29. - -

            on_comp_domain

            -
            -
            -DESCRIPTION -
            -
            - Determine if the point is in comp-domain for the processor. -
            -
            -
            -
            -
          30. -
          31. - -

            invcosh

            -
            -
            -DESCRIPTION -
            -
            - Inverse cosh function. Argument must be >=1. -
            -
            -
            -
            -
          32. -
          33. - -

            vmix_min_dissipation

            -
            -
            -DESCRIPTION -
            -
            - Impose a floor to the dissipation arising from vertical tracer diffusion. -
            -
            -
            -
            -
          34. -
          35. - -

            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. - -
            -
            -
            -
            -
          36. -
          37. - -

            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. - -
            -
            -
            -
            -
          38. -
          39. - -

            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. - -
            -
            -
            -
            -
          40. -
          41. - -

            ocean_vert_mix_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          42. -
          43. - -

            ocean_vert_mix_end

            -
            -
            -DESCRIPTION -
            -
            - Chen Scheme requires output of Krauss mixed layer for - reproducible results. - - GOTM requires fields for advection tendency. - -
            -
            -
            -
            -
          44. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Kirk Bryan and L.J. Lewis - A water mass model of the world ocean - Journal of Geophysical Research (1979) vol 84, pages 2503--2517 -
          2. -
          3. - Elements of MOM (2012) - S.M. Griffies -
          4. -
          5. - 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. -
          6. -
          -
          -
          - - -
          -

          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 @@ - - - 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. - - 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 @@ - - - -Module ocean_vert_pp_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_vert_pp_mod

          - - -
          -Contact:  Stephen Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
            -
          1. - -

            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 - -
            -
            -
            -
            -
          2. -
          3. - -

            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) - -
            -
            -
            -
            -
          4. -
          5. - -

            ri_for_pp

            -
            -
            -DESCRIPTION -
            -
            - Compute richardson number for the pp scheme -
            -
            -
            -
            -
          6. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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 -
          2. -
          -
          -
          - - -
          -

          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 @@ - - - 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 - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_vert_tidal_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization for the ocean_vert_tidal module. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          7. - -

            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. - -
            -
            -
            -
            -
          8. -
          9. - -

            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. - -
            -
            -
            -
            -
          10. -
          11. - -

            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. - -
            -
            -
            -
            -
          12. -
          13. - -

            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. - -
            -
            -
            -
            -
          14. -
          15. - -

            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. - -
            -
            -
            -
            -
          16. -
          17. - -

            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. - -
            -
            -
            -
            -
          18. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - Jayne and St. Laurent, 2001: - Parameterizing tidal dissipation over rough topography. - Geophysical Research Letters, vol. 28, pages 811-814. -
          4. -
          5. - 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 -
          6. -
          7. - Osborn, T.R., 1980: Estimates of the local rate of vertical diffusion - from dissipation measurements. JPO, vol. 10, pages 83-89. -
          8. -
          9. - Munk and Anderson, 1948: Notes on a theory of the thermocline. - Journal of Marine Research, vol 3. pages 276-295. -
          10. -
          11. - S.M. Griffies, Elements of MOM (2012) -
          12. -
          -
          -
          - -
          -
          -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 @@ - - - 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. - - 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. +! +! 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 + + +!####################################################################### +! +! +! +! 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="ocean_vert_tidal_test_init" + + +!####################################################################### +! +! +! +! 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="vert_mix_tidal_test" + + + +!####################################################################### +! +! +! +! 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="compute_bvfreq" + + + +!####################################################################### +! +! +! +! 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_wave" + + +!####################################################################### +! +! +! +! 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_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 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="vert_mix_drag_cgrid" + + +!####################################################################### +! +! +! +! 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="compute_bvfreq_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_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 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 +! 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 @@ - - - -Module ocean_vert_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
          -

          Module ocean_vert_util_mod

          - - -
          -Contact:  S. M. Griffies - -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_vert_util_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize vertical mixing utilities. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. - -
            -
            -
            -
            -
          6. -
          - - - - -
          -

          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 @@ - - - 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. - - 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 @@ - - - -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_age_tracer_end

            -
            -
            -DESCRIPTION -
            -
            - Finish up calculations for the tracer packages, - possibly writing out non-field restart information -
            -
            -
            -
            -
          2. -
          3. - -

            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. -
            -
            -
            -
            -
          4. -
          5. - -

            ocean_age_tracer_source

            -
            -
            -DESCRIPTION -
            -
            - Calculate the source arrays for the tracer packages -
            -
            -
            -
            -
          6. -
          7. - -

            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 -
            -
            -
            -
            -
          8. -
          9. - -

            ocean_age_tracer_tracer

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to do calculations needed every time-step after - the continuity equation has been integrated -
            -
            -
            -
            -
          10. -
          11. - -

            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. -
            -
            -
            -
            -
          12. -
          - - - - - - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_frazil_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization code for the frazil diagnostic tracer. -
            -
            -
            -
            -
          2. -
          3. - -

            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 - -
            -
            -
            -
            -
          4. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - 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. -
          2. -
          3. - "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. -
          4. -
          -
          -
          - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_passive_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the indices for passive tracer fields. - This routine is called by ocean_model.F90. -
            -
            -
            -
            -
          2. -
          3. - -

            passive_tracer_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize profiles for the passive tracers. - This routine is called by ocean_tracer.F90. -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            surface_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize passive tracer according to a particular iso-surface. -
            -
            -
            -
            -
          8. -
          9. - -

            layer_init

            -
            -
            -DESCRIPTION -
            -
            - - Initialize tracer inside a depth layer to have a value, and - zero outside the layer. - -
            -
            -
            -
            -
          10. -
          11. - -

            wall_init

            -
            -
            -DESCRIPTION -
            -
            - - Initialize tracer inside an (i,k) wall to have a value, and - zero outside the wall. - -
            -
            -
            -
            -
          12. -
          13. - -

            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"). - -
            -
            -
            -
            -
          14. -
          15. - -

            patch_init_klevel

            -
            -
            -DESCRIPTION -
            -
            - Initialize tracer with gaussian patch or constant on a level, - both on a single k-level -
            -
            -
            -
            -
          16. -
          17. - -

            exponential_init

            -
            -
            -DESCRIPTION -
            -
            - - Initialize tracer with a vertical exponential profile. - -
            -
            -
            -
            -
          18. -
          19. - -

            shelfbowl_init

            -
            -
            -DESCRIPTION -
            -
            - - Initialize tracer as in the shelfbowl topography of use for studying - idealized overflow problems, as in Winton etal (1998). - -
            -
            -
            -
            -
          20. -
          21. - -

            update_tracer_passive

            -
            -
            -DESCRIPTION -
            -
            - Update the squared tracer. - Restore passive tracers. -
            -
            -
            -
            -
          22. -
          - - - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_residency_init

            -
            -
            -DESCRIPTION -
            -
            - Set up any extra fields needed by the tracer packages -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_residency_source

            -
            -
            -DESCRIPTION -
            -
            - Calculate the source arrays for the tracer packages -
            -
            -
            -
            -
          4. -
          5. - -

            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 -
            -
            -
            -
            -
          6. -
          7. - -

            ocean_residency_tracer

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to do calculations needed every time-step after - the continuity equation has been integrated -
            -
            -
            -
            -
          8. -
          - - - - - - -
          -
          -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

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_residency_integrand_start

            -
            -
            -DESCRIPTION -
            -
            - Start the ocean residency integrand package - -
            -
            -
            -
            -
          4. -
          - - - - - - -
          -
          -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

          - -
            -
          1. - -

            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. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            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. -
            -
            -
            -
            -
          8. -
          - - - - - - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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 -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_residency_ml_start

            -
            -
            -DESCRIPTION -
            -
            - Start the ocean residency mixed layer package - -
            -
            -
            -
            -
          4. -
          - - - - - - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            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 -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_residency_range_start

            -
            -
            -DESCRIPTION -
            -
            - Start the ocean residency tracer range package - -
            -
            -
            -
            -
          4. -
          - - - - - - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_tempsalt_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the temperature/salinity module. -
            -
            -
            -
            -
          2. -
          3. - -

            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. - -
            -
            -
            -
            -
          4. -
          5. - -

            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 - -
            -
            -
            -
            -
          6. -
          7. - -

            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 - -
            -
            -
            -
            -
          8. -
          9. - -

            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 - -
            -
            -
            -
            -
          10. -
          11. - -

            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. - -
            -
            -
            -
            -
          12. -
          13. - -

            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). - -
            -
            -
            -
            -
          14. -
          15. - -

            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). - -
            -
            -
            -
            -
          16. -
          17. - -

            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 - -
            -
            -
            -
            -
          18. -
          19. - -

            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 - -
            -
            -
            -
            -
          20. -
          21. - -

            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 - -
            -
            -
            -
            -
          22. -
          23. - -

            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. - -
            -
            -
            -
            -
          24. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - Feistel (2003) - A new extended Gibbs thermodynamic potential of seawater - Progress in Oceanography. vol 58, pages 43-114. -
          2. -
          3. - 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. -
          4. -
          -
          -
          - -
          -
          -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

          - - -
          -Contact:  Richard D. Slater - -
          -Reviewers:  John P. Dunne - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            do_time_calc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform time calculations -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_tpm_bbc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform bottom boundary condition - calculations -
            -
            -
            -
            -
          4. -
          5. - -

            ocean_tpm_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          6. -
          7. - -

            ocean_tpm_end

            -
            -
            -DESCRIPTION -
            -
            - Finish up calculations for the tracer packages, - possibly writing out non-field restart information -
            -
            -
            -
            -
          8. -
          9. - -

            ocean_tpm_init_sfc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform surface coupler initializations - - Note: this subroutine should be merged into ocean_tpm_start -
            -
            -
            -
            -
          10. -
          11. - -

            ocean_tpm_sum_sfc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform surface coupler initializations -
            -
            -
            -
            -
          12. -
          13. - -

            ocean_tpm_avg_sfc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform surface coupler initializations -
            -
            -
            -
            -
          14. -
          15. - -

            ocean_tpm_zero_sfc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform surface coupler initializations -
            -
            -
            -
            -
          16. -
          17. - -

            ocean_tpm_sfc_end

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform surface coupler initializations -
            -
            -
            -
            -
          18. -
          19. - -

            ocean_tpm_sbc

            -
            -
            -DESCRIPTION -
            -
            - call subroutines to perform surface boundary condition - calculations -
            -
            -
            -
            -
          20. -
          21. - -

            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. -
            -
            -
            -
            -
          22. -
          23. - -

            ocean_tpm_flux_init

            -
            -
            -DESCRIPTION -
            -
            - Set up any extra fields needed by the ocean-atmosphere gas fluxes -
            -
            -
            -
            -
          24. -
          25. - -

            ocean_tpm_source

            -
            -
            -DESCRIPTION -
            -
            - Calculate the source arrays for the tracer packages -
            -
            -
            -
            -
          26. -
          27. - -

            ocean_tpm_start

            -
            -
            -DESCRIPTION -
            -
            - Start the tracer packages. - This could include reading in extra restart information, - processing namelists or doing initial calculations -
            -
            -
            -
            -
          28. -
          29. - -

            ocean_tpm_tracer

            -
            -
            -DESCRIPTION -
            -
            - Subroutine to do calculations needed every time-step after - the continuity equation has been integrated -
            -
            -
            -
            -
          30. -
          - - - - - - -
          -
          -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

          - - -
          -Contact:  Richard D. Slater - -
          -Reviewers:  John P. Dunne - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            check_ocean_mod

            -
            -
            -DESCRIPTION -
            -
            - Be sure that the /ocean_mod hierarchy has been initialized. -
            -
            -
            -
            -
          2. -
          3. - -

            otpm_set_tracer_package

            -
            -
            -DESCRIPTION -
            -
            - Set the values for a tracer package and return its index (0 on error) - -
            -
            -
            -
            -
          4. -
          5. - -

            set_prog_value_integer

            -
            -
            -DESCRIPTION -
            -
            - Set an integer value for a prognostic tracer element in the Field Manager tree. -
            -
            -
            -
            -
          6. -
          7. - -

            set_prog_value_logical

            -
            -
            -DESCRIPTION -
            -
            - Set a logical value for a prognostic tracer element in the Field Manager tree. -
            -
            -
            -
            -
          8. -
          9. - -

            set_prog_value_real

            -
            -
            -DESCRIPTION -
            -
            - Set a real value for a prognostic tracer element in the Field Manager tree. -
            -
            -
            -
            -
          10. -
          11. - -

            set_prog_value_string

            -
            -
            -DESCRIPTION -
            -
            - Set a string value for a prognostic tracer element in the Field Manager tree. -
            -
            -
            -
            -
          12. -
          13. - -

            otpm_set_prog_tracer

            -
            -
            -DESCRIPTION -
            -
            - Set the values for a prog tracer and return its index (0 on error) -
            -
            -
            -
            -
          14. -
          15. - -

            otpm_set_diag_tracer

            -
            -
            -DESCRIPTION -
            -
            - Set the values for a diag tracer and return its index (0 on error) -
            -
            -
            -
            -
          16. -
          - - - - - - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            ocean_prog_tracer_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization code for prognostic tracers, returning a pointer to - the T_prog array. -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_diag_tracer_init

            -
            -
            -DESCRIPTION -
            -
            - Initialization code for diagnostic tracers, returning a pointer to the T_diag array -
            -
            -
            -
            -
          4. -
          5. - -

            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. -
            -
            -
            -
            -
          6. -
          7. - -

            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 - -
            -
            -
            -
            -
          8. -
          9. - -

            ocean_tracer_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          10. -
          11. - -

            ocean_tracer_end

            -
            -
            -DESCRIPTION -
            -
            - Write ocean tracer restarts -
            -
            -
            -
            -
          12. -
          13. - -

            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. - -
            -
            -
            -
            -
          14. -
          15. - -

            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 - -
            -
            -
            -
            -
          16. -
          17. - -

            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 - -
            -
            -
            -
            -
          18. -
          19. - -

            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. - -
            -
            -
            -
            -
          20. -
          21. - -

            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. -
            -
            -
            -
            -
          22. -
          23. - -

            send_tracer_diagnostics

            -
            -
            -DESCRIPTION -
            -
            - - For sending some tracer diagnostics - -
            -
            -
            -
            -
          24. -
          25. - -

            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. - -
            -
            -
            -
            -
          26. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - R.C. Pacanowski and S.M. Griffies - The MOM3 Manual (1999) -
          2. -
          3. - S.M. Griffies, M.J. Harrison, R.C. Pacanowski, and A. Rosati - A Technical Guide to MOM4 (2004) -
          4. -
          5. - S.M. Griffies, Fundamentals of ocean climate models (2004) -
          6. -
          -
          -
          - -
          -
          -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

          - -
            -
          1. - -

            ocean_tracer_advect_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the tracer advection module. -
            -
            -
            -
            -
          2. -
          3. - -

            advection_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the main tracer advection diagnostics. -
            -
            -
            -
            -
          4. -
          5. - -

            watermass_diag_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the watermass diagnostics. -
            -
            -
            -
            -
          6. -
          7. - -

            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 - -
            -
            -
            -
            -
          8. -
          9. - -

            quicker_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize quicker specific fields. -
            -
            -
            -
            -
          10. -
          11. - -

            fourth_sixth_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the fourth order and sixth order advection fields. -
            -
            -
            -
            -
          12. -
          13. - -

            mdfl_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize mdfl and dst_linear specific fields. -
            -
            -
            -
            -
          14. -
          15. - -

            mdppm_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize mdppm specific fields. -
            -
            -
            -
            -
          16. -
          17. - -

            mdmdt_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize mdmdt specific fields. -
            -
            -
            -
            -
          18. -
          19. - -

            psom_init

            -
            -
            -DESCRIPTION -
            -
            - Read restart or initialize moments for prather advection -
            -
            -
            -
            -
          20. -
          21. - -

            horz_advect_tracer

            -
            -
            -DESCRIPTION -
            -
            - Compute horizontal advection of tracers -
            -
            -
            -
            -
          22. -
          23. - -

            vert_advect_tracer

            -
            -
            -DESCRIPTION -
            -
            - Compute vertical advection of tracers for case - with advect_sweby_all=.false. -
            -
            -
            -
            -
          24. -
          25. - -

            horz_advect_tracer_upwind

            -
            -
            -DESCRIPTION -
            -
            - Compute horizontal advection of tracers from first order upwind. - This scheme is positive definite but very diffusive. -
            -
            -
            -
            -
          26. -
          27. - -

            horz_advect_tracer_2nd_order

            -
            -
            -DESCRIPTION -
            -
            - Compute horizontal advection of tracers from second order - centered differences. -
            -
            -
            -
            -
          28. -
          29. - -

            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. - -
            -
            -
            -
            -
          30. -
          31. - -

            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. - -
            -
            -
            -
            -
          32. -
          33. - -

            horz_advect_tracer_quicker

            -
            -
            -DESCRIPTION -
            -
            - Compute horizontal advection of tracers from quicker. -
            -
            -
            -
            -
          34. -
          35. - -

            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. -
            -
            -
            -
            -
          36. -
          37. - -

            vert_advect_tracer_upwind

            -
            -
            -DESCRIPTION -
            -
            - Compute vertical advection of tracers from first order upwind. - This scheme is positive definite, but very diffusive. -
            -
            -
            -
            -
          38. -
          39. - -

            vert_advect_tracer_2nd_order

            -
            -
            -DESCRIPTION -
            -
            - Compute vertical advection of tracers from second order centered - differences. -
            -
            -
            -
            -
          40. -
          41. - -

            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. -
            -
            -
            -
            -
          42. -
          43. - -

            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. -
            -
            -
            -
            -
          44. -
          45. - -

            vert_advect_tracer_quicker

            -
            -
            -DESCRIPTION -
            -
            - Compute vertical advection of tracers from quicker. -
            -
            -
            -
            -
          46. -
          47. - -

            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. -
            -
            -
            -
            -
          48. -
          49. - -

            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 - -
            -
            -
            -
            -
          50. -
          51. - -

            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. - -
            -
            -
            -
            -
          52. -
          53. - -

            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). - -
            -
            -
            -
            -
          54. -
          55. - -

            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 - -
            -
            -
            -
            -
          56. -
          57. - -

            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. - -
            -
            -
            -
            -
          58. -
          59. - -

            psom_x

            -
            -
            -DESCRIPTION -
            -
            - Compute i-advective flux using Prather's SOM. -
            -
            -
            -
            -
          60. -
          61. - -

            psom_y

            -
            -
            -DESCRIPTION -
            -
            - Computes j-advective flux using Prather's SOM. -
            -
            -
            -
            -
          62. -
          63. - -

            psom_z

            -
            -
            -DESCRIPTION -
            -
            - Computes k-advective flux using Prather's SOM. -
            -
            -
            -
            -
          64. -
          65. - -

            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. - -
            -
            -
            -
            -
          66. -
          67. - -

            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 - -
            -
            -
            -
            -
          68. -
          69. - -

            ppm_limit_cw84

            -
            -
            -DESCRIPTION -
            -
            - - Kernel to limit the edge values for PPM following Colella and Woodward, 1984 - - Coded by Alistair.Adcroft - Apr 2006 - -
            -
            -
            -
            -
          70. -
          71. - -

            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 - -
            -
            -
            -
            -
          72. -
          73. - -

            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 -
            -
            -
            -
            -
          74. -
          75. - -

            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. - -
            -
            -
            -
            -
          76. -
          77. - -

            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 - -
            -
            -
            -
            -
          78. -
          79. - -

            watermass_diag

            -
            -
            -DESCRIPTION -
            -
            - Compute watermass diagnostics associated with resolved flow - advection of temperature and salinity. -
            -
            -
            -
            -
          80. -
          81. - -

            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. - -
            -
            -
            -
            -
          82. -
          83. - -

            get_tracer_stats

            -
            -
            -DESCRIPTION -
            -
            - Compute the upper/lower values of a 3D field, returning values via arguments -
            -
            -
            -
            -
          84. -
          85. - -

            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. - -
            -
            -
            -
            -
          86. -
          87. - -

            ocean_tracer_advect_restart

            -
            -
            -DESCRIPTION -
            -
            - Write out restart files registered through register_restart_file -
            -
            -
            -
            -
          88. -
          89. - -

            ocean_tracer_advect_end

            -
            -
            -DESCRIPTION -
            -
            - Write the PSOM moments for restarts. -
            -
            -
            -
            -
          90. -
          - - - - -
          -

          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

          - -
          -
            -
          1. - S.-J. Lin - A "Vertically Lagrangian" Finite-Volume Dynamical Core for Global Models - Month. Weather Rev. (2004) 132, 2293-2307 - (Appendix B) -
          2. -
          3. - H.T. Huynh - Schemes and Constraints for advection - 15th Intern. Conf. on Numeric. Meth. in Fluid Mech., Springer (1997) -
          4. -
          5. - Colella P. and P.R. Woodward - The piecewise parabloic method (PPM) for gasdynamical simulations - J. Comput. Phys. (1984) 54, 174-201 -
          6. -
          7. - A. Suresh and H.T. Huynh - Accurate Monotonicity-Preserving Schemes with Runge-Kutta Time Splitting - J. Comput. Phys. (1997) 136, 83-99 -
          8. -
          9. - V. Daru and C. Tenaud - High order one-step monotonicity-preserving schemes for unsteady - compressible flow calculations. - J. Comp. Phys. (2004) 193, 563-594 -
          10. -
          11. - R.C. Easter - Two modified versions of Botts positive-definite numerical advection scheme. - Month. Weath. Rev. (1993) 121, 297-304 -
          12. -
          13. - Prather, M. J.,"Numerical Advection by Conservation of Second-Order Moments" - JGR, Vol 91, NO. D6, p 6671-6681, May 20, 1986 -
          14. -
          15. - Merryfield and Holloway (2003), "Application of an accurate advection - algorithm to sea-ice modelling". Ocean Modelling, Vol 5, p 1-15. -
          16. -
          17. - Hundsdorder and Trompert (1994), "Method of lines and - direct discretization: a comparison for linear - advection", Applied Numerical Mathematics, - pages 469--490. -
          18. -
          19. - Sweby (1984): "High-resolution schemes using flux - limiters for hyperbolic conservation laws", - SIAM Journal of Numerical Analysis, vol. 21 - pages 995-1011. -
          20. -
          -
          -
          - -
          -
          -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

          - -
          - - -
          -

          PUBLIC ROUTINES

          - -
            -
          1. - -

            transport_matrix_init

            -
            -
            -DESCRIPTION -
            -
            - Set up any extra fields needed by tracer package manager -
            -
            -
            -
            -
          2. -
          3. - -

            transport_matrix_start

            -
            -
            -DESCRIPTION -
            -
            - - -
            -
            -
            -
            -
          4. -
          5. - -

            transport_matrix_store_explicit

            -
            -
            -DESCRIPTION -
            -
            - For the time explicit tendencies. -
            -
            -
            -
            -
          6. -
          7. - -

            transport_matrix_store_implicit

            -
            -
            -DESCRIPTION -
            -
            - For the time implicit tendencies. -
            -
            -
            -
            -
          8. -
          - - - - - - -
          -

          REFERENCES

          - -
          -
            -
          1. - Khatiwala, S., M. Visbeck, M.A. Cane, 2005. - Accelerated simulation of passive tracers in ocean circulation models. - Ocean Modelling, 9, 51-69. -
          2. -
          -
          -
          - -
          -
          -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

          - - -
          -Contact:  M. Schmidt - -
          -Reviewers:  S.M. Griffies - -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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

          - -
            -
          1. - -

            ocean_wave_init

            -
            -
            -DESCRIPTION -
            -
            - Initialize the wave module -
            -
            -
            -
            -
          2. -
          3. - -

            ocean_wave_model

            -
            -
            -DESCRIPTION -
            -
            - time step the wave model -
            -
            -
            -
            -
          4. -
          5. - -

            ocean_wave_prop

            -
            -
            -DESCRIPTION -
            -
            - wave propagation -
            -
            -
            -
            -
          6. -
          7. - -

            ocean_wave_diag

            -
            -
            -DESCRIPTION -
            -
            - wave diagnostics -
            -
            -
            -
            -
          8. -
          9. - -

            ocean_wave_filter

            -
            -
            -DESCRIPTION -
            -
            - wave filter -
            -
            -
            -
            -
          10. -
          11. - -

            read_wave

            -
            -
            -DESCRIPTION -
            -
            - Read wave restart information. -
            -
            -
            -
            -
          12. -
          13. - -

            ocean_wave_restart

            -
            -
            -DESCRIPTION -
            -
            - Save wave restart information. -
            -
            -
            -
            -
          14. -
          15. - -

            ocean_wave_end

            -
            -
            -DESCRIPTION -
            -
            - Write out external mode fields to restart file. -
            -
            -
            -
            -
          16. -
          17. - -

            wave_chksum

            -
            -
            -DESCRIPTION -
            -
            - Compute checksum for external mode fields. -
            -
            -
            -
            -
          18. -
          19. - -

            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]
            -
            -
            -
            -
          20. -
          - - - - -
          -

          NAMELIST

          - -
          -& -
          -
          -
          -
          -
          -
          -
          - - - - -
          -

          REFERENCES

          - -
          -
            -
          1. - 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). -
          2. -
          3. - Hughes, S. A. 1984. "TMA Shallow-Water Spectrum: - Description and Application," Technical Report CERC-84-7, - US Army Engineer Waterways Experiment Station, Vicksburg, Miss. -
          4. -
          -
          -
          - -
          -
          -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

          - - -
          -Contact:  -
          -Reviewers:  -
          -Change History: WebCVS Log -
          -
          -
          - - -
          -

          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" + +!####################################################################### +! +! +! +! 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="FMS_ocmip2_co2calc_old" + + +!####################################################################### +! +! +! +! 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 !} +! 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 !< - - -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

            - -
              -
            1. - -

              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]
              -
              -
              -
              -
            2. -
            3. - -

              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]
              -
              -
              -
              -
            4. -
            5. - -

              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]
              -
              -
              -
              -
            6. -
            7. - -

              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]
              -
              -
              -
              -
            8. -
            9. - -

              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]
              -
              -
              -
              -
            10. -
            11. - -

              generic_BLING_end

              -
              -call generic_BLING_end 
              -
              -
              -
              -DESCRIPTION -
              -
              - Deallocate all work arrays -
              -
              -
              -
              -
            12. -
            - - - - -
            -

            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

            - -
            -
              -
            1. - 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. -
            2. -
            -
            -
            - -
            -
            -top -
            - - diff --git a/src/ocean_shared/generic_tracers/generic_CFC.F90 b/src/ocean_shared/generic_tracers/generic_CFC.F90 index e8f35df2ff..8fa9b511be 100644 --- a/src/ocean_shared/generic_tracers/generic_CFC.F90 +++ b/src/ocean_shared/generic_tracers/generic_CFC.F90 @@ -102,6 +102,7 @@ module generic_CFC subroutine generic_CFC_register(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_register' !Specify all prognostic and diagnostic tracers of this modules. call user_add_tracers(tracer_list) @@ -131,6 +132,8 @@ end subroutine generic_CFC_register subroutine generic_CFC_init(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_init' + !Specify and initialize all parameters used by this package call user_add_params @@ -206,7 +209,7 @@ subroutine user_add_params ! pressure gradients, in units of kg m-3. call g_tracer_add_param('RHO_0', param%Rho_0, 1035.0) - call g_tracer_end_param_list() + call g_tracer_end_param_list(package_name) !=========== !Block Ends: g_tracer_add_param !=========== @@ -223,12 +226,14 @@ subroutine user_add_tracers(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'user_add_tracers' + call g_tracer_start_param_list(package_name)!nnz: Does this append? call g_tracer_add_param('ice_restart_file' , param%ice_restart_file , 'ice_ocmip2_cfc.res.nc') call g_tracer_add_param('ocean_restart_file' , param%ocean_restart_file , 'ocmip2_cfc.res.nc' ) call g_tracer_add_param('IC_file' , param%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=param%ice_restart_file, ocean_restart_file=param%ocean_restart_file ) @@ -288,6 +293,7 @@ end subroutine user_add_tracers ! subroutine generic_CFC_update_from_coupler(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_update_from_copler' ! !Nothing specific to be done for CFC's ! @@ -354,6 +360,8 @@ subroutine generic_CFC_set_boundary_values(tracer_list,ST,SSS,rho,ilb,jlb,taum1) real, dimension(:,:), ALLOCATABLE :: g_cfc_11_alpha,g_cfc_11_csurf,g_cfc_12_alpha,g_cfc_12_csurf real, dimension(:,:), ALLOCATABLE :: sc_no_11,sc_no_12 + character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_set_boundary_values' + !nnz: Can we treat these as source and move block to user_update_from_source? ! @@ -466,6 +474,7 @@ end subroutine generic_CFC_set_boundary_values ! subroutine generic_CFC_end + character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_end' end subroutine generic_CFC_end diff --git a/src/ocean_shared/generic_tracers/generic_CFC.html b/src/ocean_shared/generic_tracers/generic_CFC.html deleted file mode 100644 index 023472ed73..0000000000 --- a/src/ocean_shared/generic_tracers/generic_CFC.html +++ /dev/null @@ -1,279 +0,0 @@ - - - -Module generic_CFC - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
            -

            Module generic_CFC

            - - -
            -Contact:  Niki Zadeh - -
            -Reviewers:  William Cooke - -
            -Change History: WebCVS Log -
            -
            -
            - - -
            -

            OVERVIEW

            - -

            - Ocean Carbon Model Intercomparison Study II: CFC module - This module contains the generic version of CFC Tracers and their chemistry. - It is designed so that both GFDL Ocean models, GOLD and MOM, can use it. - The chemistry calculations in this module are ported from MOM ocmip2_cfc.F90 - released in omsk_2008_03 -

            - - - -
            - 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

            - -
            -
            coupler_types_mod
            field_manager_mod
            mpp_mod
            time_manager_mod
            fm_util_mod
            g_tracer_utils
            -
            - - - -
            -

            PUBLIC INTERFACE

            -
            -
            -
            -generic_CFC_init:
            -
            - Initialize the generic CFC module -
            -
            -generic_CFC_update_from_coupler:
            -
            - Modify the values obtained from the coupler if necessary. -
            -
            -generic_CFC_update_from_source:
            -
            - Update tracer concentration fields due to the source/sink contributions. -
            -
            -generic_CFC_set_boundary_values:
            -
            - Calculate and set coupler values at the surface / bottom -
            -
            -generic_CFC_end:
            -
            - End the module. -
            -
            -
            -
            - - -
            -

            PUBLIC ROUTINES

            - -
              -
            1. - -

              generic_CFC_init

              -
              -call generic_CFC_init (tracer_list)
              -
              -
              -DESCRIPTION -
              -
              - This subroutine: - Adds all the CFC 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]
              -
              -
              -
              -
            2. -
            3. - -

              generic_CFC_update_from_coupler

              -
              -call generic_CFC_update_from_coupler (tracer_list)
              -
              -
              -DESCRIPTION -
              -
              - Currently an empty stub for CFCs. - Some tracer fields need to be modified after values are obtained from the coupler. - This subroutine is the place for specific tracer manipulations. -
              -
              -
              -
              -INPUT -
              -
              - - - - -
              tracer_list    - Pointer to the head of generic tracer list. -
                 [type(g_tracer_type), pointer]
              -
              -
              -
              -
            4. -
            5. - -

              generic_CFC_update_from_source

              -
              -
              -DESCRIPTION -
              -
              - Currently an empty stub for CFCs. -
              -
              -
              -
              -
            6. -
            7. - -

              generic_CFC_set_boundary_values

              -
              -call generic_CFC_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]
              -
              -
              -
              -
            8. -
            9. - -

              generic_CFC_end

              -
              -call generic_CFC_end 
              -
              -
              -
              -DESCRIPTION -
              -
              - Deallocate all work arrays -
              -
              -
              -
              -
            10. -
            - - - - - - -
            -

            REFERENCES

            - -
            -
              -
            1. - http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/CFC/HOWTO-CFC.html -
            2. -
            -
            -
            - -
            -
            -top -
            - - diff --git a/src/ocean_shared/generic_tracers/generic_COBALT.F90 b/src/ocean_shared/generic_tracers/generic_COBALT.F90 new file mode 100644 index 0000000000..a7e0daeddb --- /dev/null +++ b/src/ocean_shared/generic_tracers/generic_COBALT.F90 @@ -0,0 +1,7966 @@ + +! Charles Stock +! +! +! +! This module contains the generic version of the COBALT 1.0 model: "Carbon Ocean +! Biogeochemistry and Lower Trophics". COBALT augments the foodweb dynamics +! in TOPAZ to enable anaylisis of the energy flow through the planktonic +! foodweb and improve the mechanistic resolution of foodweb dynamics that +! influence biogeochemical processes. +! +! +! COBALT simulates the biogeochemical cycling of carbon, nitrogen, +! phosphorous, iron, silica, calcium carbonate, and lithogenic +! material in the ocean. The code is built upon the TOPAZ code +! developed by John Dunne. The primary changes to TOPAZ are: +! +! 1) the addition of three zooplankton groups +! 2) The addition of bacteria +! 3) The expansion of the dissolved organic nitrogen and +! phosphorous groups to include three types each: labile, +! semi-labile, and refractory +! 4) The division of small phytoplankton into low- and high- +! light adapted varieties +! 5) The 1.0 version of the model is coded for constant P:N. Code +! related to the variable P:N formulation used in TOPAZ has +! been retained, but phytoplankton phosphorous state variables +! have been removed (commented out) for computational savings. +! +! Numerous other adjustments to TOPAZ have been made and are detailed in +! the COBALT manual, which can be found at: +! +! +! This manual provides the rationale and justification for the various +! parameterizations used herein, as well as definitions for all variables +! and parameters. The 35 model state variables are: +! +! alk: alkalinity +! cadet_arag: calcium carbonate detritus (aragonite) +! cadet_calc: calcium carbonate detritus (calcite) +! dic: dissolved inorganic carbon +! fed: dissolved iron +! fedi: diazotroph iron +! felg: large phytoplankton iron +! fedet: iron detritus +! fesm: small phytoplankton iron +! ldon: labile dissolved organic nitrogen +! ldop: labile dissolved organic phosphorous +! lith: lithogenic aluminosilicate particles +! lithdet: lithogenic detritus +! nbact: bacteria +! ndet: nitrogen detritus +! ndi: diazotroph nitrogen +! nlg: large phyto nitrogen +! nsm: high-light adapted small phyto nitrogen +! nh4: ammonia +! no3: nitrate +! o2: oxygen +! pdet: phosphorous detritus +! po4: phosphate +! srdon: semi-refractory dissolved organic nitrogen +! (decays over years to decades) +! srdop: semi-refractory dissolved organic phosphorous +! (decays over years to decades) +! sldon: semi-labile dissolved organic nitrogen +! (decays on monthly time scales) +! sldop: semi-labile dissolved organic phosphorous +! (decays on monthly time scales) +! sidet: silica detritus +! silg: large phyto silica +! sio4: silicate +! nsmz: small zooplankton nitrogen +! nmdz: medium zooplankton nitrogen +! nlgz: large zooplankton nitrogen +! +! +! +! +! +! +! +! +! +!---------------------------------------------------------------- + +module generic_COBALT + + 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: mpp_clock_id, mpp_clock_begin, mpp_clock_end + use mpp_mod, only: CLOCK_COMPONENT, CLOCK_SUBCOMPONENT, CLOCK_MODULE + use time_manager_mod, only: time_type + use fm_util_mod, only: fm_util_start_namelist, fm_util_end_namelist + use diag_manager_mod, only: register_diag_field, send_data + use constants_mod, only: WTMCO2, WTMO2 + use fms_mod, only: write_version_number, FATAL, WARNING, stdout, stdlog + + use g_tracer_utils, only : g_tracer_type,g_tracer_start_param_list,g_tracer_end_param_list + use g_tracer_utils, only : g_tracer_add,g_tracer_add_param, g_tracer_set_files + use g_tracer_utils, only : g_tracer_set_values,g_tracer_get_pointer + use g_tracer_utils, only : g_tracer_get_common,g_tracer_set_common + use g_tracer_utils, only : g_tracer_coupler_set,g_tracer_coupler_get + use g_tracer_utils, only : g_tracer_send_diag, g_tracer_get_values + use g_tracer_utils, only : g_diag_type, g_diag_field_add + + use FMS_ocmip2_co2calc_mod, only : FMS_ocmip2_co2calc, CO2_dope_vector + + implicit none ; private +!----------------------------------------------------------------------- + character(len=128) :: version = '$Id: generic_COBALT.F90,v 20.0 2013/12/14 00:18:04 fms Exp $' + character(len=128) :: tag = '$Name: tikal $' +!----------------------------------------------------------------------- + + character(len=fm_string_len), parameter :: mod_name = 'generic_COBALT' + character(len=fm_string_len), parameter :: package_name = 'generic_cobalt' + + public do_generic_COBALT + public generic_COBALT_register + public generic_COBALT_init + public generic_COBALT_register_diag + public generic_COBALT_update_from_coupler + public generic_COBALT_update_from_source + public generic_COBALT_update_from_bottom + public generic_COBALT_set_boundary_values + public generic_COBALT_end + + !The following logical for using this module is overwritten + logical, save :: do_generic_COBALT = .false. + + real, parameter :: sperd = 24.0 * 3600.0 + real, parameter :: spery = 365.25 * sperd + real, parameter :: epsln=1.0e-30 + real,parameter :: missing_value1=-1.0e+10 + real, parameter :: missing_value_diag=-1.0e+10 + + ! Declare phytoplankton, zooplankton and cobalt variable types, which contain + ! the vast majority of all variables used in this module. + + type phytoplankton + real :: alpha, & + fe_2_n_max, & + p_2_n_static, & + k_fe_2_n, & + k_fed, & + k_nh4, & + k_no3, & + k_po4, & + k_sio4, & + P_C_max, & + si_2_n_max, & + si_2_n_static, & + thetamax, & + bresp, & + agg, & + vir, & + exu + real, ALLOCATABLE, dimension(:,:) :: & + jprod_n_100, & + jprod_n_new_100, & + jprod_n_n2_100, & + jzloss_n_100, & + jaggloss_n_100, & + jvirloss_n_100, & + jexuloss_n_100, & + f_n_100 + real, ALLOCATABLE, dimension(:,:,:) :: & + def_fe , & + def_p , & + f_fe , & + f_n , & + felim , & + irrlim , & + jzloss_fe , & + jzloss_n , & + jzloss_p , & + jzloss_sio2 , & + jaggloss_fe , & + jaggloss_n , & + jaggloss_p , & + jaggloss_sio2,& + jvirloss_fe , & + jvirloss_n , & + jvirloss_p , & + jvirloss_sio2,& + jexuloss_fe , & + jexuloss_n , & + jexuloss_p , & + jhploss_fe , & + jhploss_n , & + jhploss_p , & + jhploss_sio2, & + juptake_n2 , & + juptake_fe , & + juptake_nh4 , & + juptake_no3 , & + juptake_po4 , & + juptake_sio4, & + jprod_n , & + liebig_lim , & + mu , & + nh4lim , & + no3lim , & + po4lim , & + o2lim , & + q_fe_2_n , & + q_p_2_n , & + silim , & + q_si_2_n , & + theta + integer :: & + id_def_fe = -1, & + id_def_p = -1, & + id_felim = -1, & + id_irrlim = -1, & + id_jzloss_fe = -1, & + id_jzloss_n = -1, & + id_jzloss_p = -1, & + id_jzloss_sio2 = -1, & + id_jaggloss_fe = -1, & + id_jaggloss_n = -1, & + id_jaggloss_p = -1, & + id_jaggloss_sio2= -1, & + id_jvirloss_fe = -1, & + id_jvirloss_n = -1, & + id_jvirloss_p = -1, & + id_jvirloss_sio2= -1, & + id_jexuloss_n = -1, & + id_jexuloss_p = -1, & + id_jexuloss_fe = -1, & + id_jhploss_fe = -1, & + id_jhploss_n = -1, & + id_jhploss_p = -1, & + id_jhploss_sio2 = -1, & + id_juptake_n2 = -1, & + id_juptake_fe = -1, & + id_juptake_nh4 = -1, & + id_juptake_no3 = -1, & + id_juptake_po4 = -1, & + id_juptake_sio4 = -1, & + id_jprod_n = -1, & + id_liebig_lim = -1, & + id_mu = -1, & + id_nh4lim = -1, & + id_no3lim = -1, & + id_po4lim = -1, & + id_o2lim = -1, & + id_q_fe_2_n = -1, & + id_q_p_2_n = -1, & + id_silim = -1, & + id_q_si_2_n = -1, & + id_theta = -1, & + id_jprod_n_100 = -1, & + id_jprod_n_new_100 = -1, & + id_jprod_n_n2_100 = -1, & + id_jzloss_n_100 = -1, & + id_jaggloss_n_100 = -1, & + id_jvirloss_n_100 = -1, & + id_jexuloss_n_100 = -1, & + id_f_n_100 = -1, & + id_sfc_f_n = -1, & + id_sfc_chl = -1, & + id_sfc_def_fe = -1, & + id_sfc_felim = -1, & + id_sfc_q_fe_2_n = -1, & + id_sfc_nh4lim = -1, & + id_sfc_no3lim = -1, & + id_sfc_po4lim = -1, & + id_sfc_irrlim = -1, & + id_sfc_theta = -1, & + id_sfc_mu = -1 + end type phytoplankton + + type zooplankton + real :: & + imax, & ! maximum ingestion rate (sec-1) + ki, & ! half-sat for ingestion (moles N m-3) + gge_max, & ! max gross growth efficiciency (approached as i >> bresp, dimensionless) + nswitch, & ! switching parameter (dimensionless) + mswitch, & ! switching parameter (dimensionless) + bresp, & ! basal respiration rate (sec-1) + ktemp, & ! temperature dependence of zooplankton rates (C-1) + phi_det, & ! fraction of ingested N to detritus + phi_ldon, & ! fraction of ingested N/P to labile don + phi_sldon, & ! fraction of ingested N/P to semi-labile don + phi_srdon, & ! fraction of ingested N/P to semi-refractory don + phi_ldop, & ! fraction of ingested N/P to labile dop + phi_sldop, & ! fraction of ingested N/P to semi-labile dop + phi_srdop, & ! fraction of ingested N/P to semi-refractory dop + phi_nh4, & ! fraction of ingested N to nh4 due to ingestion-related metabolism + phi_po4, & ! fraction of ingested N to po4 due to ingestion-related metabolism + q_p_2_n, & ! p:n ratio of zooplankton + ipa_smp, & ! innate prey availability of low-light adapt. small phytos + ipa_lgp, & ! innate prey availability of large phytoplankton + ipa_diaz, & ! innate prey availability of diazotrophs + ipa_smz, & ! innate prey availability of small zooplankton + ipa_mdz, & ! innate prey availability of large zooplankton + ipa_lgz, & ! innate prey availability of x-large zooplankton + ipa_det, & ! innate prey availability of detritus + ipa_bact ! innate prey availability for bacteria + real, ALLOCATABLE, dimension(:,:) :: & + jprod_n_100, & + jingest_n_100, & + jzloss_n_100, & + jhploss_n_100, & + jprod_ndet_100, & + jprod_don_100, & + jremin_n_100, & + f_n_100 + real, ALLOCATABLE, dimension(:,:,:) :: & + f_n, & ! zooplankton biomass + jzloss_n, & ! Losses of n due to consumption by other zooplankton groups + jzloss_p, & ! Losses of p due to consumption by other zooplankton groups + jhploss_n, & ! Losses of n due to consumption by unresolved higher preds + jhploss_p, & ! Losses of p due to consumption by unresolved higher preds + jingest_n, & ! Total ingestion of n + jingest_p, & ! Total ingestion of p + jingest_sio2, & ! Total ingestion of silicate + jingest_fe, & ! Total ingestion of iron + jprod_ndet, & ! production of nitrogen detritus by zooplankton group + jprod_pdet, & ! production of phosphorous detritus by zooplankton group + jprod_ldon, & ! production of labile dissolved organic N by zooplankton group + jprod_ldop, & ! production of labile dissolved organic P by zooplankton group + jprod_srdon, & ! production of semi-refractory dissolved organic N by zooplankton group + jprod_srdop, & ! production of semi-refractory dissolved organic P by zooplankton group + jprod_sldon, & ! production of semi-labile dissolved organic N by zooplankton group + jprod_sldop, & ! production of semi-labile dissolved organic P by zooplankton group + jprod_fedet, & ! production of iron detritus + jprod_fed, & ! production of dissolved iron + jprod_sidet, & ! production of silica detritus + jprod_sio4, & ! production of silicate via rapid dissolution at surface + jprod_po4, & ! phosphate production by zooplankton + jprod_nh4, & ! ammonia production by zooplankton + jprod_n, & ! zooplankton production + temp_lim ! Temperature limitation + integer :: & + id_jzloss_n = -1, & + id_jzloss_p = -1, & + id_jhploss_n = -1, & + id_jhploss_p = -1, & + id_jingest_n = -1, & + id_jingest_p = -1, & + id_jingest_sio2 = -1, & + id_jingest_fe = -1, & + id_jprod_ndet = -1, & + id_jprod_pdet = -1, & + id_jprod_ldon = -1, & + id_jprod_ldop = -1, & + id_jprod_srdon = -1, & + id_jprod_srdop = -1, & + id_jprod_sldon = -1, & + id_jprod_sldop = -1, & + id_jprod_fedet = -1, & + id_jprod_fed = -1, & + id_jprod_sidet = -1, & + id_jprod_sio4 = -1, & + id_jprod_po4 = -1, & + id_jprod_nh4 = -1, & + id_jprod_n = -1, & + id_temp_lim = -1, & + id_jprod_n_100 = -1, & + id_jingest_n_100 = -1, & + id_jzloss_n_100 = -1, & + id_jhploss_n_100 = -1, & + id_jprod_ndet_100 = -1, & + id_jprod_don_100 = -1, & + id_jremin_n_100 = -1, & + id_f_n_100 = -1 + end type zooplankton + + type bacteria + real :: & + mu_max, & ! maximum bacterial growth rate (sec-1) + k_ldon, & ! half-sat for nitrogen-limited growth (mmoles N m-3) + gge_max, & ! max gross growth efficiciency (dimensionless) + bresp, & ! basal respiration rate (sec-1) + ktemp, & ! temperature dependence of bacterial rates (C-1) + vir, & ! virus-driven loss rate for bacteria (sec-1 mmole N m-3) + q_p_2_n ! p:n ratio for bacteria + real, ALLOCATABLE, dimension(:,:) :: & + jprod_n_100, & + jzloss_n_100, & + jvirloss_n_100, & + jremin_n_100, & + juptake_ldon_100, & + f_n_100 + real, ALLOCATABLE, dimension(:,:,:) :: & + f_n, & ! bacteria biomass + jzloss_n, & ! Losses of n due to consumption by zooplankton + jzloss_p, & ! Losses of p due to consumption by zooplankton + jhploss_n, & ! Losses of n due to consumption by unresolved higher preds + jhploss_p, & ! Losses of p due to consumption by unresolved higher preds + jvirloss_n , & ! nitrogen losses via viruses + jvirloss_p , & ! phosphorous losses via viruses + juptake_ldon, & ! Total uptake of ldon + juptake_ldop, & ! Total uptake of sldon + jprod_nh4, & ! production of ammonia bacteria + jprod_po4, & ! production of phosphate by bacteria + jprod_n, & ! bacterial production + temp_lim ! Temperature limitation + integer :: & + id_jzloss_n = -1, & + id_jzloss_p = -1, & + id_jhploss_n = -1, & + id_jhploss_p = -1, & + id_jvirloss_n = -1, & + id_jvirloss_p = -1, & + id_juptake_ldon = -1, & + id_juptake_ldop = -1, & + id_jprod_nh4 = -1, & + id_jprod_po4 = -1, & + id_jprod_n = -1, & + id_temp_lim = -1, & + id_jprod_n_100 = -1, & + id_jzloss_n_100 = -1, & + id_jvirloss_n_100 = -1, & + id_jremin_n_100 = -1, & + id_juptake_ldon_100 = -1, & + id_f_n_100 + end type bacteria + + integer, parameter :: NUM_PHYTO = 3 + ! + ! Array allocations and flux calculations assume that phyto(1) is the + ! only phytoplankton group cabable of nitrogen uptake by N2 fixation while phyto(2:NUM_PHYTO) + ! are only cabable of nitrgen uptake by NH4 and NO3 uptake + ! + integer, parameter :: DIAZO = 1 + integer, parameter :: LARGE = 2 + integer, parameter :: SMALL = 3 + type(phytoplankton), dimension(NUM_PHYTO) :: phyto + + ! define three zooplankton types + integer, parameter :: NUM_ZOO = 3 + type(zooplankton), dimension(NUM_ZOO) :: zoo + + type(bacteria), dimension(1) :: bact + + integer, parameter :: NUM_PREY = 8 + + type generic_COBALT_type + + logical :: & + init, & ! If tracers should be initializated + p_2_n_static, & ! If P:N is fixed in phytoplankton + tracer_debug + + real :: & + atm_co2_flux, & + c_2_n, & + ca_2_n_arag, & + ca_2_n_calc, & + caco3_sat_max, & + fe_2_n_upt_fac, & + fe_2_n_sed, & + fe_coast, & + felig_2_don, & + felig_bkg , & + gamma_cadet_arag, & + gamma_cadet_calc, & + gamma_irr_mem, & + gamma_ndet, & + gamma_nitrif, & + gamma_sidet, & + gamma_srdon, & + gamma_srdop, & + gamma_sldon, & + gamma_sldop, & + irr_inhibit, & + k_n_inhib_di, & + k_o2, & + kappa_eppley, & + kappa_remin, & + kfe_eq_lig_hl, & + kfe_eq_lig_ll, & + alpha_fescav, & + beta_fescav, & + gamma_fescav, & + ki_fescav, & + io_fescav, & + remin_eff_fedet, & + k_lith, & + phi_lith, & + mass_2_n, & + alk_2_n_denit, & + n_2_n_denit, & + k_no3_denit, & + o2_min, & + o2_2_c, & + o2_2_nfix, & + o2_2_nh4, & + o2_2_no3, & + o2_2_nitrif, & + o2_inhib_di_pow, & + o2_inhib_di_sat, & + P_C_max_assem, & + rpcaco3, & + rplith, & + rpsio2, & + thetamin, & + thetamin_nolim, & + vir_ktemp, & + lysis_phi_ldon, & + lysis_phi_srdon, & + lysis_phi_sldon, & + lysis_phi_ldop, & + lysis_phi_srdop, & + lysis_phi_sldop, & + wsink, & + z_sed, & + zeta, & + imax_hp, & ! unresolved higher pred. max ingestion rate + ki_hp, & ! unresolved higher pred. half-sat + ktemp_hp, & ! temperature dependence for higher predators + coef_hp, & ! scaling between unresolved preds and available prey + nswitch_hp, & ! higher predator switching behavior + mswitch_hp, & ! higher predator switching behavior + hp_ipa_smp, & ! innate prey availability of small phytos to hp's + hp_ipa_lgp, & ! " " " " " " " " " large phytos to hp's + hp_ipa_diaz, & ! " " " " " " " " " diazotrophs to hp's + hp_ipa_bact, & ! " " " " " " " " " bacteria to hp's + hp_ipa_smz, & ! " " " " " " " " " small zooplankton to hp's + hp_ipa_mdz, & ! " " " " " " " " " medium zooplankton to hp's + hp_ipa_lgz, & ! " " " " " " " " " large zooplankton to hp's + hp_ipa_det, & ! " " " " " " " " " detritus to hp's + hp_phi_det, & ! fraction of ingested N to detritus + hp_phi_ldon, & ! fraction of ingested N to labile don + hp_phi_sldon, & ! fraction of ingested N to semi-labile don + hp_phi_srdon, & ! fraction of ingested N to semi-refractory don + hp_phi_ldop, & ! fraction of ingested N to labile dop + hp_phi_sldop, & ! fraction of ingested N to semi-labile dop + hp_phi_srdop, & ! fraction of ingested N to semi-refractory dop + hp_phi_nh4, & ! fraction of ingested N to nh4 due to ingestion-related metabolism + hp_phi_po4 ! fraction of ingested N to po4 due to ingestion-related metabolism + + + real, dimension(3) :: total_atm_co2 + + real :: htotal_scale_lo, htotal_scale_hi, htotal_in + real :: Rho_0, a_0, a_1, a_2, a_3, a_4, a_5, b_0, b_1, b_2, b_3, c_0 + real :: a1_co2, a2_co2, a3_co2, a4_co2, a1_o2, a2_o2, a3_o2, a4_o2 + + logical, dimension(:,:), ALLOCATABLE :: & + mask_z_sat_arag,& + mask_z_sat_calc + + real, dimension(:,:,:), ALLOCATABLE :: & + f_alk,& ! Other prognostic variables + f_cadet_arag,& + f_cadet_calc,& + f_dic,& + f_fed,& + f_fedet,& + f_ldon,& + f_ldop,& + f_lith,& + f_lithdet,& + f_ndet,& + f_nh4,& + f_no3,& + f_o2,& + f_pdet,& + f_po4,& + f_srdon,& + f_srdop,& + f_sldon,& + f_sldop,& + f_sidet,& + f_silg,& + f_sio4,& + co3_sol_arag,& + co3_sol_calc,& + f_chl,& + f_co3_ion,& + f_htotal,& + f_irr_mem,& + f_cased,& + f_cadet_arag_btf,& + f_cadet_calc_btf,& + f_fedet_btf, & + f_lithdet_btf, & + f_ndet_btf,& + f_pdet_btf,& + f_sidet_btf,& + jnbact,& + jndi,& + jnsm,& + jnlg,& + jnsmz,& + jnmdz,& + jnlgz,& + jalk,& + jcadet_arag,& + jcadet_calc,& + jdic,& + jfed,& + jfedi,& + jfelg,& + jfesm,& + jfedet,& + jldon,& + jldop,& + jlith,& + jlithdet,& + jndet,& + jnh4,& + jno3,& + jo2,& + jpdet,& + jpo4,& + jsrdon,& + jsrdop,& + jsldon,& + jsldop,& + jsidet,& + jsilg,& + jsio4,& + jprod_ndet,& + jprod_pdet,& + jprod_ldon,& + jprod_ldop,& + jprod_sldon,& + jprod_sldop,& + jprod_srdon,& + jprod_srdop,& + jprod_fedet,& + jprod_fed,& + jprod_sidet,& + jprod_sio4, & + jprod_lithdet,& + jprod_cadet_arag,& + jprod_cadet_calc,& + jprod_nh4,& + jprod_po4,& + det_jzloss_n,& + det_jzloss_p,& + det_jzloss_fe,& + det_jzloss_si,& + det_jhploss_n,& + det_jhploss_p,& + det_jhploss_fe,& + det_jhploss_si,& + jdiss_cadet_arag,& + jdiss_cadet_calc,& + jdiss_sidet,& + jremin_ndet,& + jremin_pdet,& + jremin_fedet,& + jfe_ads,& + jfe_coast,& + kfe_eq_lig,& + expkT,& + hp_temp_lim,& + hp_jingest_n,& + hp_jingest_p,& + hp_jingest_fe,& + hp_jingest_sio2,& + irr_inst,& + irr_mix,& + jno3denit_wc,& + jnitrif,& + omega_arag,& + omega_calc,& + tot_layer_int_c,& + tot_layer_int_fe,& + tot_layer_int_n,& + tot_layer_int_p,& + tot_layer_int_si,& + total_filter_feeding,& + net_prim_prod,& + gross_prim_prod,& + nlg_diatoms,& + q_si_2_n_lg_diatoms,& + zt, & + zm + + real, dimension(:,:), ALLOCATABLE :: & + b_alk,b_dic,b_fed,b_nh4,b_no3,b_o2,b_po4,b_sio4,& ! bottom flux terms + co2_csurf,pco2_csurf,co2_alpha,& + fcadet_arag_btm,& + fcadet_calc_btm,& + ffedet_btm,& + flithdet_btm,& + fpdet_btm,& + fndet_btm,& + fsidet_btm,& + fcased_burial,& + fcased_input,& + fcased_redis,& + ffe_sed,& + fnfeso4red_sed,& + fno3denit_sed,& + fnoxic_sed,& + frac_burial,& + fndet_burial,& + fpdet_burial,& + jprod_allphytos_100,& + htotallo, htotalhi,& + hp_jingest_n_100,& + hp_jremin_n_100,& + hp_jprod_ndet_100,& + jprod_lithdet_100,& + jprod_sidet_100,& + jprod_cadet_calc_100,& + jprod_cadet_arag_100,& + jprod_mesozoo_200, & + jremin_ndet_100, & + f_ndet_100, & + f_don_100, & + f_silg_100, & + f_mesozoo_200, & + fndet_100, & + fpdet_100, & + fsidet_100, & + fcadet_calc_100, & + fcadet_arag_100, & + ffedet_100, & + flithdet_100, & + btm_temp, & + btm_o2, & + o2min, & + z_o2min, & + z_sat_arag,& + z_sat_calc + + real, dimension(:,:,:,:), pointer :: & + p_alk,& + p_cadet_arag,& + p_cadet_calc,& + p_dic,& + p_fed,& + p_fedi,& + p_felg,& + p_fedet,& + p_fesm,& + p_ldon,& + p_ldop,& + p_lith,& + p_lithdet,& + p_nbact,& + p_ndet,& + p_ndi,& + p_nlg,& + p_nsm,& + p_nh4,& + p_no3,& + p_o2,& + p_pdet,& + p_po4,& + p_srdon,& + p_srdop,& + p_sldon,& + p_sldop,& + p_sidet,& + p_silg,& + p_sio4,& + p_nsmz,& + p_nmdz,& + p_nlgz + + real, dimension (:,:), pointer :: & + runoff_flux_alk,& + runoff_flux_dic,& + runoff_flux_lith,& + runoff_flux_fed,& + runoff_flux_no3,& + runoff_flux_ldon,& + runoff_flux_sldon,& + runoff_flux_srdon,& + runoff_flux_ndet,& + runoff_flux_po4,& + runoff_flux_ldop,& + runoff_flux_sldop,& + runoff_flux_srdop,& + dry_fed, wet_fed,& + dry_lith, wet_lith,& + dry_no3, wet_no3,& + dry_nh4, wet_nh4,& + dry_po4, wet_po4 + + integer :: nkml + character(len=fm_string_len) :: file + character(len=fm_string_len) :: ice_restart_file + character(len=fm_string_len) :: ocean_restart_file,IC_file + + integer :: & + id_ndi = -1, & + id_nlg = -1, & + id_nsm = -1, & + id_nsmz = -1, & + id_nmdz = -1, & + id_nlgz = -1, & + id_nbact = -1, & + id_alk = -1, & + id_cadet_arag = -1, & + id_cadet_calc = -1, & + id_dic = -1, & + id_fed = -1, & + id_fedi = -1, & + id_felg = -1, & + id_fesm = -1, & + id_fedet = -1, & + id_ldon = -1, & + id_ldop = -1, & + id_lith = -1, & + id_lithdet = -1, & + id_ndet = -1, & + id_nh4 = -1, & + id_no3 = -1, & + id_o2 = -1, & + id_pdet = -1, & + id_po4 = -1, & + id_srdop = -1, & + id_srdon = -1, & + id_sldon = -1, & + id_sldop = -1, & + id_sidet = -1, & + id_silg = -1, & + id_sio4 = -1, & + id_co3_sol_arag = -1, & + id_co3_sol_calc = -1, & + id_dep_dry_fed = -1, & + id_dep_dry_nh4 = -1, & + id_dep_dry_no3 = -1, & + id_dep_dry_po4 = -1, & + id_dep_wet_fed = -1, & + id_dep_wet_nh4 = -1, & + id_dep_wet_no3 = -1, & + id_dep_wet_po4 = -1, & + id_dep_wet_lith = -1, & + id_dep_dry_lith = -1, & + id_omega_arag = -1, & + id_omega_calc = -1, & + id_chl = -1, & + id_co3_ion = -1, & + id_htotal = -1, & + id_irr_mem = -1, & + id_cased = -1, & + id_cadet_arag_btf = -1, & + id_cadet_calc_btf = -1, & + id_fedet_btf = -1, & + id_lithdet_btf = -1, & + id_ndet_btf = -1, & + id_pdet_btf = -1, & + id_sidet_btf = -1, & + id_jprod_ndet = -1, & + id_jprod_pdet = -1, & + id_jprod_sldon = -1, & + id_jprod_ldon = -1, & + id_jprod_srdon = -1, & + id_jprod_sldop = -1, & + id_jprod_ldop = -1, & + id_jprod_srdop = -1, & + id_jprod_fedet = -1, & + id_jprod_fed = -1, & + id_jprod_sidet = -1, & + id_jprod_sio4 = -1, & + id_jprod_lithdet = -1, & + id_jprod_cadet_arag = -1, & + id_jprod_cadet_calc = -1, & + id_jprod_po4 = -1, & + id_jprod_nh4 = -1, & + id_det_jzloss_n = -1, & + id_det_jzloss_p = -1, & + id_det_jzloss_fe = -1, & + id_det_jzloss_si = -1, & + id_det_jhploss_n = -1, & + id_det_jhploss_p = -1, & + id_det_jhploss_fe = -1, & + id_det_jhploss_si = -1, & + id_jdiss_sidet = -1, & + id_jdiss_cadet_arag = -1, & + id_jdiss_cadet_calc = -1, & + id_jremin_ndet = -1, & + id_jremin_pdet = -1, & + id_jremin_fedet = -1, & + id_jfe_ads = -1, & + id_jfe_coast = -1, & + id_kfe_eq_lig = -1, & + id_expkT = -1, & + id_hp_temp_lim = -1, & + id_hp_jingest_n = -1, & + id_hp_jingest_p = -1, & + id_hp_jingest_fe = -1, & + id_hp_jingest_sio2 = -1, & + id_irr_inst = -1, & + id_irr_mix = -1, & + id_jno3denit_wc = -1, & + id_jnitrif = -1, & + id_co2_csurf = -1, & + id_pco2_csurf = -1, & + id_co2_alpha = -1, & + id_fcadet_arag = -1, & + id_fcadet_calc = -1, & + id_ffedet = -1, & + id_fndet = -1, & + id_fpdet = -1, & + id_fsidet = -1, & + id_flithdet = -1, & + id_fcadet_arag_btm = -1, & + id_fcadet_calc_btm = -1, & + id_ffedet_btm = -1, & + id_flithdet_btm = -1, & + id_fndet_btm = -1, & + id_fpdet_btm = -1, & + id_fsidet_btm = -1, & + id_fcased_burial = -1, & + id_fcased_input = -1, & + id_fcased_redis = -1, & + id_ffe_sed = -1, & + id_fnfeso4red_sed= -1, & + id_fno3denit_sed = -1, & + id_fnoxic_sed = -1, & + id_frac_burial = -1, & + id_fndet_burial = -1, & + id_fpdet_burial = -1, & + id_nphyto_tot = -1, & + id_no3_in_source = -1, & + id_pco2surf = -1, & + id_sfc_alk = -1, & + id_sfc_cadet_arag= -1, & + id_sfc_cadet_calc= -1, & + id_sfc_dic = -1, & + id_sfc_fed = -1, & + id_sfc_ldon = -1, & + id_sfc_sldon = -1, & + id_sfc_srdon = -1, & + id_sfc_no3 = -1, & + id_sfc_nh4 = -1, & + id_sfc_po4 = -1, & + id_sfc_sio4 = -1, & + id_sfc_htotal = -1, & + id_sfc_o2 = -1, & + id_sfc_chl = -1, & + id_sfc_irr = -1, & + id_sfc_irr_mem = -1, & + id_sfc_temp = -1, & + id_btm_temp = -1, & + id_btm_o2 = -1, & + id_sfc_co3_ion = -1, & + id_sfc_co3_sol_arag = -1, & + id_sfc_co3_sol_calc = -1, & + id_runoff_flux_alk = -1, & + id_runoff_flux_dic = -1, & + id_runoff_flux_fed = -1, & + id_runoff_flux_lith = -1, & + id_runoff_flux_no3 = -1, & + id_runoff_flux_ldon = -1, & + id_runoff_flux_sldon = -1, & + id_runoff_flux_srdon = -1, & + id_runoff_flux_ndet = -1, & + id_runoff_flux_po4 = -1, & + id_runoff_flux_ldop = -1, & + id_runoff_flux_sldop = -1, & + id_runoff_flux_srdop = -1, & + id_tot_layer_int_c = -1, & + id_tot_layer_int_fe = -1, & + id_tot_layer_int_n = -1, & + id_tot_layer_int_p = -1, & + id_tot_layer_int_si = -1, & + id_total_filter_feeding = -1,& + id_net_prim_prod = -1, & + id_gross_prim_prod = -1, & + id_nlg_diatoms = -1, & + id_jprod_allphytos_100 = -1, & + id_q_si_2_n_lg_diatoms = -1, & + id_hp_jingest_n_100 = -1, & + id_hp_jremin_n_100 = -1, & + id_hp_jprod_ndet_100 = -1, & + id_jprod_lithdet_100 = -1, & + id_jprod_sidet_100 = -1, & + id_jprod_cadet_calc_100 = -1, & + id_jprod_cadet_arag_100 = -1, & + id_jprod_mesozoo_200 = -1, & + id_jremin_ndet_100 = -1, & + id_f_ndet_100 = -1, & + id_f_don_100 = -1, & + id_f_silg_100 = -1, & + id_f_mesozoo_200 = -1, & + id_fndet_100 = -1, & + id_fpdet_100 = -1, & + id_ffedet_100 = -1, & + id_fcadet_calc_100 = -1, & + id_fcadet_arag_100 = -1, & + id_flithdet_100 = -1, & + id_fsidet_100 = -1, & + id_o2min = -1, & + id_z_o2min = -1, & + id_z_sat_arag = -1, & ! Depth of Aragonite saturation + id_z_sat_calc = -1 ! Depth of Calcite saturation + end type generic_COBALT_type + + !An auxiliary type for storing varible names + type, public :: vardesc + character(len=fm_string_len) :: name ! The variable name in a NetCDF file. + character(len=fm_string_len) :: longname ! The long name of that variable. + character(len=1) :: hor_grid ! The hor. grid: u, v, h, q, or 1. + character(len=1) :: z_grid ! The vert. grid: L, i, or 1. + character(len=1) :: t_grid ! The time description: s, a, m, or 1. + character(len=fm_string_len) :: units ! The dimensions of the variable. + character(len=1) :: mem_size ! The size in memory: d or f. + end type vardesc + + type(generic_COBALT_type) :: cobalt + + type(CO2_dope_vector) :: CO2_dope_vec + + ! identification numbers for mpp clocks + integer :: id_clock_carbon_calculations + integer :: id_clock_phyto_growth + integer :: id_clock_bacteria_growth + integer :: id_clock_zooplankton_calculations + integer :: id_clock_other_losses + integer :: id_clock_production_loop + integer :: id_clock_ballast_loops + integer :: id_clock_source_sink_loop1 + integer :: id_clock_source_sink_loop2 + integer :: id_clock_source_sink_loop3 + integer :: id_clock_source_sink_loop4 + integer :: id_clock_source_sink_loop5 + integer :: id_clock_source_sink_loop6 + integer :: id_clock_cobalt_send_diagnostics + integer :: id_clock_cobalt_calc_diagnostics + +contains + + subroutine generic_COBALT_register(tracer_list) + type(g_tracer_type), pointer :: tracer_list + + character(len=fm_string_len), parameter :: sub_name = 'generic_COBALT_register' + + !Specify all prognostic and diagnostic tracers of this modules. + call user_add_tracers(tracer_list) + + end subroutine generic_COBALT_register + + ! + ! + ! Initialize the generic COBALT module + ! + ! + ! This subroutine: + ! Adds all the COBALT 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. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + subroutine generic_COBALT_init(tracer_list) + type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_COBALT_init' + + !Specify and initialize all parameters used by this package + call user_add_params + + !Allocate all the private work arrays used by this module. + call user_allocate_arrays + + id_clock_carbon_calculations = mpp_clock_id('(Cobalt: carbon calcs)' ,grain=CLOCK_MODULE) + id_clock_phyto_growth = mpp_clock_id('(Cobalt: phytoplankton growth calcs)',grain=CLOCK_MODULE) + id_clock_bacteria_growth = mpp_clock_id('(Cobalt: bacteria growth calcs)',grain=CLOCK_MODULE) + id_clock_zooplankton_calculations = mpp_clock_id('(Cobalt: zooplankton calculations)',grain=CLOCK_MODULE) + id_clock_other_losses = mpp_clock_id('(Cobalt: other losses)',grain=CLOCK_MODULE) + id_clock_production_loop = mpp_clock_id('(Cobalt: production loop)',grain=CLOCK_MODULE) + id_clock_ballast_loops = mpp_clock_id('(Cobalt: ballasting loops)',grain=CLOCK_MODULE) + id_clock_source_sink_loop1 = mpp_clock_id('(Cobalt: source/sink loop 1)',grain=CLOCK_MODULE) + id_clock_source_sink_loop2 = mpp_clock_id('(Cobalt: source/sink loop 2)',grain=CLOCK_MODULE) + id_clock_source_sink_loop3 = mpp_clock_id('(Cobalt: source/sink loop 3)',grain=CLOCK_MODULE) + id_clock_source_sink_loop4 = mpp_clock_id('(Cobalt: source/sink loop 4)',grain=CLOCK_MODULE) + id_clock_source_sink_loop5 = mpp_clock_id('(Cobalt: source/sink loop 5)',grain=CLOCK_MODULE) + id_clock_source_sink_loop6 = mpp_clock_id('(Cobalt: source/sink loop 6)',grain=CLOCK_MODULE) + id_clock_cobalt_send_diagnostics = mpp_clock_id('(Cobalt: send diagnostics)',grain=CLOCK_MODULE) + id_clock_cobalt_calc_diagnostics = mpp_clock_id('(Cobalt: calculate diagnostics)',grain=CLOCK_MODULE) + + end subroutine generic_COBALT_init + + ! Register diagnostic fields to be used in this module. + ! Note that the tracer fields are automatically registered in user_add_tracers + ! User adds only diagnostics for fields that are not a member of g_tracer_type + ! + subroutine generic_COBALT_register_diag(diag_list) + type(g_diag_type), pointer :: diag_list + type(vardesc) :: vardesc_temp + integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau, axes(3) + type(time_type):: init_time + + call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes=axes,init_time=init_time) + + ! The following vardesc types contain a package of metadata about each tracer, + ! including, in order, the following elements: name; longname; horizontal + ! staggering ('h') for collocation with thickness points ; vertical staggering + ! ('L') for a layer variable ; temporal staggering ('s' for snapshot) ; units ; + ! and precision in non-restart output files ('f' for 32-bit float or 'd' for + ! 64-bit doubles). For most tracers, only the name, longname and units should + ! be changed. + + + ! Register the diagnostics for the various phytoplankton + ! + ! Register Limitation Diagnostics + ! + vardesc_temp = vardesc("def_fe_Di","Diaz. Phyto. Fe Deficiency",'h','L','s','dimensionless','f') + phyto(DIAZO)%id_def_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("def_fe_Lg","Large Phyto. Fe Deficiency",'h','L','s','dimensionless','f') + phyto(LARGE)%id_def_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("def_fe_Sm","Small Phyto. Fe Deficiency",'h','L','s','dimensionless','f') + phyto(SMALL)%id_def_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("felim_Di","Diaz. Phyto. Fed uptake Limitation",'h','L','s','dimensionless','f') + phyto(DIAZO)%id_felim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("felim_Lg","Large Phyto. Fed uptake Limitation",'h','L','s','dimensionless','f') + phyto(LARGE)%id_felim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("felim_Sm","Small Phyto. Fed uptake Limitation",'h','L','s','dimensionless','f') + phyto(SMALL)%id_felim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("irrlim_Di","Diaz. Phyto. Light Limitation",'h','L','s','dimensionless','f') + phyto(DIAZO)%id_irrlim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("irrlim_Lg","Large Phyto. Light Limitation",'h','L','s','dimensionless','f') + phyto(LARGE)%id_irrlim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("irrlim_Sm","Small Phyto. Light Limitation",'h','L','s','dimensionless','f') + phyto(SMALL)%id_irrlim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("theta_Di","Diaz. Phyto. Chl:C",'h','L','s','g Chl (g C)-1','f') + phyto(DIAZO)%id_theta = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("theta_Lg","Large Phyto. Chl:C",'h','L','s','g Chl (g C)-1','f') + phyto(LARGE)%id_theta = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("theta_Sm","Small Phyto. Chl:C",'h','L','s','g Chl (g C)-1','f') + phyto(SMALL)%id_theta = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("mu_Di","Diaz. Phyto. Overall Growth Rate",'h','L','s','s-1','f') + phyto(DIAZO)%id_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("mu_Lg","Large Phyto. Overall Growth Rate",'h','L','s','s-1','f') + phyto(LARGE)%id_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("mu_Sm","Small Phyto. Growth Rate",'h','L','s','s-1','f') + phyto(SMALL)%id_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nh4lim_Lg","Ammonia Limitation of Large Phyto",'h','L','s','dimensionless','f') + phyto(LARGE)%id_nh4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nh4lim_Sm","Ammonia Limitation of Small Phyto",'h','L','s','dimensionless','f') + phyto(SMALL)%id_nh4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("no3lim_Lg","Nitrate Limitation of Large Phyto",'h','L','s','dimensionless','f') + phyto(LARGE)%id_no3lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("no3lim_Sm","Nitrate Limitation of Small Phyto",'h','L','s','dimensionless','f') + phyto(SMALL)%id_no3lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("po4lim_Di","Phosphate Limitation of Diaz. Phyto",'h','L','s','dimensionless','f') + phyto(DIAZO)%id_po4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("po4lim_Lg","Phosphate Limitation of Large Phyto",'h','L','s','dimensionless','f') + phyto(LARGE)%id_po4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("po4lim_Sm","Phosphate Limitation of Small Phyto",'h','L','s','dimensionless','f') + phyto(SMALL)%id_po4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("o2lim_Di","Oxygen Limitation of Diaz. Phyto",'h','L','s','dimensionless','f') + phyto(DIAZO)%id_o2lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("q_fe_2_n_Di","Fe:N ratio of Diaz. Phyto",'h','L','s','mol Fe/mol N','f') + phyto(DIAZO)%id_q_fe_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("q_fe_2_n_Lg","Fe:N ratio of Large Phyto",'h','L','s','mol Fe/mol N','f') + phyto(LARGE)%id_q_fe_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("q_fe_2_n_Sm","Fe:N ratio of Small Phyto",'h','L','s','mol Fe/mol N','f') + phyto(SMALL)%id_q_fe_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("silim_Lg","SiO4 Limitation of Large Phyto",'h','L','s','dimensionless','f') + phyto(LARGE)%id_silim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("q_si_2_n_Lg","Si:N ratio of Large Phyto",'h','L','s','mol Si/mol N','f') + phyto(LARGE)%id_q_si_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for phytoplankton loss terms: zooplankton + ! CAS: loss diagnostics simplified to just N + + vardesc_temp = vardesc("jzloss_n_Di","Diazotroph nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(DIAZO)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_n_Lg","Large phyto nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(LARGE)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_n_Sm","Small phyto nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(SMALL)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for phytoplankton loss terms: aggregation + ! + + vardesc_temp = vardesc("jaggloss_n_Di","Diazotroph nitrogen loss to aggregation layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(DIAZO)%id_jaggloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jaggloss_n_Lg","Large phyto nitrogen loss to aggregation layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(LARGE)%id_jaggloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jaggloss_n_Sm","Small phyto nitrogen loss to aggregation layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(SMALL)%id_jaggloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for phytoplankton loss terms: viruses + ! + + vardesc_temp = vardesc("jvirloss_n_Di","Diazotroph nitrogen loss to viruses layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(DIAZO)%id_jvirloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jvirloss_n_Lg","Large phyto nitrogen loss to viruses layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(LARGE)%id_jvirloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jvirloss_n_Sm","Small phyto nitrogen loss to viruses layer integral",& + 'h','L','s','mol N m-2 s-1','f') + phyto(SMALL)%id_jvirloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for phytoplankton exudation + ! + vardesc_temp = vardesc("jexuloss_n_Di","Diazotroph nitrogen loss via exudation",& + 'h','L','s','mol N m-2 s-1','f') + phyto(DIAZO)%id_jexuloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jexuloss_n_Lg","Large phyto nitrogen loss via exudation",& + 'h','L','s','mol N m-2 s-1','f') + phyto(LARGE)%id_jexuloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jexuloss_n_Sm","Small phyto nitrogen loss via exudation",& + 'h','L','s','mol N m-2 s-1','f') + phyto(SMALL)%id_jexuloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register dynamic silicate diagnostics + ! + vardesc_temp = vardesc("nlg_diatoms","Fraction of large phytos that are diatoms",& + 'h','L','s','dimensionless','f') + cobalt%id_nlg_diatoms = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("q_si_2_n_lg_diatoms","Si:N ratio in large diatoms",& + 'h','L','s','mol Si mol N','f') + cobalt%id_q_si_2_n_lg_diatoms = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for phytoplankton loss terms: higher predators + ! + +! vardesc_temp = vardesc("jhploss_n_Di","Diazotroph nitrogen loss to higher predators layer integral",& +! 'h','L','s','mol N m-2 s-1','f') +! phyto(DIAZO)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& +! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) +! +! vardesc_temp = vardesc("jhploss_n_Lg","Large phyto nitrogen loss to higher predators layer integral",& +! 'h','L','s','mol N m-2 s-1','f') +! phyto(LARGE)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& +! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) +! +! vardesc_temp = vardesc("jhploss_n_Sm_hl","High light Sm. phyto nitrogen loss to higher preds layer integral",& +! 'h','L','s','mol N m-2 s-1','f') +! phyto(SMALL_HL)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& +! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) +! +! vardesc_temp = vardesc("jhploss_n_Sm_ll","Low light Sm. phyto nitrogen loss to higher preds layer integral",& +! 'h','L','s','mol N m-2 s-1','f') +! phyto(SMALL_LL)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& +! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + + ! + ! Register Phytoplankton Production Diagnostics + ! + + vardesc_temp = vardesc("juptake_n2_Di","Nitrogen fixation layer integral",'h','L','s','mol N m-2 s-1','f') + phyto(DIAZO)%id_juptake_n2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_fe_Di","Diaz. phyto. Fed uptake layer integral",'h','L','s','mol Fe m-2 s-1','f') + phyto(DIAZO)%id_juptake_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_fe_Lg","Large phyto. Fed uptake layer integral",'h','L','s','mol Fe m-2 s-1','f') + phyto(LARGE)%id_juptake_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_fe_Sm","Small phyto. Fed uptake layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + phyto(SMALL)%id_juptake_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_nh4_Di","Diaz. phyto. NH4 uptake layer integral",'h','L','s','mol NH4 m-2 s-1','f') + phyto(DIAZO)%id_juptake_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_nh4_Lg","Large phyto. NH4 uptake layer integral",'h','L','s','mol NH4 m-2 s-1','f') + phyto(LARGE)%id_juptake_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_nh4_Sm","Small phyto. NH4 uptake layer integral",& + 'h','L','s','mol NH4 m-2 s-1','f') + phyto(SMALL)%id_juptake_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_no3_Di","Diaz. phyto. NO3 uptake layer integral",'h','L','s','mol NO3 m-2 s-1','f') + phyto(DIAZO)%id_juptake_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_no3_Lg","Large phyto. NO3 uptake layer integral",'h','L','s','mol NO3 m-2 s-1','f') + phyto(LARGE)%id_juptake_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_no3_Sm","Small phyto. NO3 uptake layer integral",& + 'h','L','s','mol NO3 m-2 s-1','f') + phyto(SMALL)%id_juptake_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_po4_Di","Diaz. phyto. PO4 uptake layer integral",'h','L','s','mol PO4 m-2 s-1','f') + phyto(DIAZO)%id_juptake_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_po4_Lg","Large phyto. PO4 uptake layer integral",'h','L','s','mol PO4 m-2 s-1','f') + phyto(LARGE)%id_juptake_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_po4_Sm","Small phyto. PO4 uptake layer integral",& + 'h','L','s','mol PO4 m-2 s-1','f') + phyto(SMALL)%id_juptake_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_sio4_Lg","Large phyto. SiO4 uptake layer integral",'h','L','s','mol m-2 s-1','f') + phyto(LARGE)%id_juptake_sio4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndi","Diazotroph Nitrogen production layer integral",'h','L','s','mol m-2 s-1','f') + phyto(DIAZO)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nsmp","Small phyto. Nitrogen production layer integral",'h','L','s','mol m-2 s-1','f') + phyto(SMALL)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nlgp","Large phyto. Nitrogen production layer integral",'h','L','s','mol m-2 s-1','f') + phyto(LARGE)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register zooplankton diagnostics, starting with losses of zooplankton to ingestion by zooplankton + ! + + vardesc_temp = vardesc("jzloss_n_Smz","Small zooplankton nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_n_Mdz","Medium-sized zooplankton nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_n_Lgz","Large zooplankton nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for zooplankton loss terms: higher predators + ! + + vardesc_temp = vardesc("jhploss_n_Smz","Small zooplankton nitrogen loss to higher predators layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jhploss_n_Mdz","Medium-sized zooplankton nitrogen loss to higher predators layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jhploss_n_Lgz","Large zooplankton nitrogen loss to higher predators layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register zooplankton ingestion rates + ! + + vardesc_temp = vardesc("jingest_n_Smz","Ingestion of nitrogen by small zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jingest_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_n_Mdz","Ingestion of nitrogen by medium-sized zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jingest_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_n_Lgz","Ingestion of nitrogen by large zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jingest_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_p_Smz","Ingestion of phosphorous by small zooplankton, layer integral", & + 'h','L','s','mol P m-2 s-1','f') + zoo(1)%id_jingest_p = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_p_Mdz","Ingestion of phosphorous by medium-sized zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(2)%id_jingest_p = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_p_Lgz","Ingestion of phosphorous by large zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(3)%id_jingest_p = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_sio2_Smz","Ingestion of sio2 by small zooplankton, layer integral",& + 'h','L','s','mol SiO2 m-2 s-1','f') + zoo(1)%id_jingest_sio2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_sio2_Mdz","Ingestion of sio2 by medium-sized zooplankton, layer integral",& + 'h','L','s','mol SiO2 m-2 s-1','f') + zoo(2)%id_jingest_sio2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_sio2_Lgz","Ingestion of sio2 by large zooplankton, layer integral",& + 'h','L','s','mol SiO2 m-2 s-1','f') + zoo(3)%id_jingest_sio2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_fe_Smz","Ingestion of Fe by small zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(1)%id_jingest_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_fe_Mdz","Ingestion of Fe by medium-sized zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(2)%id_jingest_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_fe_Lgz","Ingestion of Fe by large zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(3)%id_jingest_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register detrital production terms for zooplankton + ! + + vardesc_temp = vardesc("jprod_ndet_Smz","Production of nitrogen detritus by small zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jprod_ndet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndet_Mdz","Production of nitrogen detritus by medium zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jprod_ndet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndet_Lgz","Production of nitrogen detritus by large zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jprod_ndet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_pdet_Smz","Production of phosphorous detritus by small zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(1)%id_jprod_pdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_pdet_Mdz","Production of phosphorous detritus by medium zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(2)%id_jprod_pdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_pdet_Lgz","Production of phosphorous detritus by large zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(3)%id_jprod_pdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sidet_Smz","Production of opal detritus by small zooplankton, layer integral",& + 'h','L','s','mol SiO2 m-2 s-1','f') + zoo(1)%id_jprod_sidet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sidet_Mdz","Production of opal detritus by medium zooplankton, layer integral",& + 'h','L','s','mol SiO2 m-2 s-1','f') + zoo(2)%id_jprod_sidet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sidet_Lgz","Production of opal detritus by large zooplankton, layer integral",& + 'h','L','s','mol SiO2 m-2 s-1','f') + zoo(3)%id_jprod_sidet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sio4_Smz","Production of sio4 through grazing/dissolution, layer integral",& + 'h','L','s','mol SiO4 m-2 s-1','f') + zoo(1)%id_jprod_sio4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sio4_Mdz","Production of sio4 through grazing/dissolution, layer integral",& + 'h','L','s','mol SiO4 m-2 s-1','f') + zoo(2)%id_jprod_sio4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sio4_Lgz","Production of sio4 through grazing/dissolution, layer integral",& + 'h','L','s','mol SiO4 m-2 s-1','f') + zoo(3)%id_jprod_sio4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_fedet_Smz","Production of iron detritus by small zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(1)%id_jprod_fedet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_fedet_Mdz","Production of iron detritus by medium zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(2)%id_jprod_fedet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_fedet_Lgz","Production of iron detritus by large zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(3)%id_jprod_fedet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register dissolved organic/inorganic production terms for zooplankton + ! + ! Labile dissolved organic nitrogen + vardesc_temp = vardesc("jprod_ldon_Smz","Production of labile dissolved organic nitrogen by small zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jprod_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ldon_Mdz","Production of labile dissolved organic nitrogen by medium zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jprod_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ldon_Lgz","Production of labile dissolved organic nitrogen by large zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jprod_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! Labile dissolved organic phosphorous + vardesc_temp = vardesc("jprod_ldop_Smz","Production of labile dissolved organic phosphorous by small zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(1)%id_jprod_ldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ldop_Mdz","Production of labile dissolved organic phosphorous by medium zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(2)%id_jprod_ldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ldop_Lgz","Production of labile dissolved organic phosphorous by large zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(3)%id_jprod_ldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! Refractory dissolved organic nitrogen + vardesc_temp = vardesc("jprod_srdon_Smz","Production of semi-refractory dissolved organic nitrogen by small zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jprod_srdon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_srdon_Mdz","Production of semi-refractory dissolved organic nitrogen by medium zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jprod_srdon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_srdon_Lgz","Production of semi-refractory dissolved organic nitrogen by large zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jprod_srdon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! Labile dissolved organic phosphorous + vardesc_temp = vardesc("jprod_srdop_Smz","Production of semi-refractory dissolved organic phosphorous by small zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(1)%id_jprod_srdop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_srdop_Mdz","Production of semi-refractory dissolved organic phosphorous by medium zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(2)%id_jprod_srdop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_srdop_Lgz","Production of semi-refractory dissolved organic phosphorous by large zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(3)%id_jprod_srdop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! semi-labile dissolved organic nitrogen + vardesc_temp = vardesc("jprod_sldon_Smz","Production of semi-labile dissolved organic nitrogen by small zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jprod_sldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sldon_Mdz","Production of semi-labile dissolved organic nitrogen by medium zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jprod_sldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sldon_Lgz","Production of semi-labile dissolved organic nitrogen by large zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jprod_sldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! semi-labile dissolved organic phosphorous + vardesc_temp = vardesc("jprod_sldop_Smz","Production of semi-labile dissolved organic phosphorous by small zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(1)%id_jprod_sldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sldop_Mdz","Production of semi-labile dissolved organic phosphorous by medium zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(2)%id_jprod_sldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sldop_Lgz","Production of semi-labile dissolved organic phosphorous by large zooplankton, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + zoo(3)%id_jprod_sldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! dissolved iron + vardesc_temp = vardesc("jprod_fed_Smz","Production of dissolved iron by small zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(1)%id_jprod_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_fed_Mdz","Production of dissolved iron by medium-sized zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(2)%id_jprod_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_fed_Lgz","Production of dissolved iron by large zooplankton, layer integral",& + 'h','L','s','mol Fe m-2 s-1','f') + zoo(3)%id_jprod_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! phosphate + vardesc_temp = vardesc("jprod_po4_Smz","Production of phosphate by small zooplankton, layer integral",& + 'h','L','s','mol PO4 m-2 s-1','f') + zoo(1)%id_jprod_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_po4_Mdz","Production of phosphate by medium-sized zooplankton, layer integral",& + 'h','L','s','mol PO4 m-2 s-1','f') + zoo(2)%id_jprod_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_po4_Lgz","Production of phosphate by large zooplankton, layer integral",& + 'h','L','s','mol PO4 m-2 s-1','f') + zoo(3)%id_jprod_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! ammonia + vardesc_temp = vardesc("jprod_nh4_Smz","Production of ammonia by small zooplankton, layer integral",& + 'h','L','s','mol NH4 m-2 s-1','f') + zoo(1)%id_jprod_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nh4_Mdz","Production of ammonia by medium-sized zooplankton, layer integral",& + 'h','L','s','mol NH4 m-2 s-1','f') + zoo(2)%id_jprod_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nh4_Lgz","Production of ammonia by large zooplankton, layer integral",& + 'h','L','s','mol NH4 m-2 s-1','f') + zoo(3)%id_jprod_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register zooplankton production terms + ! + + vardesc_temp = vardesc("jprod_nsmz","Production of new biomass (nitrogen) by small zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(1)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nmdz","Production of new biomass (nitrogen) by medium-sized zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(2)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nlgz","Production of new biomass (nitrogen) by large zooplankton, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + zoo(3)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("temp_lim_Smz","Temperature limitation of small zooplankton",'h','L','s','dimensionless','f') + zoo(1)%id_temp_lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("temp_lim_Mdz","Temperature limitation of medium-sized zooplankton",'h','L','s','dimensionless','f') + zoo(2)%id_temp_lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("temp_lim_Lgz","Temperature limitation of large zooplankton",'h','L','s','dimensionless','f') + zoo(3)%id_temp_lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register bacterial diagnostics, starting with losses of bacteria to ingestion by zooplankton + ! CAS: limit loss terms to N + + vardesc_temp = vardesc("jzloss_n_Bact","Bacterial nitrogen loss to zooplankton layer integral",& + 'h','L','s','mol N m-2 s-1','f') + bact(1)%id_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for bacteria loss terms: higher predators + ! + +! vardesc_temp = vardesc("jhploss_n_Bact","Bacterial nitrogen loss to higher predators layer integral",& +! 'h','L','s','mol N m-2 s-1','f') +! bact(1)%id_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& +! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register diagnostics for bacteria loss terms: viruses + ! + + vardesc_temp = vardesc("jvirloss_n_Bact","Bacterial nitrogen loss to viruses layer integral",& + 'h','L','s','mol N m-2 s-1','f') + bact(1)%id_jvirloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register bacterial uptake terms + ! + + vardesc_temp = vardesc("juptake_ldon","Bacterial uptake of labile dissolved organic nitrogen",'h','L','s','mol N m-2 s-1','f') + bact(1)%id_juptake_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_ldop","Bacterial uptake of labile dissolved organic phosphorous",'h','L','s','mol P m-2 s-1','f') + bact(1)%id_juptake_ldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register dissolved inorganic production terms for bacteria + ! + ! phosphate + vardesc_temp = vardesc("jprod_po4_Bact","Production of phosphate by bacteria, layer integral",& + 'h','L','s','mol PO4 m-2 s-1','f') + bact(1)%id_jprod_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! ammonia + vardesc_temp = vardesc("jprod_nh4_Bact","Production of ammonia by bacteria, layer integral",& + 'h','L','s','mol NH4 m-2 s-1','f') + bact(1)%id_jprod_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register bacterial production terms + ! + + vardesc_temp = vardesc("jprod_nbact","Production of new biomass (nitrogen) by bacteria, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + bact(1)%id_jprod_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("temp_lim_Bact","Temperature limitation of bacteria",'h','L','s','dimensionless','f') + bact(1)%id_temp_lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Register general COBALT diagnostics + ! + + vardesc_temp = vardesc("co3_sol_arag","Carbonate Ion Solubility for Aragonite",'h','L','s','mol kg-1','f') + cobalt%id_co3_sol_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("co3_sol_calc","Carbonate Ion Solubility for Calcite",'h','L','s','mol kg-1','f') + cobalt%id_co3_sol_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("omega_arag","Carbonate Ion Saturation State for Aragonite",'h','L','s','mol kg-1','f') + cobalt%id_omega_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("omega_calc","Carbonate Ion Saturation State for Calcite",'h','L','s','mol kg-1','f') + cobalt%id_omega_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! A few overall production diagnostics + ! + + vardesc_temp = vardesc("jprod_cadet_arag","Aragonite CaCO3 production layer integral",'h','L','s','mol m-2 s-1','f') + cobalt%id_jprod_cadet_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_cadet_calc","Calcite CaCO3 production layer integral",'h','L','s','mol m-2 s-1','f') + cobalt%id_jprod_cadet_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_lithdet","Lithogenic detritus production layer integral",'h','L','s','g m-2 s-1','f') + cobalt%id_jprod_lithdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + !vardesc_temp = vardesc("jprod_sidet","opal detritus production layer integral",'h','L','s','mol SiO2 m-2 s-1','f') + !cobalt%id_jprod_sidet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_sio4","sio4 production layer integral",'h','L','s','mol SiO2 m-2 s-1','f') + !cobalt%id_jprod_sio4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_fedet","Detrital Fedet production layer integral",'h','L','s','mol Fe m-2 s-1','f') + !cobalt%id_jprod_fedet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_ndet","Detrital PON production layer integral",'h','L','s','mol N m-2 s-1','f') + !cobalt%id_jprod_ndet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_pdet","Detrital phosphorus production layer integral",'h','L','s','mol P m-2 s-1','f') + !cobalt%id_jprod_pdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_ldon","labile dissolved organic nitrogen production layer integral",& + ! 'h','L','s','mol N m-2 s-1','f') + !cobalt%id_jprod_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_ldop","labile dissolved organic phosphorous production layer integral",& + ! 'h','L','s','mol P m-2 s-1','f') + !cobalt%id_jprod_ldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_srdon","refractory dissolved organic nitrogen production layer integral",& + ! 'h','L','s','mol N m-2 s-1','f') + !cobalt%id_jprod_srdon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_srdop","refractory dissolved organic phosphorous production layer integral",& + ! 'h','L','s','mol P m-2 s-1','f') + !cobalt%id_jprod_srdop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_sldon","semi-labile dissolved organic nitrogen production layer integral",& + ! 'h','L','s','mol N m-2 s-1','f') + !cobalt%id_jprod_sldon = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_sldop","semi-labile dissolved organic phosphorous production layer integral",& + ! 'h','L','s','mol P m-2 s-1','f') + !cobalt%id_jprod_sldop = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_fed","dissolved iron production layer integral",& + ! 'h','L','s','mol Fe m-2 s-1','f') + !cobalt%id_jprod_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_po4","phosphate production layer integral",& + ! 'h','L','s','mol PO4 m-2 s-1','f') + !cobalt%id_jprod_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("jprod_nh4","NH4 production layer integral",'h','L','s','mol NH4 m-2 s-1','f') + !cobalt%id_jprod_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + ! + ! loss diagnostics: detrital loss terms + ! + ! + !vardesc_temp = vardesc("det_jzloss_n","nitrogen detritus loss to zooplankton layer integral",& + ! 'h','L','s','mol N m-2 s-1','f') + !cobalt%id_det_jzloss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + !vardesc_temp = vardesc("det_jhploss_n","nitrogen detritus loss to higher predators layer integral",& + ! 'h','L','s','mol N m-2 s-1','f') + !cobalt%id_det_jhploss_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + ! init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + ! + ! Loss diagnostics: dissolution and remineralization + ! + + vardesc_temp = vardesc("jdiss_sidet","SiO2 detritus dissolution, layer integral",& + 'h','L','s','mol m-2 s-1','f') + cobalt%id_jdiss_sidet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jdiss_cadet_arag","CaCO3 detritus dissolution, layer integral", & + 'h','L','s','mol CaCO3 m-2 s-1','f') + cobalt%id_jdiss_cadet_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jdiss_cadet_calc","CaCO3 detritus dissolution, layer integral", & + 'h','L','s','mol CaCO3 m-2 s-1','f') + cobalt%id_jdiss_cadet_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_ndet","Nitrogen detritus remineralization, layer integral",& + 'h','L','s','mol N m-2 s-1','f') + cobalt%id_jremin_ndet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_pdet","Phosphorous detritus remineralization, layer integral",& + 'h','L','s','mol P m-2 s-1','f') + cobalt%id_jremin_pdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_fedet","Iron detritus remineralization, layer integral",& + 'h','L','s','mol m-2 s-1','f') + cobalt%id_jremin_fedet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! iron cycling diagnostics + ! + + vardesc_temp = vardesc("jfe_ads","Iron adsorption layer integral",'h','L','s','mol m-2 s-1','f') + cobalt%id_jfe_ads = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jfe_coast","Coastal iron efflux layer integral",'h','L','s','mol m-2 s-1','f') + cobalt%id_jfe_coast = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("kfe_eq_lig","Effective ligand binding strength",'h','L','s','kg mol-1','f') + cobalt%id_kfe_eq_lig = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Temperature limitation diagnostics + ! + + vardesc_temp = vardesc("expkT","Eppley temperature limitation factor",'h','L','s','dimensionless','f') + cobalt%id_expkT = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("hp_temp_lim","Temperature limitation of higher predators",'h','L','s','dimensionless','f') + cobalt%id_hp_temp_lim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Some additional light field diagnostics + ! + + vardesc_temp = vardesc("irr_inst","Instantaneous Light",'h','L','s','W m-2','f') + cobalt%id_irr_inst = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("irr_mix","Light averaged over mixing layer",'h','L','s','W m-2','f') + cobalt%id_irr_mix = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Nitrification/Denitrification diagnostics + ! + + vardesc_temp = vardesc("jnitrif","Nitrification layer integral",'h','L','s','mol m-2 s-1','f') + cobalt%id_jnitrif = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jno3denit_wc","Water column Denitrification layer integral",'h','L','s','mol m-2 s-1','f') + cobalt%id_jno3denit_wc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + + ! + ! Some useful total layer integrals + ! + + vardesc_temp = vardesc("nphyto_tot","Total NO3: Di+Lg+Sm",'h','L','s','mol m-2 s-1','f') + cobalt%id_nphyto_tot = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("tot_layer_int_c","Total Carbon (DIC+OC+IC) boxwise layer integral",'h','L','s','mol m-2','f') + cobalt%id_tot_layer_int_c = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("tot_layer_int_fe","Total Iron (Fed_OFe) boxwise layer integral",'h','L','s','mol m-2','f') + cobalt%id_tot_layer_int_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("tot_layer_int_n","Total Nitrogen (NO3+NH4+ON) boxwise layer integral",'h','L','s','mol m-2','f') + cobalt%id_tot_layer_int_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("tot_layer_int_p","Total Phosphorus (PO4+OP) boxwise layer integral",'h','L','s','mol m-2','f') + cobalt%id_tot_layer_int_p = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("tot_layer_int_si","Total Silicon (SiO4+SiO2) boxwise layer integral",'h','L','s','mol m-2','f') + cobalt%id_tot_layer_int_si = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("total_filter_feeding","Total filter feeding by large organisms",'h','L','s','mol N m-2 s-1','f') + cobalt%id_total_filter_feeding = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("net_prim_prod","net primary production by all phytoplankton",'h','L','s','mol C m-2 yr-1','f') + cobalt%id_net_prim_prod = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("gross_prim_prod","gross primary production by all phytoplankton",'h','L','s','mol C m-2 yr-1','f') + cobalt%id_gross_prim_prod = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Save river, depositon and bulk elemental fluxes + ! + + vardesc_temp = vardesc("dep_dry_fed","Dry Deposition of Iron to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_dry_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_dry_lith","Dry Deposition of Lithogenic Material",'h','1','s','g m-2 s-1','f') + cobalt%id_dep_dry_lith = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_dry_nh4","Dry Deposition of Ammonia to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_dry_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_dry_no3","Dry Deposition of Nitrate to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_dry_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_dry_po4","Dry Deposition of Phosphate to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_dry_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_wet_fed","Wet Deposition of Iron to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_wet_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_wet_lith","Wet Deposition of Lithogenic Material",'h','1','s','g m-2 s-1','f') + cobalt%id_dep_wet_lith = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_wet_nh4","Wet Deposition of Ammonia to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_wet_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_wet_no3","Wet Deposition of Nitrate to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_wet_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("dep_wet_po4","Wet Deposition of Phosphate to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_dep_wet_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_alk","Alkalinity runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_alk = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_dic","Dissolved Inorganic Carbon runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_dic = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_fed","Iron runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_lith","Lithogenic runoff flux to the ocean",'h','1','s','g m-2 s-1','f') + cobalt%id_runoff_flux_lith = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_no3","Nitrate runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_ldon","LDON runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_sldon","SLDON runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_sldon = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_srdon","SRDON runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_srdon = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_ndet","NDET runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_ndet = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_po4","PO4 runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_ldop","LDOP runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_ldop = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_sldop","SLDOP runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_sldop = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("runoff_flux_srdop","SRDOP runoff flux to the ocean",'h','1','s','mol m-2 s-1','f') + cobalt%id_runoff_flux_srdop = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! 3D sinking information + ! + + vardesc_temp = vardesc("fcadet_arag","CaCO3 sinking flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcadet_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcadet_calc","CaCO3 sinking flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcadet_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("ffedet","fedet sinking flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_ffedet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("flithdet","lithdet sinking flux",'h','1','s','g m-2 s-1','f') + cobalt%id_flithdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fndet","ndet sinking flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fndet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fpdet","pdet sinking flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fpdet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fsidet","sidet sinking flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fsidet = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! 2D sinking, bottom source/sink and burial diagnostics + ! + + vardesc_temp = vardesc("fcadet_arag_btm","CaCO3 sinking flux at bottom",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcadet_arag_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcadet_calc_btm","CaCO3 sinking flux at bottom",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcadet_calc_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcased_burial","CaCO3 permanent burial flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcased_burial = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcased_input","CaCO3 flux into sediment layer",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcased_input = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcased_redis","CaCO3 redissolution from sediments",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcased_redis = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("ffedet_btm","fedet sinking flux burial",'h','1','s','mol m-2 s-1','f') + cobalt%id_ffedet_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("ffe_sed","Sediment iron efflux",'h','1','s','mol m-2 s-1','f') + cobalt%id_ffe_sed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("flithdet_btm","Lithogenic detrital sinking flux burial",'h','1','s','g m-2 s-1','f') + cobalt%id_flithdet_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fndet_btm","ndet sinking flux to bottom",'h','1','s','mol m-2 s-1','f') + cobalt%id_fndet_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fnfeso4red_sed","Sediment Ndet Fe and SO4 reduction flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fnfeso4red_sed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fno3denit_sed","Sediment denitrification flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fno3denit_sed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fnoxic_sed","Sediment oxic Ndet remineralization flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fnoxic_sed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fpdet_btm","pdet sinking flux to bottom",'h','1','s','mol m-2 s-1','f') + cobalt%id_fpdet_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fsidet_btm","sidet sinking flux to bottom",'h','1','s','mol m-2 s-1','f') + cobalt%id_fsidet_btm = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("frac_burial","fraction of organic matter buried",'h','1','s','dimensionless','f') + cobalt%id_frac_burial = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fndet_burial","ndet burial flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fndet_burial = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fpdet_burial","pdet burial flux",'h','1','s','mol m-2 s-1','f') + cobalt%id_fpdet_burial = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Surface Diagnostics + ! + + vardesc_temp = vardesc("pco2surf","Oceanic pCO2",'h','1','s','uatm','f') + cobalt%id_pco2surf = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_alk","Surface Alkalinity",'h','1','s','eq kg-1','f') + cobalt%id_sfc_alk = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_cadet_arag","Surface Detrital Aragonite",'h','1','s','mol kg-1','f') + cobalt%id_sfc_cadet_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_cadet_calc","Surface Detrital Calcite",'h','1','s','mol kg-1','f') + cobalt%id_sfc_cadet_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_dic","Surface Dissolved Inorganic Carbon",'h','1','s','mol kg-1','f') + cobalt%id_sfc_dic = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_fed","Surface Dissolved Iron",'h','1','s','mol kg-1','f') + cobalt%id_sfc_fed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_ldon","Surface Labile Dissolved Organic Nitrogen",'h','1','s','mol kg-1','f') + cobalt%id_sfc_ldon = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_sldon","Surface semi-labile Dissolved Organic Nitrogen",'h','1','s','mol kg-1','f') + cobalt%id_sfc_sldon = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_srdon","Surface semi-refractory Dissolved Organic Nitrogen",'h','1','s','mol kg-1','f') + cobalt%id_sfc_srdon = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_no3","Surface NO3",'h','1','s','mol kg-1','f') + cobalt%id_sfc_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_nh4","Surface NH4",'h','1','s','mol kg-1','f') + cobalt%id_sfc_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_po4","Surface PO4",'h','1','s','mol kg-1','f') + cobalt%id_sfc_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_sio4","Surface SiO4",'h','1','s','mol kg-1','f') + cobalt%id_sfc_sio4 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_htotal","Surface Htotal",'h','1','s','mol kg-1','f') + cobalt%id_sfc_htotal = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_o2","Surface Oxygen",'h','1','s','mol kg-1','f') + cobalt%id_sfc_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_chl","Surface Chl",'h','1','s','ug kg-1','f') + cobalt%id_sfc_chl = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_irr","Surface Irradiance",'h','1','s','W m-2','f') + cobalt%id_sfc_irr = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_irr_mem","Surface Irradiance memory",'h','1','s','W m-2','f') + cobalt%id_sfc_irr_mem = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_temp","Surface Temperature",'h','1','s','deg C','f') + cobalt%id_sfc_temp = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("btm_temp","Bottom Temperature",'h','1','s','deg C','f') + cobalt%id_btm_temp = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("btm_o2","Bottom Oxygen",'h','1','s','mol kg-1','f') + cobalt%id_btm_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_co3_ion","Surface Carbonate Ion",'h','1','s','mol kg-1','f') + cobalt%id_sfc_co3_ion = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_co3_sol_arag","Surface Carbonate Ion Solubility for Aragonite",'h','1','s','mol kg-1','f') + cobalt%id_sfc_co3_sol_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_co3_sol_calc","Surface Carbonate Ion Solubility for Calcite ",'h','1','s','mol kg-1','f') + cobalt%id_sfc_co3_sol_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_nsmp","Surface small phyto. nitrogen",'h','1','s','mol kg-1','f') + phyto(SMALL)%id_sfc_f_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_nlgp","Surface large phyto. nitrogen",'h','1','s','mol kg-1','f') + phyto(LARGE)%id_sfc_f_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_ndi","Surface diazotroph nitrogen",'h','1','s','mol kg-1','f') + phyto(DIAZO)%id_sfc_f_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_chl_smp","Surface small phyto. chlorophyll",'h','1','s','ug kg-1','f') + phyto(SMALL)%id_sfc_chl = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_chl_lgp","Surface large phyto. chlorophyll",'h','1','s','ug kg-1','f') + phyto(LARGE)%id_sfc_chl = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_chl_di","Surface diazotroph chlorophyll",'h','1','s','mol kg-1','f') + phyto(DIAZO)%id_sfc_chl = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_def_fe_smp","Surface small phyto. iron deficiency",'h','1','s','dimensionsless','f') + phyto(SMALL)%id_sfc_def_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_def_fe_lgp","Surface large phyto. iron deficiency",'h','1','s','dimensionless','f') + phyto(LARGE)%id_sfc_def_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_def_fe_di","Surface diazotroph iron deficiency",'h','1','s','dimensionless','f') + phyto(DIAZO)%id_sfc_def_fe = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_felim_smp","Surface small phyto. iron uptake limitation",'h','1','s','dimensionsless','f') + phyto(SMALL)%id_sfc_felim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_felim_lgp","Surface large phyto. iron uptake limitation",'h','1','s','dimensionless','f') + phyto(LARGE)%id_sfc_felim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_felim_di","Surface diazotroph iron uptake limitation",'h','1','s','dimensionless','f') + phyto(DIAZO)%id_sfc_felim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_q_fe_2_n_di","Surface diazotroph iron:nitrogen",'h','1','s','moles Fe (moles N)-1','f') + phyto(DIAZO)%id_sfc_q_fe_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_q_fe_2_n_smp","Surface small phyto. iron:nitrogen",'h','1','s','moles Fe (moles N)-1','f') + phyto(SMALL)%id_sfc_q_fe_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_q_fe_2_n_lgp","Surface large phyto. iron:nitrogen",'h','1','s','moles Fe (moles N)-1','f') + phyto(LARGE)%id_sfc_q_fe_2_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_irrlim_smp","Surface small phyto. light limitation",'h','1','s','dimensionsless','f') + phyto(SMALL)%id_sfc_irrlim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_irrlim_lgp","Surface large phyto. light limitation",'h','1','s','dimensionless','f') + phyto(LARGE)%id_sfc_irrlim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_irrlim_di","Surface diazotroph light limitation",'h','1','s','dimensionless','f') + phyto(DIAZO)%id_sfc_irrlim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_theta_smp","Surface small phyto. Chl:C",'h','1','s','g Chl (g C)-1','f') + phyto(SMALL)%id_sfc_theta = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_theta_lgp","Surface large phyto. Chl:C",'h','1','s','g Chl (g C)-1','f') + phyto(LARGE)%id_sfc_theta = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_theta_di","Surface diazotroph Chl:C",'h','1','s','g Chl (g C)-1','f') + phyto(DIAZO)%id_sfc_theta = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_mu_smp","Surface small phyto. Chl:C",'h','1','s','sec-1','f') + phyto(SMALL)%id_sfc_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_mu_lgp","Surface large phyto. Chl:C",'h','1','s','sec-1','f') + phyto(LARGE)%id_sfc_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_mu_di","Surface diazotroph growth rate",'h','1','s','sec-1','f') + phyto(DIAZO)%id_sfc_mu = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_no3lim_smp","Surface small phyto. nitrate limitation",'h','1','s','dimensionsless','f') + phyto(SMALL)%id_sfc_no3lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_no3lim_lgp","Surface large phyto. nitrate limitation",'h','1','s','dimensionless','f') + phyto(LARGE)%id_sfc_no3lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_nh4lim_smp","Surface small phyto. ammonia limitation",'h','1','s','dimensionsless','f') + phyto(SMALL)%id_sfc_nh4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_nh4lim_lgp","Surface large phyto. ammonia limitation",'h','1','s','dimensionless','f') + phyto(LARGE)%id_sfc_nh4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_po4lim_smp","Surface small phyto. phosphate limitation",'h','1','s','dimensionsless','f') + phyto(SMALL)%id_sfc_po4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_po4lim_lgp","Surface large phyto. phosphate limitation",'h','1','s','dimensionless','f') + phyto(LARGE)%id_sfc_po4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("sfc_po4lim_di","Surface diazotroph phosphate limitation",'h','1','s','dimensionless','f') + phyto(DIAZO)%id_sfc_po4lim = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! 100m integrated fluxes + ! + + vardesc_temp = vardesc("jprod_allphytos_100","Total Nitrogen prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_jprod_allphytos_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndi_100","Diazotroph nitrogen prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(DIAZO)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nsmp_100","Small phyto. nitrogen prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(SMALL)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nlgp_100","Large phyto. nitrogen prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(LARGE)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndi_new_100","Diazotroph new (NO3-based) prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(DIAZO)%id_jprod_n_new_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nsmp_new_100","Small phyto. new (NO3-based) prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(SMALL)%id_jprod_n_new_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nlgp_new_100","Large phyto. new (NO3-based) prim. prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(LARGE)%id_jprod_n_new_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndi_n2_100","Diazotroph nitrogen fixation in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(DIAZO)%id_jprod_n_n2_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_ndi_100","Diazotroph nitrogen loss to zooplankton integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(DIAZO)%id_jzloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_nsmp_100","Small phyto. nitrogen loss to zooplankton integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(SMALL)%id_jzloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_nlgp_100","Large phyto. nitrogen loss to zooplankton integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(LARGE)%id_jzloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jaggloss_nsmp_100","Small phyto. nitrogen aggregation loss integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(SMALL)%id_jaggloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jaggloss_nlgp_100","Large phyto. nitrogen aggregation loss integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(LARGE)%id_jaggloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jvirloss_nsmp_100","Small phyto. nitrogen virus loss integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(SMALL)%id_jvirloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jexuloss_ndi_100","Diazotroph nitrogen exudation loss integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(DIAZO)%id_jexuloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jexuloss_nsmp_100","Small phyto. nitrogen exudation loss integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(SMALL)%id_jexuloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jexuloss_nlgp_100","Large phyto. nitrogen exudation loss integral in upper 100m",'h','1','s','mol m-2 s-1','f') + phyto(LARGE)%id_jexuloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nsmz_100","Small zooplankton nitrogen prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(1)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nmdz_100","Medium zooplankton nitrogen prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nlgz_100","Large zooplankton nitrogen prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(3)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_n_nsmz_100","Small zooplankton nitrogen ingestion integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(1)%id_jingest_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_n_nmdz_100","Medium zooplankton nitrogen ingestion integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jingest_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_n_nlgz_100","Large zooplankton nitrogen ingestion integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(3)%id_jingest_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_nsmz_100","Small zooplankton nitrogen loss to zooplankton integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(1)%id_jzloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_nmdz_100","Medium zooplankton nitrogen loss to zooplankton integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jzloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jhploss_nmdz_100","Medium zooplankton nitrogen loss to higher preds. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jhploss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jhploss_nlgz_100","Large zooplankton nitrogen loss to higher preds. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(3)%id_jhploss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndet_nmdz_100","Medium zooplankton nitrogen detritus prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jprod_ndet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndet_nlgz_100","Large zooplankton nitrogen detritus prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(3)%id_jprod_ndet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_don_nsmz_100","Small zooplankton dissolved org. nitrogen prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(1)%id_jprod_don_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_don_nmdz_100","Medium zooplankton dissolved org. nitrogen prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jprod_don_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_n_nsmz_100","Small zooplankton nitrogen remineralization integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(1)%id_jremin_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_n_nmdz_100","Medium zooplankton nitrogen remineralization integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(2)%id_jremin_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_n_nlgz_100","Large zooplankton nitrogen remineralization integral in upper 100m",'h','1','s','mol m-2 s-1','f') + zoo(3)%id_jremin_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_n_hp_100","Higher predator nitrogen remineralization integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_hp_jremin_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jingest_n_hp_100","Higher predator ingestion of nitrogen integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_hp_jingest_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_ndet_hp_100","Higher predator nitrogen detritus prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_hp_jprod_ndet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_nbact_100","Bacteria nitrogen prod. integral in upper 100m",'h','1','s','mol m-2 s-1','f') + bact(1)%id_jprod_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jzloss_nbact_100","Bacteria nitrogen loss to zooplankton integral in upper 100m",'h','1','s','mol m-2 s-1','f') + bact(1)%id_jzloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jvirloss_nbact_100","Bacteria nitrogen loss to viruses integral in upper 100m",'h','1','s','mol m-2 s-1','f') + bact(1)%id_jvirloss_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_n_nbact_100","Bacteria nitrogen remineralization integral in upper 100m",'h','1','s','mol m-2 s-1','f') + bact(1)%id_jremin_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("juptake_ldon_nbact_100","Bacterial uptake of labile dissolved org. nitrogen in upper 100m",'h','1','s','mol m-2 s-1','f') + bact(1)%id_juptake_ldon_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_lithdet_100","Lithogenic detritus production integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_jprod_lithdet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_sidet_100","Silica detritus production integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_jprod_sidet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_cadet_calc_100","Calcite detritus production integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_jprod_cadet_calc_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_cadet_arag_100","Aragonite detritus production integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_jprod_cadet_arag_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jremin_ndet_100","Remineralization of nitrogen detritus integral in upper 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_jremin_ndet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("jprod_mesozoo_200","Mesozooplankton Production, 200m integration",'h','1','s','mol m-2 s-1','f') + cobalt%id_jprod_mesozoo_200 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! 100m integrated biomass + ! + + vardesc_temp = vardesc("nsmp_100","Small phytoplankton nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + phyto(SMALL)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nlgp_100","Large phytoplankton nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + phyto(LARGE)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("ndi_100","Diazotroph nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + phyto(DIAZO)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nsmz_100","Small zooplankton nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + zoo(1)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nmdz_100","Medium zooplankton nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + zoo(2)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nlgz_100","Large zooplankton nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + zoo(3)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("nbact_100","Bacterial nitrogen biomass in upper 100m",'h','1','s','mol m-2','f') + bact(1)%id_f_n_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("silgp_100","Large phytoplankton silicon biomass in upper 100m",'h','1','s','mol m-2','f') + cobalt%id_f_silg_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("ndet_100","Nitrogen detritus biomass in upper 100m",'h','1','s','mol m-2','f') + cobalt%id_f_ndet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("don_100","Dissolved organic nitrogen (sr+sl+l) in upper 100m",'h','1','s','mol m-2','f') + cobalt%id_f_don_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("mesozoo_200","Mesozooplankton biomass, 200m integral",'h','1','s','mol m-2','f') + cobalt%id_f_mesozoo_200 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + ! + ! sinking flux = 100m + ! + + vardesc_temp = vardesc("fndet_100","Nitrogen detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_fndet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fpdet_100","Phosphorous detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_fpdet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("ffedet_100","Iron detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_ffedet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fsidet_100","Silicon detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_fsidet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcadet_calc_100","Calcite detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcadet_calc_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("fcadet_arag_100","Aragonite detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_fcadet_arag_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("flithdet_100","Lithogenic detritus sinking flux @ 100m",'h','1','s','mol m-2 s-1','f') + cobalt%id_flithdet_100 = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! Oxygen minima (value and location + ! + + vardesc_temp = vardesc("o2min","Minimum Oxygen",'h','1','s','mol kg-1','f') + cobalt%id_o2min = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + vardesc_temp = vardesc("z_o2min","Depth of Oxygen minimum",'h','1','s','m','f') + cobalt%id_z_o2min = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + + ! + ! Calcite and aragonite saturation depths + ! + + vardesc_temp = vardesc("z_sat_arag","Depth of Aragonite Saturation",'h','1','s','m','f') + cobalt%id_z_sat_arag = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1, & + mask_variant=.TRUE.) + + vardesc_temp = vardesc("z_sat_calc","Depth of Calcite Saturation",'h','1','s','m','f') + cobalt%id_z_sat_calc = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1, & + mask_variant=.TRUE.) + + + + end subroutine generic_COBALT_register_diag + + ! + ! This is an internal sub, not a public interface. + ! Add all the parameters to be used in this module. + ! + subroutine user_add_params + + !Specify all parameters used in this modules. + !===============================@=============================== + !User adds one call for each parameter below! + !User also adds the definition of each parameter in generic_COBALT_params type + !============================================================== + + !============= + !Block Starts: g_tracer_add_param + !============= + !Add the known experimental parameters used for calculations + !in this module. + !All the g_tracer_add_param calls must happen between + !g_tracer_start_param_list and g_tracer_end_param_list calls. + !This implementation enables runtime overwrite via field_table. + + call g_tracer_start_param_list(package_name) + call g_tracer_add_param('init', cobalt%init, .false. ) + + call g_tracer_add_param('htotal_scale_lo', cobalt%htotal_scale_lo, 0.01) + call g_tracer_add_param('htotal_scale_hi', cobalt%htotal_scale_hi, 100.0) + + ! Rho_0 is used in the Boussinesq + ! approximation to calculations of pressure and + ! pressure gradients, in units of kg m-3. + call g_tracer_add_param('RHO_0', cobalt%Rho_0, 1035.0) + call g_tracer_add_param('NKML' , cobalt%nkml, 1) + !----------------------------------------------------------------------- + ! coefficients for O2 saturation + !----------------------------------------------------------------------- + call g_tracer_add_param('a_0', cobalt%a_0, 2.00907) + call g_tracer_add_param('a_1', cobalt%a_1, 3.22014) + call g_tracer_add_param('a_2', cobalt%a_2, 4.05010) + call g_tracer_add_param('a_3', cobalt%a_3, 4.94457) + call g_tracer_add_param('a_4', cobalt%a_4, -2.56847e-01) + call g_tracer_add_param('a_5', cobalt%a_5, 3.88767) + call g_tracer_add_param('b_0', cobalt%b_0, -6.24523e-03) + call g_tracer_add_param('b_1', cobalt%b_1, -7.37614e-03) + call g_tracer_add_param('b_2', cobalt%b_2, -1.03410e-02 ) + call g_tracer_add_param('b_3', cobalt%b_3, -8.17083e-03) + call g_tracer_add_param('c_0', cobalt%c_0, -4.88682e-07) + !----------------------------------------------------------------------- + ! Schmidt number coefficients + !----------------------------------------------------------------------- + ! + ! Compute the Schmidt number of CO2 in seawater using the + ! formulation presented by Wanninkhof (1992, J. Geophys. Res., 97, + ! 7373-7382). + !----------------------------------------------------------------------- + !New Wanninkhof numbers + call g_tracer_add_param('a1_co2', cobalt%a1_co2, 2068.9) + call g_tracer_add_param('a2_co2', cobalt%a2_co2, -118.63) + call g_tracer_add_param('a3_co2', cobalt%a3_co2, 2.9311) + call g_tracer_add_param('a4_co2', cobalt%a4_co2, -0.027) + !--------------------------------------------------------------------- + ! Compute the Schmidt number of O2 in seawater using the + ! formulation proposed by Keeling et al. (1998, Global Biogeochem. + ! Cycles, 12, 141-163). + !--------------------------------------------------------------------- + !New Wanninkhof numbers + call g_tracer_add_param('a1_o2', cobalt%a1_o2, 1929.7) + call g_tracer_add_param('a2_o2', cobalt%a2_o2, -117.46) + call g_tracer_add_param('a3_o2', cobalt%a3_o2, 3.116) + call g_tracer_add_param('a4_o2', cobalt%a4_o2, -0.0306) + ! + !----------------------------------------------------------------------- + ! Stoichiometry + !----------------------------------------------------------------------- + ! + ! Values taken from OCMIP-II Biotic protocols after Anderson + ! and Sarmiento (1994) + ! + call g_tracer_add_param('mass_2_n', cobalt%mass_2_n, 106.0 / 16.0 * 12.0 * 1.87) ! g mol N-1 + call g_tracer_add_param('n_2_n_denit', cobalt%n_2_n_denit, 472.0/(5.0*16.0)) ! mol N NO3 mol N org-1 + call g_tracer_add_param('o2_2_c', cobalt%o2_2_c, 150.0 / 106) ! mol O2 mol C-1 + call g_tracer_add_param('o2_2_nfix', cobalt%o2_2_nfix, (118.0+3.0/(5.0+3.0)*(150.0-118.0))/16.0) ! mol O2 mol N-1 + call g_tracer_add_param('o2_2_nh4', cobalt%o2_2_nh4, 118.0 / 16) ! mol O2 mol N-1 + call g_tracer_add_param('o2_2_nitrif', cobalt%o2_2_nitrif, 2.0) ! mol O2 mol N-1 + call g_tracer_add_param('o2_2_no3', cobalt%o2_2_no3, 150.0 / 16.0) ! mol O2 mol N-1 + ! + !----------------------------------------------------------------------- + ! Nutrient Limitation Parameters (phytoplankton) + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('k_fed_Di', phyto(DIAZO)%k_fed, 5.0e-10) ! mol Fed kg-1 + call g_tracer_add_param('k_fed_Lg', phyto(LARGE)%k_fed, 5.0e-10) ! mol Fed kg-1 + call g_tracer_add_param('k_fed_Sm', phyto(SMALL)%k_fed, 1.0e-10) ! mol Fed kg-1 + call g_tracer_add_param('k_nh4_Lg', phyto(LARGE)%k_nh4, 5.0e-7) ! mol NH4 kg-1 + call g_tracer_add_param('k_nh4_Sm', phyto(SMALL)%k_nh4, 1.0e-7) ! mol NH4 kg-1 + call g_tracer_add_param('k_nh4_Di', phyto(DIAZO)%k_nh4, 5.0e-7) ! mol NH4 kg-1 + call g_tracer_add_param('k_no3_Lg', phyto(LARGE)%k_no3, 2.5e-6) ! mol NO3 kg-1 + call g_tracer_add_param('k_no3_Sm', phyto(SMALL)%k_no3, 5.0e-7) ! mol NO3 kg-1 + call g_tracer_add_param('k_no3_Di', phyto(DIAZO)%k_no3, 2.5e-6) ! mol NO3 kg-1 + call g_tracer_add_param('k_po4_Di', phyto(DIAZO)%k_po4, 5.0e-8) ! mol PO4 kg-1 + call g_tracer_add_param('k_po4_Lg', phyto(LARGE)%k_po4, 5.0e-8) ! mol PO4 kg-1 + call g_tracer_add_param('k_po4_Sm', phyto(SMALL)%k_po4, 1.0e-8) ! mol PO4 kg-1 + call g_tracer_add_param('k_sio4_Lg',phyto(LARGE)%k_sio4, 2.0e-6) ! mol SiO4 kg-1 + call g_tracer_add_param('k_fe_2_n_Di', phyto(DIAZO)%k_fe_2_n, 25.0e-6 * 106.0 / 16.0) ! mol Fe mol N-1 + call g_tracer_add_param('k_fe_2_n_Lg', phyto(LARGE)%k_fe_2_n, 6.0e-6 * 106.0 / 16.0) ! mol Fe mol N-1 + call g_tracer_add_param('k_fe_2_n_Sm',phyto(SMALL)%k_fe_2_n, 3.0e-6*106.0/16.0) ! mol Fe mol N-1 + call g_tracer_add_param('fe_2_n_max_Sm',phyto(SMALL)%fe_2_n_max, 50.e-6*106.0/16.0) ! mol Fe mol N-1 + call g_tracer_add_param('fe_2_n_max_Lg', phyto(LARGE)%fe_2_n_max, 500.0e-6*106.0/16.0) ! mol Fe mol N-1 + call g_tracer_add_param('fe_2_n_max_Di', phyto(DIAZO)%fe_2_n_max, 500.0e-6*106.0/16.0) ! mol Fe mol N-1 + call g_tracer_add_param('fe_2_n_upt_fac', cobalt%fe_2_n_upt_fac, 15.0e-6) ! mol Fe mol N-1 + ! + !----------------------------------------------------------------------- + ! Phytoplankton light limitation/growth rate + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('alpha_Di', phyto(DIAZO)%alpha, 1.0e-5 * 2.77e18 / 6.022e17) ! g C g Chl-1 m2 W-1 s-1 + call g_tracer_add_param('alpha_Lg', phyto(LARGE)%alpha, 1.0e-5 * 2.77e18 / 6.022e17) ! g C g Chl-1 m2 W-1 s-1 + call g_tracer_add_param('alpha_Sm', phyto(SMALL)%alpha,2.0e-5*2.77e18/6.022e17) ! g C g Chl-1 m2 W-1 s-1 + call g_tracer_add_param('kappa_eppley', cobalt%kappa_eppley, 0.063) ! deg C-1 + call g_tracer_add_param('P_C_max_Di', phyto(DIAZO)%P_C_max, 0.50/sperd) ! s-1 + call g_tracer_add_param('P_C_max_Lg', phyto(LARGE)%P_C_max, 1.25/sperd) ! s-1 + call g_tracer_add_param('P_C_max_Sm', phyto(SMALL)%P_C_max, 1.125/sperd) ! s-1 + call g_tracer_add_param('thetamax_Di', phyto(DIAZO)%thetamax, 0.03) ! g Chl g C-1 + call g_tracer_add_param('thetamax_Lg', phyto(LARGE)%thetamax, 0.05) ! g Chl g C-1 + call g_tracer_add_param('thetamax_Sm', phyto(SMALL)%thetamax, 0.03) ! g Chl g C-1 + call g_tracer_add_param('bresp_Di', phyto(DIAZO)%bresp,0.025/sperd) ! sec-1 + call g_tracer_add_param('bresp_Lg', phyto(LARGE)%bresp,0.025/sperd) ! sec-1 + call g_tracer_add_param('bresp_Sm', phyto(SMALL)%bresp,0.0225/sperd) ! sec-1 + call g_tracer_add_param('thetamin', cobalt%thetamin, 0.002) ! g Chl g C-1 + call g_tracer_add_param('thetamin_nolim', cobalt%thetamin_nolim, 0.0) ! g Chl g C-1 + call g_tracer_add_param('zeta', cobalt%zeta, 0.05) ! dimensionless + call g_tracer_add_param('gamma_irr_mem', cobalt%gamma_irr_mem, 1.0 / sperd) ! s-1 + ! + !----------------------------------------------------------------------- + ! Nitrogen fixation inhibition parameters + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('k_n_inhib_Di', cobalt%k_n_inhib_Di, 1.0e-6) ! mol NO3 kg-1 + call g_tracer_add_param('o2_inhib_Di_pow', cobalt%o2_inhib_Di_pow, 4.0) ! mol O2-1 m3 + call g_tracer_add_param('o2_inhib_Di_sat', cobalt%o2_inhib_Di_sat, 3.0e-4) ! mol O2 kg-1 + ! + !----------------------------------------------------------------------- + ! Other stoichiometry + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('p_2_n_static', cobalt%p_2_n_static, .true. ) + call g_tracer_add_param('c_2_n', cobalt%c_2_n, 106.0 / 16.0) + call g_tracer_add_param('alk_2_n_denit', cobalt%alk_2_n_denit, 552.0/472.0) ! eq. alk mol NO3-1 + call g_tracer_add_param('p_2_n_static_Di', phyto(DIAZO)%p_2_n_static,1.0/40.0 ) ! mol P mol N-1 + call g_tracer_add_param('p_2_n_static_Lg', phyto(LARGE)%p_2_n_static,1.0/16.0 ) ! mol P mol N-1 + call g_tracer_add_param('p_2_n_static_Sm', phyto(SMALL)%p_2_n_static,1.0/16.0 ) ! mol P mol N-1 + call g_tracer_add_param('si_2_n_static_Lg', phyto(LARGE)%si_2_n_static, 2.0) ! mol Si mol N-1 + call g_tracer_add_param('si_2_n_max_Lg', phyto(LARGE)%si_2_n_max, 5.0) ! mol Si mol N-1 + call g_tracer_add_param('ca_2_n_arag', cobalt%ca_2_n_arag, 0.020 * 106.0 / 16.0) ! mol Ca mol N-1 + call g_tracer_add_param('ca_2_n_calc', cobalt%ca_2_n_calc, 0.010 * 106.0 / 16.0) ! mol Ca mol N-1 + call g_tracer_add_param('caco3_sat_max', cobalt%caco3_sat_max,10.0) ! dimensionless + ! + !----------------------------------------------------------------------- + ! Zooplankton Stoichiometry - presently static + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('q_p_2_n_smz',zoo(1)%q_p_2_n, 1.0/16.0) ! mol P mol N-1 + call g_tracer_add_param('q_p_2_n_mdz',zoo(2)%q_p_2_n, 1.0/16.0) ! mol P mol N-1 + call g_tracer_add_param('q_p_2_n_lgz',zoo(3)%q_p_2_n, 1.0/16.0) ! mol P mol N-1 + ! + !----------------------------------------------------------------------- + ! Bacteria Stoichiometry - presently static + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('q_p_2_n_bact',bact(1)%q_p_2_n, 1.0/16.0) ! mol P mol N-1 + ! + ! + !----------------------------------------------------------------------- + ! Phytoplankton aggregation + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('agg_Sm',phyto(SMALL)%agg,0.1*1e6 / sperd) ! s-1 (mole N kg)-1 + call g_tracer_add_param('agg_Di',phyto(DIAZO)%agg, 0 / sperd) ! s-1 (mole N kg)-1 + call g_tracer_add_param('agg_Lg',phyto(LARGE)%agg,0.3*1e6/ sperd) ! s-1 (mole N kg)-1 + ! + !----------------------------------------------------------------------- + ! Phytoplankton and bacterial losses to viruses + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('vir_Sm',phyto(SMALL)%vir, 0.025*1e6/sperd ) ! s-1 (mole N kg)-1 + call g_tracer_add_param('vir_Di',phyto(DIAZO)%vir, 0.0 ) ! s-1 (mole N kg)-1 + call g_tracer_add_param('vir_Lg',phyto(LARGE)%vir, 0.0 ) ! s-1 (mole N kg)-1 + call g_tracer_add_param('vir_Bact',bact(1)%vir, 0.033*1e6/sperd) ! s-1 (mole N kg)-1 + call g_tracer_add_param('ktemp_vir',cobalt%vir_ktemp, 0.063) ! C-1 + ! + !----------------------------------------------------------------------- + ! Phytoplankton losses to exudation + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('exu_Sm',phyto(SMALL)%exu, 0.13) ! dimensionless (fraction of NPP) + call g_tracer_add_param('exu_Di',phyto(DIAZO)%exu, 0.13) ! dimensionless (fraction of NPP) + call g_tracer_add_param('exu_Lg',phyto(LARGE)%exu, 0.13) ! dimensionless (fraction of NPP) + ! + !----------------------------------------------------------------------- + ! Zooplankton ingestion parameterization and temperature dependence + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('imax_smz',zoo(1)%imax, 1.42 / sperd) ! s-1 + call g_tracer_add_param('imax_mdz',zoo(2)%imax, 0.57 / sperd) ! s-1 + call g_tracer_add_param('imax_lgz',zoo(3)%imax, 0.23 / sperd) ! s-1 + call g_tracer_add_param('ki_smz',zoo(1)%ki, 1.25e-6) ! moles N kg-1 + call g_tracer_add_param('ki_mdz',zoo(2)%ki, 1.25e-6) ! moles N kg-1 + call g_tracer_add_param('ki_lgz',zoo(3)%ki, 1.25e-6) ! moles N kg-1 + call g_tracer_add_param('ktemp_smz',zoo(1)%ktemp, 0.063) ! C-1 + call g_tracer_add_param('ktemp_mdz',zoo(2)%ktemp, 0.063) ! C-1 + call g_tracer_add_param('ktemp_lgz',zoo(3)%ktemp, 0.063) ! C-1 + ! + !----------------------------------------------------------------------- + ! Bacterial growth and uptake parameters + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('mu_max_bact',bact(1)%mu_max, 1.0/sperd ) ! s-1 + call g_tracer_add_param('k_ldon_bact', bact(1)%k_ldon, 5.0e-7) ! mol ldon kg-1 + call g_tracer_add_param('ktemp_bact', bact(1)%ktemp, 0.063) ! C-1 + ! + !----------------------------------------------------------------------- + ! Zooplankton switching and prey preference parameters + !----------------------------------------------------------------------- + ! + ! parameters controlling the extent of biomass-based switching between + ! multiple prey options + call g_tracer_add_param('nswitch_smz',zoo(1)%nswitch, 2.0) ! dimensionless + call g_tracer_add_param('nswitch_mdz',zoo(2)%nswitch, 2.0) ! dimensionless + call g_tracer_add_param('nswitch_lgz',zoo(3)%nswitch, 2.0) ! dimensionless + call g_tracer_add_param('mswitch_smz',zoo(1)%mswitch, 2.0) ! dimensionless + call g_tracer_add_param('mswitch_mdz',zoo(2)%mswitch, 2.0) ! dimensionless + call g_tracer_add_param('mswitch_lgz',zoo(3)%mswitch, 2.0) ! dimensionless + ! innate prey availability for small zooplankton + call g_tracer_add_param('smz_ipa_smp',zoo(1)%ipa_smp, 1.0) ! dimensionless + call g_tracer_add_param('smz_ipa_lgp',zoo(1)%ipa_lgp, 0.0) ! dimensionless + call g_tracer_add_param('smz_ipa_diaz',zoo(1)%ipa_diaz,0.0) ! dimensionless + call g_tracer_add_param('smz_ipa_smz',zoo(1)%ipa_smz, 0.0) ! dimensionless + call g_tracer_add_param('smz_ipa_mdz',zoo(1)%ipa_mdz, 0.0) ! dimensionless + call g_tracer_add_param('smz_ipa_lgz',zoo(1)%ipa_lgz, 0.0) ! dimensionless + call g_tracer_add_param('smz_ipa_bact',zoo(1)%ipa_bact,0.25) ! dimensionless + call g_tracer_add_param('smz_ipa_det',zoo(1)%ipa_det, 0.0) ! dimensionless + ! innate prey availability for large zooplankton + call g_tracer_add_param('mdz_ipa_smp',zoo(2)%ipa_smp, 0.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_lgp',zoo(2)%ipa_lgp, 1.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_diaz',zoo(2)%ipa_diaz,1.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_smz',zoo(2)%ipa_smz, 1.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_mdz',zoo(2)%ipa_mdz, 0.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_lgz',zoo(2)%ipa_lgz, 0.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_bact',zoo(2)%ipa_bact, 0.0) ! dimensionless + call g_tracer_add_param('mdz_ipa_det',zoo(2)%ipa_det, 0.0) ! dimensionless + ! innate prey availability large predatory zooplankton/krill + call g_tracer_add_param('lgz_ipa_smp',zoo(3)%ipa_smp, 0.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_lgp',zoo(3)%ipa_lgp, 1.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_diaz',zoo(3)%ipa_diaz, 1.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_smz',zoo(3)%ipa_smz, 0.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_mdz',zoo(3)%ipa_mdz, 1.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_lgz',zoo(3)%ipa_lgz, 0.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_bact',zoo(3)%ipa_bact, 0.0) ! dimensionless + call g_tracer_add_param('lgz_ipa_det',zoo(3)%ipa_det, 0.0) ! dimensionless + ! + !---------------------------------------------------------------------- + ! Zooplankton bioenergetics + !---------------------------------------------------------------------- + ! + call g_tracer_add_param('gge_max_smz',zoo(1)%gge_max, 0.4) ! dimensionless + call g_tracer_add_param('gge_max_mdz',zoo(2)%gge_max, 0.4) ! dimensionless + call g_tracer_add_param('gge_max_lgz',zoo(3)%gge_max, 0.4) ! dimensionless + call g_tracer_add_param('bresp_smz',zoo(1)%bresp, 0.020 / sperd) ! s-1 + call g_tracer_add_param('bresp_mdz',zoo(2)%bresp, 0.008 / sperd) ! s-1 + call g_tracer_add_param('bresp_lgz',zoo(3)%bresp, 0.0032 / sperd) ! s-1 + ! + !---------------------------------------------------------------------- + ! Bacterial bioenergetics + !---------------------------------------------------------------------- + ! + call g_tracer_add_param('gge_max_bact',bact(1)%gge_max,0.4) ! dimensionless + call g_tracer_add_param('bresp_bact',bact(1)%bresp, 0.0075/sperd) ! s-1 + ! + !---------------------------------------------------------------------- + ! Partitioning of zooplankton ingestion to other compartments + !---------------------------------------------------------------------- + ! + call g_tracer_add_param('phi_det_smz',zoo(1)%phi_det, 0.00) ! dimensionless + call g_tracer_add_param('phi_det_mdz',zoo(2)%phi_det, 0.20) ! dimensionless + call g_tracer_add_param('phi_det_lgz',zoo(3)%phi_det, 0.30) ! dimensionless + call g_tracer_add_param('phi_ldon_smz',zoo(1)%phi_ldon, 0.55*0.30) ! dimensionless + call g_tracer_add_param('phi_ldon_mdz',zoo(2)%phi_ldon, 0.55*0.10) ! dimensionless + call g_tracer_add_param('phi_ldon_lgz',zoo(3)%phi_ldon, 0.55*0.0) ! dimensionless + call g_tracer_add_param('phi_ldop_smz',zoo(1)%phi_ldop, 0.45*0.30) ! dimensionless + call g_tracer_add_param('phi_ldop_mdz',zoo(2)%phi_ldop, 0.45*0.10) ! dimensionless + call g_tracer_add_param('phi_ldop_lgz',zoo(3)%phi_ldop, 0.45*0.0) ! dimensionless + call g_tracer_add_param('phi_srdon_smz',zoo(1)%phi_srdon, 0.05*0.30) ! dimensionless + call g_tracer_add_param('phi_srdon_mdz',zoo(2)%phi_srdon, 0.05*0.10) ! dimensionless + call g_tracer_add_param('phi_srdon_lgz',zoo(3)%phi_srdon, 0.05*0.0) ! dimensionless + call g_tracer_add_param('phi_srdop_smz',zoo(1)%phi_srdop, 0.15*0.30) ! dimensionless + call g_tracer_add_param('phi_srdop_mdz',zoo(2)%phi_srdop, 0.15*0.10) ! dimensionless + call g_tracer_add_param('phi_srdop_lgz',zoo(3)%phi_srdop, 0.15*0.0) ! dimensionless + call g_tracer_add_param('phi_sldon_smz',zoo(1)%phi_sldon, 0.4*0.30) ! dimensionless + call g_tracer_add_param('phi_sldon_mdz',zoo(2)%phi_sldon, 0.4*0.10) ! dimensionless + call g_tracer_add_param('phi_sldon_lgz',zoo(3)%phi_sldon, 0.4*0.0) ! dimensionless + call g_tracer_add_param('phi_sldop_smz',zoo(1)%phi_sldop, 0.4*0.30) ! dimensionless + call g_tracer_add_param('phi_sldop_mdz',zoo(2)%phi_sldop, 0.4*0.10) ! dimensionless + call g_tracer_add_param('phi_sldop_lgz',zoo(3)%phi_sldop, 0.4*0.0) ! dimensionless + call g_tracer_add_param('phi_nh4_smz',zoo(1)%phi_nh4, 0.30) ! dimensionless + call g_tracer_add_param('phi_nh4_mdz',zoo(2)%phi_nh4, 0.30) ! dimensionless + call g_tracer_add_param('phi_nh4_lgz',zoo(3)%phi_nh4, 0.30) ! dimensionless + call g_tracer_add_param('phi_po4_smz',zoo(1)%phi_po4, 0.30) ! dimensionless + call g_tracer_add_param('phi_po4_mdz',zoo(2)%phi_po4, 0.30) ! dimensionless + call g_tracer_add_param('phi_po4_lgz',zoo(3)%phi_po4, 0.30) ! dimensionless + ! + !---------------------------------------------------------------------- + ! Partitioning of viral losses to various dissolved pools + !---------------------------------------------------------------------- + ! + call g_tracer_add_param('phi_ldon_vir',cobalt%lysis_phi_ldon, 0.55) ! dimensionless + call g_tracer_add_param('phi_srdon_vir',cobalt%lysis_phi_srdon, 0.05) ! dimensionless + call g_tracer_add_param('phi_sldon_vir',cobalt%lysis_phi_sldon, 0.40) ! dimensionless + call g_tracer_add_param('phi_ldop_vir',cobalt%lysis_phi_ldop, 0.45) ! dimensionless + call g_tracer_add_param('phi_srdop_vir',cobalt%lysis_phi_srdop, 0.15) ! dimensionless + call g_tracer_add_param('phi_sldop_vir',cobalt%lysis_phi_sldop, 0.40) ! dimensionless + ! + !---------------------------------------------------------------------- + ! Parameters for unresolved higher predators + !---------------------------------------------------------------------- + ! + call g_tracer_add_param('imax_hp', cobalt%imax_hp, 0.09/sperd) ! s-1 + call g_tracer_add_param('ki_hp', cobalt%ki_hp, 1.2e-6) ! mol N kg-1 + call g_tracer_add_param('coef_hp', cobalt%coef_hp, 2.0) ! dimensionless + call g_tracer_add_param('ktemp_hp', cobalt%ktemp_hp, 0.063) ! C-1 + call g_tracer_add_param('nswitch_hp', cobalt%nswitch_hp, 2.0) ! dimensionless + call g_tracer_add_param('mswitch_hp', cobalt%mswitch_hp, 2.0) ! dimensionless + call g_tracer_add_param('hp_ipa_smp', cobalt%hp_ipa_smp, 0.0) ! dimensionless + call g_tracer_add_param('hp_ipa_lgp', cobalt%hp_ipa_lgp, 0.0) ! dimensionless + call g_tracer_add_param('hp_ipa_diaz', cobalt%hp_ipa_diaz, 0.0) ! dimensionless + call g_tracer_add_param('hp_ipa_smz', cobalt%hp_ipa_smz, 0.0) ! dimensionless + call g_tracer_add_param('hp_ipa_mdz', cobalt%hp_ipa_mdz, 1.0) ! dimensionless + call g_tracer_add_param('hp_ipa_lgz', cobalt%hp_ipa_lgz, 1.0) ! dimensionless + call g_tracer_add_param('hp_ipa_bact', cobalt%hp_ipa_bact,0.0) ! dimensionless + call g_tracer_add_param('hp_ipa_det', cobalt%hp_ipa_det, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_det', cobalt%hp_phi_det, 0.35) ! dimensionless + call g_tracer_add_param('hp_phi_ldon', cobalt%hp_phi_ldon, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_ldop', cobalt%hp_phi_ldop, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_srdon', cobalt%hp_phi_srdon, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_srdop', cobalt%hp_phi_srdop, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_sldon', cobalt%hp_phi_sldon, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_sldop', cobalt%hp_phi_sldop, 0.0) ! dimensionless + call g_tracer_add_param('hp_phi_nh4', cobalt%hp_phi_nh4, 0.65) ! dimensionless + call g_tracer_add_param('hp_phi_po4', cobalt%hp_phi_po4, 0.65) ! dimensionless + ! + !---------------------------------------------------------------------- + ! Iron chemistry + !---------------------------------------------------------------------- + ! + call g_tracer_add_param('felig_bkg', cobalt%felig_bkg, 1.0e-9) ! mol Fe kg-1 + call g_tracer_add_param('felig_2_don', cobalt%felig_2_don, 0.0e-3 / 40.0 * 106.0 / 16.0) ! mol Fe mol N-1 + call g_tracer_add_param('fe_2_n_sed', cobalt%fe_2_n_sed, 100.0e-5 * 106 / 16) ! mol Fe mol N-1 + call g_tracer_add_param('fe_coast', cobalt%fe_coast,1.0e-11 ) ! mol Fe m kg-1 s-1 + call g_tracer_add_param('alpha_fescav',cobalt%alpha_fescav, 15.0/spery) ! sec-1 + call g_tracer_add_param('beta_fescav',cobalt%beta_fescav, 0.0/spery) ! mol N-1 sec-1 + call g_tracer_add_param('remin_eff_fedet',cobalt%remin_eff_fedet, 0.1) ! unitless + call g_tracer_add_param('ki_fescav',cobalt%ki_fescav, 1.0 ) ! watts m-2 + call g_tracer_add_param('io_fescav',cobalt%io_fescav, 10.0 ) ! watts m-2 + call g_tracer_add_param('gamma_fescav',cobalt%gamma_fescav, 1.0 ) ! watts m-2 + call g_tracer_add_param('kfe_eq_lig_ll',cobalt%kfe_eq_lig_ll, 1.0e12) ! mol lig-1 kg + call g_tracer_add_param('kfe_eq_lig_hl',cobalt%kfe_eq_lig_hl, 1e8) ! mol lig-1 kg + ! + !------------------------------------------------------------------------- + ! Remineralization + !------------------------------------------------------------------------- + ! + call g_tracer_add_param('k_o2', cobalt%k_o2, 20.0e-6) ! mol O2 kg-1 + call g_tracer_add_param('o2_min', cobalt%o2_min, 1.0 * 1.0e-06) ! mol O2 kg-1 + call g_tracer_add_param('rpcaco3', cobalt%rpcaco3, 0.070/12.0*16.0/106.0*100.0) ! mol N mol Ca-1 + call g_tracer_add_param('rplith', cobalt%rplith, 0.065/12.0*16.0/106.0) ! mol N g lith-1 + call g_tracer_add_param('rpsio2', cobalt%rpsio2, 0.026/12.0*16.0/106.0*60.0) ! mol N mol Si-1 + call g_tracer_add_param('gamma_ndet', cobalt%gamma_ndet, cobalt%wsink / 188.0 ) ! s-1 + call g_tracer_add_param('gamma_cadet_arag',cobalt%gamma_cadet_arag,cobalt%wsink/760.0) ! s-1 + call g_tracer_add_param('gamma_cadet_calc',cobalt%gamma_cadet_calc,cobalt%wsink/1343.0) ! s-1 + call g_tracer_add_param('gamma_sidet', cobalt%gamma_sidet, cobalt%wsink / 2000.0 ) ! s-1 + call g_tracer_add_param('phi_lith' , cobalt%phi_lith, 0.002) ! kg mol-1 + call g_tracer_add_param('k_lith', cobalt%k_lith, 1e-6/sperd ) ! s-1 + call g_tracer_add_param('z_sed', cobalt%z_sed, 0.1 ) ! m + call g_tracer_add_param('k_no3_denit',cobalt%k_no3_denit,1.0e-6) ! mol NO3 kg-1 + ! + !----------------------------------------------------------------------- + ! Dissolved Organic Material + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('gamma_srdon', cobalt%gamma_srdon, 1.0 / (18.0 * spery)) ! s-1 + call g_tracer_add_param('gamma_srdop', cobalt%gamma_srdop, 1.0 / (4.0 * spery)) ! s-1 + call g_tracer_add_param('gamma_sldon', cobalt%gamma_sldon, 1.0 / (90 * sperd)) ! s-1 + call g_tracer_add_param('gamma_sldop', cobalt%gamma_sldop, 1.0 / (90 * sperd)) ! s-1 + ! + !----------------------------------------------------------------------- + ! Nitrification + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('gamma_nitrif', cobalt%gamma_nitrif, 1.0 / (30.0 * sperd)) ! s-1 + call g_tracer_add_param('irr_inhibit', cobalt%irr_inhibit, 0.1) ! m2 W-1 + ! + !----------------------------------------------------------------------- + ! Miscellaneous + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('tracer_debug', cobalt%tracer_debug, .false.) + + call g_tracer_end_param_list(package_name) + !=========== + !Block Ends: g_tracer_add_param + !=========== + + 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) + ! + call g_tracer_start_param_list(package_name) + ! + call g_tracer_add_param('htotal_in', cobalt%htotal_in, 1.0e-08) + ! + ! Sinking velocity of detritus: a value of 20 m d-1 is consistent with a characteristic sinking + ! velocity of 100 m d-1 of marine aggregates and a disaggregation rate constant + ! of 5 d-1 in the surface ocean (Clegg and Whitfield, 1992; Dunne, 1999). Alternatively, 100 m d-1 + ! is more in line with the deep water synthesis of Berelson (2002; Particel settling rates increase + ! with depth in the ocean, DSR-II, 49, 237-252). + ! + call g_tracer_add_param('wsink', cobalt%wsink, 100.0 / sperd) ! m s-1 + + call g_tracer_add_param('ice_restart_file' , cobalt%ice_restart_file , 'ice_cobalt.res.nc') + call g_tracer_add_param('ocean_restart_file' , cobalt%ocean_restart_file , 'ocean_cobalt.res.nc' ) + call g_tracer_add_param('IC_file' , cobalt%IC_file , '') + ! + call g_tracer_end_param_list(package_name) + + ! Set Restart files + call g_tracer_set_files(ice_restart_file = cobalt%ice_restart_file,& + ocean_restart_file = cobalt%ocean_restart_file ) + + !All tracer fields shall be registered for diag output. + + !===================================================== + !Specify all prognostic tracers of this modules. + !===================================================== + !User adds one call for each prognostic tracer below! + !User should specify if fluxes must be extracted from boundary + !by passing one or more of the following methods as .true. + !and provide the corresponding parameters array + !methods: flux_gas,flux_runoff,flux_wetdep,flux_drydep + ! + !Pass an init_value arg if the tracers should be initialized to a nonzero value everywhere + !otherwise they will be initialized to zero. + ! + !=========================================================== + !Prognostic Tracers + !=========================================================== + ! + ! + ! ALK (Total carbonate alkalinity) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'alk', & + longname = 'Alkalinity', & + units = 'mol/kg', & + prog = .true., & + flux_runoff= .true., & + flux_param = (/ 1.0e-03 /), & + flux_bottom= .true. ) + ! + ! Aragonite (Sinking detrital/particulate CaCO3) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'cadet_arag', & + longname = 'Detrital CaCO3', & + units = 'mol/kg', & + prog = .true., & + sink_rate = cobalt%wsink, & + btm_reservoir = .true. ) + ! + ! Calcite + ! + call g_tracer_add(tracer_list,package_name,& + name = 'cadet_calc', & + longname = 'Detrital CaCO3', & + units = 'mol/kg', & + prog = .true., & + sink_rate = cobalt%wsink, & + btm_reservoir = .true. ) + ! + ! DIC (Dissolved inorganic carbon) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'dic', & + longname = 'Dissolved Inorganic Carbon', & + units = 'mol/kg', & + prog = .true., & + flux_gas = .true., & + flux_gas_name = 'co2_flux', & + flux_gas_type = 'air_sea_gas_flux_generic', & + flux_gas_molwt = WTMCO2, & + flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), & + flux_gas_restart_file = 'ocean_cobalt_airsea_flux.res.nc', & + flux_runoff= .true., & + flux_param = (/12.011e-03 /), & + flux_bottom= .true., & + init_value = 0.001 ) + ! + ! Dissolved Fe (assumed to be all available to phytoplankton) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'fed', & + longname = 'Dissolved Iron', & + units = 'mol/kg', & + prog = .true., & + flux_runoff= .true., & + flux_wetdep= .true., & + flux_drydep= .true., & + flux_param = (/ 55.847e-03 /), & + flux_bottom= .true. ) + ! + ! Fedet (Sinking detrital/particulate iron) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'fedet', & + longname = 'Detrital Iron', & + units = 'mol/kg', & + prog = .true., & + sink_rate = cobalt%wsink, & + btm_reservoir = .true. ) + ! + ! Diazotroph Fe (Iron in N2-fixing phytoplankton for variable Fe:N ratios) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'fedi', & + longname = 'Diazotroph Iron', & + units = 'mol/kg', & + prog = .true. ) + ! + ! Large Fe (Iron in large phytoplankton to allow for variable Fe:N ratios) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'felg', & + longname = 'Large Phytoplankton Iron', & + units = 'mol/kg', & + prog = .true. ) + ! + ! Small Fe + ! + call g_tracer_add(tracer_list,package_name,& + name = 'fesm', & + longname = 'Small Phytoplankton Iron', & + units = 'mol/kg', & + prog = .true. ) + ! + ! LDON (Labile dissolved organic nitrogen) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'ldon', & + flux_runoff= .true., & + longname = 'labile DON', & + units = 'mol/kg', & + prog = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! LDOP (Labile dissolved organic phosphorous) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'ldop', & + flux_runoff= .true., & + longname = 'labile DOP', & + units = 'mol/kg', & + prog = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! LITH (Lithogenic aluminosilicate particles) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'lith', & + longname = 'Lithogenic Aluminosilicate', & + units = 'g/kg', & + prog = .true., & + flux_runoff= .true., & + flux_wetdep= .true., & + flux_drydep= .true., & + flux_param = (/ 1.0e-03 /) ) + ! + ! LITHdet (Detrital Lithogenic aluminosilicate particles) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'lithdet', & + longname = 'lithdet', & + units = 'g/kg', & + prog = .true., & + sink_rate = cobalt%wsink, & + btm_reservoir = .true. ) + ! + ! NBact: Bacteria nitrogen + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nbact', & + longname = 'bacterial', & + units = 'mol/kg', & + prog = .true. ) + ! + ! Ndet (Sinking detrital/particulate Nitrogen) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'ndet', & + longname = 'ndet', & + flux_runoff= .true., & + units = 'mol/kg', & + prog = .true., & + sink_rate = cobalt%wsink,& + btm_reservoir = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! NDi (assumed to be facultative N2-fixers, with a variable N:P ratio + ! + call g_tracer_add(tracer_list,package_name,& + name = 'ndi', & + longname = 'Diazotroph Nitrogen', & + units = 'mol/kg', & + prog = .true. ) + + ! + ! NLg (assumed to be a dynamic combination of diatoms and other + ! eukaryotes all effectively greater than 5 um in diameter, + ! and having a fixed C:N ratio) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nlg', & + longname = 'Large Phytoplankton Nitrogen', & + units = 'mol/kg', & + prog = .true. ) + ! + ! NSm (Nitrogen in picoplankton and nanoplankton + ! ~less than 5 um in diameter and having a fixed C:N:P ratio) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nsm', & + longname = 'Small Phytoplankton Nitrogen', & + units = 'mol/kg', & + prog = .true. ) + ! + ! NH4 + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nh4', & + longname = 'Ammonia', & + units = 'mol/kg', & + prog = .true., & + flux_wetdep= .true., & + flux_drydep= .true., & + flux_param = (/ 14.0067e-03 /), & + flux_bottom= .true. ) + ! + ! NO3 + ! + call g_tracer_add(tracer_list,package_name,& + name = 'no3', & + longname = 'Nitrate', & + units = 'mol/kg', & + prog = .true., & + flux_runoff= .true., & + flux_wetdep= .true., & + flux_drydep= .true., & + flux_param = (/ 14.0067e-03 /), & + flux_bottom= .true. ) + ! + ! O2 + ! + call g_tracer_add(tracer_list,package_name, & + name = 'o2', & + longname = 'Oxygen', & + units = 'mol/kg', & + prog = .true., & + flux_gas = .true., & + flux_gas_name = 'o2_flux', & + flux_gas_type = 'air_sea_gas_flux_generic', & + flux_gas_molwt = WTMO2, & + flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), & + flux_gas_restart_file = 'ocean_cobalt_airsea_flux.res.nc', & + flux_bottom= .true. ) + ! + ! Pdet (Sinking detrital/particulate Phosphorus) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'pdet', & + longname = 'Detrital Phosphorus', & + units = 'mol/kg', & + prog = .true., & + sink_rate = cobalt%wsink, & + btm_reservoir = .true. ) + ! + ! PO4 + ! + call g_tracer_add(tracer_list,package_name,& + name = 'po4', & + longname = 'Phosphate', & + flux_runoff= .true., & + units = 'mol/kg', & + prog = .true., & + flux_wetdep= .true., & + flux_drydep= .true., & + flux_bottom= .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! SRDON (Semi-Refractory dissolved organic nitrogen) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'srdon', & + longname = 'Semi-Refractory DON', & + flux_runoff= .true., & + units = 'mol/kg', & + prog = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! SRDOP (Semi-Refractory dissolved organic phosphorus) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'srdop', & + longname = 'Semi-Refractory DOP', & + flux_runoff= .true., & + units = 'mol/kg', & + prog = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! SLDON (Semilabile dissolved organic nitrogen) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'sldon', & + longname = 'Semilabile DON', & + flux_runoff= .true., & + units = 'mol/kg', & + prog = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! SLDOP (Semilabile dissolved organic phosphorus) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'sldop', & + longname = 'Semilabile DOP', & + flux_runoff= .true., & + units = 'mol/kg', & + prog = .true., & + flux_param = (/ 1.0e-3 /) ) + ! + ! Sidet (Sinking detrital/particulate Silicon) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'sidet', & + longname = 'Detrital Silicon', & + units = 'mol/kg', & + prog = .true., & + sink_rate = cobalt%wsink, & + btm_reservoir = .true. ) + ! + ! SiLg (Silicon in large phytoplankton for variable Si:N ratios + ! + call g_tracer_add(tracer_list,package_name,& + name = 'silg', & + longname = 'Large Phytoplankton Silicon', & + units = 'mol/kg', & + prog = .true. ) + ! + ! SiO4 + ! + call g_tracer_add(tracer_list,package_name,& + name = 'sio4', & + longname = 'Silicate', & + units = 'mol/kg', & + prog = .true., & + flux_bottom= .true. ) + + ! + ! Small zooplankton N + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nsmz', & + longname = 'Small Zooplankton Nitrogen', & + units = 'mol/kg', & + prog = .true. ) + + ! + ! Medium-sized zooplankton N + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nmdz', & + longname = 'Medium-sized zooplankton Nitrogen', & + units = 'mol/kg', & + prog = .true. ) + + ! + ! Large zooplankton N (Pred zoo + krill) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'nlgz', & + longname = 'large Zooplankton Nitrogen', & + units = 'mol/kg', & + prog = .true. ) + + !=========================================================== + !Diagnostic Tracers + !=========================================================== + ! + ! Cased (CaCO3 in sediments) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'cased', & + longname = 'Sediment CaCO3', & + units = 'mol m-3', & + prog = .false. ) + ! + ! Chl (Chlorophyll) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'chl', & + longname = 'Chlorophyll', & + units = 'ug kg-1', & + prog = .false., & + init_value = 0.08 ) + ! + ! CO3_ion (Carbonate ion) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'co3_ion', & + longname = 'Carbonate ion', & + units = 'mol/kg', & + prog = .false. ) + ! + ! cadet_arag_btf (Aragonite flux to sediments) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'cadet_arag_btf', & + longname = 'aragonite flux to Sediments', & + units = 'mol m-2 s-1', & + prog = .false. ) + ! + ! cadet_calc_btf (Calcite flux to sediments) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'cadet_calc_btf', & + longname = 'calcite flux to Sediments', & + units = 'mol m-2 s-1', & + prog = .false. ) + ! + ! lithdet_btf (Lithogenic flux to sediments) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'lithdet_btf', & + longname = 'Lith flux to Sediments', & + units = 'g m-2 s-1', & + prog = .false. ) + ! + ! ndet_btf (N flux to sediments) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'ndet_btf', & + longname = 'N flux to Sediments', & + units = 'mol m-2 s-1', & + prog = .false. ) + ! + ! pdet_btf (P flux to sediments) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'pdet_btf', & + longname = 'P flux to Sediments', & + units = 'mol m-2 s-1', & + prog = .false. ) + ! + ! sidet_btf (SiO2 flux to sediments) + ! + call g_tracer_add(tracer_list,package_name, & + name = 'sidet_btf', & + longname = 'SiO2 flux to Sediments', & + units = 'mol m-2 s-1', & + prog = .false. ) + ! + ! htotal (H+ ion concentration) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'htotal', & + longname = 'H+ ion concentration', & + units = 'mol/kg', & + prog = .false., & + init_value = cobalt%htotal_in ) + ! + ! Irr_mem (Irradiance Memory) + ! + call g_tracer_add(tracer_list,package_name,& + name = 'irr_mem', & + longname = 'Irradiance memory', & + units = 'Watts/m^2', & + prog = .false. ) + + + end subroutine user_add_tracers + + + ! + ! + ! Modify the values obtained from the coupler if necessary. + ! + ! + ! Some tracer fields need to be modified after values are obtained from the coupler. + ! This subroutine is the place for specific tracer manipulations. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + subroutine generic_COBALT_update_from_coupler(tracer_list) + type(g_tracer_type), pointer :: tracer_list + + character(len=fm_string_len), parameter :: sub_name = 'generic_COBALT_update_from_copler' + + real, dimension(:,:) ,pointer :: stf_alk,dry_no3,wet_no3 + + ! + ! NO3 has deposition, river flux, and negative deposition contribution to alkalinity + ! + call g_tracer_get_pointer(tracer_list,'no3','drydep',dry_no3) + call g_tracer_get_pointer(tracer_list,'no3','wetdep',wet_no3) + + call g_tracer_get_pointer(tracer_list,'alk','stf',stf_alk) + + stf_alk = stf_alk - dry_no3 - wet_no3 ! update 'tracer%stf' thru pointer + + return + end subroutine generic_COBALT_update_from_coupler + + ! + ! + ! + ! Set values of bottom fluxes and reservoirs + ! + ! + ! + ! + ! This routine calculates bottom fluxes for tracers with bottom reservoirs. + ! It is called near the end of the time step, meaning that the fluxes + ! calculated pertain to the next time step. + ! + ! + ! + ! + ! + ! + ! + ! + ! Time step increment + ! + ! + ! Time step index to be used for %field + ! + ! + ! + subroutine generic_COBALT_update_from_bottom(tracer_list, dt, tau, model_time) + type(g_tracer_type), pointer :: tracer_list + real, intent(in) :: dt + integer, intent(in) :: tau + type(time_type), intent(in) :: model_time + integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau + logical :: used + real, dimension(:,:,:),pointer :: grid_tmask + real, dimension(:,:,:),pointer :: temp_field + + call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask) + + ! + ! The bottom reservoirs of aragonite and calcite are immediately redistributed to the + ! water column as a bottom flux (btf) where they impact the alkalinity and DIC + ! + call g_tracer_get_values(tracer_list,'cadet_arag','btm_reservoir',cobalt%fcadet_arag_btm,isd,jsd) + cobalt%fcadet_arag_btm = cobalt%fcadet_arag_btm/dt + call g_tracer_get_pointer(tracer_list,'cadet_arag_btf','field',temp_field) + temp_field(:,:,1) = cobalt%fcadet_arag_btm(:,:) + call g_tracer_set_values(tracer_list,'cadet_arag','btm_reservoir',0.0) + if (cobalt%id_fcadet_arag_btm .gt. 0) & + used = send_data(cobalt%id_fcadet_arag_btm,cobalt%fcadet_arag_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + + call g_tracer_get_values(tracer_list,'cadet_calc','btm_reservoir',cobalt%fcadet_calc_btm,isd,jsd) + cobalt%fcadet_calc_btm = cobalt%fcadet_calc_btm/dt + call g_tracer_get_pointer(tracer_list,'cadet_calc_btf','field',temp_field) + temp_field(:,:,1) = cobalt%fcadet_calc_btm(:,:) + call g_tracer_set_values(tracer_list,'cadet_calc','btm_reservoir',0.0) + if (cobalt%id_fcadet_calc_btm .gt. 0) & + used = send_data(cobalt%id_fcadet_calc_btm, cobalt%fcadet_calc_btm, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + ! + ! Iron is buried, but can re-enter the water column in association with + ! organic matter degradation (see ffe_sed in update_from_source) + ! + call g_tracer_get_values(tracer_list,'fedet','btm_reservoir',cobalt%ffedet_btm,isd,jsd) + cobalt%ffedet_btm = cobalt%ffedet_btm/dt + call g_tracer_set_values(tracer_list,'fedet','btm_reservoir',0.0) + if (cobalt%id_ffedet_btm .gt. 0) & + used = send_data(cobalt%id_ffedet_btm, cobalt%ffedet_btm, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + ! + ! Lithogenic material is buried + ! + call g_tracer_get_values(tracer_list,'lithdet','btm_reservoir',cobalt%flithdet_btm,isd,jsd) + cobalt%flithdet_btm = cobalt%flithdet_btm /dt + call g_tracer_get_pointer(tracer_list,'lithdet_btf','field',temp_field) + temp_field(:,:,1) = cobalt%flithdet_btm(:,:) + call g_tracer_set_values(tracer_list,'lithdet','btm_reservoir',0.0) + if (cobalt%id_flithdet_btm .gt. 0) & + used = send_data(cobalt%id_flithdet_btm, cobalt%flithdet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + ! + ! N, P, and Si detritus that hits the bottom is re-entered as a bottom source of + ! nh4, po4, and SiO4 respectively + ! + call g_tracer_get_values(tracer_list,'ndet','btm_reservoir',cobalt%fndet_btm,isd,jsd) + cobalt%fndet_btm = cobalt%fndet_btm/dt + call g_tracer_get_pointer(tracer_list,'ndet_btf','field',temp_field) + temp_field(:,:,1) = cobalt%fndet_btm(:,:) + call g_tracer_set_values(tracer_list,'ndet','btm_reservoir',0.0) + if (cobalt%id_fndet_btm .gt. 0) & + used = send_data(cobalt%id_fndet_btm,cobalt%fndet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + + call g_tracer_get_values(tracer_list,'pdet','btm_reservoir',cobalt%fpdet_btm,isd,jsd) + cobalt%fpdet_btm = cobalt%fpdet_btm/dt + call g_tracer_get_pointer(tracer_list,'pdet_btf','field',temp_field) + temp_field(:,:,1) = cobalt%fpdet_btm(:,:) + call g_tracer_set_values(tracer_list,'pdet','btm_reservoir',0.0) + if (cobalt%id_fpdet_btm .gt. 0) & + used = send_data(cobalt%id_fpdet_btm,cobalt%fpdet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + + call g_tracer_get_values(tracer_list,'sidet','btm_reservoir',cobalt%fsidet_btm,isd,jsd) + cobalt%fsidet_btm = cobalt%fsidet_btm/dt + call g_tracer_get_pointer(tracer_list,'sidet_btf','field',temp_field) + temp_field(:,:,1) = cobalt%fsidet_btm(:,:) + call g_tracer_set_values(tracer_list,'sidet','btm_reservoir',0.0) + if (cobalt%id_fsidet_btm .gt. 0) & + used = send_data(cobalt%id_fsidet_btm, cobalt%fsidet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + + end subroutine generic_COBALT_update_from_bottom + + ! + ! + ! Update tracer concentration fields due to the source/sink contributions. + ! + ! + ! This is the subroutine to contain most of the biogeochemistry for calculating the + ! interaction of tracers with each other and with outside forcings. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + ! Lower bounds of x and y extents of input arrays on data domain + ! + ! + ! Ocean temperature + ! + ! + ! Ocean salinity + ! + ! + ! Ocean layer thickness (meters) + ! + ! + ! Ocean opacity + ! + ! + ! Shortwave peneteration + ! + ! + ! + ! + ! + ! Grid area + ! + ! + ! Time step index of %field + ! + ! + ! Time step increment + ! + ! + subroutine generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hblt_depth,& + ilb,jlb,tau,dt,grid_dat,model_time,nbands,max_wavelength_band,sw_pen_band,opacity_band) + + type(g_tracer_type), pointer :: tracer_list + real, dimension(ilb:,jlb:,:), intent(in) :: Temp,Salt,rho_dzt,dzt + real, dimension(ilb:,jlb:), intent(in) :: hblt_depth + integer, intent(in) :: ilb,jlb,tau + real, intent(in) :: dt + real, dimension(ilb:,jlb:), intent(in) :: grid_dat + type(time_type), intent(in) :: model_time + + integer, intent(in) :: nbands + real, dimension(:), intent(in) :: max_wavelength_band + real, dimension(:,ilb:,jlb:), intent(in) :: sw_pen_band + real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band + + character(len=fm_string_len), parameter :: sub_name = 'generic_COBALT_update_from_source' + integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau, i, j, k , kblt, m, n, k_100, k_200 + real, dimension(:,:,:) ,pointer :: grid_tmask + integer, dimension(:,:),pointer :: mask_coast,grid_kmt + ! + !------------------------------------------------------------------------ + ! Local Variables + !------------------------------------------------------------------------ + ! + logical :: used, first + integer :: nb + real :: r_dt + real :: feprime + real :: juptake_di_tot2nterm + real :: log_btm_flx + real :: P_C_m + real :: p_lim_nhet + real :: TK, PRESS, PKSPA, PKSPC + real :: tmp_hblt, tmp_irrad, tmp_irrad_ML,tmp_opacity + real :: drho_dzt + real, dimension(:), Allocatable :: tmp_irr_band + real, dimension(:,:), Allocatable :: rho_dzt_100, rho_dzt_200 + real,dimension(1:NUM_ZOO,1:NUM_PREY) :: ipa_matrix,pa_matrix,ingest_matrix + real,dimension(1:NUM_PREY) :: hp_ipa_vec,hp_pa_vec,hp_ingest_vec + real,dimension(1:NUM_PREY) :: prey_vec,prey_p2n_vec,prey_fe2n_vec,prey_si2n_vec + real,dimension(1:NUM_ZOO) :: tot_prey + real :: tot_prey_hp, sw_fac_denom, ingest_p2n, refuge_conc + real :: bact_ldon_lim, bact_uptake_ratio, vmax_bact + real :: fpoc_btm, log_fpoc_btm + + r_dt = 1.0 / dt + + call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,& + grid_tmask=grid_tmask,grid_mask_coast=mask_coast,grid_kmt=grid_kmt) + + call mpp_clock_begin(id_clock_carbon_calculations) + !Get necessary fields + call g_tracer_get_values(tracer_list,'htotal','field', cobalt%f_htotal,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'po4' ,'field', cobalt%f_po4,isd,jsd,ntau=tau) + call g_tracer_get_values(tracer_list,'sio4' ,'field', cobalt%f_sio4,isd,jsd,ntau=tau) + call g_tracer_get_values(tracer_list,'alk' ,'field', cobalt%f_alk,isd,jsd,ntau=tau) + call g_tracer_get_values(tracer_list,'dic' ,'field', cobalt%f_dic ,isd,jsd,ntau=tau) + + !--------------------------------------------------------------------- + !Calculate co3_ion + !Also calculate co2 fluxes csurf and alpha for the next round of exchnage + !--------------------------------------------------------------------- + + k=1 + do j = jsc, jec ; do i = isc, iec !{ + cobalt%htotallo(i,j) = cobalt%htotal_scale_lo * cobalt%f_htotal(i,j,k) + cobalt%htotalhi(i,j) = cobalt%htotal_scale_hi * cobalt%f_htotal(i,j,k) + enddo; enddo ; !} i, j + + call FMS_ocmip2_co2calc(CO2_dope_vec,grid_tmask(:,:,k),& + Temp(:,:,k), Salt(:,:,k), & + cobalt%f_dic(:,:,k), & + cobalt%f_po4(:,:,k), & + cobalt%f_sio4(:,:,k), & + cobalt%f_alk(:,:,k), & + cobalt%htotallo, cobalt%htotalhi,& + !InOut + cobalt%f_htotal(:,:,k), & + !OUT + co2star=cobalt%co2_csurf(:,:), alpha=cobalt%co2_alpha(:,:), & + pCO2surf=cobalt%pco2_csurf(:,:), & + co3_ion=cobalt%f_co3_ion(:,:,k)) + + do k = 2, nk + do j = jsc, jec ; do i = isc, iec !{ + cobalt%htotallo(i,j) = cobalt%htotal_scale_lo * cobalt%f_htotal(i,j,k) + cobalt%htotalhi(i,j) = cobalt%htotal_scale_hi * cobalt%f_htotal(i,j,k) + enddo; enddo ; !} i, j + + call FMS_ocmip2_co2calc(CO2_dope_vec,grid_tmask(:,:,k),& + Temp(:,:,k), Salt(:,:,k), & + cobalt%f_dic(:,:,k), & + cobalt%f_po4(:,:,k), & + cobalt%f_sio4(:,:,k), & + cobalt%f_alk(:,:,k), & + cobalt%htotallo, cobalt%htotalhi,& + !InOut + cobalt%f_htotal(:,:,k), & + !OUT + co3_ion=cobalt%f_co3_ion(:,:,k)) + enddo + + call g_tracer_set_values(tracer_list,'htotal','field',cobalt%f_htotal ,isd,jsd,ntau=1) + call g_tracer_set_values(tracer_list,'co3_ion','field',cobalt%f_co3_ion ,isd,jsd,ntau=1) + call g_tracer_set_values(tracer_list,'dic','alpha',cobalt%co2_alpha ,isd,jsd) + call g_tracer_set_values(tracer_list,'dic','csurf',cobalt%co2_csurf ,isd,jsd) + + call mpp_clock_end(id_clock_carbon_calculations) + + + !--------------------------------------------------------------------- + ! Get positive tracer concentrations + !--------------------------------------------------------------------- + + call mpp_clock_begin(id_clock_phyto_growth) + + call g_tracer_get_values(tracer_list,'cadet_arag','field',cobalt%f_cadet_arag ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'cadet_calc','field',cobalt%f_cadet_calc ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'fed' ,'field',cobalt%f_fed ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'fedet' ,'field',cobalt%f_fedet ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'ldon' ,'field',cobalt%f_ldon ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'ldop' ,'field',cobalt%f_ldop ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'lith' ,'field',cobalt%f_lith ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'lithdet','field',cobalt%f_lithdet ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'ndet' ,'field',cobalt%f_ndet ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'nh4' ,'field',cobalt%f_nh4 ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'no3' ,'field',cobalt%f_no3 ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'o2' ,'field',cobalt%f_o2 ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'pdet' ,'field',cobalt%f_pdet ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'po4' ,'field',cobalt%f_po4 ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'srdon' ,'field',cobalt%f_srdon ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'srdop' ,'field',cobalt%f_srdop ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'sldon' ,'field',cobalt%f_sldon ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'sldop' ,'field',cobalt%f_sldop ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'sidet' ,'field',cobalt%f_sidet ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'sio4' ,'field',cobalt%f_sio4 ,isd,jsd,ntau=tau,positive=.true.) + ! + ! phytoplankton fields + ! + call g_tracer_get_values(tracer_list,'fedi' ,'field',phyto(DIAZO)%f_fe(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'felg' ,'field',phyto(LARGE)%f_fe(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'fesm','field',phyto(SMALL)%f_fe(:,:,:),isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'ndi' ,'field',phyto(DIAZO)%f_n(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'nlg' ,'field',phyto(LARGE)%f_n(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'nsm' ,'field',phyto(SMALL)%f_n(:,:,:),isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'silg' ,'field',cobalt%f_silg ,isd,jsd,ntau=tau,positive=.true.) + ! + ! zooplankton fields + ! + call g_tracer_get_values(tracer_list,'nsmz' ,'field',zoo(1)%f_n(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'nmdz' ,'field',zoo(2)%f_n(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + call g_tracer_get_values(tracer_list,'nlgz' ,'field',zoo(3)%f_n(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + ! + ! bacteria + ! + call g_tracer_get_values(tracer_list,'nbact' ,'field',bact(1)%f_n(:,:,:) ,isd,jsd,ntau=tau,positive=.true.) + ! + ! diagnostic tracers that are passed between time steps (except chlorophyll) + ! + call g_tracer_get_values(tracer_list,'cased' ,'field',cobalt%f_cased ,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'co3_ion','field',cobalt%f_co3_ion ,isd,jsd,ntau=1,positive=.true.) + call g_tracer_get_values(tracer_list,'cadet_arag_btf','field',cobalt%f_cadet_arag_btf,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'cadet_calc_btf','field',cobalt%f_cadet_calc_btf,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'lithdet_btf','field',cobalt%f_lithdet_btf,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'ndet_btf','field',cobalt%f_ndet_btf,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'pdet_btf','field',cobalt%f_pdet_btf,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'sidet_btf','field',cobalt%f_sidet_btf,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'irr_mem','field',cobalt%f_irr_mem ,isd,jsd,ntau=1) + + cobalt%zt = 0.0 + cobalt%zm = 0.0 + ! minimum concentration below which predation/basal respiration stops + refuge_conc = 1.0e-9 + + +! +!----------------------------------------------------------------------------------- +! 1: Phytoplankton growth and nutrient uptake calculations +!----------------------------------------------------------------------------------- +! + ! + !----------------------------------------------------------------------------------- + ! 1.1: Nutrient Limitation Calculations + !----------------------------------------------------------------------------------- + ! + ! Calculate iron cell quota + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec + do n = 1,NUM_PHYTO !{ + phyto(n)%q_fe_2_n(i,j,k) = max(0.0, phyto(n)%f_fe(i,j,k)/ & + max(epsln,phyto(n)%f_n(i,j,k))) + phyto(n)%q_p_2_n(i,j,k) = phyto(n)%p_2_n_static + enddo !} n + ! + ! N limitation with NH4 inhibition after Frost and Franzen (1992) + ! + do n= 2, NUM_PHYTO !{ + phyto(n)%no3lim(i,j,k) = cobalt%f_no3(i,j,k) / & + ( (phyto(n)%k_no3+cobalt%f_no3(i,j,k)) * (1.0 + cobalt%f_nh4(i,j,k)/phyto(n)%k_nh4) ) + phyto(n)%nh4lim(i,j,k) = cobalt%f_nh4(i,j,k) / (phyto(n)%k_nh4 + cobalt%f_nh4(i,j,k)) + enddo !} n + ! + ! O2 inhibition term for diazotrophs + ! + n = DIAZO + phyto(n)%o2lim(i,j,k) = (1.0 - cobalt%f_o2(i,j,k)**cobalt%o2_inhib_Di_pow / & + (cobalt%f_o2(i,j,k)**cobalt%o2_inhib_Di_pow+cobalt%o2_inhib_Di_sat**cobalt%o2_inhib_Di_pow)) + ! + ! SiO4, PO4 and Fe uptake limitation with Michaelis-Mentin + ! + phyto(LARGE)%silim(i,j,k) = cobalt%f_sio4(i,j,k) / (phyto(LARGE)%k_sio4 + cobalt%f_sio4(i,j,k)) + do n= 1, NUM_PHYTO !{ + phyto(n)%po4lim(i,j,k) = cobalt%f_po4(i,j,k) / (phyto(n)%k_po4 + cobalt%f_po4(i,j,k)) + phyto(n)%felim(i,j,k) = cobalt%f_fed(i,j,k) / (phyto(n)%k_fed + cobalt%f_fed(i,j,k)) + phyto(n)%def_fe(i,j,k) = phyto(n)%q_fe_2_n(i,j,k)**2.0 / (phyto(n)%k_fe_2_n**2.0 + & + phyto(n)%q_fe_2_n(i,j,k)**2.0) + enddo !} n + enddo; enddo ; enddo !} i,j,k + ! + ! Calculate nutrient limitation based on the most limiting nutrient (liebig_lim) + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + n=DIAZO + phyto(n)%liebig_lim(i,j,k) = phyto(n)%o2lim(i,j,k)* & + min(phyto(n)%po4lim(i,j,k), phyto(n)%def_fe(i,j,k)) + do n= 2, NUM_PHYTO !{ + phyto(n)%liebig_lim(i,j,k) = min(phyto(n)%no3lim(i,j,k)+phyto(n)%nh4lim(i,j,k),& + phyto(n)%po4lim(i,j,k), phyto(n)%def_fe(i,j,k)) + enddo !} n + enddo; enddo ; enddo !} i,j,k + ! + !----------------------------------------------------------------------- + ! 1.2: Light Limitation/Growth Calculations + !----------------------------------------------------------------------- + ! + ! Create relevant light fields based on incident radiation and opacity + ! information passed from the ocean code + ! + allocate(tmp_irr_band(nbands)) + do j = jsc, jec ; do i = isc, iec !{ + + do nb=1,nbands !{ + if (max_wavelength_band(nb) .lt. 710.0) then !{ + tmp_irr_band(nb) = sw_pen_band(nb,i,j) + else + tmp_irr_band(nb) = 0.0 + endif !} + enddo !} + + kblt = 0 ; tmp_irrad_ML = 0.0 ; tmp_hblt = 0.0 + do k = 1, nk !{ + tmp_irrad = 0.0 + do nb=1,nbands !{ + tmp_opacity = opacity_band(nb,i,j,k) + tmp_irrad = tmp_irrad + max(0.0,tmp_irr_band(nb) * exp(-tmp_opacity * dzt(i,j,k) * 0.5)) + ! Change tmp_irr_band from being the value atop layer k to the value + ! at the bottom of layer k. + tmp_irr_band(nb) = tmp_irr_band(nb) * exp(-tmp_opacity * dzt(i,j,k)) + enddo !} + cobalt%irr_inst(i,j,k) = tmp_irrad * grid_tmask(i,j,k) + cobalt%irr_mix(i,j,k) = tmp_irrad * grid_tmask(i,j,k) + if ((k == 1) .or. (tmp_hblt .lt. hblt_depth(i,j))) then !{ + kblt = kblt+1 + tmp_irrad_ML = tmp_irrad_ML + cobalt%irr_mix(i,j,k) * dzt(i,j,k) + tmp_hblt = tmp_hblt + dzt(i,j,k) + endif !} + enddo !} k-loop + cobalt%irr_mix(i,j,1:kblt) = tmp_irrad_ML / max(1.0e-6,tmp_hblt) + enddo; enddo !} i,j + + deallocate(tmp_irr_band) + ! + ! Calculate the temperature limitation (expkT) and the time integrated + ! irradiance (f_irr_mem) to which the Chl:C ratio responds (~24 hours) + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%expkT(i,j,k) = exp(cobalt%kappa_eppley * Temp(i,j,k)) + cobalt%f_irr_mem(i,j,k) = (cobalt%f_irr_mem(i,j,k) + (cobalt%irr_mix(i,j,k) - & + cobalt%f_irr_mem(i,j,k)) * min(1.0,cobalt%gamma_irr_mem * dt)) * grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + ! + ! Phytoplankton growth rate calculation based on Geider et al. (1997) + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%gross_prim_prod(i,j,k) = 0.0 + cobalt%f_chl(i,j,k) = 0.0 + + do n = 1, NUM_PHYTO !{ + P_C_m = phyto(n)%liebig_lim(i,j,k)*phyto(n)%P_C_max*cobalt%expkT(i,j,k)+epsln + phyto(n)%theta(i,j,k) = (phyto(n)%thetamax-cobalt%thetamin) / (1.0 + & + phyto(n)%thetamax*phyto(n)%alpha*cobalt%f_irr_mem(i,j,k)*0.5 / & + P_C_m) + cobalt%thetamin + cobalt%f_chl(i,j,k) = cobalt%f_chl(i,j,k)+cobalt%c_2_n*12.0e6*phyto(n)%theta(i,j,k)* & + phyto(n)%f_n(i,j,k) + phyto(n)%irrlim(i,j,k) = (1.0-exp(-phyto(n)%alpha*cobalt%irr_inst(i,j,k)* & + phyto(n)%theta(i,j,k)/P_C_m)) + + ! calculate the growth rate + phyto(n)%mu(i,j,k) = P_C_m / (1.0 + cobalt%zeta) * phyto(n)%irrlim(i,j,k) - & + cobalt%expkT(i,j,k)*phyto(n)%bresp* & + phyto(n)%f_n(i,j,k)/(refuge_conc + phyto(n)%f_n(i,j,k)) + + cobalt%gross_prim_prod(i,j,k) = cobalt%gross_prim_prod(i,j,k) + P_C_m*phyto(n)%irrlim(i,j,k)* & + phyto(n)%f_n(i,j,k) + ! Negative growth assumed to go to cell death rather than respiration (see manual) + cobalt%net_prim_prod(i,j,k) = max(phyto(n)%mu(i,j,k),0.0)*phyto(n)%f_n(i,j,k) + enddo !} n + + cobalt%gross_prim_prod(i,j,k) = cobalt%gross_prim_prod(i,j,k)*cobalt%c_2_n*spery + cobalt%net_prim_prod(i,j,k) = cobalt%net_prim_prod(i,j,k)*cobalt%c_2_n*spery + enddo; enddo ; enddo !} i,j,k + ! + !----------------------------------------------------------------------- + ! 1.3: Nutrient uptake calculations + !----------------------------------------------------------------------- + ! + ! Uptake of nitrate and ammonia + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + n = DIAZO + !juptake_di_tot2nterm=max(0.0,phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)* & + ! (1.0/(cobalt%f_no3(i,j,k)+cobalt%f_nh4(i,j,k)+cobalt%k_n_inhib_Di))) + phyto(n)%juptake_n2(i,j,k) = max(0.0,(1.0 - phyto(LARGE)%no3lim(i,j,k) - phyto(LARGE)%nh4lim(i,j,k))* & + phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)) + phyto(n)%juptake_nh4(i,j,k) = max(0.0,phyto(LARGE)%nh4lim(i,j,k)* phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)) + phyto(n)%juptake_no3(i,j,k) = max(0.0,phyto(LARGE)%no3lim(i,j,k)* phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)) + ! If growth is negative, net remineralization of organic material + phyto(n)%juptake_nh4(i,j,k) = phyto(n)%juptake_nh4(i,j,k) + & + min(0.0,phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)) + phyto(n)%jprod_n(i,j,k) = phyto(n)%juptake_nh4(i,j,k) + phyto(n)%juptake_no3(i,j,k) + & + phyto(n)%juptake_n2(i,j,k) + do n = 2, NUM_PHYTO !{ + phyto(n)%juptake_no3(i,j,k) = max( 0.0, phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)* & + phyto(n)%no3lim(i,j,k)/(phyto(n)%no3lim(i,j,k)+phyto(n)%nh4lim(i,j,k)+epsln) ) + phyto(n)%juptake_nh4(i,j,k) = max( 0.0, phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)* & + phyto(n)%nh4lim(i,j,k)/(phyto(n)%no3lim(i,j,k)+phyto(n)%nh4lim(i,j,k)+epsln) ) + ! If growth is negative, net remineralization of organic material + phyto(n)%juptake_nh4(i,j,k) = phyto(n)%juptake_nh4(i,j,k) + & + min(0.0,phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)) + phyto(n)%jprod_n(i,j,k) = phyto(n)%juptake_nh4(i,j,k) + phyto(n)%juptake_no3(i,j,k) + enddo !} n + enddo; enddo ; enddo !} i,j,k + ! + ! Phosphorous uptake + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + n=DIAZO + phyto(n)%juptake_po4(i,j,k) = (phyto(n)%juptake_n2(i,j,k)+phyto(n)%juptake_nh4(i,j,k) + & + phyto(n)%juptake_no3(i,j,k))*phyto(n)%p_2_n_static + do n = 2, NUM_PHYTO + phyto(n)%juptake_po4(i,j,k) = (phyto(n)%juptake_no3(i,j,k)+ & + phyto(n)%juptake_nh4(i,j,k)) * phyto(n)%p_2_n_static + enddo !} n + enddo; enddo ; enddo !} i,j,k + ! + ! Iron uptake + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + do n = 1, NUM_PHYTO !{ + if (phyto(n)%q_fe_2_n(i,j,k).lt.phyto(n)%fe_2_n_max) then + phyto(n)%juptake_fe(i,j,k) = phyto(n)%P_C_max*cobalt%expkT(i,j,k)*phyto(n)%f_n(i,j,k)* & + phyto(n)%felim(i,j,k)*cobalt%fe_2_n_upt_fac + else + phyto(n)%juptake_fe(i,j,k) = 0.0 + endif + enddo !} n + enddo; enddo ; enddo !} i,j,k + ! + ! Silicate uptake + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%nlg_diatoms(i,j,k)=phyto(LARGE)%f_n(i,j,k)*phyto(LARGE)%silim(i,j,k) + cobalt%q_si_2_n_lg_diatoms(i,j,k)= cobalt%f_silg(i,j,k)/ & + (cobalt%nlg_diatoms(i,j,k) + epsln) + phyto(LARGE)%juptake_sio4(i,j,k) = & + max(phyto(LARGE)%juptake_no3(i,j,k)+phyto(LARGE)%juptake_nh4(i,j,k),0.0)*phyto(LARGE)%silim(i,j,k)* & + phyto(LARGE)%silim(i,j,k)*phyto(LARGE)%si_2_n_max + + ! CAS: set q_si_2_n values for each of the phyto groups for consumption calculations + ! Note that this is si_2_n in large phytoplankton pool, not in diatoms themselves + phyto(LARGE)%q_si_2_n(i,j,k) = cobalt%f_silg(i,j,k)/(phyto(LARGE)%f_n(i,j,k)+epsln) + + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_phyto_growth) +! +!----------------------------------------------------------------------- +! 2: Bacterial Growth and Uptake Calculations +!----------------------------------------------------------------------- +! + ! + ! calculate an effective maximum ldon uptake rate (at 0 deg. C) for bacteria + ! from specified values of bact(1)%gge_max, bact(1)%mu_max and bact(1)%bresp + ! + + call mpp_clock_begin(id_clock_bacteria_growth) + vmax_bact = (1/bact(1)%gge_max)*(bact(1)%mu_max + bact(1)%bresp) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + bact(1)%temp_lim(i,j,k) = exp(bact(1)%ktemp*Temp(i,j,k)) + bact_ldon_lim = cobalt%f_ldon(i,j,k)/(bact(1)%k_ldon + cobalt%f_ldon(i,j,k)) + bact(1)%juptake_ldon(i,j,k) = vmax_bact*bact(1)%temp_lim(i,j,k)*bact_ldon_lim* & + bact(1)%f_n(i,j,k) + bact_uptake_ratio = ( cobalt%f_ldop(i,j,k)/max(cobalt%f_ldon(i,j,k),epsln) ) + bact(1)%juptake_ldop(i,j,k) = bact(1)%juptake_ldon(i,j,k)*bact_uptake_ratio + if (bact_uptake_ratio.lt.bact(1)%q_p_2_n) then + bact(1)%jprod_n(i,j,k) = bact(1)%gge_max*bact(1)%juptake_ldop(i,j,k)*16.0 - & + bact(1)%f_n(i,j,k)/(refuge_conc + bact(1)%f_n(i,j,k)) * & + bact(1)%temp_lim(i,j,k)*bact(1)%bresp*bact(1)%f_n(i,j,k) + else + bact(1)%jprod_n(i,j,k) = bact(1)%gge_max*bact(1)%juptake_ldon(i,j,k) - & + bact(1)%f_n(i,j,k)/(refuge_conc + bact(1)%f_n(i,j,k)) * & + bact(1)%temp_lim(i,j,k)*bact(1)%bresp*bact(1)%f_n(i,j,k) + endif + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_bacteria_growth) +! +!----------------------------------------------------------------------- +! 3: Plankton foodweb dynamics +!----------------------------------------------------------------------- +! + ! + ! 3.1 Plankton foodweb dynamics: consumption by zooplankton and higher predators + ! + + call mpp_clock_begin(id_clock_zooplankton_calculations) + + ! + ! Set-up local matrices for calculating zooplankton ingestion of + ! multiple prey types. The rows are consumers (i.e., NUM_ZOO zooplankton + ! groups), the columns are food sources (i.e., NUM_PREY potential food sources) + ! + ! ipa_matrix = the innate prey availability matrix + ! pa_matrix = prey availability matrix after accounting for switching + ! ingest_matrix = ingestion matrix + ! tot_prey = total prey available to predator m + ! + ! The definition of predator-prey matrices is intended to allow for + ! efficient experimentation with predator-prey interconnections. + ! However, we are still working to reduce the runtime required to + ! include this feature. The matrix structures are thus included, + ! but the standard COBALT interactions have been hard-coded such + ! that changing linkages requires changing the prey availability + ! values and adding additional code to handle the new linkages. + ! + ! With regard to stoichiometry, the primary ingestion calculations + ! (i.e., those within the i, j, k loops) are coded to allow for + ! variable stoichiometry. Several sections of the code corresponding + ! to predator-prey and other linkages not in included in the + ! default COBALT parameterizations have been commented out to + ! avoid unnecessary calculations. + ! + + do m = 1,NUM_ZOO !{ + ipa_matrix(m,1) = zoo(m)%ipa_diaz + ipa_matrix(m,2) = zoo(m)%ipa_lgp + ipa_matrix(m,3) = zoo(m)%ipa_smp + ipa_matrix(m,4) = zoo(m)%ipa_bact + ipa_matrix(m,5) = zoo(m)%ipa_smz + ipa_matrix(m,6) = zoo(m)%ipa_mdz + ipa_matrix(m,7) = zoo(m)%ipa_lgz + ipa_matrix(m,8) = zoo(m)%ipa_det + tot_prey(m) = 0.0 + do n = 1,NUM_PREY !{ + pa_matrix(m,n) = 0.0 + ingest_matrix(m,n) = 0.0 + enddo !} n + enddo !} m + + ! + ! Set-up local matrices for calculating higher predator ingestion + ! of multiple prey types + ! + + hp_ipa_vec(1) = cobalt%hp_ipa_diaz + hp_ipa_vec(2) = cobalt%hp_ipa_lgp + hp_ipa_vec(3) = cobalt%hp_ipa_smp + hp_ipa_vec(4) = cobalt%hp_ipa_bact + hp_ipa_vec(5) = cobalt%hp_ipa_smz + hp_ipa_vec(6) = cobalt%hp_ipa_mdz + hp_ipa_vec(7) = cobalt%hp_ipa_lgz + hp_ipa_vec(8) = cobalt%hp_ipa_det + tot_prey_hp = 0.0 + do n = 1,NUM_PREY !{ + hp_pa_vec(n) = 0.0 + hp_ingest_vec(n) = 0.0 + enddo !} n + + ! + ! Set all static stoichiometric ratios outside k,j,i loop + ! + + prey_p2n_vec(1) = phyto(DIAZO)%p_2_n_static + prey_p2n_vec(2) = phyto(LARGE)%p_2_n_static + prey_p2n_vec(3) = phyto(SMALL)%p_2_n_static + prey_p2n_vec(4) = bact(1)%q_p_2_n + prey_p2n_vec(5) = zoo(1)%q_p_2_n + prey_p2n_vec(6) = zoo(2)%q_p_2_n + prey_p2n_vec(7) = zoo(3)%q_p_2_n + + prey_fe2n_vec(4) = 0.0 + prey_fe2n_vec(5) = 0.0 + prey_fe2n_vec(6) = 0.0 + prey_fe2n_vec(7) = 0.0 + + prey_si2n_vec(1) = 0.0 + prey_si2n_vec(3) = 0.0 + prey_si2n_vec(4) = 0.0 + prey_si2n_vec(5) = 0.0 + prey_si2n_vec(6) = 0.0 + prey_si2n_vec(7) = 0.0 + + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec; !{ + + ! + ! 3.1.1: Calculate zooplankton ingestion fluxes + ! + + ! Prey vectors for ingestion and loss calculations + ! (note: ordering of phytoplankton must be consistent with + ! DIAZO, LARGE, SMALL ordering inherited from TOPAZ) + ! + prey_vec(1) = max(phyto(DIAZO)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(2) = max(phyto(LARGE)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(3) = max(phyto(SMALL)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(4) = max(bact(1)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(5) = max(zoo(1)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(6) = max(zoo(2)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(7) = max(zoo(3)%f_n(i,j,k) - refuge_conc,0.0) + prey_vec(8) = max(cobalt%f_ndet(i,j,k) - refuge_conc,0.0) + ! + ! Set dynamic stoichiometric rations inside k,j,i loop + prey_p2n_vec(8) = cobalt%f_pdet(i,j,k)/(cobalt%f_ndet(i,j,k)+epsln) + prey_fe2n_vec(1) = phyto(DIAZO)%q_fe_2_n(i,j,k) + prey_fe2n_vec(2) = phyto(LARGE)%q_fe_2_n(i,j,k) + prey_fe2n_vec(3) = phyto(SMALL)%q_fe_2_n(i,j,k) + prey_fe2n_vec(8) = cobalt%f_fedet(i,j,k)/(cobalt%f_ndet(i,j,k)+epsln) + prey_si2n_vec(2) = phyto(LARGE)%q_si_2_n(i,j,k) + prey_si2n_vec(8) = cobalt%f_sidet(i,j,k)/(cobalt%f_ndet(i,j,k)+epsln) + + ! + ! Calculate zooplankton ingestion + ! + ! Small zooplankton (m = 1) consuming small phytoplankton (3) and + ! bacteria (4). sw_fac_denom is the denominator of the abundance- + ! based switching factor, tot_prey is the total available prey + ! after accounting for switching. + ! + + m = 1 + zoo(m)%temp_lim(i,j,k) = exp(zoo(m)%ktemp*Temp(i,j,k)) + sw_fac_denom = (ipa_matrix(m,3)*prey_vec(3))**zoo(m)%nswitch + & + (ipa_matrix(m,4)*prey_vec(4))**zoo(m)%nswitch + pa_matrix(m,3) = ipa_matrix(m,3)* & + ( (ipa_matrix(m,3)*prey_vec(3))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + pa_matrix(m,4) = ipa_matrix(m,4)* & + ( (ipa_matrix(m,4)*prey_vec(4))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + tot_prey(m) = pa_matrix(m,3)*prey_vec(3) + pa_matrix(m,4)*prey_vec(4) + ingest_matrix(m,3) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,3)* & + prey_vec(3)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + ingest_matrix(m,4) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,4)* & + prey_vec(4)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + zoo(m)%jingest_n(i,j,k) = ingest_matrix(m,3) + ingest_matrix(m,4) + zoo(m)%jingest_p(i,j,k) = ingest_matrix(m,3)*prey_p2n_vec(3) + & + ingest_matrix(m,4)*prey_p2n_vec(4) + zoo(m)%jingest_fe(i,j,k) = ingest_matrix(m,3)*prey_fe2n_vec(3) + + ! + ! Medium zooplankton (m = 2) consuming diazotrophs (1), large + ! phytoplankton (2), and small zooplankton (5) + ! + + m = 2 + zoo(m)%temp_lim(i,j,k) = exp(zoo(m)%ktemp*Temp(i,j,k)) + sw_fac_denom = (ipa_matrix(m,1)*prey_vec(1))**zoo(m)%nswitch + & + (ipa_matrix(m,2)*prey_vec(2))**zoo(m)%nswitch + & + (ipa_matrix(m,5)*prey_vec(5))**zoo(m)%nswitch + pa_matrix(m,1) = ipa_matrix(m,1)* & + ( (ipa_matrix(m,1)*prey_vec(1))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + pa_matrix(m,2) = ipa_matrix(m,2)* & + ( (ipa_matrix(m,2)*prey_vec(2))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + pa_matrix(m,5) = ipa_matrix(m,5)* & + ( (ipa_matrix(m,5)*prey_vec(5))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + tot_prey(m) = pa_matrix(m,1)*prey_vec(1) + pa_matrix(m,2)*prey_vec(2) + & + pa_matrix(m,5)*prey_vec(5) + ingest_matrix(m,1) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,1)* & + prey_vec(1)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + ingest_matrix(m,2) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,2)* & + prey_vec(2)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + ingest_matrix(m,5) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,5)* & + prey_vec(5)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + zoo(m)%jingest_n(i,j,k) = ingest_matrix(m,1) + ingest_matrix(m,2) + & + ingest_matrix(m,5) + zoo(m)%jingest_p(i,j,k) = ingest_matrix(m,1)*prey_p2n_vec(1) + & + ingest_matrix(m,2)*prey_p2n_vec(2) + & + ingest_matrix(m,5)*prey_p2n_vec(5) + zoo(m)%jingest_fe(i,j,k) = ingest_matrix(m,1)*prey_fe2n_vec(1) + & + ingest_matrix(m,2)*prey_fe2n_vec(2) + zoo(m)%jingest_sio2(i,j,k) = ingest_matrix(m,2)*prey_si2n_vec(2) + + ! + ! Large zooplankton (m = 3) consuming diazotrophs (2), large phytoplankton (2) + ! and medium zooplankton (6) + ! + + m = 3 + zoo(m)%temp_lim(i,j,k) = exp(zoo(m)%ktemp*Temp(i,j,k)) + sw_fac_denom = (ipa_matrix(m,1)*prey_vec(1))**zoo(m)%nswitch + & + (ipa_matrix(m,2)*prey_vec(2))**zoo(m)%nswitch + & + (ipa_matrix(m,6)*prey_vec(6))**zoo(m)%nswitch + pa_matrix(m,1) = ipa_matrix(m,1)* & + ( (ipa_matrix(m,1)*prey_vec(1))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + pa_matrix(m,2) = ipa_matrix(m,2)* & + ( (ipa_matrix(m,2)*prey_vec(2))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + pa_matrix(m,6) = ipa_matrix(m,6)* & + ( (ipa_matrix(m,6)*prey_vec(6))**zoo(m)%nswitch / & + (sw_fac_denom+epsln) )**(1.0/zoo(m)%mswitch) + tot_prey(m) = pa_matrix(m,1)*prey_vec(1) + pa_matrix(m,2)*prey_vec(2) + & + pa_matrix(m,6)*prey_vec(6) + ingest_matrix(m,1) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,1)* & + prey_vec(1)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + ingest_matrix(m,2) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,2)* & + prey_vec(2)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + ingest_matrix(m,6) = zoo(m)%temp_lim(i,j,k)*zoo(m)%imax*pa_matrix(m,6)* & + prey_vec(6)*zoo(m)%f_n(i,j,k)/(zoo(m)%ki+tot_prey(m)) + zoo(m)%jingest_n(i,j,k) = ingest_matrix(m,1) + ingest_matrix(m,2) + & + ingest_matrix(m,6) + zoo(m)%jingest_p(i,j,k) = ingest_matrix(m,1)*prey_p2n_vec(1) + & + ingest_matrix(m,2)*prey_p2n_vec(2) + & + ingest_matrix(m,6)*prey_p2n_vec(6) + zoo(m)%jingest_fe(i,j,k) = ingest_matrix(m,1)*prey_fe2n_vec(1) + & + ingest_matrix(m,2)*prey_fe2n_vec(2) + zoo(m)%jingest_sio2(i,j,k) = ingest_matrix(m,2)*prey_si2n_vec(2) + + cobalt%total_filter_feeding(i,j,k) = ingest_matrix(2,1) + ingest_matrix(2,2) + & + ingest_matrix(2,3) + ingest_matrix(3,1) + ingest_matrix(3,2) + & + ingest_matrix(3,3) + hp_ingest_vec(1) + hp_ingest_vec(2) + hp_ingest_vec(3) + + ! + ! Calculate losses to zooplankton + ! + + do n = 1,NUM_PHYTO + phyto(n)%jzloss_n(i,j,k) = 0.0 + enddo + + do m = 1,NUM_ZOO !{ + phyto(DIAZO)%jzloss_n(i,j,k) = phyto(DIAZO)%jzloss_n(i,j,k) + ingest_matrix(m,DIAZO) + phyto(LARGE)%jzloss_n(i,j,k) = phyto(LARGE)%jzloss_n(i,j,k) + ingest_matrix(m,LARGE) + phyto(SMALL)%jzloss_n(i,j,k) = phyto(SMALL)%jzloss_n(i,j,k) + ingest_matrix(m,SMALL) + enddo !} m + + do n = 1,NUM_PHYTO !{ + phyto(n)%jzloss_p(i,j,k) = phyto(n)%jzloss_n(i,j,k)*prey_p2n_vec(n) + phyto(n)%jzloss_fe(i,j,k) = phyto(n)%jzloss_n(i,j,k)*prey_fe2n_vec(n) + phyto(n)%jzloss_sio2(i,j,k) = phyto(n)%jzloss_n(i,j,k)*prey_si2n_vec(n) + enddo !} n + + ! + ! losses of bacteria to zooplankton + ! + + bact(1)%jzloss_n(i,j,k) = 0.0 + do m = 1,NUM_ZOO !{ + bact(1)%jzloss_n(i,j,k) = bact(1)%jzloss_n(i,j,k) + ingest_matrix(m,4) + enddo !} m + bact(1)%jzloss_p(i,j,k) = bact(1)%jzloss_n(i,j,k)*prey_p2n_vec(4) + + ! + ! losses of zooplankton to zooplankton + ! + + do n = 1,NUM_ZOO !{ + zoo(n)%jzloss_n(i,j,k) = 0.0 + + do m = 1,NUM_ZOO !{ + zoo(n)%jzloss_n(i,j,k) = zoo(n)%jzloss_n(i,j,k) + ingest_matrix(m,NUM_PHYTO+1+n) + enddo !} m + + zoo(n)%jzloss_p(i,j,k) = zoo(n)%jzloss_n(i,j,k)*prey_p2n_vec(NUM_PHYTO+1+n) + enddo !} n + + ! + ! losses of detritus to zooplankton (no detrivory in default settings) + ! + !cobalt%det_jzloss_n(i,j,k) = 0.0 + ! + !do m = 1,NUM_ZOO !{ + ! cobalt%det_jzloss_n(i,j,k) = cobalt%det_jzloss_n(i,j,k)+ingest_matrix(m,NUM_PHYTO+NUM_ZOO+2) + !enddo !} m + ! + !cobalt%det_jzloss_p(i,j,k) = cobalt%det_jzloss_n(i,j,k)*prey_p2n_vec(NUM_PHYTO+NUM_ZOO+2) + !cobalt%det_jzloss_fe(i,j,k) = cobalt%det_jzloss_n(i,j,k)*prey_fe2n_vec(NUM_PHYTO+NUM_ZOO+2) + !cobalt%det_jzloss_si(i,j,k) = cobalt%det_jzloss_si(i,j,k)*prey_si2n_vec(NUM_PHYTO+NUM_ZOO+2) + + ! + ! 3.1.2 Calculate ingestion by higher predators + ! + + ! The higher-predator ingestion calculations mirror those used for zooplankton + ! + cobalt%hp_temp_lim(i,j,k) = exp(cobalt%ktemp_hp*Temp(i,j,k)) + sw_fac_denom = (hp_ipa_vec(6)*prey_vec(6))**cobalt%nswitch_hp + & + (hp_ipa_vec(7)*prey_vec(7))**cobalt%nswitch_hp + hp_pa_vec(6) = hp_ipa_vec(6)* & + ( (hp_ipa_vec(6)*prey_vec(6))**cobalt%nswitch_hp / & + (sw_fac_denom+epsln) )**(1.0/cobalt%mswitch_hp) + hp_pa_vec(7) = hp_ipa_vec(7)* & + ( (hp_ipa_vec(7)*prey_vec(7))**cobalt%nswitch_hp / & + (sw_fac_denom+epsln) )**(1.0/cobalt%mswitch_hp) + tot_prey_hp = hp_pa_vec(6)*prey_vec(6) + hp_pa_vec(7)*prey_vec(7) + hp_ingest_vec(6) = cobalt%hp_temp_lim(i,j,k)*cobalt%imax_hp*hp_pa_vec(6)* & + prey_vec(6)*tot_prey_hp**(cobalt%coef_hp-1)/ & + (cobalt%ki_hp+tot_prey_hp) + hp_ingest_vec(7) = cobalt%hp_temp_lim(i,j,k)*cobalt%imax_hp*hp_pa_vec(7)* & + prey_vec(7)*tot_prey_hp**(cobalt%coef_hp-1)/ & + (cobalt%ki_hp+tot_prey_hp) + cobalt%hp_jingest_n(i,j,k) = hp_ingest_vec(6) + hp_ingest_vec(7) + cobalt%hp_jingest_p(i,j,k) = hp_ingest_vec(6)*prey_p2n_vec(6) + & + hp_ingest_vec(7)*prey_p2n_vec(7) + ! + ! No iron and sio2 ingestion by higher predators with default settings + ! + !cobalt%hp_jingest_fe(i,j,k) = hp_ingest_vec(6)*prey_fe2n_vec(6) + & + ! hp_ingest_vec(7)*prey_fe2n_vec(7) + !cobalt%hp_jingest_sio2(i,j,k) = hp_ingest_vec(6)*prey_si2n_vec(6) + & + ! hp_ingest_vec(7)*prey_si2n_vec(7) + + ! + ! Calculate losses to higher predators + ! + + ! losses of phytoplankton to higher predators (none with default settings) + ! + !do n = 1,NUM_PHYTO !{ + ! phyto(n)%jhploss_n(i,j,k) = hp_ingest_vec(n) + ! phyto(n)%jhploss_p(i,j,k) = phyto(n)%jhploss_n(i,j,k)*prey_p2n_vec(n) + ! phyto(n)%jhploss_fe(i,j,k) = phyto(n)%jhploss_n(i,j,k)*prey_fe2n_vec(n) + ! phyto(n)%jhploss_sio2(i,j,k) = phyto(n)%jhploss_n(i,j,k)*prey_si2n_vec(n) + !enddo !} n + ! + ! losses of bacteria to higher predators (none with default settings) + ! + ! bact(1)%jhploss_n(i,j,k) = hp_ingest_vec(4) + ! bact(1)%jhploss_p(i,j,k) = bact(1)%jhploss_n(i,j,k)*prey_p2n_vec(4) + ! + ! losses of zooplankton to higher predators + ! + do n = 1,NUM_ZOO !{ + zoo(n)%jhploss_n(i,j,k) = hp_ingest_vec(NUM_PHYTO+1+n) + zoo(n)%jhploss_p(i,j,k) = zoo(n)%jhploss_n(i,j,k)*prey_p2n_vec(NUM_PHYTO+1+n) + enddo !} n + ! + ! losses of detritus to higher predators (none with default settings) + ! + !cobalt%det_jhploss_n(i,j,k) = hp_ingest_vec(NUM_PHYTO+NUM_ZOO+2) + !cobalt%det_jhploss_p(i,j,k) = cobalt%det_jhploss_n(i,j,k)*prey_p2n_vec(NUM_PHYTO+NUM_ZOO+2) + !cobalt%det_jhploss_fe(i,j,k) = cobalt%det_jhploss_n(i,j,k)*prey_fe2n_vec(NUM_PHYTO+NUM_ZOO+2) + !cobalt%det_jhploss_si(i,j,k) = cobalt%det_jhploss_si(i,j,k)*prey_si2n_vec(NUM_PHYTO+NUM_ZOO+2) + + enddo; enddo; enddo !} i,j,k + call mpp_clock_end(id_clock_zooplankton_calculations) + + ! + ! 3.2: Plankton foodweb dynamics: Other mortality and loss terms + ! + + call mpp_clock_begin(id_clock_other_losses) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec; !{ + + ! + ! 3.2.1 Calculate losses of phytoplankton to aggregation + ! + + do n = 1,NUM_PHYTO !{ + phyto(n)%jaggloss_n(i,j,k) = phyto(n)%agg*phyto(n)%f_n(i,j,k)**2.0 + phyto(n)%jaggloss_p(i,j,k) = phyto(n)%jaggloss_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k) + phyto(n)%jaggloss_fe(i,j,k) = phyto(n)%jaggloss_n(i,j,k)*phyto(n)%q_fe_2_n(i,j,k) + phyto(n)%jaggloss_sio2(i,j,k) = phyto(n)%jaggloss_n(i,j,k)*phyto(n)%q_si_2_n(i,j,k) + enddo !} n + + ! + ! 3.2.2 Calculate phytoplankton and bacterial losses to viruses + ! + + do n = 1,NUM_PHYTO !{ + phyto(n)%jvirloss_n(i,j,k) = bact(1)%temp_lim(i,j,k)*phyto(n)%vir*phyto(n)%f_n(i,j,k)**2.0 + phyto(n)%jvirloss_p(i,j,k) = phyto(n)%jvirloss_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k) + phyto(n)%jvirloss_fe(i,j,k) = phyto(n)%jvirloss_n(i,j,k)*phyto(n)%q_fe_2_n(i,j,k) + phyto(n)%jvirloss_sio2(i,j,k) = phyto(n)%jvirloss_n(i,j,k)*phyto(n)%q_si_2_n(i,j,k) + enddo !} n + + bact(1)%jvirloss_n(i,j,k) = bact(1)%temp_lim(i,j,k)*bact(1)%vir*bact(1)%f_n(i,j,k)**2.0 + bact(1)%jvirloss_p(i,j,k) = bact(1)%jvirloss_n(i,j,k)*bact(1)%q_p_2_n + + ! + ! 3.2.3 Calculate losses to exudation + ! + + n = DIAZO + phyto(n)%jexuloss_n(i,j,k) = phyto(n)%exu*max(phyto(n)%juptake_no3(i,j,k)+ & + phyto(n)%juptake_nh4(i,j,k)+phyto(n)%juptake_n2(i,j,k),0.0) + phyto(n)%jexuloss_p(i,j,k) = phyto(n)%exu*max(phyto(n)%juptake_po4(i,j,k),0.0) + phyto(n)%jexuloss_fe(i,j,k) = phyto(n)%exu*max(phyto(n)%juptake_fe(i,j,k),0.0) + do n = 2,NUM_PHYTO !{ + phyto(n)%jexuloss_n(i,j,k) = phyto(n)%exu*max(phyto(n)%juptake_no3(i,j,k)+phyto(n)%juptake_nh4(i,j,k),0.0) + phyto(n)%jexuloss_p(i,j,k) = phyto(n)%exu*max(phyto(n)%juptake_po4(i,j,k),0.0) + phyto(n)%jexuloss_fe(i,j,k) = phyto(n)%exu*max(phyto(n)%juptake_fe(i,j,k),0.0) + enddo + ! Adjust silica uptake by large phytoplankton downward to maintain constant Si:N stoichimetry + ! phyto(LARGE)%juptake_sio4(i,j,k) = (1-phyto(LARGE)%exu)*phyto(LARGE)%juptake_sio4(i,j,k) + + enddo; enddo; enddo !} i,j,k + call mpp_clock_end(id_clock_other_losses) + + ! + ! 3.3: Plankton foodweb dynamics: Production calculations + ! + + call mpp_clock_begin(id_clock_production_loop) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + + ! + ! 3.3.1: Calculate the production of detritus and dissolved organic material + ! + + ! initialize some cumulative COBALT-wide production diagnostics + cobalt%jprod_ndet(i,j,k) = 0.0 + cobalt%jprod_pdet(i,j,k) = 0.0 + cobalt%jprod_sldon(i,j,k) = 0.0 + cobalt%jprod_ldon(i,j,k) = 0.0 + cobalt%jprod_srdon(i,j,k) = 0.0 + cobalt%jprod_sldop(i,j,k) = 0.0 + cobalt%jprod_ldop(i,j,k) = 0.0 + cobalt%jprod_srdop(i,j,k) = 0.0 + cobalt%jprod_fedet(i,j,k) = 0.0 + cobalt%jprod_fed(i,j,k) = 0.0 + cobalt%jprod_sidet(i,j,k) = 0.0 + cobalt%jprod_sio4(i,j,k) = 0.0 + cobalt%jprod_po4(i,j,k) = 0.0 + cobalt%jprod_nh4(i,j,k) = 0.0 + + ! + ! Production of detritus and dissolved organic material from zooplankton egestion + ! + + do m = 1,NUM_ZOO + zoo(m)%jprod_ndet(i,j,k) = zoo(m)%phi_det*zoo(m)%jingest_n(i,j,k) + zoo(m)%jprod_pdet(i,j,k) = zoo(m)%phi_det*zoo(m)%jingest_p(i,j,k) + zoo(m)%jprod_sldon(i,j,k) = zoo(m)%phi_sldon*zoo(m)%jingest_n(i,j,k) + zoo(m)%jprod_ldon(i,j,k) = zoo(m)%phi_ldon*zoo(m)%jingest_n(i,j,k) + zoo(m)%jprod_srdon(i,j,k) = zoo(m)%phi_srdon*zoo(m)%jingest_n(i,j,k) + zoo(m)%jprod_sldop(i,j,k) = zoo(m)%phi_sldop*zoo(m)%jingest_p(i,j,k) + zoo(m)%jprod_ldop(i,j,k) = zoo(m)%phi_ldop*zoo(m)%jingest_p(i,j,k) + zoo(m)%jprod_srdop(i,j,k) = zoo(m)%phi_srdop*zoo(m)%jingest_p(i,j,k) + zoo(m)%jprod_fedet(i,j,k) = zoo(m)%phi_det*zoo(m)%jingest_fe(i,j,k) + zoo(m)%jprod_sidet(i,j,k) = zoo(m)%phi_det*zoo(m)%jingest_sio2(i,j,k) + + + ! augment cumulative production with zooplankton terms + cobalt%jprod_ndet(i,j,k) = cobalt%jprod_ndet(i,j,k) + zoo(m)%jprod_ndet(i,j,k) + cobalt%jprod_pdet(i,j,k) = cobalt%jprod_pdet(i,j,k) + zoo(m)%jprod_pdet(i,j,k) + cobalt%jprod_sldon(i,j,k) = cobalt%jprod_sldon(i,j,k) + zoo(m)%jprod_sldon(i,j,k) + cobalt%jprod_ldon(i,j,k) = cobalt%jprod_ldon(i,j,k) + zoo(m)%jprod_ldon(i,j,k) + cobalt%jprod_srdon(i,j,k) = cobalt%jprod_srdon(i,j,k) + zoo(m)%jprod_srdon(i,j,k) + cobalt%jprod_sldop(i,j,k) = cobalt%jprod_sldop(i,j,k) + zoo(m)%jprod_sldop(i,j,k) + cobalt%jprod_ldop(i,j,k) = cobalt%jprod_ldop(i,j,k) + zoo(m)%jprod_ldop(i,j,k) + cobalt%jprod_srdop(i,j,k) = cobalt%jprod_srdop(i,j,k) + zoo(m)%jprod_srdop(i,j,k) + cobalt%jprod_fedet(i,j,k) = cobalt%jprod_fedet(i,j,k) + zoo(m)%jprod_fedet(i,j,k) + cobalt%jprod_sidet(i,j,k) = cobalt%jprod_sidet(i,j,k) + zoo(m)%jprod_sidet(i,j,k) + enddo !} m + + ! + ! Production of detritus and dissolved organic material from higher predator egestion + ! (did not track individual terms, just add to cumulative total) + ! + + cobalt%jprod_ndet(i,j,k) = cobalt%jprod_ndet(i,j,k) + cobalt%hp_phi_det*cobalt%hp_jingest_n(i,j,k) + cobalt%jprod_pdet(i,j,k) = cobalt%jprod_pdet(i,j,k) + cobalt%hp_phi_det*cobalt%hp_jingest_p(i,j,k) + cobalt%jprod_sldon(i,j,k) = cobalt%jprod_sldon(i,j,k) + cobalt%hp_phi_sldon*cobalt%hp_jingest_n(i,j,k) + cobalt%jprod_ldon(i,j,k) = cobalt%jprod_ldon(i,j,k) + cobalt%hp_phi_ldon*cobalt%hp_jingest_n(i,j,k) + cobalt%jprod_srdon(i,j,k) = cobalt%jprod_srdon(i,j,k) + cobalt%hp_phi_srdon*cobalt%hp_jingest_n(i,j,k) + cobalt%jprod_sldop(i,j,k) = cobalt%jprod_sldop(i,j,k) + cobalt%hp_phi_sldop*cobalt%hp_jingest_p(i,j,k) + cobalt%jprod_ldop(i,j,k) = cobalt%jprod_ldop(i,j,k) + cobalt%hp_phi_ldop*cobalt%hp_jingest_p(i,j,k) + cobalt%jprod_srdop(i,j,k) = cobalt%jprod_srdop(i,j,k) + cobalt%hp_phi_srdop*cobalt%hp_jingest_p(i,j,k) + cobalt%jprod_fedet(i,j,k) = cobalt%jprod_fedet(i,j,k) + cobalt%hp_phi_det*cobalt%hp_jingest_fe(i,j,k) + cobalt%jprod_sidet(i,j,k) = cobalt%jprod_sidet(i,j,k) + cobalt%hp_phi_det*cobalt%hp_jingest_sio2(i,j,k) + + ! + ! Sources from phytoplankton aggregation + ! + + do m = 1,NUM_PHYTO + cobalt%jprod_ndet(i,j,k) = cobalt%jprod_ndet(i,j,k) + phyto(m)%jaggloss_n(i,j,k) + cobalt%jprod_pdet(i,j,k) = cobalt%jprod_pdet(i,j,k) + phyto(m)%jaggloss_p(i,j,k) + cobalt%jprod_fedet(i,j,k) = cobalt%jprod_fedet(i,j,k) + phyto(m)%jaggloss_fe(i,j,k) + cobalt%jprod_sidet(i,j,k) = cobalt%jprod_sidet(i,j,k) + phyto(m)%jaggloss_sio2(i,j,k) + enddo !} m + + ! + ! Sources due to phytoplankton mortality from adverse growth conditions (metabolic costs higher than + ! photosynthetic capacity). These conditions are assumed to lead to a source of detritus in large + ! phytoplankton and diazotrophs. + ! + !n = DIAZO + !cobalt%jprod_ndet(i,j,k) = cobalt%jprod_ndet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k),0.0) + !cobalt%jprod_pdet(i,j,k) = cobalt%jprod_pdet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k),0.0) + !cobalt%jprod_fedet(i,j,k) = cobalt%jprod_fedet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_fe_2_n(i,j,k),0.0) + !n = LARGE + !cobalt%jprod_ndet(i,j,k) = cobalt%jprod_ndet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k),0.0) + !cobalt%jprod_pdet(i,j,k) = cobalt%jprod_pdet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k),0.0) + !cobalt%jprod_fedet(i,j,k) = cobalt%jprod_fedet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_fe_2_n(i,j,k),0.0) + !cobalt%jprod_sidet(i,j,k) = cobalt%jprod_sidet(i,j,k) - min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_si_2_n(i,j,k),0.0) + + ! + ! Sources from viral lysis of phytoplankton (0 in default formulation) and exudation + ! + + do m = 1,NUM_PHYTO + cobalt%jprod_ldon(i,j,k) = cobalt%jprod_ldon(i,j,k) + cobalt%lysis_phi_ldon*phyto(m)%jvirloss_n(i,j,k) + & + phyto(m)%jexuloss_n(i,j,k) + cobalt%jprod_sldon(i,j,k) = cobalt%jprod_sldon(i,j,k) + cobalt%lysis_phi_sldon*phyto(m)%jvirloss_n(i,j,k) + cobalt%jprod_srdon(i,j,k) = cobalt%jprod_srdon(i,j,k) + cobalt%lysis_phi_srdon*phyto(m)%jvirloss_n(i,j,k) + cobalt%jprod_ldop(i,j,k) = cobalt%jprod_ldop(i,j,k) + cobalt%lysis_phi_ldop*phyto(m)%jvirloss_p(i,j,k) + & + phyto(m)%jexuloss_p(i,j,k) + cobalt%jprod_sldop(i,j,k) = cobalt%jprod_sldop(i,j,k) + cobalt%lysis_phi_sldop*phyto(m)%jvirloss_p(i,j,k) + cobalt%jprod_srdop(i,j,k) = cobalt%jprod_srdop(i,j,k) + cobalt%lysis_phi_srdop*phyto(m)%jvirloss_p(i,j,k) + cobalt%jprod_fed(i,j,k) = cobalt%jprod_fed(i,j,k) + phyto(m)%jvirloss_fe(i,j,k) + & + phyto(m)%jexuloss_fe(i,j,k) + cobalt%jprod_sio4(i,j,k) = cobalt%jprod_sio4(i,j,k) + phyto(m)%jvirloss_sio2(i,j,k) + enddo !} m + + ! + ! Sources of dissolved organic material from small phytoplankton mortality (metabolic costs higher than photosynthetic + ! capacity). These conditions are assumed to lead to a lysis-like redistribution of small phyto organic matter. + ! + + !n = SMALL + !cobalt%jprod_ldon(i,j,k) = cobalt%jprod_ldon(i,j,k) - cobalt%lysis_phi_ldon*min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k),0.0) + !cobalt%jprod_sldon(i,j,k) = cobalt%jprod_sldon(i,j,k) - cobalt%lysis_phi_sldon*min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k),0.0) + !cobalt%jprod_srdon(i,j,k) = cobalt%jprod_srdon(i,j,k) - cobalt%lysis_phi_srdon*min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k),0.0) + !cobalt%jprod_ldop(i,j,k) = cobalt%jprod_ldop(i,j,k) - & + ! cobalt%lysis_phi_ldop*min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k),0.0) + !cobalt%jprod_sldop(i,j,k) = cobalt%jprod_sldop(i,j,k) - & + ! cobalt%lysis_phi_sldop*min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k),0.0) + !cobalt%jprod_srdop(i,j,k) = cobalt%jprod_srdop(i,j,k) - & + ! cobalt%lysis_phi_srdop*min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_p_2_n(i,j,k),0.0) + !cobalt%jprod_fed(i,j,k) = cobalt%jprod_fed(i,j,k) - & + ! min(phyto(n)%mu(i,j,k)*phyto(n)%f_n(i,j,k)*phyto(n)%q_fe_2_n(i,j,k),0.0) + + ! + ! Sources of dissolved organic material from viral lysis due to bacteria + ! + + cobalt%jprod_ldon(i,j,k) = cobalt%jprod_ldon(i,j,k) + cobalt%lysis_phi_ldon*bact(1)%jvirloss_n(i,j,k) + cobalt%jprod_sldon(i,j,k) = cobalt%jprod_sldon(i,j,k) + cobalt%lysis_phi_sldon*bact(1)%jvirloss_n(i,j,k) + cobalt%jprod_srdon(i,j,k) = cobalt%jprod_srdon(i,j,k) + cobalt%lysis_phi_srdon*bact(1)%jvirloss_n(i,j,k) + cobalt%jprod_ldop(i,j,k) = cobalt%jprod_ldop(i,j,k) + cobalt%lysis_phi_ldop*bact(1)%jvirloss_p(i,j,k) + cobalt%jprod_sldop(i,j,k) = cobalt%jprod_sldop(i,j,k) + cobalt%lysis_phi_sldop*bact(1)%jvirloss_p(i,j,k) + cobalt%jprod_srdop(i,j,k) = cobalt%jprod_srdop(i,j,k) + cobalt%lysis_phi_srdop*bact(1)%jvirloss_p(i,j,k) + + ! + ! Sources of dissolved organic material from bacterial mortality (metabolic costs higher than food uptake). + ! These conditions are assumed to lead to a lysis-like redistribution of bacteria organic matter. + ! + + cobalt%jprod_ldon(i,j,k) = cobalt%jprod_ldon(i,j,k) - cobalt%lysis_phi_ldon* & + min(bact(1)%jprod_n(i,j,k),0.0) + cobalt%jprod_sldon(i,j,k) = cobalt%jprod_sldon(i,j,k) - cobalt%lysis_phi_sldon* & + min(bact(1)%jprod_n(i,j,k),0.0) + cobalt%jprod_srdon(i,j,k) = cobalt%jprod_srdon(i,j,k) - cobalt%lysis_phi_srdon* & + min(bact(1)%jprod_n(i,j,k),0.0) + cobalt%jprod_ldop(i,j,k) = cobalt%jprod_ldop(i,j,k) - cobalt%lysis_phi_ldop* & + min(bact(1)%jprod_n(i,j,k)*bact(1)%q_p_2_n,0.0) + cobalt%jprod_sldop(i,j,k) = cobalt%jprod_sldop(i,j,k) - cobalt%lysis_phi_sldop* & + min(bact(1)%jprod_n(i,j,k)*bact(1)%q_p_2_n,0.0) + cobalt%jprod_srdop(i,j,k) = cobalt%jprod_srdop(i,j,k) - cobalt%lysis_phi_srdop* & + min(bact(1)%jprod_n(i,j,k)*bact(1)%q_p_2_n,0.0) + ! + ! 3.3.2: Calculate the remineralization of organic material by free-living bacteria + ! + + bact(1)%jprod_nh4(i,j,k) = bact(1)%juptake_ldon(i,j,k) - max(bact(1)%jprod_n(i,j,k),0.0) + bact(1)%jprod_po4(i,j,k) = bact(1)%juptake_ldop(i,j,k) - & + max(bact(1)%jprod_n(i,j,k)*bact(1)%q_p_2_n,0.0) + cobalt%jprod_nh4(i,j,k) = cobalt%jprod_nh4(i,j,k) + bact(1)%jprod_nh4(i,j,k) + cobalt%jprod_po4(i,j,k) = cobalt%jprod_po4(i,j,k) + bact(1)%jprod_po4(i,j,k) + + ! + ! 3.3.3: Zooplankton production and excretion calculations + ! + + do m = 1,NUM_ZOO + + ingest_p2n = zoo(m)%jingest_p(i,j,k)/(zoo(m)%jingest_n(i,j,k)+epsln) + + if (ingest_p2n .lt. zoo(m)%q_p_2_n) then + zoo(m)%jprod_n(i,j,k) = zoo(m)%gge_max*zoo(m)%jingest_p(i,j,k)*(1.0/zoo(m)%q_p_2_n) + else + zoo(m)%jprod_n(i,j,k) = zoo(m)%gge_max*zoo(m)%jingest_n(i,j,k) + endif + + ! adjust production terms for basal respiration costs + !if (zoo(m)%f_n(i,j,k).gt.refuge_conc) then + zoo(m)%jprod_n(i,j,k) = zoo(m)%jprod_n(i,j,k) - & + zoo(m)%f_n(i,j,k)/(refuge_conc + zoo(m)%f_n(i,j,k))* & + zoo(m)%temp_lim(i,j,k)*zoo(m)%bresp*zoo(m)%f_n(i,j,k) + !endif + ! + ! Ingested material that does not go to zooplankton production, detrital production + ! or production of dissolved organic material is excreted as nh4 or po4. If production + ! is negative, zooplankton are lost to large detritus + ! + if (zoo(m)%jprod_n(i,j,k) .gt. 0.0) then + zoo(m)%jprod_nh4(i,j,k) = zoo(m)%jingest_n(i,j,k) - zoo(m)%jprod_ndet(i,j,k) - & + zoo(m)%jprod_n(i,j,k) - zoo(m)%jprod_ldon(i,j,k) - & + zoo(m)%jprod_sldon(i,j,k) - zoo(m)%jprod_srdon(i,j,k) + zoo(m)%jprod_po4(i,j,k) = zoo(m)%jingest_p(i,j,k) - zoo(m)%jprod_pdet(i,j,k) - & + zoo(m)%jprod_n(i,j,k)*zoo(m)%q_p_2_n - zoo(m)%jprod_ldop(i,j,k) - & + zoo(m)%jprod_sldop(i,j,k) - zoo(m)%jprod_srdop(i,j,k) + else + ! None of the ingestion material goes to zooplankton production + zoo(m)%jprod_nh4(i,j,k) = zoo(m)%jingest_n(i,j,k) - zoo(m)%jprod_ndet(i,j,k) - & + zoo(m)%jprod_ldon(i,j,k) - zoo(m)%jprod_sldon(i,j,k) - & + zoo(m)%jprod_srdon(i,j,k) + zoo(m)%jprod_po4(i,j,k) = zoo(m)%jingest_p(i,j,k) - zoo(m)%jprod_pdet(i,j,k) - & + zoo(m)%jprod_ldop(i,j,k) - zoo(m)%jprod_sldop(i,j,k) - & + zoo(m)%jprod_srdop(i,j,k) + + ! The negative production (i.e., mortality) is lost to large detritus. Update values + ! for zooplankton and for total. + + zoo(m)%jprod_ndet(i,j,k) = zoo(m)%jprod_ndet(i,j,k) - zoo(m)%jprod_n(i,j,k) + zoo(m)%jprod_pdet(i,j,k) = zoo(m)%jprod_pdet(i,j,k) - zoo(m)%jprod_n(i,j,k)*zoo(m)%q_p_2_n + cobalt%jprod_ndet(i,j,k) = cobalt%jprod_ndet(i,j,k) - zoo(m)%jprod_n(i,j,k) + cobalt%jprod_pdet(i,j,k) = cobalt%jprod_pdet(i,j,k) - zoo(m)%jprod_n(i,j,k)*zoo(m)%q_p_2_n + endif + + ! cumulative production of inorganic nutrients + cobalt%jprod_nh4(i,j,k) = cobalt%jprod_nh4(i,j,k) + zoo(m)%jprod_nh4(i,j,k) + cobalt%jprod_po4(i,j,k) = cobalt%jprod_po4(i,j,k) + zoo(m)%jprod_po4(i,j,k) + + ! + ! Any ingested iron that is not allocated to detritus is routed back to the + ! dissolved pool. + ! + zoo(m)%jprod_fed(i,j,k) = (1.0 - zoo(m)%phi_det)*zoo(m)%jingest_fe(i,j,k) + cobalt%jprod_fed(i,j,k) = cobalt%jprod_fed(i,j,k) + zoo(m)%jprod_fed(i,j,k) + ! + ! Any ingested opal that is not allocated to detritus is assumed to undergo + ! rapid dissolution to dissolved silica + ! + zoo(m)%jprod_sio4(i,j,k) = (1.0 - zoo(m)%phi_det)*zoo(m)%jingest_sio2(i,j,k) + cobalt%jprod_sio4(i,j,k) = cobalt%jprod_sio4(i,j,k) + zoo(m)%jprod_sio4(i,j,k) + + enddo !} m + + ! + ! Excretion by higher predators + ! + cobalt%jprod_fed(i,j,k) = cobalt%jprod_fed(i,j,k) + (1.0-cobalt%hp_phi_det)*cobalt%hp_jingest_fe(i,j,k) + cobalt%jprod_sio4(i,j,k) = cobalt%jprod_sio4(i,j,k) + (1.0-cobalt%hp_phi_det)*cobalt%hp_jingest_sio2(i,j,k) + cobalt%jprod_nh4(i,j,k) = cobalt%jprod_nh4(i,j,k) + cobalt%hp_phi_nh4*cobalt%hp_jingest_n(i,j,k) + cobalt%jprod_po4(i,j,k) = cobalt%jprod_po4(i,j,k) + cobalt%hp_phi_po4*cobalt%hp_jingest_p(i,j,k) + + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_production_loop) + + call mpp_clock_begin(id_clock_ballast_loops) + do j = jsc, jec ; do i = isc, iec !{ + cobalt%zt(i,j,1) = dzt(i,j,1) + cobalt%zm(i,j,1) = 0.5*dzt(i,j,1) + enddo; enddo !} i,j + + do k = 2, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%zt(i,j,k) = cobalt%zt(i,j,k-1) + dzt(i,j,k) + cobalt%zm(i,j,k) = cobalt%zm(i,j,k-1) + dzt(i,j,k) + enddo; enddo ; enddo !} i,j,k + +! +!------------------------------------------------------------------------------------ +! 4: Production of calcium carbonate (Calcite and Aragonite) and lithogenic material +!------------------------------------------------------------------------------------ +! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + + ! + ! 4.1: Calculate aragonite and calcite saturation states + ! + + TK = Temp(i,j,k) + 273.15 + PRESS = 0.1016 * cobalt%zt(i,j,k) + 1.013 + PKSPA = 171.945 + 0.077993 * TK - 2903.293 / TK - 71.595 * log10(TK) - (-0.068393 + 1.7276e-3 * & + TK + 88.135 / TK) * sqrt(max(epsln, Salt(i,j,k))) + 0.10018 * max(epsln, Salt(i,j,k)) - & + 5.9415e-3 * max(epsln, Salt(i,j,k))**(1.5) - 0.02 - (48.76 - 2.8 - 0.5304 * Temp(i,j,k)) * & + (PRESS - 1.013) / (191.46 * TK) + (1e-3 * (11.76 - 0.3692 * Temp(i,j,k))) * (PRESS - 1.013) *& + (PRESS - 1.013) / (382.92 * TK) + cobalt%co3_sol_arag(i,j,k) = 10**(-PKSPA) / (2.937d-4 * max(5.0, Salt(i,j,k))) + cobalt%omega_arag(i,j,k) = cobalt%f_co3_ion(i,j,k) / cobalt%co3_sol_arag(i,j,k) + PKSPC = 171.9065 + 0.077993 * TK - 2839.319 / TK - 71.595 * log10(TK) - (-0.77712 + 2.8426e-3 * & + TK + 178.34 / TK) * sqrt(max(epsln, Salt(i,j,k))) + 0.07711 * max(epsln, Salt(i,j,k)) - & + 4.1249e-3 * max(epsln, Salt(i,j,k))**(1.5) - 0.02 - (48.76 - 0.5304 * Temp(i,j,k)) * & + (PRESS - 1.013) / (191.46 * TK) + (1e-3 * (11.76 - 0.3692 * Temp(i,j,k))) * (PRESS - 1.013) *& + (PRESS - 1.013) / (382.92 * TK) + cobalt%co3_sol_calc(i,j,k) = 10**(-PKSPC) / (2.937d-4 * max(5.0, Salt(i,j,k))) + cobalt%omega_calc(i,j,k) = cobalt%f_co3_ion(i,j,k) / cobalt%co3_sol_calc(i,j,k) + enddo; enddo ; enddo !} i,j,k + + ! + ! 4.2: Calculate the production rate of aragonite and calcite detritus + ! + + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%jprod_cadet_arag(i,j,k) = (zoo(2)%jzloss_n(i,j,k) + zoo(3)%jzloss_n(i,j,k) + & + zoo(2)%jhploss_n(i,j,k) + zoo(3)%jhploss_n(i,j,k))*cobalt%ca_2_n_arag* & + min(cobalt%caco3_sat_max, max(0.0,cobalt%omega_arag(i,j,k) - 1.0)) + epsln + cobalt%jprod_cadet_calc(i,j,k) = (zoo(1)%jzloss_n(i,j,k) + phyto(SMALL)%jaggloss_n(i,j,k))*cobalt%ca_2_n_calc* & + min(cobalt%caco3_sat_max, max(0.0, cobalt%omega_calc(i,j,k) - 1.0)) + epsln + enddo; enddo ; enddo !} i,j,k + + ! + ! 4.3: Lithogenic detritus production (repackaged from f_lith during filter feeding) + ! + + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%jprod_lithdet(i,j,k)=( cobalt%total_filter_feeding(i,j,k)/ & + ( phyto(LARGE)%f_n(i,j,k) + phyto(DIAZO)%f_n(i,j,k) + epsln ) * & + cobalt%phi_lith + cobalt%k_lith ) * cobalt%f_lith(i,j,k) + enddo; enddo ; enddo !} i,j,k + +! +!--------------------------------------------------------------------------------------------------------- +! 5: Detrital dissolution and remineralization calculation +!--------------------------------------------------------------------------------------------------------- +! + + ! + ! 5.1: Dissolution of aragonite, calcite and opal detrital particles + ! + + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%jdiss_cadet_arag(i,j,k) = cobalt%gamma_cadet_arag * & + max(0.0, 1.0 - cobalt%omega_arag(i,j,k)) * cobalt%f_cadet_arag(i,j,k) + cobalt%jdiss_cadet_calc(i,j,k) = cobalt%gamma_cadet_calc * & + max(0.0, 1.0 - cobalt%omega_calc(i,j,k)) * cobalt%f_cadet_calc(i,j,k) + cobalt%jdiss_sidet(i,j,k) = cobalt%gamma_sidet * cobalt%f_sidet(i,j,k) + cobalt%jprod_sio4(i,j,k) = cobalt%jprod_sio4(i,j,k) + cobalt%jdiss_sidet(i,j,k) + enddo; enddo ; enddo !} i,j,k + + ! + ! 5.2: Remineralization of nitrogen, phosphorous and iron detritus accounting for oxygen + ! and mineral protection + ! + + do k=1,nk ; do j=jsc,jec ; do i=isc,iec !{ + cobalt%jno3denit_wc(i,j,k) = 0.0 + ! + ! Under oxic conditions + ! + if (cobalt%f_o2(i,j,k) .gt. cobalt%o2_min) then !{ + cobalt%jremin_ndet(i,j,k) = cobalt%gamma_ndet * cobalt%f_o2(i,j,k) / & + ( cobalt%k_o2 + cobalt%f_o2(i,j,k) )*max( 0.0, cobalt%f_ndet(i,j,k) - & + cobalt%rpcaco3*(cobalt%f_cadet_arag(i,j,k) + cobalt%f_cadet_calc(i,j,k)) - & + cobalt%rplith*cobalt%f_lithdet(i,j,k) - cobalt%rpsio2*cobalt%f_sidet(i,j,k) ) + ! + ! Under sub-oxic conditions + ! + else !}{ + cobalt%jremin_ndet(i,j,k) = cobalt%gamma_ndet * cobalt%o2_min / & + (cobalt%k_o2 + cobalt%o2_min)* & + cobalt%f_no3(i,j,k) / (phyto(SMALL)%k_no3 + cobalt%f_no3(i,j,k))* & + max(0.0, cobalt%f_ndet(i,j,k) - & + cobalt%rpcaco3*(cobalt%f_cadet_arag(i,j,k) + cobalt%f_cadet_calc(i,j,k)) - & + cobalt%rplith*cobalt%f_lithdet(i,j,k) + cobalt%rpsio2*cobalt%f_sidet(i,j,k) ) + cobalt%jno3denit_wc(i,j,k) = cobalt%jremin_ndet(i,j,k) * cobalt%n_2_n_denit + endif !} + ! + ! P and Fe assumed to be protected similarly to N + ! + cobalt%jremin_pdet(i,j,k) = cobalt%jremin_ndet(i,j,k)/(cobalt%f_ndet(i,j,k) + epsln)* & + cobalt%f_pdet(i,j,k) + cobalt%jremin_fedet(i,j,k) = cobalt%jremin_ndet(i,j,k) / (cobalt%f_ndet(i,j,k) + epsln) * & + cobalt%remin_eff_fedet*cobalt%f_fedet(i,j,k) + enddo; enddo; enddo !} i,j,k + +! +!-------------------------------------------------------------------------------------------- +! 6: Miscellaneous sources and sinks: Nitrification, Iron Scavenging, Coastal Iron inputs +!-------------------------------------------------------------------------------------------- +! + + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + + ! + ! Nitrification + ! + + cobalt%jnitrif(i,j,k) = cobalt%gamma_nitrif * cobalt%expkT(i,j,k) * cobalt%f_nh4(i,j,k) * & + phyto(SMALL)%nh4lim(i,j,k) * (1.0 - cobalt%f_irr_mem(i,j,k) / & + (cobalt%irr_inhibit + cobalt%f_irr_mem(i,j,k))) + + ! + ! Solve for free iron + ! + + !cobalt%kfe_eq_lig(i,j,k) = 10**( log10(cobalt%kfe_eq_lig_ll) - & + ! ( cobalt%irr_inst(i,j,k)/(cobalt%ki_fescav+cobalt%irr_inst(i,j,k)) ) * & + ! (log10(cobalt%kfe_eq_lig_ll) - log10(cobalt%kfe_eq_lig_hl)) ) + cobalt%kfe_eq_lig(i,j,k) = min(cobalt%kfe_eq_lig_ll, 10**( log10(cobalt%kfe_eq_lig_hl) + & + max(0.0,cobalt%gamma_fescav*log10(cobalt%io_fescav/cobalt%irr_inst(i,j,k))) ) ) + + feprime = 1.0 + cobalt%kfe_eq_lig(i,j,k) * (cobalt%felig_bkg + cobalt%felig_2_don * & + (cobalt%f_sldon(i,j,k) + cobalt%f_srdon(i,j,k)) - cobalt%f_fed(i,j,k)) + feprime = (-feprime + (feprime * feprime + 4.0 * cobalt%kfe_eq_lig(i,j,k) * & + cobalt%f_fed(i,j,k))**(0.5)) / (2.0 * cobalt%kfe_eq_lig(i,j,k)) + + ! + ! Iron adsorption to detrital particles + ! + + cobalt%jfe_ads(i,j,k) = min(r_dt,cobalt%alpha_fescav*feprime) + if (cobalt%f_fed(i,j,k).gt.1.0e-9) then !{ + cobalt%jfe_ads(i,j,k) = min(r_dt,5.0*cobalt%alpha_fescav*cobalt%f_fed(i,j,k)) + endif !} + ! + ! Coastal iron inputs (proxy for sediment inputs for areas with poorly resolved shelves) + ! + + cobalt%jfe_coast(i,j,k) = cobalt%fe_coast * mask_coast(i,j) * grid_tmask(i,j,k) / & + sqrt(grid_dat(i,j)) + + enddo; enddo; enddo !} i,j,k + +! +!------------------------------------------------------------------------------------------------- +! 7: Sedimentary fluxes/transformations +!------------------------------------------------------------------------------------------------- +! + do j = jsc, jec; do i = isc, iec !{ + k = grid_kmt(i,j) + if (k .gt. 0) then !{ + ! + ! Nitrogen flux from the sediments + ! + if (cobalt%f_ndet_btf(i,j,1) .gt. 0.0) then !{ + ! fpoc_bottom in mmoles C m-2 day-1 for burial relationship + fpoc_btm = (cobalt%f_ndet_btf(i,j,1)*cobalt%c_2_n*sperd*1000.0) + cobalt%frac_burial(i,j) = (0.013 + 0.53*fpoc_btm**2.0)/((7.0+fpoc_btm)**2.0) + cobalt%fndet_burial(i,j) = cobalt%frac_burial(i,j)*cobalt%f_ndet_btf(i,j,1) + cobalt%fpdet_burial(i,j) = cobalt%frac_burial(i,j)*cobalt%f_pdet_btf(i,j,1) + ! fpoc_bottom in micromoles C cm-2 day-1 for denitrification relationship, cap at 43 + ! to prevent anomalous extrapolation of the relationship + log_fpoc_btm = log(min(43.0,0.1*fpoc_btm)) + cobalt%fno3denit_sed(i,j) = min(cobalt%f_no3(i,j,k)*cobalt%Rho_0*r_dt, & + min((cobalt%f_ndet_btf(i,j,1)-cobalt%fndet_burial(i,j))*cobalt%n_2_n_denit, & + 10.0**(-0.9543+0.7662*log_fpoc_btm - 0.235*log_fpoc_btm**2.0)/(cobalt%c_2_n*sperd*100.0)* & + cobalt%n_2_n_denit*cobalt%f_no3(i,j,k)/(cobalt%k_no3_denit + cobalt%f_no3(i,j,k)))) + if (cobalt%f_o2(i,j,k) .gt. cobalt%o2_min) then !{ + cobalt%fnoxic_sed(i,j) = max(0.0, min(cobalt%f_o2(i,j,k)*cobalt%Rho_0*r_dt*(1.0/cobalt%o2_2_nh4), & + cobalt%f_ndet_btf(i,j,1) - cobalt%fndet_burial(i,j) - & + cobalt%fno3denit_sed(i,j)/cobalt%n_2_n_denit)) + else + cobalt%fnoxic_sed(i,j) = 0.0 + endif !} + cobalt%fno3denit_sed(i,j) = cobalt%fno3denit_sed(i,j) + & + min(cobalt%f_no3(i,j,k)*cobalt%Rho_0*r_dt-cobalt%fno3denit_sed(i,j), & + (cobalt%f_ndet_btf(i,j,1)-cobalt%fnoxic_sed(i,j)-cobalt%fndet_burial(i,j) - & + cobalt%fno3denit_sed(i,j)/cobalt%n_2_n_denit)*cobalt%n_2_n_denit) + cobalt%fnfeso4red_sed(i,j) = max(0.0, cobalt%f_ndet_btf(i,j,1)-cobalt%fnoxic_sed(i,j)- & + cobalt%fndet_burial(i,j)-cobalt%fno3denit_sed(i,j)/cobalt%n_2_n_denit) + else + cobalt%fnfeso4red_sed(i,j) = 0.0 + cobalt%fno3denit_sed(i,j) = 0.0 + cobalt%fnoxic_sed(i,j) = 0.0 + endif !} + + ! iron from sediment + cobalt%ffe_sed(i,j) = cobalt%fe_2_n_sed * cobalt%f_ndet_btf(i,j,1) + + ! + ! Calcium carbonate flux and burial + ! + cobalt%fcased_redis(i,j) = max(0.0, min(0.5 * cobalt%f_cased(i,j,1) * r_dt, min(0.5 * & + cobalt%f_cadet_calc_btf(i,j,1), 0.165 * cobalt%f_ndet_btf(i,j,1) * cobalt%c_2_n) + & + 0.1244 / spery * max(0.0, 1.0 - cobalt%omega_calc(i,j,k) + & + 4.38 * cobalt%f_ndet_btf(i,j,1) * cobalt%c_2_n * spery)**(2.91) * & + max(1.0, cobalt%f_lithdet_btf(i,j,1) * spery + cobalt%f_cadet_calc_btf(i,j,1) * 100.0 * & + spery)**(-2.55) * cobalt%f_cased(i,j,1))) + cobalt%fcased_burial(i,j) = max(0.0, cobalt%f_cadet_calc_btf(i,j,1) * cobalt%f_cased(i,j,1) /& + 8.1e3) + cobalt%f_cased(i,j,1) = cobalt%f_cased(i,j,1) + (cobalt%f_cadet_calc_btf(i,j,1) - & + cobalt%fcased_redis(i,j) - cobalt%fcased_burial(i,j)) / cobalt%z_sed * dt * & + grid_tmask(i,j,k) + ! + ! Bottom flux boundaries passed to the vertical mixing routine + ! + cobalt%b_alk(i,j) = - 2.0*(cobalt%fcased_redis(i,j)+cobalt%f_cadet_arag_btf(i,j,1)) - & + (cobalt%f_ndet_btf(i,j,1) - cobalt%fndet_burial(i,j)) + cobalt%alk_2_n_denit * cobalt%fno3denit_sed(i,j) + cobalt%b_dic(i,j) = - cobalt%fcased_redis(i,j) - cobalt%f_cadet_arag_btf(i,j,1) - & + (cobalt%f_ndet_btf(i,j,1) - cobalt%fndet_burial(i,j)) * cobalt%c_2_n + cobalt%b_fed(i,j) = - cobalt%ffe_sed(i,j) + cobalt%b_nh4(i,j) = - cobalt%f_ndet_btf(i,j,1) + cobalt%fndet_burial(i,j) + cobalt%b_no3(i,j) = cobalt%fno3denit_sed(i,j) + cobalt%b_o2(i,j) = cobalt%o2_2_nh4 * (cobalt%fnoxic_sed(i,j) + cobalt%fnfeso4red_sed(i,j)) + cobalt%b_po4(i,j) = - cobalt%f_pdet_btf(i,j,1) + cobalt%fpdet_burial(i,j) + cobalt%b_sio4(i,j)= - cobalt%f_sidet_btf(i,j,1) + + endif !} + enddo; enddo !} i, j + + do k = 2, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%f_cased(i,j,k) = 0.0 + enddo; enddo ; enddo !} i,j,k + + call mpp_clock_end(id_clock_ballast_loops) + + call g_tracer_set_values(tracer_list,'alk', 'btf', cobalt%b_alk ,isd,jsd) + call g_tracer_set_values(tracer_list,'dic', 'btf', cobalt%b_dic ,isd,jsd) + call g_tracer_set_values(tracer_list,'fed', 'btf', cobalt%b_fed ,isd,jsd) + call g_tracer_set_values(tracer_list,'nh4', 'btf', cobalt%b_nh4 ,isd,jsd) + call g_tracer_set_values(tracer_list,'no3', 'btf', cobalt%b_no3 ,isd,jsd) + call g_tracer_set_values(tracer_list,'o2', 'btf', cobalt%b_o2 ,isd,jsd) + call g_tracer_set_values(tracer_list,'po4', 'btf', cobalt%b_po4 ,isd,jsd) + call g_tracer_set_values(tracer_list,'sio4', 'btf', cobalt%b_sio4,isd,jsd) + + call mpp_clock_begin(id_clock_source_sink_loop1) + +! +!----------------------------------------------------------------------- +! 8: Source/sink calculations +!----------------------------------------------------------------------- +! + ! + !------------------------------------------------------------------- + ! 4.1: Update the prognostics tracer fields via their pointers. + !------------------------------------------------------------------- + ! + call g_tracer_get_pointer(tracer_list,'alk' ,'field',cobalt%p_alk ) + call g_tracer_get_pointer(tracer_list,'cadet_arag','field',cobalt%p_cadet_arag) + call g_tracer_get_pointer(tracer_list,'cadet_calc','field',cobalt%p_cadet_calc) + call g_tracer_get_pointer(tracer_list,'dic' ,'field',cobalt%p_dic ) + call g_tracer_get_pointer(tracer_list,'fed' ,'field',cobalt%p_fed ) + call g_tracer_get_pointer(tracer_list,'fedi' ,'field',cobalt%p_fedi ) + call g_tracer_get_pointer(tracer_list,'felg' ,'field',cobalt%p_felg ) + call g_tracer_get_pointer(tracer_list,'fesm' ,'field',cobalt%p_fesm ) + call g_tracer_get_pointer(tracer_list,'fedet' ,'field',cobalt%p_fedet ) + call g_tracer_get_pointer(tracer_list,'ldon' ,'field',cobalt%p_ldon ) + call g_tracer_get_pointer(tracer_list,'ldop' ,'field',cobalt%p_ldop ) + call g_tracer_get_pointer(tracer_list,'lith' ,'field',cobalt%p_lith ) + call g_tracer_get_pointer(tracer_list,'lithdet','field',cobalt%p_lithdet) + call g_tracer_get_pointer(tracer_list,'nbact' ,'field',cobalt%p_nbact ) + call g_tracer_get_pointer(tracer_list,'ndet' ,'field',cobalt%p_ndet ) + call g_tracer_get_pointer(tracer_list,'ndi' ,'field',cobalt%p_ndi ) + call g_tracer_get_pointer(tracer_list,'nlg' ,'field',cobalt%p_nlg ) + call g_tracer_get_pointer(tracer_list,'nsm' ,'field',cobalt%p_nsm ) + call g_tracer_get_pointer(tracer_list,'nh4' ,'field',cobalt%p_nh4 ) + call g_tracer_get_pointer(tracer_list,'no3' ,'field',cobalt%p_no3 ) + call g_tracer_get_pointer(tracer_list,'o2' ,'field',cobalt%p_o2 ) + call g_tracer_get_pointer(tracer_list,'pdet' ,'field',cobalt%p_pdet ) + call g_tracer_get_pointer(tracer_list,'po4' ,'field',cobalt%p_po4 ) + call g_tracer_get_pointer(tracer_list,'srdon' ,'field',cobalt%p_srdon ) + call g_tracer_get_pointer(tracer_list,'srdop' ,'field',cobalt%p_srdop ) + call g_tracer_get_pointer(tracer_list,'sldon' ,'field',cobalt%p_sldon ) + call g_tracer_get_pointer(tracer_list,'sldop' ,'field',cobalt%p_sldop ) + call g_tracer_get_pointer(tracer_list,'sidet' ,'field',cobalt%p_sidet ) + call g_tracer_get_pointer(tracer_list,'silg' ,'field',cobalt%p_silg ) + call g_tracer_get_pointer(tracer_list,'sio4' ,'field',cobalt%p_sio4 ) + call g_tracer_get_pointer(tracer_list,'nsmz' ,'field',cobalt%p_nsmz ) + call g_tracer_get_pointer(tracer_list,'nmdz' ,'field',cobalt%p_nmdz ) + call g_tracer_get_pointer(tracer_list,'nlgz' ,'field',cobalt%p_nlgz ) + + + if (cobalt%id_no3_in_source .gt. 0) & + used = send_data(cobalt%id_no3_in_source, cobalt%f_no3, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + + call mpp_clock_end(id_clock_source_sink_loop1) + ! + !----------------------------------------------------------------------- + ! 4.2: Source sink calculations + !----------------------------------------------------------------------- + ! + ! Phytoplankton Nitrogen and Phosphorus + ! + call mpp_clock_begin(id_clock_source_sink_loop2) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! Diazotrophic Phytoplankton Nitrogen + ! + cobalt%jndi(i,j,k) = phyto(DIAZO)%mu(i,j,k)*phyto(DIAZO)%f_n(i,j,k) - & + phyto(DIAZO)%jzloss_n(i,j,k) - & + phyto(DIAZO)%jhploss_n(i,j,k) - phyto(DIAZO)%jaggloss_n(i,j,k) - & + phyto(DIAZO)%jvirloss_n(i,j,k) - phyto(DIAZO)%jexuloss_n(i,j,k) + cobalt%p_ndi(i,j,k,tau) = cobalt%p_ndi(i,j,k,tau) + cobalt%jndi(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Large Phytoplankton Nitrogen + ! + cobalt%jnlg(i,j,k) = phyto(LARGE)%mu(i,j,k)*phyto(LARGE)%f_n(i,j,k) - & + phyto(LARGE)%jzloss_n(i,j,k) - phyto(LARGE)%jhploss_n(i,j,k) - & + phyto(LARGE)%jaggloss_n(i,j,k) - phyto(LARGE)%jvirloss_n(i,j,k) - & + phyto(LARGE)%jexuloss_n(i,j,k) + cobalt%p_nlg(i,j,k,tau) = cobalt%p_nlg(i,j,k,tau) + cobalt%jnlg(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Small Phytoplankton Nitrogen + ! + cobalt%jnsm(i,j,k) = phyto(SMALL)%mu(i,j,k)*phyto(SMALL)%f_n(i,j,k) - & + phyto(SMALL)%jzloss_n(i,j,k) - phyto(SMALL)%jhploss_n(i,j,k) - & + phyto(SMALL)%jaggloss_n(i,j,k) - phyto(SMALL)%jvirloss_n(i,j,k) - & + phyto(SMALL)%jexuloss_n(i,j,k) + cobalt%p_nsm(i,j,k,tau) = cobalt%p_nsm(i,j,k,tau) + cobalt%jnsm(i,j,k)*dt*grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_source_sink_loop2) + ! + ! Phytoplankton Silicon and Iron + ! + call mpp_clock_begin(id_clock_source_sink_loop3) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! Large Phytoplankton Silicon + ! + cobalt%jsilg(i,j,k) = phyto(LARGE)%juptake_sio4(i,j,k) - & + phyto(LARGE)%jzloss_sio2(i,j,k) - phyto(LARGE)%jhploss_sio2(i,j,k) - & + phyto(LARGE)%jaggloss_sio2(i,j,k) - phyto(LARGE)%jvirloss_sio2(i,j,k) + cobalt%p_silg(i,j,k,tau) = cobalt%p_silg(i,j,k,tau) + cobalt%jsilg(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Diazotrophic Phytoplankton Iron + ! + cobalt%jfedi(i,j,k) = phyto(DIAZO)%juptake_fe(i,j,k) - & + phyto(DIAZO)%jzloss_fe(i,j,k) - & + phyto(DIAZO)%jhploss_fe(i,j,k) - phyto(DIAZO)%jaggloss_fe(i,j,k) - & + phyto(DIAZO)%jvirloss_fe(i,j,k) - phyto(DIAZO)%jexuloss_fe(i,j,k) + cobalt%p_fedi(i,j,k,tau) = cobalt%p_fedi(i,j,k,tau) + cobalt%jfedi(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Large Phytoplankton Iron + ! + cobalt%jfelg(i,j,k) = phyto(LARGE)%juptake_fe(i,j,k) - & + phyto(LARGE)%jzloss_fe(i,j,k) - & + phyto(LARGE)%jhploss_fe(i,j,k) - phyto(LARGE)%jaggloss_fe(i,j,k) - & + phyto(LARGE)%jvirloss_fe(i,j,k) - phyto(LARGE)%jexuloss_fe(i,j,k) + cobalt%p_felg(i,j,k,tau) = cobalt%p_felg(i,j,k,tau) + cobalt%jfelg(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Small Phytoplankton Iron + ! + cobalt%jfesm(i,j,k) = phyto(SMALL)%juptake_fe(i,j,k) - & + phyto(SMALL)%jzloss_fe(i,j,k) - & + phyto(SMALL)%jhploss_fe(i,j,k) - phyto(SMALL)%jaggloss_fe(i,j,k) - & + phyto(SMALL)%jvirloss_fe(i,j,k) - phyto(SMALL)%jexuloss_fe(i,j,k) + cobalt%p_fesm(i,j,k,tau) = cobalt%p_fesm(i,j,k,tau) + cobalt%jfesm(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Bacteria + ! + cobalt%jnbact(i,j,k) = bact(1)%jprod_n(i,j,k) - bact(1)%jzloss_n(i,j,k) - & + bact(1)%jvirloss_n(i,j,k) - bact(1)%jhploss_n(i,j,k) + cobalt%p_nbact(i,j,k,tau) = cobalt%p_nbact(i,j,k,tau) + cobalt%jnbact(i,j,k)*dt*grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_source_sink_loop3) + ! + ! Zooplankton + ! + call mpp_clock_begin(id_clock_source_sink_loop4) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! Small zooplankton + ! + cobalt%jnsmz(i,j,k) = zoo(1)%jprod_n(i,j,k) - zoo(1)%jzloss_n(i,j,k) - & + zoo(1)%jhploss_n(i,j,k) + cobalt%p_nsmz(i,j,k,tau) = cobalt%p_nsmz(i,j,k,tau) + cobalt%jnsmz(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Medium zooplankton + ! + cobalt%jnmdz(i,j,k) = zoo(2)%jprod_n(i,j,k) - zoo(2)%jzloss_n(i,j,k) - & + zoo(2)%jhploss_n(i,j,k) + cobalt%p_nmdz(i,j,k,tau) = cobalt%p_nmdz(i,j,k,tau) + cobalt%jnmdz(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Large zooplankton + ! + cobalt%jnlgz(i,j,k) = zoo(3)%jprod_n(i,j,k) - zoo(3)%jzloss_n(i,j,k) - & + zoo(3)%jhploss_n(i,j,k) + cobalt%p_nlgz(i,j,k,tau) = cobalt%p_nlgz(i,j,k,tau) + cobalt%jnlgz(i,j,k)*dt*grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_source_sink_loop4) + ! + ! NO3 + ! + call mpp_clock_begin(id_clock_source_sink_loop5) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%jno3(i,j,k) = cobalt%jnitrif(i,j,k) - phyto(DIAZO)%juptake_no3(i,j,k) - & + phyto(LARGE)%juptake_no3(i,j,k) - phyto(SMALL)%juptake_no3(i,j,k) - & + cobalt%jno3denit_wc(i,j,k) + cobalt%p_no3(i,j,k,tau) = cobalt%p_no3(i,j,k,tau) + cobalt%jno3(i,j,k)*dt*grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + ! + ! Other nutrients + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! NH4 + ! + cobalt%jprod_nh4(i,j,k) = cobalt%jprod_nh4(i,j,k) + cobalt%jremin_ndet(i,j,k) + cobalt%jnh4(i,j,k) = cobalt%jprod_nh4(i,j,k) - phyto(DIAZO)%juptake_nh4(i,j,k) - & + phyto(LARGE)%juptake_nh4(i,j,k) - phyto(SMALL)%juptake_nh4(i,j,k) - & + cobalt%jnitrif(i,j,k) + cobalt%p_nh4(i,j,k,tau) = cobalt%p_nh4(i,j,k,tau) + cobalt%jnh4(i,j,k) * dt * grid_tmask(i,j,k) + ! + ! PO4 + ! + cobalt%jprod_po4(i,j,k) = cobalt%jprod_po4(i,j,k) + cobalt%jremin_pdet(i,j,k) + cobalt%jpo4(i,j,k) = cobalt%jprod_po4(i,j,k) - phyto(DIAZO)%juptake_po4(i,j,k) - & + phyto(LARGE)%juptake_po4(i,j,k) - phyto(SMALL)%juptake_po4(i,j,k) + cobalt%p_po4(i,j,k,tau) = cobalt%p_po4(i,j,k,tau) + cobalt%jpo4(i,j,k) * dt * grid_tmask(i,j,k) + ! + ! SiO4 + ! + cobalt%jsio4(i,j,k) = cobalt%jprod_sio4(i,j,k) - phyto(LARGE)%juptake_sio4(i,j,k) + cobalt%p_sio4(i,j,k,tau) = cobalt%p_sio4(i,j,k,tau) + cobalt%jsio4(i,j,k) * dt * grid_tmask(i,j,k) + ! + ! Fed + ! + cobalt%jprod_fed(i,j,k) = cobalt%jprod_fed(i,j,k) + & + cobalt%jremin_fedet(i,j,k) + cobalt%jfe_coast(i,j,k) + cobalt%jfed(i,j,k) = cobalt%jprod_fed(i,j,k) - phyto(DIAZO)%juptake_fe(i,j,k) - & + phyto(LARGE)%juptake_fe(i,j,k) - phyto(SMALL)%juptake_fe(i,j,k) - & + cobalt%jfe_ads(i,j,k) + cobalt%p_fed(i,j,k,tau) = cobalt%p_fed(i,j,k,tau) + cobalt%jfed(i,j,k) * dt * grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + + call mpp_clock_end(id_clock_source_sink_loop5) + ! + !----------------------------------------------------------------------- + ! Detrital Components + !----------------------------------------------------------------------- + ! + call mpp_clock_begin(id_clock_source_sink_loop6) + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! Cadet_arag + ! + cobalt%jcadet_arag(i,j,k) = cobalt%jprod_cadet_arag(i,j,k) - cobalt%jdiss_cadet_arag(i,j,k) + cobalt%p_cadet_arag(i,j,k,tau) = cobalt%p_cadet_arag(i,j,k,tau) + cobalt%jcadet_arag(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Cadet_calc + ! + cobalt%jcadet_calc(i,j,k) = cobalt%jprod_cadet_calc(i,j,k) - cobalt%jdiss_cadet_calc(i,j,k) + cobalt%p_cadet_calc(i,j,k,tau) = cobalt%p_cadet_calc(i,j,k,tau) + cobalt%jcadet_calc(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Fedet + ! + cobalt%jprod_fedet(i,j,k) = cobalt%jprod_fedet(i,j,k) + cobalt%jfe_ads(i,j,k) + cobalt%jfedet(i,j,k) = cobalt%jprod_fedet(i,j,k) - & + cobalt%jremin_fedet(i,j,k) - cobalt%det_jzloss_fe(i,j,k) - & + cobalt%det_jhploss_fe(i,j,k) + cobalt%p_fedet(i,j,k,tau) = cobalt%p_fedet(i,j,k,tau) + cobalt%jfedet(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Lithdet + ! + cobalt%jlithdet(i,j,k) = cobalt%jprod_lithdet(i,j,k) + cobalt%p_lithdet(i,j,k,tau) = cobalt%p_lithdet(i,j,k,tau) + cobalt%jlithdet(i,j,k) * dt * & + grid_tmask(i,j,k) + ! + ! Ndet + ! + cobalt%jndet(i,j,k) = cobalt%jprod_ndet(i,j,k) - cobalt%jremin_ndet(i,j,k) - & + cobalt%det_jzloss_n(i,j,k) - cobalt%det_jhploss_n(i,j,k) + cobalt%p_ndet(i,j,k,tau) = cobalt%p_ndet(i,j,k,tau) + cobalt%jndet(i,j,k)*dt*grid_tmask(i,j,k) + !cobalt%p_ndet(i,j,k,tau) = max(cobalt%p_ndet(i,j,k,tau),0.0) + ! + ! Pdet + ! + cobalt%jpdet(i,j,k) = cobalt%jprod_pdet(i,j,k) - cobalt%jremin_pdet(i,j,k) - & + cobalt%det_jzloss_p(i,j,k) - cobalt%det_jhploss_p(i,j,k) + cobalt%p_pdet(i,j,k,tau) = cobalt%p_pdet(i,j,k,tau) + cobalt%jpdet(i,j,k)*dt*grid_tmask(i,j,k) + ! + ! Sidet + ! + cobalt%jsidet(i,j,k) = cobalt%jprod_sidet(i,j,k) - & + cobalt%jdiss_sidet(i,j,k) - cobalt%det_jzloss_si(i,j,k) - & + cobalt%det_jhploss_si(i,j,k) + cobalt%p_sidet(i,j,k,tau) = cobalt%p_sidet(i,j,k,tau) + cobalt%jsidet(i,j,k)*dt*grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + ! + ! Dissolved Organic Matter + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! Labile Dissolved Organic Nitrogen + ! + cobalt%jldon(i,j,k) = cobalt%jprod_ldon(i,j,k) + & + cobalt%gamma_sldon*cobalt%f_sldon(i,j,k) + & + cobalt%gamma_srdon*cobalt%f_srdon(i,j,k) - bact(1)%juptake_ldon(i,j,k) + cobalt%p_ldon(i,j,k,tau) = cobalt%p_ldon(i,j,k,tau) + cobalt%jldon(i,j,k)*dt* & + grid_tmask(i,j,k) + ! + ! Labile Dissolved Organic Phosphorous + ! + cobalt%jldop(i,j,k) = cobalt%jprod_ldop(i,j,k) + & + cobalt%gamma_sldop*cobalt%f_sldop(i,j,k) + & + cobalt%gamma_srdop*cobalt%f_srdop(i,j,k) - bact(1)%juptake_ldop(i,j,k) + cobalt%p_ldop(i,j,k,tau) = cobalt%p_ldop(i,j,k,tau) + cobalt%jldop(i,j,k)*dt* & + grid_tmask(i,j,k) + ! + ! Semilabile Dissolved Organic Nitrogen + ! + cobalt%jsldon(i,j,k) = cobalt%jprod_sldon(i,j,k) - & + cobalt%gamma_sldon*cobalt%f_sldon(i,j,k) + cobalt%p_sldon(i,j,k,tau) = cobalt%p_sldon(i,j,k,tau) + cobalt%jsldon(i,j,k) * dt * & + grid_tmask(i,j,k) + ! + ! Semilabile dissolved organic phosphorous + ! + cobalt%jsldop(i,j,k) = cobalt%jprod_sldop(i,j,k) - & + cobalt%gamma_sldop*cobalt%f_sldop(i,j,k) + cobalt%p_sldop(i,j,k,tau) = cobalt%p_sldop(i,j,k,tau) + cobalt%jsldop(i,j,k) * dt * & + grid_tmask(i,j,k) + ! + ! Refractory Dissolved Organic Nitrogen + ! + cobalt%jsrdon(i,j,k) = cobalt%jprod_srdon(i,j,k) - cobalt%gamma_srdon * cobalt%f_srdon(i,j,k) + cobalt%p_srdon(i,j,k,tau) = cobalt%p_srdon(i,j,k,tau) + cobalt%jsrdon(i,j,k) * dt * & + grid_tmask(i,j,k) + ! + ! Refractory dissolved organic phosphorous + ! + cobalt%jsrdop(i,j,k) = cobalt%jprod_srdop(i,j,k) - cobalt%gamma_srdop * cobalt%f_srdop(i,j,k) + cobalt%p_srdop(i,j,k,tau) = cobalt%p_srdop(i,j,k,tau) + cobalt%jsrdop(i,j,k) * dt * & + grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + ! + ! O2 + ! + do k = 1, nk ; do j =jsc, jec ; do i = isc, iec !{ + cobalt%jo2(i,j,k) = (cobalt%o2_2_no3 * (phyto(DIAZO)%juptake_no3(i,j,k) + & + phyto(LARGE)%juptake_no3(i,j,k) + phyto(SMALL)%juptake_no3(i,j,k)) + & + + cobalt%o2_2_nh4 * & + (phyto(DIAZO)%juptake_nh4(i,j,k) + phyto(LARGE)%juptake_nh4(i,j,k) + & + phyto(SMALL)%juptake_nh4(i,j,k) + & + phyto(DIAZO)%juptake_n2(i,j,k))) * grid_tmask(i,j,k) + if (cobalt%f_o2(i,j,k) .gt. cobalt%o2_min) then !{ + cobalt%jo2(i,j,k) = cobalt%jo2(i,j,k) - cobalt%o2_2_nh4*cobalt%jprod_nh4(i,j,k) & + - cobalt%o2_2_nitrif*cobalt%jnitrif(i,j,k) + endif !} + cobalt%p_o2(i,j,k,tau) = cobalt%p_o2(i,j,k,tau) + cobalt%jo2(i,j,k) * dt * grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + ! + ! The Carbon system + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + ! + ! Alkalinity + ! + cobalt%jalk(i,j,k) = (2.0 * (cobalt%jdiss_cadet_arag(i,j,k) + & + cobalt%jdiss_cadet_calc(i,j,k) - cobalt%jprod_cadet_arag(i,j,k) - & + cobalt%jprod_cadet_calc(i,j,k)) + phyto(DIAZO)%juptake_no3(i,j,k) + & + phyto(LARGE)%juptake_no3(i,j,k) + phyto(SMALL)%juptake_no3(i,j,k) + & + cobalt%jprod_nh4(i,j,k) - phyto(DIAZO)%juptake_nh4(i,j,k) - & + phyto(LARGE)%juptake_nh4(i,j,k) - phyto(SMALL)%juptake_nh4(i,j,k) - & + 2.0 * cobalt%jnitrif(i,j,k) + cobalt%alk_2_n_denit * cobalt%jno3denit_wc(i,j,k)) + cobalt%p_alk(i,j,k,tau) = cobalt%p_alk(i,j,k,tau) + cobalt%jalk(i,j,k) * dt * grid_tmask(i,j,k) + ! + ! Dissolved Inorganic Carbon + ! + cobalt%jdic(i,j,k) =(cobalt%c_2_n * (cobalt%jno3(i,j,k) + & + cobalt%jnh4(i,j,k) + cobalt%jno3denit_wc(i,j,k) - phyto(DIAZO)%juptake_n2(i,j,k)) + & + cobalt%jdiss_cadet_arag(i,j,k) + cobalt%jdiss_cadet_calc(i,j,k) - & + cobalt%jprod_cadet_arag(i,j,k) - cobalt%jprod_cadet_calc(i,j,k)) + cobalt%p_dic(i,j,k,tau) = cobalt%p_dic(i,j,k,tau) + cobalt%jdic(i,j,k) * dt * grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + ! + !----------------------------------------------------------------------- + ! Lithogenic aluminosilicate particulates + !----------------------------------------------------------------------- + ! + do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ + cobalt%p_lith(i,j,k,tau) = cobalt%p_lith(i,j,k,tau) - cobalt%jlithdet(i,j,k) * dt * & + grid_tmask(i,j,k) + enddo; enddo ; enddo !} i,j,k + call mpp_clock_end(id_clock_source_sink_loop6) + call mpp_clock_begin(id_clock_cobalt_calc_diagnostics) + ! + !Set the diagnostics tracer fields. + ! + call g_tracer_set_values(tracer_list,'cased', 'field',cobalt%f_cased ,isd,jsd,ntau=1) + call g_tracer_set_values(tracer_list,'chl', 'field',cobalt%f_chl ,isd,jsd,ntau=1) + call g_tracer_set_values(tracer_list,'co3_ion','field',cobalt%f_co3_ion ,isd,jsd,ntau=1) + call g_tracer_set_values(tracer_list,'irr_mem' ,'field',cobalt%f_irr_mem ,isd,jsd,ntau=1) + ! + !----------------------------------------------------------------------- + ! Save variables for diagnostics + !----------------------------------------------------------------------- + ! + + do j = jsc, jec ; do i = isc, iec !{ + if (grid_kmt(i,j) .gt. 0) then !{ + cobalt%o2min(i,j)=cobalt%p_o2(i,j,1,tau) + cobalt%z_o2min(i,j)=cobalt%zt(i,j,1) + cobalt%z_sat_arag(i,j)=missing_value1 + cobalt%z_sat_calc(i,j)=missing_value1 + cobalt%mask_z_sat_arag(i,j) = .FALSE. + cobalt%mask_z_sat_calc(i,j) = .FALSE. + if (cobalt%omega_arag(i,j,1) .le. 1.0) cobalt%z_sat_arag(i,j)=0.0 + if (cobalt%omega_calc(i,j,1) .le. 1.0) cobalt%z_sat_calc(i,j)=0.0 + endif !} + enddo ; enddo !} i,j,k + do j = jsc, jec ; do i = isc, iec !{ + first = .true. + do k = 2, nk + if (k .le. grid_kmt(i,j) .and. first) then !{ + if (cobalt%p_o2(i,j,k,tau) .lt. cobalt%p_o2(i,j,k-1,tau)) then + cobalt%o2min(i,j)=cobalt%p_o2(i,j,k,tau) + cobalt%z_o2min(i,j)=cobalt%zt(i,j,k) + else + first = .false. + endif !} + endif !} + enddo; + enddo ; enddo !} i,j + + do k = 2, nk ; do j = jsc, jec ; do i = isc, iec !{ + if (k .le. grid_kmt(i,j)) then !{ + if (cobalt%omega_arag(i,j,k) .le. 1.0 .and. cobalt%z_sat_arag(i,j) .lt. 0.0) then + cobalt%z_sat_arag(i,j)=cobalt%zt(i,j,k) + cobalt%mask_z_sat_arag(i,j) = .TRUE. + endif + if (cobalt%omega_calc(i,j,k) .le. 1.0 .and. cobalt%z_sat_calc(i,j) .lt. 0.0) then + cobalt%z_sat_calc(i,j)=cobalt%zt(i,j,k) + cobalt%mask_z_sat_calc(i,j) = .TRUE. + endif + endif !} + enddo; enddo ; enddo !} i,j,k + + ! + !--------------------------------------------------------------------- + ! Calculate total carbon = Dissolved Inorganic Carbon + Phytoplankton Carbon + ! + Dissolved Organic Carbon (including refractory) + Heterotrophic Biomass + ! + Detrital Orgainc and Inorganic Carbon + ! For the oceanic carbon budget, a constant 42 uM of dissolved organic + ! carbon is added to represent the refractory component. + ! For the oceanic nitrogen budget, a constant 2 uM of dissolved organic + ! nitrogen is added to represent the refractory component. + !--------------------------------------------------------------------- + ! + cobalt%tot_layer_int_c(:,:,:) = (cobalt%p_dic(:,:,:,tau) + 4.2e-5 + cobalt%p_cadet_arag(:,:,:,tau) +& + cobalt%p_cadet_calc(:,:,:,tau) + cobalt%c_2_n * (cobalt%p_ndi(:,:,:,tau) + cobalt%p_nlg(:,:,:,tau) + & + cobalt%p_nsm(:,:,:,tau) + cobalt%p_nbact(:,:,:,tau) + & + cobalt%p_ldon(:,:,:,tau) + cobalt%p_sldon(:,:,:,tau) + cobalt%p_srdon(:,:,:,tau) + & + cobalt%p_ndet(:,:,:,tau) + cobalt%p_nsmz(:,:,:,tau) + cobalt%p_nmdz(:,:,:,tau) + & + cobalt%p_nlgz(:,:,:,tau))) * rho_dzt(:,:,:) + + cobalt%tot_layer_int_fe(:,:,:) = (cobalt%p_fed(:,:,:,tau) + cobalt%p_fedi(:,:,:,tau) + & + cobalt%p_felg(:,:,:,tau) + cobalt%p_fesm(:,:,:,tau) + & + cobalt%p_fedet(:,:,:,tau)) * rho_dzt(:,:,:) + + cobalt%tot_layer_int_n(:,:,:) = (cobalt%p_no3(:,:,:,tau) + & + cobalt%p_nh4(:,:,:,tau) + cobalt%p_ndi(:,:,:,tau) + cobalt%p_nlg(:,:,:,tau) + & + cobalt%p_nsm(:,:,:,tau) + cobalt%p_nbact(:,:,:,tau) + & + cobalt%p_ldon(:,:,:,tau) + cobalt%p_sldon(:,:,:,tau) + cobalt%p_srdon(:,:,:,tau) + cobalt%p_ndet(:,:,:,tau) + & + cobalt%p_nsmz(:,:,:,tau) + cobalt%p_nmdz(:,:,:,tau) + cobalt%p_nlgz(:,:,:,tau)) * & + rho_dzt(:,:,:) + + cobalt%tot_layer_int_p(:,:,:) = (cobalt%p_po4(:,:,:,tau) + & + cobalt%p_ndi(:,:,:,tau)*phyto(1)%p_2_n_static + & + cobalt%p_nlg(:,:,:,tau)*phyto(2)%p_2_n_static + & + cobalt%p_nsm(:,:,:,tau)*phyto(3)%p_2_n_static + & + cobalt%p_ldop(:,:,:,tau) + cobalt%p_sldop(:,:,:,tau) + & + cobalt%p_srdop(:,:,:,tau) + cobalt%p_pdet(:,:,:,tau) + & + bact(1)%q_p_2_n*cobalt%p_nbact(:,:,:,tau) + zoo(1)%q_p_2_n*cobalt%p_nsmz(:,:,:,tau) + & + zoo(2)%q_p_2_n*cobalt%p_nmdz(:,:,:,tau) + zoo(3)%q_p_2_n*cobalt%p_nlgz(:,:,:,tau)) & + * rho_dzt(:,:,:) + + cobalt%tot_layer_int_si(:,:,:) = (cobalt%p_sio4(:,:,:,tau) + cobalt%p_silg(:,:,:,tau) + & + cobalt%p_sidet(:,:,:,tau)) * rho_dzt(:,:,:) + +!**************************************************************************************************** + + allocate(rho_dzt_100(isc:iec,jsc:jec)) + ! + !--------------------------------------------------------------------- + ! calculate upper 100 m vertical integrals + !--------------------------------------------------------------------- + ! + do j = jsc, jec ; do i = isc, iec !{ + rho_dzt_100(i,j) = rho_dzt(i,j,1) + do n = 1, NUM_PHYTO !{ + phyto(n)%jprod_n_100(i,j) = phyto(n)%jprod_n(i,j,1) * rho_dzt(i,j,1) + phyto(n)%jprod_n_new_100(i,j) = phyto(n)%juptake_no3(i,j,1) * rho_dzt(i,j,1) + phyto(n)%jzloss_n_100(i,j) = phyto(n)%jzloss_n(i,j,1) * rho_dzt(i,j,1) + phyto(n)%jexuloss_n_100(i,j) = phyto(n)%jexuloss_n(i,j,1) * rho_dzt(i,j,1) + phyto(n)%f_n_100(i,j) = phyto(n)%f_n(i,j,1) * rho_dzt(i,j,1) + enddo !} n + phyto(DIAZO)%jprod_n_n2_100(i,j) = phyto(DIAZO)%juptake_n2(i,j,1) * rho_dzt(i,j,1) + phyto(SMALL)%jvirloss_n_100(i,j) = phyto(SMALL)%jvirloss_n(i,j,1) * rho_dzt(i,j,1) + phyto(SMALL)%jaggloss_n_100(i,j) = phyto(SMALL)%jaggloss_n(i,j,1) * rho_dzt(i,j,1) + phyto(LARGE)%jaggloss_n_100(i,j) = phyto(LARGE)%jaggloss_n(i,j,1) * rho_dzt(i,j,1) + + do n = 1, NUM_ZOO !{ + zoo(n)%jprod_n_100(i,j) = zoo(n)%jprod_n(i,j,1) * rho_dzt(i,j,1) + zoo(n)%jingest_n_100(i,j) = zoo(n)%jingest_n(i,j,1) * rho_dzt(i,j,1) + zoo(n)%jremin_n_100(i,j) = zoo(n)%jprod_nh4(i,j,1) * rho_dzt(i,j,1) + zoo(n)%f_n_100(i,j) = zoo(n)%f_n(i,j,1) * rho_dzt(i,j,1) + enddo !} n + + do n = 1,2 !{ + zoo(n)%jzloss_n_100(i,j) = zoo(n)%jzloss_n(i,j,1) * rho_dzt(i,j,1) + zoo(n)%jprod_don_100(i,j) = (zoo(n)%jprod_ldon(i,j,1) + zoo(n)%jprod_sldon(i,j,1) + & + zoo(n)%jprod_srdon(i,j,1)) * rho_dzt(i,j,1) + enddo !} n + + do n = 2,3 !{ + zoo(n)%jhploss_n_100(i,j) = zoo(n)%jhploss_n(i,j,1) * rho_dzt(i,j,1) + zoo(n)%jprod_ndet_100(i,j) = zoo(n)%jprod_ndet(i,j,1) * rho_dzt(i,j,1) + enddo !} n + + cobalt%hp_jingest_n_100(i,j) = cobalt%hp_jingest_n(i,j,1)*rho_dzt(i,j,1) + cobalt%hp_jremin_n_100(i,j) = cobalt%hp_jingest_n(i,j,1)*rho_dzt(i,j,1)*cobalt%hp_phi_nh4 + cobalt%hp_jprod_ndet_100(i,j) = cobalt%hp_jingest_n(i,j,1)*rho_dzt(i,j,1)*cobalt%hp_phi_det + + bact(1)%jprod_n_100(i,j) = bact(1)%jprod_n(i,j,1) * rho_dzt(i,j,1) + bact(1)%jzloss_n_100(i,j) = bact(1)%jzloss_n(i,j,1) * rho_dzt(i,j,1) + bact(1)%jvirloss_n_100(i,j) = bact(1)%jvirloss_n(i,j,1) * rho_dzt(i,j,1) + bact(1)%jremin_n_100(i,j) = bact(1)%jprod_nh4(i,j,1) * rho_dzt(i,j,1) + bact(1)%juptake_ldon_100(i,j) = bact(1)%juptake_ldon(i,j,1) * rho_dzt(i,j,1) + bact(1)%f_n_100(i,j) = bact(1)%f_n(i,j,1) * rho_dzt(i,j,1) + + cobalt%jprod_lithdet_100(i,j) = cobalt%jprod_lithdet(i,j,1) * rho_dzt(i,j,1) + cobalt%jprod_sidet_100(i,j) = cobalt%jprod_sidet(i,j,1) * rho_dzt(i,j,1) + cobalt%jprod_cadet_calc_100(i,j) = cobalt%jprod_cadet_calc(i,j,1) * rho_dzt(i,j,1) + cobalt%jprod_cadet_arag_100(i,j) = cobalt%jprod_cadet_arag(i,j,1) * rho_dzt(i,j,1) + cobalt%jremin_ndet_100(i,j) = cobalt%jremin_ndet(i,j,1) * rho_dzt(i,j,1) + + cobalt%f_ndet_100(i,j) = cobalt%f_ndet(i,j,1)*rho_dzt(i,j,1) + cobalt%f_don_100(i,j) = (cobalt%f_ldon(i,j,1)+cobalt%f_sldon(i,j,1)+cobalt%f_srdon(i,j,1))* & + rho_dzt(i,j,1) + cobalt%f_silg_100(i,j) = cobalt%f_silg(i,j,1)*rho_dzt(i,j,1) + + cobalt%fndet_100(i,j) = cobalt%f_ndet(i,j,1) * cobalt%Rho_0 * cobalt%wsink + cobalt%fpdet_100(i,j) = cobalt%f_pdet(i,j,1) * cobalt%Rho_0 * cobalt%wsink + cobalt%ffedet_100(i,j) = cobalt%f_fedet(i,j,1) * cobalt%Rho_0 * cobalt%wsink + cobalt%flithdet_100(i,j) = cobalt%f_lithdet(i,j,1) * cobalt%Rho_0 * cobalt%wsink + cobalt%fsidet_100(i,j) = cobalt%f_sidet(i,j,1) * cobalt%Rho_0 * cobalt%wsink + cobalt%fcadet_arag_100(i,j) = cobalt%f_cadet_arag(i,j,1) * cobalt%Rho_0 * cobalt%wsink + cobalt%fcadet_calc_100(i,j) = cobalt%f_cadet_calc(i,j,1) * cobalt%Rho_0 * cobalt%wsink + enddo; enddo !} i,j + + do j = jsc, jec ; do i = isc, iec ; !{ + k_100 = 1 + do k = 2, grid_kmt(i,j) !{ + if (rho_dzt_100(i,j) .lt. cobalt%Rho_0 * 100.0) then + k_100 = k + rho_dzt_100(i,j) = rho_dzt_100(i,j) + rho_dzt(i,j,k) + do n = 1, NUM_PHYTO !{ + phyto(n)%jprod_n_100(i,j) = phyto(n)%jprod_n_100(i,j) + phyto(n)%jprod_n(i,j,k)* & + rho_dzt(i,j,k) + phyto(n)%jprod_n_new_100(i,j) = phyto(n)%jprod_n_new_100(i,j) + phyto(n)%juptake_no3(i,j,k)* & + rho_dzt(i,j,k) + phyto(n)%jzloss_n_100(i,j) = phyto(n)%jzloss_n_100(i,j) + phyto(n)%jzloss_n(i,j,k)* & + rho_dzt(i,j,k) + phyto(n)%jexuloss_n_100(i,j) = phyto(n)%jexuloss_n_100(i,j) + phyto(n)%jexuloss_n(i,j,k)* & + rho_dzt(i,j,k) + phyto(n)%f_n_100(i,j) = phyto(n)%f_n_100(i,j) + phyto(n)%f_n(i,j,k)*rho_dzt(i,j,k) + enddo !} n + phyto(DIAZO)%jprod_n_n2_100(i,j) = phyto(DIAZO)%jprod_n_n2_100(i,j) + & + phyto(DIAZO)%juptake_n2(i,j,k)*rho_dzt(i,j,k) + phyto(SMALL)%jvirloss_n_100(i,j) = phyto(SMALL)%jvirloss_n_100(i,j) + & + phyto(SMALL)%jvirloss_n(i,j,k)*rho_dzt(i,j,k) + phyto(SMALL)%jaggloss_n_100(i,j) = phyto(SMALL)%jaggloss_n_100(i,j) + & + phyto(SMALL)%jaggloss_n(i,j,k)*rho_dzt(i,j,k) + phyto(LARGE)%jaggloss_n_100(i,j) = phyto(LARGE)%jaggloss_n_100(i,j) + & + phyto(LARGE)%jaggloss_n(i,j,k)*rho_dzt(i,j,k) + + do n = 1, NUM_ZOO !{ + zoo(n)%jprod_n_100(i,j) = zoo(n)%jprod_n_100(i,j) + zoo(n)%jprod_n(i,j,k)* & + rho_dzt(i,j,k) + zoo(n)%jingest_n_100(i,j) = zoo(n)%jingest_n_100(i,j) + zoo(n)%jingest_n(i,j,k)* & + rho_dzt(i,j,k) + zoo(n)%jremin_n_100(i,j) = zoo(n)%jremin_n_100(i,j) + zoo(n)%jprod_nh4(i,j,k)* & + rho_dzt(i,j,k) + zoo(n)%f_n_100(i,j) = zoo(n)%f_n_100(i,j) + zoo(n)%f_n(i,j,k)*rho_dzt(i,j,k) + enddo !} n + + do n = 1,2 !{ + zoo(n)%jzloss_n_100(i,j) = zoo(n)%jzloss_n_100(i,j) + zoo(n)%jzloss_n(i,j,k)* & + rho_dzt(i,j,k) + zoo(n)%jprod_don_100(i,j) = zoo(n)%jprod_don_100(i,j) + (zoo(n)%jprod_ldon(i,j,k) + & + zoo(n)%jprod_sldon(i,j,k) + zoo(n)%jprod_srdon(i,j,k))*rho_dzt(i,j,k) + enddo !} n + + do n = 2,3 !{ + zoo(n)%jhploss_n_100(i,j) = zoo(n)%jhploss_n_100(i,j) + zoo(n)%jhploss_n(i,j,k)* & + rho_dzt(i,j,k) + zoo(n)%jprod_ndet_100(i,j) = zoo(n)%jprod_ndet_100(i,j) + zoo(n)%jprod_ndet(i,j,k)* & + rho_dzt(i,j,k) + enddo !} n + + cobalt%hp_jingest_n_100(i,j) = cobalt%hp_jingest_n_100(i,j) + cobalt%hp_jingest_n(i,j,k)* & + rho_dzt(i,j,k) + cobalt%hp_jremin_n_100(i,j) = cobalt%hp_jremin_n_100(i,j) + cobalt%hp_jingest_n(i,j,k)* & + cobalt%hp_phi_nh4*rho_dzt(i,j,k) + cobalt%hp_jprod_ndet_100(i,j) = cobalt%hp_jprod_ndet_100(i,j) + cobalt%hp_jingest_n(i,j,k)* & + cobalt%hp_phi_det*rho_dzt(i,j,k) + + bact(1)%jprod_n_100(i,j) = bact(1)%jprod_n_100(i,j) + bact(1)%jprod_n(i,j,k) * rho_dzt(i,j,k) + bact(1)%jzloss_n_100(i,j) = bact(1)%jzloss_n_100(i,j) + bact(1)%jzloss_n(i,j,k) * rho_dzt(i,j,k) + bact(1)%jvirloss_n_100(i,j) = bact(1)%jvirloss_n_100(i,j) + bact(1)%jvirloss_n(i,j,k) * rho_dzt(i,j,k) + bact(1)%jremin_n_100(i,j) = bact(1)%jremin_n_100(i,j) + bact(1)%jprod_nh4(i,j,k) * rho_dzt(i,j,k) + bact(1)%juptake_ldon_100(i,j) = bact(1)%juptake_ldon_100(i,j) + bact(1)%juptake_ldon(i,j,k) * rho_dzt(i,j,k) + bact(1)%f_n_100(i,j) = bact(1)%f_n_100(i,j) + bact(1)%f_n(i,j,k)*rho_dzt(i,j,k) + + cobalt%jprod_lithdet_100(i,j) = cobalt%jprod_lithdet_100(i,j) + cobalt%jprod_lithdet(i,j,k) * rho_dzt(i,j,k) + cobalt%jprod_sidet_100(i,j) = cobalt%jprod_sidet_100(i,j) + cobalt%jprod_sidet(i,j,k) * rho_dzt(i,j,k) + cobalt%jprod_cadet_calc_100(i,j) = cobalt%jprod_cadet_calc_100(i,j) + cobalt%jprod_cadet_calc(i,j,k) * rho_dzt(i,j,k) + cobalt%jprod_cadet_arag_100(i,j) = cobalt%jprod_cadet_arag_100(i,j) + cobalt%jprod_cadet_arag(i,j,k) * rho_dzt(i,j,k) + cobalt%jremin_ndet_100(i,j) = cobalt%jremin_ndet_100(i,j) + cobalt%jremin_ndet(i,j,k) * rho_dzt(i,j,k) + cobalt%f_ndet_100(i,j) = cobalt%f_ndet_100(i,j) + cobalt%f_ndet(i,j,k)*rho_dzt(i,j,k) + cobalt%f_don_100(i,j) = cobalt%f_don_100(i,j) + (cobalt%f_ldon(i,j,k) + cobalt%f_sldon(i,j,k) + & + cobalt%f_srdon(i,j,k))*rho_dzt(i,j,k) + cobalt%f_silg_100(i,j) = cobalt%f_silg_100(i,j) + cobalt%f_silg(i,j,k)*rho_dzt(i,j,k) + + cobalt%fndet_100(i,j) = cobalt%f_ndet(i,j,k) * cobalt%Rho_0 * cobalt%wsink + cobalt%fpdet_100(i,j) = cobalt%f_pdet(i,j,k) * cobalt%Rho_0 * cobalt%wsink + cobalt%ffedet_100(i,j) = cobalt%f_fedet(i,j,k) * cobalt%Rho_0 * cobalt%wsink + cobalt%flithdet_100(i,j) = cobalt%f_lithdet(i,j,k) * cobalt%Rho_0 * cobalt%wsink + cobalt%fsidet_100(i,j) = cobalt%f_sidet(i,j,k) * cobalt%Rho_0 * cobalt%wsink + cobalt%fcadet_arag_100(i,j) = cobalt%f_cadet_arag(i,j,k) * cobalt%Rho_0 * cobalt%wsink + cobalt%fcadet_calc_100(i,j) = cobalt%f_cadet_calc(i,j,k) * cobalt%Rho_0 * cobalt%wsink + + endif + enddo !} k + + if (k_100 .gt. 1 .and. k_100 .lt. grid_kmt(i,j)) then + drho_dzt = cobalt%Rho_0 * 100.0 - rho_dzt_100(i,j) + do n = 1, NUM_PHYTO !{ + phyto(n)%jprod_n_100(i,j) = phyto(n)%jprod_n_100(i,j) + phyto(n)%jprod_n(i,j,k_100)* & + drho_dzt + phyto(n)%jprod_n_new_100(i,j) = phyto(n)%jprod_n_new_100(i,j) + phyto(n)%juptake_no3(i,j,k_100)* & + drho_dzt + phyto(n)%jzloss_n_100(i,j) = phyto(n)%jzloss_n_100(i,j) + phyto(n)%jzloss_n(i,j,k_100)* & + drho_dzt + phyto(n)%jexuloss_n_100(i,j) = phyto(n)%jexuloss_n_100(i,j) + phyto(n)%jexuloss_n(i,j,k_100)* & + drho_dzt + phyto(n)%f_n_100(i,j) = phyto(n)%f_n_100(i,j) + phyto(n)%f_n(i,j,k_100)*drho_dzt + enddo !} n + phyto(DIAZO)%jprod_n_n2_100(i,j) = phyto(DIAZO)%jprod_n_n2_100(i,j) + & + phyto(DIAZO)%juptake_n2(i,j,k_100)*drho_dzt + phyto(SMALL)%jvirloss_n_100(i,j) = phyto(SMALL)%jvirloss_n_100(i,j) + & + phyto(SMALL)%jvirloss_n(i,j,k_100)*drho_dzt + phyto(SMALL)%jaggloss_n_100(i,j) = phyto(SMALL)%jaggloss_n_100(i,j) + & + phyto(SMALL)%jaggloss_n(i,j,k_100)*drho_dzt + phyto(LARGE)%jaggloss_n_100(i,j) = phyto(LARGE)%jaggloss_n_100(i,j) + & + phyto(LARGE)%jaggloss_n(i,j,k_100)*drho_dzt + + do n = 1, NUM_ZOO !{ + zoo(n)%jprod_n_100(i,j) = zoo(n)%jprod_n_100(i,j) + zoo(n)%jprod_n(i,j,k_100)* & + drho_dzt + zoo(n)%jingest_n_100(i,j) = zoo(n)%jingest_n_100(i,j) + zoo(n)%jingest_n(i,j,k_100)* & + drho_dzt + zoo(n)%jremin_n_100(i,j) = zoo(n)%jremin_n_100(i,j) + zoo(n)%jprod_nh4(i,j,k_100)* & + drho_dzt + zoo(n)%f_n_100(i,j) = zoo(n)%f_n_100(i,j) + zoo(n)%f_n(i,j,k_100)*drho_dzt + enddo !} n + + do n = 1,2 !{ + zoo(n)%jzloss_n_100(i,j) = zoo(n)%jzloss_n_100(i,j) + zoo(n)%jzloss_n(i,j,k_100)* & + drho_dzt + zoo(n)%jprod_don_100(i,j) = zoo(n)%jprod_don_100(i,j) + (zoo(n)%jprod_ldon(i,j,k_100) + & + zoo(n)%jprod_sldon(i,j,k_100) + zoo(n)%jprod_srdon(i,j,k_100))*drho_dzt + enddo !} n + + do n = 2,3 !{ + zoo(n)%jhploss_n_100(i,j) = zoo(n)%jhploss_n_100(i,j) + zoo(n)%jhploss_n(i,j,k_100)* & + drho_dzt + zoo(n)%jprod_ndet_100(i,j) = zoo(n)%jprod_ndet_100(i,j) + zoo(n)%jprod_ndet(i,j,k_100)* & + drho_dzt + enddo !} n + + cobalt%hp_jingest_n_100(i,j) = cobalt%hp_jingest_n_100(i,j) + cobalt%hp_jingest_n(i,j,k_100)* & + drho_dzt + cobalt%hp_jremin_n_100(i,j) = cobalt%hp_jremin_n_100(i,j) + cobalt%hp_jingest_n(i,j,k_100)* & + cobalt%hp_phi_nh4*drho_dzt + cobalt%hp_jprod_ndet_100(i,j) = cobalt%hp_jprod_ndet_100(i,j) + cobalt%hp_jingest_n(i,j,k_100)* & + cobalt%hp_phi_det*drho_dzt + + bact(1)%jprod_n_100(i,j) = bact(1)%jprod_n_100(i,j) + bact(1)%jprod_n(i,j,k_100)* & + drho_dzt + bact(1)%jzloss_n_100(i,j) = bact(1)%jzloss_n_100(i,j) + bact(1)%jzloss_n(i,j,k_100)* & + drho_dzt + bact(1)%jvirloss_n_100(i,j) = bact(1)%jvirloss_n_100(i,j) + bact(1)%jvirloss_n(i,j,k_100)* & + drho_dzt + bact(1)%jremin_n_100(i,j) = bact(1)%jremin_n_100(i,j) + bact(1)%jprod_nh4(i,j,k_100)* & + drho_dzt + bact(1)%juptake_ldon_100(i,j) = bact(1)%juptake_ldon_100(i,j) + bact(1)%juptake_ldon(i,j,k_100)* & + drho_dzt + bact(1)%f_n_100(i,j) = bact(1)%f_n_100(i,j) + bact(1)%f_n(i,j,k_100)*drho_dzt + + cobalt%jprod_lithdet_100(i,j) = cobalt%jprod_lithdet_100(i,j) + cobalt%jprod_lithdet(i,j,k_100)* & + drho_dzt + cobalt%jprod_sidet_100(i,j) = cobalt%jprod_sidet_100(i,j) + cobalt%jprod_sidet(i,j,k_100)* & + drho_dzt + cobalt%jprod_cadet_calc_100(i,j) = cobalt%jprod_cadet_calc_100(i,j) + cobalt%jprod_cadet_calc(i,j,k_100)* & + drho_dzt + cobalt%jprod_cadet_arag_100(i,j) = cobalt%jprod_cadet_arag_100(i,j) + cobalt%jprod_cadet_arag(i,j,k_100)* & + drho_dzt + cobalt%jremin_ndet_100(i,j) = cobalt%jremin_ndet_100(i,j) + cobalt%jremin_ndet(i,j,k_100)* & + drho_dzt + + cobalt%f_ndet_100(i,j) = cobalt%f_ndet_100(i,j) + cobalt%f_ndet(i,j,k_100)*drho_dzt + cobalt%f_don_100(i,j) = cobalt%f_don_100(i,j) + (cobalt%f_ldon(i,j,k_100) + cobalt%f_sldon(i,j,k_100) + & + cobalt%f_srdon(i,j,k_100))*drho_dzt + cobalt%f_silg_100(i,j) = cobalt%f_silg_100(i,j) + cobalt%f_silg(i,j,k_100)*drho_dzt + + cobalt%fndet_100(i,j) = cobalt%f_ndet(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + cobalt%fpdet_100(i,j) = cobalt%f_pdet(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + cobalt%ffedet_100(i,j) = cobalt%f_fedet(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + cobalt%flithdet_100(i,j) = cobalt%f_lithdet(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + cobalt%fsidet_100(i,j) = cobalt%f_sidet(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + cobalt%fcadet_arag_100(i,j) = cobalt%f_cadet_arag(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + cobalt%fcadet_calc_100(i,j) = cobalt%f_cadet_calc(i,j,k_100) * cobalt%Rho_0 * cobalt%wsink + endif + + cobalt%jprod_allphytos_100(i,j) = phyto(SMALL)%jprod_n_100(i,j) + phyto(LARGE)%jprod_n_100(i,j) + & + phyto(DIAZO)%jprod_n_100(i,j) + enddo ; enddo !} i,j + deallocate(rho_dzt_100) + + do j = jsc, jec ; do i = isc, iec ; !{ + cobalt%btm_temp(i,j) = TEMP(i,j,grid_kmt(i,j)) + cobalt%btm_o2(i,j) = cobalt%f_o2(i,j,grid_kmt(i,j)) + enddo; enddo !} i, j + + ! + !--------------------------------------------------------------------- + ! calculate upper 200m vertical integrals for mesozooplankton + ! quantities for comparison with COPEPOD database + !--------------------------------------------------------------------- + ! + allocate(rho_dzt_200(isc:iec,jsc:jec)) + do j = jsc, jec ; do i = isc, iec !{ + rho_dzt_200(i,j) = rho_dzt(i,j,1) + cobalt%jprod_mesozoo_200(i,j) = (zoo(2)%jprod_n(i,j,1) + zoo(3)%jprod_n(i,j,1))*rho_dzt(i,j,1) + cobalt%f_mesozoo_200(i,j) = (zoo(2)%f_n(i,j,1)+zoo(3)%f_n(i,j,1))*rho_dzt(i,j,1) + enddo; enddo !} i,j + + do j = jsc, jec ; do i = isc, iec ; !{ + k_200 = 1 + do k = 2, grid_kmt(i,j) !{ + if (rho_dzt_200(i,j) .lt. cobalt%Rho_0 * 200.0) then + k_200 = k + rho_dzt_200(i,j) = rho_dzt_200(i,j) + rho_dzt(i,j,k) + cobalt%jprod_mesozoo_200(i,j) = cobalt%jprod_mesozoo_200(i,j) + & + (zoo(2)%jprod_n(i,j,k) + zoo(3)%jprod_n(i,j,k))*rho_dzt(i,j,k) + cobalt%f_mesozoo_200(i,j) = cobalt%f_mesozoo_200(i,j) + & + (zoo(2)%f_n(i,j,k)+zoo(3)%f_n(i,j,k))*rho_dzt(i,j,k) + endif + enddo !} k + + if (k_200 .gt. 1 .and. k_200 .lt. grid_kmt(i,j)) then + drho_dzt = cobalt%Rho_0 * 200.0 - rho_dzt_200(i,j) + cobalt%jprod_mesozoo_200(i,j) = cobalt%jprod_mesozoo_200(i,j) + & + (zoo(2)%jprod_n(i,j,k_200) + zoo(3)%jprod_n(i,j,k_200))*drho_dzt + cobalt%f_mesozoo_200(i,j) = cobalt%f_mesozoo_200(i,j) + & + (zoo(2)%f_n(i,j,k_200)+zoo(3)%f_n(i,j,k_200))*drho_dzt + endif + enddo ; enddo !} i,j + + call g_tracer_get_pointer(tracer_list,'alk','runoff_tracer_flux',cobalt%runoff_flux_alk) + call g_tracer_get_pointer(tracer_list,'dic','runoff_tracer_flux',cobalt%runoff_flux_dic) + call g_tracer_get_pointer(tracer_list,'fed','runoff_tracer_flux',cobalt%runoff_flux_fed) + call g_tracer_get_pointer(tracer_list,'fed','drydep',cobalt%dry_fed) + call g_tracer_get_pointer(tracer_list,'fed','wetdep',cobalt%wet_fed) + call g_tracer_get_pointer(tracer_list,'lith','drydep',cobalt%dry_lith) + call g_tracer_get_pointer(tracer_list,'lith','wetdep',cobalt%wet_lith) + call g_tracer_get_pointer(tracer_list,'lith','runoff_tracer_flux',cobalt%runoff_flux_lith) + call g_tracer_get_pointer(tracer_list,'no3','runoff_tracer_flux',cobalt%runoff_flux_no3) + call g_tracer_get_pointer(tracer_list,'no3','drydep',cobalt%dry_no3) + call g_tracer_get_pointer(tracer_list,'no3','wetdep',cobalt%wet_no3) + call g_tracer_get_pointer(tracer_list,'nh4','drydep',cobalt%dry_nh4) + call g_tracer_get_pointer(tracer_list,'nh4','wetdep',cobalt%wet_nh4) + call g_tracer_get_pointer(tracer_list,'po4','drydep',cobalt%dry_po4) + call g_tracer_get_pointer(tracer_list,'po4','wetdep',cobalt%wet_po4) + call g_tracer_get_pointer(tracer_list,'ldon','runoff_tracer_flux',cobalt%runoff_flux_ldon) + call g_tracer_get_pointer(tracer_list,'sldon','runoff_tracer_flux',cobalt%runoff_flux_sldon) + call g_tracer_get_pointer(tracer_list,'srdon','runoff_tracer_flux',cobalt%runoff_flux_srdon) + call g_tracer_get_pointer(tracer_list,'ndet','runoff_tracer_flux',cobalt%runoff_flux_ndet) + call g_tracer_get_pointer(tracer_list,'po4','runoff_tracer_flux',cobalt%runoff_flux_po4) + call g_tracer_get_pointer(tracer_list,'ldop','runoff_tracer_flux',cobalt%runoff_flux_ldop) + call g_tracer_get_pointer(tracer_list,'sldop','runoff_tracer_flux',cobalt%runoff_flux_sldop) + call g_tracer_get_pointer(tracer_list,'srdop','runoff_tracer_flux',cobalt%runoff_flux_srdop) + + +!--------------------------------------------------------------------- +! Add vertical integrals for diagnostics +!--------------------------------------------------------------------- +! + + call mpp_clock_end(id_clock_cobalt_calc_diagnostics) + call mpp_clock_begin(id_clock_cobalt_send_diagnostics) + +!--------------------------------------------------------------------- +! +! Send phytoplankton diagnostic data + + do n= 1, NUM_PHYTO + if (phyto(n)%id_def_fe .gt. 0) & + used = send_data(phyto(n)%id_def_fe, phyto(n)%def_fe, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_felim .gt. 0) & + used = send_data(phyto(n)%id_felim, phyto(n)%felim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_irrlim .gt. 0) & + used = send_data(phyto(n)%id_irrlim, phyto(n)%irrlim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_jzloss_n .gt. 0) & + used = send_data(phyto(n)%id_jzloss_n, phyto(n)%jzloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_jaggloss_n .gt. 0) & + used = send_data(phyto(n)%id_jaggloss_n, phyto(n)%jaggloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_jvirloss_n .gt. 0) & + used = send_data(phyto(n)%id_jvirloss_n, phyto(n)%jvirloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_jexuloss_n .gt. 0) & + used = send_data(phyto(n)%id_jexuloss_n, phyto(n)%jexuloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) +! if (phyto(n)%id_jhploss_n .gt. 0) & +! used = send_data(phyto(n)%id_jhploss_n, phyto(n)%jhploss_n*rho_dzt, & +! model_time, rmask = grid_tmask,& +! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_juptake_fe .gt. 0) & + used = send_data(phyto(n)%id_juptake_fe, phyto(n)%juptake_fe*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_juptake_nh4 .gt. 0) & + used = send_data(phyto(n)%id_juptake_nh4, phyto(n)%juptake_nh4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_juptake_no3 .gt. 0) & + used = send_data(phyto(n)%id_juptake_no3, phyto(n)%juptake_no3*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_juptake_po4 .gt. 0) & + used = send_data(phyto(n)%id_juptake_po4, phyto(n)%juptake_po4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_juptake_sio4 .gt. 0) & + used = send_data(phyto(n)%id_juptake_sio4, phyto(n)%juptake_sio4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_juptake_n2 .gt. 0) & + used = send_data(phyto(n)%id_juptake_n2, phyto(n)%juptake_n2*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_jprod_n .gt. 0) & + used = send_data(phyto(n)%id_jprod_n, phyto(n)%jprod_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) +! if (phyto(n)%id_liebig_lim .gt. 0) & +! used = send_data(phyto(n)%id_liebig_lim,phyto(n)%liebig_lim, & +! model_time, rmask = grid_tmask,& +! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_mu .gt. 0) & + used = send_data(phyto(n)%id_mu, phyto(n)%mu, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_nh4lim .gt. 0) & + used = send_data(phyto(n)%id_nh4lim, phyto(n)%nh4lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_no3lim .gt. 0) & + used = send_data(phyto(n)%id_no3lim, phyto(n)%no3lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_po4lim .gt. 0) & + used = send_data(phyto(n)%id_po4lim, phyto(n)%po4lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_o2lim .gt. 0) & + used = send_data(phyto(n)%id_o2lim, phyto(n)%o2lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_q_fe_2_n .gt. 0) & + used = send_data(phyto(n)%id_q_fe_2_n, phyto(n)%q_fe_2_n, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_silim .gt. 0) & + used = send_data(phyto(n)%id_silim, phyto(n)%silim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_q_si_2_n .gt. 0) & + used = send_data(phyto(n)%id_q_si_2_n, phyto(n)%q_si_2_n, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (phyto(n)%id_theta .gt. 0) & + used = send_data(phyto(n)%id_theta, phyto(n)%theta, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + enddo + !-------------------------------------------------------------------------------------- + ! Send bacterial diagnostic data + ! + + if (bact(1)%id_jzloss_n .gt. 0) & + used = send_data(bact(1)%id_jzloss_n, bact(1)%jzloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) +! if (bact(1)%id_jhploss_n .gt. 0) & +! used = send_data(bact(1)%id_jhploss_n, bact(1)%jhploss_n*rho_dzt, & +! model_time, rmask = grid_tmask,& +! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_jvirloss_n .gt. 0) & + used = send_data(bact(1)%id_jvirloss_n, bact(1)%jvirloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_juptake_ldon .gt. 0) & + used = send_data(bact(1)%id_juptake_ldon, bact(1)%juptake_ldon*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_juptake_ldop .gt. 0) & + used = send_data(bact(1)%id_juptake_ldop, bact(1)%juptake_ldop*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_jprod_nh4 .gt. 0) & + used = send_data(bact(1)%id_jprod_nh4, bact(1)%jprod_nh4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_jprod_po4 .gt. 0) & + used = send_data(bact(1)%id_jprod_po4, bact(1)%jprod_po4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_jprod_n .gt. 0) & + used = send_data(bact(1)%id_jprod_n, bact(1)%jprod_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bact(1)%id_temp_lim .gt. 0) & + used = send_data(bact(1)%id_temp_lim, bact(1)%temp_lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + + !-------------------------------------------------------------------------------------- + ! Send zooplankton diagnostic data + ! + + do n= 1, NUM_ZOO + if (zoo(n)%id_jzloss_n .gt. 0) & + used = send_data(zoo(n)%id_jzloss_n, zoo(n)%jzloss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jhploss_n .gt. 0) & + used = send_data(zoo(n)%id_jhploss_n, zoo(n)%jhploss_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jingest_n .gt. 0) & + used = send_data(zoo(n)%id_jingest_n, zoo(n)%jingest_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jingest_p .gt. 0) & + used = send_data(zoo(n)%id_jingest_p, zoo(n)%jingest_p*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jingest_sio2 .gt. 0) & + used = send_data(zoo(n)%id_jingest_sio2, zoo(n)%jingest_sio2*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jingest_fe .gt. 0) & + used = send_data(zoo(n)%id_jingest_fe, zoo(n)%jingest_fe*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_ndet .gt. 0) & + used = send_data(zoo(n)%id_jprod_ndet, zoo(n)%jprod_ndet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_pdet .gt. 0) & + used = send_data(zoo(n)%id_jprod_pdet, zoo(n)%jprod_pdet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_ldon .gt. 0) & + used = send_data(zoo(n)%id_jprod_ldon, zoo(n)%jprod_ldon*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_ldop .gt. 0) & + used = send_data(zoo(n)%id_jprod_ldop, zoo(n)%jprod_ldop*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_sldon .gt. 0) & + used = send_data(zoo(n)%id_jprod_sldon, zoo(n)%jprod_sldon*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_sldop .gt. 0) & + used = send_data(zoo(n)%id_jprod_sldop, zoo(n)%jprod_sldop*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_srdon .gt. 0) & + used = send_data(zoo(n)%id_jprod_srdon, zoo(n)%jprod_srdon*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_srdop .gt. 0) & + used = send_data(zoo(n)%id_jprod_srdop, zoo(n)%jprod_srdop*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_fedet .gt. 0) & + used = send_data(zoo(n)%id_jprod_fedet, zoo(n)%jprod_fedet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_fed .gt. 0) & + used = send_data(zoo(n)%id_jprod_fed, zoo(n)%jprod_fed*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_sidet .gt. 0) & + used = send_data(zoo(n)%id_jprod_sidet, zoo(n)%jprod_sidet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_sio4 .gt. 0) & + used = send_data(zoo(n)%id_jprod_sio4, zoo(n)%jprod_sio4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_po4 .gt. 0) & + used = send_data(zoo(n)%id_jprod_po4, zoo(n)%jprod_po4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_nh4 .gt. 0) & + used = send_data(zoo(n)%id_jprod_nh4, zoo(n)%jprod_nh4*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_jprod_n .gt. 0) & + used = send_data(zoo(n)%id_jprod_n, zoo(n)%jprod_n*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (zoo(n)%id_temp_lim .gt. 0) & + used = send_data(zoo(n)%id_temp_lim, zoo(n)%temp_lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + enddo + ! + ! Production diagnostics + ! + if (cobalt%id_jprod_cadet_arag .gt. 0) & + used = send_data(cobalt%id_jprod_cadet_arag, cobalt%jprod_cadet_arag * rho_dzt, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jprod_cadet_calc .gt. 0) & + used = send_data(cobalt%id_jprod_cadet_calc, cobalt%jprod_cadet_calc * rho_dzt, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_ndet .gt. 0) & + ! used = send_data(cobalt%id_jprod_ndet, cobalt%jprod_ndet*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_pdet .gt. 0) & + ! used = send_data(cobalt%id_jprod_pdet, cobalt%jprod_pdet*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_srdon .gt. 0) & + ! used = send_data(cobalt%id_jprod_srdon, cobalt%jprod_srdon*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_sldon .gt. 0) & + ! used = send_data(cobalt%id_jprod_sldon, cobalt%jprod_sldon*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_ldon .gt. 0) & + ! used = send_data(cobalt%id_jprod_ldon, cobalt%jprod_ldon*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_srdop .gt. 0) & + ! used = send_data(cobalt%id_jprod_srdop, cobalt%jprod_srdop*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_sldop .gt. 0) & + ! used = send_data(cobalt%id_jprod_sldop, cobalt%jprod_sldop*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_ldop .gt. 0) & + ! used = send_data(cobalt%id_jprod_ldop, cobalt%jprod_ldop*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_nh4 .gt. 0) & + ! used = send_data(cobalt%id_jprod_nh4, cobalt%jprod_nh4*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_po4 .gt. 0) & + ! used = send_data(cobalt%id_jprod_po4, cobalt%jprod_po4*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_fedet .gt. 0) & + ! used = send_data(cobalt%id_jprod_fedet, cobalt%jprod_fedet*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_fed .gt. 0) & + ! used = send_data(cobalt%id_jprod_fed, cobalt%jprod_fed*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_sidet .gt. 0) & + ! used = send_data(cobalt%id_jprod_sidet, cobalt%jprod_sidet*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_jprod_sio4 .gt. 0) & + ! used = send_data(cobalt%id_jprod_sio4, cobalt%jprod_sio4*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jprod_lithdet .gt. 0) & + used = send_data(cobalt%id_jprod_lithdet, cobalt%jprod_lithdet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_det_jzloss_n .gt. 0) & + ! used = send_data(cobalt%id_det_jzloss_n, cobalt%det_jzloss_n*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + !if (cobalt%id_det_jhploss_n .gt. 0) & + ! used = send_data(cobalt%id_det_jhploss_n, cobalt%det_jhploss_n*rho_dzt, & + ! model_time, rmask = grid_tmask,& + ! is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jdiss_cadet_arag .gt. 0) & + used = send_data(cobalt%id_jdiss_cadet_arag, cobalt%jdiss_cadet_arag*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jdiss_cadet_calc .gt. 0) & + used = send_data(cobalt%id_jdiss_cadet_calc, cobalt%jdiss_cadet_calc*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jdiss_sidet .gt. 0) & + used = send_data(cobalt%id_jdiss_sidet, cobalt%jdiss_sidet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jremin_ndet .gt. 0) & + used = send_data(cobalt%id_jremin_ndet, cobalt%jremin_ndet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jremin_pdet .gt. 0) & + used = send_data(cobalt%id_jremin_pdet, cobalt%jremin_pdet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jremin_fedet .gt. 0) & + used = send_data(cobalt%id_jremin_fedet, cobalt%jremin_fedet*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jfe_ads .gt. 0) & + used = send_data(cobalt%id_jfe_ads, cobalt%jfe_ads*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jfe_coast .gt. 0) & + used = send_data(cobalt%id_jfe_coast, cobalt%jfe_coast*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_kfe_eq_lig .gt. 0) & + used = send_data(cobalt%id_kfe_eq_lig, log10(cobalt%kfe_eq_lig), & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_expkT .gt. 0) & + used = send_data(cobalt%id_expkT, cobalt%expkT, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_hp_temp_lim .gt. 0) & + used = send_data(cobalt%id_hp_temp_lim, cobalt%hp_temp_lim, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_irr_inst .gt. 0) & + used = send_data(cobalt%id_irr_inst, cobalt%irr_inst, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_irr_mix .gt. 0) & + used = send_data(cobalt%id_irr_mix, cobalt%irr_mix, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jno3denit_wc .gt. 0) & + used = send_data(cobalt%id_jno3denit_wc, cobalt%jno3denit_wc*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_jnitrif .gt. 0) & + used = send_data(cobalt%id_jnitrif, cobalt%jnitrif*rho_dzt, & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_tot_layer_int_c .gt. 0) & + used = send_data(cobalt%id_tot_layer_int_c, cobalt%tot_layer_int_c,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_tot_layer_int_fe .gt. 0) & + used = send_data(cobalt%id_tot_layer_int_fe,cobalt%tot_layer_int_fe,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_tot_layer_int_n .gt. 0) & + used = send_data(cobalt%id_tot_layer_int_n,cobalt%tot_layer_int_n,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_tot_layer_int_p .gt. 0) & + used = send_data(cobalt%id_tot_layer_int_p,cobalt%tot_layer_int_p,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_tot_layer_int_si .gt. 0) & + used = send_data(cobalt%id_tot_layer_int_si,cobalt%tot_layer_int_si,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_total_filter_feeding .gt. 0) & + used = send_data(cobalt%id_total_filter_feeding,cobalt%total_filter_feeding,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_net_prim_prod .gt. 0) & + used = send_data(cobalt%id_net_prim_prod,cobalt%net_prim_prod*rho_dzt,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_gross_prim_prod.gt. 0) & + used = send_data(cobalt%id_gross_prim_prod,cobalt%gross_prim_prod*rho_dzt,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_nlg_diatoms.gt. 0) & + used = send_data(cobalt%id_nlg_diatoms,cobalt%nlg_diatoms,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_q_si_2_n_lg_diatoms.gt. 0) & + used = send_data(cobalt%id_q_si_2_n_lg_diatoms,cobalt%q_si_2_n_lg_diatoms,& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_co2_csurf .gt. 0) & + used = send_data(cobalt%id_co2_csurf, cobalt%co2_csurf, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_pco2_csurf .gt. 0) & + used = send_data(cobalt%id_pco2_csurf, cobalt%pco2_csurf, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_co2_alpha .gt. 0) & + used = send_data(cobalt%id_co2_alpha, cobalt%co2_alpha, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fcadet_arag_btm .gt. 0) & + used = send_data(cobalt%id_fcadet_arag_btm, cobalt%fcadet_arag_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fcadet_calc_btm .gt. 0) & + used = send_data(cobalt%id_fcadet_calc_btm, cobalt%fcadet_calc_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_ffedet_btm .gt. 0) & + used = send_data(cobalt%id_ffedet_btm, cobalt%ffedet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fndet_btm .gt. 0) & + used = send_data(cobalt%id_fndet_btm, cobalt%fndet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fpdet_btm .gt. 0) & + used = send_data(cobalt%id_fpdet_btm, cobalt%fpdet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fsidet_btm .gt. 0) & + used = send_data(cobalt%id_fsidet_btm, cobalt%fsidet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_flithdet_btm .gt. 0) & + used = send_data(cobalt%id_flithdet_btm, cobalt%flithdet_btm, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fcased_burial .gt. 0) & + used = send_data(cobalt%id_fcased_burial, cobalt%fcased_burial, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fcased_input .gt. 0) & + used = send_data(cobalt%id_fcased_input, cobalt%fcased_input, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fcased_redis .gt. 0) & + used = send_data(cobalt%id_fcased_redis, cobalt%fcased_redis, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_ffe_sed .gt. 0) & + used = send_data(cobalt%id_ffe_sed, cobalt%ffe_sed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fnfeso4red_sed .gt. 0) & + used = send_data(cobalt%id_fnfeso4red_sed,cobalt%fnfeso4red_sed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fno3denit_sed .gt. 0) & + used = send_data(cobalt%id_fno3denit_sed, cobalt%fno3denit_sed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fnoxic_sed .gt. 0) & + used = send_data(cobalt%id_fnoxic_sed, cobalt%fnoxic_sed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_frac_burial .gt. 0) & + used = send_data(cobalt%id_frac_burial, cobalt%frac_burial, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fndet_burial .gt. 0) & + used = send_data(cobalt%id_fndet_burial, cobalt%fndet_burial, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_fpdet_burial .gt. 0) & + used = send_data(cobalt%id_fpdet_burial, cobalt%fpdet_burial, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_co3_sol_arag .gt. 0) & + used = send_data(cobalt%id_co3_sol_arag, cobalt%co3_sol_arag, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_co3_sol_calc .gt. 0) & + used = send_data(cobalt%id_co3_sol_calc, cobalt%co3_sol_calc, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_omega_arag .gt. 0) & + used = send_data(cobalt%id_omega_arag, cobalt%omega_arag, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_omega_calc .gt. 0) & + used = send_data(cobalt%id_omega_calc, cobalt%omega_calc, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_fcadet_arag .gt. 0) & + used = send_data(cobalt%id_fcadet_arag, cobalt%p_cadet_arag(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink * grid_tmask(:,:,:), & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_fcadet_calc .gt. 0) & + used = send_data(cobalt%id_fcadet_calc, cobalt%p_cadet_calc(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink*grid_tmask(:,:,:), & + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_ffedet .gt. 0) & + used = send_data(cobalt%id_ffedet, cobalt%p_fedet(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink * grid_tmask(:,:,:),& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_flithdet .gt. 0) & + used = send_data(cobalt%id_flithdet, cobalt%p_lithdet(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink * grid_tmask(:,:,:),& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_fndet .gt. 0) & + used = send_data(cobalt%id_fndet, cobalt%p_ndet(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink * grid_tmask(:,:,:),& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_fpdet .gt. 0) & + used = send_data(cobalt%id_fpdet, cobalt%p_pdet(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink * grid_tmask(:,:,:),& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_fsidet .gt. 0) & + used = send_data(cobalt%id_fsidet, cobalt%p_sidet(:,:,:,tau) * cobalt%Rho_0 * & + cobalt%wsink *grid_tmask(:,:,:),& + model_time, rmask = grid_tmask,& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (cobalt%id_nphyto_tot .gt. 0) & + used = send_data(cobalt%id_nphyto_tot, (cobalt%p_ndi(:,:,:,tau) + & + cobalt%p_nlg(:,:,:,tau) + cobalt%p_nsm(:,:,:,tau)), & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + ! + ! 2D COBALT fields + ! + if (cobalt%id_pco2surf .gt. 0) & + used = send_data(cobalt%id_pco2surf, cobalt%pco2_csurf, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_alk .gt. 0) & + used = send_data(cobalt%id_sfc_alk, cobalt%p_alk(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_cadet_arag .gt. 0) & + used = send_data(cobalt%id_sfc_cadet_arag,cobalt%p_cadet_arag(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_cadet_calc .gt. 0) & + used = send_data(cobalt%id_sfc_cadet_calc,cobalt%p_cadet_calc(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_dic .gt. 0) & + used = send_data(cobalt%id_sfc_dic, cobalt%p_dic(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_fed .gt. 0) & + used = send_data(cobalt%id_sfc_fed, cobalt%p_fed(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_ldon .gt. 0) & + used = send_data(cobalt%id_sfc_ldon, cobalt%p_ldon(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_sldon .gt. 0) & + used = send_data(cobalt%id_sfc_sldon, cobalt%p_sldon(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_srdon .gt. 0) & + used = send_data(cobalt%id_sfc_srdon, cobalt%p_srdon(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_no3 .gt. 0) & + used = send_data(cobalt%id_sfc_no3, cobalt%p_no3(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_nh4 .gt. 0) & + used = send_data(cobalt%id_sfc_nh4, cobalt%p_nh4(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_po4 .gt. 0) & + used = send_data(cobalt%id_sfc_po4, cobalt%p_po4(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_sio4 .gt. 0) & + used = send_data(cobalt%id_sfc_sio4, cobalt%p_sio4(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_htotal .gt. 0) & + used = send_data(cobalt%id_sfc_htotal, cobalt%f_htotal(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_o2 .gt. 0) & + used = send_data(cobalt%id_sfc_o2, cobalt%p_o2(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_chl .gt. 0) & + used = send_data(cobalt%id_sfc_chl, cobalt%f_chl(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_irr .gt. 0) & + used = send_data(cobalt%id_sfc_irr, cobalt%irr_inst(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_irr_mem .gt. 0) & + used = send_data(cobalt%id_sfc_irr_mem, cobalt%f_irr_mem(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_temp .gt. 0) & + used = send_data(cobalt%id_sfc_temp, Temp(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_temp .gt. 0) & + used = send_data(cobalt%id_btm_temp, cobalt%btm_temp, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_btm_o2 .gt. 0) & + used = send_data(cobalt%id_btm_o2, cobalt%btm_o2, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_co3_ion .gt. 0) & + used = send_data(cobalt%id_sfc_co3_ion, cobalt%f_co3_ion(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_co3_sol_arag .gt. 0) & + used = send_data(cobalt%id_sfc_co3_sol_arag, cobalt%co3_sol_arag(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (cobalt%id_sfc_co3_sol_calc .gt. 0) & + used = send_data(cobalt%id_sfc_co3_sol_calc, cobalt%co3_sol_calc(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + do n= 1, NUM_PHYTO + if (phyto(n)%id_sfc_f_n .gt. 0) & + used = send_data(phyto(n)%id_sfc_f_n, phyto(n)%f_n(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_chl .gt. 0) & + used = send_data(phyto(n)%id_sfc_chl, cobalt%c_2_n * 12.0e6 * & + phyto(n)%theta(:,:,1) * phyto(n)%f_n(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_def_fe .gt. 0) & + used = send_data(phyto(n)%id_sfc_def_fe, phyto(n)%def_fe(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_felim .gt. 0) & + used = send_data(phyto(n)%id_sfc_felim, phyto(n)%felim(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_irrlim .gt. 0) & + used = send_data(phyto(n)%id_sfc_irrlim, phyto(n)%irrlim(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_theta .gt. 0) & + used = send_data(phyto(n)%id_sfc_theta, phyto(n)%theta(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_mu .gt. 0) & + used = send_data(phyto(n)%id_sfc_mu, phyto(n)%mu(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_po4lim .gt. 0) & + used = send_data(phyto(n)%id_sfc_po4lim, phyto(n)%po4lim(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_q_fe_2_n .gt. 0) & + used = send_data(phyto(n)%id_sfc_q_fe_2_n, phyto(n)%q_fe_2_n(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + enddo + + do n= 2,3 + if (phyto(n)%id_sfc_nh4lim .gt. 0) & + used = send_data(phyto(n)%id_sfc_nh4lim, phyto(n)%nh4lim(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_sfc_no3lim .gt. 0) & + used = send_data(phyto(n)%id_sfc_no3lim, phyto(n)%no3lim(:,:,1), & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + enddo + + + ! + ! Save river, depositon and bulk elemental fluxes + ! + if (cobalt%id_dep_dry_fed .gt. 0) & + used = send_data(cobalt%id_dep_dry_fed, cobalt%dry_fed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_dry_lith .gt. 0) & + used = send_data(cobalt%id_dep_dry_lith, cobalt%dry_lith, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_dry_nh4 .gt. 0) & + used = send_data(cobalt%id_dep_dry_nh4, cobalt%dry_nh4, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_dry_no3 .gt. 0) & + used = send_data(cobalt%id_dep_dry_no3, cobalt%dry_no3, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_dry_po4 .gt. 0) & + used = send_data(cobalt%id_dep_dry_po4, cobalt%dry_po4, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_wet_fed .gt. 0) & + used = send_data(cobalt%id_dep_wet_fed, cobalt%wet_fed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_wet_lith .gt. 0) & + used = send_data(cobalt%id_dep_wet_lith, cobalt%wet_lith, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_wet_nh4 .gt. 0) & + used = send_data(cobalt%id_dep_wet_nh4, cobalt%wet_nh4, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_wet_no3 .gt. 0) & + used = send_data(cobalt%id_dep_wet_no3, cobalt%wet_no3, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_dep_wet_po4 .gt. 0) & + used = send_data(cobalt%id_dep_wet_po4, cobalt%wet_po4, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_alk .gt. 0) & + used = send_data(cobalt%id_runoff_flux_alk, cobalt%runoff_flux_alk, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_dic .gt. 0) & + used = send_data(cobalt%id_runoff_flux_dic, cobalt%runoff_flux_dic, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_fed .gt. 0) & + used = send_data(cobalt%id_runoff_flux_fed, cobalt%runoff_flux_fed, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_lith .gt. 0) & + used = send_data(cobalt%id_runoff_flux_lith, cobalt%runoff_flux_lith, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_no3 .gt. 0) & + used = send_data(cobalt%id_runoff_flux_no3, cobalt%runoff_flux_no3, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_ldon .gt. 0) & + used = send_data(cobalt%id_runoff_flux_ldon, cobalt%runoff_flux_ldon, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_sldon .gt. 0) & + used = send_data(cobalt%id_runoff_flux_sldon, cobalt%runoff_flux_sldon, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_srdon .gt. 0) & + used = send_data(cobalt%id_runoff_flux_srdon, cobalt%runoff_flux_srdon, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_ndet .gt. 0) & + used = send_data(cobalt%id_runoff_flux_ndet, cobalt%runoff_flux_ndet, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_po4 .gt. 0) & + used = send_data(cobalt%id_runoff_flux_po4, cobalt%runoff_flux_po4, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_ldop .gt. 0) & + used = send_data(cobalt%id_runoff_flux_ldop, cobalt%runoff_flux_ldop, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_sldop .gt. 0) & + used = send_data(cobalt%id_runoff_flux_sldop, cobalt%runoff_flux_sldop, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_runoff_flux_srdop .gt. 0) & + used = send_data(cobalt%id_runoff_flux_srdop, cobalt%runoff_flux_srdop, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + ! + ! Save 100m integral fluxes + ! + if (cobalt%id_jprod_allphytos_100 .gt. 0) & + used = send_data(cobalt%id_jprod_allphytos_100, cobalt%jprod_allphytos_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + do n= 1, NUM_PHYTO !{ + if (phyto(n)%id_jprod_n_100 .gt. 0) & + used = send_data(phyto(n)%id_jprod_n_100, phyto(n)%jprod_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_jprod_n_new_100 .gt. 0) & + used = send_data(phyto(n)%id_jprod_n_new_100, phyto(n)%jprod_n_new_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_jzloss_n_100 .gt. 0) & + used = send_data(phyto(n)%id_jzloss_n_100, phyto(n)%jzloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_jexuloss_n_100 .gt. 0) & + used = send_data(phyto(n)%id_jexuloss_n_100, phyto(n)%jexuloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(n)%id_f_n_100 .gt. 0) & + used = send_data(phyto(n)%id_f_n_100, phyto(n)%f_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + enddo !} n + if (phyto(DIAZO)%id_jprod_n_n2_100 .gt. 0) & + used = send_data(phyto(DIAZO)%id_jprod_n_n2_100, phyto(DIAZO)%jprod_n_n2_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(SMALL)%id_jvirloss_n_100 .gt. 0) & + used = send_data(phyto(SMALL)%id_jvirloss_n_100, phyto(SMALL)%jvirloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(SMALL)%id_jaggloss_n_100 .gt. 0) & + used = send_data(phyto(SMALL)%id_jaggloss_n_100, phyto(SMALL)%jaggloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (phyto(LARGE)%id_jaggloss_n_100 .gt. 0) & + used = send_data(phyto(LARGE)%id_jaggloss_n_100, phyto(LARGE)%jaggloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + do n= 1, NUM_ZOO !{ + if (zoo(n)%id_jprod_n_100 .gt. 0) & + used = send_data(zoo(n)%id_jprod_n_100, zoo(n)%jprod_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (zoo(n)%id_jingest_n_100 .gt. 0) & + used = send_data(zoo(n)%id_jingest_n_100, zoo(n)%jingest_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (zoo(n)%id_jremin_n_100 .gt. 0) & + used = send_data(zoo(n)%id_jremin_n_100, zoo(n)%jremin_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (zoo(n)%id_f_n_100 .gt. 0) & + used = send_data(zoo(n)%id_f_n_100, zoo(n)%f_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + enddo !} n + + do n= 1,2 !{ + if (zoo(n)%id_jzloss_n_100 .gt. 0) & + used = send_data(zoo(n)%id_jzloss_n_100, zoo(n)%jzloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (zoo(n)%id_jprod_don_100 .gt. 0) & + used = send_data(zoo(n)%id_jprod_don_100, zoo(n)%jprod_don_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + enddo !} n + + do n= 2,3 !{ + if (zoo(n)%id_jhploss_n_100 .gt. 0) & + used = send_data(zoo(n)%id_jhploss_n_100, zoo(n)%jhploss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (zoo(n)%id_jprod_ndet_100 .gt. 0) & + used = send_data(zoo(n)%id_jprod_ndet_100, zoo(n)%jprod_ndet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + enddo !} n + + if (cobalt%id_hp_jingest_n_100 .gt. 0) & + used = send_data(cobalt%id_hp_jingest_n_100, cobalt%hp_jingest_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_hp_jremin_n_100 .gt. 0) & + used = send_data(cobalt%id_hp_jremin_n_100, cobalt%hp_jremin_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_hp_jprod_ndet_100 .gt. 0) & + used = send_data(cobalt%id_hp_jprod_ndet_100, cobalt%hp_jprod_ndet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (bact(1)%id_jprod_n_100 .gt. 0) & + used = send_data(bact(1)%id_jprod_n_100, bact(1)%jprod_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (bact(1)%id_jzloss_n_100 .gt. 0) & + used = send_data(bact(1)%id_jzloss_n_100, bact(1)%jzloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (bact(1)%id_jvirloss_n_100 .gt. 0) & + used = send_data(bact(1)%id_jvirloss_n_100, bact(1)%jvirloss_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (bact(1)%id_jremin_n_100 .gt. 0) & + used = send_data(bact(1)%id_jremin_n_100, bact(1)%jremin_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (bact(1)%id_juptake_ldon_100 .gt. 0) & + used = send_data(bact(1)%id_juptake_ldon_100, bact(1)%juptake_ldon_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (bact(1)%id_f_n_100 .gt. 0) & + used = send_data(bact(1)%id_f_n_100, bact(1)%f_n_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (cobalt%id_jprod_lithdet_100 .gt. 0) & + used = send_data(cobalt%id_jprod_lithdet_100, cobalt%jprod_lithdet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_jprod_sidet_100 .gt. 0) & + used = send_data(cobalt%id_jprod_sidet_100, cobalt%jprod_sidet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_jprod_cadet_calc_100 .gt. 0) & + used = send_data(cobalt%id_jprod_cadet_calc_100, cobalt%jprod_cadet_calc_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_jprod_cadet_arag_100 .gt. 0) & + used = send_data(cobalt%id_jprod_cadet_arag_100, cobalt%jprod_cadet_arag_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_jremin_ndet_100 .gt. 0) & + used = send_data(cobalt%id_jremin_ndet_100, cobalt%jremin_ndet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_jprod_mesozoo_200 .gt. 0) & + used = send_data(cobalt%id_jprod_mesozoo_200, cobalt%jprod_mesozoo_200, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (cobalt%id_f_ndet_100 .gt. 0) & + used = send_data(cobalt%id_f_ndet_100, cobalt%f_ndet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_f_don_100 .gt. 0) & + used = send_data(cobalt%id_f_don_100, cobalt%f_don_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_f_silg_100 .gt. 0) & + used = send_data(cobalt%id_f_silg_100, cobalt%f_silg_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_f_mesozoo_200 .gt. 0) & + used = send_data(cobalt%id_f_mesozoo_200, cobalt%f_mesozoo_200, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + if (cobalt%id_fndet_100 .gt. 0) & + used = send_data(cobalt%id_fndet_100, cobalt%fndet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fpdet_100 .gt. 0) & + used = send_data(cobalt%id_fpdet_100, cobalt%fpdet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fsidet_100 .gt. 0) & + used = send_data(cobalt%id_fsidet_100, cobalt%fsidet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_flithdet_100 .gt. 0) & + used = send_data(cobalt%id_flithdet_100, cobalt%flithdet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fcadet_calc_100 .gt. 0) & + used = send_data(cobalt%id_fcadet_calc_100, cobalt%fcadet_calc_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_fcadet_arag_100 .gt. 0) & + used = send_data(cobalt%id_fcadet_arag_100, cobalt%fcadet_arag_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_ffedet_100 .gt. 0) & + used = send_data(cobalt%id_ffedet_100, cobalt%ffedet_100, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + ! + !--------------------------------------------------------------------- + ! Save CaCO3 saturation and O2 minimum depths + !--------------------------------------------------------------------- + ! + if (cobalt%id_o2min .gt. 0) & + used = send_data(cobalt%id_o2min, cobalt%o2min, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_z_o2min .gt. 0) & + used = send_data(cobalt%id_z_o2min, cobalt%z_o2min, & + model_time, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_z_sat_arag .gt. 0) & + used = send_data(cobalt%id_z_sat_arag, cobalt%z_sat_arag, & + model_time, mask = cobalt%mask_z_sat_arag, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + if (cobalt%id_z_sat_calc .gt. 0) & + used = send_data(cobalt%id_z_sat_calc, cobalt%z_sat_calc, & + model_time, mask = cobalt%mask_z_sat_calc, rmask = grid_tmask(:,:,1),& + is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + + call mpp_clock_end(id_clock_cobalt_send_diagnostics) + + end subroutine generic_COBALT_update_from_source + + ! + ! + ! Calculate and set coupler values at the surface / bottom + ! + ! + ! + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + ! Lower bounds of x and y extents of input arrays on data domain + ! + ! + ! Sea Surface Temperature + ! + ! + ! Sea Surface Salinity + ! + ! + ! Ocean density + ! + ! + ! Time step index of %field + ! + ! + + !User must provide the calculations for these boundary values. + subroutine generic_COBALT_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau) + type(g_tracer_type), pointer :: tracer_list + real, dimension(ilb:,jlb:), intent(in) :: SST, SSS + real, dimension(ilb:,jlb:,:,:), intent(in) :: rho + integer, intent(in) :: ilb,jlb,tau + + integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau , i, j + real :: sal,ST,o2_saturation + real :: tt,tk,ts,ts2,ts3,ts4,ts5 + real, dimension(:,:,:) ,pointer :: grid_tmask + real, dimension(:,:,:,:), pointer :: o2_field,dic_field,po4_field,sio4_field,alk_field + real, dimension(:,:,:), ALLOCATABLE :: htotal_field,co3_ion_field + real, dimension(:,:), ALLOCATABLE :: co2_alpha,co2_csurf,co2_sc_no,o2_alpha,o2_csurf,o2_sc_no + character(len=fm_string_len), parameter :: sub_name = 'generic_COBALT_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) + + call g_tracer_get_pointer(tracer_list,'o2' ,'field', o2_field) + + allocate(co2_alpha(isd:ied, jsd:jed)); co2_alpha=0.0 + allocate(co2_csurf(isd:ied, jsd:jed)); co2_csurf=0.0 + allocate(co2_sc_no(isd:ied, jsd:jed)); co2_sc_no=0.0 + allocate( o2_alpha(isd:ied, jsd:jed)); o2_alpha=0.0 + allocate( o2_csurf(isd:ied, jsd:jed)); o2_csurf=0.0 + allocate( o2_sc_no(isd:ied, jsd:jed)); o2_sc_no=0.0 + allocate(htotal_field(isd:ied,jsd:jed,nk),co3_ion_field(isd:ied,jsd:jed,nk)) + htotal_field=0.0 ; co3_ion_field=0.0 + + !nnz: Since the generic_COBALT_update_from_source() subroutine is called by this time + ! the following if block is not really necessary (since this calculation is already done in source). + ! It is only neccessary if source routine is commented out for debugging. + !Note: In order for this to work we should NOT zero out the coupler values for generic tracers + ! This zeroing is done for non-generic TOPAZ by calling zero_ocean_sfc. + ! Since the coupler values here are non-cumulative there is no need to zero them out anyway. + + if (cobalt%init ) then + !Get necessary fields + call g_tracer_get_pointer(tracer_list,'dic' ,'field', dic_field) + call g_tracer_get_pointer(tracer_list,'po4' ,'field', po4_field) + call g_tracer_get_pointer(tracer_list,'sio4' ,'field', sio4_field) + call g_tracer_get_pointer(tracer_list,'alk' ,'field', alk_field) + + call g_tracer_get_values(tracer_list,'htotal' ,'field', htotal_field,isd,jsd,ntau=1) + call g_tracer_get_values(tracer_list,'co3_ion','field',co3_ion_field,isd,jsd,ntau=1) + + do j = jsc, jec ; do i = isc, iec !{ + cobalt%htotallo(i,j) = cobalt%htotal_scale_lo * htotal_field(i,j,1) + cobalt%htotalhi(i,j) = cobalt%htotal_scale_hi * htotal_field(i,j,1) + enddo; enddo ; !} i, j + + call FMS_ocmip2_co2calc(CO2_dope_vec,grid_tmask(:,:,1), & + SST(:,:), SSS(:,:), & + dic_field(:,:,1,tau), & + po4_field(:,:,1,tau), & + sio4_field(:,:,1,tau), & + alk_field(:,:,1,tau), & + cobalt%htotallo, cobalt%htotalhi, & + !InOut + htotal_field(:,:,1), & + !OUT + co2star=co2_csurf(:,:), alpha=co2_alpha(:,:), & + pCO2surf=cobalt%pco2_csurf(:,:), & + co3_ion=co3_ion_field(:,:,1)) + + !Set fields !nnz: if These are pointers do I need to do this? + call g_tracer_set_values(tracer_list,'htotal' ,'field',htotal_field ,isd,jsd,ntau=1) + call g_tracer_set_values(tracer_list,'co3_ion','field',co3_ion_field,isd,jsd,ntau=1) + + call g_tracer_set_values(tracer_list,'dic','alpha',co2_alpha ,isd,jsd) + call g_tracer_set_values(tracer_list,'dic','csurf',co2_csurf ,isd,jsd) + + !!nnz: If source is called uncomment the following + cobalt%init = .false. !nnz: This is necessary since the above two calls appear in source subroutine too. + endif + + call g_tracer_get_values(tracer_list,'dic','alpha', co2_alpha ,isd,jsd) + call g_tracer_get_values(tracer_list,'dic','csurf', co2_csurf ,isd,jsd) + + call g_tracer_get_values(tracer_list,'o2','alpha', o2_alpha ,isd,jsd) + call g_tracer_get_values(tracer_list,'o2','csurf', o2_csurf ,isd,jsd) + do j=jsc,jec ; do i=isc,iec + !This calculation needs an input of SST and SSS + sal = SSS(i,j) ; ST = SST(i,j) + + !nnz: + !Note: In the following calculations in order to get results for co2 and o2 + ! identical with cobalt code in MOM cobalt%Rho_0 must be replaced with rho(i,j,1,tau) + ! This is achieved by uncommenting the following if desired. + !! cobalt%Rho_0 = rho(i,j,1,tau) + ! But since %Rho_0 plays the role of a unit conversion factor in this module + ! it may be safer to keep it as a constant (1035.0) rather than the actual variable + ! surface density rho(i,j,1,tau) + + !--------------------------------------------------------------------- + ! CO2 + !--------------------------------------------------------------------- + + !--------------------------------------------------------------------- + ! Compute the Schmidt number of CO2 in seawater using the + ! formulation presented by Wanninkhof (1992, J. Geophys. Res., 97, + ! 7373-7382). + !--------------------------------------------------------------------- + co2_sc_no(i,j) = cobalt%a1_co2 + ST * (cobalt%a2_co2 + ST * (cobalt%a3_co2 + ST * cobalt%a4_co2)) * & + grid_tmask(i,j,1) +! sc_no_term = sqrt(660.0 / (sc_co2 + epsln)) +! +! co2_alpha(i,j) = co2_alpha(i,j)* sc_no_term * cobalt%Rho_0 !nnz: MOM has rho(i,j,1,tau) +! co2_csurf(i,j) = co2_csurf(i,j)* sc_no_term * cobalt%Rho_0 !nnz: MOM has rho(i,j,1,tau) +! +! in 'ocmip2_new' atmos_ocean_fluxes.F90 coupler formulation, the schmidt number is carried in explicitly +! + co2_alpha(i,j) = co2_alpha(i,j) * cobalt%Rho_0 !nnz: MOM has rho(i,j,1,tau) + co2_csurf(i,j) = co2_csurf(i,j) * cobalt%Rho_0 !nnz: MOM has rho(i,j,1,tau) + + !--------------------------------------------------------------------- + ! O2 + !--------------------------------------------------------------------- + ! Compute the oxygen saturation concentration at 1 atm total + ! pressure in mol/kg given the temperature (t, in deg C) and + ! the salinity (s, in permil) + ! + ! From Garcia and Gosrdon (1992), Limnology and Oceonography. + ! The formula used is from page 1310, eq (8). + ! + ! *** Note: the "a3*ts^2" term (in the paper) is incorrect. *** + ! *** It shouldn't be there. *** + ! + ! o2_saturation is defined between T(freezing) <= T <= 40 deg C and + ! 0 permil <= S <= 42 permil + ! + ! check value: T = 10 deg C, S = 35 permil, + ! o2_saturation = 0.282015 mol m-3 + !--------------------------------------------------------------------- + ! + tt = 298.15 - ST + tk = 273.15 + ST + ts = log(tt / tk) + ts2 = ts * ts + ts3 = ts2 * ts + ts4 = ts3 * ts + ts5 = ts4 * ts + + o2_saturation = (1000.0/22391.6) * grid_tmask(i,j,1) * & !convert from ml/l to mol m-3 + exp( cobalt%a_0 + cobalt%a_1*ts + cobalt%a_2*ts2 + cobalt%a_3*ts3 + cobalt%a_4*ts4 + cobalt%a_5*ts5 + & + (cobalt%b_0 + cobalt%b_1*ts + cobalt%b_2*ts2 + cobalt%b_3*ts3 + cobalt%c_0*sal)*sal) + + !--------------------------------------------------------------------- + ! Compute the Schmidt number of O2 in seawater using the + ! formulation proposed by Keeling et al. (1998, Global Biogeochem. + ! Cycles, 12, 141-163). + !--------------------------------------------------------------------- + ! + ! In 'ocmip2_generic' atmos_ocean_fluxes.F90 coupler formulation, + ! the schmidt number is carried in explicitly + ! + o2_sc_no(i,j) = cobalt%a1_o2 + ST * (cobalt%a2_o2 + ST * (cobalt%a3_o2 + ST * cobalt%a4_o2 )) * & + grid_tmask(i,j,1) + ! + ! renormalize the alpha value for atm o2 + ! data table override for o2_flux_pcair_atm is now set to 0.21 + ! + o2_alpha(i,j) = (o2_saturation / 0.21) + o2_csurf(i,j) = o2_field(i,j,1,tau) * cobalt%Rho_0 !nnz: MOM has rho(i,j,1,tau) + + + enddo; enddo + + ! + ! Set %csurf, %alpha and %sc_no for these tracers. This will mark them + ! for sending fluxes to coupler + ! + call g_tracer_set_values(tracer_list,'dic','alpha',co2_alpha,isd,jsd) + call g_tracer_set_values(tracer_list,'dic','csurf',co2_csurf,isd,jsd) + call g_tracer_set_values(tracer_list,'dic','sc_no',co2_sc_no,isd,jsd) + + call g_tracer_set_values(tracer_list,'o2', 'alpha',o2_alpha, isd,jsd) + call g_tracer_set_values(tracer_list,'o2', 'csurf',o2_csurf, isd,jsd) + call g_tracer_set_values(tracer_list,'o2', 'sc_no',o2_sc_no, isd,jsd) + + deallocate(co2_alpha,co2_csurf,co2_sc_no,o2_alpha,o2_csurf,o2_sc_no) + + end subroutine generic_COBALT_set_boundary_values + + + ! + ! + ! End the module. + ! + ! + ! Deallocate all work arrays + ! + ! + ! + + + subroutine generic_COBALT_end + character(len=fm_string_len), parameter :: sub_name = 'generic_COBALT_end' + call user_deallocate_arrays + end subroutine generic_COBALT_end + + ! + ! This is an internal sub, not a public interface. + ! Allocate all the work arrays to be used in this module. + ! + subroutine user_allocate_arrays + integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,n + + call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau) + + !Allocate all the private arrays. + + !Used in ocmip2_co2calc + CO2_dope_vec%isc = isc ; CO2_dope_vec%iec = iec + CO2_dope_vec%jsc = jsc ; CO2_dope_vec%jec = jec + CO2_dope_vec%isd = isd ; CO2_dope_vec%ied = ied + CO2_dope_vec%jsd = jsd ; CO2_dope_vec%jed = jed + + allocate(cobalt%htotallo(isd:ied,jsd:jed)) + allocate(cobalt%htotalhi(isd:ied,jsd:jed)) + + ! + ! allocate and initialize array elements of all phytoplankton groups + ! CAS: add fluxes for additional explicit phytoplankton loss terms + + do n = 1, NUM_PHYTO + allocate(phyto(n)%def_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%def_fe = 0.0 + allocate(phyto(n)%def_p(isd:ied,jsd:jed,nk)) ; phyto(n)%def_p = 0.0 + allocate(phyto(n)%f_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%f_fe = 0.0 + allocate(phyto(n)%f_n(isd:ied,jsd:jed,nk)) ; phyto(n)%f_n = 0.0 + allocate(phyto(n)%felim(isd:ied,jsd:jed,nk)) ; phyto(n)%felim = 0.0 + allocate(phyto(n)%irrlim(isd:ied,jsd:jed,nk)) ; phyto(n)%irrlim = 0.0 + allocate(phyto(n)%jzloss_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%jzloss_fe = 0.0 + allocate(phyto(n)%jzloss_n(isd:ied,jsd:jed,nk)) ; phyto(n)%jzloss_n = 0.0 + allocate(phyto(n)%jzloss_p(isd:ied,jsd:jed,nk)) ; phyto(n)%jzloss_p = 0.0 + allocate(phyto(n)%jzloss_sio2(isd:ied,jsd:jed,nk)) ; phyto(n)%jzloss_sio2 = 0.0 + allocate(phyto(n)%jaggloss_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%jaggloss_fe = 0.0 + allocate(phyto(n)%jaggloss_n(isd:ied,jsd:jed,nk)) ; phyto(n)%jaggloss_n = 0.0 + allocate(phyto(n)%jaggloss_p(isd:ied,jsd:jed,nk)) ; phyto(n)%jaggloss_p = 0.0 + allocate(phyto(n)%jaggloss_sio2(isd:ied,jsd:jed,nk)); phyto(n)%jaggloss_sio2 = 0.0 + allocate(phyto(n)%jvirloss_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%jvirloss_fe = 0.0 + allocate(phyto(n)%jvirloss_n(isd:ied,jsd:jed,nk)) ; phyto(n)%jvirloss_n = 0.0 + allocate(phyto(n)%jvirloss_p(isd:ied,jsd:jed,nk)) ; phyto(n)%jvirloss_p = 0.0 + allocate(phyto(n)%jvirloss_sio2(isd:ied,jsd:jed,nk)); phyto(n)%jvirloss_sio2 = 0.0 + allocate(phyto(n)%jexuloss_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%jexuloss_fe = 0.0 + allocate(phyto(n)%jexuloss_n(isd:ied,jsd:jed,nk)) ; phyto(n)%jexuloss_n = 0.0 + allocate(phyto(n)%jexuloss_p(isd:ied,jsd:jed,nk)) ; phyto(n)%jexuloss_p = 0.0 + allocate(phyto(n)%jhploss_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%jhploss_fe = 0.0 + allocate(phyto(n)%jhploss_n(isd:ied,jsd:jed,nk)) ; phyto(n)%jhploss_n = 0.0 + allocate(phyto(n)%jhploss_p(isd:ied,jsd:jed,nk)) ; phyto(n)%jhploss_p = 0.0 + allocate(phyto(n)%jhploss_sio2(isd:ied,jsd:jed,nk)) ; phyto(n)%jhploss_sio2 = 0.0 + allocate(phyto(n)%juptake_fe(isd:ied,jsd:jed,nk)) ; phyto(n)%juptake_fe = 0.0 + allocate(phyto(n)%juptake_nh4(isd:ied,jsd:jed,nk)) ; phyto(n)%juptake_nh4 = 0.0 + allocate(phyto(n)%juptake_no3(isd:ied,jsd:jed,nk)) ; phyto(n)%juptake_no3 = 0.0 + allocate(phyto(n)%juptake_po4(isd:ied,jsd:jed,nk)) ; phyto(n)%juptake_po4 = 0.0 + allocate(phyto(n)%jprod_n(isd:ied,jsd:jed,nk)) ; phyto(n)%jprod_n = 0.0 + allocate(phyto(n)%liebig_lim(isd:ied,jsd:jed,nk)) ; phyto(n)%liebig_lim = 0.0 + allocate(phyto(n)%mu(isd:ied,jsd:jed,nk)) ; phyto(n)%mu = 0.0 + allocate(phyto(n)%po4lim(isd:ied,jsd:jed,nk)) ; phyto(n)%po4lim = 0.0 + allocate(phyto(n)%q_fe_2_n(isd:ied,jsd:jed,nk)) ; phyto(n)%q_fe_2_n = 0.0 + allocate(phyto(n)%q_p_2_n(isd:ied,jsd:jed,nk)) ; phyto(n)%q_p_2_n = 0.0 + allocate(phyto(n)%q_si_2_n(isd:ied,jsd:jed,nk)) ; phyto(n)%q_si_2_n = 0.0 + allocate(phyto(n)%theta(isd:ied,jsd:jed,nk)) ; phyto(n)%theta = 0.0 + enddo + ! + ! allocate and initialize array elements of only some phytoplankton groups + ! + do n = 2, NUM_PHYTO + allocate(phyto(n)%nh4lim(isd:ied,jsd:jed,nk)) ; phyto(n)%nh4lim = 0.0 + allocate(phyto(n)%no3lim(isd:ied,jsd:jed,nk)) ; phyto(n)%no3lim = 0.0 + enddo + ! + ! allocate and initialize array elements of only one phytoplankton group + ! + allocate(phyto(DIAZO)%juptake_n2(isd:ied,jsd:jed,nk)) ; phyto(DIAZO)%juptake_n2 = 0.0 + allocate(phyto(DIAZO)%o2lim(isd:ied,jsd:jed,nk)) ; phyto(DIAZO)%o2lim = 0.0 + allocate(phyto(LARGE)%juptake_sio4(isd:ied,jsd:jed,nk)) ; phyto(LARGE)%juptake_sio4 = 0.0 + allocate(phyto(LARGE)%silim(isd:ied,jsd:jed,nk)) ; phyto(LARGE)%silim = 0.0 + ! + ! allocate and initialize arrays for bacteria + ! + allocate(bact(1)%f_n(isd:ied,jsd:jed,nk)) ; bact(1)%f_n = 0.0 + allocate(bact(1)%jzloss_n(isd:ied,jsd:jed,nk)) ; bact(1)%jzloss_n = 0.0 + allocate(bact(1)%jzloss_p(isd:ied,jsd:jed,nk)) ; bact(1)%jzloss_p = 0.0 + allocate(bact(1)%jvirloss_n(isd:ied,jsd:jed,nk)) ; bact(1)%jvirloss_n = 0.0 + allocate(bact(1)%jvirloss_p(isd:ied,jsd:jed,nk)) ; bact(1)%jvirloss_p = 0.0 + allocate(bact(1)%jhploss_n(isd:ied,jsd:jed,nk)) ; bact(1)%jhploss_n = 0.0 + allocate(bact(1)%jhploss_p(isd:ied,jsd:jed,nk)) ; bact(1)%jhploss_p = 0.0 + allocate(bact(1)%juptake_ldon(isd:ied,jsd:jed,nk)) ; bact(1)%juptake_ldon = 0.0 + allocate(bact(1)%juptake_ldop(isd:ied,jsd:jed,nk)) ; bact(1)%juptake_ldop = 0.0 + allocate(bact(1)%jprod_nh4(isd:ied,jsd:jed,nk)) ; bact(1)%jprod_nh4 = 0.0 + allocate(bact(1)%jprod_po4(isd:ied,jsd:jed,nk)) ; bact(1)%jprod_po4 = 0.0 + allocate(bact(1)%jprod_n(isd:ied,jsd:jed,nk)) ; bact(1)%jprod_n = 0.0 + allocate(bact(1)%temp_lim(isd:ied,jsd:jed,nk)) ; bact(1)%temp_lim = 0.0 + ! + ! CAS: allocate and initialize array elements for all zooplankton groups + ! + do n = 1, NUM_ZOO + allocate(zoo(n)%f_n(isd:ied,jsd:jed,nk)) ; zoo(n)%f_n = 0.0 + allocate(zoo(n)%jzloss_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jzloss_n = 0.0 + allocate(zoo(n)%jzloss_p(isd:ied,jsd:jed,nk)) ; zoo(n)%jzloss_p = 0.0 + allocate(zoo(n)%jhploss_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jhploss_n = 0.0 + allocate(zoo(n)%jhploss_p(isd:ied,jsd:jed,nk)) ; zoo(n)%jhploss_p = 0.0 + allocate(zoo(n)%jingest_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jingest_n = 0.0 + allocate(zoo(n)%jingest_p(isd:ied,jsd:jed,nk)) ; zoo(n)%jingest_p = 0.0 + allocate(zoo(n)%jingest_sio2(isd:ied,jsd:jed,nk)) ; zoo(n)%jingest_sio2 = 0.0 + allocate(zoo(n)%jingest_fe(isd:ied,jsd:jed,nk)) ; zoo(n)%jingest_fe = 0.0 + allocate(zoo(n)%jprod_ndet(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_ndet = 0.0 + allocate(zoo(n)%jprod_pdet(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_pdet = 0.0 + allocate(zoo(n)%jprod_ldon(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_ldon = 0.0 + allocate(zoo(n)%jprod_ldop(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_ldop = 0.0 + allocate(zoo(n)%jprod_srdon(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_srdon = 0.0 + allocate(zoo(n)%jprod_srdop(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_srdop = 0.0 + allocate(zoo(n)%jprod_sldon(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_sldon = 0.0 + allocate(zoo(n)%jprod_sldop(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_sldop = 0.0 + allocate(zoo(n)%jprod_fedet(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_fedet = 0.0 + allocate(zoo(n)%jprod_fed(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_fed = 0.0 + allocate(zoo(n)%jprod_sidet(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_sidet = 0.0 + allocate(zoo(n)%jprod_sio4(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_sio4 = 0.0 + allocate(zoo(n)%jprod_po4(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_po4 = 0.0 + allocate(zoo(n)%jprod_nh4(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_nh4 = 0.0 + allocate(zoo(n)%jprod_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jprod_n = 0.0 + allocate(zoo(n)%temp_lim(isd:ied,jsd:jed,nk)) ; zoo(n)%temp_lim = 0.0 + enddo + + ! higher predator ingestion + allocate(cobalt%hp_jingest_n(isd:ied,jsd:jed,nk)) ; cobalt%hp_jingest_n = 0.0 + allocate(cobalt%hp_jingest_p(isd:ied,jsd:jed,nk)) ; cobalt%hp_jingest_p = 0.0 + allocate(cobalt%hp_jingest_sio2(isd:ied,jsd:jed,nk)) ; cobalt%hp_jingest_sio2 = 0.0 + allocate(cobalt%hp_jingest_fe(isd:ied,jsd:jed,nk)) ; cobalt%hp_jingest_fe = 0.0 + + allocate(cobalt%f_alk(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_alk=0.0 + allocate(cobalt%f_cadet_arag(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_cadet_arag=0.0 + allocate(cobalt%f_cadet_calc(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_cadet_calc=0.0 + allocate(cobalt%f_dic(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_dic=0.0 + allocate(cobalt%f_fed(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_fed=0.0 + allocate(cobalt%f_fedet(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_fedet=0.0 + allocate(cobalt%f_ldon(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_ldon=0.0 + allocate(cobalt%f_ldop(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_ldop=0.0 + allocate(cobalt%f_lith(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_lith=0.0 + allocate(cobalt%f_lithdet(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_lithdet=0.0 + allocate(cobalt%f_ndet(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_ndet=0.0 + allocate(cobalt%f_nh4(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_nh4=0.0 + allocate(cobalt%f_no3(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_no3=0.0 + allocate(cobalt%f_o2(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_o2=0.0 + allocate(cobalt%f_pdet(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_pdet=0.0 + allocate(cobalt%f_po4(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_po4=0.0 + allocate(cobalt%f_srdon(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_srdon=0.0 + allocate(cobalt%f_srdop(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_srdop=0.0 + allocate(cobalt%f_sldon(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_sldon=0.0 + allocate(cobalt%f_sldop(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_sldop=0.0 + allocate(cobalt%f_sidet(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_sidet=0.0 + allocate(cobalt%f_silg(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_silg=0.0 + allocate(cobalt%f_sio4(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_sio4=0.0 + allocate(cobalt%co3_sol_arag(isd:ied, jsd:jed, 1:nk)) ; cobalt%co3_sol_arag=0.0 + allocate(cobalt%co3_sol_calc(isd:ied, jsd:jed, 1:nk)) ; cobalt%co3_sol_calc=0.0 + allocate(cobalt%omega_arag(isd:ied, jsd:jed, 1:nk)) ; cobalt%omega_arag=0.0 + allocate(cobalt%omega_calc(isd:ied, jsd:jed, 1:nk)) ; cobalt%omega_calc=0.0 + allocate(cobalt%f_chl(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_chl=0.0 + allocate(cobalt%f_co3_ion(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_co3_ion=0.0 + allocate(cobalt%f_htotal(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_htotal=0.0 + allocate(cobalt%f_irr_mem(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_irr_mem=0.0 + allocate(cobalt%f_cased(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_cased=0.0 + allocate(cobalt%f_cadet_arag_btf(isd:ied, jsd:jed, 1:nk)); cobalt%f_cadet_arag_btf=0.0 + allocate(cobalt%f_cadet_calc_btf(isd:ied, jsd:jed, 1:nk)); cobalt%f_cadet_calc_btf=0.0 + allocate(cobalt%f_fedet_btf(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_fedet_btf=0.0 + allocate(cobalt%f_lithdet_btf(isd:ied, jsd:jed, 1:nk)); cobalt%f_lithdet_btf=0.0 + allocate(cobalt%f_ndet_btf(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_ndet_btf=0.0 + allocate(cobalt%f_pdet_btf(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_pdet_btf=0.0 + allocate(cobalt%f_sidet_btf(isd:ied, jsd:jed, 1:nk)) ; cobalt%f_sidet_btf=0.0 + + allocate(cobalt%jndi(isd:ied, jsd:jed, 1:nk)) ; cobalt%jndi=0.0 + allocate(cobalt%jnsm(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnsm=0.0 + allocate(cobalt%jnlg(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnlg=0.0 + allocate(cobalt%jnbact(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnbact=0.0 + allocate(cobalt%jnsmz(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnsmz=0.0 + allocate(cobalt%jnmdz(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnmdz=0.0 + allocate(cobalt%jnlgz(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnlgz=0.0 + allocate(cobalt%jalk(isd:ied, jsd:jed, 1:nk)) ; cobalt%jalk=0.0 + allocate(cobalt%jcadet_arag(isd:ied, jsd:jed, 1:nk)) ; cobalt%jcadet_arag=0.0 + allocate(cobalt%jcadet_calc(isd:ied, jsd:jed, 1:nk)) ; cobalt%jcadet_calc=0.0 + allocate(cobalt%jdic(isd:ied, jsd:jed, 1:nk)) ; cobalt%jdic=0.0 + allocate(cobalt%jfed(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfed=0.0 + allocate(cobalt%jfedi(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfedi=0.0 + allocate(cobalt%jfelg(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfelg=0.0 + allocate(cobalt%jfesm(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfesm=0.0 + allocate(cobalt%jfedet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfedet=0.0 + allocate(cobalt%jldon(isd:ied, jsd:jed, 1:nk)) ; cobalt%jldon=0.0 + allocate(cobalt%jldop(isd:ied, jsd:jed, 1:nk)) ; cobalt%jldop=0.0 + allocate(cobalt%jlith(isd:ied, jsd:jed, 1:nk)) ; cobalt%jlith=0.0 + allocate(cobalt%jlithdet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jlithdet=0.0 + allocate(cobalt%jndet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jndet=0.0 + allocate(cobalt%jnh4(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnh4=0.0 + allocate(cobalt%jno3(isd:ied, jsd:jed, 1:nk)) ; cobalt%jno3=0.0 + allocate(cobalt%jo2(isd:ied, jsd:jed, 1:nk)) ; cobalt%jo2=0.0 + allocate(cobalt%jpdet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jpdet=0.0 + allocate(cobalt%jpo4(isd:ied, jsd:jed, 1:nk)) ; cobalt%jpo4=0.0 + allocate(cobalt%jsrdon(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsrdon=0.0 + allocate(cobalt%jsrdop(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsrdop=0.0 + allocate(cobalt%jsldon(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsldon=0.0 + allocate(cobalt%jsldop(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsldop=0.0 + allocate(cobalt%jsidet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsidet=0.0 + allocate(cobalt%jsilg(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsilg=0.0 + allocate(cobalt%jsio4(isd:ied, jsd:jed, 1:nk)) ; cobalt%jsio4=0.0 + allocate(cobalt%jprod_ndet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_ndet=0.0 + allocate(cobalt%jprod_pdet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_pdet=0.0 + allocate(cobalt%jprod_srdon(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_srdon=0.0 + allocate(cobalt%jprod_sldon(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_sldon=0.0 + allocate(cobalt%jprod_ldon(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_ldon=0.0 + allocate(cobalt%jprod_srdop(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_srdop=0.0 + allocate(cobalt%jprod_sldop(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_sldop=0.0 + allocate(cobalt%jprod_ldop(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_ldop=0.0 + allocate(cobalt%jprod_fedet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_fedet=0.0 + allocate(cobalt%jprod_fed(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_fed=0.0 + allocate(cobalt%jprod_sidet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_sidet=0.0 + allocate(cobalt%jprod_sio4(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_sio4=0.0 + allocate(cobalt%jprod_lithdet(isd:ied, jsd:jed, 1:nk)); cobalt%jprod_lithdet=0.0 + allocate(cobalt%jprod_cadet_arag(isd:ied, jsd:jed, 1:nk)); cobalt%jprod_cadet_arag=0.0 + allocate(cobalt%jprod_cadet_calc(isd:ied, jsd:jed, 1:nk)); cobalt%jprod_cadet_calc=0.0 + allocate(cobalt%jprod_nh4(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_nh4=0.0 + allocate(cobalt%jprod_po4(isd:ied, jsd:jed, 1:nk)) ; cobalt%jprod_po4=0.0 + allocate(cobalt%det_jzloss_n(isd:ied, jsd:jed, 1:nk)) ; cobalt%det_jzloss_n=0.0 + allocate(cobalt%det_jzloss_p(isd:ied, jsd:jed, 1:nk)) ; cobalt%det_jzloss_p=0.0 + allocate(cobalt%det_jzloss_fe(isd:ied, jsd:jed, 1:nk)); cobalt%det_jzloss_fe=0.0 + allocate(cobalt%det_jzloss_si(isd:ied, jsd:jed, 1:nk)); cobalt%det_jzloss_si=0.0 + allocate(cobalt%det_jhploss_n(isd:ied, jsd:jed, 1:nk)); cobalt%det_jhploss_n=0.0 + allocate(cobalt%det_jhploss_p(isd:ied, jsd:jed, 1:nk)); cobalt%det_jhploss_p=0.0 + allocate(cobalt%det_jhploss_fe(isd:ied, jsd:jed, 1:nk)); cobalt%det_jhploss_fe=0.0 + allocate(cobalt%det_jhploss_si(isd:ied, jsd:jed, 1:nk)); cobalt%det_jhploss_si=0.0 + allocate(cobalt%jdiss_cadet_arag(isd:ied, jsd:jed, 1:nk)); cobalt%jdiss_cadet_arag=0.0 + allocate(cobalt%jdiss_cadet_calc(isd:ied, jsd:jed, 1:nk)); cobalt%jdiss_cadet_calc=0.0 + allocate(cobalt%jdiss_sidet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jdiss_sidet=0.0 + allocate(cobalt%jremin_ndet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jremin_ndet=0.0 + allocate(cobalt%jremin_pdet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jremin_pdet=0.0 + allocate(cobalt%jremin_fedet(isd:ied, jsd:jed, 1:nk)) ; cobalt%jremin_fedet=0.0 + allocate(cobalt%jfe_ads(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfe_ads=0.0 + allocate(cobalt%jfe_coast(isd:ied, jsd:jed, 1:nk)) ; cobalt%jfe_coast=0.0 + allocate(cobalt%kfe_eq_lig(isd:ied, jsd:jed, 1:nk)) ; cobalt%kfe_eq_lig=0.0 + allocate(cobalt%expkT(isd:ied, jsd:jed, 1:nk)) ; cobalt%expkT=0.0 + allocate(cobalt%hp_temp_lim(isd:ied, jsd:jed, 1:nk)) ; cobalt%hp_temp_lim=0.0 + allocate(cobalt%irr_inst(isd:ied, jsd:jed, 1:nk)) ; cobalt%irr_inst=0.0 + allocate(cobalt%irr_mix(isd:ied, jsd:jed, 1:nk)) ; cobalt%irr_mix=0.0 + allocate(cobalt%jno3denit_wc(isd:ied, jsd:jed, 1:nk)) ; cobalt%jno3denit_wc=0.0 + allocate(cobalt%jnitrif(isd:ied, jsd:jed, 1:nk)) ; cobalt%jnitrif=0.0 + allocate(cobalt%total_filter_feeding(isd:ied,jsd:jed,1:nk)); cobalt%total_filter_feeding=0.0 + allocate(cobalt%zt(isd:ied, jsd:jed, 1:nk)) ; cobalt%zt=0.0 + allocate(cobalt%zm(isd:ied, jsd:jed, 1:nk)) ; cobalt%zm=0.0 + allocate(cobalt%tot_layer_int_c(isd:ied, jsd:jed,1:nk)) ; cobalt%tot_layer_int_c=0.0 + allocate(cobalt%tot_layer_int_fe(isd:ied, jsd:jed,1:nk)) ; cobalt%tot_layer_int_fe=0.0 + allocate(cobalt%tot_layer_int_n(isd:ied, jsd:jed, 1:nk)) ; cobalt%tot_layer_int_n=0.0 + allocate(cobalt%tot_layer_int_p(isd:ied, jsd:jed, 1:nk)) ; cobalt%tot_layer_int_p=0.0 + allocate(cobalt%tot_layer_int_si(isd:ied, jsd:jed, 1:nk)); cobalt%tot_layer_int_si=0.0 + allocate(cobalt%net_prim_prod(isd:ied, jsd:jed, 1:nk)); cobalt%net_prim_prod=0.0 + allocate(cobalt%gross_prim_prod(isd:ied, jsd:jed, 1:nk)); cobalt%gross_prim_prod=0.0 + allocate(cobalt%nlg_diatoms(isd:ied, jsd:jed, 1:nk)); cobalt%nlg_diatoms=0.0 + allocate(cobalt%q_si_2_n_lg_diatoms(isd:ied, jsd:jed, 1:nk)); cobalt%q_si_2_n_lg_diatoms=0.0 + allocate(cobalt%b_alk(isd:ied, jsd:jed)) ; cobalt%b_alk=0.0 + allocate(cobalt%b_dic(isd:ied, jsd:jed)) ; cobalt%b_dic=0.0 + allocate(cobalt%b_fed(isd:ied, jsd:jed)) ; cobalt%b_fed=0.0 + allocate(cobalt%b_nh4(isd:ied, jsd:jed)) ; cobalt%b_nh4=0.0 + allocate(cobalt%b_no3(isd:ied, jsd:jed)) ; cobalt%b_no3=0.0 + allocate(cobalt%b_o2(isd:ied, jsd:jed)) ; cobalt%b_o2=0.0 + allocate(cobalt%b_po4(isd:ied, jsd:jed)) ; cobalt%b_po4=0.0 + allocate(cobalt%b_sio4(isd:ied, jsd:jed)) ; cobalt%b_sio4=0.0 + allocate(cobalt%pco2_csurf(isd:ied, jsd:jed)) ; cobalt%pco2_csurf=0.0 + allocate(cobalt%co2_csurf(isd:ied, jsd:jed)) ; cobalt%co2_csurf=0.0 + allocate(cobalt%co2_alpha(isd:ied, jsd:jed)) ; cobalt%co2_alpha=0.0 + allocate(cobalt%fcadet_arag_btm(isd:ied, jsd:jed)) ; cobalt%fcadet_arag_btm=0.0 + allocate(cobalt%fcadet_calc_btm(isd:ied, jsd:jed)) ; cobalt%fcadet_calc_btm=0.0 + allocate(cobalt%ffedet_btm(isd:ied, jsd:jed)) ; cobalt%ffedet_btm=0.0 + allocate(cobalt%flithdet_btm(isd:ied, jsd:jed)) ; cobalt%flithdet_btm=0.0 + allocate(cobalt%fpdet_btm(isd:ied, jsd:jed)) ; cobalt%fpdet_btm=0.0 + allocate(cobalt%fndet_btm(isd:ied, jsd:jed)) ; cobalt%fndet_btm=0.0 + allocate(cobalt%fsidet_btm(isd:ied, jsd:jed)) ; cobalt%fsidet_btm=0.0 + allocate(cobalt%fcased_burial(isd:ied, jsd:jed)) ; cobalt%fcased_burial=0.0 + allocate(cobalt%fcased_input(isd:ied, jsd:jed)) ; cobalt%fcased_input=0.0 + allocate(cobalt%fcased_redis(isd:ied, jsd:jed)) ; cobalt%fcased_redis=0.0 + allocate(cobalt%ffe_sed(isd:ied, jsd:jed)) ; cobalt%ffe_sed=0.0 + allocate(cobalt%fnfeso4red_sed(isd:ied, jsd:jed)) ; cobalt%fnfeso4red_sed=0.0 + allocate(cobalt%fno3denit_sed(isd:ied, jsd:jed)) ; cobalt%fno3denit_sed=0.0 + allocate(cobalt%fnoxic_sed(isd:ied, jsd:jed)) ; cobalt%fnoxic_sed=0.0 + allocate(cobalt%frac_burial(isd:ied, jsd:jed)) ; cobalt%frac_burial=0.0 + allocate(cobalt%fndet_burial(isd:ied, jsd:jed)) ; cobalt%fndet_burial=0.0 + allocate(cobalt%fpdet_burial(isd:ied, jsd:jed)) ; cobalt%fpdet_burial=0.0 + + ! + ! allocate 100m integrated quantities + ! + do n = 1, NUM_PHYTO + allocate(phyto(n)%jprod_n_100(isd:ied,jsd:jed)) ; phyto(n)%jprod_n_100 = 0.0 + allocate(phyto(n)%jprod_n_new_100(isd:ied,jsd:jed)) ; phyto(n)%jprod_n_new_100 = 0.0 + allocate(phyto(n)%jzloss_n_100(isd:ied,jsd:jed)) ; phyto(n)%jzloss_n_100 = 0.0 + allocate(phyto(n)%jexuloss_n_100(isd:ied,jsd:jed)) ; phyto(n)%jexuloss_n_100 = 0.0 + allocate(phyto(n)%f_n_100(isd:ied,jsd:jed)) ; phyto(n)%f_n_100 = 0.0 + enddo + allocate(phyto(DIAZO)%jprod_n_n2_100(isd:ied,jsd:jed)); phyto(DIAZO)%jprod_n_n2_100 = 0.0 + allocate(phyto(SMALL)%jvirloss_n_100(isd:ied,jsd:jed)) ; phyto(SMALL)%jvirloss_n_100 = 0.0 + allocate(phyto(SMALL)%jaggloss_n_100(isd:ied,jsd:jed)) ; phyto(SMALL)%jaggloss_n_100 = 0.0 + allocate(phyto(LARGE)%jaggloss_n_100(isd:ied,jsd:jed)) ; phyto(LARGE)%jaggloss_n_100 = 0.0 + allocate(cobalt%jprod_allphytos_100(isd:ied,jsd:jed)) ; cobalt%jprod_allphytos_100 = 0.0 + + do n = 1, NUM_ZOO + allocate(zoo(n)%jprod_n_100(isd:ied,jsd:jed)) ; zoo(n)%jprod_n_100 = 0.0 + allocate(zoo(n)%jingest_n_100(isd:ied,jsd:jed)) ; zoo(n)%jingest_n_100 = 0.0 + allocate(zoo(n)%jremin_n_100(isd:ied,jsd:jed)) ; zoo(n)%jremin_n_100 = 0.0 + allocate(zoo(n)%f_n_100(isd:ied,jsd:jed)) ; zoo(n)%f_n_100 = 0.0 + enddo + + do n = 1,2 + allocate(zoo(n)%jzloss_n_100(isd:ied,jsd:jed)) ; zoo(n)%jzloss_n_100 = 0.0 + allocate(zoo(n)%jprod_don_100(isd:ied,jsd:jed)) ; zoo(n)%jprod_don_100 = 0.0 + enddo + + do n = 2,3 + allocate(zoo(n)%jhploss_n_100(isd:ied,jsd:jed)) ; zoo(n)%jhploss_n_100 = 0.0 + allocate(zoo(n)%jprod_ndet_100(isd:ied,jsd:jed)) ; zoo(n)%jprod_ndet_100 = 0.0 + enddo + + allocate(cobalt%hp_jingest_n_100(isd:ied,jsd:jed)) ; cobalt%hp_jingest_n_100 = 0.0 + allocate(cobalt%hp_jremin_n_100(isd:ied,jsd:jed)) ; cobalt%hp_jremin_n_100 = 0.0 + allocate(cobalt%hp_jprod_ndet_100(isd:ied,jsd:jed)) ; cobalt%hp_jprod_ndet_100 = 0.0 + + allocate(bact(1)%jprod_n_100(isd:ied,jsd:jed)) ; bact(1)%jprod_n_100 = 0.0 + allocate(bact(1)%jzloss_n_100(isd:ied,jsd:jed)) ; bact(1)%jzloss_n_100 = 0.0 + allocate(bact(1)%jvirloss_n_100(isd:ied,jsd:jed)); bact(1)%jvirloss_n_100 = 0.0 + allocate(bact(1)%jremin_n_100(isd:ied,jsd:jed)) ; bact(1)%jremin_n_100 = 0.0 + allocate(bact(1)%juptake_ldon_100(isd:ied,jsd:jed)) ; bact(1)%juptake_ldon_100 = 0.0 + allocate(bact(1)%f_n_100(isd:ied,jsd:jed)) ; bact(1)%f_n_100 = 0.0 + + allocate(cobalt%jprod_lithdet_100(isd:ied,jsd:jed)) ; cobalt%jprod_lithdet_100 = 0.0 + allocate(cobalt%jprod_sidet_100(isd:ied,jsd:jed)) ; cobalt%jprod_sidet_100 = 0.0 + allocate(cobalt%jprod_cadet_calc_100(isd:ied,jsd:jed)) ; cobalt%jprod_cadet_calc_100 = 0.0 + allocate(cobalt%jprod_cadet_arag_100(isd:ied,jsd:jed)) ; cobalt%jprod_cadet_arag_100 = 0.0 + allocate(cobalt%jremin_ndet_100(isd:ied,jsd:jed)) ; cobalt%jremin_ndet_100 = 0.0 + allocate(cobalt%jprod_mesozoo_200(isd:ied,jsd:jed)) ; cobalt%jprod_mesozoo_200 = 0.0 + + allocate(cobalt%f_ndet_100(isd:ied,jsd:jed)) ; cobalt%f_ndet_100 = 0.0 + allocate(cobalt%f_don_100(isd:ied,jsd:jed)) ; cobalt%f_don_100 = 0.0 + allocate(cobalt%f_silg_100(isd:ied,jsd:jed)) ; cobalt%f_silg_100 = 0.0 + allocate(cobalt%f_mesozoo_200(isd:ied,jsd:jed)) ; cobalt%f_mesozoo_200 = 0.0 + + allocate(cobalt%fndet_100(isd:ied,jsd:jed)) ; cobalt%fndet_100 = 0.0 + allocate(cobalt%fpdet_100(isd:ied,jsd:jed)) ; cobalt%fpdet_100 = 0.0 + allocate(cobalt%fsidet_100(isd:ied,jsd:jed)) ; cobalt%fsidet_100 = 0.0 + allocate(cobalt%flithdet_100(isd:ied,jsd:jed)) ; cobalt%flithdet_100 = 0.0 + allocate(cobalt%fcadet_calc_100(isd:ied,jsd:jed)) ; cobalt%fcadet_calc_100 = 0.0 + allocate(cobalt%fcadet_arag_100(isd:ied,jsd:jed)) ; cobalt%fcadet_arag_100 = 0.0 + allocate(cobalt%ffedet_100(isd:ied,jsd:jed)) ; cobalt%ffedet_100 = 0.0 + + allocate(cobalt%btm_temp(isd:ied,jsd:jed)) ; cobalt%btm_temp = 0.0 + allocate(cobalt%btm_o2(isd:ied,jsd:jed)) ; cobalt%btm_o2 = 0.0 + + allocate(cobalt%o2min(isd:ied, jsd:jed)); cobalt%o2min=0.0 + allocate(cobalt%z_o2min(isd:ied, jsd:jed)); cobalt%z_o2min=0.0 + allocate(cobalt%z_sat_arag(isd:ied, jsd:jed)); cobalt%z_sat_arag=0.0 + allocate(cobalt%z_sat_calc(isd:ied, jsd:jed)); cobalt%z_sat_calc=0.0 + allocate(cobalt%mask_z_sat_arag(isd:ied, jsd:jed)); cobalt%mask_z_sat_arag = .FALSE. + allocate(cobalt%mask_z_sat_calc(isd:ied, jsd:jed)); cobalt%mask_z_sat_calc = .FALSE. + + + end subroutine user_allocate_arrays + + ! + ! This is an internal sub, not a public interface. + ! Deallocate all the work arrays allocated by user_allocate_arrays. + ! + subroutine user_deallocate_arrays + integer n + + deallocate(cobalt%htotalhi,cobalt%htotallo) + + do n = 1, NUM_PHYTO + deallocate(phyto(n)%def_fe) + deallocate(phyto(n)%def_p) + deallocate(phyto(n)%f_fe) + deallocate(phyto(n)%f_n) + deallocate(phyto(n)%felim) + deallocate(phyto(n)%irrlim) + deallocate(phyto(n)%jzloss_fe) + deallocate(phyto(n)%jzloss_n) + deallocate(phyto(n)%jzloss_p) + deallocate(phyto(n)%jzloss_sio2) + deallocate(phyto(n)%jaggloss_n) + deallocate(phyto(n)%jaggloss_p) + deallocate(phyto(n)%jaggloss_fe) + deallocate(phyto(n)%jaggloss_sio2) + deallocate(phyto(n)%jvirloss_n) + deallocate(phyto(n)%jvirloss_p) + deallocate(phyto(n)%jvirloss_fe) + deallocate(phyto(n)%jvirloss_sio2) + deallocate(phyto(n)%jexuloss_n) + deallocate(phyto(n)%jexuloss_p) + deallocate(phyto(n)%jexuloss_fe) + deallocate(phyto(n)%jhploss_fe) + deallocate(phyto(n)%jhploss_n) + deallocate(phyto(n)%jhploss_p) + deallocate(phyto(n)%juptake_fe) + deallocate(phyto(n)%juptake_nh4) + deallocate(phyto(n)%juptake_no3) + deallocate(phyto(n)%juptake_po4) + deallocate(phyto(n)%jprod_n) + deallocate(phyto(n)%liebig_lim) + deallocate(phyto(n)%mu) + deallocate(phyto(n)%po4lim) + deallocate(phyto(n)%q_fe_2_n) + deallocate(phyto(n)%q_p_2_n) + deallocate(phyto(n)%q_si_2_n) + deallocate(phyto(n)%theta) + enddo + do n = 2, NUM_PHYTO + deallocate(phyto(n)%nh4lim) + deallocate(phyto(n)%no3lim) + enddo + deallocate(phyto(DIAZO)%juptake_n2) + deallocate(phyto(DIAZO)%o2lim) + deallocate(phyto(LARGE)%juptake_sio4) + deallocate(phyto(LARGE)%silim) + + ! bacteria + deallocate(bact(1)%f_n) + deallocate(bact(1)%jzloss_n) + deallocate(bact(1)%jzloss_p) + deallocate(bact(1)%jvirloss_n) + deallocate(bact(1)%jvirloss_p) + deallocate(bact(1)%jhploss_n) + deallocate(bact(1)%jhploss_p) + deallocate(bact(1)%juptake_ldon) + deallocate(bact(1)%juptake_ldop) + deallocate(bact(1)%jprod_nh4) + deallocate(bact(1)%jprod_po4) + deallocate(bact(1)%jprod_n) + deallocate(bact(1)%temp_lim) + + ! zooplankton + do n = 1, NUM_ZOO + deallocate(zoo(n)%f_n) + deallocate(zoo(n)%jzloss_n) + deallocate(zoo(n)%jzloss_p) + deallocate(zoo(n)%jhploss_n) + deallocate(zoo(n)%jhploss_p) + deallocate(zoo(n)%jingest_n) + deallocate(zoo(n)%jingest_p) + deallocate(zoo(n)%jingest_sio2) + deallocate(zoo(n)%jingest_fe) + deallocate(zoo(n)%jprod_ndet) + deallocate(zoo(n)%jprod_pdet) + deallocate(zoo(n)%jprod_ldon) + deallocate(zoo(n)%jprod_ldop) + deallocate(zoo(n)%jprod_srdon) + deallocate(zoo(n)%jprod_srdop) + deallocate(zoo(n)%jprod_sldon) + deallocate(zoo(n)%jprod_sldop) + deallocate(zoo(n)%jprod_fedet) + deallocate(zoo(n)%jprod_fed) + deallocate(zoo(n)%jprod_sidet) + deallocate(zoo(n)%jprod_sio4) + deallocate(zoo(n)%jprod_po4) + deallocate(zoo(n)%jprod_nh4) + deallocate(zoo(n)%jprod_n) + deallocate(zoo(n)%temp_lim) + enddo + + deallocate(cobalt%hp_jingest_n) + deallocate(cobalt%hp_jingest_p) + deallocate(cobalt%hp_jingest_sio2) + deallocate(cobalt%hp_jingest_fe) + + deallocate(& + cobalt%f_alk,& + cobalt%f_cadet_arag,& + cobalt%f_cadet_calc,& + cobalt%f_dic,& + cobalt%f_fed,& + cobalt%f_fedet,& + cobalt%f_ldon,& + cobalt%f_ldop,& + cobalt%f_lith,& + cobalt%f_lithdet,& + cobalt%f_ndet,& + cobalt%f_nh4,& + cobalt%f_no3,& + cobalt%f_o2,& + cobalt%f_pdet,& + cobalt%f_po4,& + cobalt%f_srdon,& + cobalt%f_srdop,& + cobalt%f_sldon,& + cobalt%f_sldop,& + cobalt%f_sidet,& + cobalt%f_silg,& + cobalt%f_sio4,& + cobalt%f_chl,& + cobalt%f_co3_ion,& + cobalt%f_htotal,& + cobalt%f_irr_mem,& + cobalt%f_cased,& + cobalt%f_cadet_arag_btf,& + cobalt%f_cadet_calc_btf,& + cobalt%f_fedet_btf,& + cobalt%f_lithdet_btf,& + cobalt%f_ndet_btf,& + cobalt%f_pdet_btf,& + cobalt%f_sidet_btf,& + cobalt%jndi,& + cobalt%jnsm,& + cobalt%jnlg,& + cobalt%jnsmz,& + cobalt%jnmdz,& + cobalt%jnlgz,& + cobalt%jalk,& + cobalt%jcadet_arag,& + cobalt%jcadet_calc,& + cobalt%jdic,& + cobalt%jfed,& + cobalt%jfedi,& + cobalt%jfelg,& + cobalt%jfesm,& + cobalt%jfedet,& + cobalt%jldon,& + cobalt%jldop,& + cobalt%jlith,& + cobalt%jlithdet,& + cobalt%jndet,& + cobalt%jnh4,& + cobalt%jno3,& + cobalt%jo2,& + cobalt%jpdet,& + cobalt%jpo4,& + cobalt%jsrdon,& + cobalt%jsrdop,& + cobalt%jsldon,& + cobalt%jsldop,& + cobalt%jsidet,& + cobalt%jsilg,& + cobalt%jsio4,& + cobalt%jprod_ndet,& + cobalt%jprod_pdet,& + cobalt%jprod_srdon,& + cobalt%jprod_sldon,& + cobalt%jprod_ldon,& + cobalt%jprod_srdop,& + cobalt%jprod_sldop,& + cobalt%jprod_ldop,& + cobalt%jprod_fedet,& + cobalt%jprod_fed,& + cobalt%jprod_sidet,& + cobalt%jprod_sio4,& + cobalt%jprod_lithdet,& + cobalt%jprod_cadet_arag,& + cobalt%jprod_cadet_calc,& + cobalt%jprod_nh4,& + cobalt%jprod_po4,& + cobalt%det_jzloss_n,& + cobalt%det_jzloss_p,& + cobalt%det_jzloss_fe,& + cobalt%det_jzloss_si,& + cobalt%det_jhploss_n,& + cobalt%det_jhploss_p,& + cobalt%det_jhploss_fe,& + cobalt%det_jhploss_si,& + cobalt%jdiss_cadet_arag,& + cobalt%jdiss_cadet_calc,& + cobalt%jdiss_sidet,& + cobalt%jremin_ndet,& + cobalt%jremin_pdet,& + cobalt%jremin_fedet,& + cobalt%jfe_ads,& + cobalt%jfe_coast,& + cobalt%kfe_eq_lig,& + cobalt%expkT,& + cobalt%hp_temp_lim,& + cobalt%irr_inst,& + cobalt%irr_mix,& + cobalt%jno3denit_wc,& + cobalt%jnitrif,& + cobalt%total_filter_feeding,& + cobalt%net_prim_prod,& + cobalt%gross_prim_prod,& + cobalt%nlg_diatoms,& + cobalt%q_si_2_n_lg_diatoms,& + cobalt%zt,& + cobalt%zm,& + cobalt%tot_layer_int_c,& + cobalt%tot_layer_int_fe,& + cobalt%tot_layer_int_n,& + cobalt%tot_layer_int_p,& + cobalt%tot_layer_int_si) + + deallocate(& + cobalt%b_alk,& + cobalt%b_dic,& + cobalt%b_fed,& + cobalt%b_nh4,& + cobalt%b_no3,& + cobalt%b_o2,& + cobalt%b_po4,& + cobalt%b_sio4,& + cobalt%pco2_csurf,& + cobalt%co2_csurf,& + cobalt%co2_alpha,& + cobalt%fcadet_arag_btm,& + cobalt%fcadet_calc_btm,& + cobalt%ffedet_btm,& + cobalt%flithdet_btm,& + cobalt%fpdet_btm,& + cobalt%fndet_btm,& + cobalt%fsidet_btm,& + cobalt%fcased_burial,& + cobalt%fcased_input,& + cobalt%fcased_redis,& + cobalt%ffe_sed,& + cobalt%fnfeso4red_sed,& + cobalt%fno3denit_sed, & + cobalt%fnoxic_sed, & + cobalt%frac_burial,& + cobalt%fndet_burial,& + cobalt%fpdet_burial) + + do n = 1, NUM_PHYTO + deallocate(phyto(n)%jprod_n_100) + deallocate(phyto(n)%jprod_n_new_100) + deallocate(phyto(n)%jzloss_n_100) + deallocate(phyto(n)%jexuloss_n_100) + deallocate(phyto(n)%f_n_100) + enddo + deallocate(phyto(DIAZO)%jprod_n_n2_100) + deallocate(phyto(SMALL)%jvirloss_n_100) + deallocate(phyto(SMALL)%jaggloss_n_100) + deallocate(phyto(LARGE)%jaggloss_n_100) + deallocate(cobalt%jprod_allphytos_100) + + do n = 1, NUM_ZOO + deallocate(zoo(n)%jprod_n_100) + deallocate(zoo(n)%jingest_n_100) + deallocate(zoo(n)%jremin_n_100) + deallocate(zoo(n)%f_n_100) + enddo + + do n = 1,2 + deallocate(zoo(n)%jzloss_n_100) + deallocate(zoo(n)%jprod_don_100) + enddo + + do n = 2,3 + deallocate(zoo(n)%jhploss_n_100) + deallocate(zoo(n)%jprod_ndet_100) + enddo + + deallocate(cobalt%hp_jingest_n_100) + deallocate(cobalt%hp_jremin_n_100) + deallocate(cobalt%hp_jprod_ndet_100) + + deallocate(bact(1)%jprod_n_100) + deallocate(bact(1)%jzloss_n_100) + deallocate(bact(1)%jvirloss_n_100) + deallocate(bact(1)%jremin_n_100) + deallocate(bact(1)%juptake_ldon_100) + deallocate(bact(1)%f_n_100) + + deallocate(cobalt%jprod_lithdet_100) + deallocate(cobalt%jprod_sidet_100) + deallocate(cobalt%jprod_cadet_arag_100) + deallocate(cobalt%jprod_cadet_calc_100) + deallocate(cobalt%jremin_ndet_100) + deallocate(cobalt%jprod_mesozoo_200) + + deallocate(cobalt%f_ndet_100) + deallocate(cobalt%f_don_100) + deallocate(cobalt%f_silg_100) + deallocate(cobalt%f_mesozoo_200) + + deallocate(cobalt%fndet_100) + deallocate(cobalt%fpdet_100) + deallocate(cobalt%fsidet_100) + deallocate(cobalt%flithdet_100) + deallocate(cobalt%fcadet_calc_100) + deallocate(cobalt%fcadet_arag_100) + deallocate(cobalt%ffedet_100) + + deallocate(cobalt%btm_temp) + deallocate(cobalt%btm_o2) + + deallocate(cobalt%o2min) + deallocate(cobalt%z_o2min) + deallocate(cobalt%z_sat_arag) + deallocate(cobalt%z_sat_calc) + deallocate(cobalt%mask_z_sat_arag) + deallocate(cobalt%mask_z_sat_calc) + + end subroutine user_deallocate_arrays + + +end module generic_COBALT diff --git a/src/ocean_shared/generic_tracers/generic_ERGOM.F90 b/src/ocean_shared/generic_tracers/generic_ERGOM.F90 index 973fbf74f8..79fbe01753 100644 --- a/src/ocean_shared/generic_tracers/generic_ERGOM.F90 +++ b/src/ocean_shared/generic_tracers/generic_ERGOM.F90 @@ -34,8 +34,8 @@ module generic_ERGOM use coupler_types_mod, only: coupler_2d_bc_type use field_manager_mod, only: fm_string_len - use fms_mod, only: open_namelist_file, close_file, check_nml_error - use mpp_mod, only: mpp_error, NOTE, WARNING, FATAL, stdout, stdlog + use fms_mod, only: write_version_number, open_namelist_file, close_file, check_nml_error + use mpp_mod, only: mpp_error, NOTE, WARNING, FATAL, stdout, stdlog, input_nml_file use mpp_mod, only: mpp_clock_id, mpp_clock_begin, mpp_clock_end, CLOCK_ROUTINE use time_manager_mod, only: time_type use fm_util_mod, only: fm_util_start_namelist, fm_util_end_namelist @@ -52,6 +52,9 @@ module generic_ERGOM implicit none ; private + character(len=128) :: version = '$Id: generic_ERGOM.F90,v 20.0 2013/12/14 00:18:05 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' + character(len=fm_string_len), parameter :: mod_name = 'generic_ERGOM' character(len=fm_string_len), parameter :: package_name = 'generic_ergom' @@ -102,10 +105,10 @@ module generic_ERGOM nf = 0., & ! nitrification rate [1/s] alpha_nit = 0., & ! half-saturation constant for nitrification [mol/kg] alp_o2 = 0., & ! slope function for detritus recycling [kg/mol] - alp_no3 = 0., & ! slope function for detritus recycling [kg/mol] - alp_h2s = 0., & ! slope function for detritus recycling [kg/mol] - alp_nh4 = 0., & ! slope function for detritus recycling [kg/mol] - k_h2s_o2 = 0., & ! reaction constant h2s oxidation with o2 [kg/mol/s] + alp_no3 = 0., & ! slope function for detritus recycling [kg/mol] + alp_h2s = 0., & ! slope function for detritus recycling [kg/mol] + alp_nh4 = 0., & ! slope function for detritus recycling [kg/mol] + k_h2s_o2 = 0., & ! reaction constant h2s oxidation with o2 [kg/mol/s] k_h2s_no3 = 0., & ! reaction constant h2s oxidation with no3 [kg/mol/s] k_sul_o2 = 0., & ! reaction constant sulfur oxidation with o2 [kg/mol/s] k_sul_no3 = 0., & ! reaction constant sulfur oxidation with no3 [kg/mol/s] @@ -116,9 +119,9 @@ module generic_ERGOM f_po4, & !po4 concentration [mol/kg] f_o2 , & !o2 concentration [mol/kg] f_h2s, & !h2s concentration [mol/kg] - f_sul, & !sulfur concentration [mol/kg] - f_chl, & !chlorophyll concentration [µg/kg] - irr_inst,& !instantaneous light [W/m2] + f_sul, & !sulfur concentration [mol/kg] + f_chl, & !chlorophyll concentration [µg/kg] + irr_inst,& !instantaneous light [W/m2] jno3 , & !time change of no3 concentration [mol/kg/s] jnh4 , & !time change of nh4 concentration [mol/kg/s] jpo4 , & !time change of po4 concentration [mol/kg/s] @@ -129,19 +132,19 @@ module generic_ERGOM jh2s_no3 , & !time change of h2s concentration [mol/kg/s] by nitrate jsul_o2 , & !time change of sul concentration [mol/kg/s] by oxygen jsul_no3 , & !time change of sul concentration [mol/kg/s] by nitrate - jrec_o2 , & !nitrogen loss to nh4 by recycling with o2 [mol/kg/s] - jrec_no3 , & !nitrogen loss to nh4 by recycling with no3 [mol/kg/s] - jrec_so4 , & !nitrogen loss to nh4 by recycling with so4 [mol/kg/s] - jrec_ana , & !nitrogen loss to nh4 by recycling and subseqent anammox [mol/kg/s] - jdenit_wc, & !denitrification in water column [mol/kg/s] - jnitrif !nitrification in water column [mol/kg/s] + jrec_o2 , & !nitrogen loss to nh4 by recycling with o2 [mol/kg/s] + jrec_no3 , & !nitrogen loss to nh4 by recycling with no3 [mol/kg/s] + jrec_so4 , & !nitrogen loss to nh4 by recycling with so4 [mol/kg/s] + jrec_ana , & !nitrogen loss to nh4 by recycling and subseqent anammox [mol/kg/s] + jdenit_wc, & !denitrification in water column [mol/kg/s] + jnitrif !nitrification in water column [mol/kg/s] real, dimension(:,:), ALLOCATABLE :: & b_nh4, & - b_no3, & - b_o2, & - b_po4, & - b_nitrogen, & - b_h2s + b_no3, & + b_o2, & + b_po4, & + b_nitrogen, & + b_h2s real, dimension(:,:,:,:), pointer :: & p_no3, & !no3 concentration [mol/kg] p_nh4, & !nh4 concentration [mol/kg] @@ -163,7 +166,7 @@ module generic_ERGOM id_cya = -1, & ! nitrogen in cyanobacteria prognostic tracer id_zoo = -1, & ! nitrogen in zooplankton prognostic tracer id_det = -1, & ! nitrogen in detritus prognostic tracer - id_irr_inst = -1, & ! instantaneous light + id_irr_inst = -1, & ! instantaneous light id_jno3 = -1, & ! no3 source layer integral [mol/m2/s] id_jnh4 = -1, & ! nh4 source layer integral [mol/m2/s] id_jpo4 = -1, & ! po4 source layer integral [mol/m2/s] @@ -198,101 +201,101 @@ module generic_ERGOM f_n , & ! nitrogen in phytoplankton, the intermediate value after physics [mol/kg] ilim , & ! light limitation factor [dimensionless] jprod_no3 , & ! no3 uptake [mol/kg/s] - jprod_nh4 , & ! nh4 uptake [mol/kg/s] + jprod_nh4 , & ! nh4 uptake [mol/kg/s] jprod_po4 , & ! po4 uptake [mol/kg/s] jprod_n2 , & ! n2 fixation [mol/kg/s] - jgraz_n , & ! nitrogen loss by grazing [mol/kg/s] - jres_n , & ! nitrogen loss by respiration [mol/kg/s] - jdet_n , & ! nitrogen loss to detritus [mol/kg/s] - move ! phytoplankton sinking velocity (<0 for sinking) [m/s] + jgraz_n , & ! nitrogen loss by grazing [mol/kg/s] + jres_n , & ! nitrogen loss by respiration [mol/kg/s] + jdet_n , & ! nitrogen loss to detritus [mol/kg/s] + move ! phytoplankton sinking velocity (<0 for sinking) [m/s] real, dimension(:,:,:,:), pointer :: & p_phyt !nitrogen in phytoplankton [mol/kg] real :: & imin = 0. , & ! minimum light [W/m2] - tmin = 0. , & ! minimum temperature [Celsius] - smin = 0. , & ! minimum phytoplankton salinity [g/kg] - smax = 0. , & ! maximum phytoplankton salinity [g/kg] + tmin = 0. , & ! minimum temperature [Celsius] + smin = 0. , & ! minimum phytoplankton salinity [g/kg] + smax = 0. , & ! maximum phytoplankton salinity [g/kg] alpha = 0. , & ! DIN half-saturation constant [mol/kg] talpha = 0. , & ! Michaeles Menton-like temperature [Celsius] rp0 = 0. , & ! maximum uptake rate [1/s] p0 = 0. , & ! background concentration for initial growth [mol/kg] - pnr = 0. , & ! P/N ratio - cnr = 0. , & ! C/N ratio - lpd = 0. , & ! phytoplankton loss to detritus [1/s] - lpr = 0. , & ! phytoplankton loss by respiration [1/s] - wsink0 = 0. ! surface phytoplankton sinking velocity [m/s] + pnr = 0. , & ! P/N ratio + cnr = 0. , & ! C/N ratio + lpd = 0. , & ! phytoplankton loss to detritus [1/s] + lpr = 0. , & ! phytoplankton loss by respiration [1/s] + wsink0 = 0. ! surface phytoplankton sinking velocity [m/s] integer :: & id_jprod_no3 = -1 , & ! Diag id for no3 production layer integral [mol/m2/s] - id_jprod_nh4 = -1 , & ! Diag id for nh4 production layer integral [mol/m2/s] + id_jprod_nh4 = -1 , & ! Diag id for nh4 production layer integral [mol/m2/s] id_jprod_po4 = -1 , & ! Diag id for po4 production layer integral [mol/m2/s] id_jprod_n2 = -1 , & ! Diag id for n2 fixation layer integral [mol/m2/s] - id_jgraz_n = -1 , & ! Diag id for nitrogen grazing layer integral [mol/m2/s] - id_jres_n = -1 , & ! Diag id for nitrogen respiration layer integral [mol/m2/s] - id_jdet_n = -1 , & ! Diag id for nitrogen detritus layer integral [mol/m2/s] - id_ilim = -1 , & ! light limitation + id_jgraz_n = -1 , & ! Diag id for nitrogen grazing layer integral [mol/m2/s] + id_jres_n = -1 , & ! Diag id for nitrogen respiration layer integral [mol/m2/s] + id_jdet_n = -1 , & ! Diag id for nitrogen detritus layer integral [mol/m2/s] + id_ilim = -1 , & ! light limitation id_nlim = -1 , & ! DIN limitation - id_plim = -1 ! DIP limitation - character(len=3) :: name + id_plim = -1 ! DIP limitation + character(len=3) :: name end type phytoplankton type zooplankton real, ALLOCATABLE, dimension(:) :: pref_phy, pref_zoo, pref_det real, ALLOCATABLE, dimension(:,:,:) :: & f_n , & ! nitrogen in zooplankton, the intermediate value after physics [mol/kg] - jgraz_n , & ! nitrogen loss by grazing [mol/kg/s] + jgraz_n , & ! nitrogen loss by grazing [mol/kg/s] jgain_n , & ! nitrogen gain by grazing [mol/kg/s] - jres_n , & ! nitrogen loss by respiration [mol/kg/s] - jdet_n , & ! nitrogen loss to detritus [mol/kg/s] - move ! zooplankton movement [m/s] + jres_n , & ! nitrogen loss by respiration [mol/kg/s] + jdet_n , & ! nitrogen loss to detritus [mol/kg/s] + move ! zooplankton movement [m/s] real, dimension(:,:,:,:), pointer :: & p_zoo !nitrogen in zooplankton [mol/kg] real, dimension(:,:,:), pointer :: & p_vmove , & !vertical movement [m/s] p_vdiff !vertical diffusion [m²/s] real :: & - pnr = 0. , & ! P/N ratio - cnr = 0. , & ! C/N ratio - t_opt = 0. , & ! optimal grazing temperature [Celsius] + pnr = 0. , & ! P/N ratio + cnr = 0. , & ! C/N ratio + t_opt = 0. , & ! optimal grazing temperature [Celsius] t_max = 0. , & ! maximal grazing temperature [Celsius] beta = 0. , & ! parameter for temperature dependence of grazing [dimensionless] - sigma_b = 0. , & ! zooplankton loss rate to detritus [1/s] + sigma_b = 0. , & ! zooplankton loss rate to detritus [1/s] oxy_sub = 0. , & ! oxygen level below which reduced respiration starts [mol/kg] oxy_min = 0. , & ! oxygen level below which no respiration takes place [mol/kg] resp_red = 0. , & ! reduction factor for respiration under suboxic conditions [dimensionless] - nue = 0. , & ! zooplankton loss rate to nh4 by respiration [1/s] + nue = 0. , & ! zooplankton loss rate to nh4 by respiration [1/s] food_to_nh4 = 0. , & ! fraction of eaten food directly lost to respiration [dimensionless] food_to_det = 0. , & ! fraction of eaten food directly lost to detritus [dimensionless] food_to_nh4_2 = 0. , & ! fraction of (food that could be eaten at optimal temperature) - ! directly lost to respiration [dimensionless] + ! directly lost to respiration [dimensionless] food_to_det_2 = 0. , & ! fraction of (food that could be eaten at optimal temperature) - ! directly lost to detritus [dimensionless] - iv = 0. , & ! Ivlev constant [kg/mol] - zcl1 = 0. , & ! closure parameter [kg/mol] - graz = 0. , & ! zooplankton maximum grazing rate [1/s] + ! directly lost to detritus [dimensionless] + iv = 0. , & ! Ivlev constant [kg/mol] + zcl1 = 0. , & ! closure parameter [kg/mol] + graz = 0. , & ! zooplankton maximum grazing rate [1/s] z0 = 0. , & ! background concentration for initial growth [mol/kg] - Imax = 0. , & ! maximum light intensity [W/m^2] + Imax = 0. , & ! maximum light intensity [W/m^2] alpha = 0. , & ! light inhibition shape factor o2min = 0. , & ! minimum oxygen concentration where sinking stops [mol/kg] h2smax = 0. , & ! maximum h2s concentration where sinking stops [mol/kg] wtemp = 0. , & ! weight number for temperature sensitivity wo2 = 0. , & ! weight number for o2 sensitivity wh2s = 0. , & ! weight number for h2s sensitivity - wsink0 = 0. , & ! sink velocity (<0 for sinking) [m/s] - wrise0 = 0. , & ! maximum rise velocity (>0 for rising) [m/s] - vdiff_max = 0. , & ! maximum enhanced diffusion + wsink0 = 0. , & ! sink velocity (<0 for sinking) [m/s] + wrise0 = 0. , & ! maximum rise velocity (>0 for rising) [m/s] + vdiff_max = 0. , & ! maximum enhanced diffusion dark_rise = 0. , & ! whether zooplankton rises in the dark independent off a food gradients [dimensionless] - wfood = 0. ! weight number for food gradiens + wfood = 0. ! weight number for food gradiens logical :: & vertical_migration = .false., & ! if true this special undergoes vertical migration blanchard_temperature = .false. ! .false.: old ERGOM temperature dependence, - ! .true. : Blanchard 1996 formula + ! .true. : Blanchard 1996 formula integer :: & - graz_pref = -1 , & ! flag to select grazing preferences - id_jgraz_n = -1 , & ! Diag id for nitrogen grazing (loss) layer integral [mol/m2/s] + graz_pref = -1 , & ! flag to select grazing preferences + id_jgraz_n = -1 , & ! Diag id for nitrogen grazing (loss) layer integral [mol/m2/s] id_jgain_n = -1 , & ! Diag id for nitrogen grazing (gain) layer integral [mol/m2/s] - id_jres_n = -1 , & ! Diag id for nitrogen respiration layer integral [mol/m2/s] - id_jdet_n = -1 , & ! Diag id for nitrogen detritus layer integral [mol/m2/s] - id_vmove = -1 ! Diag id for sink velocity + id_jres_n = -1 , & ! Diag id for nitrogen respiration layer integral [mol/m2/s] + id_jdet_n = -1 , & ! Diag id for nitrogen detritus layer integral [mol/m2/s] + id_vmove = -1 ! Diag id for sink velocity character(len=32) :: & name = 'none' end type zooplankton @@ -302,11 +305,11 @@ module generic_ERGOM ! It must have the same name. real, ALLOCATABLE, dimension(:,:,:) :: & f_n , & ! nitrogen in detritus, the intermediate value after physics [mol/kg] - jgraz_n , & ! nitrogen loss to zooplankton by grazing [mol/kg/s] - jmort ! nitrogen gain in detritus by mortality [mol/kg/s] + jgraz_n , & ! nitrogen loss to zooplankton by grazing [mol/kg/s] + jmort ! nitrogen gain in detritus by mortality [mol/kg/s] real :: & - dn = 0. , & ! recycling rate [1/s] - q10_rec = 0. ! q10 parameter for recycling of detritus [1/Celsius] + dn = 0. , & ! recycling rate [1/s] + q10_rec = 0. ! q10 parameter for recycling of detritus [1/Celsius] integer :: & ! detritus is suspended matter. The data field is in spm(i) index_spm = -1 , & ! stores the index index_spm in spm(index_spm) @@ -321,23 +324,23 @@ module generic_ERGOM ! It contains no own data array. real, ALLOCATABLE, dimension(:,:) :: & bioerosion , & ! local intensity of bioerosion (0.0 to 1.0) - jsed_n , & ! Nitrogen gain by sedimentation [mol/m2/s] - jrec_n , & ! Nitrogen loss to nh4 by recycling [mol/m2/s] - jdenit_sed , & ! Nitrogen loss to n2 by denitrification [mol/m2/s] - mode_sed ! support of bacterial matts + jsed_n , & ! Nitrogen gain by sedimentation [mol/m2/s] + jrec_n , & ! Nitrogen loss to nh4 by recycling [mol/m2/s] + jdenit_sed , & ! Nitrogen loss to n2 by denitrification [mol/m2/s] + mode_sed ! support of bacterial matts real :: & - dn = 0. , & ! recycling rate [1/s] + dn = 0. , & ! recycling rate [1/s] frac_dn_anoxic = 0. , & ! fraction of recycling in shallow sediments for anoxic bottom water [dimensionless] - thio_bact_min = 0. , & ! minimum amount of active sediment for thiomargarita [mol/m2] - q10_rec = 0. , & ! q10 parameter for recycling [1/Celsius] - den_rate = 0. , & ! proportion of denitrification at the redoxcline in sediment - pnr = 0. , & ! P/N ratio - cnr = 0. , & ! C/N ratio - wsed = 0. , & ! sedimentation rate [m/s] + thio_bact_min = 0. , & ! minimum amount of active sediment for thiomargarita [mol/m2] + q10_rec = 0. , & ! q10 parameter for recycling [1/Celsius] + den_rate = 0. , & ! proportion of denitrification at the redoxcline in sediment + pnr = 0. , & ! P/N ratio + cnr = 0. , & ! C/N ratio + wsed = 0. , & ! sedimentation rate [m/s] po4_lib_rate = 0. , & ! liberation rate for iron phosphate in the sediment [1/s] po4_retention = 0. , & ! fraction of phosphorous retained in the sediment while recycled [dimensionless] po4_ret_plus_BB = 0. , & ! value added to po4_retention north of 60.75N - ! (special treatment for the Bothnian Bay to supress cyanobacterial blooms) + ! (special treatment for the Bothnian Bay to supress cyanobacterial blooms) o2_bioerosion = 0. ! oxygen threshold for bioerosion [mol/kg] character(len=32) :: & name_redfield_sed = 'sed' , & ! name of the redfield-ratio sediment variable in sed @@ -355,7 +358,7 @@ module generic_ERGOM ! that is able to settle (such as detritus). ! You should specify "sediment_to" to allow sedimentation to a sed_type tracer. real, ALLOCATABLE, dimension(:,:,:) :: & - move ! sinking velocity (<0 for sinking) [m/s] + move ! sinking velocity (<0 for sinking) [m/s] real, dimension(:,:,:,:), pointer :: & p_wat ! pointer to 3d variable for concentration in water column [mol/kg] real, ALLOCATABLE, dimension(:,:) :: & @@ -363,7 +366,7 @@ module generic_ERGOM real, ALLOCATABLE, dimension(:,:) :: & btf ! The total bottom flux [mol/m2/s] real :: & - wsink0 = 0. , & ! sinking velocity (<0 for sinking) [m/d] + wsink0 = 0. , & ! sinking velocity (<0 for sinking) [m/d] wsed = 0. ! sedimentation rate [m/d] character(len=32) :: & name = 'none' , & ! name of 3d tracer @@ -406,7 +409,7 @@ module generic_ERGOM integer :: & NUM_LAYERS = -1 , & ! Number of vertical layers layer_propagation = -1 , & ! Sediment layer propagation settings, - ! SLP_DOWNWARD=1, SLP_FULL_BOX=2, SLP_OLD_ERGOM=3 + ! SLP_DOWNWARD=1, SLP_FULL_BOX=2, SLP_OLD_ERGOM=3 erosion_mode = -1 ! Sediment erosion mode, INDEPENDENT=1, MAXSTRESS=2, ORGANIC=3 real, allocatable, dimension(:) :: layer_height ! (maximum) height of vertical layers [m]. ! <0 means the layer may become infinitely thick. @@ -469,20 +472,20 @@ module generic_ERGOM integer, parameter :: maxphyt=3, maxzoo=4, maxdet=2 integer, parameter :: maxspm=2, maxsed=2, max_sediment_layers=2 real, dimension(maxphyt) :: & - imin , & ! minimum light [W/m2] - tmin , & ! minimum phytoplankton growth temperature (for cyanobacteria only) [Celsius] - smin , & ! minimum phytoplankton salinity (for diatoms only) - smax , & ! maximum phytoplankton salinity (for diatoms only) - alpha , & ! half-saturation constants of nutrient uptake by phytoplankton [mol/kg] - talpha , & ! Michaeles Menton-like temperature [Celsius] - rp0 , & ! maximum growth rates of phytoplankton [1/d] - p0 , & ! background concentration for initial phytoplankton growth [mol/kg] - np , & ! number of P atoms in uptake - nn , & ! number of N atoms in uptake - nc , & ! number of C atoms in uptake - lpd , & ! loss rate of phytoplankton to detritus [1/d] - lpr , & ! loss rate of phytoplankton by respiration [1/d] - sinkp ! phytoplankton sinking velocity [m/d] + imin , & ! minimum light [W/m2] + tmin , & ! minimum phytoplankton growth temperature (for cyanobacteria only) [Celsius] + smin , & ! minimum phytoplankton salinity (for diatoms only) + smax , & ! maximum phytoplankton salinity (for diatoms only) + alpha , & ! half-saturation constants of nutrient uptake by phytoplankton [mol/kg] + talpha , & ! Michaeles Menton-like temperature [Celsius] + rp0 , & ! maximum growth rates of phytoplankton [1/d] + p0 , & ! background concentration for initial phytoplankton growth [mol/kg] + np , & ! number of P atoms in uptake + nn , & ! number of N atoms in uptake + nc , & ! number of C atoms in uptake + lpd , & ! loss rate of phytoplankton to detritus [1/d] + lpr , & ! loss rate of phytoplankton by respiration [1/d] + sinkp ! phytoplankton sinking velocity [m/d] character(len=32) :: name_phyt(maxphyt) real, dimension(maxzoo) :: & @@ -492,33 +495,33 @@ module generic_ERGOM oxy_sub_zoo , & ! oxygen level below which reduced respiration starts [mol/kg] oxy_min_zoo, & ! oxygen level below which no respiration takes place [mol/kg] resp_red_zoo, & ! reduction factor for respiration under suboxic conditions [dimensionless] - sigma_b, & ! loss rate of zooplankton to detritus [mol/kg/d] - nue , & ! loss rate of zooplankton to nh4 by respiration [mol/kg/d] + sigma_b, & ! loss rate of zooplankton to detritus [mol/kg/d] + nue , & ! loss rate of zooplankton to nh4 by respiration [mol/kg/d] food_to_nh4 , & ! fraction of eaten food that is directly lost to respiration [dimensionless] food_to_det , & ! fraction of eaten food that is directly lost to detritus [dimensionless] food_to_nh4_2 , & ! fraction of food eaten potentially at optimal temperature - ! directly lost to respiration [dimensionless] + ! directly lost to respiration [dimensionless] food_to_det_2 , & ! fraction of food eaten potentially at optimal temperature - ! directly lost to detritus [dimensionless] - iv , & ! Ivlev constant [kg/mol] - zcl1 , & ! closure parameter [kg2/mol2] - graz , & ! zooplankton grazing rate [1/d] - z0 , & ! background concentration for initial zooplankton growth [mol/kg] - Imax , & ! zooplankton maximum light intensity [W/m^2] - alpha_zoo, & ! light inhibition shape factor - sinkz , & ! zooplankton sink velocity (<0 for sinking) [m/d] - risez , & ! zooplankton rise velocity (>0 for rising) [m/d] - vdiff_max , & ! zooplankton maximum enhanced diffusion[m^2/s] - dark_rise,& ! whether zooplankton rises independent off a food gradient in the dark [dimensionless] - wfood , & ! weight for food gradients in zooplankton rise velocity - o2min , & ! minimum oxygen concentration where sinking stops [mol/kg] - h2smax , & ! maximum h2s concentration where sinking stops [mol/kg] - wtemp , & ! weight number for temperature sensitivity - wo2 , & ! weight number for o2 sensitivity - wh2s , & ! weight number for h2s sensitivity - np_zoo , & ! number of P atoms in the zooplankton, Redfield ratio - nn_zoo , & ! number of N atoms in the zooplankton, Redfield ratio - nc_zoo ! number of C atoms in the zooplankton, Redfield ratio + ! directly lost to detritus [dimensionless] + iv , & ! Ivlev constant [kg/mol] + zcl1 , & ! closure parameter [kg2/mol2] + graz , & ! zooplankton grazing rate [1/d] + z0 , & ! background concentration for initial zooplankton growth [mol/kg] + Imax , & ! zooplankton maximum light intensity [W/m^2] + alpha_zoo, & ! light inhibition shape factor + sinkz , & ! zooplankton sink velocity (<0 for sinking) [m/d] + risez , & ! zooplankton rise velocity (>0 for rising) [m/d] + vdiff_max , & ! zooplankton maximum enhanced diffusion[m^2/s] + dark_rise,& ! whether zooplankton rises independent off a food gradient in the dark [dimensionless] + wfood , & ! weight for food gradients in zooplankton rise velocity + o2min , & ! minimum oxygen concentration where sinking stops [mol/kg] + h2smax , & ! maximum h2s concentration where sinking stops [mol/kg] + wtemp , & ! weight number for temperature sensitivity + wo2 , & ! weight number for o2 sensitivity + wh2s , & ! weight number for h2s sensitivity + np_zoo , & ! number of P atoms in the zooplankton, Redfield ratio + nn_zoo , & ! number of N atoms in the zooplankton, Redfield ratio + nc_zoo ! number of C atoms in the zooplankton, Redfield ratio real, dimension(maxzoo,maxphyt) :: pref_phy ! food preferences of zooplankton for phytoplankton real, dimension(maxzoo,maxzoo) :: pref_zoo ! food preferences of zooplankton for zooplankton real, dimension(maxzoo,maxdet) :: pref_det ! food preferences of zooplankton for detritus @@ -526,12 +529,12 @@ module generic_ERGOM character(len=32) :: name_zoo(maxzoo) logical, dimension(maxzoo):: & - vertical_migration, & ! enables zooplankton migration + vertical_migration, & ! enables zooplankton migration blanchard_temperature ! .false.: old ERGOM temperature dependence, .true.: Blanchard 1996 formula real, dimension(maxdet) :: & dn , & ! recycling rate - q10_rec ! q10 parameter for recycling [1/Celsius] + q10_rec ! q10 parameter for recycling [1/Celsius] character(len=32) :: & name_det(maxdet), & name_redfield_sed = 'sed', & @@ -549,16 +552,16 @@ module generic_ERGOM character(len=32) :: & name_spm(maxspm) , & ! name of this type of spm (suspended particulate matter) sediment_to(maxspm) , & ! name of the sed(:) tracer to which sedimentation takes place - longname_spm(maxspm) ! long name for output + longname_spm(maxspm) ! long name for output character(len=32) :: & name_sed(maxsed) , & ! name of this type of sedimented matter suspend_to(maxsed) , & ! name of spm(:) tracer to which the resuspension takes place - longname_sed(maxsed) ! long name for output + longname_sed(maxsed) ! long name for output real, dimension(max_sediment_layers) :: & sed_layer_height ! (maximum) height of vertical layers [m]. - ! < 0: the layer may become infinitely thick. + ! < 0: the layer may become infinitely thick. real :: & nf = .1 , & ! nitrification rate [1/d] q10_nit = .11 , & ! q10 parameter for nitrification [1/Celsius] @@ -568,30 +571,30 @@ module generic_ERGOM k_h2s_no3 = 8.e5 , & ! reaction constant h2s oxidation with no3 [kg/mol/d] k_sul_o2 = 2.e4 , & ! reaction constant sulfur oxidation with o2 [kg/mol/d] k_sul_no3 = 2.e4 , & ! reaction constant sulfur oxidation with no3 [kg/mol/d] - ldn_N = 5.3 , & ! stochiometric ratio no3/det for detritus recycling (denitrification) [1] - ldn_O = 6.625 , & ! stochiometric ratio o2/det for detritus recycling (oxic) [1] - ldn_S = 3.3125 , & ! stochiometric ratio h2s/det for detritus recycling (sulfate reduction) [1] - ldn_A = 13.25 , & ! stochiometric ratio no3/det = nh4/det for detritus recycling (anammox) [1] - alp_o2 = 5.e5 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] - alp_no3 = 2.2e6 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] - alp_h2s = 5.e3 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] - alp_nh4 = 2.2e6 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] - k_an0 = .02 , & ! maximum anammox rate [1/d] - k_DN = 1. , & ! - k_DS = 1. , & ! - den_rate = 0.5 , & ! proportion of denitrification at the sediment redoxcline - dn_sed = 0.003 , & ! recycling rate of detritus in the sediment [1/d] + ldn_N = 5.3 , & ! stochiometric ratio no3/det for detritus recycling (denitrification) [1] + ldn_O = 6.625 , & ! stochiometric ratio o2/det for detritus recycling (oxic) [1] + ldn_S = 3.3125 , & ! stochiometric ratio h2s/det for detritus recycling (sulfate reduction) [1] + ldn_A = 13.25 , & ! stochiometric ratio no3/det = nh4/det for detritus recycling (anammox) [1] + alp_o2 = 5.e5 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] + alp_no3 = 2.2e6 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] + alp_h2s = 5.e3 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] + alp_nh4 = 2.2e6 , & ! smooth oxygen swithch function for detritus recycling [kg/mol] + k_an0 = .02 , & ! maximum anammox rate [1/d] + k_DN = 1. , & ! + k_DS = 1. , & ! + den_rate = 0.5 , & ! proportion of denitrification at the sediment redoxcline + dn_sed = 0.003 , & ! recycling rate of detritus in the sediment [1/d] frac_dn_anoxic = 0.3 , & ! fraction of recycling rate in shallow sediments for anoxic bottom water [dimensionless] thio_bact_min = 1.0 , & ! minimum nitrogen content of active sediment for thiomargarita [mol/m2] - q10_rec_sed = 0.0693 , & ! q10 paramter for recycling of detritus in the sediment - np_sed = 1. , & ! number of P atoms in the sediment, Redfield ratio + q10_rec_sed = 0.0693 , & ! q10 paramter for recycling of detritus in the sediment + np_sed = 1. , & ! number of P atoms in the sediment, Redfield ratio nn_sed = 16. , & ! number of N atoms in the sediment, Redfield ratio nc_sed = 106. , & ! number of C atoms in the sediment, Redfield ratio - po4_lib_rate = 0., & ! fraction of phosphorous retained in the sediment while recycled [1/d] - po4_retention = 0., & ! fraction of phosphorous retained in the sediment while recycled [dimensionless] + po4_lib_rate = 0., & ! fraction of phosphorous retained in the sediment while recycled [1/d] + po4_retention = 0., & ! fraction of phosphorous retained in the sediment while recycled [dimensionless] po4_ret_plus_BB = 0., & ! value added to po4_retention north of 60.75N - ! (special treatment for the Bothnian Bay to supress cyanobacterial blooms) - o2_bioerosion = 6.5e-5 ! oxygen thresold to enable bioerosion [mol/kg] + ! (special treatment for the Bothnian Bay to supress cyanobacterial blooms) + o2_bioerosion = 6.5e-5 ! oxygen thresold to enable bioerosion [mol/kg] integer :: NUM_PHYTO = 3 integer :: NUM_ZOO = 1 @@ -653,11 +656,11 @@ module generic_ERGOM data (z0 (n), n=1, maxzoo) /1.0e-9, 1.0e-9, 1.0e-9, 1.0e-9/ ! background concentration for initial growth [mol/kg] data (sigma_b(n), n=1, maxzoo) /0.03, 0.03, 0.03, 0.03/ ! loss rate of zooplankton to detritus [mol/kg/d] - data (t_opt_zoo(n), n=1, maxzoo) /15.0, 10.0, 10.0, 10.0/ ! temperature optimum of zooplankton for grazing [Celsius] - data (t_max_zoo(n), n=1, maxzoo) /25.0, 15.0, 15.0, 15.0/ ! maximal grazing temperature [Celsius] + data (t_opt_zoo(n), n=1, maxzoo) /15.0, 10.0, 10.0, 10.0/ ! temperature optimum of zooplankton for grazing [Celsius] + data (t_max_zoo(n), n=1, maxzoo) /25.0, 15.0, 15.0, 15.0/ ! maximal grazing temperature [Celsius] data (beta_zoo(n), n=1, maxzoo) /1.7, 1.7, 1.7, 1.7/ ! parameter for temperature dependence of grazing ! [dimensionless] - data (oxy_sub_zoo(n), n=1, maxzoo) /60.e-6, 60.e-6, 60.e-6, 60.e-6/ + data (oxy_sub_zoo(n), n=1, maxzoo) /60.e-6, 60.e-6, 60.e-6, 60.e-6/ ! threshold oxygen level for reduced respiration [mol/kg] data (oxy_min_zoo(n), n=1, maxzoo) /5.e-6, 5.e-6, 5.e-6, 5.e-6/ ! threshold level for no respiration [mol/kg] @@ -669,10 +672,10 @@ module generic_ERGOM data (Imax (n), n=1, maxzoo) /0.1, 0.1, 0.1, 0.1/ ! maximum light 10µE/m^2 / 4.6 data (o2min (n), n=1, maxzoo) /5.e-6, 5.e-6, 5.e-6, 5.e-6/ ! minimum oxygen concentration where sinking stops [mol/kg] data (h2smax (n), n=1, maxzoo) /1.e-6, 1.e-6, 1.e-6, 1.e-6/ ! maximum h2s concentration where sinking stops [mol/kg] - data (wtemp (n), n=1, maxzoo) /1., 1., 1., 1. / ! weight number for temperature sensitivity - data (wo2 (n), n=1, maxzoo) /1., 1., 1., 1. / ! weight number for o2 sensitivity - data (wh2s (n), n=1, maxzoo) /1., 1., 1., 1. / ! weight number for h2s sensitivity - data (np_zoo (n), n=1, maxzoo) /1., 1., 1., 1. / ! number of P atoms in the zooplankton + data (wtemp (n), n=1, maxzoo) /1., 1., 1., 1. / ! weight number for temperature sensitivity + data (wo2 (n), n=1, maxzoo) /1., 1., 1., 1. / ! weight number for o2 sensitivity + data (wh2s (n), n=1, maxzoo) /1., 1., 1., 1. / ! weight number for h2s sensitivity + data (np_zoo (n), n=1, maxzoo) /1., 1., 1., 1. / ! number of P atoms in the zooplankton data (nn_zoo (n), n=1, maxzoo) /16., 16., 16., 16. / ! number of N atoms in the zooplankton data (nc_zoo (n), n=1, maxzoo) /106., 106., 106., 106./ ! number of C atoms in the zooplankton data (alpha_zoo(n), n=1, maxzoo) /0., 0.012, 0.012, 0.012/ ! light inhibitation parameter @@ -688,31 +691,31 @@ module generic_ERGOM /0.39, 0.29, 0. ,0.29, & 0.39, 0.29, 0. ,0.29, & 0.02, 0.02, 0. ,0.02 & - / ! + / ! data ((pref_zoo(n, m), n=1, maxzoo), m=1, maxzoo)& /0. , 0.2, 0.5, 0., & 0. , 0. , 0.2, 0., & 0. , 0. , 0.1, 0., & 0. , 0. , 0., 0. & - / ! + / ! data ((pref_det(n, m), n=1, maxzoo), m=1, maxdet)& /0.2, 0.2, 0.2, 0.0, & 0. , 0.0, 0.0, 0.0 & - / ! + / ! data (name_zoo(n), n=1, maxzoo) /'cop','kr1','kr2','sal'/ ! data (graz_pref (n), n=1, maxzoo) /ERGOM_PREFS,GENUS_IVLEV,GENUS_IVLEV,0/ ! flag to select grazing preferences - data (dn (n), n=1, maxdet) /0.003, 0.003 / ! recycling rate of detritus [1/d] - data (q10_rec(n), n=1, maxdet) /0.0693, 0.0693/ ! q10 paramter for recycling of detritus [1/Celsius] + data (dn (n), n=1, maxdet) /0.003, 0.003 / ! recycling rate of detritus [1/d] + data (q10_rec(n), n=1, maxdet) /0.0693, 0.0693/ ! q10 paramter for recycling of detritus [1/Celsius] data (name_det(n), n=1, maxdet) /'det','fast'/ ! - data(wsink0_spm (n) , n=1, maxspm) /-3.0, -1.0/ ! sinking velocity (<0 for sinking) [m/d] - data(wsed_spm (n) , n=1, maxspm) / 2.5, 0.5/ ! sedimentation rate [m/d] - data(name_spm(n) , n=1, maxspm) /'det','ipw'/ ! name of spm tracer - data(sediment_to(n) , n=1, maxspm) /'none','none'/ ! name of sed tracer to which sedimentation takes place + data(wsink0_spm (n) , n=1, maxspm) /-3.0, -1.0/ ! sinking velocity (<0 for sinking) [m/d] + data(wsed_spm (n) , n=1, maxspm) / 2.5, 0.5/ ! sedimentation rate [m/d] + data(name_spm(n) , n=1, maxspm) /'det','ipw'/ ! name of spm tracer + data(sediment_to(n) , n=1, maxspm) /'none','none'/ ! name of sed tracer to which sedimentation takes place - data(name_sed(n) , n=1, maxsed) /'sed','ips'/ ! name of sed tracer - data(suspend_to(n) , n=1, maxsed) /'none','none'/ ! name of spm tracer to which resuspension takes place + data(name_sed(n) , n=1, maxsed) /'sed','ips'/ ! name of sed tracer + data(suspend_to(n) , n=1, maxsed) /'none','none'/ ! name of spm tracer to which resuspension takes place data(longname_sed(n), n=1, maxsed) /'detritus','iron phosphate'/ ! long name for output data(erosion_rate_sed(n), n=1, maxsed) /6.0, 6.0/ ! erosion rate [1/d] @@ -771,7 +774,7 @@ module generic_ERGOM food_to_det , & ! fraction of eaten food that is directly lost to detritus [dimensionless] food_to_nh4_2, & ! fraction of food eaten potentially, directly lost to respiration [dimensionless] food_to_det_2, & ! fraction of food eaten potentially, directly lost to detritus [dimensionless] - iv , & ! Ivlev paramter for zooplankton grazing [kg/mol] + iv , & ! Ivlev paramter for zooplankton grazing [kg/mol] zcl1 , & ! closure parameter for zooplankton [kg/mol] graz , & ! zooplankton maximum grazing rate [1/d] z0 , & ! background concentration for initial zooplankton growth [mol/kg] @@ -785,10 +788,10 @@ module generic_ERGOM graz_pref , & ! flag to select grazing preferences ! detritus parameters name_det , & ! name of detritus, must be equal to a suspended particulate matter (spm) variable name - dn , & ! recycling rate [1/d] + dn , & ! recycling rate [1/d] q10_rec , & ! q10 paramter for recycling of detritus [1/Celsius] ! generic_ERGOM_type parameters - nf , & ! nitrification rate [1/d] + nf , & ! nitrification rate [1/d] q10_nit , & ! q10 parameter for nitrification [1/Celsius] alpha_nit , & ! half-saturation constant for nitrification [mol/kg] q10_h2s , & ! q10 parameter for chemolithotrophs (h2s oxidation) [1/Celsius] @@ -842,18 +845,29 @@ module generic_ERGOM subroutine generic_ERGOM_register(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_register' character(len=fm_string_len) :: errorstring integer :: ioun, io_status, ierr, i, j logical :: found + integer :: stdoutunit,stdlogunit + + stdoutunit=stdout();stdlogunit=stdlog() + + call write_version_number( version, tagname ) ! provide for namelist over-ride of defaults +#ifdef INTERNAL_FILE_NML + read (input_nml_file, nml=ergom_nml, iostat=io_status) +#else ioun = open_namelist_file() read (ioun, ergom_nml,iostat=io_status) - write (stdout(),'(/)') - write (stdout(), ergom_nml) - write (stdlog(), ergom_nml) - ierr = check_nml_error(io_status,'ergom_nml') call close_file (ioun) +#endif + ierr = check_nml_error(io_status,'ergom_nml') + + write (stdoutunit,'(/)') + write (stdoutunit, ergom_nml) + write (stdlogunit, ergom_nml) allocate(phyto (NUM_PHYTO) ) allocate(zoo (NUM_ZOO) ) @@ -869,23 +883,23 @@ subroutine generic_ERGOM_register(tracer_list) found = .false. sed(i)%index_suspend_to = -1 do j=1,NUM_SPM - if (trim(adjustl(suspend_to(i))) .eq. trim(adjustl(name_spm(j)))) then - found = .true. - sed(i)%index_suspend_to = j - endif + if (trim(adjustl(suspend_to(i))) .eq. trim(adjustl(name_spm(j)))) then + found = .true. + sed(i)%index_suspend_to = j + endif enddo if (.not. found) then - if ((trim(adjustl(suspend_to(i))) .eq. 'none') .and. (NUM_SPM .eq. NUM_SED)) then - sed(i)%index_suspend_to = i - else + if ((trim(adjustl(suspend_to(i))) .eq. 'none') .and. (NUM_SPM .eq. NUM_SED)) then + sed(i)%index_suspend_to = i + else write(errorstring, '(a)') & - 'Error: settled matter tracer '// & - trim(adjustl(name_sed(i))) // & - ' shall be resuspended to tracer ' // & - trim(adjustl(suspend_to(i))) // & - ', but that does not exist as an spm tracer.' - call mpp_error(FATAL, errorstring) - endif + 'Error: settled matter tracer '// & + trim(adjustl(name_sed(i))) // & + ' shall be resuspended to tracer ' // & + trim(adjustl(suspend_to(i))) // & + ', but that does not exist as an spm tracer.' + call mpp_error(FATAL, errorstring) + endif endif enddo ! B) Set the values in det @@ -898,10 +912,10 @@ subroutine generic_ERGOM_register(tracer_list) endif enddo if (.not. found) then - write(errorstring, '(a)') & - 'Error: detritus tracer '// & - trim(adjustl(name_det(i))) // & - ' does not exist as a suspended particulate matter (spm) tracer.' + write(errorstring, '(a)') & + 'Error: detritus tracer '// & + trim(adjustl(name_det(i))) // & + ' does not exist as a suspended particulate matter (spm) tracer.' call mpp_error(FATAL, errorstring) endif enddo @@ -913,23 +927,23 @@ subroutine generic_ERGOM_register(tracer_list) found = .false. spm(i)%index_sediment_to = -1 do j=1,NUM_SED - if (trim(adjustl(sediment_to(i))) .eq. trim(adjustl(name_sed(j)))) then - found = .true. - spm(i)%index_sediment_to = j - endif + if (trim(adjustl(sediment_to(i))) .eq. trim(adjustl(name_sed(j)))) then + found = .true. + spm(i)%index_sediment_to = j + endif enddo if (.not. found) then - if ((trim(adjustl(sediment_to(i))) .eq. 'none') .and. (NUM_SPM .eq. NUM_SED)) then - spm(i)%index_sediment_to = i - else + if ((trim(adjustl(sediment_to(i))) .eq. 'none') .and. (NUM_SPM .eq. NUM_SED)) then + spm(i)%index_sediment_to = i + else write(errorstring, '(a)') & 'Error: suspended particulate matter (spm) tracer '// & - trim(adjustl(name_spm(i))) // & - ' shall be sedimented to tracer ' // & - trim(adjustl(sediment_to(i))) // & - ', but that does not exist as a settled matter (sed) tracer.' - call mpp_error(FATAL, errorstring) - endif + trim(adjustl(name_spm(i))) // & + ' shall be sedimented to tracer ' // & + trim(adjustl(sediment_to(i))) // & + ', but that does not exist as a settled matter (sed) tracer.' + call mpp_error(FATAL, errorstring) + endif endif enddo ! C) Set the values in biosed @@ -959,7 +973,7 @@ subroutine generic_ERGOM_register(tracer_list) 'Error: iron phosphate sediment tracer '// & trim(adjustl(name_iron_phosphate)) // & ' does not exist as a settled matter (sed) tracer, '// & - 'but po4_retention is not zero.' + 'but po4_retention is not zero.' call mpp_error(FATAL, errorstring) endif @@ -994,23 +1008,17 @@ end subroutine generic_ERGOM_register subroutine generic_ERGOM_init(tracer_list) type(g_tracer_type), pointer :: tracer_list - integer :: ioun, io_status, ierr - + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_init' + integer :: stdoutunit,stdlogunit + + stdoutunit=stdout();stdlogunit=stdlog() + id_init = mpp_clock_id('(ERGOM init) ' ,grain=CLOCK_ROUTINE) id_alloc = mpp_clock_id('(ERGOM allocate) ' ,grain=CLOCK_ROUTINE) id_source = mpp_clock_id('(ERGOM source terms) ' ,grain=CLOCK_ROUTINE) id_susp = mpp_clock_id('(ERGOM resuspension) ' ,grain=CLOCK_ROUTINE) call mpp_clock_begin(id_init) - ! provide for namelist over-ride of defaults - ioun = open_namelist_file() - read (ioun, ergom_nml,iostat=io_status) - write (stdout(),'(/)') - write (stdout(), ergom_nml) - write (stdlog(), ergom_nml) - ierr = check_nml_error(io_status,'ergom_nml') - call close_file (ioun) - !Specify and initialize all parameters used by this package call user_add_params @@ -1018,152 +1026,152 @@ subroutine generic_ERGOM_init(tracer_list) call user_allocate_arrays ! now print a summary of all parameters - write (stdout(),'(/)') - write (stdout(),*) 'Summary of the ERGOM model setup' - write (stdout(),'(a,I2)') 'Number of phytoplankton types : ', NUM_PHYTO - write (stdout(),'(a,I2)') 'Number of zoooplankton types : ', NUM_ZOO - write (stdout(),'(a,I2)') 'Number of detritus types : ', NUM_DET - write (stdout(),'(a,I2)') 'Number of SPM types : ', NUM_SPM - write (stdout(),'(a,I2)') 'Number of settled matter types: ', NUM_SED + write (stdoutunit,'(/)') + write (stdoutunit,*) 'Summary of the ERGOM model setup' + write (stdoutunit,'(a,I2)') 'Number of phytoplankton types : ', NUM_PHYTO + write (stdoutunit,'(a,I2)') 'Number of zoooplankton types : ', NUM_ZOO + write (stdoutunit,'(a,I2)') 'Number of detritus types : ', NUM_DET + write (stdoutunit,'(a,I2)') 'Number of SPM types : ', NUM_SPM + write (stdoutunit,'(a,I2)') 'Number of settled matter types: ', NUM_SED do n=1, NUM_PHYTO - write (stdout(),'(a)') phyto(n)%name//':' - write (stdout(),'(a)') ' Parameters: ' - write (stdout(),'((a), e13.6)')' P/N ratio, pnr : ', phyto(n)%pnr - write (stdout(),'((a), e13.6)')' C/N ratio, cnr : ', phyto(n)%cnr - write (stdout(),'((a), e13.6)')' seed concentration, p0, [mol/kg] : ', phyto(n)%p0 - write (stdout(),'(a)') ' Parameters for growth: ' - write (stdout(),'((a), e13.6)')' minimum light imin [W/m2] : ', phyto(n)%imin - write (stdout(),'((a), e13.6)')' minimum temperature tmin [C] : ', phyto(n)%tmin - write (stdout(),'((a), e13.6)')' minimum phytoplankton salinity smin [g/kg] : ', phyto(n)%smin - write (stdout(),'((a), e13.6)')' maximum phytoplankton salinity smax [g/kg] : ', phyto(n)%smax - write (stdout(),'((a), e13.6)')' DIN half-sat constant, alpha [mol/kg] : ', phyto(n)%alpha - write (stdout(),'((a), e13.6)')' temperature dep. uptake, talpha [Celsius] : ', phyto(n)%talpha - write (stdout(),'((a), e13.6)')' maximum uptake rate rp0 [1/s] : ', phyto(n)%rp0 - write (stdout(),'(a)') ' Parameters for losses: ' - write (stdout(),'((a), e13.6)')' loss to detritus, lpd [1/s] : ', phyto(n)%lpd - write (stdout(),'((a), e13.6)')' loss by respiration, lpr [1/s] : ', phyto(n)%lpr - write (stdout(),'((a), e13.6)')' sinking velocity, wsink0 [m/s] : ', phyto(n)%wsink0 - write (stdout(),'(/)') + write (stdoutunit,'(a)') phyto(n)%name//':' + write (stdoutunit,'(a)') ' Parameters: ' + write (stdoutunit,'((a), e13.6)')' P/N ratio, pnr : ', phyto(n)%pnr + write (stdoutunit,'((a), e13.6)')' C/N ratio, cnr : ', phyto(n)%cnr + write (stdoutunit,'((a), e13.6)')' seed concentration, p0, [mol/kg] : ', phyto(n)%p0 + write (stdoutunit,'(a)') ' Parameters for growth: ' + write (stdoutunit,'((a), e13.6)')' minimum light imin [W/m2] : ', phyto(n)%imin + write (stdoutunit,'((a), e13.6)')' minimum temperature tmin [C] : ', phyto(n)%tmin + write (stdoutunit,'((a), e13.6)')' minimum phytoplankton salinity smin [g/kg] : ', phyto(n)%smin + write (stdoutunit,'((a), e13.6)')' maximum phytoplankton salinity smax [g/kg] : ', phyto(n)%smax + write (stdoutunit,'((a), e13.6)')' DIN half-sat constant, alpha [mol/kg] : ', phyto(n)%alpha + write (stdoutunit,'((a), e13.6)')' temperature dep. uptake, talpha [Celsius] : ', phyto(n)%talpha + write (stdoutunit,'((a), e13.6)')' maximum uptake rate rp0 [1/s] : ', phyto(n)%rp0 + write (stdoutunit,'(a)') ' Parameters for losses: ' + write (stdoutunit,'((a), e13.6)')' loss to detritus, lpd [1/s] : ', phyto(n)%lpd + write (stdoutunit,'((a), e13.6)')' loss by respiration, lpr [1/s] : ', phyto(n)%lpr + write (stdoutunit,'((a), e13.6)')' sinking velocity, wsink0 [m/s] : ', phyto(n)%wsink0 + write (stdoutunit,'(/)') enddo do n=1, NUM_ZOO - write (stdout(),'(a)') zoo(n)%name//':' - write (stdout(),'(a,(5f7.4,2x))')' Grazing preferences phytoplankton : ', & + write (stdoutunit,'(a)') zoo(n)%name//':' + write (stdoutunit,'(a,(5f7.4,2x))')' Grazing preferences phytoplankton : ', & (zoo(n)%pref_phy(m),m=1,NUM_PHYTO) - write (stdout(),'(a,(5f7.4,2x))')' Grazing preferences zooplankton : ', & + write (stdoutunit,'(a,(5f7.4,2x))')' Grazing preferences zooplankton : ', & (zoo(n)%pref_zoo(m),m=1,NUM_ZOO) - write (stdout(),'(a,(5f7.4,2x))')' Grazing preferences detritus : ', & + write (stdoutunit,'(a,(5f7.4,2x))')' Grazing preferences detritus : ', & (zoo(n)%pref_det(m),m=1,NUM_DET) - write (stdout(),'(a)') ' Parameters: ' - write (stdout(),'((a), e13.6)') ' P/N ratio, pnr : ', zoo(n)%pnr - write (stdout(),'((a), e13.6)') ' C/N ratio, cnr : ', zoo(n)%cnr - write (stdout(),'((a), e13.6)') ' seed concentration, z0, [mol/kg] : ', zoo(n)%z0 - write (stdout(),'(a)') ' Parameters for grazing: ' - write (stdout(),'((a), I2)') ' grazing preference method : ', zoo(n)%graz_pref - write (stdout(),'((a), e13.6)') ' Ivlev constant, iv, [kg/mol] : ', zoo(n)%iv - write (stdout(),'((a), e13.6)') ' maximum grazing rate, graz, [1/s] : ', zoo(n)%graz - write (stdout(),'((a), e13.6)') ' maximal grazing temperature, t_max [C] : ', zoo(n)%t_max - write (stdout(),'((a), e13.6)') ' optimal grazing temperature, t_opt [C] : ', zoo(n)%t_opt - write (stdout(),'((a), e13.6)') ' parameter for temperature dependence, beta : ', zoo(n)%beta - write (stdout(),'((a), e13.6)') ' fraction lost to respiration, food_to_nh4 : ', zoo(n)%food_to_nh4 - write (stdout(),'((a), e13.6)') ' fraction lost to detritus : ', zoo(n)%food_to_det - write (stdout(),'(a)') ' Parameters for migration: ' + write (stdoutunit,'(a)') ' Parameters: ' + write (stdoutunit,'((a), e13.6)') ' P/N ratio, pnr : ', zoo(n)%pnr + write (stdoutunit,'((a), e13.6)') ' C/N ratio, cnr : ', zoo(n)%cnr + write (stdoutunit,'((a), e13.6)') ' seed concentration, z0, [mol/kg] : ', zoo(n)%z0 + write (stdoutunit,'(a)') ' Parameters for grazing: ' + write (stdoutunit,'((a), I2)') ' grazing preference method : ', zoo(n)%graz_pref + write (stdoutunit,'((a), e13.6)') ' Ivlev constant, iv, [kg/mol] : ', zoo(n)%iv + write (stdoutunit,'((a), e13.6)') ' maximum grazing rate, graz, [1/s] : ', zoo(n)%graz + write (stdoutunit,'((a), e13.6)') ' maximal grazing temperature, t_max [C] : ', zoo(n)%t_max + write (stdoutunit,'((a), e13.6)') ' optimal grazing temperature, t_opt [C] : ', zoo(n)%t_opt + write (stdoutunit,'((a), e13.6)') ' parameter for temperature dependence, beta : ', zoo(n)%beta + write (stdoutunit,'((a), e13.6)') ' fraction lost to respiration, food_to_nh4 : ', zoo(n)%food_to_nh4 + write (stdoutunit,'((a), e13.6)') ' fraction lost to detritus : ', zoo(n)%food_to_det + write (stdoutunit,'(a)') ' Parameters for migration: ' if (zoo(n)%vertical_migration) then - write (stdout(),'(a)') ' migrating ' - write (stdout(),'((a), e13.6)')' maximum light intensity, Imax [W/m^2] : ', zoo(n)%imax - write (stdout(),'((a), e13.6)')' minimum oxygen conc., o2min [mol/kg] : ', zoo(n)%o2min - write (stdout(),'((a), e13.6)')' maximal temp for migration, t_max [C] : ', zoo(n)%t_max - write (stdout(),'((a), e13.6)')' maximum rise velocity, wrise0 [m/s] : ', zoo(n)%wrise0 - write (stdout(),'((a), e13.6)')' maximum sink velocity, wsink0 [m/s] : ', zoo(n)%wsink0 - write (stdout(),'((a), e13.6)')' maximum enhanced diff., vdiff_max [m2/s] : ', zoo(n)%vdiff_max + write (stdoutunit,'(a)') ' migrating ' + write (stdoutunit,'((a), e13.6)')' maximum light intensity, Imax [W/m^2] : ', zoo(n)%imax + write (stdoutunit,'((a), e13.6)')' minimum oxygen conc., o2min [mol/kg] : ', zoo(n)%o2min + write (stdoutunit,'((a), e13.6)')' maximal temp for migration, t_max [C] : ', zoo(n)%t_max + write (stdoutunit,'((a), e13.6)')' maximum rise velocity, wrise0 [m/s] : ', zoo(n)%wrise0 + write (stdoutunit,'((a), e13.6)')' maximum sink velocity, wsink0 [m/s] : ', zoo(n)%wsink0 + write (stdoutunit,'((a), e13.6)')' maximum enhanced diff., vdiff_max [m2/s] : ', zoo(n)%vdiff_max else - write (stdout(),'(a)') ' not migrating ' + write (stdoutunit,'(a)') ' not migrating ' endif - write (stdout(),'(a)') ' Closure term: ' - write (stdout(),'((a), e13.6)') ' closure parameter, zcl1 [kg/mol] : ', zoo(n)%zcl1 - write (stdout(),'((a), e13.6)') ' loss rate by respiration, nue [1/s] : ', zoo(n)%nue - write (stdout(),'((a), e13.6)') ' loss rate to detritus, sigma_b [1/s] : ', zoo(n)%sigma_b - write (stdout(),'(a)') ' Respiration: ' - write (stdout(),'((a), e13.6)') ' reduction factor for respiration, resp_red : ', zoo(n)%resp_red - write (stdout(),'((a), e13.6)') ' max oxy. f. reduced resp., oxy_sub [mol/kg]: ', zoo(n)%oxy_sub - write (stdout(),'((a), e13.6)') ' min oxy. f. resp., oxy_min [mol/kg] : ', zoo(n)%oxy_min - - write (stdout(),'(/)') + write (stdoutunit,'(a)') ' Closure term: ' + write (stdoutunit,'((a), e13.6)') ' closure parameter, zcl1 [kg/mol] : ', zoo(n)%zcl1 + write (stdoutunit,'((a), e13.6)') ' loss rate by respiration, nue [1/s] : ', zoo(n)%nue + write (stdoutunit,'((a), e13.6)') ' loss rate to detritus, sigma_b [1/s] : ', zoo(n)%sigma_b + write (stdoutunit,'(a)') ' Respiration: ' + write (stdoutunit,'((a), e13.6)') ' reduction factor for respiration, resp_red : ', zoo(n)%resp_red + write (stdoutunit,'((a), e13.6)') ' max oxy. f. reduced resp., oxy_sub [mol/kg]: ', zoo(n)%oxy_sub + write (stdoutunit,'((a), e13.6)') ' min oxy. f. resp., oxy_min [mol/kg] : ', zoo(n)%oxy_min + + write (stdoutunit,'(/)') enddo do n=1, NUM_DET - write (stdout(),'(a)') det(n)%name//':' - write (stdout(),'(/)') + write (stdoutunit,'(a)') det(n)%name//':' + write (stdoutunit,'(/)') enddo do n=1, NUM_SPM - write (stdout(),'(a)') trim(spm(n)%name)//':' - write (stdout(),'((a), e13.6)') ' sinking velocity, wsink0 [m/d] : ', spm(n)%wsink0 - write (stdout(),'((a), e13.6)') ' sedimentation rate, wsed [m/d] : ', spm(n)%wsed - write (stdout(),'((a), (a))') ' will sediment to tracer, (sediment_to) : ', trim(sed(spm(n)%index_sediment_to)%name) + write (stdoutunit,'(a)') trim(spm(n)%name)//':' + write (stdoutunit,'((a), e13.6)') ' sinking velocity, wsink0 [m/d] : ', spm(n)%wsink0 + write (stdoutunit,'((a), e13.6)') ' sedimentation rate, wsed [m/d] : ', spm(n)%wsed + write (stdoutunit,'((a), (a))') ' will sediment to tracer, (sediment_to) : ', trim(sed(spm(n)%index_sediment_to)%name) enddo do n=1, NUM_SED - write (stdout(),'(a)') trim(sed(n)%name)//':' - write (stdout(),'((a), e13.6)') ' critical shear stress, critical_stress [N/m2]: ', sed(n)%critical_stress - write (stdout(),'((a), (a))') ' will be resuspended to tracer, (suspend_to) : ', trim(spm(sed(n)%index_suspend_to)%name) + write (stdoutunit,'(a)') trim(sed(n)%name)//':' + write (stdoutunit,'((a), e13.6)') ' critical shear stress, critical_stress [N/m2]: ', sed(n)%critical_stress + write (stdoutunit,'((a), (a))') ' will be resuspended to tracer, (suspend_to) : ', trim(spm(sed(n)%index_suspend_to)%name) enddo - write (stdout(),'(a)') 'Sediment parameters:' - write (stdout(),'((a), e13.6)') ' recycling rate, dn [1/s] : ', & - biosed%dn - write (stdout(),'((a), e13.6)') ' frac. rec.-rate in shallow sediments when anoxic, frac_dn_anoxic : ', & + write (stdoutunit,'(a)') 'Sediment parameters:' + write (stdoutunit,'((a), e13.6)') ' recycling rate, dn [1/s] : ', & + biosed%dn + write (stdoutunit,'((a), e13.6)') ' frac. rec.-rate in shallow sediments when anoxic, frac_dn_anoxic : ', & biosed%frac_dn_anoxic - write (stdout(),'((a), e13.6)') ' minimum amount of active sed for thiomargarita, thio_bact_min [mol/m2]: ', & + write (stdoutunit,'((a), e13.6)') ' minimum amount of active sed for thiomargarita, thio_bact_min [mol/m2]: ', & biosed%thio_bact_min - write (stdout(),'((a), e13.6)') ' q10 parameter for recycling, q10_rec [1/C] : ', & - biosed%q10_rec - write (stdout(),'((a), e13.6)') ' proportion of denit in sediment, den_rate : ', & + write (stdoutunit,'((a), e13.6)') ' q10 parameter for recycling, q10_rec [1/C] : ', & + biosed%q10_rec + write (stdoutunit,'((a), e13.6)') ' proportion of denit in sediment, den_rate : ', & biosed%den_rate - write (stdout(),'((a), e13.6)') ' P/N ratio, pnr : ', & - biosed%pnr - write (stdout(),'((a), e13.6)') ' C/N ratio, cnr : ', & - biosed%cnr - write (stdout(),'((a), e13.6)') ' liberation rate for iron phosphate, po4_lib_rate [1/s] : ', & + write (stdoutunit,'((a), e13.6)') ' P/N ratio, pnr : ', & + biosed%pnr + write (stdoutunit,'((a), e13.6)') ' C/N ratio, cnr : ', & + biosed%cnr + write (stdoutunit,'((a), e13.6)') ' liberation rate for iron phosphate, po4_lib_rate [1/s] : ', & biosed%po4_lib_rate - write (stdout(),'((a), e13.6)') ' fraction of phosphorous retained in the sediment, po4_retention : ', & + write (stdoutunit,'((a), e13.6)') ' fraction of phosphorous retained in the sediment, po4_retention : ', & biosed%po4_retention - write (stdout(),'((a), e13.6)') ' value added to po4_retention north of 60.75N, po4_ret_plus_BB : ', & + write (stdoutunit,'((a), e13.6)') ' value added to po4_retention north of 60.75N, po4_ret_plus_BB : ', & biosed%po4_ret_plus_BB - write (stdout(),'(/)') - write (stdout(),'(a)') 'Ergom parameters:' - write (stdout(),'((a), e13.6)') ' q10 parameter for nitrification, q10_nit [1/C] : ', & + write (stdoutunit,'(/)') + write (stdoutunit,'(a)') 'Ergom parameters:' + write (stdoutunit,'((a), e13.6)') ' q10 parameter for nitrification, q10_nit [1/C] : ', & ergom%q10_nit - write (stdout(),'((a), e13.6)') ' q10 parameter for chemolithotrophs (so4 reduction), q10_h2s [1/C] : ', & + write (stdoutunit,'((a), e13.6)') ' q10 parameter for chemolithotrophs (so4 reduction), q10_h2s [1/C] : ', & ergom%q10_h2s - write (stdout(),'((a), e13.6)') ' nitrification rate, nf [1/s] : ', & + write (stdoutunit,'((a), e13.6)') ' nitrification rate, nf [1/s] : ', & ergom%nf - write (stdout(),'((a), e13.6)') ' half-saturation constant for nitrification, alpha_nit [mol/kg] : ', & + write (stdoutunit,'((a), e13.6)') ' half-saturation constant for nitrification, alpha_nit [mol/kg] : ', & ergom%alpha_nit - write (stdout(),'((a), e13.6)') ' slope function for detritus recycling, alp_o2 [kg/mol] : ', & + write (stdoutunit,'((a), e13.6)') ' slope function for detritus recycling, alp_o2 [kg/mol] : ', & ergom%alp_o2 - write (stdout(),'((a), e13.6)') ' slope function for detritus recycling, alp_no3 [kg/mol] : ', & + write (stdoutunit,'((a), e13.6)') ' slope function for detritus recycling, alp_no3 [kg/mol] : ', & ergom%alp_no3 - write (stdout(),'((a), e13.6)') ' slope function for detritus recycling, alp_h2s [kg/mol] : ', & + write (stdoutunit,'((a), e13.6)') ' slope function for detritus recycling, alp_h2s [kg/mol] : ', & ergom%alp_h2s - write (stdout(),'((a), e13.6)') ' slope function for detritus recycling, alp_nh4 [kg/mol] : ', & + write (stdoutunit,'((a), e13.6)') ' slope function for detritus recycling, alp_nh4 [kg/mol] : ', & ergom%alp_nh4 - write (stdout(),'((a), e13.6)') ' reaction constant h2s oxidation with o2, k_h2s_o2 [kg/mol/s] : ', & + write (stdoutunit,'((a), e13.6)') ' reaction constant h2s oxidation with o2, k_h2s_o2 [kg/mol/s] : ', & ergom%k_h2s_o2 - write (stdout(),'((a), e13.6)') ' reaction constant h2s oxidation with no3, k_h2s_no3 [kg/mol/s] : ', & + write (stdoutunit,'((a), e13.6)') ' reaction constant h2s oxidation with no3, k_h2s_no3 [kg/mol/s] : ', & ergom%k_h2s_no3 - write (stdout(),'((a), e13.6)') ' reaction constant sulfur oxidation with o2, k_sul_o2 [kg/mol/s] : ', & + write (stdoutunit,'((a), e13.6)') ' reaction constant sulfur oxidation with o2, k_sul_o2 [kg/mol/s] : ', & ergom%k_sul_o2 - write (stdout(),'((a), e13.6)') ' reaction constant sulfur oxidation with no3, k_sul_no3 [kg/mol/s] : ', & + write (stdoutunit,'((a), e13.6)') ' reaction constant sulfur oxidation with no3, k_sul_no3 [kg/mol/s] : ', & ergom%k_sul_no3 - write (stdout(),'((a), e13.6)') ' maximum anammox rate, k_an0 [1/s] : ', & - ergom%k_an0 - write (stdout(),'(/)') + write (stdoutunit,'((a), e13.6)') ' maximum anammox rate, k_an0 [1/s] : ', & + ergom%k_an0 + write (stdoutunit,'(/)') !! Do not delete, men at work !! food_to_nh4_2 ! fraction of food eaten potentially at optimal temperature directly lost to respiration [dimensionless] !! food_to_det_2 ! fraction of food eaten potentially at optimal temperature directly lost to detritus [dimensionless] -!! alpha ! light inhibition shape factor -!! h2smax ! maximum h2s concentration where sinking stops [mol/kg] -!! wo2 ! weight number for o2 sensitivity -!! wh2s ! weight number for h2s sensitivity -!! dark_rise ! whether zooplankton rises independent from a food gradient if it is dark [dimensionless] -!! wfood ! weight number for food gradiens +!! alpha ! light inhibition shape factor +!! h2smax ! maximum h2s concentration where sinking stops [mol/kg] +!! wo2 ! weight number for o2 sensitivity +!! wh2s ! weight number for h2s sensitivity +!! dark_rise ! whether zooplankton rises independent from a food gradient if it is dark [dimensionless] +!! wfood ! weight number for food gradiens !! call mpp_clock_end(id_init) @@ -1216,11 +1224,11 @@ subroutine user_allocate_arrays enddo allocate(phyto(CYA)%jprod_n2(isd:ied,jsd:jed,nk)) ; phyto(CYA)%jprod_n2 = 0.0 do n = 1, NUM_ZOO - allocate(zoo(n)%f_n (isd:ied, jsd:jed, 1:nk)) ; zoo(n)%f_n = 0.0 - allocate(zoo(n)%jgraz_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jgraz_n = 0.0 - allocate(zoo(n)%jgain_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jgain_n = 0.0 - allocate(zoo(n)%jres_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jres_n = 0.0 - allocate(zoo(n)%jdet_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jdet_n = 0.0 + allocate(zoo(n)%f_n (isd:ied, jsd:jed, 1:nk)) ; zoo(n)%f_n = 0.0 + allocate(zoo(n)%jgraz_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jgraz_n = 0.0 + allocate(zoo(n)%jgain_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jgain_n = 0.0 + allocate(zoo(n)%jres_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jres_n = 0.0 + allocate(zoo(n)%jdet_n(isd:ied,jsd:jed,nk)) ; zoo(n)%jdet_n = 0.0 ! if(vertical_migration(n)) & ! allocate(zoo(n)%move (isd:ied,jsd:jed,nk)) ; zoo(n)%move = 0.0 enddo @@ -1237,9 +1245,9 @@ subroutine user_allocate_arrays allocate(sed(n)%jres (isd:ied,jsd:jed)); sed(n)%jres = 0.0 allocate(sed(n)%jbiores (isd:ied,jsd:jed)); sed(n)%jbiores = 0.0 do i=1,NUM_SEDIMENT_LAYERS - write( mystring, '(i4)' ) i - call user_2d_tracer_assign_array(trim(sed(n)%name)//'_'//trim(adjustl(mystring)), & - sed(n)%f_sed(:,:,i)) + write( mystring, '(i4)' ) i + call user_2d_tracer_assign_array(trim(sed(n)%name)//'_'//trim(adjustl(mystring)), & + sed(n)%f_sed(:,:,i)) enddo enddo do n = 1, NUM_DET @@ -1252,7 +1260,8 @@ subroutine user_allocate_arrays end subroutine user_allocate_arrays - subroutine generic_ERGOM_register_diag() + subroutine generic_ERGOM_register_diag(diag_list) + type(g_diag_type), pointer :: diag_list type(vardesc) :: vardesc_temp integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau, axes(3) type(time_type):: init_time @@ -1319,38 +1328,38 @@ subroutine generic_ERGOM_register_diag() init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jno3","NO3 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jno3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jdenit_wc","Water column Denitrification layer integral",'h','L','s',& 'mol m-2 s-1','f') ergom%id_jdenit_wc = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jo2","O2 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jo2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jh2s","H2S source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jh2s = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jh2s_o2","H2S with O2 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jh2s_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jh2s_no3","H2S with NO3 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jh2s_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jsul_o2","sulfur with O2 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jsul_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jsul_no3","sulfur with NO3 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jsul_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jsul","sulfur source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jsul = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jpo4","PO4 source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jpo4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jnitrif","Nitrification source layer integral",'h','L','s','mol m-2 s-1','f') ergom%id_jnitrif = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc("jrec_o2", "Nitrogen flux to NH4, recycling o2",'h','L','s','mol m-2 s-1','f') ergom%id_jrec_o2 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) @@ -1405,7 +1414,7 @@ subroutine generic_ERGOM_register_diag() do n=1, NUM_SED vardesc_temp = vardesc(trim(sed(n)%name)//"_jgain_sed", & "Gain of "//trim(sed(n)%longname)//" by transformation of other sediment classes", & - 'h','L','s','mol m-2 s-1','f') + 'h','L','s','mol m-2 s-1','f') sed(n)%id_jgain_sed = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(sed(n)%name)//"_jloss_sed", & @@ -1425,65 +1434,65 @@ subroutine generic_ERGOM_register_diag() vardesc_temp = vardesc(trim(det(n)%name)//"_jgraz_n", "Nitrogen loss to zooplankton by grazing", & 'h','L','s','mol m-2 s-1','f') det(n)%id_jgraz_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(det(n)%name)//"_jmort","Detritus mort. source layer integral", & 'h','L','s','mol m-2 s-1','f') det(n)%jmort = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) - enddo + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + enddo do n=1, NUM_ZOO vardesc_temp = vardesc(trim(zoo(n)%name)//"_jgraz_n","Nitrogen loss to zooplankton by grazing", & 'h','L','s','mol m-2 s-1','f') zoo(n)%id_jgraz_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(zoo(n)%name)//"_jgain_n","Grazing nitrogen uptake layer integral", & 'h','L','s','mol m-2 s-1','f') zoo(n)%id_jgain_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(zoo(n)%name)//"_jres_n","Respiration nitrogen loss layer integral", & 'h','L','s','mol m-2 s-1','f') zoo(n)%id_jres_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(zoo(n)%name)//"_jdet_n","Zooplankton nitrogen loss to detritus layer integral", & 'h','L','s','mol m-2 s-1','f') zoo(n)%id_jdet_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) - enddo + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + enddo do n=1, NUM_PHYTO vardesc_temp = vardesc(trim(phyto(n)%name)//"_jgraz_n","Grazing nitrogen uptake layer integral",& 'h','L','s','mol m-2 s-1','f') phyto(n)%id_jgraz_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(phyto(n)%name)//"_jres_n","Respiration nitrogen loss layer integral", & 'h','L','s','mol m-2 s-1','f') phyto(n)%id_jres_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(phyto(n)%name)//"_jdet_n","phytoplankton nitrogen loss to detritus layer integral", & 'h','L','s','mol m-2 s-1','f') phyto(n)%id_jdet_n = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(phyto(n)%name)//"_jprod_po4","phytoplankton nitrate uptake layer integral", & 'h','L','s','mol m-2 s-1','f') phyto(n)%id_jprod_po4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(phyto(n)%name)//"_ilim","Light limitation",'h','L','s','W m-2','f') phyto(n)%id_ilim = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) if (phyto(n)%id_ilim .gt. 0) then allocate(phyto(n)%ilim(isd:ied,jsd:jed,nk)) - phyto(n)%ilim = 0.0 + phyto(n)%ilim = 0.0 endif if (n .ne. cya) then vardesc_temp = vardesc(trim(phyto(n)%name)//"_jprod_no3","phytoplankton nitrate uptake layer integral", & - 'h','L','s','mol m-2 s-1','f') + 'h','L','s','mol m-2 s-1','f') phyto(n)%id_jprod_no3 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) vardesc_temp = vardesc(trim(phyto(n)%name)//"_jprod_nh4","phytoplankton nitrate uptake layer integral", & - 'h','L','s','mol m-2 s-1','f') + 'h','L','s','mol m-2 s-1','f') phyto(n)%id_jprod_nh4 = register_diag_field(package_name, vardesc_temp%name, axes(1:3),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) endif - enddo + enddo vardesc_temp = vardesc("jrec_n_sed","nitrogen loss by mineralisation",'h','L','s','mol m-2 s-1','f') biosed%id_jrec_n = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) @@ -1534,8 +1543,11 @@ subroutine user_add_params integer :: n real :: pref_sum character(len=fm_string_len) :: mystring - call g_tracer_start_param_list(package_name) + integer :: stdoutunit + stdoutunit=stdout() + call g_tracer_start_param_list(package_name) + !----------------------------------------------------------------------- ! Schmidt number coefficients !----------------------------------------------------------------------- @@ -1643,17 +1655,17 @@ subroutine user_add_params call g_tracer_add_param(trim(name_zoo(n))//'vdiff_max',zoo(n)%vdiff_max, vdiff_max(n)) call g_tracer_add_param(trim(name_zoo(n))//'dark_rise',zoo(n)%dark_rise,dark_rise(n)) call g_tracer_add_param(trim(name_zoo(n))//'wfood' ,zoo(n)%wfood, wfood(n)) - call g_tracer_add_param(trim(name_zoo(n))//'o2min' ,zoo(n)%o2min, o2min(n)) - call g_tracer_add_param(trim(name_zoo(n))//'h2smax',zoo(n)%h2smax, h2smax(n)) - call g_tracer_add_param(trim(name_zoo(n))//'wtemp', zoo(n)%wtemp, wtemp(n)) - call g_tracer_add_param(trim(name_zoo(n))//'wo2' , zoo(n)%wo2, wo2(n)) - call g_tracer_add_param(trim(name_zoo(n))//'wh2s' , zoo(n)%wh2s, wh2s(n)) + call g_tracer_add_param(trim(name_zoo(n))//'o2min' ,zoo(n)%o2min, o2min(n)) + call g_tracer_add_param(trim(name_zoo(n))//'h2smax',zoo(n)%h2smax, h2smax(n)) + call g_tracer_add_param(trim(name_zoo(n))//'wtemp', zoo(n)%wtemp, wtemp(n)) + call g_tracer_add_param(trim(name_zoo(n))//'wo2' , zoo(n)%wo2, wo2(n)) + call g_tracer_add_param(trim(name_zoo(n))//'wh2s' , zoo(n)%wh2s, wh2s(n)) call g_tracer_add_param(trim(name_zoo(n))//'name' ,zoo(n)%name, trim(name_zoo(n))) call g_tracer_add_param(trim(name_zoo(n))//'pnr', zoo(n)%pnr, np_zoo(n)/nn_zoo(n)) call g_tracer_add_param(trim(name_zoo(n))//'cnr', zoo(n)%cnr, nc_zoo(n)/nn_zoo(n)) - allocate(zoo(n)%pref_phy(NUM_PHYTO)) ; zoo(n)%pref_phy = 0.0 - allocate(zoo(n)%pref_zoo(NUM_ZOO)) ; zoo(n)%pref_zoo = 0.0 - allocate(zoo(n)%pref_det(NUM_DET)) ; zoo(n)%pref_det = 0.0 + allocate(zoo(n)%pref_phy(NUM_PHYTO)) ; zoo(n)%pref_phy = 0.0 + allocate(zoo(n)%pref_zoo(NUM_ZOO)) ; zoo(n)%pref_zoo = 0.0 + allocate(zoo(n)%pref_det(NUM_DET)) ; zoo(n)%pref_det = 0.0 ! ! The sum of all food weights should be 1 pref_sum = 0. @@ -1676,7 +1688,7 @@ subroutine user_add_params pref_zoo(n,m) = pref_zoo(n,m)/(pref_sum+epsln) enddo if (pref_sum .le. epsln) then - write (stdout(),'(a)') 'WARNING, all preferences of '//trim(zoo(n)%name)//' are zero.' + write (stdoutunit,'(a)') 'WARNING, all preferences of '//trim(zoo(n)%name)//' are zero.' endif do m=1, NUM_PHYTO call g_tracer_add_param(trim(zoo(n)%name)//'pref'//trim(phyto(m)%name), zoo(n)%pref_phy(m), pref_phy(n,m)) @@ -1694,7 +1706,7 @@ subroutine user_add_params if (NUM_DET .eq. 1) FAST = SLOW do n=1, NUM_DET ! Detritus parameters for recycling and sinking - call g_tracer_add_param(trim(name_det(n))//'dn', det(n)%dn, dn (n)/sperd) + call g_tracer_add_param(trim(name_det(n))//'dn', det(n)%dn, dn (n)/sperd) call g_tracer_add_param(trim(name_det(n))//'q10_rec',det(n)%q10_rec, q10_rec(n)) call g_tracer_add_param(trim(name_det(n))//'name' , det(n)%name, trim(name_det(n))) enddo @@ -1725,12 +1737,12 @@ subroutine user_add_params call g_tracer_add_param(trim(name_sed(n))//'name_2d', sed(n)%name, name_sed(n)) call g_tracer_add_param(trim(name_sed(n))//'suspend_to', sed(n)%suspend_to, suspend_to(n)) call g_tracer_add_param(trim(name_sed(n))//'erosion_rate',sed(n)%erosion_rate,& - erosion_rate_sed(n)/sperd) + erosion_rate_sed(n)/sperd) call g_tracer_add_param(trim(name_sed(n))//'bioerosion_rate',sed(n)%bioerosion_rate, & - bioerosion_rate_sed(n)/sperd) + bioerosion_rate_sed(n)/sperd) call g_tracer_add_param(trim(name_sed(n))//'molar_volume',sed(n)%molar_volume,molar_volume_sed(n)) call g_tracer_add_param(trim(name_sed(n))//'critical_stress',sed(n)%critical_stress, & - critical_stress_sed(n)) + critical_stress_sed(n)) call g_tracer_add_param(trim(longname_sed(n))//'longname', sed(n)%longname, longname_sed(n)) enddo @@ -1743,7 +1755,7 @@ subroutine user_add_params enddo call g_tracer_add_param('sed_layer_propagation', sed_defs%layer_propagation, sed_layer_propagation) call g_tracer_add_param('sed_erosion_mode', sed_defs%erosion_mode , sed_erosion_mode ) - call g_tracer_add_param('NUM_SEDIMENT_LAYERS' , sed_defs%NUM_LAYERS , NUM_SEDIMENT_LAYERS ) + call g_tracer_add_param('NUM_SEDIMENT_LAYERS' , sed_defs%NUM_LAYERS , NUM_SEDIMENT_LAYERS ) call g_tracer_add_param('q10_nit', ergom%q10_nit, q10_nit) call g_tracer_add_param('nf', ergom%nf, nf/sperd) @@ -1767,7 +1779,7 @@ subroutine user_add_params - call g_tracer_end_param_list() + call g_tracer_end_param_list(package_name) !===================================================================== !Block Ends: g_tracer_add_param @@ -1784,6 +1796,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' integer :: i, n character(len=fm_string_len) :: mystring @@ -1791,7 +1804,7 @@ subroutine user_add_tracers(tracer_list) call g_tracer_add_param('ice_restart_file' , ergom%ice_restart_file , 'ice_ergom.res.nc') call g_tracer_add_param('ocean_restart_file' , ergom%ocean_restart_file , 'ocean_ergom.res.nc' ) call g_tracer_add_param('IC_file' , ergom%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=ergom%ice_restart_file, ocean_restart_file=ergom%ocean_restart_file ) @@ -1816,7 +1829,7 @@ subroutine user_add_tracers(tracer_list) name = trim(name_spm(n)), & longname = trim(longname_spm(n))//' concentration in water', & units = 'mol/kg', & - prog = .true. , & + prog = .true. , & flux_bottom= .true. ) enddo do n=1, NUM_SED @@ -1868,12 +1881,12 @@ subroutine user_add_tracers(tracer_list) do n=1, NUM_ZOO call g_tracer_add(tracer_list,package_name,& - name = trim(name_zoo(n)), & - longname = trim(name_zoo(n))//' Nitrogen', & + name = trim(name_zoo(n)), & + longname = trim(name_zoo(n))//' Nitrogen', & units = 'mol/kg', & prog = .true. , & - move_vertical = vertical_migration(n), & - diff_vertical = vertical_migration(n)) + move_vertical = vertical_migration(n), & + diff_vertical = vertical_migration(n)) enddo !! call g_tracer_add(tracer_list,package_name,& @@ -1910,7 +1923,7 @@ subroutine user_add_tracers(tracer_list) flux_drydep= .true., & flux_param = (/ 14.0067e-03 /), & flux_bottom= .true. ) - + call g_tracer_add(tracer_list,package_name,& name = 'h2s', & longname = 'Sulfide', & @@ -1933,7 +1946,7 @@ subroutine user_add_tracers(tracer_list) flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), & flux_gas_restart_file = 'ocean_ergom_airsea_flux.res.nc', & flux_bottom= .true. ) - + call g_tracer_add(tracer_list,package_name,& name = 'sul', & longname = 'Sulfur', & @@ -1952,6 +1965,7 @@ end subroutine user_add_tracers ! initialize the list of 2d tracers with a length of zero ! subroutine user_init_2d_tracer_list + character(len=fm_string_len), parameter :: sub_name = 'user_init_2d_tracer_list' allocate(tracers_2d(0)) end subroutine user_init_2d_tracer_list ! @@ -1964,7 +1978,8 @@ subroutine user_add_2d_tracer(tracer_list,name,longname,units) type(g_tracer_type), pointer :: tracer_list character(len=*), intent(in) :: name, longname, units - integer :: m, n + character(len=fm_string_len), parameter :: sub_name = 'user_add_2d_tracer' + integer :: m, n, dummy character(len=fm_string_len) :: temp_string type(tracer_2d), ALLOCATABLE, dimension(:) :: temp_tracers_2d @@ -2014,7 +2029,7 @@ subroutine user_register_2d_tracers vardesc_temp = vardesc( & tracers_2d(m)%name, tracers_2d(m)%longname,'h','L','s',tracers_2d(m)%units,'f') tracers_2d(m)%diag_field = register_diag_field(package_name, vardesc_temp%name, axes(1:2),& - init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) + init_time, vardesc_temp%longname,vardesc_temp%units, missing_value = missing_value1) end do end subroutine user_register_2d_tracers @@ -2057,7 +2072,7 @@ subroutine user_get_2d_tracer_values(tracer_list,isd,ied,jsd,jed,nk) if (tracers_2d(n)%field_assigned) then if (trim(adjustl(tracers_2d(n)%name_of_3d_tracer)) .ne. trim(adjustl(loaded_3d_tracer))) then call g_tracer_get_values( & - tracer_list,tracers_2d(n)%name_of_3d_tracer,'field',a3d,isd,jsd,ntau=1,positive=.true.) + tracer_list,tracers_2d(n)%name_of_3d_tracer,'field',a3d,isd,jsd,ntau=1,positive=.true.) loaded_3d_tracer=tracers_2d(n)%name_of_3d_tracer end if tracers_2d(n)%p_field = a3d(:,:,tracers_2d(n)%layer_in_3d_tracer) @@ -2127,6 +2142,7 @@ end subroutine user_set_2d_tracer_values ! subroutine generic_ERGOM_update_from_coupler(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_update_from_coupler' ! !Nothing specific to be done for CFC's ! @@ -2155,7 +2171,7 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & integer, intent(in) :: NUM_SPM, & NUM_SED, & isc, iec, jsc, jec, & - isd, ied, jsd, jed, tau + isd, ied, jsd, jed, tau type(spm_type), intent(inout), dimension(:) :: spm type(sed_type), intent(inout), dimension(:) :: sed integer, dimension(isd:,jsd:) :: grid_kmt @@ -2191,8 +2207,8 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & temp1 = spm(n)%p_wat(i,j,k,tau) * spm(n)%wsed * ergom%rho_0 ! settling rate [mol m-2 s-1] spm(n)%btf(i,j) = spm(n)%btf(i,j) + temp1 sed(n_sed)%f_sed(i,j,1) = & - sed(n_sed)%f_sed(i,j,1) + temp1 * dt ! add suspended matter to sediment - if (spm(n)%id_jsed .gt. 0) spm(n)%jsed(i,j) = temp1 ! output of sedimentation + sed(n_sed)%f_sed(i,j,1) + temp1 * dt ! add suspended matter to sediment + if (spm(n)%id_jsed .gt. 0) spm(n)%jsed(i,j) = temp1 ! output of sedimentation enddo; enddo !i,j endif enddo !n @@ -2209,12 +2225,12 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & if (current_wave_stress(i,j) .gt. sed(n)%critical_stress) then ! constant erosion independent off stress. The more organic matter is in the ! sediment the more will be suspended. Inorganic matter is not considered here. - temp1 = sed(n)%f_sed(i,j,1) * sed(n)%erosion_rate ! erosion rate [mol m-2 s-1] - if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = temp1 ! output of resuspension - sed(n)%f_sed(i,j,1) = sed(n)%f_sed(i,j,1) - temp1 * dt ! remove sediment [mol m-2] + temp1 = sed(n)%f_sed(i,j,1) * sed(n)%erosion_rate ! erosion rate [mol m-2 s-1] + if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = temp1 ! output of resuspension + sed(n)%f_sed(i,j,1) = sed(n)%f_sed(i,j,1) - temp1 * dt ! remove sediment [mol m-2] spm(n_sed)%btf(i,j) = spm(n_sed)%btf(i,j) - temp1 else - if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = 0. + if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = 0. endif enddo; enddo !i,j endif @@ -2227,16 +2243,16 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & do j = jsc, jec; do i = isc, iec k=grid_kmt(i,j) if (k == 0) cycle - diff_stress = current_wave_stress(i,j) - sed(n)%critical_stress + diff_stress = current_wave_stress(i,j) - sed(n)%critical_stress if (diff_stress .gt. 0.0) then - temp1 = diff_stress * sed(n)%erosion_rate ! erosion rate [mol m-2 s-1] - if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = temp1 ! output of resuspension - sed(n)%f_sed(i,j,1) = sed(n)%f_sed(i,j,1) - temp1 * dt ! remove sediment [mol m-2] + temp1 = diff_stress * sed(n)%erosion_rate ! erosion rate [mol m-2 s-1] + if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = temp1 ! output of resuspension + sed(n)%f_sed(i,j,1) = sed(n)%f_sed(i,j,1) - temp1 * dt ! remove sediment [mol m-2] spm(n_sed)%btf(i,j) = spm(n_sed)%btf(i,j) - temp1 -! spm(n_sed)%p_wat(i,j,k,tau) = & -! spm(n_sed)%p_wat(i,j,k,tau) + temp1 * dt ! add concentration to spm +! spm(n_sed)%p_wat(i,j,k,tau) = & +! spm(n_sed)%p_wat(i,j,k,tau) + temp1 * dt ! add concentration to spm else - if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = 0. + if (sed(n)%id_jres .gt. 0) sed(n)%jres(i,j) = 0. endif enddo; enddo !i,j endif @@ -2255,8 +2271,8 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & k=grid_kmt(i,j) if (k == 0) cycle temp1 = sed(n)%f_sed(i,j,1) * sed(n)%bioerosion_rate * bioerosion(i,j) ! bioerosion [mol m-2 s-1] - if (sed(n)%id_jbiores .gt. 0) sed(n)%jbiores(i,j) = temp1 ! output of bioerosion - sed(n)%f_sed(i,j,1) = sed(n)%f_sed(i,j,1) - temp1 * dt ! remove sediment [mol m-2] + if (sed(n)%id_jbiores .gt. 0) sed(n)%jbiores(i,j) = temp1 ! output of bioerosion + sed(n)%f_sed(i,j,1) = sed(n)%f_sed(i,j,1) - temp1 * dt ! remove sediment [mol m-2] spm(n_sed)%btf(i,j) = spm(n_sed)%btf(i,j) - temp1 enddo; enddo !i,j endif @@ -2302,9 +2318,9 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & if (l .lt. sed_defs%NUM_LAYERS) then do n=1, NUM_SED do j = jsc, jec; do i = isc, iec - k=grid_kmt(i,j) - if (k == 0) cycle - sed(n)%f_sed(i,j,l+1) = sed(n)%f_sed(i,j,l+1) + sed(n)%f_sed(i,j,l)*work1(i,j) + k=grid_kmt(i,j) + if (k == 0) cycle + sed(n)%f_sed(i,j,l+1) = sed(n)%f_sed(i,j,l+1) + sed(n)%f_sed(i,j,l)*work1(i,j) enddo; enddo !i,j enddo !n endif @@ -2348,9 +2364,9 @@ subroutine sedimentation_and_resuspension(NUM_SPM, spm, NUM_SED, sed, & if (l .lt. sed_defs%NUM_LAYERS) then do n=1,1 !NUM_SED do j = jsc, jec; do i = isc, iec - k=grid_kmt(i,j) - if (k == 0) cycle - sed(n)%f_sed(i,j,l+1) = sed(n)%f_sed(i,j,l+1) + sed(n)%f_sed(i,j,l)*work1(i,j) + k=grid_kmt(i,j) + if (k == 0) cycle + sed(n)%f_sed(i,j,l+1) = sed(n)%f_sed(i,j,l+1) + sed(n)%f_sed(i,j,l)*work1(i,j) enddo; enddo !i,j enddo !n endif @@ -2449,6 +2465,7 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band real, dimension(ilb:,jlb:), intent(in) :: current_wave_stress + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_update_from_source' integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau, i, j, k , kblt, n, m real, dimension(:,:,:) ,pointer :: grid_tmask integer, dimension(:,:),pointer :: mask_coast,grid_kmt @@ -2600,7 +2617,7 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb phyto(n)%jprod_no3(i,j,k) = jtemp * ergom%f_no3(i,j,k) phyto(n)%jprod_nh4(i,j,k) = jtemp * ergom%f_nh4(i,j,k) phyto(n)%jprod_po4(i,j,k) = (phyto(n)%jprod_no3(i,j,k) & - +phyto(n)%jprod_nh4(i,j,k))*phyto(n)%pnr + +phyto(n)%jprod_nh4(i,j,k))*phyto(n)%pnr endif enddo; enddo ; enddo; enddo !} i,j,k,n @@ -2686,7 +2703,7 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb ! wrk4 is used to reduce grazing when sinking fast ! The movement and diffusion are carried out in the generic triagonal solver IOWtridiag in generic_tracer_utils ! Otherwise use - ! call generic_ERGOM_vmove(zoo(n)%p_vmove, dzt, zoo(n)%p_zoo(:,:,:,tau), dt, isd, ied, jsd, jed) + ! call generic_ERGOM_vmove(zoo(n)%p_vmove, dzt, zoo(n)%p_zoo(:,:,:,tau), dt, isd, ied, jsd, jed) endif ! temporarily store temperature dependence factor for zooplankton grazing in zoo%jdet_n @@ -2716,34 +2733,34 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb tominq = zoo(n)%oxy_min**2 tosubq = zoo(n)%oxy_sub**2 do k = 1, nk ; do j = jsc, jec ; do i = isc, iec - food_pref = wrk2(i,j,k) - food = wrk3(i,j,k) - temp3 = zoo(n)%iv*food - teo2q = ergom%f_o2(i,j,k)**2 - ! no feeding if anoxic - temp2 = teo2q / (tominq + teo2q) - ! Ivlev^2-grazing model, grazing only at oxic conditions - gg = wrk4(i,j,k) * zoo(n)%graz*(1. - exp(-temp3*temp3)) * temp2 + food_pref = wrk2(i,j,k) + food = wrk3(i,j,k) + temp3 = zoo(n)%iv*food + teo2q = ergom%f_o2(i,j,k)**2 + ! no feeding if anoxic + temp2 = teo2q / (tominq + teo2q) + ! Ivlev^2-grazing model, grazing only at oxic conditions + gg = wrk4(i,j,k) * zoo(n)%graz*(1. - exp(-temp3*temp3)) * temp2 - ! temperature-, oxygen- and food-dependent total grazing rate [1/s] - ! (multiply by temporarily stored temperature dependence in zoo(n)%jdet_n) - graz_z = gg * zoo(n)%jdet_n(i,j,k) + ! temperature-, oxygen- and food-dependent total grazing rate [1/s] + ! (multiply by temporarily stored temperature dependence in zoo(n)%jdet_n) + graz_z = gg * zoo(n)%jdet_n(i,j,k) - ! mortality enhancement factor (10x if anoxic) - ! mortality of zooplankton (loss to detritus), 10x higher at anoxic than oxic conditions - ! loss to detritus by feeding, 10x higher at anoxic than oxic conditions - temp1 = 1.0 + 9.0 * tominq / (tominq + teo2q) - lzd1 = zoo(n)%sigma_b * temp1 - lzd2 = (zoo(n)%food_to_det_2*gg + zoo(n)%food_to_det*graz_z) * temp1 - lzd = lzd1 + lzd2 - - !respiration reduction factor (reduced if suboxic, none if anoxic) - temp2 = zoo(n)%resp_red * temp2 + (1.0-zoo(n)%resp_red) * teo2q / (tosubq + teo2q) - ! respiration of zooplankton - lzn = (zoo(n)%nue + zoo(n)%food_to_nh4_2*gg + zoo(n)%food_to_nh4*graz_z) * temp2 - - ! grazing is divided by total food to distribute it to different food types - graz_z = graz_z*(zoo(n)%f_n(i,j,k)+zoo(n)%z0)/(food + epsln) + ! mortality enhancement factor (10x if anoxic) + ! mortality of zooplankton (loss to detritus), 10x higher at anoxic than oxic conditions + ! loss to detritus by feeding, 10x higher at anoxic than oxic conditions + temp1 = 1.0 + 9.0 * tominq / (tominq + teo2q) + lzd1 = zoo(n)%sigma_b * temp1 + lzd2 = (zoo(n)%food_to_det_2*gg + zoo(n)%food_to_det*graz_z) * temp1 + lzd = lzd1 + lzd2 + + !respiration reduction factor (reduced if suboxic, none if anoxic) + temp2 = zoo(n)%resp_red * temp2 + (1.0-zoo(n)%resp_red) * teo2q / (tosubq + teo2q) + ! respiration of zooplankton + lzn = (zoo(n)%nue + zoo(n)%food_to_nh4_2*gg + zoo(n)%food_to_nh4*graz_z) * temp2 + + ! grazing is divided by total food to distribute it to different food types + graz_z = graz_z*(zoo(n)%f_n(i,j,k)+zoo(n)%z0)/(food + epsln) zoo(n)%jgain_n(i,j,k)= graz_z * food_pref do m=1,NUM_PHYTO @@ -2786,31 +2803,31 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ ergom%jno3(i,j,k) = ergom%jnitrif(i,j,k) & ! nitrification releases no3 - phyto(DIA)%jprod_no3(i,j,k) & ! no3-uptake by diatoms and flagellates - - phyto(FLA)%jprod_no3(i,j,k) + - phyto(FLA)%jprod_no3(i,j,k) ergom%jnh4(i,j,k) = - ergom%jnitrif(i,j,k) & ! nitrification consumes nh4 - phyto(DIA)%jprod_nh4(i,j,k) & ! nh4-uptake by diatoms and flagellates - - phyto(FLA)%jprod_nh4(i,j,k) & - + phyto(DIA)%jres_n(i,j,k) & ! nh4-release by all phytoplankton and zooplankton - + phyto(FLA)%jres_n(i,j,k) & - + phyto(CYA)%jres_n(i,j,k) - ! O2-release by no3 assimilation (photosynthesis) of diatoms and flagellates + - phyto(FLA)%jprod_nh4(i,j,k) & + + phyto(DIA)%jres_n(i,j,k) & ! nh4-release by all phytoplankton and zooplankton + + phyto(FLA)%jres_n(i,j,k) & + + phyto(CYA)%jres_n(i,j,k) + ! O2-release by no3 assimilation (photosynthesis) of diatoms and flagellates ergom%jo2(i,j,k) = 8.625*(phyto(DIA)%jprod_no3(i,j,k) + phyto(FLA)%jprod_no3(i,j,k)) & - ! O2-release by nh4 assimilation (photosynthesis) of diatoms and flagellates - + 6.625*(phyto(DIA)%jprod_nh4(i,j,k) + phyto(FLA)%jprod_nh4(i,j,k) & - ! O2-release by n2-fixation and subsequent nh4 assimilation (photosynthesis)of cyanobacteria - + phyto(CYA)%jprod_n2(i,j,k)) & - ! O2-consumption by respiration of all phytoplankton and zooplankton - - 6.625*(phyto(DIA)%jres_n(i,j,k) + phyto(FLA)%jres_n(i,j,k) & - + phyto(CYA)%jres_n(i,j,k)) & - ! nitrification consumes 2 mol o2 - - 2. * ergom%jnitrif(i,j,k) + ! O2-release by nh4 assimilation (photosynthesis) of diatoms and flagellates + + 6.625*(phyto(DIA)%jprod_nh4(i,j,k) + phyto(FLA)%jprod_nh4(i,j,k) & + ! O2-release by n2-fixation and subsequent nh4 assimilation (photosynthesis)of cyanobacteria + + phyto(CYA)%jprod_n2(i,j,k)) & + ! O2-consumption by respiration of all phytoplankton and zooplankton + - 6.625*(phyto(DIA)%jres_n(i,j,k) + phyto(FLA)%jres_n(i,j,k) & + + phyto(CYA)%jres_n(i,j,k)) & + ! nitrification consumes 2 mol o2 + - 2. * ergom%jnitrif(i,j,k) enddo; enddo ; enddo !} i,j,k ergom%jpo4 = 0. do n = 1, NUM_PHYTO;do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ ergom%jpo4(i,j,k) = ergom%jpo4(i,j,k) & - - phyto(n)%jprod_po4(i,j,k) & - + phyto(n)%jres_n(i,j,k) * phyto(n)%pnr + - phyto(n)%jprod_po4(i,j,k) & + + phyto(n)%jres_n(i,j,k) * phyto(n)%pnr enddo; enddo; enddo ; enddo !} i,j,k,n do n = 1, NUM_ZOO;do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ @@ -2831,22 +2848,22 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb phyto(DIA)%p_phyt(i,j,k,tau) = phyto(DIA)%p_phyt(i,j,k,tau) + (phyto(DIA)%jprod_no3(i,j,k) & + phyto(DIA)%jprod_nh4(i,j,k) & - phyto(DIA)%jres_n(i,j,k) - phyto(DIA)%jdet_n(i,j,k) & - - phyto(DIA)%jgraz_n(i,j,k)) * dt * grid_tmask(i,j,k) + - phyto(DIA)%jgraz_n(i,j,k)) * dt * grid_tmask(i,j,k) phyto(FLA)%p_phyt(i,j,k,tau) = phyto(FLA)%p_phyt(i,j,k,tau) + (phyto(FLA)%jprod_no3(i,j,k) & + phyto(FLA)%jprod_nh4(i,j,k) & - - phyto(FLA)%jres_n(i,j,k) - phyto(FLA)%jdet_n(i,j,k) & - - phyto(FLA)%jgraz_n(i,j,k)) * dt * grid_tmask(i,j,k) + - phyto(FLA)%jres_n(i,j,k) - phyto(FLA)%jdet_n(i,j,k) & + - phyto(FLA)%jgraz_n(i,j,k)) * dt * grid_tmask(i,j,k) phyto(CYA)%p_phyt(i,j,k,tau) = phyto(CYA)%p_phyt(i,j,k,tau) + (phyto(CYA)%jprod_n2(i,j,k) & - phyto(CYA)%jres_n(i,j,k) - phyto(CYA)%jdet_n(i,j,k) & - - phyto(CYA)%jgraz_n(i,j,k)) * dt * grid_tmask(i,j,k) + - phyto(CYA)%jgraz_n(i,j,k)) * dt * grid_tmask(i,j,k) ergom%p_nitrogen(i,j,k,tau) = ergom%p_nitrogen(i,j,k,tau) & - 0.5*phyto(CYA)%jprod_n2(i,j,k) * dt * grid_tmask(i,j,k) enddo; enddo ; enddo !} i,j,k do n = 1, NUM_DET do k = 1, nk ; do j = jsc, jec ; do i = isc, iec !{ spm(det(n)%index_spm)%p_wat(i,j,k,tau) = spm(det(n)%index_spm)%p_wat(i,j,k,tau) + (& - det(n)%jmort(i,j,k) - det(n)%jgraz_n(i,j,k) & - ) * dt * grid_tmask(i,j,k) + det(n)%jmort(i,j,k) - det(n)%jgraz_n(i,j,k) & + ) * dt * grid_tmask(i,j,k) enddo; enddo ; enddo !} n,i,j,k enddo @@ -2886,13 +2903,13 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb ! the following may be improved by MM shaped functions no3_h2s = q10 * no3_avail * ergom%k_h2s_no3 *temp2 * h2s_avail ! mainly reacts at anoxic conditions no3_sul = q10 * no3_avail * ergom%k_sul_no3 *temp2 * sul_avail ! mainly reacts at anoxic conditions - o2_h2s = q10 * o2_avail * ergom%k_h2s_o2 * h2s_avail ! mainly reacts at oxic conditions - o2_sul = q10 * o2_avail * ergom%k_sul_o2 * sul_avail ! mainly reacts at oxic conditions + o2_h2s = q10 * o2_avail * ergom%k_h2s_o2 * h2s_avail ! mainly reacts at oxic conditions + o2_sul = q10 * o2_avail * ergom%k_sul_o2 * sul_avail ! mainly reacts at oxic conditions ! make scheme positive, clip with available concentrations ! and rescale the reaction rates ! check availability of the reaction partners - dh2s = dt * (o2_h2s + no3_h2s) + dh2s = dt * (o2_h2s + no3_h2s) ! scaling with sca sca = min(dh2s, h2s_avail)/(dh2s + epsln) o2_h2s = o2_h2s * sca @@ -2908,7 +2925,7 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb no3_h2s = no3_h2s * sca no3_sul = no3_sul * sca - dsul = dt * (o2_sul + no3_sul) + dsul = dt * (o2_sul + no3_sul) sca = min(dsul, sul_avail+dt*(o2_h2s+o2_h2s))/(dsul + epsln) o2_sul = o2_sul * sca no3_sul = no3_sul * sca @@ -2961,34 +2978,34 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb do k = 1, nk ; do j = jsc, jec ; do i = isc, iec ! temperature dependenc of anammox ! i.e. only between 7 and 30degC (Dalsgaard & Thamdrup 2002 in ApplEnvMicrobiol) - k_an = ergom%k_an0 * det(SLOW)%f_n(i,j,k) & ! only det(SLOW) - / (1. + exp((temp(i,j,k) - 30.)*0.5)) & - / (1. + exp((7. - temp(i,j,k))*0.5)) + k_an = ergom%k_an0 * det(SLOW)%f_n(i,j,k) & ! only det(SLOW) + / (1. + exp((temp(i,j,k) - 30.)*0.5)) & + / (1. + exp((7. - temp(i,j,k))*0.5)) - det_recyc = wrk2(i,j,k) ! first guess for the recycling rate - o2_avail = max(ergom%p_o2 (i,j,k,tau), 0.0) ! available amount of electron donors + det_recyc = wrk2(i,j,k) ! first guess for the recycling rate + o2_avail = max(ergom%p_o2 (i,j,k,tau), 0.0) ! available amount of electron donors no3_avail = max(ergom%p_no3(i,j,k,tau), 0.0) h2s_avail = max(ergom%p_h2s(i,j,k,tau), 0.0) - nh4_avail = max(ergom%p_nh4(i,j,k,tau), 0.0) ! nh4 for anammox + nh4_avail = max(ergom%p_nh4(i,j,k,tau), 0.0) ! nh4 for anammox ! functions tend to 1 for high concentrations and have a linear slope at X=0 r_o2 = 2./(1.+exp(-2.*ergom%alp_o2 * o2_avail)) -1. ! "soft switch" r_no3 = 2./(1.+exp(-2.*ergom%alp_no3 * no3_avail))-1. r_h2s = 2./(1.+exp(-2.*ergom%alp_h2s * h2s_avail))-1. r_nh4 = 2./(1.+exp(-2.*ergom%alp_nh4 * nh4_avail))-1. - + ! subdivide the recycling into the four possible electron donors ! oxygenrecycling = o (if oxygen is present) ! denitrification = (NOT o) AND n AND NOT (a AND (NOT h)) ! sulfatreduction = (NOT o) AND (NOT n) - ! anammox = (NOT o) AND n AND a AND (NOT h) - rec_o2 = det_recyc*r_o2 - rec_no3 = k_DN * det_recyc*(1-r_o2)*r_no3*(1-r_nh4*(1-r_h2s)) - rec_so4 = k_DS * det_recyc*(1-r_o2)*(1-r_no3) - rec_ana = k_an * (1-r_o2)*r_no3*r_nh4*(1-r_h2s) + ! anammox = (NOT o) AND n AND a AND (NOT h) + rec_o2 = det_recyc*r_o2 + rec_no3 = k_DN * det_recyc*(1-r_o2)*r_no3*(1-r_nh4*(1-r_h2s)) + rec_so4 = k_DS * det_recyc*(1-r_o2)*(1-r_no3) + rec_ana = k_an * (1-r_o2)*r_no3*r_nh4*(1-r_h2s) ! anammox is regarded as additional "bonus" recycling - det_recyc = rec_o2+rec_no3+rec_so4+rec_ana + det_recyc = rec_o2+rec_no3+rec_so4+rec_ana if(ergom%id_jrec_o2 .gt. 0) ergom%jrec_o2(i,j,k) = rec_o2 if(ergom%id_jrec_no3.gt. 0) ergom%jrec_no3(i,j,k) = rec_no3 @@ -2997,7 +3014,7 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb ergom%jdenit_wc(i,j,k) = ldn_N * rec_no3 ergom%jno3(i,j,k) = ergom%jno3(i,j,k) - ldn_A * rec_ana - ldn_N * rec_no3 - ergom%jnh4(i,j,k) = ergom%jnh4(i,j,k) - ldn_A * rec_ana + det_recyc + ergom%jnh4(i,j,k) = ergom%jnh4(i,j,k) - ldn_A * rec_ana + det_recyc ergom%jo2(i,j,k) = ergom%jo2(i,j,k) - ldn_O * rec_o2 ergom%jh2s(i,j,k) = ergom%jh2s(i,j,k) + ldn_S * rec_so4 ergom%jpo4(i,j,k) = ergom%jpo4(i,j,k) + det_recyc * phyto(DIA)%pnr @@ -3008,7 +3025,7 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb ergom%p_h2s(i,j,k,tau) = ergom%p_h2s(i,j,k,tau) + dt * grid_tmask(i,j,k) * ldn_S * rec_so4 ergom%p_po4(i,j,k,tau) = ergom%p_po4(i,j,k,tau) + dt * grid_tmask(i,j,k) * det_recyc * phyto(DIA)%pnr ergom%p_nitrogen(i,j,k,tau) = ergom%p_nitrogen(i,j,k,tau) & - + dt * grid_tmask(i,j,k) * 0.5 * (2.*ldn_A * rec_ana + ldn_N * rec_no3) + + dt * grid_tmask(i,j,k) * 0.5 * (2.*ldn_A * rec_ana + ldn_N * rec_no3) wrk2(i,j,k) = - dt * grid_tmask(i,j,k) * det_recyc enddo; enddo ; enddo !} i,j,k do n=1, NUM_DET; do k = 1, nk ; do j = jsc, jec ; do i = isc, iec @@ -3036,31 +3053,31 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb if (active_sed > biosed%thio_bact_min ) then - ! the layer may support sulfur bacteria, this is anoxic sediment - det_recyc = biosed%frac_dn_anoxic*det_recyc + ! the layer may support sulfur bacteria, this is anoxic sediment + det_recyc = biosed%frac_dn_anoxic*det_recyc - if (biosed%id_mode_sed .gt. 0) biosed%mode_sed = 1. - dsed = dt*det_recyc + if (biosed%id_mode_sed .gt. 0) biosed%mode_sed = 1. + dsed = dt*det_recyc dh2s_dt = 0.5*ldn_O*det_recyc o2_avail = max(ergom%p_o2(i,j,k,tau), 0.0) do2_dt = min(o2_avail*rhodztdt_r, 2.*dh2s_dt) - - ! oxidation of h2s with o2 + + ! oxidation of h2s with o2 ergom%b_o2(i,j) = do2_dt dh2s_dt = dh2s_dt - 0.5 * do2_dt - ! oxidation of the remaining h2s with no3 + ! oxidation of the remaining h2s with no3 no3_avail = max(ergom%p_no3(i,j,k,tau), 0.0) dno3_dt = min(no3_avail*rhodztdt_r, dh2s_dt) dh2s_dt = dh2s_dt - dno3_dt - - ! sulfur bacteria release nh4, i.e. no denitrification - ! release the remaining h2s into the water - ergom%b_no3(i,j) = dno3_dt - ergom%b_nh4(i,j) = - dno3_dt - det_recyc + + ! sulfur bacteria release nh4, i.e. no denitrification + ! release the remaining h2s into the water + ergom%b_no3(i,j) = dno3_dt + ergom%b_nh4(i,j) = - dno3_dt - det_recyc ergom%b_h2s(i,j) = - dh2s_dt - ! po4 recycling + ! po4 recycling ergom%b_po4(i,j) = - det_recyc*biosed%pnr else ! sediment too thin for the growth of sulfur bacteria @@ -3068,11 +3085,11 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb if (biosed%id_mode_sed .gt. 0) biosed%mode_sed = 0. ! now unit back to mol/kg pot_o2 = ergom%p_o2(i,j,k,tau) - 2. * ergom%p_h2s(i,j,k,tau) - if (pot_o2 < 0.) det_recyc = biosed%frac_dn_anoxic*det_recyc - dsed = dt*det_recyc + if (pot_o2 < 0.) det_recyc = biosed%frac_dn_anoxic*det_recyc + dsed = dt*det_recyc ! use o2 for re-mineralisation - o2_avail = max(ergom%p_o2(i,j,k,tau), 0.0) + o2_avail = max(ergom%p_o2(i,j,k,tau), 0.0) do2_dt = min(o2_avail*rhodztdt_r, det_recyc*ldn_O) ergom%b_o2(i,j) = do2_dt det_left = det_recyc - do2_dt / ldn_O @@ -3080,37 +3097,37 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb ! use no3 for re-mineralisation if o2-availability is too low no3_avail = max(ergom%p_no3(i,j,k,tau), 0.0) dno3_dt = min(no3_avail*rhodztdt_r, det_left*ldn_N) - ergom%b_no3(i,j) = dno3_dt + ergom%b_no3(i,j) = dno3_dt ergom%b_nitrogen(i,j) = -0.5 * dno3_dt det_left = det_left - dno3_dt / ldn_N ! use so4 for re-mineralisation of the remaining part if o2 and no3-availability is too low - dh2s_dt = 0.5*ldn_O*det_left + dh2s_dt = 0.5*ldn_O*det_left ergom%b_h2s(i,j) = - dh2s_dt ! release of the remaining part into the water ! if the bottom water is oxic, denitrification happens in the sediment ! in this case less nh4 is released. - ! oxygen used for nitrification in the sediment is 2.* biosed%den_rate * det_recyc + ! oxygen used for nitrification in the sediment is 2.* biosed%den_rate * det_recyc temp2 = dt * (2.*biosed%den_rate * det_recyc + do2_dt) if (pot_o2 > temp2) then !oxic sediment --> denitrification - ergom%b_o2(i,j) = ergom%b_o2(i,j) + 2.* biosed%den_rate * det_recyc - dsed = dsed + det_recyc*biosed%den_rate/ldn_N*dt - ergom%b_nh4(i,j) = - det_recyc *(1.+ biosed%den_rate*(1./ldn_N - 1.)) - ergom%b_nitrogen(i,j) = ergom%b_nitrogen(i,j) - det_recyc * 0.5* biosed%den_rate + ergom%b_o2(i,j) = ergom%b_o2(i,j) + 2.* biosed%den_rate * det_recyc + dsed = dsed + det_recyc*biosed%den_rate/ldn_N*dt + ergom%b_nh4(i,j) = - det_recyc *(1.+ biosed%den_rate*(1./ldn_N - 1.)) + ergom%b_nitrogen(i,j) = ergom%b_nitrogen(i,j) - det_recyc * 0.5* biosed%den_rate - ! po4 recycling - ergom%b_po4(i,j) = - det_recyc*biosed%pnr*(1. + biosed%den_rate/ldn_N) - if (biosed%id_jdenit_sed .gt. 0) biosed%jdenit_sed(i,j) = det_recyc*biosed%den_rate - - else !unoxic sediment --> no denitrification - - ergom%b_nh4(i,j) = - det_recyc + ! po4 recycling + ergom%b_po4(i,j) = - det_recyc*biosed%pnr*(1. + biosed%den_rate/ldn_N) + if (biosed%id_jdenit_sed .gt. 0) biosed%jdenit_sed(i,j) = det_recyc*biosed%den_rate + + else !unoxic sediment --> no denitrification + + ergom%b_nh4(i,j) = - det_recyc - ! po4 recycling - ergom%b_po4(i,j) = - det_recyc*biosed%pnr - endif + ! po4 recycling + ergom%b_po4(i,j) = - det_recyc*biosed%pnr + endif endif if (biosed%id_jrec_n .gt. 0) biosed%jrec_n(i,j) = dsed/dt sed(biosed%index_sed)%f_sed(i,j,1) = sed(biosed%index_sed)%f_sed(i,j,1) - dsed @@ -3130,18 +3147,18 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb ! retention of phosphate ! rate at which phosphorous is retained in the sediment [mol m-2 s-1], remember b_po4 is negative ! phosphate flux into the water column (b_po4, negative) is reduced - temp2 = -ergom%b_po4(i,j) * temp1 * wrk1(i,j,k) + temp2 = -ergom%b_po4(i,j) * temp1 * wrk1(i,j,k) ergom%b_po4(i,j) = ergom%b_po4(i,j)+temp2 sed(biosed%index_ips)%f_sed(i,j,1) = sed(biosed%index_ips)%f_sed(i,j,1) + temp2*dt if (sed(biosed%index_ips)%id_jgain_sed .gt. 0) & - sed(biosed%index_ips)%jgain_sed(i,j) = temp2 + sed(biosed%index_ips)%jgain_sed(i,j) = temp2 ! liberation of phosphate under anoxic conditions ! rate at which phosphorous is liberated from sediment [mol m-2 s-1] - temp2 = sed(biosed%index_ips)%f_sed(i,j,1) * (1.0-wrk1(i,j,k)) * biosed%po4_lib_rate + temp2 = sed(biosed%index_ips)%f_sed(i,j,1) * (1.0-wrk1(i,j,k)) * biosed%po4_lib_rate ergom%b_po4(i,j) = ergom%b_po4(i,j) - temp2 sed(biosed%index_ips)%f_sed(i,j,1) = sed(biosed%index_ips)%f_sed(i,j,1) - temp2 * dt if (sed(biosed%index_ips)%id_jloss_sed .gt. 0) & - sed(biosed%index_ips)%jloss_sed(i,j) = temp2 + sed(biosed%index_ips)%jloss_sed(i,j) = temp2 enddo !} i enddo !} j endif @@ -3259,22 +3276,22 @@ subroutine generic_ERGOM_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb used = send_data(ergom%id_jsul_no3, ergom%jsul_no3*rho_dzt, & model_time, rmask = grid_tmask(:,:,:),& is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) - if (ergom%id_jrec_o2 .gt. 0) & - used = send_data(ergom%id_jrec_o2, ergom%jrec_o2*rho_dzt, & - model_time, rmask = grid_tmask(:,:,:),& - is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) - if (ergom%id_jrec_no3 .gt. 0) & - used = send_data(ergom%id_jrec_no3, ergom%jrec_no3*rho_dzt, & - model_time, rmask = grid_tmask(:,:,:),& - is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) - if (ergom%id_jrec_so4 .gt. 0) & - used = send_data(ergom%id_jrec_so4, ergom%jrec_so4*rho_dzt, & - model_time, rmask = grid_tmask(:,:,:),& - is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) - if (ergom%id_jrec_ana .gt. 0) & - used = send_data(ergom%id_jrec_ana, ergom%jrec_ana*rho_dzt, & - model_time, rmask = grid_tmask(:,:,:),& - is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (ergom%id_jrec_o2 .gt. 0) & + used = send_data(ergom%id_jrec_o2, ergom%jrec_o2*rho_dzt, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (ergom%id_jrec_no3 .gt. 0) & + used = send_data(ergom%id_jrec_no3, ergom%jrec_no3*rho_dzt, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (ergom%id_jrec_so4 .gt. 0) & + used = send_data(ergom%id_jrec_so4, ergom%jrec_so4*rho_dzt, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (ergom%id_jrec_ana .gt. 0) & + used = send_data(ergom%id_jrec_ana, ergom%jrec_ana*rho_dzt, & + model_time, rmask = grid_tmask(:,:,:),& + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) ! do n=1, NUM_DET if (det(n)%id_jgraz_n .gt. 0) & @@ -3431,6 +3448,8 @@ subroutine generic_ERGOM_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau real, dimension(:,:), ALLOCATABLE :: nitrogen_alpha, nitrogen_csurf, nitrogen_sc_no real, dimension(:,:), ALLOCATABLE :: o2_alpha, o2_csurf , o2_sc_no + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_set_boundary_values' + !nnz: Can we treat these as source and move block to user_update_from_source? ! @@ -3522,7 +3541,7 @@ subroutine generic_ERGOM_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau o2_saturation = (1000.0/22391.6) * grid_tmask(i,j,1) * & !convert from ml/l to mol m-3 exp( ergom%t0_o2 + ergom%t1_o2*ts + ergom%t2_o2*ts2 + & - ergom%t3_o2*ts3 + ergom%t4_o2*ts4 + ergom%t5_o2*ts5 + & + ergom%t3_o2*ts3 + ergom%t4_o2*ts4 + ergom%t5_o2*ts5 + & (ergom%b0_o2 + ergom%b1_o2*ts + ergom%b2_o2*ts2 + ergom%b3_o2*ts3 + ergom%c0_o2*sal)*sal) !--------------------------------------------------------------------- @@ -3651,6 +3670,8 @@ subroutine generic_ERGOM_vmove(move, dzt, field, dt, ilb, iub, jlb, jub) real :: velocity, wpos, wneg integer :: k, i, j, kp1 integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_vmove' + call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,& grid_tmask=tmask, grid_kmt=kmt) @@ -3688,6 +3709,7 @@ end subroutine generic_ERGOM_vmove ! subroutine generic_ERGOM_end + character(len=fm_string_len), parameter :: sub_name = 'generic_ERGOM_end' call user_deallocate_arrays end subroutine generic_ERGOM_end @@ -3730,11 +3752,11 @@ subroutine user_deallocate_arrays deallocate(phyto(n)%jprod_nh4) deallocate(phyto(n)%jprod_no3) deallocate(phyto(n)%jprod_po4) - deallocate(phyto(n)%jres_n) - deallocate(phyto(n)%jdet_n) + deallocate(phyto(n)%jres_n) + deallocate(phyto(n)%jdet_n) enddo n = DIA - deallocate(phyto(n)%move) + deallocate(phyto(n)%move) n = CYA deallocate(phyto(n)%move) deallocate(phyto(n)%f_n) @@ -3745,12 +3767,12 @@ subroutine user_deallocate_arrays deallocate(phyto(n)%jdet_n) deallocate(phyto(n)%jprod_n2) do n = 1, NUM_ZOO - deallocate(zoo(n)%f_n) - deallocate(zoo(n)%jgraz_n) - deallocate(zoo(n)%jgain_n) - deallocate(zoo(n)%jres_n) - deallocate(zoo(n)%jdet_n) -! deallocate(zoo(n)%move) + deallocate(zoo(n)%f_n) + deallocate(zoo(n)%jgraz_n) + deallocate(zoo(n)%jgain_n) + deallocate(zoo(n)%jres_n) + deallocate(zoo(n)%jdet_n) +! deallocate(zoo(n)%move) enddo do n = 1, NUM_DET deallocate(det(n)%f_n) diff --git a/src/ocean_shared/generic_tracers/generic_ERGOM.html b/src/ocean_shared/generic_tracers/generic_ERGOM.html deleted file mode 100644 index a50ddf2c87..0000000000 --- a/src/ocean_shared/generic_tracers/generic_ERGOM.html +++ /dev/null @@ -1,394 +0,0 @@ - - - -Module generic_ERGOM - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
            -

            Module generic_ERGOM

            - - -
            -Contact:  - -
            -Reviewers:  - -
            -Change History: WebCVS Log -
            -
            -
            - - -
            -

            OVERVIEW

            - -

            - This module contains the generic version of ERGOM modified for the project GENUS. - It is designed so that both GFDL Ocean models, GOLD and MOM, can use it. - The genreal coding scheme follows that of the TOPAZ package -

            - - - -
            - Implementation of routines to solve the ERGOM equations - Fennel and Neumann - S. Schaefer - M. Schmidt, A Eggert, H. Radtke - Some code pieces are reused from the TOPAZ code - - no need to invent the wheel twice. Thanks to John Dunne and Niki Zadeh. -
            -
            - - -
            -

            OTHER MODULES USED

            - -
            -
            coupler_types_mod
            field_manager_mod
            fms_mod
            mpp_mod
            time_manager_mod
            fm_util_mod
            diag_manager_mod
            constants_mod
            g_tracer_utils
            -
            - - - -
            -

            PUBLIC INTERFACE

            -
            -
            -
            -generic_ERGOM_init:
            -
            - Initialize the generic ERGOM module -
            -
            -generic_ERGOM_update_from_coupler:
            -
            - Modify the values obtained from the coupler if necessary. -
            -
            -sedimentation_and_resuspension:
            -
            - Perform sedimentation and resuspension for all spm and sed tracers -
            -
            -generic_ERGOM_update_from_bottom:
            -
            - Set values of bottom fluxes and reservoirs -
            -
            -generic_ERGOM_update_from_source:
            -
            - Update tracer concentration fields due to the source/sink contributions. -
            -
            -generic_ERGOM_set_boundary_values:
            -
            - Calculate and set coupler values at the surface / bottom -
            -
            -generic_ERGOM_find_vmove:
            -
            - Calculates vertical movement of zooplankton -
            -
            -generic_ERGOM_vmove:
            -
            - Performs vertical movement (up or down) -
            -
            -generic_ERGOM_end:
            -
            - End the module. -
            -
            -
            -
            - - -
            -

            PUBLIC ROUTINES

            - -
              -
            1. - -

              generic_ERGOM_init

              -
              -call generic_ERGOM_init (tracer_list)
              -
              -
              -DESCRIPTION -
              -
              - This subroutine: - Adds all the CFC 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]
              -
              -
              -
              -
            2. -
            3. - -

              generic_ERGOM_update_from_coupler

              -
              -call generic_ERGOM_update_from_coupler (tracer_list)
              -
              -
              -DESCRIPTION -
              -
              - Currently an empty stub for CFCs. - Some tracer fields need to be modified after values are obtained from the coupler. - This subroutine is the place for specific tracer manipulations. -
              -
              -
              -
              -INPUT -
              -
              - - - - -
              tracer_list    - Pointer to the head of generic tracer list. -
                 [type(g_tracer_type), pointer]
              -
              -
              -
              -
            4. -
            5. - -

              sedimentation_and_resuspension

              -
              -call sedimentation_and_resuspension (NUM_SPM, spm, NUM_SED, sed, & isc, iec, jsc, jec, isd, ied, jsd, jed, grid_kmt, dzt, rho_dzt, tau, dt, & sed_defs, current_wave_stress, bioerosion)
              -
              -
              -DESCRIPTION -
              -
              - All tracers that are able to be sedimented are stored in the spm array. - All tracers that are able to be resuspended are stored in the sed array. - This subroutine performs the sedimentation and resuspension. -
              -
              -
              -
              -
            6. -
            7. - -

              generic_ERGOM_update_from_bottom

              -
              -call generic_ERGOM_update_from_bottom (tracer_list,dt, tau, model_time)
              -
              -
              -DESCRIPTION -
              -
              - Some tracers have bottom fluxes and reservoirs. - This subroutine is the place for specific tracer manipulations. -
              -
              -
              -
              -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]
              -
              -
              -
              -
            8. -
            9. - -

              generic_ERGOM_update_from_source

              -
              -
              -DESCRIPTION -
              -
              - Currently an empty stub for CFCs. -
              -
              -
              -
              -
            10. -
            11. - -

              generic_ERGOM_set_boundary_values

              -
              -call generic_ERGOM_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]
              -
              -
              -
              -
            12. -
            13. - -

              generic_ERGOM_find_vmove

              -
              -call generic_ERGOM_find_vmove 
              -
              -
              -
              -DESCRIPTION -
              -
              - - -
              -
              -
              -
              -
            14. -
            15. - -

              generic_ERGOM_vmove

              -
              -call generic_ERGOM_vmove 
              -
              -
              -
              -DESCRIPTION -
              -
              - Updates particulate tracer concentrations -
              -
              -
              -
              -
            16. -
            17. - -

              generic_ERGOM_end

              -
              -call generic_ERGOM_end 
              -
              -
              -
              -DESCRIPTION -
              -
              - Deallocate all work arrays -
              -
              -
              -
              -
            18. -
            - - - - - - -
            -

            REFERENCES

            - -
            -
              -
            1. - http://www.io-warnemuende.de -
            2. -
            -
            -
            - -
            -
            -top -
            - - diff --git a/src/ocean_shared/generic_tracers/generic_TOPAZ.F90 b/src/ocean_shared/generic_tracers/generic_TOPAZ.F90 index baed282bdc..0455c53bd1 100644 --- a/src/ocean_shared/generic_tracers/generic_TOPAZ.F90 +++ b/src/ocean_shared/generic_tracers/generic_TOPAZ.F90 @@ -75,8 +75,6 @@ ! !---------------------------------------------------------------- -#include - module generic_TOPAZ use coupler_types_mod, only: coupler_2d_bc_type @@ -95,12 +93,12 @@ module generic_TOPAZ use g_tracer_utils, only : g_tracer_send_diag, g_tracer_get_values use g_tracer_utils, only : g_diag_type, g_diag_field_add - use FMS_ocmip2_co2calc_mod, only : FMS_ocmip2_co2calc, CO2_dope_vector + use FMS_ocmip2_co2calc_mod, only : FMS_ocmip2_co2calc, FMS_ocmip2_co2calc_old, CO2_dope_vector implicit none ; private !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: generic_TOPAZ.F90,v 19.0.4.1 2012/04/19 17:25:15 jgj Exp $' - character(len=128) :: tag = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: generic_TOPAZ.F90,v 20.0 2013/12/14 00:18:07 fms Exp $' + character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- character(len=fm_string_len), parameter :: mod_name = 'generic_TOPAZ' @@ -247,6 +245,7 @@ module generic_TOPAZ fe_ballast_assoc, & ! If iron scavenging is associated with ballast init, & ! If tracers should be initializated p_2_n_static, & ! If P:N is fixed in phytoplankton + reproduce_esm2, & ! Do not add changes post-CMIP5 version of ESM2 si_2_n_static ! If Si:N is fixed in phytoplankton real :: & @@ -759,6 +758,8 @@ module generic_TOPAZ subroutine generic_TOPAZ_register(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_TOPAZ_register' + !Specify all prognostic and diagnostic tracers of this modules. call user_add_tracers(tracer_list) @@ -784,6 +785,8 @@ end subroutine generic_TOPAZ_register ! subroutine generic_TOPAZ_init(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_TOPAZ_init' + !Specify and initialize all parameters used by this package call user_add_params @@ -2669,6 +2672,9 @@ subroutine user_add_params ! call g_tracer_add_param('do_extra_diag_calcs', topaz%do_extra_diag_calcs, .true.) ! + ! Prevent incorporation of changes since CMIP5 version of ESM2 + call g_tracer_add_param('reproduce_esm2', topaz%reproduce_esm2, .false.) + ! ! Nitrification rate constant assumed to be light-limited with an inhibition ! factor. gamma_nitrif was tuned to reproduce the scaling observed in Ward et ! al. (1982; Microbial nitrification rates in the primary nitrite maximum off @@ -2704,7 +2710,7 @@ subroutine user_add_params call g_tracer_add_param('r_bio_tau', topaz%r_bio_tau,1.0 / topaz%bio_tau) - call g_tracer_end_param_list() + call g_tracer_end_param_list(package_name) !=========== !Block Ends: g_tracer_add_param !=========== @@ -2721,6 +2727,8 @@ 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) @@ -2741,7 +2749,7 @@ subroutine user_add_tracers(tracer_list) call g_tracer_add_param('ocean_restart_file' , topaz%ocean_restart_file , 'ocean_topaz.res.nc' ) call g_tracer_add_param('IC_file' , topaz%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 = topaz%ice_restart_file,& @@ -3203,6 +3211,8 @@ end subroutine user_add_tracers subroutine generic_TOPAZ_update_from_coupler(tracer_list) type(g_tracer_type), pointer :: tracer_list + character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_update_from_coupler' + real, dimension(:,:) ,pointer :: stf_alk,dry_no3,wet_no3 ! @@ -3246,7 +3256,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau logical :: used real, dimension(:,:,:),pointer :: grid_tmask - real, dimension(:,:,:,:),pointer :: temp_field + real, dimension(:,:,:),pointer :: temp_field call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask) @@ -3258,7 +3268,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) call g_tracer_get_values(tracer_list,'cadet_arag' ,'btm_reservoir', topaz%fcadet_arag_btm,isd,jsd) topaz%fcadet_arag_btm = topaz%fcadet_arag_btm /dt call g_tracer_get_pointer(tracer_list,'cadet_arag_btf','field',temp_field) - temp_field(:,:,1,1) = topaz%fcadet_arag_btm(:,:) + temp_field(:,:,1) = topaz%fcadet_arag_btm(:,:) call g_tracer_set_values(tracer_list,'cadet_arag','btm_reservoir',0.0) if (topaz%id_fcadet_arag_btm .gt. 0) & used = send_data(topaz%id_fcadet_arag_btm, topaz%fcadet_arag_btm, & @@ -3268,7 +3278,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) call g_tracer_get_values(tracer_list,'cadet_calc' ,'btm_reservoir', topaz%fcadet_calc_btm,isd,jsd) topaz%fcadet_calc_btm = topaz%fcadet_calc_btm /dt call g_tracer_get_pointer(tracer_list,'cadet_calc_btf','field',temp_field) - temp_field(:,:,1,1) = topaz%fcadet_calc_btm(:,:) + temp_field(:,:,1) = topaz%fcadet_calc_btm(:,:) call g_tracer_set_values(tracer_list,'cadet_calc','btm_reservoir',0.0) if (topaz%id_fcadet_calc_btm .gt. 0) & used = send_data(topaz%id_fcadet_calc_btm, topaz%fcadet_calc_btm, & @@ -3287,7 +3297,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) topaz%flithdet_btm = topaz%flithdet_btm /dt call g_tracer_set_values(tracer_list,'lithdet','btm_reservoir',0.0) call g_tracer_get_pointer(tracer_list,'lithdet_btf','field',temp_field) - temp_field(:,:,1,1) = topaz%flithdet_btm(:,:) + temp_field(:,:,1) = topaz%flithdet_btm(:,:) if (topaz%id_flithdet_btm .gt. 0) & used = send_data(topaz%id_flithdet_btm, topaz%flithdet_btm, & model_time, rmask = grid_tmask(:,:,1),& @@ -3296,7 +3306,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) call g_tracer_get_values(tracer_list,'ndet' ,'btm_reservoir', topaz%fndet_btm,isd,jsd) topaz%fndet_btm = topaz%fndet_btm /dt call g_tracer_get_pointer(tracer_list,'ndet_btf','field',temp_field) - temp_field(:,:,1,1) = topaz%fndet_btm(:,:) + temp_field(:,:,1) = topaz%fndet_btm(:,:) call g_tracer_set_values(tracer_list,'ndet','btm_reservoir',0.0) if (topaz%id_fndet_btm .gt. 0) & used = send_data(topaz%id_fndet_btm, topaz%fndet_btm, & @@ -3306,7 +3316,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) call g_tracer_get_values(tracer_list,'pdet' ,'btm_reservoir', topaz%fpdet_btm,isd,jsd) topaz%fpdet_btm = topaz%fpdet_btm /dt call g_tracer_get_pointer(tracer_list,'pdet_btf','field',temp_field) - temp_field(:,:,1,1) = topaz%fpdet_btm(:,:) + temp_field(:,:,1) = topaz%fpdet_btm(:,:) call g_tracer_set_values(tracer_list,'pdet','btm_reservoir',0.0) if (topaz%id_fpdet_btm .gt. 0) & used = send_data(topaz%id_fpdet_btm, topaz%fpdet_btm, & @@ -3316,7 +3326,7 @@ subroutine generic_TOPAZ_update_from_bottom(tracer_list, dt, tau, model_time) call g_tracer_get_values(tracer_list,'sidet' ,'btm_reservoir', topaz%fsidet_btm,isd,jsd) topaz%fsidet_btm = topaz%fsidet_btm /dt call g_tracer_get_pointer(tracer_list,'sidet_btf','field',temp_field) - temp_field(:,:,1,1) = topaz%fsidet_btm(:,:) + temp_field(:,:,1) = topaz%fsidet_btm(:,:) call g_tracer_set_values(tracer_list,'sidet','btm_reservoir',0.0) if (topaz%id_fsidet_btm .gt. 0) & used = send_data(topaz%id_fsidet_btm, topaz%fsidet_btm, & @@ -3387,6 +3397,7 @@ subroutine generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band + character(len=fm_string_len), parameter :: sub_name = 'generic_TOPAZ_update_from_source' integer :: isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,i,j,k,kblt,n,k_100 real, dimension(:,:,:) ,pointer :: grid_tmask integer, dimension(:,:),pointer :: mask_coast,grid_kmt @@ -3441,6 +3452,21 @@ subroutine generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb topaz%htotalhi(i,j) = topaz%htotal_scale_hi * topaz%f_htotal(i,j,k) enddo; enddo ; !} i, j + if (topaz%reproduce_esm2) then + call FMS_ocmip2_co2calc_old(CO2_dope_vec,grid_tmask(:,:,k),& + Temp(:,:,k), Salt(:,:,k), & + topaz%f_dic(:,:,k), & + topaz%f_po4(:,:,k), & + topaz%f_sio4(:,:,k), & + topaz%f_alk(:,:,k), & + topaz%htotallo, topaz%htotalhi,& + !InOut + topaz%f_htotal(:,:,k), & + !OUT + co2star=topaz%co2_csurf(:,:), alpha=topaz%co2_alpha(:,:), & + pCO2surf=topaz%pco2_csurf(:,:), & + co3_ion=topaz%f_co3_ion(:,:,k)) + else call FMS_ocmip2_co2calc(CO2_dope_vec,grid_tmask(:,:,k),& Temp(:,:,k), Salt(:,:,k), & topaz%f_dic(:,:,k), & @@ -3454,13 +3480,32 @@ subroutine generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb co2star=topaz%co2_csurf(:,:), alpha=topaz%co2_alpha(:,:), & pCO2surf=topaz%pco2_csurf(:,:), & co3_ion=topaz%f_co3_ion(:,:,k)) + endif + if(topaz%reproduce_esm2)then + do k = 2, nk + do j = jsc, jec ; do i = isc, iec !{ + topaz%htotallo(i,j) = topaz%htotal_scale_lo * topaz%f_htotal(i,j,k) + topaz%htotalhi(i,j) = topaz%htotal_scale_hi * topaz%f_htotal(i,j,k) + enddo; enddo ; !} i, j + call FMS_ocmip2_co2calc_old(CO2_dope_vec,grid_tmask(:,:,k),& + Temp(:,:,k), Salt(:,:,k), & + topaz%f_dic(:,:,k), & + topaz%f_po4(:,:,k), & + topaz%f_sio4(:,:,k), & + topaz%f_alk(:,:,k), & + topaz%htotallo, topaz%htotalhi,& + !InOut + topaz%f_htotal(:,:,k), & + !OUT + co3_ion=topaz%f_co3_ion(:,:,k)) + enddo + else do k = 2, nk do j = jsc, jec ; do i = isc, iec !{ topaz%htotallo(i,j) = topaz%htotal_scale_lo * topaz%f_htotal(i,j,k) topaz%htotalhi(i,j) = topaz%htotal_scale_hi * topaz%f_htotal(i,j,k) enddo; enddo ; !} i, j - call FMS_ocmip2_co2calc(CO2_dope_vec,grid_tmask(:,:,k),& Temp(:,:,k), Salt(:,:,k), & topaz%f_dic(:,:,k), & @@ -3473,6 +3518,7 @@ subroutine generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb !OUT co3_ion=topaz%f_co3_ion(:,:,k)) enddo + endif call g_tracer_set_values(tracer_list,'htotal','field',topaz%f_htotal ,isd,jsd,ntau=1) call g_tracer_set_values(tracer_list,'co3_ion','field',topaz%f_co3_ion ,isd,jsd,ntau=1) @@ -4089,14 +4135,14 @@ subroutine generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb 5.9415e-3 * max(epsln, Salt(i,j,k))**(1.5) - 0.02 - (48.76 - 2.8 - 0.5304 * Temp(i,j,k)) * & (PRESS - 1.013) / (191.46 * TK) + (1e-3 * (11.76 - 0.3692 * Temp(i,j,k))) * (PRESS - 1.013) *& (PRESS - 1.013) / (382.92 * TK) - topaz%co3_sol_arag(i,j,k) = 10**(-PKSPA) / (2.937e-4 * max(5.0, Salt(i,j,k))) + topaz%co3_sol_arag(i,j,k) = 10**(-PKSPA) / (2.937d-4 * max(5.0, Salt(i,j,k))) topaz%omega_arag(i,j,k) = topaz%f_co3_ion(i,j,k) / topaz%co3_sol_arag(i,j,k) PKSPC = 171.9065 + 0.077993 * TK - 2839.319 / TK - 71.595 * log10(TK) - (-0.77712 + 2.8426e-3 * & TK + 178.34 / TK) * sqrt(max(epsln, Salt(i,j,k))) + 0.07711 * max(epsln, Salt(i,j,k)) - & 4.1249e-3 * max(epsln, Salt(i,j,k))**(1.5) - 0.02 - (48.76 - 0.5304 * Temp(i,j,k)) * & (PRESS - 1.013) / (191.46 * TK) + (1e-3 * (11.76 - 0.3692 * Temp(i,j,k))) * (PRESS - 1.013) *& (PRESS - 1.013) / (382.92 * TK) - topaz%co3_sol_calc(i,j,k) = 10**(-PKSPC) / (2.937e-4 * max(5.0, Salt(i,j,k))) + topaz%co3_sol_calc(i,j,k) = 10**(-PKSPC) / (2.937d-4 * max(5.0, Salt(i,j,k))) topaz%omega_calc(i,j,k) = topaz%f_co3_ion(i,j,k) / topaz%co3_sol_calc(i,j,k) enddo; enddo ; enddo !} i,j,k @@ -4937,7 +4983,7 @@ subroutine generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,hb endif enddo !} k if (k_100 .gt. 1 .and. k_100 .lt. grid_kmt(i,j)) then - k_100 = k_100+1 +! 2013/05/22 CAS/JPD/JGJ remove line incrementing k_100 drho_dzt = topaz%Rho_0 * 100.0 - rho_dzt_100(i,j) topaz%f_alk_int_100(i,j) = topaz%f_alk_int_100(i,j) + topaz%p_alk(i,j,k_100,tau) * drho_dzt topaz%f_dic_int_100(i,j) = topaz%f_dic_int_100(i,j) + topaz%p_dic(i,j,k_100,tau) * drho_dzt @@ -6054,6 +6100,8 @@ subroutine generic_TOPAZ_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau real, dimension(:,:,:,:), pointer :: o2_field,dic_field,po4_field,sio4_field,alk_field real, dimension(:,:,:), ALLOCATABLE :: htotal_field,co3_ion_field real, dimension(:,:), ALLOCATABLE :: co2_alpha,co2_csurf,co2_sc_no,o2_alpha,o2_csurf,o2_sc_no + character(len=fm_string_len), parameter :: sub_name = 'generic_TOPAZ_set_boundary_values' + ! ! @@ -6094,6 +6142,21 @@ subroutine generic_TOPAZ_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau topaz%htotalhi(i,j) = topaz%htotal_scale_hi * htotal_field(i,j,1) enddo; enddo ; !} i, j + if(topaz%reproduce_esm2) then + call FMS_ocmip2_co2calc_old(CO2_dope_vec,grid_tmask(:,:,1), & + SST(:,:), SSS(:,:), & + dic_field(:,:,1,tau), & + po4_field(:,:,1,tau), & + sio4_field(:,:,1,tau), & + alk_field(:,:,1,tau), & + topaz%htotallo, topaz%htotalhi, & + !InOut + htotal_field(:,:,1), & + !OUT + co2star=co2_csurf(:,:), alpha=co2_alpha(:,:), & + pCO2surf=topaz%pco2_csurf(:,:), & + co3_ion=co3_ion_field(:,:,1)) + else call FMS_ocmip2_co2calc(CO2_dope_vec,grid_tmask(:,:,1), & SST(:,:), SSS(:,:), & dic_field(:,:,1,tau), & @@ -6107,6 +6170,7 @@ subroutine generic_TOPAZ_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau co2star=co2_csurf(:,:), alpha=co2_alpha(:,:), & pCO2surf=topaz%pco2_csurf(:,:), & co3_ion=co3_ion_field(:,:,1)) + endif !Set fields !nnz: if These are pointers do I need to do this? call g_tracer_set_values(tracer_list,'htotal' ,'field',htotal_field ,isd,jsd,ntau=1) @@ -6242,6 +6306,7 @@ end subroutine generic_TOPAZ_set_boundary_values subroutine generic_TOPAZ_end + character(len=fm_string_len), parameter :: sub_name = 'generic_TOPAZ_end' call user_deallocate_arrays end subroutine generic_TOPAZ_end diff --git a/src/ocean_shared/generic_tracers/generic_miniBLING.F90 b/src/ocean_shared/generic_tracers/generic_miniBLING.F90 new file mode 100644 index 0000000000..7908ae2e7b --- /dev/null +++ b/src/ocean_shared/generic_tracers/generic_miniBLING.F90 @@ -0,0 +1,3847 @@ +!---------------------------------------------------------------- +! Eric D. Galbraith +! +! +! John P. Dunne +! +! +! Anand Gnanandesikan +! +! +! Niki Zadeh +! +! +! Rick Slater +! +! +! +! This module contains the generic version of miniBLING. +! 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 reasonably well tested, the other components should be viewed as +! developmental at this point. There may still be some bugs. +! +! Also, the growth parameters have been tuned to produce a reasonable simulation +! of PO4 and chl in a 3-degree CORE-forced version of MOM4p1. It is unlikely that +! these parameter choices will produce satisfactory simulations in other physical +! model configurations, and may need to be adjusted. +! +! +! +! Biogeochemistry with Light, Iron, Nutrient and Gas version zero (BLINGv0) +! 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 miniBLING behaviour, as +! well as tracers for radiocarbon (14c), a decomposition of carbon +! components by gas exchange and remineralization (carbon_pre), a +! decomposition of oxygen as preformed and total (o2_pre), saturation and +! consumed, and a decomposition of phosphate as preformed and remineralized +! (po4_pre). +! +! +! +! +! This model is available for public use. +! The current version is BLINGv0. 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. 2010. +! Regional impacts of iron-light colimitation in a global +! biogeochemical model. Biogeosciences , 7, 1043-1064. +! +! 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. +! +! +! +! This code was originally developed based on the template of Perth generic TOPAZ code. +! +! +! +! +! +! +! If true, then simulate radiocarbon. Includes 2 prognostic tracers, DI14C +! and DO14C. Requires that do_carbon = .true. +! +! +! +! If true, then simulate the carbon cycle based on strict stoichiometry +! of C:P. Includes 1 prognostic tracer, DIC. +! +! +! +! +!---------------------------------------------------------------- + +#include + +module generic_miniBLING_mod + + use coupler_types_mod, only: coupler_2d_bc_type + use field_manager_mod, only: fm_string_len, fm_path_name_len, fm_field_name_len + use mpp_mod, only: mpp_error, NOTE, FATAL + use mpp_mod, only: stdout + use time_manager_mod, only: time_type + use diag_manager_mod, only: register_diag_field, send_data + use constants_mod, only: WTMCO2, WTMO2 + use data_override_mod, only: data_override + + use g_tracer_utils, only : g_tracer_type,g_tracer_start_param_list,g_tracer_end_param_list + use g_tracer_utils, only : g_tracer_add,g_tracer_add_param, g_tracer_set_files + use g_tracer_utils, only : g_tracer_set_values,g_tracer_get_pointer + use g_tracer_utils, only : g_tracer_get_common + use g_tracer_utils, only : g_tracer_coupler_set,g_tracer_coupler_get + use g_tracer_utils, only : g_tracer_get_values, g_tracer_column_int, g_tracer_flux_at_depth + + use FMS_ocmip2_co2calc_mod, only : FMS_ocmip2_co2calc, CO2_dope_vector + + implicit none ; private + + character(len=fm_string_len), parameter :: mod_name = 'generic_miniBLING' + character(len=fm_string_len), parameter :: package_name = 'generic_minibling' + + public do_generic_miniBLING + public generic_miniBLING_register + public generic_miniBLING_init + public generic_miniBLING_register_diag + public generic_miniBLING_update_from_coupler + public generic_miniBLING_diag + public generic_miniBLING_update_from_source + public generic_miniBLING_update_from_bottom + public generic_miniBLING_set_boundary_values + public generic_miniBLING_end + + !The following logical for using this module is overwritten + ! generic_tracer_nml namelist + logical, save :: do_generic_miniBLING = .false. + logical, save :: module_is_initialized = .false. + + real, parameter :: sperd = 24.0 * 3600.0 + real, parameter :: spery = 365.25 * sperd + real, parameter :: epsln=1.0e-30 + + + ! + !The following two types contain all the parameters and arrays used in this module. + + type generic_miniBLING_type + + character(len=fm_string_len) :: name = '_' + character(len=fm_field_name_len) :: suffix = ' ' + character(len=fm_field_name_len) :: long_suffix = ' ' + logical :: prevent_neg_o2 = .true. + + ! Turn on additional complexity. Most relevant diagnostic variables and all + ! tracers are not activated unless the appropriate switch is set to true. + + logical :: do_14c = .true. ! Requires do_carbon = .true. + logical :: do_carbon = .true. + real :: min_frac_pop = 0.0 ! Set to 1 to turn off recycling + + character(len=fm_string_len) :: alk_scheme = 'normal' ! Specify the scheme to use for calculating alkalinity + character(len=fm_string_len) :: biomass_type = 'single' ! Specify the scheme to use for calculating biomass + real :: alk_slope = 32.0e-06 ! Slope of alk:salt equation + real :: alk_intercept = 1200.0e-06 ! Intercept of alk:salt equation + real :: alpha_photo ! Quantum yield under low light + real :: c_2_p ! Carbon to Phosphorus ratio + real :: chl_min ! Minimum chl concentration allowed (for numerical stability) + logical :: fe_is_prognostic = .false. ! Set whether Fed is prognostic or diagnostic + logical :: fe_is_diagnostic = .false. ! Set whether Fed is diagnostic or data + real :: fe_restoring = 10.0 ! Restoring time scale, in days, if Fed is diagnostic + real :: fe_coastal = 2.0e-09 ! Coastal iron concentration, in mol/kg, if Fed is diagnostic + real :: fe_coastal_depth = 200.0 ! Coastal depth, in meters, if Fed is diagnostic + real :: fe_2_p_max ! Iron to Phosphate uptake ratio scaling + real :: def_fe_min = 0.0 ! Minimum for iron deficiency + real :: fe_2_p_sed ! Iron to Phosphorus ratio in sediments + real :: felig_bkg ! Iron ligand concentration + real :: gamma_biomass ! Biomass adjustment timescale + real :: gamma_irr_mem ! Photoadaptation timescale + real :: gamma_pop ! Patriculate Organic Phosphorus decay + real :: half_life_14c ! Radiocarbon half-life + real :: k_fe_2_p ! Fe:P half-saturation constant + real :: k_fe_uptake ! Iron half-saturation concentration + real :: k_o2 ! Oxygen half-saturation concentration + real :: k_po4 ! Phosphate half-saturation concentration + real :: k_po4_recycle ! Phosphate half-saturation concentration + real :: kappa_eppley ! Temperature dependence + real :: kappa_remin ! Temperature dependence for particle fractionation + real :: kfe_inorg ! Iron scavenging, 2nd order + real :: kfe_eq_lig_max ! Maximum light-dependent iron ligand stability constant + real :: kfe_eq_lig_min ! Minimum light-dependent iron ligand stability constant + real :: kfe_eq_lig_irr ! Irradiance scaling for iron ligand stability constant + real :: kfe_eq_lig_femin ! Low-iron threshold for ligand stability constant + real :: kfe_org ! Iron scavenging, 1st order + real :: lambda0 ! Total mortality rate constant + real :: lambda_14c ! Radiocarbon decay rate + real :: mass_2_p ! Organic matter mass to Phosphorus ratio + real :: o2_2_p ! Oxygen to Phosphorus ratio + real :: o2_min ! Anaerobic respiration threshold + real :: P_star ! Pivotal phytoplankton concentration + real :: pc_0 ! Maximum carbon-specific growth rate + real :: phi_lg ! Fraction of small phytoplankton converted to detritus + real :: phi_sm ! Fraction of large phytoplankton converted to detritus + real :: po4_min ! Minimum PO4 concentration + real :: remin_min ! Minimum remineralization under low O2 + real :: thetamax_hi ! Maximum Chl:C ratio when iron-replete + real :: thetamax_lo ! Maximum Chl:C ratio when iron-limited + real :: wsink_acc ! Sinking rate acceleration with depth + real :: wsink0 ! Sinking rate at surface + real :: wsink0_z ! Depth to which sinking rate remains constant + + real :: htotal_scale_lo + real :: htotal_scale_hi + real :: htotal_in + real :: Rho_0 + real :: a_0 + real :: a_1 + real :: a_2 + real :: a_3 + real :: a_4 + real :: a_5 + real :: b_0 + real :: b_1 + real :: b_2 + real :: b_3 + real :: c_0 + real :: a1_co2 + real :: a2_co2 + real :: a3_co2 + real :: a4_co2 + real :: a1_o2 + real :: a2_o2 + real :: a3_o2 + real :: a4_o2 + +! +! the following arrays are used for calculation diagnostic integrals and fluxes at depth +! + + real, dimension(:,:,:), _ALLOCATABLE :: wrk_3d _NULL + real, dimension(:,:), _ALLOCATABLE :: wrk_2d _NULL + integer, dimension(:,:), _ALLOCATABLE :: k_lev _NULL + real, dimension(:,:), _ALLOCATABLE :: integral _NULL + real, dimension(:,:), _ALLOCATABLE :: flux _NULL + +! The prefix nomenclature is as follows: +! "f_t" = a "field", generally a working array for the concentration of tracer t +! "jt_process" = a source/sink term for tracer t due to a biogeochemical process. +! * Note, j terms are in units of mol kg-1 in the code, but are saved to the diagnostic +! file as layer integrals (i.e. multiplied by the layer thickness/density) +! "b_t" = the flux of tracer t out of the ocean bottom +! "p_t" = a pointer, generally to the concentration of a tracer t + + real, dimension(:,:,:), _ALLOCATABLE :: biomass_p_ts _NULL + real, dimension(:,:,:), _ALLOCATABLE :: def_fe _NULL + real, dimension(:,:,:), _ALLOCATABLE :: expkT _NULL + real, dimension(:,:,:), pointer :: p_biomass_p => NULL() + real, dimension(:,:,:), _ALLOCATABLE :: f_chl _NULL + real, dimension(:,:,:), _ALLOCATABLE :: f_fed _NULL + real, dimension(:,:,:), _ALLOCATABLE :: f_fed_data _NULL + real, dimension(:,:,:), pointer :: p_phyto_lg => NULL() + real, dimension(:,:,:), pointer :: p_phyto_sm => NULL() + real, dimension(:,:,:), pointer :: p_htotal => NULL() + real, dimension(:,:,:), pointer :: p_irr_mem => NULL() + real, dimension(:,:,:), _ALLOCATABLE :: f_o2 _NULL + real, dimension(:,:,:), _ALLOCATABLE :: f_po4 _NULL + real, dimension(:,:,:), _ALLOCATABLE :: fe_2_p_uptake _NULL + real, dimension(:,:,:), _ALLOCATABLE :: feprime _NULL + real, dimension(:,:,:), _ALLOCATABLE :: fpofe _NULL + real, dimension(:,:,:), _ALLOCATABLE :: fpop _NULL + real, dimension(:,:,:), _ALLOCATABLE :: frac_lg _NULL + real, dimension(:,:,:), _ALLOCATABLE :: frac_pop _NULL + real, dimension(:,:,:), _ALLOCATABLE :: irr_inst _NULL + real, dimension(:,:,:), _ALLOCATABLE :: irr_mix _NULL + real, dimension(:,:,:), _ALLOCATABLE :: irrk _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jfe_ads_inorg _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jfe_ads_org _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jfe_recycle _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jfe_reminp _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jfe_uptake _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jo2 _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jp_recycle _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jp_reminp _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jp_uptake _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jpo4 _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jfeop _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jpop _NULL + real, dimension(:,:,:), _ALLOCATABLE :: kfe_eq_lig _NULL + real, dimension(:,:,:), _ALLOCATABLE :: mu _NULL + real, dimension(:,:,:), _ALLOCATABLE :: pc_m _NULL + real, dimension(:,:,:), _ALLOCATABLE :: theta _NULL + real, dimension(:,:,:), _ALLOCATABLE :: thetamax_fe _NULL + real, dimension(:,:,:), _ALLOCATABLE :: wsink _NULL + real, dimension(:,:,:), _ALLOCATABLE :: zremin _NULL + real, dimension(:,:,:), _ALLOCATABLE :: zbot _NULL + + real, dimension(:,:), _ALLOCATABLE :: b_fed _NULL + real, dimension(:,:), _ALLOCATABLE :: b_o2 _NULL + real, dimension(:,:), _ALLOCATABLE :: b_po4 _NULL + real, dimension(:,:), _ALLOCATABLE :: fe_burial _NULL + real, dimension(:,:), _ALLOCATABLE :: ffe_sed _NULL + real, dimension(:,:), _ALLOCATABLE :: o2_saturation _NULL + + real, dimension(:,:), _ALLOCATABLE :: b_dic _NULL + real, dimension(:,:), _ALLOCATABLE :: co2_alpha _NULL + real, dimension(:,:), _ALLOCATABLE :: co2_csurf _NULL + real, dimension(:,:), _ALLOCATABLE :: htotallo _NULL + real, dimension(:,:), _ALLOCATABLE :: htotalhi _NULL + real, dimension(:,:), _ALLOCATABLE :: pco2_surf _NULL + real, dimension(:,:), _ALLOCATABLE :: surf_temp _NULL + real, dimension(:,:), _ALLOCATABLE :: surf_salt _NULL + real, dimension(:,:), _ALLOCATABLE :: surf_alk _NULL + real, dimension(:,:), _ALLOCATABLE :: surf_po4 _NULL + real, dimension(:,:), _ALLOCATABLE :: surf_sio4 _NULL + real, dimension(:,:), _ALLOCATABLE :: surf_dic _NULL + + real, dimension(:,:,:), _ALLOCATABLE :: c14_2_p _NULL + real, dimension(:,:,:), _ALLOCATABLE :: fpo14c _NULL + real, dimension(:,:,:), _ALLOCATABLE :: j14c_decay_dic _NULL + real, dimension(:,:,:), _ALLOCATABLE :: j14c_reminp _NULL + real, dimension(:,:,:), _ALLOCATABLE :: jdi14c _NULL + real, dimension(:,:), _ALLOCATABLE :: b_di14c _NULL + real, dimension(:,:), _ALLOCATABLE :: c14o2_alpha _NULL + real, dimension(:,:), _ALLOCATABLE :: c14o2_csurf _NULL + + real, dimension(:,:,:,:), pointer :: p_fed => NULL() + real, dimension(:,:,:), pointer :: p_fed_diag => NULL() + real, dimension(:,:,:,:), pointer :: p_o2 => NULL() + real, dimension(:,:,:,:), pointer :: p_po4 => NULL() + + real, dimension(:,:,:,:), pointer :: p_di14c => NULL() + real, dimension(:,:,:,:), pointer :: p_dic => NULL() + + character(len=fm_string_len) :: ice_restart_file + character(len=fm_string_len) :: ocean_restart_file + character(len=fm_string_len) :: IC_file + + real :: diag_depth = 100.0 ! Depth over which to integrate and at which to get flux + ! for diagnostics + character(len=16) :: diag_depth_str = ' ' ! String to hold diag depth + + integer :: id_b_dic = -1 ! Bottom flux of DIC + integer :: id_b_di14c = -1 ! Bottom flux of DI14C + integer :: id_b_fed = -1 ! Bottom flux of Fe + integer :: id_b_o2 = -1 ! Bottom flux of O2 + integer :: id_b_po4 = -1 ! Bottom flux of PO4 + integer :: id_biomass_p_ts = -1 ! Instantaneous P concentration in biomass + integer :: id_c14_2_p = -1 ! DI14C to PO4 uptake ratio + integer :: id_c14o2_csurf = -1 ! Surface water 14CO2* + integer :: id_c14o2_alpha = -1 ! Surface water 14CO2* solubility + integer :: id_co2_csurf = -1 ! Surface water CO2* + integer :: id_co2_alpha = -1 ! Surface water CO2* solubility + integer :: id_def_fe = -1 ! Iron deficiency term + integer :: id_expkT = -1 ! Temperature dependence + integer :: id_fe_2_p_uptake = -1 ! Fed:PO4 of instantaneous uptake + integer :: id_feprime = -1 ! Free (unbound) iron concentration + integer :: id_fe_burial = -1 ! Flux of iron to sediment as particulate + integer :: id_ffe_sed = -1 ! Sediment iron efflux + integer :: id_fpofe = -1 ! POFe sinking flux + integer :: id_fpo14c = -1 ! PO14C sinking flux + integer :: id_fpop = -1 ! POP sinking flux + integer :: id_fpop_depth = -1 ! POP sinking flux at depth + integer :: id_frac_lg = -1 ! Fraction of production by large phytoplankton + integer :: id_frac_pop = -1 ! Fraction of uptake converted to particulate + integer :: id_irr_inst = -1 ! Instantaneous irradiance + integer :: id_irr_mix = -1 ! Mixed layer irradiance + integer :: id_irrk = -1 ! Effective susceptibility to light limitation + integer :: id_j14c_decay_dic = -1 ! Radioactive decay of DI14C + integer :: id_j14c_reminp = -1 ! 14C particle remineralization layer integral + integer :: id_jdi14c = -1 ! DI14C source layer integral + integer :: id_jfe_ads_inorg = -1 ! Iron adsorption (2nd order) layer integral + integer :: id_jfe_ads_org = -1 ! Iron adsorption to fpop layer integral + integer :: id_jfe_recycle = -1 ! Iron fast recycling layer integral + integer :: id_jfe_reminp = -1 ! Iron particle remineralization layer integral + integer :: id_jfe_uptake = -1 ! Iron uptake layer integral + integer :: id_jo2 = -1 ! O2 source layer integral + integer :: id_jo2_depth = -1 ! Depth integral of O2 source + integer :: id_jp_recycle = -1 ! Phosphorus fast recycling layer integral + integer :: id_jp_recycle_depth = -1 ! Depth integral of Phosphorus fast recycling + integer :: id_jp_reminp = -1 ! Phosphorus particle remineralization layer integral + integer :: id_jp_reminp_depth = -1 ! Depth integral of Phosphorus particle remineralization + integer :: id_jp_uptake = -1 ! Phosphorus uptake layer integral + integer :: id_jp_uptake_depth = -1 ! Depth integral of Phosphorus uptake + integer :: id_jpo4 = -1 ! PO4 source layer integral + integer :: id_jpo4_depth = -1 ! Depth integral of PO4 source layer integral + integer :: id_jfeop = -1 ! Particulate organic iron source layer integral + integer :: id_jpop = -1 ! Particulate organic phosphorus source layer integral + integer :: id_kfe_eq_lig = -1 ! Iron-ligand stability constant + integer :: id_mu = -1 ! Growth rate after respiratory loss(carbon specific) + integer :: id_o2_saturation = -1 ! Surface water O2 saturation + integer :: id_pc_m = -1 ! Light-saturated maximum photosynthesis rate (carbon specific) + integer :: id_pco2_surf = -1 ! Surface water pCO2 + integer :: id_temp_co2calc = -1 ! Surface temp for co2calc + integer :: id_salt_co2calc = -1 ! Surface salt for co2calc + integer :: id_alk_co2calc = -1 ! Surface temp for co2calc + integer :: id_po4_co2calc = -1 ! Surface temp for co2calc + integer :: id_sio4_co2calc = -1 ! Surface temp for co2calc + integer :: id_dic_co2calc = -1 ! Surface temp for co2calc + integer :: id_theta = -1 ! Chl:C ratio + integer :: id_thetamax_fe = -1 ! Iron-limited maximum Chl:C ratio + integer :: id_wsink = -1 ! Sinking rate + integer :: id_zremin = -1 ! Remineralization length scale + integer :: id_fed_data = -1 ! Dissolved Iron data + + integer :: id_di14c_surf = -1 ! Surface dissolved inorganic radiocarbon Prognostic tracer + integer :: id_dic_surf = -1 ! Surface dissolved inorganic carbon Prognostic tracer + integer :: id_fed_surf = -1 ! Surface dissolved Iron Prognostic tracer + integer :: id_o2_surf = -1 ! Surface oxygen Prognostic tracer + integer :: id_po4_surf = -1 ! Surface phosphate Prognostic tracer + integer :: id_di14c_depth = -1 ! Depth integral of dissolved inorganic radiocarbon Prognostic tracer + integer :: id_dic_depth = -1 ! Depth integral of dissolved inorganic carbon Prognostic tracer + integer :: id_fed_depth = -1 ! Depth integral of dissolved Iron Prognostic tracer + integer :: id_o2_depth = -1 ! Depth integral of oxygen Prognostic tracer + integer :: id_po4_depth = -1 ! Depth integral of phosphate Prognostic tracer + + integer :: id_fed_data_surf = -1 ! Surface dissolved Iron data + integer :: id_htotal_surf = -1 ! Surface hydrogen ion Diagnostic tracer + integer :: id_chl_surf = -1 ! Surface chlorophyll Diagnostic tracer + integer :: id_biomass_p_surf = -1 ! Surface biomass Diagnostic tracer + integer :: id_phyto_lg_surf = -1 ! Surface large phytoplankton + integer :: id_phyto_sm_surf = -1 ! Surface small phytoplankton + integer :: id_irr_mem_surf = -1 ! Surface irradiance Memory Diagnostic tracer + integer :: id_fed_data_depth = -1 ! Depth integral of dissolved Iron data + integer :: id_chl_depth = -1 ! Depth integral of chlorophyll Diagnostic tracer + integer :: id_biomass_p_depth = -1 ! Depth integral of biomass Diagnostic tracer + integer :: id_phyto_lg_depth = -1 ! Depth integral of large phytoplankton + integer :: id_phyto_sm_depth = -1 ! Depth integral of small phytoplankton + integer :: id_irr_mem_depth = -1 ! Depth integral of irradiance Memory Diagnostic tracer + + logical :: override_surf_temp = .true. ! True if overriding surface properties + logical :: override_surf_salt = .true. ! Must be true for first try, and will then + logical :: override_surf_alk = .true. ! be set accordingly by data_override + logical :: override_surf_po4 = .true. + logical :: override_surf_sio4 = .true. + logical :: override_surf_dic = .true. + + end type generic_miniBLING_type + + !An auxiliary type for storing varible names and descriptions + type, public :: vardesc + character(len=fm_string_len) :: name ! The variable name in a NetCDF file. + character(len=fm_string_len) :: longname ! The long name of that variable. + character(len=1) :: hor_grid ! The hor. grid: u, v, h, q, or 1. + character(len=1) :: z_grid ! The vert. grid: L, i, or 1. + character(len=1) :: t_grid ! The time description: s, a, m, or 1. + character(len=fm_string_len) :: units ! The dimensions of the variable. + character(len=1) :: mem_size ! The size in memory: d or f. + end type vardesc + + type(generic_miniBLING_type) :: bling + integer, parameter :: num_instances = 1 + !type(generic_miniBLING_type), dimension(:), pointer :: bling + !integer :: num_instances + + type(CO2_dope_vector) :: CO2_dope_vec + +contains + + +!####################################################################### + + subroutine generic_miniBLING_register(tracer_list) + + type(g_tracer_type), pointer, intent(inout) :: tracer_list + +!----------------------------------------------------------------------- +! local parameters +!----------------------------------------------------------------------- +! + character(len=fm_string_len), parameter :: sub_name = 'generic_miniBLING_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) // '): ' + + integer :: n + integer :: stdout_unit + + stdout_unit = stdout() + + !Add here only the parameters that are required at the time of registeration + !(to make flux exchanging Ocean tracers known for all PE's) + ! + call g_tracer_start_param_list(package_name) + + call g_tracer_add_param('name', bling%name, '_') + + ! Turn on additional complexity. Most relevant diagnostic variables and all + ! tracers are not activated unless the appropriate switch is set to true. + call g_tracer_add_param('do_14c', bling%do_14c, .true.) + call g_tracer_add_param('do_carbon', bling%do_carbon, .true.) + + call g_tracer_add_param('ice_restart_file' , bling%ice_restart_file , 'ice_minibling.res.nc') + call g_tracer_add_param('ocean_restart_file', bling%ocean_restart_file, 'ocean_minibling.res.nc') + call g_tracer_add_param('IC_file' , bling%IC_file , '') + + call g_tracer_end_param_list(package_name) + + !----------------------------------------------------------------------- + +! Set the suffixes for this instance + + if (bling%name(1:1) .eq. '_') then + bling%suffix = ' ' + bling%long_suffix = ' ' + else !}{ + bling%suffix = '_' // bling%name + bling%long_suffix = ' (' // trim(bling%name) // ')' + endif !} + + ! Check for some possible fatal problems in the namelist variables. + + if ((bling%do_14c) .and. (bling%do_carbon)) then + write (stdout_unit,*) trim(note_header), 'Simulating radiocarbon for instance ' // trim(bling%name) + else if ((bling%do_14c) .and. .not. (bling%do_carbon)) then + call mpp_error(FATAL, trim(error_header) // & + ' Do_14c requires do_carbon for instance ' // trim(bling%name)) + endif + + ! Set Restart files + call g_tracer_set_files(ice_restart_file = bling%ice_restart_file,& + ocean_restart_file = bling%ocean_restart_file ) + + do n = 1, num_instances + + !All tracer fields shall be registered for diag output. + + !===================================================== + !Specify all prognostic tracers of this modules. + !===================================================== + !User adds one call for each prognostic tracer below! + !User should specify if fluxes must be extracted from boundary + !by passing one or more of the following methods as .true. + !and provide the corresponding parameters array + !methods: flux_gas,flux_runoff,flux_wetdep,flux_drydep + ! + !Pass an init_value arg if the tracers should be initialized to a nonzero value everywhere + !otherwise they will be initialized to zero. + ! + !=========================================================== + !Prognostic Tracers + !=========================================================== + ! + + ! Dissolved Fe + ! + if (bling%fe_is_prognostic) then + call g_tracer_add(tracer_list, package_name, & + name = 'fed' // bling%suffix, & + longname = 'Dissolved Iron' // bling%long_suffix, & + units = 'mol/kg', & + prog = .true., & + flux_runoff = .false., & + flux_wetdep = .true., & + flux_drydep = .true., & + flux_param = (/ 55.847e-03 /), & + flux_bottom = .true. ) + elseif (bling%fe_is_diagnostic) then + call g_tracer_add(tracer_list, package_name, & + name = 'fed' // bling%suffix, & + longname = 'Dissolved Iron' // bling%long_suffix, & + units = 'mol/kg', & + prog = .false.) + else + call mpp_error(NOTE, trim(note_header) // ' Fe is data overridden for instance ' // trim(bling%name)) + endif + + ! O2 + ! + call g_tracer_add(tracer_list, package_name, & + name = 'o2' // bling%suffix, & + longname = 'Oxygen' // bling%long_suffix, & + units = 'mol/kg', & + prog = .true., & + flux_gas = .true., & + flux_gas_type = 'air_sea_gas_flux_generic', & + flux_gas_name = 'o2_flux' // trim(bling%suffix), & + flux_gas_molwt = WTMO2, & + flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), & + flux_bottom = .true., & + flux_gas_restart_file = 'ocean_minibling_airsea_flux.res.nc' ) + + + ! PO4 + ! + call g_tracer_add(tracer_list, package_name, & + name = 'po4' // bling%suffix, & + longname = 'Phosphate' // bling%long_suffix, & + units = 'mol/kg', & + prog = .true., & + flux_bottom = .true. ) + + + !=========================================================== + !Diagnostic Tracers + !=========================================================== + + ! Chl (Chlorophyll) + ! + call g_tracer_add(tracer_list, package_name, & + name = 'chl' // bling%suffix, & + longname = 'Chlorophyll' // bling%long_suffix, & + units = 'ug kg-1', & + prog = .false., & + init_value = 0.08 ) + + ! Irr_mem (Irradiance Memory) + ! + call g_tracer_add(tracer_list, package_name, & + name = 'irr_mem' // bling%suffix, & + longname = 'Irradiance memory' // bling%long_suffix, & + units = 'Watts/m^2', & + prog = .false.) + + if (bling%biomass_type .eq. 'single') then + + ! Biomass + ! + call g_tracer_add(tracer_list, package_name, & + name = 'biomass_p' // bling%suffix, & + longname = 'Biomass in P units' // bling%long_suffix, & + units = 'mol P kg-1', & + prog = .false.) + + elseif (bling%biomass_type .eq. 'lg_sm_phyto') then + + ! Large phytoplankton biomass + ! + call g_tracer_add(tracer_list, package_name, & + name = 'phyto_lg' // bling%suffix, & + longname = 'Large phytoplankton biomass in P units' // bling%long_suffix, & + units = 'mol P kg-1', & + prog = .false., & + init_value = 4.e-07 ) + + ! Small phytoplankton biomass + ! + call g_tracer_add(tracer_list, package_name, & + name = 'phyto_sm' // bling%suffix, & + longname = 'Small phytoplankton biomass in P units' // bling%long_suffix, & + units = 'mol P kg-1', & + prog = .false., & + init_value = 4.e-07 ) + + else + + call mpp_error(FATAL, trim(error_header) // ' Unknown biomass type "' // trim(bling%biomass_type) // '"') + + endif + + if (bling%do_carbon) then !<> + + endif !} !CARBON CYCLE>> + + enddo !} n + + end subroutine generic_miniBLING_register + + +!####################################################################### + ! + ! + ! Initialize the generic miniBLING module + ! + ! + ! This subroutine: + ! Adds all the miniBLING 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. + ! + ! + ! + + subroutine generic_miniBLING_init(tracer_list) + + type(g_tracer_type), pointer :: tracer_list + +!----------------------------------------------------------------------- +! local parameters +!----------------------------------------------------------------------- +! + character(len=64), parameter :: sub_name = 'generic_miniBLING_init' + + character(len=256) :: caller_str + character(len=256) :: error_header + character(len=256) :: warn_header + character(len=256) :: note_header + integer :: n + character(len=fm_field_name_len) :: name + integer :: nn + character(len=fm_field_name_len), pointer, dimension(:) :: names => NULL() + integer :: stdout_unit + character(len=fm_string_len) :: string + integer :: package_index + + stdout_unit = stdout() + + ! Set up the field input + + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[]' + error_header = '==>Error from ' // trim(caller_str) // ':' + warn_header = '==>Warning from ' // trim(caller_str) // ':' + note_header = '==>Note from ' // trim(caller_str) // ':' + + write (stdout_unit,*) + write (stdout_unit,*) trim(note_header), ' Processing generic tracer package miniBLING' + + do n = 1, num_instances + + !Specify all parameters used in this modules. + !============================================================== + !User adds one call for each parameter below! + !User also adds the definition of each parameter in generic_miniBLING_params type + !============================================================== + + !Add the known experimental parameters used for calculations in this module. + !All the g_tracer_add_param calls must happen between + !g_tracer_start_param_list and g_tracer_end_param_list calls. + !This implementation enables runtime overwrite via field_table. + + call g_tracer_start_param_list(package_name) + + ! Rho_0 is used in the Boussinesq + ! approximation to calculations of pressure and + ! pressure gradients, in units of kg m-3. + call g_tracer_add_param('RHO_0', bling%Rho_0, 1035.0) + + !----------------------------------------------------------------------- + ! Gas exchange + !----------------------------------------------------------------------- + ! coefficients for O2 saturation + !----------------------------------------------------------------------- + call g_tracer_add_param('a_0', bling%a_0, 2.00907) + call g_tracer_add_param('a_1', bling%a_1, 3.22014) + call g_tracer_add_param('a_2', bling%a_2, 4.05010) + call g_tracer_add_param('a_3', bling%a_3, 4.94457) + call g_tracer_add_param('a_4', bling%a_4, -2.56847e-01) + call g_tracer_add_param('a_5', bling%a_5, 3.88767) + call g_tracer_add_param('b_0', bling%b_0, -6.24523e-03) + call g_tracer_add_param('b_1', bling%b_1, -7.37614e-03) + call g_tracer_add_param('b_2', bling%b_2, -1.03410e-02 ) + call g_tracer_add_param('b_3', bling%b_3, -8.17083e-03) + call g_tracer_add_param('c_0', bling%c_0, -4.88682e-07) + !----------------------------------------------------------------------- + ! Schmidt number coefficients + !----------------------------------------------------------------------- + ! Compute the Schmidt number of CO2 in seawater using the + ! formulation presented by Wanninkhof (1992, J. Geophys. Res., 97, + ! 7373-7382). + !----------------------------------------------------------------------- + !New Wanninkhof numbers + call g_tracer_add_param('a1_co2', bling%a1_co2, 2068.9) + call g_tracer_add_param('a2_co2', bling%a2_co2, -118.63) + call g_tracer_add_param('a3_co2', bling%a3_co2, 2.9311) + call g_tracer_add_param('a4_co2', bling%a4_co2, -0.027) + !--------------------------------------------------------------------- + ! Compute the Schmidt number of O2 in seawater using the + ! formulation proposed by Keeling et al. (1998, Global Biogeochem. + ! Cycles, 12, 141-163). + !--------------------------------------------------------------------- + !New Wanninkhof numbers + call g_tracer_add_param('a1_o2', bling%a1_o2, 1929.7) + call g_tracer_add_param('a2_o2', bling%a2_o2, -117.46) + call g_tracer_add_param('a3_o2', bling%a3_o2, 3.116) + call g_tracer_add_param('a4_o2', bling%a4_o2, -0.0306) + + call g_tracer_add_param('htotal_scale_lo', bling%htotal_scale_lo, 0.01) + call g_tracer_add_param('htotal_scale_hi', bling%htotal_scale_hi, 100.0) + + !----------------------------------------------------------------------- + ! Uptake + !----------------------------------------------------------------------- + ! + ! Phytoplankton growth altered from Geider et al (1997) + ! and Moore et al (2002). + ! The factor of 6.022e17 is to convert + ! from umol to quanta and 2.77e18 to convert from quanta/sec + ! to Watts given the average energy spectrum for underwater + ! PAR from the Seabird sensor. + ! + call g_tracer_add_param('alk_scheme', bling%alk_scheme, 'normal') + call g_tracer_add_param('alk_slope', bling%alk_slope, 32.0e-06) + call g_tracer_add_param('alk_intercept', bling%alk_intercept, 1200.0e-06) + call g_tracer_add_param('biomass_type', bling%biomass_type, 'single') + call g_tracer_add_param('alpha_photo', bling%alpha_photo, 1.e-5 * 2.77e+18 / 6.022e+17) ! g C g Chl-1 m2 W-1 s-1 + call g_tracer_add_param('kappa_eppley', bling%kappa_eppley, 0.063) ! deg C-1 + call g_tracer_add_param('pc_0', bling%pc_0, 1.0e-5) ! s-1 + call g_tracer_add_param('thetamax_hi', bling%thetamax_hi, 0.040) ! g Chl g C-1 + call g_tracer_add_param('thetamax_lo', bling%thetamax_lo, 0.010) ! g Chl g C-1 + ! + ! Chl:C response rate constant for phytoplankton calibrated to 1 d-1 + ! after Owens et al (1980, Diel Periodicity in cellular Chlorophyll + ! content of marine diatoms, Mar. Biol, 59, 71-77). + ! + call g_tracer_add_param('gamma_irr_mem', bling%gamma_irr_mem, 1.0 / sperd) ! s-1 + + ! Introduce a minimum chlorophyll concentration for numerical stability. + ! Value is an order of magnitude less than the minimum produced in topaz. + ! + call g_tracer_add_param('chl_min', bling%chl_min, 1.e-5) ! ug kg-1 + ! + ! The biomass reponds to changes in growth rate with an arbitrary 2 day lag. + ! + call g_tracer_add_param('gamma_biomass', bling%gamma_biomass, 0.5 / sperd) ! s-1 + + !----------------------------------------------------------------------- + ! Monod half saturation coefficient for phosphate. Value of Aumont (JGR, 2002) + ! used for large phytoplankton. + + call g_tracer_add_param('k_po4', bling%k_po4, 1.0e-7) ! mol PO4 kg-1 + + call g_tracer_add_param('po4_min', bling%po4_min, 1.0e-8) ! mol PO4 kg-1 + + !----------------------------------------------------------------------- + ! Fe uptake and limitation. + ! The uptake ratio of Fe:P is determined from a Monod constant and a + ! scaling factor. + ! The k_Fe_uptake is high, to provide luxury uptake of iron as a + ! relatively linear function of iron concentrations under open-ocean + ! conditions, consistent with the results of Sunda and Huntsman (Fig 1, + ! Nature, 1997). + + call g_tracer_add_param('k_fe_uptake', bling%k_fe_uptake, 0.8e-9) ! mol Fe kg-1 + + ! This Monod term, which is nearly linear with [Fe], is multiplied by a + ! scaling term to provide the actual Fe:P uptake ratio such that, at + ! [Fe] = k_fe_uptake, Fe:P = fe_2_p_max / 2. + ! This maximum value was set in accordance with the range of + ! open-ocean Fe:C ratios summarized by Boyd et al. (Science, 2007) and + ! converted to a Fe:P ratio. + ! As a tuning parameter, it affects the amount of Fe that cycles via the + ! organic matter pathway, and its ratio to k_fe_2_p determines the + ! degree of iron limitation (the larger this ratio, the less iron + ! limitation there will be). + + call g_tracer_add_param('fe_2_p_max', bling%fe_2_p_max, 28.e-6 * 106.) ! mol Fed mol PO4-1 + + ! + ! New paramter to help with non-prognostic iron + ! + + call g_tracer_add_param('def_fe_min', bling%def_fe_min, 0.0) ! ? + + ! + ! If fe_is_prognostic is true, then Fed will be a prognostic variable, otherwise + ! if fe_is_diagnostic is true, then it will be diagnostic, restoring to a 3-d field with + ! a time-scale of fe_restoring (in days), otherwise fed will be data driven + ! with any coastal increase. + ! + call g_tracer_add_param('fe_is_prognostic', bling%fe_is_prognostic, .false.) + call g_tracer_add_param('fe_is_diagnostic', bling%fe_is_diagnostic, .false.) + call g_tracer_add_param('fe_restoring', bling%fe_restoring, 10.0) ! days + call g_tracer_add_param('fe_coastal', bling%fe_coastal, 2.0e-09) ! mol/kg + call g_tracer_add_param('fe_coastal_depth', bling%fe_coastal_depth, 200.0) ! m + + ! The k_fe_2_p is the Fe:P at which the iron-limitation term has a + ! value of 0.5, chosen according to Sunda and Huntsman (Fig. 2, + ! Nature, 1997). Converted from Fe:C ratio. + + call g_tracer_add_param('k_fe_2_p', bling%k_fe_2_p, 7.e-6 * 106.) ! mol Fe mol P-1 + + !----------------------------------------------------------------------- + ! Mortality & Remineralization + !----------------------------------------------------------------------- + ! + ! T=0 phytoplankton specific total-mortality rate from the global + ! synthesis of Dunne et al. (2005) + ! + call g_tracer_add_param('lambda0', bling%lambda0, 0.19 / sperd) ! s-1 + ! + ! Pivot phytoplankton concentration for grazing-based + ! variation in ecosystem structure from the global + ! synthesis of Dunne et al. (2005). Converted from mol C m-3. + ! + call g_tracer_add_param('P_star', bling%P_star, 1.9e-3 / 1028. / 106.0) ! mol P kg-1 + ! + ! Temperature-dependence of fractional detritus production + ! from the global synthesis of Dunne et al. (2005) + ! + call g_tracer_add_param('kappa_remin', bling%kappa_remin, -0.032) ! deg C-1 + + ! Phytoplankton fractional detritus production by size class, + ! from the global synthesis of Dunne et al. (2005) + call g_tracer_add_param('phi_lg', bling%phi_lg, 1.0) ! unitless + call g_tracer_add_param('phi_sm', bling%phi_sm, 0.18) ! unitless + + ! Half saturation constant for fast recycling of P, very low to act only in nutrient-poor waters + call g_tracer_add_param('k_po4_recycle', bling%k_po4_recycle, 2.0e-8) ! mol PO4 kg-1 + + !----------------------------------------------------------------------- + ! Remineralization + !----------------------------------------------------------------------- + ! + ! Stoichiometric ratios taken from Anderson (1995) as discussed in + ! Sarmiento and Gruber (2008), and Sarmiento et al. (2002) for Ca:P. + ! + call g_tracer_add_param('c_2_p', bling%c_2_p, 106.0 ) ! mol C mol P-1 + call g_tracer_add_param('o2_2_p', bling%o2_2_p, 150.0 ) ! mol O2 mol P-1 + ! Convert from mol P m-3 to mg C l-1 + call g_tracer_add_param('mass_2_p', bling%mass_2_p, 106. * 12.001 ) ! g C mol P-1 + + ! Radiocarbon + call g_tracer_add_param('half_life_14c', bling%half_life_14c, 5730.0 ) ! a + + ! + !----------------------------------------------------------------------- + ! Remineralization length scales + ! + ! Values of parameters to approximate upper e-folding of the globally-tuned + ! "Martin curve" used in the OCMIP-II Biotic configuration of (z/75)^-0.9 + ! that gives a value of exp(-1) at 228 m from 75 m for an e-folding scale + ! of 188 m. + ! Here these are given as a linear function of depth, + ! wsink = wsink0 + wsink_acc * (z - wsink0_z) + + call g_tracer_add_param('wsink_acc', bling%wsink_acc, 0.05 / sperd) ! s-1 + call g_tracer_add_param('wsink0', bling%wsink0, 16.0 / sperd) ! m s-1 + call g_tracer_add_param('wsink0_z', bling%wsink0_z, 80. ) ! m + call g_tracer_add_param('gamma_pop', bling%gamma_pop, 0.12 / sperd ) ! s-1 + + ! Half saturation oxygen concentration for oxic remineralization rate. + ! + call g_tracer_add_param('k_o2', bling%k_o2, 20.0e-6) ! mol O2 kg-1 + ! + ! Remineralization rate under suboxic/anoxic conditions, as a fraction of the rate under + ! fully oxidized conditions. As this code is currently intended for short, high-resolution runs, + ! this value is set to zero to cause a cessation of remineralization under suboxia/anoxia. + ! This will allow P to sink past the OMZ, which lead lead to a downward expansion of the OMZ, + ! but it hopefully won't be a huge problem on the timescale of 100-200 years. + ! + call g_tracer_add_param('remin_min', bling%remin_min, 0.0) ! dimensionless + ! + ! Minimum oxygen concentration for oxic remineralization. + ! At O2 less than this, anaerobic remineralization occurs at remin_min rate. + ! + call g_tracer_add_param('o2_min', bling%o2_min, 1.0e-06) ! mol O2 kg-1 + ! + ! Prevent oxygen from becoming negative. Setting to false allows negative + ! oxygen in anoxic zones, which can be thought of as equivalent to + ! denitrification plus H2S production. + ! + call g_tracer_add_param('prevent_neg_o2', bling%prevent_neg_o2, .true. ) + + !----------------------------------------------------------------------- + ! Iron Cycling + ! + ! Global uniform iron ligand concentration. + ! Taken from Parekh, P., M. J. Follows and E. A. Boyle (2005) Decoupling of iron + ! and phosphate in the global ocean. Glob. Biogeochem. Cycles, 19, + ! doi: 10.1029/2004GB002280. + ! + call g_tracer_add_param('felig_bkg', bling%felig_bkg, 1.0e-9) ! mol ligand kg-1 + ! + ! Ratio of iron efflux from bottom sediment boundaries to the sedimenting phosphorus flux. + ! From Elrod et al. (2004), 0.68 mmol Fe mol C-1, after Moore et al (2008): + ! + call g_tracer_add_param('fe_2_p_sed', bling%fe_2_p_sed, 1.e-4 * 106.0 ) ! mol Fe mol P-1 + ! + ! 1.5-order iron scavenging in order to prevent high iron + ! accumulations in high deposition regions (like the tropical + ! Atlantic). This also helps prevent Fe accumulating in oligotrophic gyres and in + ! the abyssal ocean, where organic fluxes are low. + ! + call g_tracer_add_param('kfe_inorg', bling%kfe_inorg, 1.e3/sperd) ! mol.5 Fe-.5 kg s-1 + ! + ! Equilibrium constant for (free and inorganically bound) iron binding with organic + ! ligands taken from range similar to Parekh, P., M. J. Follows and E. A. Boyle + ! (2005) Decoupling of iron and phosphate in the global ocean. Glob. Biogeochem. + ! Cycles, 19, doi: 10.1029/2004GB002280. + ! + call g_tracer_add_param('kfe_eq_lig_max', bling%kfe_eq_lig_max, 8.e10) ! mol lig-1 kg + ! + ! Minimum ligand strength under high light, to represent photodissociation of + ! ligand-Fe complexes. + ! + call g_tracer_add_param('kfe_eq_lig_min', bling%kfe_eq_lig_min, 0.8e10) ! mol lig-1 kg + ! + ! Photodecay irradiance scaling. + ! + call g_tracer_add_param('kfe_eq_lig_irr', bling%kfe_eq_lig_irr, 0.1) ! W m-2 + ! + ! Iron concentration near which photodecay is compensated by enhanced siderophore + ! production. + ! + call g_tracer_add_param('kfe_eq_lig_femin', bling%kfe_eq_lig_femin, 0.05e-9) ! W m-2 + ! + ! Adsorption rate coefficient for detrital organic material. + ! + call g_tracer_add_param('kfe_org', bling%kfe_org, 0.5/sperd) ! g org-1 m3 s-1 + ! + ! Mimimum fraction of POP (for turning off recycling set to 1.0) + ! + call g_tracer_add_param('min_frac_pop', bling%min_frac_pop, 0.0) + ! + ! Depth for integral and flux diagnostics + ! + + !----------------------------------------------------------------------- + ! Miscellaneous + !----------------------------------------------------------------------- + ! + call g_tracer_add_param('diag_depth', bling%diag_depth, 100.0) ! use nearest integer + + ! + call g_tracer_end_param_list(package_name) + + ! + ! Check the diag depth and set a string for that depth + ! + + if (bling%diag_depth .gt. 0.0) then + bling%diag_depth = nint(bling%diag_depth) + write (bling%diag_depth_str, '(f10.0)') bling%diag_depth + bling%diag_depth_str = adjustl(bling%diag_depth_str) + bling%diag_depth_str = bling%diag_depth_str(1:len_trim(bling%diag_depth_str)-1) ! remove trailing decimal point + else + call mpp_error(FATAL, trim(error_header) // ' diag_depth <= 0 for instance ' // trim(bling%name)) + endif + + enddo !} n + + ! Allocate all the private work arrays used by this module. + call user_allocate_arrays + + end subroutine generic_miniBLING_init + + + +!####################################################################### + ! Register diagnostic fields to be used in this module. + ! Note that the tracer fields are automatically registered in user_add_tracers + ! User adds only diagnostics for fields that are not a member of g_tracer_type + ! + + subroutine generic_miniBLING_register_diag + + real, parameter :: missing_value1 = -1.0e+10 + type(vardesc) :: vardesc_temp + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + integer :: n + integer :: axes(3) + type(time_type) :: init_time + + call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, axes = axes, init_time = init_time) + + + ! The following vardesc types contain a package of metadata about each tracer, + ! including, in order, the following elements: name; longname; horizontal + ! staggering ('h') for collocation with thickness points ; vertical staggering + ! ('L') for a layer variable ; temporal staggering ('s' for snapshot) ; units ; + ! and precision in non-restart output files ('f' for 32-bit float or 'd' for + ! 64-bit doubles). For most tracers, only the name, longname and units should + ! be changed. + + ! + ! Register Diagnostics + !=========================================================== + ! + ! Core diagnostics + + do n = 1, num_instances + + if (bling%fe_is_prognostic) then + vardesc_temp = vardesc& + ("b_fed","Bottom flux of Fe into sediment",'h','1','s','mol m-2 s-1','f') + bling%id_b_fed = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("b_o2","Bottom flux of O2 into sediment",'h','1','s','mol m-2 s-1','f') + bling%id_b_o2 = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("b_po4","Bottom flux of PO4 into sediment",'h','1','s','mol m-2 s-1','f') + bling%id_b_po4 = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (bling%biomass_type .eq. 'single') then + vardesc_temp = vardesc& + ("biomass_p_ts","Instantaneous P concentration in biomass",'h','L','s','mol kg-1','f') + bling%id_biomass_p_ts = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("def_Fe","Iron deficiency term",'h','L','s','unitless','f') + bling%id_def_fe = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("expkT","Temperature dependence",'h','L','s','unitless','f') + bling%id_expkT = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("fe_2_p_uptake","Uptake ratio of Fed:PO4",'h','L','s','mol Fe mol P-1','f') + bling%id_fe_2_p_uptake = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (bling%fe_is_prognostic) then + vardesc_temp = vardesc& + ("fe_burial","Sedimenting iron flux",'h','1','s','mol m-2 s-1','f') + bling%id_fe_burial = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("feprime","Concentration of free, unbound iron",'h','L','s','mol kg-1','f') + bling%id_feprime = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("ffe_sed","Sediment iron efflux",'h','1','s','mol m-2 s-1','f') + bling%id_ffe_sed = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("fpofe","POFe sinking flux at layer bottom",'h','L','s','mol m-2 s-1','f') + bling%id_fpofe = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("fpop_" // trim(bling%diag_depth_str),"POP sinking flux at " // trim(bling%diag_depth_str) // " m", & + 'h','L','s','mol m-2 s-1','f') + bling%id_fpop_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("fpop","POP sinking flux at layer bottom",'h','L','s','mol m-2 s-1','f') + bling%id_fpop = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("frac_lg","Fraction of production by large phytoplankton",'h','L','s','unitless','f') + bling%id_frac_lg = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("frac_pop","Particulate fraction of total uptake",'h','L','s','unitless','f') + bling%id_frac_pop = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("irr_inst","Instantaneous light",'h','L','s','W m-2','f') + bling%id_irr_inst = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("irr_mix","Mixed layer light",'h','L','s','W m-2','f') + bling%id_irr_mix = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("irrk","Tendency to light limitation",'h','L','s','W m-2','f') + bling%id_irrk = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (bling%fe_is_prognostic) then + vardesc_temp = vardesc& + ("jfe_ads_inorg","Iron adsorption (2nd order) layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jfe_ads_inorg = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jfe_ads_org","Iron adsorption to FPOP layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jfe_ads_org = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jfe_recycle","Fast recycling of iron layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jfe_recycle = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + if (bling%fe_is_prognostic .or. bling%fe_is_diagnostic) then + vardesc_temp = vardesc& + ("jfe_reminp","Sinking particulate Fe decay layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jfe_reminp = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("jfe_uptake","Iron production layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jfe_uptake = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jo2_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral of o2 source", & + 'h','L','s','mol m-2 s-1','f') + bling%id_jo2_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jo2","O2 source layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jo2 = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jp_recycle_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral of fast recycling of PO4", & + 'h','L','s','mol m-2 s-1','f') + bling%id_jp_recycle_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jp_recycle","Fast recycling of PO4 layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jp_recycle = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jp_reminp_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral of sinking particulate P decay", & + 'h','L','s','mol m-2 s-1','f') + bling%id_jp_reminp_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jp_reminp","Sinking particulate P decay layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jp_reminp = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jp_uptake_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral of pO4 uptake", & + 'h','L','s','mol m-2 s-1','f') + bling%id_jp_uptake_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jp_uptake","PO4 uptake layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jp_uptake = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jpo4_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral of PO4 source", & + 'h','L','s','mol m-2 s-1','f') + bling%id_jpo4_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jpo4","PO4 source layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jpo4 = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("jpop","Particulate P source layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jpop = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (bling%fe_is_prognostic) then + vardesc_temp = vardesc& + ("jfeop","Particulate Fe source layer integral",'h','L','s','mol m-2 s-1','f') + bling%id_jfeop = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("kfe_eq_lig","Iron ligand stability constant",'h','L','s','mol-1 kg','f') + bling%id_kfe_eq_lig = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("mu","Net growth rate after respiratory loss",'h','L','s','s-1','f') + bling%id_mu = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("o2_saturation","Saturation O2 concentration",'h','1','s','mol kg-1','f') + bling%id_o2_saturation = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("pc_m","Light-saturated photosynthesis rate (carbon specific)",'h','L','s','s-1','f') + bling%id_pc_m = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("theta","Chl:C ratio",'h','L','s','g Chl g C-1','f') + bling%id_theta = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("thetamax_fe","Fe-limited max Chl:C",'h','L','s','g Chl g C-1','f') + bling%id_thetamax_fe = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("wsink","Sinking rate",'h','L','s','m s-1','f') + bling%id_wsink = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("zremin","Remineralization lengthscale",'h','L','s','m','f') + bling%id_zremin = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("o2_surf","Surface O2 concentration",'h','1','s','mol kg-1','f') + bling%id_o2_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("o2_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral O2", & + 'h','1','s','mol m-2','f') + bling%id_o2_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("fed_surf","Surface Fed concentration",'h','1','s','mol kg-1','f') + bling%id_fed_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("fed_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral Fed", & + 'h','1','s','mol m-2','f') + bling%id_fed_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (.not. bling%fe_is_prognostic) then + vardesc_temp = vardesc& + ("fed_data_surf","Surface Fed data concentration",'h','1','s','mol kg-1','f') + bling%id_fed_data_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("fed_data_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral Fedconcentration", & + 'h','1','s','mol m-2','f') + bling%id_fed_data_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("po4_surf","Surface PO4 concentration",'h','1','s','mol kg-1','f') + bling%id_po4_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("po4_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral PO4", & + 'h','1','s','mol m-2','f') + bling%id_po4_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("htotal_surf","Surface H+ concentration",'h','1','s','mol kg-1','f') + bling%id_htotal_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (bling%biomass_type .eq. 'single') then + vardesc_temp = vardesc& + ("biomass_p_surf","Surface Biomass-P concentration",'h','1','s','mol kg-1','f') + bling%id_biomass_p_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("biomass_p_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral BiomasP concentration", & + 'h','1','s','mol m-2','f') + bling%id_biomass_p_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + elseif (bling%biomass_type .eq. 'lg_sm_phyto') then + vardesc_temp = vardesc& + ("phyto_lg_surf","Surface large phytoplankton concentration",'h','1','s','mol kg-1','f') + bling%id_phyto_lg_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("phyto_lg_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral largeconcentration", & + 'h','1','s','mol m-2','f') + bling%id_phyto_lg_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("phyto_sm_surf","Surface small phytoplankton concentration",'h','1','s','mol kg-1','f') + bling%id_phyto_sm_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("phyto_sm_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral smallconcentration", & + 'h','1','s','mol m-2','f') + bling%id_phyto_sm_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + vardesc_temp = vardesc& + ("chl_surf","Surface Chl concentration",'h','1','s','mol kg-1','f') + bling%id_chl_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("chl_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral Chl", & + 'h','1','s','mol m-2','f') + bling%id_chl_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("irr_mem_surf","Surface IRR_mem concentration",'h','1','s','mol kg-1','f') + bling%id_irr_mem_surf = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + vardesc_temp = vardesc& + ("irr_mem_" // trim(bling%diag_depth_str),trim(bling%diag_depth_str) // " m integral IRR_mem", & + 'h','1','s','mol m-2','f') + bling%id_irr_mem_depth = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:2), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + if (.not. bling%fe_is_prognostic) then + vardesc_temp = vardesc& + ("fed_data","Fed data concentration",'h','1','s','mol kg-1','f') + bling%id_fed_data = register_diag_field(package_name, trim(vardesc_temp%name) // bling%suffix, & + axes(1:3), init_time, trim(vardesc_temp%longname) // bling%long_suffix, & + vardesc_temp%units, missing_value = missing_value1) + endif + + + if (bling%do_carbon) then !<> + + endif !} !CARBON CYCLE>> + + enddo !} n + + end subroutine generic_miniBLING_register_diag + + +!####################################################################### +! + ! + ! Modify the values obtained from the coupler if necessary. + ! + ! + ! Some tracer fields could be modified after values are obtained from the + ! coupler. This subroutine is the place for specific tracer manipulations. + ! miniBLING currently does not use this. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + + subroutine generic_miniBLING_update_from_coupler(tracer_list) + + type(g_tracer_type), pointer, intent(inout) :: tracer_list + + character(len=fm_string_len), parameter :: sub_name = 'generic_miniBLING_update_from_coupler' + + end subroutine generic_miniBLING_update_from_coupler + + +!####################################################################### + ! + ! + ! Set values of bottom fluxes and reservoirs + ! + ! + ! Some tracers could have bottom fluxes and reservoirs. + ! This subroutine is the place for specific tracer manipulations. + ! miniBLING currently does not use this. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + ! Time step increment + ! + ! + ! Time step index to be used for %field + ! + ! + + subroutine generic_miniBLING_update_from_bottom(tracer_list, dt, tau) + + type(g_tracer_type), pointer, intent(inout) :: tracer_list + real, intent(in) :: dt + integer, intent(in) :: tau + + end subroutine generic_miniBLING_update_from_bottom + + +!####################################################################### + ! + ! + ! Do things which must be done after tronsports and sources have been applied + ! + ! + ! This subroutine saves out surface diagnostic firlds for prognostic tracers + ! after vertical transport has been calculated + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + ! Time step index of %field + ! + ! + ! Model time + ! + ! + + subroutine generic_miniBLING_diag(tracer_list, ilb, jlb, tau, model_time, dzt, rho_dzt, caller) + + type(g_tracer_type), pointer, intent(inout) :: tracer_list + integer, intent(in) :: ilb + integer, intent(in) :: jlb + integer, intent(in) :: tau + type(time_type), intent(in) :: model_time + real, dimension(ilb:,jlb:,:), intent(in) :: dzt + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt + character(len=*), intent(in), optional :: caller + +!----------------------------------------------------------------------- +! local parameters + + character(len=fm_string_len), parameter :: sub_name = 'generic_miniBLING_diag' + + character(len=256) :: caller_str + character(len=256) :: error_header + character(len=256) :: warn_header + character(len=256) :: note_header + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + integer :: i + integer :: j + integer :: k + integer :: n + real, dimension(:,:,:), pointer :: grid_tmask + logical :: used + integer :: k_int + logical :: diag_initialized + + ! Set up the headers for stdout messages. + + if (present(caller)) then + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[' // trim(caller) // ']' + else + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[]' + endif + error_header = '==> Error from ' // trim(caller_str) // ':' + warn_header = '==> Warning from ' // trim(caller_str) // ':' + note_header = '==> Note from ' // trim(caller_str) // ':' + + ! Set up the module if not already done + + call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & + grid_tmask = grid_tmask) + + ! + !----------------------------------------------------------------------- + ! Save depth integrals and fluxes + !----------------------------------------------------------------------- + ! + + k_int = 0 + diag_initialized = .false. + + do n = 1, num_instances + + if (bling%id_po4_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_po4(:,:,:,tau), dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_po4_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_o2_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_o2(:,:,:,tau), dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_o2_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_dic_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_dic(:,:,:,tau), dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_dic_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_di14c_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_di14c(:,:,:,tau), dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_di14c_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%fe_is_prognostic) then + if (bling%id_fed_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_fed(:,:,:,tau), dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_fed_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + elseif (bling%fe_is_diagnostic) then + if (bling%id_fed_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_fed_diag, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_fed_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + else + if (bling%id_fed_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%f_fed, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_fed_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + endif + if (.not. bling%fe_is_prognostic) then + if (bling%id_fed_data_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%f_fed_data, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_fed_data_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + endif !} + if (bling%id_chl_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%f_chl, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_chl_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_biomass_p_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_biomass_p, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_biomass_p_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_phyto_lg_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_phyto_lg, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_phyto_lg_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_phyto_sm_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_phyto_sm, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_phyto_sm_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_irr_mem_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%p_irr_mem, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_irr_mem_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_jp_uptake_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%jp_uptake, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_jp_uptake_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_jp_recycle_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%jp_recycle, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_jp_recycle_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_jp_reminp_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%jp_reminp, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_jp_reminp_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_jpo4_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%jpo4, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_jpo4_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_jo2_depth .gt. 0) then + call g_tracer_column_int(bling%diag_depth, isd, jsd, bling%jo2, dzt, rho_dzt, & + bling%wrk_3d, k_int, bling%integral) + used = send_data(bling%id_jo2_depth, bling%integral, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + if (bling%id_fpop_depth .gt. 0) then + call g_tracer_flux_at_depth(bling%diag_depth, isd, jsd, bling%fpop, dzt, & + bling%k_lev, bling%wrk_2d, diag_initialized, bling%flux) + used = send_data(bling%id_fpop_depth, bling%flux, & + model_time, rmask = grid_tmask(:,:,1), is_in=isc, js_in=jsc, ie_in=iec, je_in=jec) + endif !} + + enddo + + ! + !----------------------------------------------------------------------- + ! Save surface prognostic variables for diagnostics, after vertical diffusion + !----------------------------------------------------------------------- + ! + + do n = 1, num_instances + + if (bling%id_po4_surf .gt. 0) & + used = send_data(bling%id_po4_surf, bling%p_po4(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_o2_surf .gt. 0) & + used = send_data(bling%id_o2_surf, bling%p_o2(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_dic_surf .gt. 0) & + used = send_data(bling%id_dic_surf, bling%p_dic(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_di14c_surf .gt. 0) & + used = send_data(bling%id_di14c_surf, bling%p_di14c(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%fe_is_prognostic) then + if (bling%id_fed_surf .gt. 0) & + used = send_data(bling%id_fed_surf, bling%p_fed(:,:,1,tau), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + elseif (bling%fe_is_diagnostic) then + if (bling%id_fed_surf .gt. 0) & + used = send_data(bling%id_fed_surf, bling%p_fed_diag(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + else + if (bling%id_fed_surf .gt. 0) & + used = send_data(bling%id_fed_surf, bling%f_fed(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + endif + + enddo + + return + + end subroutine generic_miniBLING_diag + + +!####################################################################### + ! + ! + ! Update tracer concentration fields due to the source/sink contributions. + ! + ! + ! This subroutine contains most of the biogeochemistry for calculating the + ! interaction of the core set of tracers with each other and with outside forcings. + ! Additional tracers (e.g. carbon, isotopes) are calculated in other subroutines. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + ! Lower bounds of x and y extents of input arrays on data domain + ! + ! + ! Ocean temperature + ! + ! + ! Ocean salinity + ! + ! + ! Ocean layer thickness (meters) + ! + ! + ! Ocean opacity + ! + ! + ! Shortwave peneteration + ! + ! + ! + ! + ! + ! Grid area + ! + ! + ! Time step index of %field + ! + ! + ! Time step increment + ! + ! + + subroutine generic_miniBLING_update_from_source(tracer_list, Temp, Salt, & + rho_dzt, dzt, hblt_depth, ilb, jlb, tau, dtts, grid_dat, model_time, nbands, & + max_wavelength_band, sw_pen_band, opacity_band, grid_ht) + + type(g_tracer_type), pointer, intent(inout) :: tracer_list + real, dimension(ilb:,jlb:,:), intent(in) :: Temp + real, dimension(ilb:,jlb:,:), intent(in) :: Salt + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt + real, dimension(ilb:,jlb:,:), intent(in) :: dzt + real, dimension(ilb:,jlb:), intent(in) :: hblt_depth + real, dimension(ilb:,jlb:), intent(in) :: grid_ht + integer, intent(in) :: ilb + integer, intent(in) :: jlb + integer, intent(in) :: tau + real, intent(in) :: dtts + real, dimension(ilb:,jlb:), intent(in) :: grid_dat + type(time_type), intent(in) :: model_time + integer, intent(in) :: nbands + real, dimension(:), intent(in) :: max_wavelength_band + real, dimension(:,ilb:,jlb:), intent(in) :: sw_pen_band + real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band + +!----------------------------------------------------------------------- +! local parameters + + character(len=fm_string_len), parameter :: sub_name = 'generic_miniBLING_update_from_source' + + character(len=256) :: caller_str + character(len=256) :: error_header + character(len=256) :: warn_header + character(len=256) :: note_header + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + integer :: i + integer :: j + integer :: k + integer :: kblt + integer :: n + real, dimension(:,:,:), pointer :: grid_tmask + integer, dimension(:,:), pointer :: grid_kmt + logical :: used + integer :: nb + real :: tmp_hblt + real :: tmp_Irrad + real :: tmp_irrad_ML + real :: tmp_phyto_lg_ML + real :: tmp_phyto_sm_ML + real :: tmp_opacity + real, dimension(:), Allocatable :: tmp_irr_band + real :: s_over_p + + ! Set up the headers for stdout messages. + + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[]' + error_header = '==>Error from ' // trim(caller_str) // ':' + warn_header = '==>Warning from ' // trim(caller_str) // ':' + note_header = '==>Note from ' // trim(caller_str) // ':' + + ! Set up the module if not already done + + call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & + grid_tmask = grid_tmask, grid_kmt = grid_kmt) + + + + ! SURFACE GAS FLUXES + ! + ! This subroutine coordinates the calculation of gas concentrations and solubilities + ! in the surface layer. The concentration of a gas is written as csurf, while the + ! solubility (in mol kg-1 atm-1 or mol m-3 atm-1) is written as alpha. These two + ! quantities are passed to the coupler, which multiplies their difference by the + ! gas exchange piston velocity over the mixed layer depth to provide the gas + ! exchange flux, + ! Flux = Kw/dz * (alpha - csurf) + ! + ! 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, and PO4. + ! + ! + ! Oxygen solubility is calculated here, using in situ temperature and salinity. + + !--------------------------------------------------------------------- + ! Get positive tracer concentrations for carbon calculation + !--------------------------------------------------------------------- + + allocate(tmp_irr_band(nbands)) + + do n = 1, num_instances + + bling%zbot = 0.0 + s_over_p = 0.0 + + !--------------------------------------------------------------------- + ! Get positive concentrations for prognostic tracers + !--------------------------------------------------------------------- + call g_tracer_get_values(tracer_list, 'po4' // bling%suffix, 'field', bling%f_po4, isd, jsd, & + ntau = tau, positive = .true.) + if (bling%fe_is_prognostic) then + call g_tracer_get_values(tracer_list, 'fed' // bling%suffix, 'field', bling%f_fed, isd, jsd, & + ntau = tau, positive = .true.) + else + call data_override('OCN', 'fed_data' // trim(bling%suffix), bling%f_fed_data, model_time) + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%f_fed_data(i,j,k) = & + max(bling%f_fed_data(i,j,k), & + bling%fe_coastal * (1.0 - grid_ht(i,j)/bling%fe_coastal_depth)) * grid_tmask(i,j,k) + enddo !} i + enddo !} j + enddo !} k + if (bling%fe_is_diagnostic) then + call g_tracer_get_values(tracer_list, 'fed' // bling%suffix, 'field', bling%f_fed, isd, jsd, & + positive = .true.) + else + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%f_fed(i,j,k) = bling%f_fed_data(i,j,k) + enddo !} i + enddo !} j + enddo !} k + endif + endif + call g_tracer_get_values(tracer_list, 'o2' // bling%suffix, 'field', bling%f_o2, isd, jsd, & + ntau = tau, positive = .true.) + + !--------------------------------------------------------------------- + ! Assign pointers for diagnostic tracers + !--------------------------------------------------------------------- + if (bling%biomass_type .eq. 'single') then + call g_tracer_get_pointer(tracer_list,'biomass_p' // bling%suffix,'field',bling%p_biomass_p) + elseif (bling%biomass_type .eq. 'lg_sm_phyto') then + call g_tracer_get_pointer(tracer_list,'phyto_lg'// bling%suffix,'field',bling%p_phyto_lg) + call g_tracer_get_pointer(tracer_list,'phyto_sm'// bling%suffix,'field',bling%p_phyto_sm) + endif + call g_tracer_get_pointer(tracer_list,'irr_mem' // bling%suffix,'field',bling%p_irr_mem) + + + if (bling%do_carbon) then !<> + endif !CARBON CYCLE>> + + + !-------------------------------------------------------------------------- + ! NUTRIENT UPTAKE + !-------------------------------------------------------------------------- + + ! Available light calculation + !----------------------------------------------------------------------- + ! There are multiple types of light. + ! irr_inst is the instantaneous irradiance field. + ! irr_mix is the same, but with the irr_inst averaged throughout the + ! mixed layer as defined in the KPP routine plus one more vertical box + ! to account for mixing directly below the boundary layer. This quantity + ! is intended to represent the light to which phytoplankton subject to + ! turbulent transport in the mixed-layer would be exposed. + ! irr_mem is a temporally smoothed field carried between timesteps, to + ! represent photoadaptation. + !----------------------------------------------------------------------- + + if (bling%biomass_type .eq. 'single') then + + do j = jsc, jec + do i = isc, iec + + do nb = 1,nbands + if (max_wavelength_band(nb) .lt. 710) then + tmp_irr_band(nb) = max(0.0,sw_pen_band(nb,i,j)) + else + tmp_irr_band(nb) = 0.0 + endif + enddo !} nbands + + kblt = 0 + tmp_irrad_ML = 0.0 + tmp_hblt = 0.0 + do k = 1, nk + tmp_Irrad = 0.0 + do nb = 1,nbands + tmp_opacity = opacity_band(nb,i,j,k) + tmp_Irrad = tmp_Irrad + tmp_irr_band(nb) * exp(-tmp_opacity * dzt(i,j,k) * 0.5) + ! Change tmp_irr_band from being the value atop layer k to the value at the bottom of layer k. + tmp_irr_band(nb) = tmp_irr_band(nb) * exp(-tmp_opacity * dzt(i,j,k)) + enddo !} nbands + bling%irr_inst(i,j,k) = tmp_Irrad * grid_tmask(i,j,k) + bling%irr_mix(i,j,k) = tmp_Irrad * grid_tmask(i,j,k) + if ((k == 1) .or. (tmp_hblt .lt. hblt_depth(i,j))) then + kblt = kblt+1 + tmp_irrad_ML = tmp_irrad_ML + bling%irr_mix(i,j,k) * dzt(i,j,k) + tmp_hblt = tmp_hblt + dzt(i,j,k) + endif + enddo !} k + bling%irr_mix(i,j,1:kblt) = tmp_irrad_ML / max(1.0e-6,tmp_hblt) + + enddo !} i + enddo !} j + + elseif (bling%biomass_type .eq. 'lg_sm_phyto') then + + do j = jsc, jec + do i = isc, iec + + do nb = 1,nbands + if (max_wavelength_band(nb) .lt. 710) then + tmp_irr_band(nb) = max(0.0,sw_pen_band(nb,i,j)) + else + tmp_irr_band(nb) = 0.0 + endif + enddo !} nbands + + kblt = 0 + tmp_irrad_ML = 0.0 + tmp_phyto_lg_ML = 0.0 + tmp_phyto_sm_ML = 0.0 + tmp_hblt = 0.0 + do k = 1, nk + tmp_Irrad = 0.0 + do nb = 1,nbands + tmp_opacity = opacity_band(nb,i,j,k) + tmp_Irrad = tmp_Irrad + tmp_irr_band(nb) * exp(-tmp_opacity * dzt(i,j,k) * 0.5) + ! Change tmp_irr_band from being the value atop layer k to the value at the bottom of layer k. + tmp_irr_band(nb) = tmp_irr_band(nb) * exp(-tmp_opacity * dzt(i,j,k)) + enddo !} nbands + bling%irr_inst(i,j,k) = tmp_Irrad * grid_tmask(i,j,k) + bling%irr_mix(i,j,k) = tmp_Irrad * grid_tmask(i,j,k) + if ((k == 1) .or. (tmp_hblt .lt. hblt_depth(i,j))) then + kblt = kblt+1 + tmp_irrad_ML = tmp_irrad_ML + bling%irr_mix(i,j,k) * dzt(i,j,k) + tmp_phyto_lg_ML = tmp_phyto_lg_ML + bling%p_phyto_lg(i,j,k) * dzt(i,j,k) + tmp_phyto_sm_ML = tmp_phyto_sm_ML + bling%p_phyto_sm(i,j,k) * dzt(i,j,k) + tmp_hblt = tmp_hblt + dzt(i,j,k) + endif + enddo !} k + bling%irr_mix(i,j,1:kblt) = tmp_irrad_ML / max(1.0e-6,tmp_hblt) + bling%p_phyto_lg(i,j,1:kblt) = tmp_phyto_lg_ML / max(1.0e-6,tmp_hblt) + bling%p_phyto_lg(i,j,1:kblt) = tmp_phyto_sm_ML / max(1.0e-6,tmp_hblt) + + enddo !} i + enddo !} j + + endif + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + !-------------------------------------------------------------------- + ! Phytoplankton photoadaptation. This represents the fact that phytoplankton cells are + ! adapted to the averaged light field to which they've been exposed over their lifetimes, + ! rather than the instantaneous light. The timescale is set by gamma_irr_mem. + + bling%p_irr_mem(i,j,k) = (bling%p_irr_mem(i,j,k) + & + (bling%irr_mix(i,j,k) - bling%p_irr_mem(i,j,k)) * min( 1.0 , & + bling%gamma_irr_mem * dtts)) * grid_tmask(i,j,k) + + !-------------------------------------------------------------------- + ! Temperature functionality of growth and grazing + ! NB The temperature effect of Eppley (1972) is used instead + ! of that in Geider et al (1997) for both simplicity and + ! to incorporate combined effects on uptake, incorporation + ! into organic matter and photorespiration. Values of PCmax + ! are normalized to 0C rather than 20C in Geider et al. (1997) + + bling%expkT(i,j,k) = exp(bling%kappa_eppley * Temp(i,j,k)) + + enddo !} i + enddo !} j + enddo !} k + + !----------------------------------------------------------------------- + ! Phytoplankton are assumed to grow according to the general properties + ! described in Geider (1997). This formulation gives a biomass-specific + ! growthrate as a function of light, nutrient limitation, and + ! temperature. We modify this relationship slightly here, as described + ! below, and also use the assumption of steady state growth vs. loss to + ! derive a simple relationship between growth rate, biomass and uptake. + ! + !----------------------------------------------------------------------- + ! First, we calculate the limitation terms for PO4 and Fe, and the + ! Fe-limited Chl:C maximum. + ! The light-saturated maximal photosynthesis rate term (pc_m) is simply + ! the product of a prescribed maximal photosynthesis rate (pc_0), the + ! Eppley temperature dependence, and a Liebig limitation (the minimum + ! of Michaelis-Menton PO4-limitation, or iron-limitation). The iron + ! limitation term is scaled by (k_fe_2_p + fe_2_p_max) / fe_2_p_max + ! so that it approaches 1 as fed approaches infinity. Thus, + ! it's of comparable magnitude to the PO4 limitation term. + ! + ! Fe limitation acts by reducing the maximum achievable Chl:C ratio + ! (theta) below a prescribed, Fe-replete maximum value (thetamax), to + ! approach a prescribed minimum Chl:C (thetamin) under extreme + ! Fe-limitation. + !----------------------------------------------------------------------- + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%fe_2_p_uptake(i,j,k) = bling%fe_2_p_max * & + bling%f_fed(i,j,k) / (bling%k_fe_uptake + bling%f_fed(i,j,k)) + bling%def_fe(i,j,k) = max(bling%def_fe_min, & + (bling%fe_2_p_uptake(i,j,k) / & + (bling%k_fe_2_p + bling%fe_2_p_uptake(i,j,k)) * & + (bling%k_fe_2_p + bling%fe_2_p_max) / bling%fe_2_p_max)) + bling%pc_m(i,j,k) = bling%pc_0 * bling%expkT(i,j,k) * min( & + max(0.,((bling%f_po4(i,j,k) - bling%po4_min) / & + (bling%k_po4 + bling%f_po4(i,j,k) - bling%po4_min))) , & + bling%def_fe(i,j,k)) + bling%thetamax_fe(i,j,k) = bling%thetamax_lo + & + (bling%thetamax_hi - bling%thetamax_lo) * bling%def_fe(i,j,k) + + !----------------------------------------------------------------------- + ! Next, the nutrient-limited efficiency of algal photosystems, Irrk, is + ! calculated. This requires a prescribed quantum yield, alpha. + ! The iron deficiency term is included here as a multiplier of the + ! thetamax_fe to represent the importance of Fe in forming chlorophyll + ! accessory antennae, which do not affect the Chl:C but still affect the + ! phytoplankton ability to use light (eg Stzrepek & Harrison Nature + ! 2004). + + bling%irrk(i,j,k) = (bling%pc_m(i,j,k) / ( epsln + & + bling%alpha_photo * bling%thetamax_fe(i,j,k) )) + & + bling%p_irr_mem(i,j,k) * 0.5 + + !----------------------------------------------------------------------- + ! We also calculate the Chl:C ratio here, although it does not enter + ! into the uptake calculation and is only used for the diagnostic + ! chlorophyll concentration, below. + + bling%theta(i,j,k) = bling%thetamax_fe(i,j,k) / (1. + & + bling%thetamax_fe(i,j,k) * bling%alpha_photo * & + bling%p_irr_mem(i,j,k) / (epsln + 2. * bling%pc_m(i,j,k))) + + !----------------------------------------------------------------------- + ! Now we can calculate the carbon-specific photosynthesis rate, mu. + + bling%mu(i,j,k) = bling%pc_m(i,j,k) * & + (1. - exp(-bling%irr_mix(i,j,k) / (epsln + bling%irrk(i,j,k)))) + + enddo !} i + enddo !} j + enddo !} k + + !----------------------------------------------------------------------- + ! We now must convert this net carbon-specific growth rate to nutrient + ! uptake rates, the quantities we are interested in. Since we have no + ! explicit biomass tracer, we use the result of Dunne et al. (GBC, 2005) + ! to calculate an implicit biomass from the uptake rate through the + ! application of a simple idealized grazing law. This has the effect of + ! reducing uptake in low growth-rate regimes and increasing uptake in + ! high growth-rate regimes - essentially a non-linear amplification of + ! the growth rate variability. The result is: + + if (bling%biomass_type .eq. 'single') then + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + bling%biomass_p_ts(i,j,k) = & + ((bling%mu(i,j,k)/(bling%lambda0 * bling%expkT(i,j,k)))**3 & + + (bling%mu(i,j,k)/(bling%lambda0 * bling%expkT(i,j,k)))) & + * bling%p_star + + bling%p_biomass_p(i,j,k) = bling%p_biomass_p(i,j,k) + & + (bling%biomass_p_ts(i,j,k) - bling%p_biomass_p(i,j,k)) * & + min(1.0, bling%gamma_biomass * dtts) * grid_tmask(i,j,k) + + bling%jp_uptake(i,j,k) = bling%p_biomass_p(i,j,k) * & + bling%mu(i,j,k) + + ! We can now use the diagnostic biomass to calculate the chlorophyll + ! concentration: + + bling%f_chl(i,j,k) = max(bling%chl_min, bling%p_biomass_p(i,j,k) & + * bling%c_2_p * 12.011e6 * bling%theta(i,j,k)) * & + grid_tmask(i,j,k) + + ! As a helpful diagnostic, the implied fraction of production by large + ! phytoplankton is calculated, also following Dunne et al. 2005. This + ! could be done more simply, but is done here in a complicated way as + ! a sanity check. Note the calculation is made in P units, rather than C. + + s_over_p = ( -1. + ( 1. + 4. * bling%jp_uptake(i,j,k) / & + (bling%expkT(i,j,k) * bling%lambda0 * bling%p_star))**0.5) * .5 + bling%frac_lg(i,j,k) = s_over_p / (1 + s_over_p) + + enddo !} i + enddo !} j + enddo !} k + + elseif (bling%biomass_type .eq. 'lg_sm_phyto') then + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%jp_uptake(i,j,k) = bling%mu(i,j,k) * & + (bling%p_phyto_lg(i,j,k) + bling%p_phyto_sm(i,j,k)) + enddo !} i + enddo !} j + enddo !} k + + endif + + !----------------------------------------------------------------------- + ! Iron is then taken up as a function of PO4 uptake and iron limitation, + ! with a maximum Fe:P uptake ratio of fe2p_max: + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%jfe_uptake(i,j,k) = bling%jp_uptake(i,j,k) * & + bling%fe_2_p_uptake(i,j,k) + enddo !} i + enddo !} j + enddo !} k + + + !------------------------------------------------------------------------- + ! PARTITIONING BETWEEN ORGANIC POOLS + !------------------------------------------------------------------------- + + ! The uptake of nutrients is assumed to contribute to the growth of + ! phytoplankton, which subsequently die and are consumed by heterotrophs. + ! This can involve the transfer of nutrient elements between many + ! organic pools, both particulate and dissolved, with complex histories. + ! We take a simple approach here, partitioning the total uptake into two + ! fractions - sinking and non-sinking - as a function of temperature, + ! following Dunne et al. (2005). + ! The non-sinking fraction is recycled instantaneously to the inorganic + ! nutrient pool, + ! representing the fast turnover of labile dissolved organic matter via + ! the microbial loop, and the remainder is converted to semi-labile + ! dissolved organic matter. Iron and phosphorus are treated identically + ! for the first step, but all iron is recycled instantaneously in the + ! second step (i.e. there is no dissolved organic iron pool). + !------------------------------------------------------------------------- + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + bling%frac_pop(i,j,k) = max((bling%phi_sm + bling%phi_lg * & + (bling%mu(i,j,k)/(bling%lambda0*bling%expkT(i,j,k)))**2.)/ & + (1. + (bling%mu(i,j,k)/(bling%lambda0*bling%expkT(i,j,k)))**2.)* & + exp(bling%kappa_remin * Temp(i,j,k)) * & + ! Experimental! Reduce frac_pop under strong PO4 limitation + bling%f_po4(i,j,k) / (bling%k_po4_recycle + bling%f_po4(i,j,k)), & + bling%min_frac_pop) + + bling%jpop(i,j,k) = bling%frac_pop(i,j,k) * bling%jp_uptake(i,j,k) + + ! Whatever isn't converted to sinking particulate is recycled to the dissolved pool. + + bling%jp_recycle(i,j,k) = bling%jp_uptake(i,j,k) - & + bling%jpop(i,j,k) + + enddo !] i + enddo !} j + enddo !} k + + if (bling%biomass_type .eq. 'lg_sm_phyto') then + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + ! Finally, update the biomass of total phytoplankton, and of diazotrophs. + ! Use this to solve the Dunne et al. 2005 mortality term, with alpha=1/3 (eq. 5b). + ! Then, add this to the pre-exisiting phytoplankton biomass and the total uptake to give + + bling%p_phyto_lg(i,j,k) = bling%p_phyto_lg(i,j,k) + & + bling%p_phyto_lg(i,j,k) * (bling%mu(i,j,k) - & + bling%lambda0 * bling%expkT(i,j,k) * & + (bling%p_phyto_lg(i,j,k) / bling%p_star)**(1./3.) ) * dtts * grid_tmask(i,j,k) + + bling%p_phyto_sm(i,j,k) = bling%p_phyto_sm(i,j,k) + & + bling%p_phyto_sm(i,j,k) * (bling%mu(i,j,k) - & + bling%lambda0 * bling%expkT(i,j,k) * & + (bling%p_phyto_sm(i,j,k) / bling%p_star) ) * dtts * grid_tmask(i,j,k) + + bling%frac_lg(i,j,k) = bling%p_phyto_lg(i,j,k) / & + (epsln + bling%p_phyto_lg(i,j,k)+bling%p_phyto_sm(i,j,k)) + + ! Calculate the chlorophyll concentration: + + bling%f_chl(i,j,k) = max(bling%chl_min, & + bling%c_2_p * 12.011e6 * bling%theta(i,j,k) * & + (bling%p_phyto_lg(i,j,k) + bling%p_phyto_sm(i,j,k))) * grid_tmask(i,j,k) + + enddo !] i + enddo !} j + enddo !} k + + endif + + ! + ! perform recycling, as above, for the prognostic Fed tracer + ! + if (bling%fe_is_prognostic) then + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + bling%jfeop(i,j,k) = bling%frac_pop(i,j,k)*bling%jfe_uptake(i,j,k) + + bling%jfe_recycle(i,j,k) = bling%jfe_uptake(i,j,k) - & + bling%jfeop(i,j,k) + + enddo !] i + enddo !} j + enddo !} k + endif + + + !------------------------------------------------------------------------- + ! SINKING AND REMINERALIZATION + !------------------------------------------------------------------------- + ! Calculate the depth of each grid cell (needs to be 3d for use with + ! isopycnal co-ordinate model). + + do j = jsc, jec + do i = isc, iec + bling%zbot(i,j,1) = dzt(i,j,1) + enddo !} i + enddo !} j + + do k = 2, nk + do j = jsc, jec + do i = isc, iec + bling%zbot(i,j,k) = bling%zbot(i,j,k-1) + dzt(i,j,k) + enddo !} i + enddo !} j + enddo !} k + + !----------------------------------------------------------------------- + ! Calculate the remineralization lengthscale matrix, zremin, a function + ! of z. Sinking rate (wsink) is constant over the upper wsink0_z metres, + ! then increases linearly with depth. + ! The remineralization rate is a function of oxygen concentrations, + ! to slow remineralization under suboxia/anoxia. The remineralization rate + ! approaches the remin_min as O2 approaches O2 min. + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + if (bling%zbot(i,j,k) .lt. bling%wsink0_z) then + bling%wsink(i,j,k) = bling%wsink0 + else + bling%wsink(i,j,k) = (bling%wsink_acc * (bling%zbot(i,j,k) - & + bling%wsink0_z) + bling%wsink0) + endif + + bling%zremin(i,j,k) = bling%gamma_pop * (bling%f_o2(i,j,k) / & + (bling%k_o2 + bling%f_o2(i,j,k)) * (1. - bling%remin_min)+ & + bling%remin_min) / (bling%wsink(i,j,k) + epsln) + + enddo !} i + enddo !} j + enddo !} k + + if (bling%do_carbon) then !<> + endif !CARBON CYCLE>> + + if (bling%fe_is_prognostic) then + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + !--------------------------------------------------------------------- + ! Calculate free and inorganically associated iron concentration for + ! scavenging. + ! We assume that there is a + ! spectrum of iron ligands present in seawater, with varying binding + ! strengths and whose composition varies with light and iron + ! concentrations. For example, photodissocation of ligand complexes + ! occurs under bright light, weakening the binding strength + ! (e.g. Barbeau et al., Nature 2001), while at very low iron + ! concentrations (order kfe_eq_lig_femin), siderophores are thought + ! to be produced as a response to extreme iron stress. + ! In anoxic waters, iron should be reduced, and therefore mostly + ! immune to scavenging. Easiest way to do this is to skip the feprime + ! calculation if oxygen is less than 0. + + if (bling%f_o2(i,j,k) .gt. bling%o2_min) then + bling%kfe_eq_lig(i,j,k) = bling%kfe_eq_lig_max - & + (bling%kfe_eq_lig_max - bling%kfe_eq_lig_min) * & + (bling%irr_inst(i,j,k)**2. / (bling%irr_inst(i,j,k)**2. + & + bling%kfe_eq_lig_irr **2.)) * max(0., min(1., (bling%f_fed(i,j,k) - & + bling%kfe_eq_lig_femin) / (epsln + bling%f_fed(i,j,k)) * 1.2)) + + bling%feprime(i,j,k) = 1.0 + bling%kfe_eq_lig(i,j,k) * & + (bling%felig_bkg - bling%f_fed(i,j,k)) + + bling%feprime(i,j,k) = (-bling%feprime(i,j,k) +(bling%feprime(i,j,k)* & + bling%feprime(i,j,k) + 4.0 * bling%kfe_eq_lig(i,j,k) * & + bling%f_fed(i,j,k))**(0.5)) /(2.0 * bling%kfe_eq_lig(i,j,k)) + else !}{ + bling%feprime(i,j,k) = 0. + endif !} + + bling%jfe_ads_inorg(i,j,k) = min(0.5/dtts, bling%kfe_inorg * & + bling%feprime(i,j,k) ** 0.5) * bling%feprime(i,j,k) + + enddo !} i + enddo !} j + enddo !} k + endif + + !--------------------------------------------------------------------- + ! In general, the flux at the bottom of a grid cell should equal + ! Fb = (Ft + Prod*dz) / (1 + zremin*dz) + ! where Ft is the flux at the top, and prod*dz is the integrated + ! production of new sinking particles within the layer. + ! Since Ft=0 in the first layer, + + do j = jsc, jec + do i = isc, iec + + bling%fpop(i,j,1) = bling%jpop(i,j,1) * rho_dzt(i,j,1) / & + (1.0 + dzt(i,j,1) * bling%zremin(i,j,1)) + + !----------------------------------------------------------------------- + ! Calculate remineralization terms + + bling%jp_reminp(i,j,1) = & + (bling%jpop(i,j,1) * rho_dzt(i,j,1) - bling%fpop(i,j,1)) / & + (epsln + rho_dzt(i,j,1)) + + enddo !} i + enddo !} j + + + !----------------------------------------------------------------------- + ! Then, for the rest of water column, include flux from above: + + do k = 2, nk + do j = jsc, jec + do i = isc, iec + + bling%fpop(i,j,k) = (bling%fpop(i,j,k-1) + & + bling%jpop(i,j,k) * rho_dzt(i,j,k)) / & + (1.0 + dzt(i,j,k) * bling%zremin(i,j,k)) + + !--------------------------------------------------------------------- + ! Calculate remineralization terms + + bling%jp_reminp(i,j,k) = (bling%fpop(i,j,k-1) + & + bling%jpop(i,j,k) * rho_dzt(i,j,k) - bling%fpop(i,j,k)) / & + (epsln + rho_dzt(i,j,k)) + + enddo !} i + enddo !} j + enddo !} k + + + !--------------------------------------------------------------------- + ! BOTTOM LAYER + ! Account for remineralization in bottom box, and bottom fluxes + + do j = jsc, jec + do i = isc, iec + k = grid_kmt(i,j) + if (k .gt. 0) then + + !--------------------------------------------------------------------- + ! Calculate external bottom fluxes for tracer_vertdiff. Positive fluxes + ! are from the water column into the seafloor. For P, the bottom flux + ! puts the sinking flux reaching the bottom cell into the water column + ! through diffusion. + ! For oxygen, the consumption of oxidant required to respire + ! the settling flux of organic matter (in support of the + ! PO4 bottom flux) diffuses from the bottom water into the sediment. + + bling%b_po4(i,j) = - bling%fpop(i,j,k) + + if (bling%f_o2(i,j,k) .gt. bling%o2_min) then + bling%b_o2(i,j) = bling%o2_2_p * bling%fpop(i,j,k) + else + bling%b_o2(i,j) = 0.0 + endif + + endif + enddo !} i + enddo !} j + + if (bling%fe_is_prognostic) then + + do j = jsc, jec + do i = isc, iec + + !----------------------------------------------------------------------- + ! Now, calculate the Fe adsorption using this fpop: + ! The absolute first order rate constant is calculated from the + ! concentration of organic particles, after Parekh et al. (2005). Never + ! allowed to be greater than 1/2dt for numerical stability. + + bling%jfe_ads_org(i,j,1) = min (0.5/dtts, & + bling%kfe_org * (bling%fpop(i,j,1) / (epsln + bling%wsink(i,j,1)) * & + bling%mass_2_p) ** 0.58) * bling%feprime(i,j,1) + + bling%fpofe(i,j,1) = (bling%jfeop(i,j,1) +bling%jfe_ads_inorg(i,j,1) & + + bling%jfe_ads_org(i,j,1)) * rho_dzt(i,j,1) / & + (1.0 + dzt(i,j,1) * bling%zremin(i,j,1)) + + !----------------------------------------------------------------------- + ! Calculate remineralization terms + + bling%jfe_reminp(i,j,1) = & + ((bling%jfeop(i,j,1) + bling%jfe_ads_org(i,j,1) + & + bling%jfe_ads_inorg(i,j,1)) * rho_dzt(i,j,1) - & + bling%fpofe(i,j,1)) / (epsln + rho_dzt(i,j,1)) + + enddo !} i + enddo !} j + + + !----------------------------------------------------------------------- + ! Then, for the rest of water column, include flux from above: + + do k = 2, nk + do j = jsc, jec + do i = isc, iec + + !----------------------------------------------------------------------- + ! Again, calculate the Fe adsorption using this fpop: + + bling%jfe_ads_org(i,j,k) = min (0.5/dtts, bling%kfe_org * & + (bling%fpop(i,j,k) / (epsln + bling%wsink(i,j,k)) * & + bling%mass_2_p) ** 0.58) * bling%feprime(i,j,k) + + bling%fpofe(i,j,k) = (bling%fpofe(i,j,k-1) + & + (bling%jfe_ads_org(i,j,k) + bling%jfe_ads_inorg(i,j,k) + & + bling%jfeop(i,j,k)) *rho_dzt(i,j,k)) / & + (1.0 + dzt(i,j,k) * bling%zremin(i,j,k)) + + !--------------------------------------------------------------------- + ! Calculate remineralization terms + + bling%jfe_reminp(i,j,k) = (bling%fpofe(i,j,k-1) + & + (bling%jfe_ads_org(i,j,k) + bling%jfe_ads_inorg(i,j,k) + & + bling%jfeop(i,j,k)) * rho_dzt(i,j,k) - & + bling%fpofe(i,j,k)) / (epsln + rho_dzt(i,j,k)) + + enddo !} i + enddo !} j + enddo !} k + + + !--------------------------------------------------------------------- + ! BOTTOM LAYER + ! Account for remineralization in bottom box, and bottom fluxes + + do j = jsc, jec + do i = isc, iec + k = grid_kmt(i,j) + if (k .gt. 0) then + + !--------------------------------------------------------------------- + ! Calculate iron addition from sediments as a function of organic + ! matter supply. + + bling%ffe_sed(i,j) = bling%fe_2_p_sed * bling%fpop(i,j,k) + + ! Added the burial flux of sinking particulate iron here as a + ! diagnostic, needed to calculate mass balance of iron. + + bling%fe_burial(i,j) = bling%fpofe(i,j,k) + + !--------------------------------------------------------------------- + ! Calculate external bottom fluxes for tracer_vertdiff. Positive fluxes + ! are from the water column into the seafloor. For iron, the sinking flux disappears into the + ! sediments if bottom waters are oxic (assumed adsorbed as oxides), + ! while an efflux of dissolved iron occurs dependent on the supply of + ! reducing organic matter (scaled by the org-P sedimentation rate). + ! If bottom waters are anoxic, the sinking flux of Fe is returned to + ! the water column. Note this is not appropriate for very long runs + ! with an anoxic ocean (iron will keep accumulating forever). + + if (bling%f_o2(i,j,k) .gt. bling%o2_min) then + bling%b_fed(i,j) = - bling%ffe_sed(i,j) + else + bling%b_fed(i,j) = - bling%ffe_sed(i,j) - bling%fpofe(i,j,k) + endif + + endif + enddo !} i + enddo !} j + endif + + if (bling%fe_is_prognostic) then + call g_tracer_set_values(tracer_list,'fed' // bling%suffix, 'btf', bling%b_fed ,isd,jsd) + endif + call g_tracer_set_values(tracer_list,'po4' // bling%suffix, 'btf', bling%b_po4 ,isd,jsd) + call g_tracer_set_values(tracer_list,'o2' // bling%suffix, 'btf', bling%b_o2 ,isd,jsd) + + if (bling%do_carbon) then !<> + + endif !} !CARBON CYCLE>> + + + !------------------------------------------------------------------------- + ! CALCULATE SOURCE/SINK TERMS FOR EACH TRACER + !------------------------------------------------------------------------- + + !Update the prognostics tracer fields via their pointers. + + if (bling%fe_is_prognostic) then + call g_tracer_get_pointer(tracer_list, 'fed' // bling%suffix, 'field', bling%p_fed) + elseif (bling%fe_is_diagnostic) then + call g_tracer_get_pointer(tracer_list, 'fed' // bling%suffix, 'field', bling%p_fed_diag) + endif + call g_tracer_get_pointer(tracer_list,'o2' // bling%suffix ,'field',bling%p_o2 ) + call g_tracer_get_pointer(tracer_list,'po4' // bling%suffix ,'field',bling%p_po4 ) + + if (bling%do_carbon) then + call g_tracer_get_pointer(tracer_list,'dic' // bling%suffix,'field',bling%p_dic) + if (bling%do_14c) then + call g_tracer_get_pointer(tracer_list,'di14c' // bling%suffix,'field',bling%p_di14c) + endif !} + endif !} + + do k = 1, nk + do j = jsc, jec + do i = isc, iec + + ! + ! PO4 + ! Sum of fast recycling and decay of sinking POP, less uptake. + ! + bling%jpo4(i,j,k) = bling%jp_recycle(i,j,k) + & + bling%jp_reminp(i,j,k) - bling%jp_uptake(i,j,k) + + bling%p_po4(i,j,k,tau) = bling%p_po4(i,j,k,tau) + & + bling%jpo4(i,j,k) * dtts * grid_tmask(i,j,k) + + !----------------------------------------------------------------------- + ! O2 + ! Assuming constant P:O ratio. + ! Optional prevention of negative oxygen (does not conserve ocean + ! redox potential) or alternatively it can be allowed to go negative, + ! keeping track of an implicit nitrate deficit + ! plus sulfate reduction. + !----------------------------------------------------------------------- + + if ( (bling%prevent_neg_o2) .and. & + (bling%f_o2(i,j,k) .lt. bling%o2_min) ) then + bling%jo2(i,j,k) = 0. * grid_tmask(i,j,k) + else + bling%jo2(i,j,k) = - bling%o2_2_p * bling%jpo4(i,j,k) & + * grid_tmask(i,j,k) + endif !} + + bling%p_o2(i,j,k,tau) = bling%p_o2(i,j,k,tau) + bling%jo2(i,j,k) * & + dtts * grid_tmask(i,j,k) + enddo !} i + enddo !} j + enddo !} k + + ! + ! Fed + ! + + if (bling%fe_is_prognostic) then + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%p_fed(i,j,k,tau) = bling%p_fed(i,j,k,tau) + & + (bling%jfe_recycle(i,j,k) + bling%jfe_reminp(i,j,k) - & + bling%jfe_uptake(i,j,k) - bling%jfe_ads_org(i,j,k) - & + bling%jfe_ads_inorg(i,j,k) ) * dtts * grid_tmask(i,j,k) + enddo !} i + enddo !} j + enddo !} k + elseif (bling%fe_is_diagnostic) then + do k = 1, nk + do j = jsc, jec + do i = isc, iec + bling%p_fed_diag(i,j,k) = bling%p_fed_diag(i,j,k) - & + bling%jfe_uptake(i,j,k) * dtts * grid_tmask(i,j,k) + bling%jfe_reminp(i,j,k) = (bling%f_fed_data(i,j,k) - bling%p_fed_diag(i,j,k)) * & + (1.0 / (bling%fe_restoring * 86400.0)) * grid_tmask(i,j,k) + bling%p_fed_diag(i,j,k) = bling%p_fed_diag(i,j,k) + & + bling%jfe_reminp(i,j,k) * dtts + enddo !} i + enddo !} j + enddo !} k + endif + + if (bling%do_carbon) then !<> + + enddo !} i + enddo !} j + enddo !} k + endif !CARBON CYCLE>> + + ! + !Set the diagnostics tracer fields. + ! + call g_tracer_set_values(tracer_list,'chl' // bling%suffix,'field',bling%f_chl,isd,jsd, & + ntau=1) + + !----------------------------------------------------------------------- + ! Save variables for diagnostics + !----------------------------------------------------------------------- + ! + + if (.not. bling%fe_is_prognostic) then + if (bling%id_fed_data_surf .gt. 0) & + used = send_data(bling%id_fed_data_surf, bling%f_fed_data(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + endif + if (bling%id_htotal_surf .gt. 0) & + used = send_data(bling%id_htotal_surf, bling%p_htotal(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_chl_surf .gt. 0) & + used = send_data(bling%id_chl_surf, bling%f_chl(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%biomass_type .eq. 'single') then + if (bling%id_biomass_p_surf .gt. 0) & + used = send_data(bling%id_biomass_p_surf, bling%p_biomass_p(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + elseif (bling%biomass_type .eq. 'lg_sm_phyto') then + if (bling%id_phyto_lg_surf .gt. 0) & + used = send_data(bling%id_phyto_lg_surf, bling%p_phyto_lg(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_phyto_sm_surf .gt. 0) & + used = send_data(bling%id_phyto_sm_surf, bling%p_phyto_sm(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + endif + if (bling%id_irr_mem_surf .gt. 0) & + used = send_data(bling%id_irr_mem_surf, bling%p_irr_mem(:,:,1), & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_pco2_surf .gt. 0) & + used = send_data(bling%id_pco2_surf, bling%pco2_surf, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_temp_co2calc .gt. 0) & + used = send_data(bling%id_temp_co2calc, bling%surf_temp, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_salt_co2calc .gt. 0) & + used = send_data(bling%id_salt_co2calc, bling%surf_salt, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_po4_co2calc .gt. 0) & + used = send_data(bling%id_po4_co2calc, bling%surf_po4, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_alk_co2calc .gt. 0) & + used = send_data(bling%id_alk_co2calc, bling%surf_alk, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_sio4_co2calc .gt. 0) & + used = send_data(bling%id_sio4_co2calc, bling%surf_sio4, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_dic_co2calc .gt. 0) & + used = send_data(bling%id_dic_co2calc, bling%surf_dic, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%fe_is_prognostic) then + if (bling%id_b_fed .gt. 0) & + used = send_data(bling%id_b_fed, bling%b_fed, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + endif + if (bling%id_b_o2 .gt. 0) & + used = send_data(bling%id_b_o2, bling%b_o2, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_b_po4 .gt. 0) & + used = send_data(bling%id_b_po4, bling%b_po4, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%biomass_type .eq. 'single') then + if (bling%id_biomass_p_ts .gt. 0) & + used = send_data(bling%id_biomass_p_ts, bling%biomass_p_ts, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + endif + if (bling%id_def_fe .gt. 0) & + used = send_data(bling%id_def_fe, bling%def_fe, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_expkT .gt. 0) & + used = send_data(bling%id_expkT, bling%expkT, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_fe_2_p_uptake .gt. 0) & + used = send_data(bling%id_fe_2_p_uptake, bling%fe_2_p_uptake, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%fe_is_prognostic) then + if (bling%id_feprime .gt. 0) & + used = send_data(bling%id_feprime, bling%feprime, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_fe_burial .gt. 0) & + used = send_data(bling%id_fe_burial, bling%fe_burial, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_ffe_sed .gt. 0) & + used = send_data(bling%id_ffe_sed, bling%ffe_sed, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_fpofe .gt. 0) & + used = send_data(bling%id_fpofe, bling%fpofe, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + endif + if (bling%id_fpop .gt. 0) & + used = send_data(bling%id_fpop, bling%fpop, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_frac_lg .gt. 0) & + used = send_data(bling%id_frac_lg, bling%frac_lg, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_frac_pop .gt. 0) & + used = send_data(bling%id_frac_pop, bling%frac_pop, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_irr_inst .gt. 0) & + used = send_data(bling%id_irr_inst, bling%irr_inst, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_irr_mix .gt. 0) & + used = send_data(bling%id_irr_mix, bling%irr_mix, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_irrk .gt. 0) & + used = send_data(bling%id_irrk, bling%irrk, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%fe_is_prognostic) then + if (bling%id_jfe_ads_inorg .gt. 0) & + used = send_data(bling%id_jfe_ads_inorg, bling%jfe_ads_inorg*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jfe_ads_org .gt. 0) & + used = send_data(bling%id_jfe_ads_org, bling%jfe_ads_org*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jfe_recycle .gt. 0) & + used = send_data(bling%id_jfe_recycle, bling%jfe_recycle*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + endif + if (bling%fe_is_prognostic .or. bling%fe_is_diagnostic) then + if (bling%id_jfe_reminp .gt. 0) & + used = send_data(bling%id_jfe_reminp, bling%jfe_reminp*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + endif + if (bling%id_jfe_uptake .gt. 0) & + used = send_data(bling%id_jfe_uptake, bling%jfe_uptake*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jo2 .gt. 0) & + used = send_data(bling%id_jo2, bling%jo2*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jp_recycle .gt. 0) & + used = send_data(bling%id_jp_recycle, bling%jp_recycle*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jp_reminp .gt. 0) & + used = send_data(bling%id_jp_reminp, bling%jp_reminp*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jp_uptake .gt. 0) & + used = send_data(bling%id_jp_uptake, bling%jp_uptake*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jpo4 .gt. 0) & + used = send_data(bling%id_jpo4, bling%jpo4*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_jpop .gt. 0) & + used = send_data(bling%id_jpop, bling%jpop*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%fe_is_prognostic) then + if (bling%id_jfeop .gt. 0) & + used = send_data(bling%id_jfeop, bling%jfeop*rho_dzt, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_kfe_eq_lig .gt. 0) & + used = send_data(bling%id_kfe_eq_lig, bling%kfe_eq_lig, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + endif + if (bling%id_pc_m .gt. 0) & + used = send_data(bling%id_pc_m, bling%pc_m, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_mu .gt. 0) & + used = send_data(bling%id_mu, bling%mu, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_o2_saturation .gt. 0) & + used = send_data(bling%id_o2_saturation, bling%o2_saturation, & + model_time, rmask = grid_tmask(:,:,1), & + is_in=isc, js_in=jsc,ie_in=iec, je_in=jec) + if (bling%id_theta .gt. 0) & + used = send_data(bling%id_theta, bling%theta, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_thetamax_fe .gt. 0) & + used = send_data(bling%id_thetamax_fe, bling%thetamax_fe, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_wsink .gt. 0) & + used = send_data(bling%id_wsink, bling%wsink, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (bling%id_zremin .gt. 0) & + used = send_data(bling%id_zremin, bling%zremin, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + if (.not. bling%fe_is_prognostic) then + if (bling%id_fed_data .gt. 0) & + used = send_data(bling%id_fed_data, bling%f_fed_data, & + model_time, rmask = grid_tmask, & + is_in=isc, js_in=jsc, ks_in=1,ie_in=iec, je_in=jec, ke_in=nk) + endif + + enddo !} n + + deallocate(tmp_irr_band) + + return + + end subroutine generic_miniBLING_update_from_source + + + + +!####################################################################### + ! + ! + ! Calculate and set coupler values at the surface / bottom of the ocean. + ! + ! + ! + ! Pointer to the head of generic tracer list. + ! + ! + ! Lower bounds of x and y extents of input arrays on data domain + ! + ! + ! Sea Surface Temperature + ! + ! + ! Sea Surface Salinity + ! + ! + ! Ocean density + ! + ! + ! Time step index of %field + ! + ! + + !User must provide the calculations for these boundary values. + + subroutine generic_miniBLING_set_boundary_values(tracer_list, SST, SSS, rho, ilb, jlb, tau) + + type(g_tracer_type), pointer, intent(inout) :: tracer_list + real, dimension(ilb:,jlb:), intent(in) :: SST + real, dimension(ilb:,jlb:), intent(in) :: SSS + real, dimension(ilb:,jlb:,:,:), intent(in) :: rho + integer, intent(in) :: ilb + integer, intent(in) :: jlb + integer, intent(in) :: tau + + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + integer :: i + integer :: j + integer :: n + real :: sal + real :: ST + real :: sc_co2 + real :: sc_o2 + !real :: sc_no_term + real :: o2_saturation + real :: tt + real :: tk + real :: ts + real :: ts2 + real :: ts3 + real :: ts4 + real :: ts5 + real, dimension(:,:,:), pointer :: grid_tmask + real, dimension(:,:,:,:), pointer :: o2_field + real, dimension(:,:), pointer :: co2_alpha + real, dimension(:,:), pointer :: co2_csurf + real, dimension(:,:), pointer :: co2_schmidt + real, dimension(:,:), pointer :: o2_alpha + real, dimension(:,:), pointer :: o2_csurf + real, dimension(:,:), pointer :: o2_schmidt + real, dimension(:,:), pointer :: co2_sat_rate + real, dimension(:,:), pointer :: c14o2_alpha + real, dimension(:,:), pointer :: c14o2_csurf + real, dimension(:,:), pointer :: c14o2_schmidt + real :: surface_rho + + character(len=fm_string_len), parameter :: sub_name = 'generic_miniBLING_set_boundary_values' + + ! SURFACE GAS FLUXES + ! + ! This subroutine coordinates the calculation of gas concentrations and solubilities + ! in the surface layer. The concentration of a gas is written as csurf, while the + ! solubility (in mol kg-1 atm-1 or mol m-3 atm-1) is written as alpha. These two + ! quantities are passed to the coupler, which multiplies their difference by the + ! gas exchange piston velocity over the mixed layer depth to provide the gas + ! exchange flux, + ! Flux = Kw/dz * (alpha - csurf) + ! In order to simplify code flow, the Schmidt number parameters, which are part of + ! the piston velocity, are calculated here and applied to each of csurf and alpha + ! before being sent to the coupler. + ! + ! 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, ALK, PO4 and SiO4. + ! + ! Oxygen solubility is calculated here, using in situ temperature and salinity. + + !Get the necessary properties + call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, grid_tmask = grid_tmask) + + do n = 1, num_instances + + call g_tracer_get_pointer(tracer_list, 'o2' // bling%suffix ,'field', o2_field) + call g_tracer_get_pointer(tracer_list, 'o2' // bling%suffix, 'alpha', o2_alpha) + call g_tracer_get_pointer(tracer_list, 'o2' // bling%suffix, 'csurf', o2_csurf) + call g_tracer_get_pointer(tracer_list, 'o2' // bling%suffix, 'sc_no', o2_schmidt) + + do j = jsc, jec + do i = isc, iec + + sal = SSS(i,j) + ST = SST(i,j) + + surface_rho = bling%Rho_0 + + !--------------------------------------------------------------------- + ! O2 + !--------------------------------------------------------------------- + ! Compute the oxygen saturation concentration at 1 atm total pressure in mol/kg + ! given the temperature (T, in deg C) and the salinity (S, in permil). + ! + ! From Garcia and Gordon (1992), Limnology and Oceonography (page 1310, eq (8)). + ! *** Note: the "a3*ts^2" term was erroneous, and not included here. *** + ! Defined between T(freezing) <= T <= 40 deg C and 0 <= S <= 42 permil. + ! + ! check value: T = 10 deg C, S = 35 permil, o2_saturation = 0.282015 mol m-3 + !--------------------------------------------------------------------- + + tt = 298.15 - ST + tk = 273.15 + ST + ts = log(tt / tk) + ts2 = ts * ts + ts3 = ts2 * ts + ts4 = ts3 * ts + ts5 = ts4 * ts + + o2_saturation = (1000.0/22391.6) * grid_tmask(i,j,1) * & !convert from ml/l to mol m-3 + exp(bling%a_0 + bling%a_1*ts + bling%a_2*ts2 + bling%a_3*ts3 + & + bling%a_4*ts4 + bling%a_5*ts5 + (bling%b_0 + bling%b_1*ts + & + bling%b_2*ts2 + bling%b_3*ts3 + bling%c_0 * sal) * sal) + + !--------------------------------------------------------------------- + ! Compute the Schmidt number of O2 in seawater using the formulation proposed + ! by Keeling et al. (1998, Global Biogeochem. Cycles, 12, 141-163). + !--------------------------------------------------------------------- + + sc_o2 = bling%a1_o2 + ST * (bling%a2_o2 + ST * (bling%a3_o2 + & + ST * bling%a4_o2 )) * grid_tmask(i,j,1) + + o2_alpha(i,j) = o2_saturation + bling%o2_saturation(i,j) = o2_saturation / surface_rho + o2_csurf(i,j) = o2_field(i,j,1,tau) * surface_rho + o2_schmidt(i,j) = sc_o2 + + enddo !} i + enddo !} j + + if (bling%do_carbon) then !<> + + enddo + + return + + end subroutine generic_miniBLING_set_boundary_values + + + + +!####################################################################### + ! + ! + ! End the module. Deallocate all work arrays. + ! + ! + + subroutine generic_miniBLING_end + + character(len=fm_string_len), parameter :: sub_name = 'generic_miniBLING_end' + 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) // '): ' + + integer :: stdout_unit + + stdout_unit = stdout() + + call user_deallocate_arrays + + return + end subroutine generic_miniBLING_end + + +!####################################################################### + ! + ! This is an internal sub, not a public interface. + ! Allocate all the work arrays to be used in this module. + ! + + subroutine user_allocate_arrays + + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + integer :: n + + call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau) + + !Used in ocmip2_co2calc + CO2_dope_vec%isc = isc + CO2_dope_vec%iec = iec + CO2_dope_vec%jsc = jsc + CO2_dope_vec%jec = jec + CO2_dope_vec%isd = isd + CO2_dope_vec%ied = ied + CO2_dope_vec%jsd = jsd + CO2_dope_vec%jed = jed + + do n = 1, num_instances + + allocate(bling%wrk_3d (isd:ied, jsd:jed, 1:nk)); bling%wrk_3d=0.0 + allocate(bling%wrk_2d (isd:ied, jsd:jed) ); bling%wrk_2d=0.0 + allocate(bling%flux (isd:ied, jsd:jed) ); bling%flux=0.0 + allocate(bling%integral (isd:ied, jsd:jed) ); bling%integral=0.0 + allocate(bling%k_lev (isd:ied, jsd:jed) ); bling%k_lev=0.0 + + if (bling%biomass_type .eq. 'single') then + allocate(bling%biomass_p_ts (isd:ied, jsd:jed, 1:nk)); bling%biomass_p_ts=0.0 + endif + allocate(bling%def_fe (isd:ied, jsd:jed, 1:nk)); bling%def_fe=0.0 + allocate(bling%expkT (isd:ied, jsd:jed, 1:nk)); bling%expkT=0.0 + allocate(bling%f_chl (isd:ied, jsd:jed, 1:nk)); bling%f_chl=0.0 + allocate(bling%f_fed (isd:ied, jsd:jed, 1:nk)); bling%f_fed=0.0 + if (.not. bling%fe_is_prognostic) then + allocate(bling%f_fed_data (isc:iec, jsc:jec, 1:nk)); bling%f_fed_data=0.0 + endif + allocate(bling%f_o2 (isd:ied, jsd:jed, 1:nk)); bling%f_o2=0.0 + allocate(bling%f_po4 (isd:ied, jsd:jed, 1:nk)); bling%f_po4=0.0 + allocate(bling%fe_2_p_uptake (isd:ied, jsd:jed, 1:nk)); bling%fe_2_p_uptake=0.0 + if (bling%fe_is_prognostic) then + allocate(bling%feprime (isd:ied, jsd:jed, 1:nk)); bling%feprime=0.0 + allocate(bling%fpofe (isd:ied, jsd:jed, 1:nk)); bling%fpofe=0.0 + endif + allocate(bling%fpop (isd:ied, jsd:jed, 1:nk)); bling%fpop=0.0 + allocate(bling%frac_lg (isd:ied, jsd:jed, 1:nk)); bling%frac_lg=0.0 + allocate(bling%frac_pop (isd:ied, jsd:jed, 1:nk)); bling%frac_pop=0.0 + allocate(bling%irr_inst (isd:ied, jsd:jed, 1:nk)); bling%irr_inst=0.0 + allocate(bling%irr_mix (isd:ied, jsd:jed, 1:nk)); bling%irr_mix=0.0 + allocate(bling%irrk (isd:ied, jsd:jed, 1:nk)); bling%irrk=0.0 + if (bling%fe_is_prognostic) then + allocate(bling%jfe_ads_inorg (isd:ied, jsd:jed, 1:nk)); bling%jfe_ads_inorg=0.0 + allocate(bling%jfe_ads_org (isd:ied, jsd:jed, 1:nk)); bling%jfe_ads_org=0.0 + allocate(bling%jfe_recycle (isd:ied, jsd:jed, 1:nk)); bling%jfe_recycle=0.0 + endif + if (bling%fe_is_prognostic .or. bling%fe_is_diagnostic) then + allocate(bling%jfe_reminp (isd:ied, jsd:jed, 1:nk)); bling%jfe_reminp=0.0 + endif + allocate(bling%jfe_uptake (isd:ied, jsd:jed, 1:nk)); bling%jfe_uptake=0.0 + allocate(bling%jo2 (isd:ied, jsd:jed, 1:nk)); bling%jo2=0.0 + allocate(bling%jp_recycle (isd:ied, jsd:jed, 1:nk)); bling%jp_recycle=0.0 + allocate(bling%jp_reminp (isd:ied, jsd:jed, 1:nk)); bling%jp_reminp=0.0 + allocate(bling%jp_uptake (isd:ied, jsd:jed, 1:nk)); bling%jp_uptake=0.0 + allocate(bling%jpo4 (isd:ied, jsd:jed, 1:nk)); bling%jpo4=0.0 + allocate(bling%jpop (isd:ied, jsd:jed, 1:nk)); bling%jpop=0.0 + if (bling%fe_is_prognostic) then + allocate(bling%jfeop (isd:ied, jsd:jed, 1:nk)); bling%jfeop=0.0 + allocate(bling%kfe_eq_lig (isd:ied, jsd:jed, 1:nk)); bling%kfe_eq_lig=0.0 + endif + allocate(bling%mu (isd:ied, jsd:jed, 1:nk)); bling%mu=0.0 + allocate(bling%pc_m (isd:ied, jsd:jed, 1:nk)); bling%pc_m=0.0 + allocate(bling%theta (isd:ied, jsd:jed, 1:nk)); bling%theta=0.0 + allocate(bling%thetamax_fe (isd:ied, jsd:jed, 1:nk)); bling%thetamax_fe=0.0 + allocate(bling%wsink (isd:ied, jsd:jed, 1:nk)); bling%wsink=0.0 + allocate(bling%zremin (isd:ied, jsd:jed, 1:nk)); bling%zremin=0.0 + allocate(bling%zbot (isd:ied, jsd:jed, 1:nk)); bling%zbot=0.0 + allocate(bling%b_o2 (isd:ied, jsd:jed)); bling%b_o2=0.0 + allocate(bling%b_po4 (isd:ied, jsd:jed)); bling%b_po4=0.0 + if (bling%fe_is_prognostic) then + allocate(bling%b_fed (isd:ied, jsd:jed)); bling%b_fed=0.0 + allocate(bling%fe_burial (isd:ied, jsd:jed)); bling%fe_burial=0.0 + allocate(bling%ffe_sed (isd:ied, jsd:jed)); bling%ffe_sed=0.0 + endif + allocate(bling%o2_saturation (isd:ied, jsd:jed)); bling%o2_saturation=0.0 + + if (bling%do_carbon) then !<> + endif !CARBON CYCLE>> + + enddo + + return + + end subroutine user_allocate_arrays + + + +!####################################################################### + ! + ! This is an internal sub, not a public interface. + ! Deallocate all the work arrays allocated by user_allocate_arrays. + ! + subroutine user_deallocate_arrays + + integer :: n + + do n = 1, num_instances + + deallocate(bling%wrk_3d) + deallocate(bling%wrk_2d) + deallocate(bling%flux) + deallocate(bling%integral) + deallocate(bling%k_lev) + + deallocate(bling%o2_saturation) + if (bling%biomass_type .eq. 'single') then + deallocate(bling%biomass_p_ts) + endif + deallocate(bling%def_fe) + deallocate(bling%expkT) + deallocate(bling%f_chl) + deallocate(bling%f_fed) + if (.not. bling%fe_is_prognostic) then + deallocate(bling%f_fed_data) + endif + deallocate(bling%f_o2) + deallocate(bling%f_po4) + deallocate(bling%fe_2_p_uptake) + if (bling%fe_is_prognostic) then + deallocate(bling%feprime) + deallocate(bling%fpofe) + endif + deallocate(bling%fpop) + deallocate(bling%frac_lg) + deallocate(bling%frac_pop) + deallocate(bling%irr_inst) + deallocate(bling%irr_mix) + deallocate(bling%irrk) + if (bling%fe_is_prognostic) then + deallocate(bling%jfe_ads_inorg) + deallocate(bling%jfe_ads_org) + deallocate(bling%jfe_recycle) + endif + if (bling%fe_is_prognostic .or. bling%fe_is_diagnostic) then + deallocate(bling%jfe_reminp) + endif + deallocate(bling%jfe_uptake) + deallocate(bling%jo2) + deallocate(bling%jp_recycle) + deallocate(bling%jp_reminp) + deallocate(bling%jp_uptake) + deallocate(bling%jpo4) + deallocate(bling%jpop) + if (bling%fe_is_prognostic) then + deallocate(bling%jfeop) + deallocate(bling%kfe_eq_lig) + endif + deallocate(bling%pc_m) + deallocate(bling%mu) + deallocate(bling%theta) + deallocate(bling%thetamax_fe) + deallocate(bling%wsink) + deallocate(bling%zremin) + deallocate(bling%zbot) + if (bling%fe_is_prognostic) then + deallocate(bling%fe_burial) + deallocate(bling%ffe_sed) + deallocate(bling%b_fed) + endif + deallocate(bling%b_o2) + deallocate(bling%b_po4) + + if (bling%do_carbon) then !<> + endif !} !CARBON CYCLE>> + + enddo !} n + + return + + end subroutine user_deallocate_arrays + + +end module generic_miniBLING_mod diff --git a/src/ocean_shared/generic_tracers/generic_tracer.F90 b/src/ocean_shared/generic_tracers/generic_tracer.F90 index ac8bc646fc..68c3ac74cf 100644 --- a/src/ocean_shared/generic_tracers/generic_tracer.F90 +++ b/src/ocean_shared/generic_tracers/generic_tracer.F90 @@ -9,18 +9,19 @@ ! This module provides the main interfaces between Ocean models and ! generic tracers. !
            -! +! ! Generic Tracers are designed to be used by both GFDL Ocean models, GOLD and MOM. ! This module provides the main interfaces for using generic tracers. ! Generic Tracers are contained in separate modules according to their -! chemical/physical similarity (currently generic_TOPAZ and generic_CFC) +! chemical/physical similarity (currently generic_TOPAZ, generic_COBALT, +! generic_ERGOM and generic_CFC) ! This module acts as a router for these various tracer modules and ! routes the subroutine calls to the appropriate tracer module. ! It also maintains a (linked) list of all generic tracers created in ! the experiment. This list acts as the "state" of generic tracers and ! contains all the information for all such tracers. This module provides ! a subroutine to query its state at any time. -! +! ! ! http://cobweb.gfdl.noaa.gov/~nnz/MITeam_GUTS_022708.pdf ! @@ -42,6 +43,7 @@ module generic_tracer use g_tracer_utils, only : g_tracer_get_common, g_tracer_set_common, g_tracer_is_prog use g_tracer_utils, only : g_tracer_coupler_set,g_tracer_coupler_get, g_tracer_register_diag use g_tracer_utils, only : g_tracer_vertdiff_M, g_tracer_vertdiff_G, g_tracer_get_next + use g_tracer_utils, only : g_tracer_diag use generic_CFC, only : generic_CFC_register use generic_CFC, only : generic_CFC_init, generic_CFC_update_from_source,generic_CFC_update_from_coupler @@ -62,6 +64,17 @@ module generic_tracer use generic_BLING, only : generic_BLING_update_from_bottom,generic_BLING_update_from_coupler use generic_BLING, only : generic_BLING_set_boundary_values, generic_BLING_end, do_generic_BLING + use generic_miniBLING_mod, only : generic_miniBLING_register + use generic_miniBLING_mod, only : generic_miniBLING_init, generic_miniBLING_update_from_source,generic_miniBLING_register_diag + use generic_miniBLING_mod, only : generic_miniBLING_update_from_bottom,generic_miniBLING_update_from_coupler + use generic_miniBLING_mod, only : generic_miniBLING_set_boundary_values, generic_miniBLING_end, do_generic_miniBLING + use generic_miniBLING_mod, only : generic_miniBLING_diag + + use generic_COBALT, only : generic_COBALT_register + use generic_COBALT, only : generic_COBALT_init, generic_COBALT_update_from_source,generic_COBALT_register_diag + use generic_COBALT, only : generic_COBALT_update_from_bottom,generic_COBALT_update_from_coupler + use generic_COBALT, only : generic_COBALT_set_boundary_values, generic_COBALT_end, do_generic_COBALT + implicit none ; private character(len=fm_string_len), parameter :: mod_name = 'generic_tracer' @@ -71,6 +84,7 @@ module generic_tracer public generic_tracer_init public generic_tracer_register_diag public generic_tracer_source + public generic_tracer_diag public generic_tracer_update_from_bottom public generic_tracer_coupler_get public generic_tracer_coupler_set @@ -93,30 +107,34 @@ module generic_tracer logical, save :: do_generic_tracer = .false. - namelist /generic_tracer_nml/ do_generic_tracer, do_generic_CFC, do_generic_TOPAZ, do_generic_ERGOM, do_generic_BLING + !JGJ 2013/05/31 merged COBALT into siena_201303 + namelist /generic_tracer_nml/ do_generic_tracer, do_generic_CFC, do_generic_TOPAZ, & + do_generic_ERGOM, do_generic_BLING, do_generic_miniBLING, do_generic_COBALT contains + subroutine generic_tracer_register integer :: ioun, io_status, ierr integer :: stdoutunit,stdlogunit + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_register' + stdoutunit=stdout();stdlogunit=stdlog() ! provide for namelist over-ride of defaults - #ifdef INTERNAL_FILE_NML - read (input_nml_file, nml=generic_tracer_nml, iostat=io_status) - ierr = check_nml_error(io_status,'generic_tracer_nml') +read (input_nml_file, nml=generic_tracer_nml, iostat=io_status) +ierr = check_nml_error(io_status,'generic_tracer_nml') #else ioun = open_namelist_file() read (ioun, generic_tracer_nml,iostat=io_status) - write (stdoutunit,'(/)') - write (stdoutunit, generic_tracer_nml) - write (stdlogunit, generic_tracer_nml) ierr = check_nml_error(io_status,'generic_tracer_nml') call close_file (ioun) #endif + write (stdoutunit,'(/)') + write (stdoutunit, generic_tracer_nml) + write (stdlogunit, generic_tracer_nml) if(do_generic_CFC) & call generic_CFC_register(tracer_list) @@ -130,6 +148,12 @@ subroutine generic_tracer_register if(do_generic_BLING) & call generic_BLING_register(tracer_list) + if(do_generic_miniBLING) & + call generic_miniBLING_register(tracer_list) + + if(do_generic_COBALT) & + call generic_COBALT_register(tracer_list) + end subroutine generic_tracer_register @@ -167,23 +191,13 @@ subroutine generic_tracer_init(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes,grid integer, dimension(:,:) , intent(in) :: grid_kmt type(g_tracer_type), pointer :: g_tracer,g_tracer_next - integer :: ioun, io_status, ierr - integer :: stdoutunit,stdlogunit - - stdoutunit=stdout();stdlogunit=stdlog() - ! provide for namelist over-ride of defaults - ioun = open_namelist_file() - read (ioun, generic_tracer_nml,iostat=io_status) - write (stdoutunit,'(/)') - write (stdoutunit, generic_tracer_nml) - write (stdlogunit, generic_tracer_nml) - ierr = check_nml_error(io_status,'generic_tracer_nml') - call close_file (ioun) + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_init' call g_tracer_set_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes,grid_tmask,grid_kmt,init_time) !Allocate and initialize all registered generic tracers - if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING) then + !JGJ 2013/05/31 merged COBALT into siena_201303 + if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING .or. do_generic_miniBLING .or. do_generic_COBALT) then g_tracer => tracer_list !Go through the list of tracers do @@ -210,14 +224,22 @@ subroutine generic_tracer_init(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes,grid if(do_generic_BLING) & call generic_BLING_init(tracer_list) + if(do_generic_miniBLING) & + call generic_miniBLING_init(tracer_list) + + if(do_generic_COBALT) & + call generic_COBALT_init(tracer_list) + end subroutine generic_tracer_init subroutine generic_tracer_register_diag + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_register_diag' type(g_tracer_type), pointer :: g_tracer,g_tracer_next !Diagnostics register for the fields common to All generic tracers + !JGJ 2013/05/31 merged COBALT into siena_201303 - if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING) then + if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING .or. do_generic_miniBLING .or. do_generic_COBALT) then g_tracer => tracer_list !Go through the list of tracers @@ -236,10 +258,14 @@ subroutine generic_tracer_register_diag if(do_generic_TOPAZ) call generic_TOPAZ_register_diag(diag_list) - if(do_generic_ERGOM) call generic_ERGOM_register_diag() + if(do_generic_ERGOM) call generic_ERGOM_register_diag(diag_list) if(do_generic_BLING) call generic_BLING_register_diag() + if(do_generic_miniBLING) call generic_miniBLING_register_diag() + + if(do_generic_COBALT) call generic_COBALT_register_diag(diag_list) + end subroutine generic_tracer_register_diag ! @@ -260,6 +286,7 @@ end subroutine generic_tracer_register_diag subroutine generic_tracer_coupler_get(IOB_struc) type(coupler_2d_bc_type), intent(in) :: IOB_struc + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_coupler_get' !All generic tracers !Update tracer boundary values (%stf and %triver) from coupler fluxes foreach tracer in the prog_tracer_list call g_tracer_coupler_get(tracer_list,IOB_struc) @@ -271,8 +298,59 @@ subroutine generic_tracer_coupler_get(IOB_struc) if(do_generic_BLING) call generic_BLING_update_from_coupler(tracer_list) + if(do_generic_miniBLING) call generic_miniBLING_update_from_coupler(tracer_list) + + if(do_generic_COBALT) call generic_COBALT_update_from_coupler(tracer_list) + end subroutine generic_tracer_coupler_get + + ! + ! + ! Do things which must be done after all transports and sources have been calculated + ! + ! + ! Calls the corresponding generic_X_diag routine for each package X. + ! + ! + ! + ! Lower bounds of x and y extents of input arrays on data domain + ! + ! + ! Time step index of %field + ! + ! + ! Model time + ! + ! + ! Ocean layer thickness (meters) + ! + ! + + subroutine generic_tracer_diag(ilb, jlb, tau, taup1, dtts, model_time, dzt, rho_dzt_tau, rho_dzt_taup1) + integer, intent(in) :: ilb + integer, intent(in) :: jlb + integer, intent(in) :: tau + integer, intent(in) :: taup1 + real, intent(in) :: dtts + type(time_type), intent(in) :: model_time + real, dimension(ilb:,jlb:,:), intent(in) :: dzt + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt_tau + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt_taup1 + + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_update_from_diag' + + if(do_generic_miniBLING) call generic_miniBLING_diag(tracer_list, ilb, jlb, taup1, model_time, dzt, rho_dzt_taup1) + + call g_tracer_diag(tracer_list, ilb, jlb, rho_dzt_tau, rho_dzt_taup1, model_time, tau, taup1, dtts) + + return + + end subroutine generic_tracer_diag + + ! ! ! Update the tracers from sources/sinks @@ -319,7 +397,7 @@ end subroutine generic_tracer_coupler_get subroutine generic_tracer_source(Temp,Salt,rho_dzt,dzt,hblt_depth,ilb,jlb,tau,dtts,& grid_dat,model_time,nbands,max_wavelength_band,sw_pen_band,opacity_band, & - current_wave_stress) + grid_ht, current_wave_stress) real, dimension(ilb:,jlb:,:), intent(in) :: Temp,Salt,rho_dzt,dzt real, dimension(ilb:,jlb:), intent(in) :: hblt_depth integer, intent(in) :: ilb,jlb,tau @@ -330,9 +408,12 @@ subroutine generic_tracer_source(Temp,Salt,rho_dzt,dzt,hblt_depth,ilb,jlb,tau,dt real, dimension(:), intent(in) :: max_wavelength_band real, dimension(:,ilb:,jlb:), intent(in) :: sw_pen_band real, dimension(:,ilb:,jlb:,:), intent(in) :: opacity_band + real, dimension(ilb:,jlb:),optional, intent(in) :: grid_ht real, dimension(ilb:,jlb:),optional , intent(in) :: current_wave_stress + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_update_from_source' + ! if(do_generic_CFC) call generic_CFC_update_from_source(tracer_list) !Nothing to do for CFC if(do_generic_TOPAZ) call generic_TOPAZ_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,& @@ -347,6 +428,14 @@ subroutine generic_tracer_source(Temp,Salt,rho_dzt,dzt,hblt_depth,ilb,jlb,tau,dt hblt_depth,ilb,jlb,tau,dtts,grid_dat,model_time,& nbands,max_wavelength_band,sw_pen_band,opacity_band) + if(do_generic_miniBLING) call generic_miniBLING_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,& + hblt_depth,ilb,jlb,tau,dtts,grid_dat,model_time,& + nbands,max_wavelength_band,sw_pen_band,opacity_band, grid_ht) + + if(do_generic_COBALT) call generic_COBALT_update_from_source(tracer_list,Temp,Salt,rho_dzt,dzt,& + hblt_depth,ilb,jlb,tau,dtts,grid_dat,model_time,& + nbands,max_wavelength_band,sw_pen_band,opacity_band) + return end subroutine generic_tracer_source @@ -374,6 +463,8 @@ subroutine generic_tracer_update_from_bottom(dt, tau, model_time) integer, intent(in) ::tau type(time_type), intent(in) :: model_time + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_update_from_bottom' + ! if(do_generic_CFC) call generic_CFC_update_from_bottom(tracer_list)!Nothing to do for CFC if(do_generic_TOPAZ) call generic_TOPAZ_update_from_bottom(tracer_list,dt, tau, model_time) @@ -382,6 +473,10 @@ subroutine generic_tracer_update_from_bottom(dt, tau, model_time) if(do_generic_BLING) call generic_BLING_update_from_bottom(tracer_list,dt, tau) + if(do_generic_miniBLING) call generic_miniBLING_update_from_bottom(tracer_list,dt, tau) + + if(do_generic_COBALT) call generic_COBALT_update_from_bottom(tracer_list,dt, tau, model_time) + return end subroutine generic_tracer_update_from_bottom @@ -410,7 +505,8 @@ subroutine generic_tracer_vertdiff_G(h_old, ea, eb, dt, kg_m2_to_H, m_to_H, tau) type(g_tracer_type), pointer :: g_tracer,g_tracer_next !nnz: Should I loop here or inside the sub g_tracer_vertdiff ? - if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING) then + !JGJ 2013/05/31 merged COBALT into siena_201303 + if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING .or. do_generic_miniBLING .or. do_generic_COBALT) then g_tracer => tracer_list !Go through the list of tracers @@ -449,7 +545,8 @@ subroutine generic_tracer_vertdiff_M(dh, dhw, diff_cbt, dt, Rho_0,tau) type(g_tracer_type), pointer :: g_tracer,g_tracer_next !nnz: Should I loop here or inside the sub g_tracer_vertdiff ? - if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING) then + !JGJ 2013/05/31 merged COBALT into siena_201303 + if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING .or. do_generic_miniBLING .or. do_generic_COBALT) then g_tracer => tracer_list !Go through the list of tracers @@ -502,6 +599,8 @@ subroutine generic_tracer_coupler_set(IOB_struc, ST,SS,rho,ilb,jlb,tau) real, dimension(ilb:,jlb:), intent(in) :: ST,SS real, dimension(ilb:,jlb:,:,:), intent(in) :: rho + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_coupler_set' + !Set coupler fluxes from tracer boundary values (%stf and %triver)for each tracer in the prog_tracer_list !User must identify these tracers (not all tracers in module need to set coupler) !User must provide the calculations for these boundary values. @@ -518,10 +617,19 @@ subroutine generic_tracer_coupler_set(IOB_struc, ST,SS,rho,ilb,jlb,tau) if(do_generic_BLING) & call generic_BLING_set_boundary_values(tracer_list,ST,SS,rho,ilb,jlb,tau) ! + if(do_generic_miniBLING) & + call generic_miniBLING_set_boundary_values(tracer_list,ST,SS,rho,ilb,jlb,tau) + + if(do_generic_COBALT) & + call generic_COBALT_set_boundary_values(tracer_list,ST,SS,rho,ilb,jlb,tau) + + ! !Set coupler fluxes from tracer boundary values (%alpha and %csurf) !for each tracer in the tracer_list that has been marked by the user routine above + !JGJ 2013/05/31 merged COBALT into siena_201303 ! - if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING) call g_tracer_coupler_set(tracer_list,IOB_struc) + if(do_generic_CFC .or. do_generic_TOPAZ .or. do_generic_ERGOM .or. do_generic_BLING .or. do_generic_miniBLING .or. do_generic_COBALT) & + call g_tracer_coupler_set(tracer_list,IOB_struc) end subroutine generic_tracer_coupler_set @@ -554,10 +662,14 @@ end subroutine generic_tracer_coupler_zero ! ! subroutine generic_tracer_end + character(len=fm_string_len), parameter :: sub_name = 'generic_tracer_end' if(do_generic_CFC) call generic_CFC_end if(do_generic_TOPAZ) call generic_TOPAZ_end if(do_generic_ERGOM) call generic_ERGOM_end if(do_generic_BLING) call generic_BLING_end + if(do_generic_miniBLING) call generic_miniBLING_end + if(do_generic_COBALT) call generic_COBALT_end + end subroutine generic_tracer_end ! diff --git a/src/ocean_shared/generic_tracers/generic_tracer_utils.F90 b/src/ocean_shared/generic_tracers/generic_tracer_utils.F90 index 26444c1d1d..08a0d3aa5d 100644 --- a/src/ocean_shared/generic_tracers/generic_tracer_utils.F90 +++ b/src/ocean_shared/generic_tracers/generic_tracer_utils.F90 @@ -1,8 +1,8 @@ !---------------------------------------------------------------- -! Niki Zadeh +! Niki Zadeh ! ! -! William Cooke +! William Cooke ! ! ! @@ -35,8 +35,8 @@ module g_tracer_utils implicit none ; private !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: generic_tracer_utils.F90,v 19.0.4.2 2012/08/06 21:55:22 nnz Exp $' - character(len=128) :: tag = '$Name: $' + character(len=128) :: version = '$Id: generic_tracer_utils.F90,v 20.0 2013/12/14 00:18:12 fms Exp $' + character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- character(len=48), parameter :: mod_name = 'g_tracer_utils' @@ -102,6 +102,9 @@ module g_tracer_utils ! ! An 3D field for random vertical movement, esp. for zooplankton, ... ! real, _ALLOCATABLE, dimension(:,:,:) :: vdiff _NULL + ! ! An 3D field for implicit vertical diffusion + ! real, _ALLOCATABLE, dimension(:,:,:) :: vdiffuse_impl _NULL + ! ! An auxiliary 3D field for keeping model dependent change tendencies, ... ! real, _ALLOCATABLE, dimension(:,:,:) :: tendency _NULL ! @@ -162,8 +165,16 @@ module g_tracer_utils character(len=fm_string_len) :: units, flux_units ! Tracer concentration field in space (and time) - ! MOM keeps the field at 3 time levels, hence 4D. - real, _ALLOCATABLE, dimension(:,:,:,:):: field _NULL + ! MOM keeps the prognostic tracer fields at 3 time levels, hence 4D. + real, pointer, dimension(:,:,:,:):: field => NULL() + !The following pointer is intended to point to prognostic tracer field in MOM. Do not allocate! + real, pointer, dimension(:,:,:,:):: field4d_ptr => NULL() + !The following pointer is intended to point to diagnostic tracer field in MOM. Do not allocate! + real, pointer, dimension(:,:,:) :: field3d_ptr => NULL() + ! Define a 3-d field pointer so as to retain the lower + ! and upper bounds for the 3-d version of g_tracer_get_pointer + ! for the field option + real, pointer, dimension(:,:,:) :: field_3d => NULL() ! Surface flux, surface flux of gas, deltap and kw real, _ALLOCATABLE, dimension(:,:) :: stf _NULL @@ -205,14 +216,17 @@ module g_tracer_utils ! An 3D field for random vertical movement, esp. for zooplankton, ... real, _ALLOCATABLE, dimension(:,:,:) :: vdiff _NULL - ! An auxiliary 3D field for keeping model dependent change tendencies, ... - real, _ALLOCATABLE, dimension(:,:,:) :: tendency _NULL + ! An 3D field for implicit vertical diffusion + real, _ALLOCATABLE, dimension(:,:,:) :: vdiffuse_impl _NULL + ! An auxiliary 3D field for keeping model dependent change tendencies, ... + real, pointer, dimension(:,:,:) :: tendency => NULL() ! IDs for using diag_manager tools integer :: diag_id_field=-1, diag_id_stf=-1, diag_id_stf_gas=-1, diag_id_deltap=-1, diag_id_kw=-1, diag_id_trunoff=-1 integer :: diag_id_alpha=-1, diag_id_csurf=-1, diag_id_sc_no=-1, diag_id_aux=-1 integer :: diag_id_btf=-1,diag_id_btm=-1, diag_id_vmove=-1, diag_id_vdiff=-1 + integer :: diag_id_vdiffuse_impl = -1, diag_id_tendency = -1, diag_id_field_taup1 = -1 ! Tracer Initial concentration if constant everywhere real :: const_init_value = 0.0 @@ -298,6 +312,8 @@ module g_tracer_utils public :: g_tracer_add public :: g_tracer_init public :: g_tracer_flux_init + public :: g_tracer_column_int + public :: g_tracer_flux_at_depth public :: g_tracer_add_param public :: g_tracer_set_values public :: g_tracer_get_values @@ -308,6 +324,7 @@ module g_tracer_utils public :: g_tracer_coupler_set public :: g_tracer_coupler_get public :: g_tracer_send_diag + public :: g_tracer_diag public :: g_tracer_get_name public :: g_tracer_get_alias public :: g_tracer_get_next @@ -319,6 +336,7 @@ module g_tracer_utils public :: g_tracer_end_param_list public :: g_diag_type public :: g_diag_field_add + public :: g_tracer_set_pointer ! ! @@ -363,6 +381,11 @@ module g_tracer_utils module procedure g_tracer_add_param_string end interface + interface g_tracer_set_pointer + module procedure g_tracer_set_pointer_3d + module procedure g_tracer_set_pointer_4d + end interface g_tracer_set_pointer + ! ! ! Set the values of various (array) memebers of the tracer node g_tracer_type @@ -500,7 +523,8 @@ end subroutine g_tracer_start_param_list ! ! - subroutine g_tracer_end_param_list() + subroutine g_tracer_end_param_list(package_name) + character(len=fm_string_len) :: package_name end subroutine g_tracer_end_param_list @@ -510,7 +534,16 @@ subroutine g_tracer_add_param_real(name, var, value) real, intent(in) :: value real, intent(out) :: var - if(.NOT. fm_get_value(name, var)) var = value + real :: x + + ! Need to save "value" since if "var" and "value" are the same + ! variable, and "name" does not exist, then "var/value" will be + ! set to 0 in the fm_get_value routine, and "var" cannot then be + ! set to the supplied default value + + x = value + + if(.NOT. fm_get_value(name, var)) var = x end subroutine g_tracer_add_param_real @@ -520,7 +553,16 @@ subroutine g_tracer_add_param_logical(name, var, value) logical, intent(in) :: value logical, intent(out) :: var - if(.NOT. fm_get_value(name, var)) var = value + logical :: x + + ! Need to save "value" since if "var" and "value" are the same + ! variable, and "name" does not exist, then "var/value" will be + ! set to false in the fm_get_value routine, and "var" cannot then be + ! set to the supplied default value + + x = value + + if(.NOT. fm_get_value(name, var)) var = x end subroutine g_tracer_add_param_logical @@ -530,7 +572,16 @@ subroutine g_tracer_add_param_integer(name, var, value) integer, intent(in) :: value integer, intent(out) :: var - if(.NOT. fm_get_value(name, var)) var = value + real :: x + + ! Need to save "value" since if "var" and "value" are the same + ! variable, and "name" does not exist, then "var/value" will be + ! set to 0 in the fm_get_value routine, and "var" cannot then be + ! set to the supplied default value + + x = value + + if(.NOT. fm_get_value(name, var)) var = x end subroutine g_tracer_add_param_integer @@ -540,7 +591,16 @@ subroutine g_tracer_add_param_string(name, var, value) character(len=*), intent(in) :: value character(len=*), intent(out) :: var - if(.NOT. fm_get_value(name, var)) var = value + character(len=fm_string_len) :: x + + ! Need to save "value" since if "var" and "value" are the same + ! variable, and "name" does not exist, then "var/value" will be + ! set to '' in the fm_get_value routine, and "var" cannot then be + ! set to the supplied default value + + x = value + + if(.NOT. fm_get_value(name, var)) var = x end subroutine g_tracer_add_param_string @@ -672,6 +732,8 @@ subroutine g_tracer_add(node_ptr, package, name, longname, units, prog, const_i ! Local parameters ! + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_add' + character(len=fm_string_len) :: flux_name ! ! Local variables ! @@ -784,6 +846,25 @@ subroutine g_tracer_add(node_ptr, package, name, longname, units, prog, const_i end subroutine g_tracer_add + ! + ! Local functiion to remap the bounds of an array + ! (Thanks to wikipedia for the suggestion) + ! + + function remap_bounds(ilb, jlb, klb, array) result(ptr) + + real, dimension(:,:,:), pointer :: ptr + + integer, intent(in) :: ilb + integer, intent(in) :: jlb + integer, intent(in) :: klb + real, dimension(ilb:,jlb:,klb:), target, intent(in) :: array + + ptr => array + + return + end function remap_bounds + subroutine g_tracer_init(g_tracer) type(g_tracer_type), pointer :: g_tracer integer :: isc,iec,jsc,jec,isd,ied,jsd,jed, nk,ntau,axes(3) @@ -792,9 +873,12 @@ subroutine g_tracer_init(g_tracer) call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes) allocate(g_tracer%field(isd:ied,jsd:jed,nk,ntau)); g_tracer%field(:,:,:,:) = g_tracer%initial_value + g_tracer%field_3d => remap_bounds(isd, jsd, 1, g_tracer%field(:,:,:,1)) if(g_tracer%prog) then allocate(g_tracer%tendency(isd:ied,jsd:jed,nk)); g_tracer%tendency(:,:,:) = 0.0 + allocate(g_tracer%vdiffuse_impl(isd:ied,jsd:jed,nk)) + g_tracer%vdiffuse_impl(:,:,:) = 0.0 endif if(g_tracer%flux_gas) then @@ -926,6 +1010,15 @@ subroutine g_tracer_register_diag(g_tracer) trim(g_tracer%units), & missing_value = -1.0e+20) + string=trim(g_tracer%alias) // trim("_taup1") + g_tracer%diag_id_field_taup1 = register_diag_field(g_tracer%package_name, & + trim(string), & + g_tracer_com%axes(1:3), & + g_tracer_com%init_time, & + trim(g_tracer%longname) // ' at taup1', & + trim(g_tracer%units), & + missing_value = -1.0e+20) + string=trim(g_tracer%alias) // trim("_aux") g_tracer%diag_id_aux = register_diag_field(g_tracer%package_name, & trim(string), & @@ -944,6 +1037,24 @@ subroutine g_tracer_register_diag(g_tracer) trim('m/s'), & missing_value = -1.0e+20) + string=trim(g_tracer%alias) // trim("_vdiffuse_impl") + g_tracer%diag_id_vdiffuse_impl = register_diag_field(g_tracer%package_name, & + trim(string), & + g_tracer_com%axes(1:3), & + g_tracer_com%init_time, & + 'Implicit vertical diffusion of ' // trim(g_tracer%alias), & + trim('mole/m^2/s'), & + missing_value = -1.0e+20) + + string=trim(g_tracer%alias) // trim("_tendency") + g_tracer%diag_id_tendency = register_diag_field(g_tracer%package_name, & + trim(string), & + g_tracer_com%axes(1:3), & + g_tracer_com%init_time, & + 'Generic tracer tendency of ' // trim(g_tracer%alias), & + trim('mole/m^2/s'), & + missing_value = -1.0e+20) + string=trim(g_tracer%alias) // trim("_vdiff") g_tracer%diag_id_vdiff = register_diag_field(g_tracer%package_name, & trim(string), & @@ -1329,6 +1440,7 @@ subroutine g_tracer_set_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes,grid integer,dimension(isd:,jsd:),intent(in) :: grid_kmt type(time_type), intent(in) :: init_time + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_set_common' integer :: i,j !Here we assume that all the tracers in the list have the same following properties @@ -1398,6 +1510,8 @@ subroutine g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,& integer, optional, dimension(:,:), pointer :: grid_mask_coast integer, optional, dimension(:,:), pointer :: grid_kmt + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_get_common' + !Here we assume that all the tracers in the list have the same following properties isd=g_tracer_com%isd @@ -1449,10 +1563,14 @@ subroutine g_tracer_get_4D(g_tracer_list,name,member,array_ptr) ": No tracer in the list with name="//trim(name)) select case(member) - case ('field') - array_ptr => g_tracer%field + case ('field') + if(associated(g_tracer%field)) then + array_ptr => g_tracer%field + else + call mpp_error(FATAL, trim(sub_name)//": Cannot get member variable: "//trim(name)//" % "//trim(member)) + endif case default - call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(member)) + call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(name)//" % "//trim(member)) end select end subroutine g_tracer_get_4D @@ -1478,11 +1596,19 @@ subroutine g_tracer_get_3D(g_tracer_list,name,member,array_ptr) select case(member) case ('field') - array_ptr => g_tracer%field(:,:,:,1) + if(associated(g_tracer%field3d_ptr)) then + array_ptr => g_tracer%field3d_ptr + elseif(associated(g_tracer%field_3d)) then + array_ptr => g_tracer%field_3d + else + call mpp_error(FATAL, trim(sub_name)//": Cannot get member variable: "//trim(name)//" % "//trim(member)) + endif case ('vmove') array_ptr => g_tracer%vmove case ('vdiff') array_ptr => g_tracer%vdiff + case ('vdiffuse_impl') + array_ptr => g_tracer%vdiffuse_impl case default call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(member)) end select @@ -1563,9 +1689,13 @@ subroutine g_tracer_get_4D_val(g_tracer_list,name,member,array,isd,jsd) select case(member) case ('field') - array = g_tracer%field + if(associated(g_tracer%field)) then + array = g_tracer%field + else + call mpp_error(FATAL, trim(sub_name)//": Cannot get member variable: "//trim(name)//" % "//trim(member)) + endif case default - call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(member)) + call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(name)//" % "//trim(member)) end select end subroutine g_tracer_get_4D_val @@ -1597,7 +1727,14 @@ subroutine g_tracer_get_3D_val(g_tracer_list,name,member,array,isd,jsd,ntau,posi select case(member) case ('field') - array(:,:,:) = g_tracer%field(:,:,:,tau) + if(associated(g_tracer%field)) then + array(:,:,:) = g_tracer%field(:,:,:,tau) + elseif(associated(g_tracer%field3d_ptr)) then + array(:,:,:) = g_tracer%field3d_ptr(:,:,:) + else + call mpp_error(FATAL, trim(sub_name)//": Cannot get member variable: "//trim(name)//" % "//trim(member)) + endif + if(present(positive)) array = max(0.0,array) case ('tendency') array(:,:,:) = g_tracer%tendency(:,:,:) @@ -1605,6 +1742,8 @@ subroutine g_tracer_get_3D_val(g_tracer_list,name,member,array,isd,jsd,ntau,posi array(:,:,:) = g_tracer%vmove(:,:,:) case ('vdiff') array(:,:,:) = g_tracer%vdiff(:,:,:) + case ('vdiffuse_impl') + array(:,:,:) = g_tracer%vdiffuse_impl(:,:,:) case default call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(member)) end select @@ -1820,11 +1959,19 @@ subroutine g_tracer_set_3D(g_tracer_list,name,member,array,isd,jsd,ntau) case ('tendency') g_tracer%tendency = array case ('field') - g_tracer%field(:,:,:,tau) = array(:,:,:) + if(associated(g_tracer%field)) then + g_tracer%field(:,:,:,tau) = array(:,:,:) + elseif(associated(g_tracer%field3d_ptr)) then + g_tracer%field3d_ptr(:,:,:) = array(:,:,:) + else + call mpp_error(FATAL, trim(sub_name)//": Cannot set member variable: "//trim(name)//" % "//trim(member)) + endif case ('vmove') g_tracer%vmove = array case ('vdiff') g_tracer%vdiff = array + case ('vdiffuse_impl') + g_tracer%vdiffuse_impl = array case default call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(member)) end select @@ -1853,8 +2000,12 @@ subroutine g_tracer_set_4D(g_tracer_list,name,member,array,isd,jsd) ": No tracer in the list with name="//trim(name)) select case(member) - case ('field') - g_tracer%field = array + case ('field') + if(associated(g_tracer%field)) then + g_tracer%field = array + else + call mpp_error(FATAL, trim(sub_name)//": Cannot set member variable: "//trim(name)//" % "//trim(member)) + endif case default call mpp_error(FATAL, trim(sub_name)//": Not a known member variable: "//trim(member)) end select @@ -1883,7 +2034,11 @@ subroutine g_tracer_set_real(g_tracer_list,name,member,value) select case(member) case ('field') - g_tracer%field = value !Set all elements to value + if(associated(g_tracer%field)) then + g_tracer%field = value !Set all elements to value + else + call mpp_error(FATAL, trim(sub_name)//": Cannot set member variable: "//trim(name)//" % "//trim(member)) + endif case ('tendency') g_tracer%tendency = value case ('alpha') @@ -1916,6 +2071,94 @@ subroutine g_tracer_set_real(g_tracer_list,name,member,value) end subroutine g_tracer_set_real + subroutine g_tracer_set_pointer_4D(g_tracer_list,name,member,array,ilb,jlb) + character(len=*), intent(in) :: name + character(len=*), intent(in) :: member + type(g_tracer_type), pointer :: g_tracer_list, g_tracer + integer, intent(in) :: ilb,jlb + real, dimension(ilb:,jlb:,:,:), target, intent(in) :: array + + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_set_pointer_4D' + + if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list.") + + g_tracer => g_tracer_list !Local pointer. Do not change the input pointer! + + !Find the node which has name=name + call g_tracer_find(g_tracer,name) + if(.NOT. associated(g_tracer)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list with name="//trim(name)) + + select case(member) + case ('field') + if (associated(g_tracer%field )) then + call mpp_error(NOTE, trim(sub_name) // ": Deallocating generic tracer "//trim(name)//" % "//trim(member)) + deallocate( g_tracer%field ) + endif + g_tracer%field => array + case default + call mpp_error(FATAL, trim(sub_name)//": Not a supported operation for member variable: "//trim(name)//" % "//trim(member)) + end select + + end subroutine g_tracer_set_pointer_4D + + subroutine g_tracer_set_pointer_3D(g_tracer_list,name,member,array,ilb,jlb) + character(len=*), intent(in) :: name + character(len=*), intent(in) :: member + type(g_tracer_type), pointer :: g_tracer_list, g_tracer + integer, intent(in) :: ilb,jlb + real, dimension(ilb:,jlb:,:), target, intent(in) :: array + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_set_pointer_3D' + + if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list.") + + g_tracer => g_tracer_list !Local pointer. Do not change the input pointer! + + !Find the node which has name=name + call g_tracer_find(g_tracer,name) + if(.NOT. associated(g_tracer)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list with name="//trim(name)) + + select case(member) + case ('tendency') + if (associated( g_tracer%tendency )) then + call mpp_error(NOTE, trim(sub_name) // ": Deallocating generic tracer "//trim(name)//" % "//trim(member)) + deallocate( g_tracer%tendency ) + endif + g_tracer%tendency => array + case ('field') + if (associated( g_tracer%field )) then + call mpp_error(NOTE, trim(sub_name) // ": Deallocating generic tracer "//trim(name)//" % "//trim(member)) + deallocate( g_tracer%field ) + endif + g_tracer%field3d_ptr => array +! call set_cray_pointer_field(g_tracer%field,array,ilb,jlb) + + case default + call mpp_error(FATAL, trim(sub_name)//": Not a supported operation for member variable: "//trim(name)//" % "//trim(member)) + end select + + end subroutine g_tracer_set_pointer_3D + + !The following does not compile: + !error #6406: Conflicting attributes or multiple declaration of name. [FIELD] + ! pointer(ptr,field) + !----------------^ + +! subroutine set_cray_pointer_field(field,array,ilb,jlb) +! real, dimension(:,:,:,:), intent(inout) :: field +! integer, intent(in) :: ilb,jlb +! real, dimension(ilb:,jlb:,:), target, intent(in) :: array +! +! pointer(ptr,field) +! +! ptr = LOC(array) +! +! end subroutine set_cray_pointer_field + + ! ! ! Get the pointer for the named tracer node @@ -1958,6 +2201,329 @@ subroutine g_tracer_find(g_tracer,name) g_tracer => g_tracer%next enddo end subroutine g_tracer_find + + +!####################################################################### + ! + ! + ! Calculate the column interval for a given variable + ! + ! + ! Calculate the column interval for a given variable + ! + ! + ! + ! Depth over which to integrate + ! + ! + ! Lower bound of 1st dimension of arrays + ! + ! + ! Lower bound of 2nd dimension of arrays + ! + ! + ! Variable to integrate + ! + ! + ! Layer thicknesses + ! + ! + ! Density times layer thicknesses + ! + ! + ! Work array: rho_dzt to be multiplied by var to do the integral (may be used in subsequent calls) + ! + ! + ! K level for maximum depth to perform the integral, if 0 then calculate rd array (may be used in subsequent calls) + ! If set greater than 0, then the work array can be used in subsequent calls for the same depth to save some + ! computation. Care should be taken that if k_level is set > 0 that the same depth range is used. + ! + ! + ! Integral of var over depth + ! + ! + ! string indicating caller of this routine, for traceback + ! + ! + + subroutine g_tracer_column_int(depth, ilb, jlb, var, dzt, rho_dzt, rd, k_level, integral, caller) + + real, intent(in) :: depth + integer, intent(in) :: ilb + integer, intent(in) :: jlb + real, dimension(ilb:,jlb:,:), intent(in) :: var + real, dimension(ilb:,jlb:,:), intent(in) :: dzt + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt + real, dimension(ilb:,jlb:,:), intent(inout) :: rd + integer, intent(inout) :: k_level + real, dimension(ilb:,jlb:), intent(out) :: integral + character(len=*), intent(in), optional :: caller + +!----------------------------------------------------------------------- +! local parameters + + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_column_int' + + character(len=256) :: caller_str + character(len=256) :: error_header + character(len=256) :: warn_header + character(len=256) :: note_header + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + real, dimension(:,:,:), pointer :: grid_tmask + integer :: i + integer :: j + integer :: k + logical :: continue_calc + real, dimension(:,:), allocatable :: depth_x + + ! Set up the headers for stdout messages. + + if (present(caller)) then + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[' // trim(caller) // ']' + else + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[]' + endif + error_header = '==> Error from ' // trim(caller_str) // ':' + warn_header = '==> Warning from ' // trim(caller_str) // ':' + note_header = '==> Note from ' // trim(caller_str) // ':' + + ! + ! Check the depth + ! + + if (depth .le. 0.0) then + call mpp_error(FATAL, trim(error_header) // ' Depth <= 0,0') + endif + + ! Set up the module if not already done + + call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & + grid_tmask = grid_tmask) + + ! + ! Check the k_level + ! + + if (k_level .gt. nk) then + call mpp_error(FATAL, trim(error_header) // ' k_level > nk') + endif + + ! + ! Calculate the integral + ! + + if (k_level .le. 0) then !{ + allocate (depth_x(isd:ied,jsd:jed)) + depth_x(:,:) = depth + rd(:,:,:) = 0.0 + do k = 1, nk !} + continue_calc = .false. + do j = jsc, jec !{ + do i = isc, iec !{ + if (grid_tmask(i,j,k) .gt. 0.5 .and. depth_x(i,j) .gt. 0.0) then !{ + k_level = k + if (depth_x(i,j) .gt. dzt(i,j,k)) then !{ + continue_calc = .true. + rd(i,j,k) = rho_dzt(i,j,k) + depth_x(i,j) = depth_x(i,j) - dzt(i,j,k) + else !}{ + rd(i,j,k) = depth_x(i,j) / dzt(i,j,k) * rho_dzt(i,j,k) + depth_x(i,j) = 0.0 + endif !} + endif !} + enddo !} i + enddo !} j + if (.not. continue_calc) then + exit + endif + enddo !} k + deallocate (depth_x) + endif !} + + integral(:,:) = 0.0 + do k = 1, k_level !} + do j = jsc, jec !{ + do i = isc, iec !{ + integral(i,j) = integral(i,j) + var(i,j,k) * rd(i,j,k) + enddo !} i + enddo !} j + enddo !} k + + return + + end subroutine g_tracer_column_int + + +!####################################################################### + ! + ! + ! Calculate the column interval for a given variable + ! + ! + ! Calculate the column interval for a given variable + ! + ! + ! + ! Depth over which to integrate + ! + ! + ! Lower bound of 1st dimension of arrays + ! + ! + ! Lower bound of 2nd dimension of arrays + ! + ! + ! Variable to integrate + ! + ! + ! Layer thicknesses + ! + ! + ! Work array: array of k level for each grid point at which depth occurs (may be used in future calls) + ! + ! + ! Work array: fraction of level at which depth occurs (may be used in future calls) + ! + ! + ! True if the arrays have been initialized from a previous call, set to true in subroutine. + ! If true, then the work arrays can be used in subsequent calls for the same depth to save some + ! computation. Care should be taken that if iniitialized is set to true that the same depth range is used. + ! + ! + ! Flux at specified depth + ! + ! + ! string indicating caller of this routine, for traceback + ! + ! + + subroutine g_tracer_flux_at_depth(depth, ilb, jlb, var, dzt, k_level, frac, initialized, flux, caller) + + real, intent(in) :: depth + integer, intent(in) :: ilb + integer, intent(in) :: jlb + real, dimension(ilb:,jlb:,:), intent(in) :: var + real, dimension(ilb:,jlb:,:), intent(in) :: dzt + integer, dimension(ilb:,jlb:), intent(inout) :: k_level + real, dimension(ilb:,jlb:), intent(inout) :: frac + logical, intent(inout) :: initialized + real, dimension(ilb:,jlb:), intent(out) :: flux + character(len=*), intent(in), optional :: caller + +!----------------------------------------------------------------------- +! local parameters + + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_flux_at_depth' + + character(len=256) :: caller_str + character(len=256) :: error_header + character(len=256) :: warn_header + character(len=256) :: note_header + integer :: isc + integer :: iec + integer :: jsc + integer :: jec + integer :: isd + integer :: ied + integer :: jsd + integer :: jed + integer :: nk + integer :: ntau + real, dimension(:,:,:), pointer :: grid_tmask + integer :: i + integer :: j + integer :: k + real, dimension(:,:), allocatable :: depth_x + logical :: continue_calc + + ! Set up the headers for stdout messages. + + if (present(caller)) then + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[' // trim(caller) // ']' + else + caller_str = trim(mod_name) // '(' // trim(sub_name) // ')[]' + endif + error_header = '==> Error from ' // trim(caller_str) // ':' + warn_header = '==> Warning from ' // trim(caller_str) // ':' + note_header = '==> Note from ' // trim(caller_str) // ':' + + ! + ! Check the depth + ! + + if (depth .le. 0.0) then + call mpp_error(FATAL, trim(error_header) // ' Depth <= 0,0') + endif + + ! Set up the module if not already done + + call g_tracer_get_common(isc, iec, jsc, jec, isd, ied, jsd, jed, nk, ntau, & + grid_tmask = grid_tmask) + + ! + ! Calculate the flux + ! + + if (.not. initialized) then !{ + allocate (depth_x(isd:ied,jsd:jed)) + depth_x(:,:) = depth + frac(:,:) = 0.0 + k_level(:,:) = 0 + do k = 1, nk !{ + continue_calc = .false. + do j = jsc, jec !{ + do i = isc, iec !{ + if (grid_tmask(i,j,k) .gt. 0.5 .and. depth_x(i,j) .gt. 0.0) then !{ + if (depth_x(i,j) .gt. dzt(i,j,k)) then !{ + continue_calc = .true. + depth_x(i,j) = depth_x(i,j) - dzt(i,j,k) + else !}{ + frac(i,j) = depth_x(i,j) / dzt(i,j,k) + k_level(i,j) = k + depth_x(i,j) = 0.0 + endif !} + endif !} + enddo !} i + enddo !} j + if (.not. continue_calc) then + exit + endif + enddo !} k + deallocate (depth_x) + endif !} + initialized = .true. + + flux(:,:) = 0.0 + do j = jsc, jec !{ + do i = isc, iec !{ + if (k_level(i,j) .gt. 0) then !{ + k = k_level(i,j) + if (k .eq. 1) then + flux(i,j) = frac(i,j) * var(i,j,k) + else + flux(i,j) = (1.0 - frac(i,j)) * var(i,j,k-1) + frac(i,j) * var(i,j,k) + endif + endif !} + enddo !} i + enddo !} j + + return + + end subroutine g_tracer_flux_at_depth + ! ! @@ -1999,10 +2565,23 @@ subroutine g_tracer_send_diag(g_tracer_list,model_time,tau) tau_1=tau if (g_tracer%diag_id_field .gt. 0) then if(.NOT. g_tracer_is_prog(g_tracer)) tau_1=1 + + if(associated(g_tracer%field)) then used = send_data(g_tracer%diag_id_field, g_tracer%field(:,:,:,tau_1), model_time,& rmask = g_tracer_com%grid_tmask(:,:,:),& is_in=g_tracer_com%isc, js_in=g_tracer_com%jsc, ks_in=1,& ie_in=g_tracer_com%iec, je_in=g_tracer_com%jec, ke_in=g_tracer_com%nk) + elseif(associated(g_tracer%field3d_ptr)) then + used = send_data(g_tracer%diag_id_field, g_tracer%field3d_ptr(:,:,:), model_time,& + rmask = g_tracer_com%grid_tmask(:,:,:),& + is_in=g_tracer_com%isc, js_in=g_tracer_com%jsc, ks_in=1,& + ie_in=g_tracer_com%iec, je_in=g_tracer_com%jec, ke_in=g_tracer_com%nk) + + else + call mpp_error(FATAL, trim(sub_name)//": Cannot send_diag field variable for "//trim(g_tracer%name) ) + endif + + endif if (g_tracer%diag_id_vmove .gt. 0 .and. _ALLOCATED(g_tracer%vmove)) then @@ -2104,6 +2683,82 @@ subroutine g_tracer_send_diag(g_tracer_list,model_time,tau) end subroutine g_tracer_send_diag + ! + ! + ! Send diagnostics for all registered fields at finish (if in diag_table) + ! + ! + ! Collectively sends out the diagnostics for all registered fields of all generic tracers + ! + ! + ! + ! pointer to the head of the generic tracer list + ! + ! + ! Time that the diagnostics is sent + ! + ! + ! The time step for the %field 4D field to be reported + ! + ! + + subroutine g_tracer_diag(g_tracer_list, ilb, jlb, rho_dzt_tau, rho_dzt_taup1, model_time, tau, taup1, dtts) + type(g_tracer_type), pointer :: g_tracer_list + integer, intent(in) :: ilb + integer, intent(in) :: jlb + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt_tau + real, dimension(ilb:,jlb:,:), intent(in) :: rho_dzt_taup1 + type(time_type), intent(in) :: model_time + integer, intent(in) :: tau + integer, intent(in) :: taup1 + real, intent(in) :: dtts + + type(g_tracer_type), pointer :: g_tracer + integer :: tau_1 + logical :: used + + character(len=fm_string_len), parameter :: sub_name = 'g_tracer_diag' + + if(.NOT. associated(g_tracer_list)) call mpp_error(FATAL, trim(sub_name)//& + ": No tracer in the list.") + + g_tracer => g_tracer_list !Local pointer. Do not change the input pointer! + + !Go through the list of tracers + do + tau_1=taup1 + if (g_tracer%diag_id_field_taup1 .gt. 0) then + if(.NOT. g_tracer_is_prog(g_tracer)) tau_1=1 + used = send_data(g_tracer%diag_id_field_taup1, g_tracer%field(:,:,:,tau_1), model_time,& + rmask = g_tracer_com%grid_tmask(:,:,:),& + is_in=g_tracer_com%isc, js_in=g_tracer_com%jsc, ks_in=1,& + ie_in=g_tracer_com%iec, je_in=g_tracer_com%jec, ke_in=g_tracer_com%nk) + endif + + if (g_tracer%diag_id_tendency .gt. 0 .and. g_tracer%prog) then + used = send_data(g_tracer%diag_id_tendency,& + (g_tracer%field(:,:,:,taup1)*rho_dzt_taup1(:,:,:) - g_tracer%field(:,:,:,tau)*rho_dzt_tau(:,:,:))/dtts, model_time,& + rmask = g_tracer_com%grid_tmask(:,:,:),& + is_in=g_tracer_com%isc, js_in=g_tracer_com%jsc, ks_in=1,& + ie_in=g_tracer_com%iec, je_in=g_tracer_com%jec, ke_in=g_tracer_com%nk) + endif + + if (g_tracer%diag_id_vdiffuse_impl .gt. 0 .and. _ALLOCATED(g_tracer%vdiffuse_impl)) then + used = send_data(g_tracer%diag_id_vdiffuse_impl, g_tracer%vdiffuse_impl(:,:,:), model_time,& + rmask = g_tracer_com%grid_tmask(:,:,:),& + is_in=g_tracer_com%isc, js_in=g_tracer_com%jsc, ks_in=1,& + ie_in=g_tracer_com%iec, je_in=g_tracer_com%jec, ke_in=g_tracer_com%nk) + endif + + !traverse the linked list till hit NULL + if(.NOT. associated(g_tracer%next)) exit + g_tracer => g_tracer%next + enddo + + end subroutine g_tracer_diag + subroutine g_tracer_traverse(g_tracer_list) type(g_tracer_type), pointer :: g_tracer_list, g_tracer @@ -2239,11 +2894,12 @@ end subroutine g_tracer_get_next ! ! - subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, tau) + subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, tau, mom) type(g_tracer_type), pointer :: g_tracer real, dimension(g_tracer_com%isd:,g_tracer_com%jsd:,:), intent(in) :: h_old, ea, eb real, intent(in) :: dt, kg_m2_to_H, m_to_H integer, intent(in) :: tau + logical, intent(in), optional :: mom ! Arguments: h_old - Layer thickness before entrainment, in m or kg m-2. ! In all the following comments the units of h_old are @@ -2255,6 +2911,8 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, ! the units of h_old (H). ! (in) m_to_H - A conversion factor that translates m into the units ! of h_old (H). + ! (in,opt) mom - If true, then called from MOM and don't do diagnostic, + ! if false or not present, then not from MOM and do diagnostics. ! This subroutine solves a tridiagonal equation for the final tracer ! concentrations after the dual-entrainments, and possibly sinking or surface @@ -2278,8 +2936,32 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, real :: b_denom_1 ! The first term in the denominator of b1, in H. real :: H_to_kg_m2 ! 1 / kg_m2_to_H. integer :: i, j, k, nz + logical :: do_diagnostic - d1=0.0 + ! + ! Save the current state for calculation of the implicit vertical diffusion term + ! + + if (g_tracer%diag_id_vdiffuse_impl .gt. 0) then + if (present(mom)) then + do_diagnostic = .not. mom + else + do_diagnostic = .false. + endif + else + do_diagnostic = .false. + endif + if (do_diagnostic) then + do j = g_tracer_com%jsc, g_tracer_com%jec + do i = g_tracer_com%isc, g_tracer_com%iec + do k = 1, g_tracer_com%nk + g_tracer%vdiffuse_impl(i,j,k) = g_tracer%field(i,j,k,tau) + enddo + enddo + enddo + endif + + d1 = 0.0 H_to_kg_m2 = 1.0 / kg_m2_to_H sink_dist = (dt*g_tracer%sink_rate) * m_to_H @@ -2291,8 +2973,8 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, nz=g_tracer_com%grid_kmt(i,j) if (g_tracer%move_vertical) then - do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo - endif + do k=2,nz; sink_dist(k) = (dt*g_tracer%vmove(i,j,k)) * m_to_H; enddo + endif sfc_src = 0.0 ; btm_src = 0.0 ! Find the sinking rates at all interfaces, limiting them if necesary @@ -2367,10 +3049,26 @@ subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, g_tracer%field(i,j,k,tau) = g_tracer%field(i,j,k,tau) + c1(k+1)*g_tracer%field(i,j,k+1,tau) enddo - endif !(g_tracer_com%grid_tmask(i,j,1) > 0.5) + endif !(g_tracer_com%grid_tmask(i,j,1) > 0.5) enddo; enddo ! i,j + ! + ! Calculate the implicit vertical diffusion term + ! (Note: not sure if this needs any unit conversion) + ! + + if (do_diagnostic) then + do j = g_tracer_com%jsc, g_tracer_com%jec + do i = g_tracer_com%isc, g_tracer_com%iec + do k = 1, g_tracer_com%nk + g_tracer%vdiffuse_impl(i,j,k) = g_tracer_com%grid_tmask(i,j,k) * & + (g_tracer%field(i,j,k,tau) - g_tracer%vdiffuse_impl(i,j,k)) / dt + enddo + enddo + enddo + endif + end subroutine g_tracer_vertdiff_G ! @@ -2415,6 +3113,21 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) endif eps = 1.e-30 + + ! + ! Save the current state for calculation of the implicit vertical diffusion term + ! + + if (g_tracer%diag_id_vdiffuse_impl .gt. 0) then + do j = g_tracer_com%jsc, g_tracer_com%jec + do i = g_tracer_com%isc, g_tracer_com%iec + do k = 1, g_tracer_com%nk + g_tracer%vdiffuse_impl(i,j,k) = g_tracer%field(i,j,k,tau) + enddo + enddo + enddo + endif + ! !Add the contribution of K33_implicit to the diffusivity ! @@ -2467,7 +3180,7 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) enddo enddo !Note: dh, ea, and eb have units here of kg m-2. - call g_tracer_vertdiff_G(g_tracer, dh, ea, eb, dt, 1.0, rho0, tau) + call g_tracer_vertdiff_G(g_tracer, dh, ea, eb, dt, 1.0, rho0, tau, mom = .true.) !Mask out the field over "land" (land under Ocean) g_tracer%field(:,:,:,tau) = g_tracer%field(:,:,:,tau) * g_tracer_com%grid_tmask(:,:,:) @@ -2494,15 +3207,15 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) kp1 = min(k+1,g_tracer_com%nk) do i=g_tracer_com%isc,g_tracer_com%iec fact1 = dt/dh(i,j,k) - fact2 = rho0*fact1*0.5 - factu = fact1/dhw(i,j,km1) + fact2 = rho0*fact1*0.5 + factu = fact1/dhw(i,j,km1) factl = fact1/dhw(i,j,k) - wabsu = abs(g_tracer%vmove(i,j,km1)) - wposu(i,k) = fact2*(g_tracer%vmove(i,j,km1) + wabsu)*g_tracer_com%grid_tmask(i,j,k) - wnegu(i,k) = fact2*(g_tracer%vmove(i,j,km1) - wabsu)*g_tracer_com%grid_tmask(i,j,k) - wabsl = abs(g_tracer%vmove(i,j,k)) - wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1) - wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,kp1) + wabsu = abs(g_tracer%vmove(i,j,km1)) + wposu(i,k) = fact2*(g_tracer%vmove(i,j,km1) + wabsu)*g_tracer_com%grid_tmask(i,j,k) + wnegu(i,k) = fact2*(g_tracer%vmove(i,j,km1) - wabsu)*g_tracer_com%grid_tmask(i,j,k) + wabsl = abs(g_tracer%vmove(i,j,k)) + wposl(i,k) = fact2*(g_tracer%vmove(i,j,k ) + wabsl)*g_tracer_com%grid_tmask(i,j,kp1) + wnegl(i,k) = fact2*(g_tracer%vmove(i,j,k ) - wabsl)*g_tracer_com%grid_tmask(i,j,kp1) a1(i,k) = dcb(i,j,km1)*factu*g_tracer_com%grid_tmask(i,j,k) c1(i,k) = dcb(i,j,k) *factl*g_tracer_com%grid_tmask(i,j,kp1) a(i,k) = -(a1(i,k) - wnegu(i,k)) @@ -2514,14 +3227,14 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) do i=g_tracer_com%isc,g_tracer_com%iec a1(i,1) = 0.0 - wnegu(i,1) = 0.0; wposu(i,1) = 0.0 - a(i,1) = 0.0 + wnegu(i,1) = 0.0; wposu(i,1) = 0.0 + a(i,1) = 0.0 c1(i,g_tracer_com%nk) = 0.0 - wposl(i,g_tracer_com%nk) = 0.0; wnegl(i,g_tracer_com%nk) = 0.0 + wposl(i,g_tracer_com%nk) = 0.0; wnegl(i,g_tracer_com%nk) = 0.0 c(i,g_tracer_com%nk) = 0.0 b(i,1) = 1.0 + a1(i,1) + c1(i,1) - wnegl(i,1) + wposu(i,1) b(i,g_tracer_com%nk) = 1.0 + a1(i,g_tracer_com%nk) + c1(i,g_tracer_com%nk) & - - wnegl(i,g_tracer_com%nk) + wposu(i,g_tracer_com%nk) + - wnegl(i,g_tracer_com%nk) + wposu(i,g_tracer_com%nk) ! top and bottom b.c. if (_ALLOCATED(g_tracer%stf)) & @@ -2618,6 +3331,24 @@ subroutine g_tracer_vertdiff_M(g_tracer,dh, dhw, diff_cbt, dt, rho0,tau) endif + ! + ! Calculate the implicit vertical diffusion term + ! (Note: dh = rho_dzt(taup1) + ! + + if (g_tracer%diag_id_vdiffuse_impl .gt. 0) then + do j = g_tracer_com%jsc, g_tracer_com%jec + do i = g_tracer_com%isc, g_tracer_com%iec + do k = 1, g_tracer_com%nk + g_tracer%vdiffuse_impl(i,j,k) = dh(i,j,k) * g_tracer_com%grid_tmask(i,j,k) * & + (g_tracer%field(i,j,k,tau) - g_tracer%vdiffuse_impl(i,j,k)) / dt + enddo + enddo + enddo + endif + + return + end subroutine g_tracer_vertdiff_M diff --git a/src/postprocessing/land_utils/COPYING b/src/postprocessing/land_utils/COPYING new file mode 100644 index 0000000000..93a221957b --- /dev/null +++ b/src/postprocessing/land_utils/COPYING @@ -0,0 +1,159 @@ +TERMS AND CONDITIONS +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. +1. Source Code. + +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. +2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. +7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. +8. Termination. + +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. +11. Patents. + +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. diff --git a/src/postprocessing/land_utils/combine-ncc.F90 b/src/postprocessing/land_utils/combine-ncc.F90 index b2ddcace80..f4a6009103 100644 --- a/src/postprocessing/land_utils/combine-ncc.F90 +++ b/src/postprocessing/land_utils/combine-ncc.F90 @@ -1,5 +1,13 @@ -! this program reads several input netcdf files, presumably containing "compressed -! by gathering" data, and combines them into a single output file +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +! +! This program reads several input netcdf files, presumably containing +! "compressed by gathering" data, and combines them into a single output file +! +!----------------------------------------------------------------------- + #define __NF_ASRT__(ierr) call nfu_check_err(ierr,__FILE__,__LINE__) program combine_res diff --git a/src/postprocessing/land_utils/decompress-ncc.F90 b/src/postprocessing/land_utils/decompress-ncc.F90 index 5e62fb2c5a..86163fad1c 100644 --- a/src/postprocessing/land_utils/decompress-ncc.F90 +++ b/src/postprocessing/land_utils/decompress-ncc.F90 @@ -1,5 +1,13 @@ -! this program reads several input netcdf files, presumably containing "compressed +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +! +! This program reads several input netcdf files, presumably containing "compressed ! by gathering" data, and combines them into a single output file +! +!----------------------------------------------------------------------- + #define __NF_ASRT__(ierr) call nfu_check_err(ierr,__FILE__,__LINE__) program decompress diff --git a/src/postprocessing/land_utils/env.gaea b/src/postprocessing/land_utils/env.gaea new file mode 100644 index 0000000000..5ca521ef74 --- /dev/null +++ b/src/postprocessing/land_utils/env.gaea @@ -0,0 +1,3 @@ +# ORNL builds explicit fortran interface library +LIBNETCDFF := -lnetcdff +STATIC := -static diff --git a/src/postprocessing/land_utils/env.gfdl-ws b/src/postprocessing/land_utils/env.gfdl-ws new file mode 100644 index 0000000000..723744dad1 --- /dev/null +++ b/src/postprocessing/land_utils/env.gfdl-ws @@ -0,0 +1 @@ +LIBNETCDFF := -lnetcdff diff --git a/src/postprocessing/land_utils/env.pan b/src/postprocessing/land_utils/env.pan new file mode 100644 index 0000000000..52cb634624 --- /dev/null +++ b/src/postprocessing/land_utils/env.pan @@ -0,0 +1,4 @@ +LIBNETCDFF := -lnetcdff + +LIBS2 := +CLIBS2 := diff --git a/src/postprocessing/land_utils/env.zeus b/src/postprocessing/land_utils/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/postprocessing/land_utils/fre-nctools.mk b/src/postprocessing/land_utils/fre-nctools.mk new file mode 100644 index 0000000000..4c7557c304 --- /dev/null +++ b/src/postprocessing/land_utils/fre-nctools.mk @@ -0,0 +1,62 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:28:52 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include ./env.$(SITE) + +CC := icc +CFLAGS := -O3 -g -traceback +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) + +FC := ifort +FFLAGS := -fltconsistency -fno-alias -stack_temps -safe_cray_ptr -ftz -assume byterecl -g -O2 -i4 -real_size 64 -traceback +INCLUDES := -I${NETCDF_HOME}/include +LIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib $(LIBNETCDFF) -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(LIBS2) $(STATIC) + +TARGETS := combine-ncc decompress-ncc is-compressed + +SOURCES := nfu.F90 nfu_compress.F90 + +OBJECTS := $(SOURCES:F90=o) + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +combine-ncc: combine-ncc.o + $(FC) -o $@ $^ $(OBJECTS) $(LIBS) + +combine-ncc.o: combine-ncc.F90 $(OBJECTS) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c $< + +decompress-ncc: decompress-ncc.o + $(FC) -o $@ $^ $(OBJECTS) $(LIBS) + +decompress-ncc.o: decompress-ncc.F90 $(OBJECTS) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c $< + +nfu_compress.o: nfu_compress.F90 nfu.o $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c $< + +nfu.o: nfu.F90 $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c $< + +is-compressed: is-compressed.o + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CLIBS) + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + -rm -f *.o *.mod $(TARGETS) diff --git a/src/postprocessing/land_utils/is-compressed.c b/src/postprocessing/land_utils/is-compressed.c new file mode 100644 index 0000000000..fd4d1671cb --- /dev/null +++ b/src/postprocessing/land_utils/is-compressed.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +#define __NC_ASRT__(ierr) check_error(ierr,__FILE__,__LINE__) + +void usage(const char* name) +{ + printf("==============================================================================\n"); + printf("%s -- tests for compressed-by-gathering variables\n",name); + printf("==============================================================================\n"); + printf("This utility tests if any of the variables in the given netcdf file are \n"); + printf("compressed-by-gathering. It returns 0 if yes, and -1 otherwise. \n"); + + printf("\nFor information of compression, see:"); + printf("http://cf-pcmdi.llnl.gov/documents/cf-conventions/1.5/cf-conventions.html#compression-by-gathering\n"); + + printf("\nUsage:\n"); + printf("%s [-d] [-h] file-name\n", name); + printf(" -d -- adds verbosity to the output\n"); + printf(" -h -- prints this help message and exits\n"); + + printf("\nFor example:\n"); + printf("%s -d cana.res.nc.0000\n", name); + + printf("==============================================================================\n"); +} + +void check_error(int ierr, const char* file, int line) +{ + if (ierr!=NC_NOERR) { + fprintf(stderr,"ERROR :: FILE \"%s\" LINE %d :: %s\n", + file,line,nc_strerror(ierr)); + exit(ierr); + } +} + +int main(int argc, char* argv[]) +{ + int c; + int ncid; // id of netcdf file + int dimid; // dimension id + int varid; // variable id + int attid; // attribute id + int ndims; // number of dimensions + int verbose=0; // level of verbosity + char name[NC_MAX_NAME+1]; + + if(argc<2) { + usage(argv[0]); + return 1; + } + + // parse command-line arguments + while ((c = getopt(argc, argv, "dh")) != -1) + switch (c) { + case 'd': + verbose++; + break; + case 'h': + default: + usage(argv[0]); + return 1; + } + + __NC_ASRT__(nc_open(argv[optind],NC_NOWRITE,&ncid)); + __NC_ASRT__(nc_inq_ndims(ncid,&ndims)); + if (verbose) printf("Found %d dimensions\n",ndims); + for (dimid=0; dimid $nml_name << EOF + &input + filename = '$file', + list_static = $static, + list_nonstatic = $nonstatic, + var0d = $var0d, + var1d = $var1d, + var2d = $var2d, + var3d = $var3d, + var4d = $var4d, + &end +EOF + +list_ncvars < $nml_name + +end +#------------------------- + +# clean up +rm -f $nml_name + diff --git a/src/postprocessing/list_ncvars/list_ncvars.f90 b/src/postprocessing/list_ncvars/list_ncvars.f90 index 2bbcf1f668..90f1b3b6be 100644 --- a/src/postprocessing/list_ncvars/list_ncvars.f90 +++ b/src/postprocessing/list_ncvars/list_ncvars.f90 @@ -1,3 +1,11 @@ +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +! +! This program lists the variables in a netcdf filei +! +!----------------------------------------------------------------------- program list_ncvars diff --git a/src/postprocessing/mppnccombine/COPYING b/src/postprocessing/mppnccombine/COPYING new file mode 100644 index 0000000000..93a221957b --- /dev/null +++ b/src/postprocessing/mppnccombine/COPYING @@ -0,0 +1,159 @@ +TERMS AND CONDITIONS +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. +1. Source Code. + +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. +2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. +7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. +8. Termination. + +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. +11. Patents. + +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. diff --git a/src/postprocessing/mppnccombine/env.gaea b/src/postprocessing/mppnccombine/env.gaea new file mode 100644 index 0000000000..5ca521ef74 --- /dev/null +++ b/src/postprocessing/mppnccombine/env.gaea @@ -0,0 +1,3 @@ +# ORNL builds explicit fortran interface library +LIBNETCDFF := -lnetcdff +STATIC := -static diff --git a/src/postprocessing/mppnccombine/env.gfdl-ws b/src/postprocessing/mppnccombine/env.gfdl-ws new file mode 100644 index 0000000000..723744dad1 --- /dev/null +++ b/src/postprocessing/mppnccombine/env.gfdl-ws @@ -0,0 +1 @@ +LIBNETCDFF := -lnetcdff diff --git a/src/postprocessing/mppnccombine/env.pan b/src/postprocessing/mppnccombine/env.pan new file mode 100644 index 0000000000..52cb634624 --- /dev/null +++ b/src/postprocessing/mppnccombine/env.pan @@ -0,0 +1,4 @@ +LIBNETCDFF := -lnetcdff + +LIBS2 := +CLIBS2 := diff --git a/src/postprocessing/mppnccombine/env.zeus b/src/postprocessing/mppnccombine/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/postprocessing/mppnccombine/fre-nctools.mk b/src/postprocessing/mppnccombine/fre-nctools.mk new file mode 100644 index 0000000000..3ea0df1d85 --- /dev/null +++ b/src/postprocessing/mppnccombine/fre-nctools.mk @@ -0,0 +1,44 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:29:24 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include ./env.$(SITE) + +CC := icc +CFLAGS := -O3 -g -traceback +CFLAGS_O2:= -O2 -g -traceback +INCLUDES := -I${NETCDF_HOME}/include +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) + +TARGETS := mppnccombine + +SOURCES := mppnccombine.c + +OBJECTS := $(SOURCES:c=o) + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +mppnccombine: $(OBJECTS) + $(CC) -o $@ $^ $(CLIBS) + +mppnccombine.o: mppnccombine.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + -rm -f *.o $(TARGETS) diff --git a/src/postprocessing/mppnccombine/mppnccombine.c b/src/postprocessing/mppnccombine/mppnccombine.c index afc1f9f1e5..b90192d253 100644 --- a/src/postprocessing/mppnccombine/mppnccombine.c +++ b/src/postprocessing/mppnccombine/mppnccombine.c @@ -4,6 +4,51 @@ designed to be used as a postprocessor for the parallel I/O programming interface "mpp_io_mod" + V2.2.5: Seth Underwood + Fix for NetCDF files that do not have a time dimension. + V2.2.4: Tushar.Mohan + Round memory footprint to ceiling integral value. + + V2.2.3: Tushar.Mohan + Fixed handling of -k when -x is set. + Print memory estimate in MB when -x is used without -v. + Fixed help message for -k and -x. + If user sets blocking factor > # records (nrecs), set bf to nrecs + + V2.2.2: Tushar.Mohan + Added a -x option to print estimate resident memory footprint and exit + Changed default blocking factor 1, so the combine behaves as the + combine of the past if no "-k" option is set. This is useful + for low-memory nodes. + + V2.2.1: Do not bail out when we cannot write variables to output file. + Instead, issue a warning and set an error condition. Continue + processing. + Fixed bug in allocation of memory for decomposed variables that + only showed up in certain rare input conditions. + Added -M to show memory usage statistics. + Added -V to print version information. + + V2.2: Added record blocking (see, the -k option) to the memory buffering + code. This significantly improves performance, by buffering multiple + records of decomposed variables in memory. Output I/O performance + improves, due to reduced seeks and larger contiguous writes. We also + reduce the number of file open/close operations in the input files + (by the blocking factor), thus we can expect better performance on + file-systems with expensive metadata operations (such as Lustre). + This performance improvement comes at the cost of increased resident + memory size (by the blocking factor). For questions regarding these + changes, contact: Tushar Mohan (Tushar.Mohan) 08/03/2011. + Also added fixes to the following bugs: + - flush_decomp ignored errors, when it was not able to + write variables to the output file. We now exit on such errors. + - when -n and -e are used and files are not present then + the message of the number of files remaining was misleading. + - when a range is specified, and not all files are present, + then the -r option was deleting files properly only when + NumInFiles in set was correct. That may occasionally be + be wrongly set in the input. We now correctly remove files, + nevertheless. V2.1.7: Added option to initialize output variables with a missing_value from the variables of the first input file as suggested by Martin Schmidt (martin.schmidt@io-warnemuende.de) and @@ -34,9 +79,33 @@ Written by Hans Vahlenkamp (Hans.Vahlenkamp) Geophysical Fluid Dynamics Laboratory / NOAA Princeton Forrestal Campus - Last Updated: 05/15/08 */ +/* Algorithm: + there are k records in a block + + for block b: 1 .. N + for file f: 1 .. n + for record r: 1 .. k + Read rec (r) from file (f) + for var v: 1 .. nvars + If var is undecomposed write to output + if var (v) is decomposed: + IF not allocated, allocate memory for var (v), record (r) + write variable (v) into memory buffer + done var + done record + done file + for record r: 1 .. k + for var: 1..nvars + if decomposed variable, flush variable v for rec r to output + done + done + free memory for all variables for all records in block + done block + */ + +#include #include #include #include @@ -44,6 +113,14 @@ #include #include #include +#include + +#ifndef MAX_BF +# define MAX_BF 100 /* maximum blocking factor */ +#endif +#ifndef DEFAULT_BF /* default blocking factor, if none set */ +# define DEFAULT_BF 1 +#endif /* Information structure for a file */ struct fileinfo @@ -71,14 +148,57 @@ struct fileinfo /* Auxiliary function prototypes */ void usage(); int process_file(char *, unsigned char, struct fileinfo *, char *, int *, - int *, int, int, void *[], int, unsigned char, + int *, int *, int*, int, int, int, unsigned char, unsigned char); int process_vars(struct fileinfo *, struct fileinfo *, unsigned char, int *, - int, int, int, void *[], unsigned char, unsigned char); -int flush_decomp(struct fileinfo *, int, int, void *[], unsigned char); + int *, int*, int, int, int, unsigned char, unsigned char); +int flush_decomp(struct fileinfo *, int, int, int, unsigned char); void print_debug(struct fileinfo *, unsigned char); char *nc_type_to_str(nc_type); +static void ***varbuf = NULL; /* Buffers for multiple records of decomposed var */ + +struct rusage ruse; /* structure used to store values from getrusage() */ +static unsigned long maxrss = 0; /* maximum memory used so far in kilobytes */ +static int print_mem_usage = 0; +static unsigned long mem_allocated = 0; /* memory allocated so far */ + +static const char version[] = "2.2.5"; +static const char last_updated[] = "Mar-02-2012"; + +static unsigned long estimated_maxrss = 0; /* see option: -x */ +static int mem_dry_run = 0; /* set if -x option is used */ + +static inline void check_mem_usage(void) { + static long prev_rss = 0; + static long PAGE_SIZE = 0; + long rss = 0; + if (PAGE_SIZE == 0) PAGE_SIZE = sysconf(_SC_PAGESIZE); + if (getrusage(RUSAGE_SELF, &ruse) == 0) rss = ruse.ru_maxrss * PAGE_SIZE; + if (rss == 0) { + /* bug in Linux kernel means resident size is reported 0 */ + FILE * f = fopen("/proc/self/statm", "r"); + if (f != NULL) { + int discard; + fscanf(f, "%d %ld\n", &discard, &rss); + fclose(f); + rss *= PAGE_SIZE; + } + } + if (rss > maxrss) maxrss = rss; + printf("rss=%lu KB, delta=%ld KB, maxrss=%lu KB\n", rss/1024, (rss - prev_rss)/1024, maxrss/1024); + prev_rss = rss; + return; +} + +static void print_estimated_mem_footprint(int verbose) { + if (verbose) { + printf("Estimated peak memory resident size (k=1) : %.1f MB\n", (float)estimated_maxrss/(1024*1024)); + printf("For estimating RSS for a different value of k, multiply above usage by k.\n"); + } + else printf("%.0f\n", ceil((float)estimated_maxrss/(1024*1024))); + return; +} int main(int argc, char *argv[]) { @@ -87,6 +207,7 @@ int main(int argc, char *argv[]) unsigned char removein=0; /* Remove the ".####" decomposed input files? */ int nstart=0; /* PE number of the first input netCDF file */ int nend=(-1); /* PE number of the last input netCDF file */ + int force=0; /* Allows combining of incomplete input filesets */ int headerpad=16384; /* Additional padding at the end of the header */ int format=NC_NOCLOBBER; /* Format of new netCDF output file */ unsigned char missing=0; /* Initialize output variables with */ @@ -100,11 +221,14 @@ int main(int argc, char *argv[]) char infilename[2048]; /* Name of an input file */ unsigned char infileerror=0; /* Errors reading an input file */ unsigned char infileerrors=0; /* Errors reading any input files */ + unsigned char outfileerrors=0; /* error in output file writing */ int nfiles=(-1); /* Number of files in the decomposed domain */ - int a, f, r; /* Loop variables */ + int a, f, r, block, k, v; /* Loop variables */ int status; /* Return status */ int nrecs=1; /* Number of records in each decomposed file */ - void *varbuf[NC_MAX_VARS]; /* Buffers for decomposed variables */ + int bf=DEFAULT_BF; /* default blocking factor: bf records will be read and written at a time */ + int nblocks=1; /* nblocks=nrecs/bf = number of iterations of outer loop */ + int peWidth = -1; /* Width of PE number in uncombined file extension */ size_t blksz=65536; /* netCDF block size */ /* Check the command-line arguments */ @@ -116,8 +240,18 @@ int main(int argc, char *argv[]) { if (!strcmp(argv[a],"-v")) verbose=1; else if (!strcmp(argv[a],"-vv")) verbose=2; /* Hidden debug mode */ + else if (!strcmp(argv[a],"-V")) { + fprintf(stderr, "mppnccombine version: %s\n", version); + fprintf(stderr, "Last updated: %s\n", last_updated); + exit(0); + } + else if (!strcmp(argv[a],"-M")) print_mem_usage=1; + else if (!strcmp(argv[a],"-x")) { + mem_dry_run=1; + } else if (!strcmp(argv[a],"-a")) appendnc=1; else if (!strcmp(argv[a],"-r")) removein=1; + else if (!strcmp(argv[a],"-f")) force=1; else if (!strcmp(argv[a],"-n")) { a++; @@ -127,6 +261,21 @@ int main(int argc, char *argv[]) usage(); return(1); } } + else if (!strcmp(argv[a],"-k")) + { + a++; + if (a < argc) bf=atoi(argv[a]); + else + { + usage(); return(1); + } + if (mem_dry_run) continue; + if (bf > MAX_BF) + { + fprintf(stderr, "Warning: k is set to high. Choosing a more sane value of %d.\n", MAX_BF); + bf = MAX_BF; + } + } else if (!strcmp(argv[a],"-e")) { a++; @@ -167,112 +316,210 @@ int main(int argc, char *argv[]) if (!strcmp(strptr,".0000")) outfilename[outlen-5]='\0'; } + + /* if -x (estimate memory usage) is set, k will be automatically set to 1 */ + if (mem_dry_run) { + if (bf != 1) fprintf(stderr, "-x is set, so blocking factor will be set to 1. The -k option will be ignored.\n"); + bf = 1; + if (verbose) printf("This run will estimate peak memory resident size. No output file will be created.\n"); + } + /* Disable fatal returns from netCDF library functions */ ncopts=0; - /* Create a new netCDF output file */ - if ((ncoutfile=(struct fileinfo *)malloc(sizeof(struct fileinfo)))==NULL) - { - fprintf(stderr,"Error: cannot allocate enough memory!\n"); return(1); - } - if (!appendnc) - { - if (stat(outfilename,&statbuf)==0) - { - fprintf(stderr,"Error: output file seems to exist already!\n"); - free(ncoutfile); return(1); - } - status = nc__create(outfilename, format, 0, &blksz, &ncoutfile->ncfid); - if (status==(-1)) - { - fprintf(stderr,"Error: cannot create the output netCDF file!\n"); - free(ncoutfile); return(1); - } - ncsetfill(ncoutfile->ncfid,NC_NOFILL); - } - /* Open an existing netCDF file for appending */ - else - { - if ((ncoutfile->ncfid=ncopen(outfilename,NC_WRITE))==(-1)) - { - fprintf(stderr,"Error: cannot open the output netCDF file for appending!\n"); - free(ncoutfile); return(1); - } - } - - for (f=0; f < NC_MAX_VARS; f++) - varbuf[f]=NULL; + if (!mem_dry_run) { + /* Create a new netCDF output file */ + if ((ncoutfile=(struct fileinfo *)malloc(sizeof(struct fileinfo)))==NULL) + { + fprintf(stderr,"Error: cannot allocate enough memory!\n"); return(1); + } + if (!appendnc) + { + if (stat(outfilename,&statbuf)==0) + { + fprintf(stderr,"Error: output file seems to exist already!\n"); + free(ncoutfile); return(1); + } + status = nc__create(outfilename, format, 0, &blksz, &ncoutfile->ncfid); + if (status==(-1)) + { + fprintf(stderr,"Error: cannot create the output netCDF file!\n"); + free(ncoutfile); return(1); + } + ncsetfill(ncoutfile->ncfid,NC_NOFILL); + } + /* Open an existing netCDF file for appending */ + else + { + if ((ncoutfile->ncfid=ncopen(outfilename,NC_WRITE))==(-1)) + { + fprintf(stderr,"Error: cannot open the output netCDF file for appending!\n"); + free(ncoutfile); return(1); + } + } + } /* No input files are specified on the command-line */ if (inputarg==(-1)) { + int num_infiles_used = 0; /* we may use only a subset of the input files */ if (nend > -1) - for (r=0; r < nrecs; r++) + for (block=0; block < nblocks; block++) { - if (verbose) printf("record = %d\n",r); + if (verbose) printf("block = %d\n",block); f=0; for (a=nstart; a <= nend; a++) { - sprintf(infilename,"%s.%04d",outfilename,a); + if (peWidth<0) + { + sprintf(infilename,"%s.%04d",outfilename,a); + if (stat(infilename,&statbuf)==0) + { + peWidth=4; + } + else + { + sprintf(infilename,"%s.%06d",outfilename,a); + if (stat(infilename,&statbuf)==0) + { + peWidth=6; + } + else + { + continue; + } + } + } + sprintf(infilename,"%s.%0*d",outfilename,peWidth,a); + if (stat(infilename,&statbuf)!=0){ + if (force==0) { + printf("ERROR: missing at least %s from the input fileset. Exiting.\n", infilename); + unlink(outfilename); + return 9; + }else{ + infileerrors=1; + } + } if (verbose) { - if (a==nstart && r==0) printf(" n files to go... "); - else printf(" %d files to go... ",nend-nstart+1-f); + if (block==0) printf(" n files to go... "); + else printf(" %d files to go... ",num_infiles_used-f); printf("processing \"%s\"\n",infilename); } - if (stat(infilename,&statbuf)!=0) continue; infileerror=process_file(infilename,appendnc,ncoutfile, - outfilename,&nfiles,&nrecs,r,f,varbuf, + outfilename,&nfiles,&nrecs,&nblocks,&bf,block,f, headerpad,verbose,missing); if (infileerror) infileerrors=1; appendnc=1; f++; if (f==nfiles || a==nend) { + if (mem_dry_run) { + print_estimated_mem_footprint(verbose); + exit(0); + } if (verbose > 1) printf(" Write variables from previous %d files\n",f); - flush_decomp(ncoutfile,nfiles,r,varbuf,verbose); + for (r=block * bf; r 0) nend=nstart+nfiles; appendnc=1; f++; if (f==nfiles || a==(nend-1)) { + if (mem_dry_run) { + print_estimated_mem_footprint(verbose); + exit(0); + } if (verbose > 1) printf(" Write variables from previous %d files\n",f); - flush_decomp(ncoutfile,nfiles,r,varbuf,verbose); + for (r=block*bf; r 1) printf(" Write variables from previous %d files\n",f); - flush_decomp(ncoutfile,nfiles,r,varbuf,verbose); + for (r=block*bf; rncfid); free(ncoutfile); - if (!infileerrors) + if ((!infileerrors) && (!outfileerrors)) { if (removein) { @@ -313,8 +577,32 @@ int main(int argc, char *argv[]) f=0; for (a=nstart; a <= nend; a++) { - if (++f > nfiles) break; - sprintf(infilename,"%s.%04d",outfilename,a); + // commenting line below, as it's a bug + // occasionally nfiles may be wrongly set to zero, + // and yet the user wants to remove the input files in a range. + //if (++f > nfiles) break; + if (peWidth<0) + { + sprintf(infilename,"%s.%04d",outfilename,a); + if (stat(infilename,&statbuf)==0) + { + peWidth=4; + } + else + { + sprintf(infilename,"%s.%06d",outfilename,a); + if (stat(infilename,&statbuf)==0) + { + peWidth=6; + } + else + { + continue; + } + } + } + sprintf(infilename,"%s.%0*d",outfilename,peWidth,a); + if (stat(infilename,&statbuf)!=0) continue; if (verbose) printf("Removing \"%s\"\n",infilename); unlink(infilename); } @@ -323,6 +611,7 @@ int main(int argc, char *argv[]) else for (a=inputarg; a < argc; a++) { + if (stat(argv[a],&statbuf)!=0) continue; if (verbose) printf("Removing \"%s\"\n",argv[a]); unlink(argv[a]); } @@ -337,20 +626,41 @@ int main(int argc, char *argv[]) /* Print the usage message for mppnccombine */ void usage() { - printf("mppnccombine 2.1.7 - (written by Hans.Vahlenkamp)\n\n"); - printf("Usage: mppnccombine [-v] [-a] [-r] [-n #] [-e #] [-h #] [-64] [-n4] [-m]\n"); + printf("mppnccombine %s - (written by Hans.Vahlenkamp)\n\n", version); + printf("Usage: mppnccombine [-v] [-V] [-M] [-a] [-r] [-n #] [-k #] [-e #] [-h #] [-64] [-n4] [-m]\n"); printf(" output.nc [input ...]\n\n"); printf(" -v Print some progress information.\n"); + printf(" -V Print version information.\n"); + printf(" -M Print memory usage statistics.\n"); + printf(" -f Force combine to happen even if input files are missing.\n"); printf(" -a Append to an existing netCDF file (not heavily tested...).\n"); printf(" -r Remove the \".####\" decomposed files after a successful run.\n"); printf(" -n # Input filename extensions start with number #### instead of 0000.\n"); + printf(" -k # Blocking factor. k records are read from an input file at a time.\n"); + printf(" Valid values are between 0 and %d. For a given input, the maximum\n", MAX_BF); + printf(" permissible value for k is min(total number of records, %d).\n", MAX_BF); + printf(" Setting k to zero will set the blocking factor to this maximum\n"); + printf(" permissible value. Setting k to a value higher than this value,\n"); + printf(" will make the system implictly set k to the highest permissible value.\n"); + printf(" A value of 1 for k disables blocking. This is the default behavior.\n"); + printf(" Blocking often improves performance, but increases the peak memory\n"); + printf(" footprint (by the blocking factor). Beware of running out of\n"); + printf(" available physical memory and causing swapping to disk due to\n"); + printf(" large blocking factors and/or large input datasets.\n"); + printf(" A value of 10 for k has worked well on many input datasets.\n"); + printf(" See -x for estimating memory usage for a given input set.\n"); printf(" -e # Ending number #### of a specified range of input filename extensions.\n"); printf(" Files within the range do not have to be consecutively numbered.\n"); printf(" -h # Add a specified number of bytes of padding at the end of the header.\n"); printf(" -64 Create netCDF output files with the 64-bit offset format.\n"); printf(" -n4 Create netCDF output files in NETCDF4_CLASSIC mode (no v4 enhanced features).\n"); printf(" -m Initialize output variables with a \"missing_value\" from the variables\n"); - printf(" of the first input file instead of the default 0 value.\n\n"); + printf(" of the first input file instead of the default 0 value.\n"); + printf(" -x Print an estimate for peak memory resident size in (MB) and exit.\n"); + printf(" No output file will be created. Setting -x automatically sets\n"); + printf(" the blocking factor (-k) to 1. Any value set for -k on the\n"); + printf(" command-line will be ignored. To estimate memory usage for a\n"); + printf(" a different blocking factor, simply multiply the estimate by k.\n\n"); printf("mppnccombine joins together an arbitrary number of netCDF input files, each\n"); printf("containing parts of a decomposed domain, into a unified netCDF output file.\n"); printf("An output file must be specified and it is assumed to be the first filename\n"); @@ -367,12 +677,19 @@ void usage() } +inline int min(int a, int b) +{ + if (anvars=ncinfile->nvars; ncoutfile->recdim=ncinfile->recdim; } @@ -460,12 +779,14 @@ int process_file(char *ncname, unsigned char appendnc, if (ncattget(ncinfile->ncfid,v,"domain_decomposition", (void *)decomp)!=(-1)) { + /* the dimension is decomposed */ ncinfile->dimfullsize[dimid]=decomp[1]-decomp[0]+1; ncinfile->dimstart[dimid]=decomp[2]-(decomp[0]-1); ncinfile->dimend[dimid]=decomp[3]-(decomp[0]-1); } else { + /* the dimension is NOT decomposed */ ncinfile->dimfullsize[dimid]=ncinfile->dimsize[dimid]; ncinfile->dimstart[dimid]=1; ncinfile->dimend[dimid]=(-1); } @@ -475,10 +796,16 @@ int process_file(char *ncname, unsigned char appendnc, /* Get some additional information about the variables */ for (v=0; v < ncinfile->nvars; v++) { - /* Does the variable have a decomposed dimension? */ + + /* start by assuming the variable has no decomposed dimension */ ncinfile->vardecomp[v]=0; + + /* now, iterate over the variable's dimensions and mark the */ + /* variable as a decomposed variable if any dimension of */ + /* the variable is decomposed */ for (d=0; d < ncinfile->varndims[v]; d++) { + /* Does the variable have a decomposed dimension? */ if (ncinfile->dimend[ncinfile->vardim[v][d]]!=(-1)) { ncinfile->vardecomp[v]=1; break; @@ -486,7 +813,8 @@ int process_file(char *ncname, unsigned char appendnc, } /* Save some information for the output file */ - if (r==0) + /* This only needs to be done once per output file */ + if ((block==0) && (!mem_dry_run)) { ncoutfile->varndims[v]=ncinfile->varndims[v]; for (d=0; d < ncinfile->ndims; d++) @@ -500,7 +828,7 @@ int process_file(char *ncname, unsigned char appendnc, } /* If the output netCDF file was just created then define its structure */ - if (!appendnc) + if ((!appendnc) && (!mem_dry_run)) { if (verbose) printf(" Creating output \"%s\"\n",outncname); @@ -567,23 +895,38 @@ int process_file(char *ncname, unsigned char appendnc, } /* Copy all data values of the dimensions and variables to memory */ - ncinfileerror=process_vars(ncinfile,ncoutfile,appendnc,nrecs,r,*nfiles, - f,varbuf,verbose,missing); + /* For non-decomposed variables, process_vars will write them to the */ + /* output file. Decomposed variables for N records from this file will */ + /* be written to memory, where they will eventually get merged with those */ + /* from other input files */ + int r = block * (*bf); // the position of r is absolute + unsigned long mem_for_rec, tmp_mem_alloc; + do + { + tmp_mem_alloc = mem_allocated; /* store current memory usage in a temporary */ + ncinfileerror+=process_vars(ncinfile,ncoutfile,appendnc,nrecs,nblocks,bf,r,*nfiles, + f,verbose,missing); + mem_for_rec= mem_allocated - tmp_mem_alloc; + if (verbose && print_mem_usage) + if (mem_for_rec > 0) printf(" mem alloc for r=%d, infile=%s is %lu KB\n", r, ncname, mem_for_rec/1024); + r++; + appendnc = 1; + } while (rncfid); free(ncinfile); return(ncinfileerror); } -/* Copy all data values in an input file at the current record to memory */ +/* Decomposed variables from an input file and record will be written to memory */ +/* non-decomposed variables will be written to the output file */ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, - unsigned char appendnc, int *nrecs, int r, int nfiles, - int f, void *varbuf[], unsigned char verbose, - unsigned char missing) + unsigned char appendnc, int *nrecs, int *nblocks, int* bf, int r, int nfiles, + int f, unsigned char verbose, unsigned char missing) { int v, d, i, j, k, l, b, s; /* Loop variables */ int dimid; /* ID of a dimension */ - void *values; /* Current data values */ + void *values = NULL; /* Current data values */ long instart[MAX_NC_DIMS], outstart[MAX_NC_DIMS]; /* Data array sizes */ long count[MAX_NC_DIMS]; /* " */ long long recsize; /* Decomposed size of one record of a variable */ @@ -594,17 +937,82 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, int imaxfull, jmaxfull, kmaxfull, lmaxfull; int imaxjmaxfull, imaxjmaxkmaxfull; int offset, ioffset, joffset, koffset, loffset; + int recdimsize; /* Using a local recdimsize to correct issue when netcdf file does not have a record dimension */ long long varbufsize; + if ( ncinfile->recdim < 0 ) + recdimsize=1; + else + recdimsize=ncinfile->dimsize[ncinfile->recdim]; + /* Check the number of records */ - if (*nrecs==1) *nrecs=ncinfile->dimsize[ncinfile->recdim]; + if (*nrecs==1) + { + *nrecs=recdimsize; + + if ((*bf) >= 1) + { + if ((*bf) > (*nrecs)) { + fprintf(stderr, "blocking factor (k) > total records (%d). Setting blocking factor to %d.\n", + *nrecs, *nrecs); + *bf = *nrecs; + } + if (((*nrecs) % (*bf)) != 0) *nblocks = (int)((*nrecs)/(*bf)) + 1; + else *nblocks = (int)((*nrecs)/(*bf)); + } + else + { + /* bf was set to zero, so we do full buffering */ + *bf = min(MAX_BF,*nrecs); // we use the maximum blocking factor in our capacity + /* normally we'll have one block, unless we hit MAX_BF */ + *nblocks = (int)((*nrecs)/(*bf)); + } + if (verbose) fprintf(stderr, "blocking factor=%d, num. blocks=%d, num. records=%d\n",*bf,*nblocks, *nrecs); + } else - if (ncinfile->dimsize[ncinfile->recdim] != *nrecs) + if (recdimsize != *nrecs) { fprintf(stderr,"Error: different number of records than the first input file!\n"); return(1); } + /* Allocate memory for the decomposed variables, if none has been allocated yet + We use an optimized algorithm to malloc and set up a double dimension array + using a single malloc call. We do the cross-linking after the malloc, so + the entire allocation appears to be a double-dimensional array. The memory + allocated below is a trivial amount. The real allocation will happen later. + This allocation is done exactly once in the whole program */ + if (varbuf == NULL) { + int nbytes = (*bf)*sizeof(void**) + ((*bf) * MAX_NC_VARS* sizeof(void *)); + if (verbose || print_mem_usage) fprintf(stderr, "allocating a buffer of %d bytes for the multi-dimensional pointer array\n", nbytes); + if (mem_dry_run) estimated_maxrss += nbytes; + varbuf = (void ***)calloc(nbytes, 1); + if (varbuf == NULL) { + fprintf(stderr, "Could not allocate a memory of size %lu bytes\n", sizeof(void*)*(*bf)*MAX_NC_VARS); + exit(1); + } + /* now initialize the buffer to create a mult-dimensional array */ + int z; + for (z=0; z<(*bf); z++) { + varbuf[z] = (void**) ((size_t)varbuf + (*bf)*sizeof(void**) + z*MAX_NC_VARS*sizeof(void*)); + } + /* The nested memory alloc works fine, but it involves multiple malloc calls. + varbuf = (void ***)malloc((*bf) * sizeof(void **)); + if (varbuf == NULL) { + fprintf(stderr, "Could not allocate memory\n"); + exit(1); + } + int z; + for (z=0; z<(*bf); z++) { + varbuf[z] = calloc(MAX_NC_VARS*sizeof(void*),1); + if (varbuf == NULL) { + fprintf(stderr, "Could not allocate memory\n"); + exit(1); + } + } + */ + } /* end of memory allocation, done once per block */ + /* Loop over all the variables */ for (v=0; v < ncinfile->nvars; v++) { @@ -679,7 +1087,7 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, } /* Write the buffered variable immediately if it's not decomposed */ - if (ncinfile->vardecomp[v]!=1) + if ((ncinfile->vardecomp[v]!=1) && (!mem_dry_run)) { if (verbose > 1) printf(" writing %lld bytes to file\n", @@ -695,52 +1103,62 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, else { /* Allocate a buffer for the variable's non-decomposed record size */ - if (first) + /* rather than checking for whether this is the first file, and so */ + /* we do this once per record per variable for each block */ + /* if (f==0) */ + if (varbuf[(r % (*bf))][v] == NULL) { varbufsize=nctypelen(ncinfile->datatype[v])*recfullsize; - if (verbose > 1) - printf(" allocating %lld bytes for full domain\n", - varbufsize); - if ((varbuf[v]=calloc(varbufsize,1))==NULL) + if (verbose && print_mem_usage) + printf(" allocating %lld bytes for full domain of variable %s\n", + varbufsize, ncinfile->varname[v]); + if (mem_dry_run) { + estimated_maxrss += varbufsize; + varbuf[(r % (*bf))][v] = "deadbeef"; + continue; + } + if ((varbuf[(r % (*bf))][v]=calloc(varbufsize,1))==NULL) { fprintf(stderr,"Error: cannot allocate %lld bytes for entire variable \"%s\"'s values!\n", varbufsize,ncinfile->varname[v]); return(1); } + mem_allocated += varbufsize; if (missing && ncoutfile->varmiss[v]) switch (ncinfile->datatype[v]) { case NC_BYTE: case NC_CHAR: for (s=0; s < recfullsize; s++) - *((unsigned char *)(varbuf[v])+s)= + *((unsigned char *)(varbuf[(r % (*bf))][v])+s)= *((unsigned char *)(ncoutfile->varmissval[v])); break; case NC_SHORT: for (s=0; s < recfullsize; s++) - *((short *)(varbuf[v])+s)= + *((short *)(varbuf[(r % (*bf))][v])+s)= *((short *)(ncoutfile->varmissval[v])); break; case NC_INT: for (s=0; s < recfullsize; s++) - *((int *)(varbuf[v])+s)= + *((int *)(varbuf[(r % (*bf))][v])+s)= *((int *)(ncoutfile->varmissval[v])); break; case NC_FLOAT: for (s=0; s < recfullsize; s++) - *((float *)(varbuf[v])+s)= + *((float *)(varbuf[(r % (*bf))][v])+s)= *((float *)(ncoutfile->varmissval[v])); break; case NC_DOUBLE: for (s=0; s < recfullsize; s++) - *((double *)(varbuf[v])+s)= + *((double *)(varbuf[(r % (*bf))][v])+s)= *((double *)(ncoutfile->varmissval[v])); break; } } - if (varbuf[v]==NULL) + if (varbuf[(r % (*bf))][v]==NULL) { - fprintf(stderr,"Internal memory usage error!\n"); return(1); + fprintf(stderr,"Internal memory usage error!\n"); exit(1); } + if (mem_dry_run) continue; if (verbose > 1) printf(" writing %lld bytes to memory\n", nctypelen(ncinfile->datatype[v])*recsize); @@ -837,7 +1255,7 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, (j+joffset)*imaxfull+ (k+koffset)*imaxjmaxfull+ (l+loffset)*imaxjmaxkmaxfull; - *((unsigned char *)(varbuf[v])+offset)= + *((unsigned char *)(varbuf[(r % (*bf))][v])+offset)= *((unsigned char *)values+(b++)); } if (verbose > 1) printf(" end copying byte/char\n"); @@ -854,7 +1272,7 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, (j+joffset)*imaxfull+ (k+koffset)*imaxjmaxfull+ (l+loffset)*imaxjmaxkmaxfull; - *((short *)(varbuf[v])+offset)= + *((short *)(varbuf[(r % (*bf))][v])+offset)= *((short *)values+(b++)); } if (verbose > 1) printf(" end copying short\n"); @@ -871,7 +1289,7 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, (j+joffset)*imaxfull+ (k+koffset)*imaxjmaxfull+ (l+loffset)*imaxjmaxkmaxfull; - *((int *)(varbuf[v])+offset)= + *((int *)(varbuf[(r % (*bf))][v])+offset)= *((int *)values+(b++)); } if (verbose > 1) printf(" end copying int\n"); @@ -888,7 +1306,7 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, (j+joffset)*imaxfull+ (k+koffset)*imaxjmaxfull+ (l+loffset)*imaxjmaxkmaxfull; - *((float *)(varbuf[v])+offset)= + *((float *)(varbuf[(r % (*bf))][v])+offset)= *((float *)values+(b++)); } if (verbose > 1) printf(" end copying float\n"); @@ -905,7 +1323,7 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, (j+joffset)*imaxfull+ (k+koffset)*imaxjmaxfull+ (l+loffset)*imaxjmaxkmaxfull; - *((double *)(varbuf[v])+offset)= + *((double *)(varbuf[(r % (*bf))][v])+offset)= *((double *)values+(b++)); } if (verbose > 1) printf(" end copying double\n"); @@ -914,15 +1332,14 @@ int process_vars(struct fileinfo *ncinfile, struct fileinfo *ncoutfile, } /* Deallocate the decomposed variable's buffer */ - free(values); + if (values != NULL) free(values); } first=0; return(0); } /* Write all the buffered decomposed variables to the output file */ -int flush_decomp(struct fileinfo *ncoutfile, int nfiles, int r, - void *varbuf[], unsigned char verbose) +int flush_decomp(struct fileinfo *ncoutfile, int nfiles, int r, int bf, unsigned char verbose) { int v, d; /* Loop variable */ long outstart[MAX_NC_DIMS]; /* Data array sizes */ @@ -959,7 +1376,7 @@ int flush_decomp(struct fileinfo *ncoutfile, int nfiles, int r, if (varrecdim==(-1) && r > 0) continue; if (verbose > 1) printf(" writing to disk\n"); - if (ncvarput(ncoutfile->ncfid,v,outstart,count,varbuf[v])==(-1)) + if (ncvarput(ncoutfile->ncfid,v,outstart,count,varbuf[(r % bf)][v])==(-1)) { fprintf(stderr,"Error: cannot write variable \"%d\"'s values!\n", v); return(1); diff --git a/src/postprocessing/plevel/COPYING b/src/postprocessing/plevel/COPYING new file mode 100644 index 0000000000..93a221957b --- /dev/null +++ b/src/postprocessing/plevel/COPYING @@ -0,0 +1,159 @@ +TERMS AND CONDITIONS +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. +1. Source Code. + +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. +2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. +7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. +8. Termination. + +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. +11. Patents. + +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. diff --git a/src/postprocessing/plevel/env.gaea b/src/postprocessing/plevel/env.gaea new file mode 100644 index 0000000000..5ca521ef74 --- /dev/null +++ b/src/postprocessing/plevel/env.gaea @@ -0,0 +1,3 @@ +# ORNL builds explicit fortran interface library +LIBNETCDFF := -lnetcdff +STATIC := -static diff --git a/src/postprocessing/plevel/env.gfdl-ws b/src/postprocessing/plevel/env.gfdl-ws new file mode 100644 index 0000000000..723744dad1 --- /dev/null +++ b/src/postprocessing/plevel/env.gfdl-ws @@ -0,0 +1 @@ +LIBNETCDFF := -lnetcdff diff --git a/src/postprocessing/plevel/env.pan b/src/postprocessing/plevel/env.pan new file mode 100644 index 0000000000..52cb634624 --- /dev/null +++ b/src/postprocessing/plevel/env.pan @@ -0,0 +1,4 @@ +LIBNETCDFF := -lnetcdff + +LIBS2 := +CLIBS2 := diff --git a/src/postprocessing/plevel/env.zeus b/src/postprocessing/plevel/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/postprocessing/plevel/fre-nctools.mk b/src/postprocessing/plevel/fre-nctools.mk new file mode 100644 index 0000000000..a3cee18bb7 --- /dev/null +++ b/src/postprocessing/plevel/fre-nctools.mk @@ -0,0 +1,85 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:29:51 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include ./env.$(SITE) + +FC := ifort +FFLAGS := -module ./modules.r8 -fltconsistency -fno-alias -stack_temps -safe_cray_ptr -ftz -assume byterecl -g -O2 -i4 -real_size 64 -traceback +FFLAGS_r4:= -module ./modules.r4 -fltconsistency -fno-alias -stack_temps -safe_cray_ptr -ftz -assume byterecl -g -O2 -i4 -real_size 32 -traceback +INCLUDES := -I${NETCDF_HOME}/include +LIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib $(LIBNETCDFF) -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(LIBS2) $(STATIC) + +TARGETS := PLEV.exe PLEV.r4.exe + +OBJECTS := plev_constants.o moisture_convert.o pressure_interp.o pinterp_utilities.o +OBJECTS_r4= plev_constants.r4.o moisture_convert.r4.o pressure_interp.r4.o pinterp_utilities.r4.o + +MODULES := modules.r8 +MODULES_r4 := modules.r4 + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +PLEV.exe: run_pressure_interp.o + $(FC) -o $@ $^ $(OBJECTS) $(LIBS) + +run_pressure_interp.o: run_pressure_interp.F90 $(OBJECTS) $(MODULES) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +PLEV.r4.exe: run_pressure_interp.r4.o + $(FC) -o $@ $^ $(OBJECTS) $(LIBS) + +run_pressure_interp.r4.o: run_pressure_interp.F90 $(OBJECTS_r4) $(MODULES_r4) $(HEADERS) + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +pinterp_utilities.o: pinterp_utilities.F90 $(MODULES) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +pinterp_utilities.r4.o: pinterp_utilities.F90 $(MODULES_r4) $(HEADERS) + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +pressure_interp.o: pressure_interp.F90 moisture_convert.o plev_constants.o $(MODULES) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +pressure_interp.r4.o: pressure_interp.F90 moisture_convert.r4.o plev_constants.r4.o $(MODULES_r4) $(HEADERS) + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +moisture_convert.o: moisture_convert.F90 plev_constants.o $(MODULES) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +moisture_convert.r4.o: moisture_convert.F90 plev_constants.r4.o $(MODULES_r4) $(HEADERS) + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +plev_constants.o: plev_constants.F90 $(MODULES) $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +plev_constants.r4.o: plev_constants.F90 $(MODULES_r4) $(MODULES_r4) $(HEADERS) + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +modules.r8: + mkdir -p ./modules.r8 + +modules.r4: + mkdir -p ./modules.r4 + +%.o: %.F90 + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +%.r4..o: %.F90 + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +clean: + -rm -rf *.o *.mod $(TARGETS) $(MODULES) $(MODULES_r4) diff --git a/src/postprocessing/plevel/moisture_convert.F90 b/src/postprocessing/plevel/moisture_convert.F90 index 439eed865f..f31d3adc0d 100644 --- a/src/postprocessing/plevel/moisture_convert.F90 +++ b/src/postprocessing/plevel/moisture_convert.F90 @@ -1,3 +1,8 @@ +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +!----------------------------------------------------------------------- module moisture_convert_mod diff --git a/src/postprocessing/plevel/pinterp_utilities.F90 b/src/postprocessing/plevel/pinterp_utilities.F90 index e073f74a8f..bf0961167a 100644 --- a/src/postprocessing/plevel/pinterp_utilities.F90 +++ b/src/postprocessing/plevel/pinterp_utilities.F90 @@ -223,7 +223,8 @@ subroutine put_missing_value ( ncid, varid, xtype, missval ) integer, intent(in) :: ncid, varid, xtype real, intent(in) :: missval - integer :: istat + integer :: istatmiss + integer :: istatfill ! machine dependent data kind integer(2) :: imiss2 integer(4) :: imiss4 @@ -235,21 +236,26 @@ subroutine put_missing_value ( ncid, varid, xtype, missval ) select case (xtype) case (NF90_REAL4) miss4 = missval - istat = NF90_PUT_ATT (ncid, varid, 'missing_value', miss4) + istatmiss = NF90_PUT_ATT (ncid, varid, 'missing_value', miss4) + istatfill = NF90_PUT_ATT (ncid, varid, '_FillValue', miss4) case (NF90_INT2) imiss2 = nint(missval) - istat = NF90_PUT_ATT (ncid, varid, 'missing_value', imiss2) + istatmiss = NF90_PUT_ATT (ncid, varid, 'missing_value', imiss2) + istatfill = NF90_PUT_ATT (ncid, varid, '_FillValue', imiss2) case (NF90_INT) imiss4 = nint(missval) - istat = NF90_PUT_ATT (ncid, varid, 'missing_value', imiss4) + istatmiss = NF90_PUT_ATT (ncid, varid, 'missing_value', imiss4) + istatfill = NF90_PUT_ATT (ncid, varid, '_FillValue', imiss4) case (NF90_REAL8) miss8 = missval - istat = NF90_PUT_ATT (ncid, varid, 'missing_value', miss8) + istatmiss = NF90_PUT_ATT (ncid, varid, 'missing_value', miss8) + istatfill = NF90_PUT_ATT (ncid, varid, '_FillValue', miss8) case default call error_handler ('invalid xtype for missing value') end select - if (istat /= NF90_NOERR) call error_handler ('putting missing value', ncode=istat) + if (istatmiss /= NF90_NOERR) call error_handler ('putting missing value', ncode=istatmiss) + if (istatfill /= NF90_NOERR) call error_handler ('putting fill value', ncode=istatfill) end subroutine put_missing_value diff --git a/src/postprocessing/plevel/plev_constants.F90 b/src/postprocessing/plevel/plev_constants.F90 index 6d599709bd..ee8bc613cb 100644 --- a/src/postprocessing/plevel/plev_constants.F90 +++ b/src/postprocessing/plevel/plev_constants.F90 @@ -1,3 +1,9 @@ +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +!----------------------------------------------------------------------- + module plev_constants_mod implicit none private diff --git a/src/postprocessing/plevel/plevel.sh b/src/postprocessing/plevel/plevel.sh new file mode 100755 index 0000000000..6d902c5e44 --- /dev/null +++ b/src/postprocessing/plevel/plevel.sh @@ -0,0 +1,184 @@ +#!/bin/sh +# +# $Id: plevel.sh,v 20.0 2013/12/14 00:29:52 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Script to Call Converters to Pressure Levels +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Copied from ~fms/local/ia64/netcdf4.fix June 10 +# afy Ver 1.00 Don't source the 'init.sh' script June 10 +# afy Ver 1.01 Use 'which' to locate executables June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2000-2010 +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# + +fields= +more_output=1 +ofile=plevel.nc +ifiles= +do_all_3d_fields=.false. +do_all_fields=.false. +allow_zero=.false. +default_missval=.false. +mask_extrap=.true. +tlist= + +# default is ncep reanalysis levels +plevs="100000 92500 85000 70000 60000 50000 40000 30000 25000 \ + 20000 15000 10000 7000 5000 3000 2000 1000" + +#----------------------------------------------------------------------- + +while getopts 03amxi:o:d:p:t: arg +do + case $arg in + 0) allow_zero=.true.;; + 3) do_all_3d_fields=.true.;; + a) do_all_fields=.true.;; + m) default_missval=.true.;; + x) mask_extrap=.false.;; + i) ifiles=$OPTARG;; + o) ofile=$OPTARG;; + d) more_output=$OPTARG;; + p) plevs=$OPTARG;; + t) tlist=$OPTARG;; + *) exit 1;; + esac +done +shift `expr $OPTIND - 1` +fields=$@ + +#----------------------------------------------------------------------- + +if [ "${ifiles:-NULL}" = "NULL" ]; then +name=`basename $0` +cat << EOF + +Interpolates data from model levels to pressure levels. +The input model grid is a hybrid sigma-pressure coordinate +and the output pressure levels may be specified. +The minimum required input fields are "bk", "pk", and "ps". + +Usage: $name [-a] [-3] [-0] [-f] [-d #] -i file [-o ofile] [-m] [fields.....] + + -a = Output all fields converting 3d fields to pressure levels. + -3 = Output and convert all 3d fields to pressure levels. + -0 = When fields sphum or zsurf do not exist use zero, otherwise fail. + -m = Default missing value is used for all fields (the _FillValue). + -x = DO NOT set data extrapolated beneath the surface to missing values. + -i file = Input netcdf file, the file must contain the required variables + (pk,bk,ps,...). + If the -i files option is omitted a usage message is printed. + -o ofile = The output file name. (Default: plevel.nc) + -p plevs = A list of output pressure levels in pascals (with no decimal point). + The default is the 17 NCEP reananalysis levels (bottom to top). + The list must be in quotes and values must be separated by a space. + -d value The verbosity level, use an integer number where value >= 0. + (Default: value=1) + -t #,#,# The starting, ending, and increment index for time axis processing + where # is a positive number. + (The default is to process all time indices.) + + fields = A list of (additional) output fields. If this list is not supplied, + then the "-a" or "-3" option must be specified. Possible list entries + included any fields in the input files, and additional fields: slp, hght. + Additional input fields may be required for these output fields. + +Example: $name -a -i atmos.nc slp hght + +EOF +exit 1 +fi + +# location of executable +executable=`which PLEV.exe` + +if [ ! -x "$executable" ]; then + echo "ERROR: executable does not exist" + echo " executable=$executable" + exit 1 +fi + +# make sure input files are present + +list= +for file in $ifiles; +do + if [ ! -e $file ]; then + list="$list $file" + fi +done +if [ ${#list} -gt 0 ]; then + echo ERROR: the following input files do not exist + for file in $list; + do + echo $file + done + exit 1 +fi + +# process time loop limits (create array of length 3) + +tlist=`echo ${tlist} | sed -e "s/,,,/,,0,/"` +tlist=`echo ${tlist} | sed -e "s/^,/0,/"` +tlist=`echo ${tlist} | sed -e "s/,,/,0,/"` +tloop=`echo ${tlist} | sed -e "s/,/ /g"` + +#----------------------------------------------------------------------- +# ---- namelist for pressure interp program ---- + + namelist="plev.input.nml" + + echo " &input" > $namelist + +# input file names + echo " in_file_name = '$file' ," >> $namelist + echo " out_file_name = '$ofile' ," >> $namelist + +# input field names +i=0 +for field in $fields; +do + let "i=$i+1" + echo " field_names($i) = '$field' ," >> $namelist +done + +# pressure level values +i=0 +for prs in $plevs; +do + let "i=$i+1" + echo " pout($i) = $prs.," >> $namelist +done + +# more namelist values +cat >> $namelist << EOF + do_all_3d_fields = $do_all_3d_fields, + do_all_fields = $do_all_fields, + allow_zero_sphum = $allow_zero, + allow_zero_topog = $allow_zero, + mask_extrap = $mask_extrap, + use_default_missing_value = $default_missval, + verbose = $more_output, +EOF + +#--- time loop limits --- +i=0 +for index in $tloop; +do + let "i=$i+1" + if [ $index -gt 0 ]; then + case $i in + 1) echo " time_beg = $index" >> $namelist;; + 2) echo " time_end = $index" >> $namelist;; + 3) echo " time_inc = $index" >> $namelist;; + esac + fi +done + + echo " /" >> $namelist + +$executable + +#rm -f $namelist + diff --git a/src/postprocessing/plevel/pressure_interp.F90 b/src/postprocessing/plevel/pressure_interp.F90 index fb6af65fc3..c9040752c7 100644 --- a/src/postprocessing/plevel/pressure_interp.F90 +++ b/src/postprocessing/plevel/pressure_interp.F90 @@ -1,3 +1,8 @@ +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +!----------------------------------------------------------------------- module pressure_interp_mod diff --git a/src/postprocessing/plevel/run_pressure_interp.F90 b/src/postprocessing/plevel/run_pressure_interp.F90 index afa65520c4..be9a30a1a9 100644 --- a/src/postprocessing/plevel/run_pressure_interp.F90 +++ b/src/postprocessing/plevel/run_pressure_interp.F90 @@ -1,4 +1,12 @@ - +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +! +! This program aggregates vertical data by pressure levels +! +!----------------------------------------------------------------------- + program run_pressure_interp use netcdf @@ -234,7 +242,7 @@ program run_pressure_interp call set_verbose_level (verbose) - ! create version string (may replace with CVS $Id: run_pressure_interp.F90,v 19.0 2012/01/06 22:07:23 fms Exp $) + ! create version string (may replace with CVS $Id: run_pressure_interp.F90,v 20.0 2013/12/14 00:29:42 fms Exp $) version = 'pressure level interpolator, version 3.0' if (precision(ps) == precision(time)) then version = trim(version)//', precision=double' diff --git a/src/postprocessing/regrid/regrid.F90 b/src/postprocessing/regrid/regrid.F90 index 6c11437dcb..5c565b4fd8 100644 --- a/src/postprocessing/regrid/regrid.F90 +++ b/src/postprocessing/regrid/regrid.F90 @@ -138,7 +138,7 @@ program regrid !--- version information --------------------------------------------- character(len=128) :: version = '$Id: regrid.F90,v 14.0 2007/03/15 22:45:28 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--- variables about source data or on source grid integer :: ncid_src ! ncid corresponding to source file. diff --git a/src/postprocessing/regrid_hfls/fre-nctools.mk b/src/postprocessing/regrid_hfls/fre-nctools.mk new file mode 100644 index 0000000000..1bc6ecf939 --- /dev/null +++ b/src/postprocessing/regrid_hfls/fre-nctools.mk @@ -0,0 +1,39 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:29:57 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2010 +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# + +FC := ifort +FFLAGS := -fltconsistency -fno-alias -stack_temps -safe_cray_ptr -ftz -assume byterecl -g -O2 -i4 -r8 -traceback +INCLUDES := -I${NETCDF_HOME}/include +LIBS := -L${NETCDF_HOME}/lib/shared -L${HDF5_HOME}/lib/shared -lnetcdff -lnetcdf -lhdf5_hl -lhdf5 -lz -limf + +TARGETS := regrid_hfls.exe + +SOURCES := regrid_hfls.F90 + +OBJECTS := $(SOURCES:F90=o) + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +regrid_hfls.exe: regrid_hfls.o + $(FC) -o $@ $^ $(OBJECTS) $(LIBS) + +regrid_hfls.o: regrid_hfls.F90 $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c $< + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + -rm -f *.o $(TARGETS) diff --git a/src/postprocessing/regrid_hfls/regrid_hfls.F90 b/src/postprocessing/regrid_hfls/regrid_hfls.F90 new file mode 100644 index 0000000000..ce58d36295 --- /dev/null +++ b/src/postprocessing/regrid_hfls/regrid_hfls.F90 @@ -0,0 +1,749 @@ +program regrid_hlfs + + !----------------------------------------------------------------------- + ! 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 + !----------------------------------------------------------------------- + ! + ! Zhi Liang + ! + ! + ! This program is to calculate surface upward laten heat flux on the atmosphere grid. + ! + + ! + ! to compile, in the command line, type + ! " + ! + + implicit none +#include "netcdf.inc" + + real, parameter :: epsln = 1.e-20 + integer :: stdout = 6 + + character(len=24) :: grid_file = "input/grid_spec.nc" + character(len=24) :: fld_in_from_lnd = 'latent' + character(len=24) :: fld_in_from_ice = 'LH' + character(len=24) :: src_from_lnd, src_from_ice + character(len=24) :: fld_out_from_ice = 'LH_from_ice' + character(len=24) :: fld_out_from_tot = 'sfc_latent_tot' + character(len=24) :: output_from_ice, output_from_tot + character(len=32) :: tunits = " " + + logical :: time_bounds_exist + integer :: ni_ice, nj_ice, ntime + integer :: ni_atm, nj_atm + integer :: ncid_ice, ncid_tot + integer :: id_time_ice, id_timeb_ice + integer :: id_time_tot, id_timeb_tot + integer :: id_lh_ice, id_lh_tot + integer :: id_t1_ice, id_t2_ice, id_dt_ice + integer :: id_t1_tot, id_t2_tot, id_dt_tot + real :: missing_lnd, missing_ice + + + real, dimension(:), allocatable :: lon, lat, lonb, latb + integer, dimension(:), allocatable :: i_atm_atmxocn, j_atm_atmxocn + integer, dimension(:), allocatable :: i_ocn_atmxocn, j_ocn_atmxocn + real, dimension(:), allocatable :: area_atmxocn + real, dimension(:,:), allocatable :: area_atm, area_ocn + real, dimension(:), allocatable :: time_value, t1, t2, dt + real, dimension(:,:), allocatable :: time_bounds + + call regrid_hfls_init + + !---- read grid information + call read_grid + + !--- get source data information + call get_src_info + + !--- setup meta data for the output file + call setup_meta + + !--- processing data and write out the data sets + call process_data() + + +contains + + !##################################################################### + subroutine regrid_hfls_init + integer :: unit_begin, unit_end, unit + logical :: opened, file_exist + + src_from_lnd = 'input/'//trim(fld_in_from_lnd)//'.nc' + src_from_ice = 'input/'//trim(fld_in_from_ice)//'.nc' + output_from_ice = trim(fld_out_from_ice)//'.nc' + output_from_tot = trim(fld_out_from_tot)//'.nc' + + end subroutine regrid_hfls_init + + !##################################################################### + subroutine read_grid + + integer :: rcode, ncid, ncells + + rcode = nf_open(grid_file, NF_NOWRITE, ncid) + call error_handler('error in open file '//grid_file, rcode) + + + !--- read the ocean grid information ( source grid ) + ni_ice = get_dimlen(ncid, 'gridlon_t') + nj_ice = get_dimlen(ncid, 'gridlat_t') + + !--- read the atmos grid information ( destination grid ) + ni_atm = get_dimlen(ncid, 'xta') + nj_atm = get_dimlen(ncid, 'yta') + + allocate(lon(ni_atm), lat(nj_atm), lonb(ni_atm+1), latb(nj_atm+1) ) + + call get_var_real_1d(ncid, 'xta', lon) + call get_var_real_1d(ncid, 'yta', lat) + call get_var_real_1d(ncid, 'xba', lonb) + call get_var_real_1d(ncid, 'yba', latb) + + !--- get exchange grid information + ncells = get_dimlen(ncid, 'I_ATM_ATMxOCN') + allocate(i_atm_atmxocn(ncells), j_atm_atmxocn(ncells) ) + allocate(i_ocn_atmxocn(ncells), j_ocn_atmxocn(ncells) ) + allocate(area_atmxocn(ncells), area_atm(ni_atm, nj_atm) ) + + call get_var_int_1d(ncid, 'I_ATM_ATMxOCN', i_atm_atmxocn) + call get_var_int_1d(ncid, 'J_ATM_ATMxOCN',j_atm_atmxocn ) + call get_var_int_1d(ncid, 'I_OCN_ATMxOCN',i_ocn_atmxocn ) + call get_var_int_1d(ncid, 'J_OCN_ATMxOCN',j_ocn_atmxocn ) + call get_var_real_1d(ncid, 'AREA_ATMxOCN',area_atmxocn ) + call get_var_real_2d(ncid, 'AREA_ATM',area_atm ) + + allocate(area_ocn(ni_atm,nj_atm) ) + + rcode = nf_close(ncid) + + + end subroutine read_grid + + !##################################################################### + + subroutine get_src_info + + integer :: rcode, ncid, varid + + rcode = nf_open(trim(src_from_lnd), NF_NOWRITE, ncid) + call error_handler('error in opening file '//trim(src_from_lnd), rcode) + + ! check if time_bounds exist or not + rcode = nf_inq_varid(ncid, 'time_bounds', varid) + if(rcode == 0) then + time_bounds_exist = .true.; + else + time_bounds_exist = .false.; + write(stdout,*)" time average information does not exist, ", & + "There will be not time_bounds, average_T1, average_T2 ", & + "and average_DT in the output file" + endif + + ntime = get_dimlen(ncid, 'time') + allocate(time_value(ntime), time_bounds(2, ntime) ) + allocate(t1(ntime), t2(ntime), dt(ntime) ) + call get_var_real_1d(ncid, 'time', time_value) + if(time_bounds_exist) then + call get_var_real_1d(ncid, 'average_T1', t1) + call get_var_real_1d(ncid, 'average_T2', t2) + call get_var_real_1d(ncid, 'average_DT', dt) + call get_var_real_2d(ncid, 'time_bounds', time_bounds) + endif + + !--- get the time units + call get_time_units(ncid) + + !--- get the missing value + call get_missing_value(ncid, fld_in_from_lnd, missing_lnd ) + + rcode = nf_close(ncid) + + rcode = nf_open(trim(src_from_ice), NF_NOWRITE, ncid) + call error_handler('error in opening file '//trim(src_from_ice), rcode) + + call get_missing_value(ncid, fld_in_from_ice, missing_ice ) + + end subroutine get_src_info + + !##################################################################### + subroutine setup_meta + + integer :: rcode, dims(6), id_xt, id_yt, id_xb, id_yb, id_nv + character(len=4) :: units + + if(tunits(1:4) == 'days') then + units = 'days' + else + call error_handler('time units should be days, need to update the source code') + endif + + !--- setup for the part from ice model + rcode = nf_create(trim(output_from_ice),NF_WRITE, ncid_ice) + call error_handler('error in creating file '//trim(output_from_ice), rcode) + + !--- define dimension + dims(1) = define_dim(ncid_ice, 'xt',ni_atm) + dims(2) = define_dim(ncid_ice, 'yt',nj_atm) + dims(3) = define_dim(ncid_ice, 'time', NF_UNLIMITED) + dims(4) = define_dim(ncid_ice, 'xb', ni_atm+1) + dims(5) = define_dim(ncid_ice, 'yb', nj_atm+1) + dims(6) = define_dim(ncid_ice, 'nv', 2) + + !--- define variable + id_xt = define_var_1d(ncid_ice, 'xt', NF_FLOAT, dims(1) ) + call put_att_text(ncid_ice, id_xt, 'long_name', 'longitude') + call put_att_text(ncid_ice, id_xt, 'units', 'degrees_E') + call put_att_text(ncid_ice, id_xt, 'cartesian_axis', 'X') + call put_att_text(ncid_ice, id_xt, 'edges', 'xb') + + id_yt = define_var_1d(ncid_ice, 'yt', NF_FLOAT, dims(2) ) + call put_att_text(ncid_ice, id_yt, 'long_name', 'latitude') + call put_att_text(ncid_ice, id_yt, 'units', 'degrees_N') + call put_att_text(ncid_ice, id_yt, 'cartesian_axis', 'Y') + call put_att_text(ncid_ice, id_yt, 'edges', 'yb') + + id_xb = define_var_1d(ncid_ice, 'xb', NF_FLOAT, dims(4) ) + call put_att_text(ncid_ice, id_xb, 'long_name', 'longitude edges') + call put_att_text(ncid_ice, id_xb, 'units', 'degrees_E') + call put_att_text(ncid_ice, id_xb, 'cartesian_axis', 'X') + + id_yb = define_var_1d(ncid_ice, 'yb', NF_FLOAT, dims(5) ) + call put_att_text(ncid_ice, id_yb, 'long_name', 'latitude edges') + call put_att_text(ncid_ice, id_yb, 'units', 'degrees_N') + call put_att_text(ncid_ice, id_yb, 'cartesian_axis', 'Y') + + id_time_ice = define_var_1d(ncid_ice, 'time', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_ice, id_time_ice, 'long_name', 'time') + call put_att_text(ncid_ice, id_time_ice, 'units', trim(tunits) ) + call put_att_text(ncid_ice, id_time_ice, 'cartesian_axis', 'T') + call put_att_text(ncid_ice, id_time_ice, 'calendar_type', 'NOLEAP') + call put_att_text(ncid_ice, id_time_ice, 'calendar', 'NOLEAP') + if(time_bounds_exist) then + call put_att_text(ncid_ice, id_time_ice, 'bounds', 'time_bounds') + endif + + id_nv = define_var_1d(ncid_ice, 'nv', NF_FLOAT, dims(6) ) + call put_att_text(ncid_ice, id_nv, 'long_name', 'vertex number') + call put_att_text(ncid_ice, id_nv, 'units', 'none') + call put_att_text(ncid_ice, id_nv, 'cartesian_axis', 'N') + + if(time_bounds_exist) then + id_t1_ice = define_var_1d(ncid_ice, 'average_T1', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_ice, id_t1_ice, 'long_name', 'Start time for average period') + call put_att_text(ncid_ice, id_t1_ice, 'units', trim(tunits) ) + + id_t2_ice = define_var_1d(ncid_ice, 'average_T2', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_ice, id_t2_ice, 'long_name', 'End time for average period') + call put_att_text(ncid_ice, id_t2_ice, 'units', trim(tunits) ) + + id_dt_ice = define_var_1d(ncid_ice, 'average_DT', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_ice, id_dt_ice, 'long_name', 'Length of average period') + call put_att_text(ncid_ice, id_dt_ice, 'units', trim(units)) + + id_timeb_ice = define_var_2d(ncid_ice, 'time_bounds', NF_DOUBLE, (/dims(6), dims(3)/) ) + call put_att_text(ncid_ice, id_timeb_ice, 'long_name', 'time axis boundaries') + call put_att_text(ncid_ice, id_timeb_ice, 'units', trim(units) ) + endif + + id_lh_ice = define_var_3d(ncid_ice, trim(fld_out_from_ice), NF_FLOAT, dims(1:3) ) + call put_att_text(ncid_ice, id_lh_ice, 'long_name', 'latent heat flux') + call put_att_text(ncid_ice, id_lh_ice, 'units', 'W/m^2') + call put_att_real(ncid_ice, id_lh_ice, 'missing_value', missing_ice) + call put_att_text(ncid_ice, id_lh_ice, 'cell_methods', 'time: mean') + + if(time_bounds_exist) then + call put_att_text(ncid_ice, id_lh_ice, 'time_avg_info', 'average_T1,average_T2,average_DT') + endif + + rcode = nf_enddef(ncid_ice) + + !--- write out axis data + call put_var_real_1d(ncid_ice, id_xt, lon) + call put_var_real_1d(ncid_ice, id_yt, lat) + call put_var_real_1d(ncid_ice, id_xb, lonb) + call put_var_real_1d(ncid_ice, id_yb, latb) + call put_var_real_1d(ncid_ice, id_nv, (/1.,2./) ) + + !--- setup for the part from addition of ice and land model + rcode = nf_create(trim(output_from_tot),NF_WRITE, ncid_tot) + call error_handler('error in creating file '//trim(output_from_tot), rcode) + + !--- define dimension + dims(1) = define_dim(ncid_tot, 'lon',ni_atm) + dims(2) = define_dim(ncid_tot, 'lat',nj_atm) + dims(3) = define_dim(ncid_tot, 'time', NF_UNLIMITED) + dims(4) = define_dim(ncid_tot, 'lonb', ni_atm+1) + dims(5) = define_dim(ncid_tot, 'latb', nj_atm+1) + dims(6) = define_dim(ncid_tot, 'nv', 2) + + !--- define variable + id_xt = define_var_1d(ncid_tot, 'lon', NF_FLOAT, dims(1) ) + call put_att_text(ncid_tot, id_xt, 'long_name', 'longitude') + call put_att_text(ncid_tot, id_xt, 'units', 'degrees_E') + call put_att_text(ncid_tot, id_xt, 'cartesian_axis', 'X') + call put_att_text(ncid_tot, id_xt, 'edges', 'lonb') + + id_yt = define_var_1d(ncid_tot, 'lat', NF_FLOAT, dims(2) ) + call put_att_text(ncid_tot, id_yt, 'long_name', 'latitude') + call put_att_text(ncid_tot, id_yt, 'units', 'degrees_N') + call put_att_text(ncid_tot, id_yt, 'cartesian_axis', 'Y') + call put_att_text(ncid_tot, id_yt, 'edges', 'latb') + + id_xb = define_var_1d(ncid_tot, 'lonb', NF_FLOAT, dims(4) ) + call put_att_text(ncid_tot, id_xb, 'long_name', 'longitude edges') + call put_att_text(ncid_tot, id_xb, 'units', 'degrees_E') + call put_att_text(ncid_tot, id_xb, 'cartesian_axis', 'X') + + id_yb = define_var_1d(ncid_tot, 'latb', NF_FLOAT, dims(5) ) + call put_att_text(ncid_tot, id_yb, 'long_name', 'latitude edges') + call put_att_text(ncid_tot, id_yb, 'units', 'degrees_N') + call put_att_text(ncid_tot, id_yb, 'cartesian_axis', 'Y') + + id_time_tot = define_var_1d(ncid_tot, 'time', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_tot, id_time_tot, 'long_name', 'time') + call put_att_text(ncid_tot, id_time_tot, 'units', trim(tunits) ) + call put_att_text(ncid_tot, id_time_tot, 'cartesian_axis', 'T') + call put_att_text(ncid_tot, id_time_tot, 'calendar_type', 'NOLEAP') + call put_att_text(ncid_tot, id_time_tot, 'calendar', 'NOLEAP') + if(time_bounds_exist) then + call put_att_text(ncid_tot, id_time_tot, 'bounds', 'time_bounds') + endif + + id_nv = define_var_1d(ncid_tot, 'nv', NF_FLOAT, dims(6) ) + call put_att_text(ncid_tot, id_nv, 'long_name', 'vertex number') + call put_att_text(ncid_tot, id_nv, 'units', 'none') + call put_att_text(ncid_tot, id_nv, 'cartesian_axis', 'N') + + if(time_bounds_exist) then + id_t1_tot = define_var_1d(ncid_tot, 'average_T1', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_tot, id_t1_tot, 'long_name', 'Start time for average period') + call put_att_text(ncid_tot, id_t1_tot, 'units', trim(tunits) ) + + id_t2_tot = define_var_1d(ncid_tot, 'average_T2', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_tot, id_t2_tot, 'long_name', 'End time for average period') + call put_att_text(ncid_tot, id_t2_tot, 'units', trim(tunits) ) + + id_dt_tot = define_var_1d(ncid_tot, 'average_DT', NF_DOUBLE, dims(3) ) + call put_att_text(ncid_tot, id_dt_tot, 'long_name', 'Length of average period') + call put_att_text(ncid_tot, id_dt_tot, 'units', trim(units)) + + id_timeb_tot = define_var_2d(ncid_tot, 'time_bounds', NF_DOUBLE, (/dims(6), dims(3)/) ) + call put_att_text(ncid_tot, id_timeb_tot, 'long_name', 'time axis boundaries') + call put_att_text(ncid_tot, id_timeb_tot, 'units', trim(units)) + endif + + id_lh_tot = define_var_3d(ncid_tot, trim(fld_out_from_tot), NF_FLOAT, dims(1:3) ) + call put_att_text(ncid_tot, id_lh_tot, 'long_name', 'latent heat flux') + call put_att_text(ncid_tot, id_lh_tot, 'units', 'W/m^2') + call put_att_real(ncid_tot, id_lh_tot, 'missing_value', missing_lnd) + call put_att_text(ncid_tot, id_lh_tot, 'cell_methods', 'time: mean') + if(time_bounds_exist) then + call put_att_text(ncid_tot, id_lh_tot, 'time_avg_info', 'average_T1,average_T2,average_DT') + endif + + rcode = nf_enddef(ncid_tot) + + !--- write out axis data + call put_var_real_1d(ncid_tot, id_xt, lon) + call put_var_real_1d(ncid_tot, id_yt, lat) + call put_var_real_1d(ncid_tot, id_xb, lonb) + call put_var_real_1d(ncid_tot, id_yb, latb) + call put_var_real_1d(ncid_tot, id_nv, (/1.,2./) ) + + return + + end subroutine setup_meta + + !##################################################################### + + subroutine process_data + + integer :: rcode, m, i, j + real, dimension(ni_ice, nj_ice) :: data_src_ice + real, dimension(ni_atm, nj_atm) :: data_src_lnd, data_dst_ice, data_dst_tot + + do m = 1, ntime + + write(stdout,*)'******* processing at time step: ', m + + !--- read input data + call get_var_level_2d(src_from_ice, fld_in_from_ice, m, data_src_ice ) + call get_var_level_2d(src_from_lnd, fld_in_from_lnd, m, data_src_lnd ) + + !--- data conversion + data_dst_ice = 0.0 + area_ocn = 0.0 + do i = 1, size(i_atm_atmxocn) + if(data_src_ice(i_ocn_atmxocn(i),j_ocn_atmxocn(i)) .ne. missing_ice ) then + data_dst_ice(i_atm_atmxocn(i),j_atm_atmxocn(i)) = data_dst_ice(i_atm_atmxocn(i),j_atm_atmxocn(i)) & + + data_src_ice(i_ocn_atmxocn(i),j_ocn_atmxocn(i)) * area_atmxocn(i) + area_ocn(i_atm_atmxocn(i),j_atm_atmxocn(i)) = area_ocn(i_atm_atmxocn(i),j_atm_atmxocn(i)) + area_atmxocn(i) + endif + enddo + + do j = 1, nj_atm + do i = 1, ni_atm + if(area_ocn(i,j) > epsln ) then + data_dst_ice(i,j) = data_dst_ice(i,j)/area_ocn(i,j) + else + data_dst_ice(i,j) = missing_ice + endif + enddo + enddo + + do j = 1, nj_atm + do i = 1, ni_atm + if(data_dst_ice(i,j) .ne. missing_ice ) then + data_dst_tot(i,j) = data_dst_ice(i,j) * area_ocn(i,j) + else + data_dst_tot(i,j) = 0.0 + endif + + if(data_src_lnd(i,j) .ne. missing_lnd ) then + data_dst_tot(i,j) = data_dst_tot(i,j) + data_src_lnd(i,j) * (area_atm(i,j)-area_ocn(i,j)) + endif + data_dst_tot(i,j) = data_dst_tot(i,j)/area_atm(i,j) + enddo + enddo + + !--- write out data from ice model + call put_var_level_2d(ncid_ice, id_lh_ice, m, data_dst_ice ) + call put_var_level_0d(ncid_ice, id_time_ice, m, time_value(m) ) + if(time_bounds_exist) then + call put_var_level_0d(ncid_ice, id_t1_ice, m, t1(m) ) + call put_var_level_0d(ncid_ice, id_t2_ice, m, t2(m) ) + call put_var_level_0d(ncid_ice, id_dt_ice, m, dt(m) ) + call put_var_level_1d(ncid_ice, id_timeb_ice, m, time_bounds(:,m) ) + endif + + !--- write out the total hfls + call put_var_level_2d(ncid_tot, id_lh_tot, m, data_dst_tot ) + call put_var_level_0d(ncid_tot, id_time_tot, m, time_value(m) ) + if(time_bounds_exist) then + call put_var_level_0d(ncid_tot, id_t1_tot, m, t1(m) ) + call put_var_level_0d(ncid_tot, id_t2_tot, m, t2(m) ) + call put_var_level_0d(ncid_tot, id_dt_tot, m, dt(m) ) + call put_var_level_1d(ncid_tot, id_timeb_tot, m, time_bounds(:,m) ) + endif + + enddo + + rcode = nf_close(ncid_ice) + rcode = nf_close(ncid_tot) + + end subroutine process_data + + !##################################################################### + ! get the dimension length of any one dimensional variable + function get_dimlen(ncid, name) + integer, intent(in) :: ncid + character(len=*), intent(in) :: name + integer :: get_dimlen + integer :: varid, rcode, dims(1) + + rcode = nf_inq_varid(ncid, trim(name), varid) + call error_handler('error in inquiring variable id of '//trim(name), rcode) + + rcode = nf_inq_vardimid(ncid, varid, dims) + call error_handler('error in inquiring dimension id of '//trim(name), rcode) + + rcode = nf_inq_dimlen(ncid, dims(1), get_dimlen) + call error_handler('error in inquiring dimension length of '//trim(name), rcode) + + end function get_dimlen + + !##################################################################### + ! read the 1d integer data from netcdf file. + subroutine get_var_int_1d(ncid, name, data) + integer, intent(in) :: ncid + character(len=*), intent(in) :: name + integer, dimension(:), intent(out) :: data + integer :: rcode, varid + + rcode = nf_inq_varid(ncid, name, varid) + call error_handler('error in inquiring variable id of '//trim(name), rcode) + rcode = nf_get_var_int(ncid, varid, data) + call error_handler('error in reading data of '//trim(name), rcode) + + end subroutine get_var_int_1d + + !##################################################################### + ! read the 1d real data from netcdf file. + subroutine get_var_real_1d(ncid, name, data) + integer, intent(in) :: ncid + character(len=*), intent(in) :: name + real, dimension(:), intent(out) :: data + integer :: rcode, varid + + rcode = nf_inq_varid(ncid, name, varid) + call error_handler('error in inquiring variable id of '//trim(name), rcode) + + rcode = nf_get_var_double(ncid, varid, data) + call error_handler('error in reading data of '//trim(name), rcode) + + + end subroutine get_var_real_1d + + !##################################################################### + ! read the 2d real data from netcdf file. + subroutine get_var_real_2d(ncid, name, data) + integer, intent(in) :: ncid + character(len=*), intent(in) :: name + real, dimension(:,:), intent(out) :: data + integer :: rcode, varid + + + rcode = nf_inq_varid(ncid, name, varid) + call error_handler('error in inquiring variable id of '//trim(name), rcode) + + rcode = nf_get_var_double(ncid, varid, data) + call error_handler('error in reading data of '//trim(name), rcode) + + end subroutine get_var_real_2d + + !##################################################################### + subroutine get_missing_value(ncid, name, missing) + + integer, intent(in) :: ncid + character(len=*), intent(in) :: name + real, intent(in) :: missing + + integer :: rcode, id_fld + + rcode = nf_inq_varid(ncid,trim(name), id_fld) + call error_handler('error in inquring id of field '//trim(name), rcode) + + rcode = nf_get_att_double(ncid, id_fld, 'missing_value', missing ) + call error_handler('error in get field '//trim(name)//' missing value' , rcode) + rcode = nf_close(ncid) + + end subroutine get_missing_value + + !##################################################################### + subroutine get_time_units(ncid) + integer, intent(in) :: ncid + + integer :: rcode, id_fld + + rcode = nf_inq_varid(ncid,'time', id_fld) + call error_handler('error in inquring id of time', rcode) + + rcode = nf_get_att_text(ncid, id_fld, 'units', tunits ) + call error_handler('error in get time units' , rcode) + + end subroutine get_time_units + + !##################################################################### + function define_dim(ncid, name, size ) + integer, intent(in) :: ncid, size + character(len=*), intent(in) :: name + integer :: define_dim + + integer :: rcode + + rcode = nf_def_dim(ncid, trim(name), size, define_dim) + call error_handler('error in defining dimension '//trim(name) , rcode) + + end function define_dim + + !##################################################################### + function define_var_1d(ncid, name, type, dim ) + integer, intent(in) :: ncid, type, dim + character(len=*), intent(in) :: name + integer :: define_var_1d + + integer :: rcode + + rcode = nf_def_var(ncid, trim(name), type, 1, dim, define_var_1d) + call error_handler('error in defining variable '//trim(name) , rcode) + + + end function define_var_1d + + !##################################################################### + function define_var_2d(ncid, name, type, dim ) + integer, intent(in) :: ncid, type + character(len=*), intent(in) :: name + integer, dimension(:), intent(in) :: dim + integer :: define_var_2d + + integer :: rcode + + rcode = nf_def_var(ncid, trim(name), type, 2, dim, define_var_2d) + call error_handler('error in defining variable '//trim(name) , rcode) + + + end function define_var_2d + + !##################################################################### + + function define_var_3d(ncid, name, type, dim ) + integer, intent(in) :: ncid, type + character(len=*), intent(in) :: name + integer, dimension(:), intent(in) :: dim + integer :: define_var_3d + + integer :: rcode + + rcode = nf_def_var(ncid, trim(name), type, 3, dim, define_var_3d) + call error_handler('error in defining variable '//trim(name) , rcode) + + + end function define_var_3d + + !##################################################################### + + subroutine get_var_level_2d(file, field, level, data ) + character(len=*), intent(in) :: file, field + integer, intent(in) :: level + real, intent(out) :: data(:,:) + + integer :: start(4), nread(4), ncid, rcode, id_fld, nlon, nlat + + nlon = size(data,1) + nlat = size(data,2) + + rcode = nf_open(trim(file), NF_NOWRITE, ncid) + call error_handler('error in opening file '//trim(file), rcode) + + rcode = nf_inq_varid(ncid, trim(field), id_fld ) + call error_handler('error in inquiring variable id of '//trim(field), rcode) + + start = 1; nread = 1 + nread(1) = nlon; nread(2) = nlat + start(3) = level + rcode = nf_get_vara_double(ncid, id_fld, start, nread, data) + call error_handler('Error in reading the data ', rcode) + + rcode = nf_close(ncid) + + end subroutine get_var_level_2d + + !##################################################################### + subroutine put_att_text(ncid, id_fld, name, cval) + integer, intent(in) :: ncid, id_fld + character(len=*), intent(in) :: name, cval + + integer :: rcode + + rcode = nf_put_att_text(ncid,id_fld, trim(name),len_trim(cval), trim(cval) ) + call error_handler('error in putting attribute '//trim(name) , rcode) + + end subroutine put_att_text + + !##################################################################### + + subroutine put_att_real(ncid, id_fld, name, rval) + integer, intent(in) :: ncid, id_fld + character(len=*), intent(in) :: name + real, intent(in) :: rval + + integer :: rcode + + rcode = nf_put_att_double(ncid,id_fld, trim(name), NF_DOUBLE, 1, rval ) + call error_handler('error in putting attribute '//trim(name) , rcode) + + end subroutine put_att_real + + !##################################################################### + + subroutine put_var_real_1d(ncid, varid, data) + integer, intent(in) :: ncid, varid + real, dimension(:), intent(in) :: data + integer :: rcode, start(4), nwrite(4) + + start = 1; nwrite = 1; + nwrite(1) = size(data) + rcode = nf_put_vara_double(ncid, varid, start, nwrite, data) + call error_handler('Error in put real 1d data', rcode ) + + + end subroutine put_var_real_1d + + !##################################################################### + subroutine put_var_level_0d(ncid, id_fld, level, data) + integer, intent(in) :: ncid, id_fld, level + real, intent(in) :: data + + integer :: rcode + + rcode = nf_put_var1_double(ncid, id_fld, level, data) + call error_handler('error in putting scalar data', rcode) + + end subroutine put_var_level_0d + + !##################################################################### + + subroutine put_var_level_1d(ncid, id_fld, level, data) + integer, intent(in) :: ncid, id_fld, level + real, intent(in) :: data(:) + + integer :: nwrite(4), start(4), rcode + + start = 1; nwrite = 1 + start(2) = level; nwrite(1) = size(data) + + rcode = nf_put_vara_double(ncid, id_fld, start, nwrite, data) + call error_handler('error in putting 1d data', rcode) + + end subroutine put_var_level_1d + + !##################################################################### + subroutine put_var_level_2d(ncid, id_fld, level, data) + integer, intent(in) :: ncid, id_fld, level + real, intent(in) :: data(:,:) + + integer :: rcode, start(4), nwrite(4) + + start = 1; nwrite = 1; + start(3) = level + nwrite(1) = size(data,1); nwrite(2) = size(data,2) + + rcode = nf_put_vara_double(ncid, id_fld, start, nwrite, data) + call error_handler('error in putting 2d data ', rcode) + + end subroutine put_var_level_2d + + !##################################################################### + ! error handling routine. + subroutine error_handler(mesg, status) + character(len=*), intent(in) :: mesg + integer, optional, intent(in) :: status + character(len=256) :: msg + + + if(present(status)) then + if(status == 0) return + msg = nf_strerror(status) + msg = trim(mesg)//': '// trim(msg) + else + msg = trim(mesg) + endif + + write(stdout,*)'Error: '//trim(msg) + call abort() + + end subroutine error_handler + + !##################################################################### + +end program regrid_hlfs diff --git a/src/postprocessing/timavg/COPYING b/src/postprocessing/timavg/COPYING new file mode 100644 index 0000000000..93a221957b --- /dev/null +++ b/src/postprocessing/timavg/COPYING @@ -0,0 +1,159 @@ +TERMS AND CONDITIONS +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. +1. Source Code. + +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. +2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. +7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. +8. Termination. + +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. +11. Patents. + +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. diff --git a/src/postprocessing/timavg/env.gaea b/src/postprocessing/timavg/env.gaea new file mode 100644 index 0000000000..5ca521ef74 --- /dev/null +++ b/src/postprocessing/timavg/env.gaea @@ -0,0 +1,3 @@ +# ORNL builds explicit fortran interface library +LIBNETCDFF := -lnetcdff +STATIC := -static diff --git a/src/postprocessing/timavg/env.gfdl-ws b/src/postprocessing/timavg/env.gfdl-ws new file mode 100644 index 0000000000..723744dad1 --- /dev/null +++ b/src/postprocessing/timavg/env.gfdl-ws @@ -0,0 +1 @@ +LIBNETCDFF := -lnetcdff diff --git a/src/postprocessing/timavg/env.pan b/src/postprocessing/timavg/env.pan new file mode 100644 index 0000000000..52cb634624 --- /dev/null +++ b/src/postprocessing/timavg/env.pan @@ -0,0 +1,4 @@ +LIBNETCDFF := -lnetcdff + +LIBS2 := +CLIBS2 := diff --git a/src/postprocessing/timavg/env.zeus b/src/postprocessing/timavg/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/postprocessing/timavg/fre-nctools.mk b/src/postprocessing/timavg/fre-nctools.mk new file mode 100644 index 0000000000..f6ab36f30f --- /dev/null +++ b/src/postprocessing/timavg/fre-nctools.mk @@ -0,0 +1,52 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:30:17 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include ./env.$(SITE) + +FC := ifort +FFLAGS := -fltconsistency -fno-alias -stack_temps -safe_cray_ptr -ftz -assume byterecl -g -O2 -i4 -real_size 64 -traceback +FFLAGS_r4:= -fltconsistency -fno-alias -stack_temps -safe_cray_ptr -ftz -assume byterecl -g -O2 -i4 -real_size 32 -traceback +INCLUDES := -I${NETCDF_HOME}/include +LIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib $(LIBNETCDFF) -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(LIBS2) $(STATIC) + +TARGETS := TAVG.exe TAVG.r4.exe + +OBJECTS := time_average.o +OBJECTS_r4= time_average.r4.o + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +TAVG.exe: time_average.o + $(FC) -o $@ $(OBJECTS) $(LIBS) + +time_average.o: time_average.f90 $(HEADERS) + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +TAVG.r4.exe: time_average.r4.o + $(FC) -o $@ $(OBJECTS_r4) $(LIBS) + +time_average.r4.o: time_average.f90 $(HEADERS) + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +%.o: %.f90 + $(FC) $(FFLAGS) $(INCLUDES) -c -o $@ $< + +%.r4..o: %.f90 + $(FC) $(FFLAGS_r4) $(INCLUDES) -c -o $@ $< + +clean: + -rm -f *.o *.mod $(TARGETS) diff --git a/src/postprocessing/timavg/timavg.csh b/src/postprocessing/timavg/timavg.csh new file mode 100755 index 0000000000..e65b8f1f7e --- /dev/null +++ b/src/postprocessing/timavg/timavg.csh @@ -0,0 +1,154 @@ +#!/bin/tcsh -f +# +# $Id: timavg.csh,v 20.0 2013/12/14 00:30:18 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Script to Call Time-Averaging Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Copied from ~fms/local/ia64/netcdf4.fix June 10 +# afy Ver 2.00 Don't source the 'init.csh' script June 10 +# afy Ver 2.01 Use 'which' to locate executables June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2000-2010 +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# + +#----------------------------------------------------------------------- +# +# This script takes multiple netcdf files that all contain the same +# dimensions and variables but may have a different number of time +# records and writes a new netcdf file that has a time record +# averaged from each input file. +# +#----------------------------------------------------------------------- + +set ofile +set ifiles +set etime = .true. +set do_verbose = .false. +set do_bounds = .false. +set do_errors = .false. +set no_warning = .false. +set vers = v08 +set precision = 8 + +# ----- parse input argument list ------ + +set argv = (`getopt abdmWo:v:w:r: $*`) + +while ("$argv[1]" != "--") + switch ($argv[1]) + case -a: + set do_errors = .true.; breaksw + case -b: + set do_bounds = .true.; breaksw + case -d: + set debug; set do_verbose = .true.; breaksw + case -m: + set etime = .false.; breaksw + case -r: + set precision = $argv[2]; shift argv; breaksw + case -W: + set no_warning = .true.; breaksw + case -w: + set weight = $argv[2]; shift argv; breaksw + case -o: + set ofile = $argv[2]; shift argv; breaksw + case -v: + set vers = $argv[2]; shift argv; breaksw + endsw + shift argv +end +shift argv +if ($?debug) set echo +set ifiles = ( $argv ) + +################################################################## +# ----- help message ----- + +if ($ofile == "" || $#ifiles == 0) then +set name = `basename $0` +cat << EOF + +Time averaging script + +Usage: $name [-a] [-b] [-d] [-m] [-r prec] [-v vers] -o ofile files..... + + -a = skips "average information does not agree" errors + -b = adds time axis bounds and cell methods (CF convention) + -d = turns on command echo (for debugging) + -m = average time (instead of end time) for t-axis values + -r prec = precision used for time averaging, either -r4 or -r8 (default) + -W = suppress warning messages (use with caution) + -w wght = minimum fraction of missing data needed for valid data + -o ofile = name of the output file + + files... = list netcdf files, each file will be a time record + in the output file (the files should be in + chronological order) + +EOF +exit 1 +endif + +# -v vers = executable version (TAVG.$vers.exe) +################################################################## + +# executable name depends on precision +if ($precision == 4) then + set executable = `which TAVG.r4.exe` +else if ($precision == 8) then + set executable = `which TAVG.exe` +else + echo "ERROR: use -r4 or -r8"; exit 1 +endif + +set error_flag = 0 + +#-- check existence of executable -- +if (! -e $executable) then + echo Executable does not exist + set error_flag = 1 +endif + +#-- check existence of files -- +foreach file ($ifiles) + if (! -e $file) then + echo File $file does not exist + set error_flag = 1 + endif +end +if ($error_flag != 0) then + echo ERROR: input files do not exist + exit 1 +endif + +#-- namelist (create unique name) -- +set nml_name = nml`date '+%j%H%M%S'` + echo " &input" > $nml_name +set i = 1 +foreach file ($ifiles) + echo " file_names("$i") = " \'$file\' , >> $nml_name + @ i++ +end + echo " file_name_out = " \'$ofile\' , >> $nml_name + echo " use_end_time = " $etime , >> $nml_name + echo " verbose = " $do_verbose , >> $nml_name + echo " add_cell_methods = " $do_bounds , >> $nml_name + echo " skip_tavg_errors = " $do_errors , >> $nml_name + echo " suppress_warnings = " $no_warning, >> $nml_name + + if ($?weight) then + echo " frac_valid_data = " $weight , >> $nml_name + endif + + echo " &end" >> $nml_name + +#-- run averaging program -- + $executable < $nml_name + set exit_status = $status + +#-- clean up -- +rm -f $nml_name + +exit $exit_status + diff --git a/src/postprocessing/timavg/time_average.f90 b/src/postprocessing/timavg/time_average.f90 index 0044f7cc85..ff3a9eb8ab 100644 --- a/src/postprocessing/timavg/time_average.f90 +++ b/src/postprocessing/timavg/time_average.f90 @@ -1,3 +1,10 @@ +!----------------------------------------------------------------------- +! Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ +! This program is distributed under the terms of the GNU General Public +! License. See the file COPYING contained in this directory +! +! This program averages variables stored in netCDF format over the time axis +!----------------------------------------------------------------------- program time_average @@ -11,7 +18,7 @@ program time_average integer :: blksz = BSIZE ! blksz must be writable for nf__create !----------------------------------------------------------------------- -character(len=256) :: file_names(MAX_FILES), file_name_out +character(len=2048) :: file_names(MAX_FILES), file_name_out logical :: use_end_time = .true. logical :: verbose = .false. logical :: add_cell_methods = .false. @@ -71,7 +78,7 @@ program time_average enddo do i=1,len(file_name_out); file_name_out(i:i) = ' '; enddo - ! create version string (may replace with CVS $Id: time_average.f90,v 19.0 2012/01/06 22:07:34 fms Exp $) + ! create version string (may replace with CVS $Id: time_average.f90,v 20.0 2013/12/14 00:30:08 fms Exp $) version = 'FMS time averaging, version 3.0' if (precision(ddata) == precision(time)) then version = trim(version)//', precision=double' diff --git a/src/preprocessing/generate_grids/atmos/atmos_grid.f90 b/src/preprocessing/generate_grids/atmos/atmos_grid.f90 index 6eeb4c0b12..f6ed66ab3c 100644 --- a/src/preprocessing/generate_grids/atmos/atmos_grid.f90 +++ b/src/preprocessing/generate_grids/atmos/atmos_grid.f90 @@ -142,7 +142,7 @@ module atmos_grid_mod !---------version information------------------------------------------- character(len=128) :: version = '$Id: atmos_grid.f90,v 10.0 2003/10/24 22:01:43 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !---------public interface---------------------------------------------- public :: generate_atmos_grid, atmos_grid_init, atmos_grid_end, atmos_grid_type public :: write_atmos_grid_meta, write_atmos_grid_data diff --git a/src/preprocessing/generate_grids/atmos/atmos_grid.html b/src/preprocessing/generate_grids/atmos/atmos_grid.html deleted file mode 100644 index 90128ea60f..0000000000 --- a/src/preprocessing/generate_grids/atmos/atmos_grid.html +++ /dev/null @@ -1,388 +0,0 @@ - - - -Module atmos_grid_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
            -

            Module atmos_grid_mod

            - - -
            -Contact: Z. Liang -
            -Reviewers: S. M. Griffies -
            -Change History: WebCVS Log -
            -
            -
            - - -
            -

            OVERVIEW

            - -

            - -atmos_grid_mod Generate horizontal grid ( either bgrid or spectral grid ) - for atmosphere and land model. -

            - - - -
            - There are four subgrids, labeled T (for tracer), C (corner of T), N (north of T) - and E (east of T). The following schematic describes the grid cell notation. - - -
                                      Ni,j
            -               +----------+-----------+Ci,j
            -               |                      |     
            -               |                      |
            -               |                      |
            -               +          +Ti,j       +Ei,j
            -               |                      |
            -               |                      |
            -               +----------+-----------+
            - - The grid_spec file would contains all of the following information. - -
               x_T, y_T           = Geographic location of T-cell center
            -   x_vert_T, y_vert_T = Geographic location of T-cell vertices(each cell has 4 vertices)
            -   x_C, y_C           = Geographic location of C-cell center
            - - -
            -
            - - -
            -

            OTHER MODULES USED

            - -
            -
                   mpp_mod
            mpp_io_mod
            fms_mod
            transforms_mod
            constants_mod
            -
            - - - -
            -

            PUBLIC INTERFACE

            -
            -
            -
            -atmos_grid_init:
            -
            - Initialization routine. -
            -
            -generate_atmos_grid:
            -
            - Generate horizontal grid. -
            -
            -write_atmos_grid_data:
            -
            - write the Hgrid data to netcdf file -
            -
            -write_atmos_grid_meta:
            -
            - Write out horizontal grid meta data. -
            -
            -atmos_grid_end:
            -
            - Destruction routine. -
            -
            -
            -
            - - -
            -

            PUBLIC ROUTINES

            - -
              -
            1. - -

              atmos_grid_init

              -
              -call atmos_grid_init ( )
              -
              -
              -DESCRIPTION -
              -
              - Read namelist, write out version and namelist informaiton. -
              -
              -
              -
              -
            2. -
            3. - -

              generate_atmos_grid

              -
              -call generate_atmos_grid 
              -
              -
              -
              -DESCRIPTION -
              -
              - Calculate geographic locations of T and C-cell center. -
              -
              -
              -
              -INPUT/OUTPUT -
              -
              - - - - -
              Hgrid    - A derived-type variable that contains horizontal grid information. -
                 [atmos_grid_type]
              -
              -
              -
              -
            4. -
            5. - -

              write_atmos_grid_data

              -
              -call write_atmos_grid_data (unit,Hgrid)
              -
              -
              -DESCRIPTION -
              -
              -
              -
              -
              -INPUT -
              -
              - - - - - - - -
              unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                 [integer]
              Hgrid    - A derived-type variable that contains horizontal grid information. -
                 [atmos_grid_type]
              -
              -
              -
              -
            6. -
            7. - -

              write_atmos_grid_meta

              -
              -call write_atmos_grid_meta (unit, Hgrid)
              -
              -
              -DESCRIPTION -
              -
              -
              -
              -
              -INPUT -
              -
              - - - - - - - -
              unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                 [integer]
              Hgrid    - A derived-type variable that contains horizontal grid information. -
                 [atmos_grid_type]
              -
              -
              -
              -
            8. -
            9. - -

              atmos_grid_end

              -
              -call atmos_grid_end ( Hgrid )
              -
              -
              -DESCRIPTION -
              -
              - Deallocates memory used by "atmos_grid_type" variables. -
              -
              -
              -
              -INPUT/OUTPUT -
              -
              - - - - -
              Hgrid    - A derived-type variable that contains horizontal grid information. -
                 [atmos_grid_type]
              -
              -
              -
              -
            10. -
            - - - -
            -

            PUBLIC TYPES

            -
            - - - - -
            -
              type atmos_grid_type
            -     real, dimension(:,:), pointer   :: x_T => NULL()      ! geographical longitude of T-cell center
            -     real, dimension(:,:), pointer   :: y_T => NULL()      ! geographical latitude of T-cell center 
            -     real, dimension(:,:), pointer   :: x_C => NULL()      ! geographical longitude of C-cell center
            -     real, dimension(:,:), pointer   :: y_C => NULL()      ! geographical latitude of C-cell center 
            -     real, dimension(:,:,:), pointer :: x_vert_T => NULL() ! geographical longitude of T-cell vertices
            -     real, dimension(:,:,:), pointer :: y_vert_T => NULL() ! geographical latitude of T-cell vertices
            -  end type atmos_grid_type
            -
            -
            -
            - - -
            -

            NAMELIST

            - -
            -&atmos_grid_nml -
            -
            -
            -
            -
            -grid_type -
            -
            - type of grid. Its value can be "bgrid" or "spectral". Its default value is "bgrid". -
            -[character(len=24)] -
            -
            -debug -
            -
            - control standard output. -
            -[logical] -
            -
            -num_lon -
            -
            - number of longitude points. -
            -[integer] -
            -
            -num_lat -
            -
            - number of latitude points. -
            -[integer] -
            -
            -num_fourier -
            -
            - the fourier wavenumbers in the truncation are set equal to fourier_inc*m, where m = 0, - num_fourier therefore, the total number of fourier modes is num_fourier +1. - This namelist option is only for grid_type = 'spectral' -
            -[integer] -
            -
            -num_spherical -
            -
            - the wavenumber increment (see num_fourier above). This namelist option is only - for grid_type = 'spectral' -
            -[integer] -
            -
            -fourier_inc -
            -
            - the maximum meridional wavenumber Retained meridional wavewnumbers are n = 0, - num_spherical The total spherical wavenumber is L = n+m. This namelist option is only - for grid_type = 'spectral' -
            -[integer] -
            -
            -lon_begin, lon_end -
            -
            - range of the longitude. Default value is : lon_begin=0, lon_end=360. If you want to - generate regional grid, you may need to set these namelists. Otherwise use default value. - This namelist option is only for grid_type = 'bgrid' -
            -[real] -
            -
            -lat_begin, lat_end -
            -
            - range of the latitude. Default value is : lat_begin=-90, lat_end=90. If you want to - generate regional grid, you may need to set these namelists. Otherwise use default value. - This namelist option is only for grid_type = 'bgrid' -
            -[real] -
            -
            -
            -
            -
            - - - - -
            -
            -top -
            - - diff --git a/src/preprocessing/generate_grids/atmos/atmos_grid_generator.csh b/src/preprocessing/generate_grids/atmos/atmos_grid_generator.csh index b7da502241..9bdc1e0f49 100755 --- a/src/preprocessing/generate_grids/atmos/atmos_grid_generator.csh +++ b/src/preprocessing/generate_grids/atmos/atmos_grid_generator.csh @@ -18,7 +18,7 @@ ####################################################################### set echo - set platform = "gfdl_ws_64.intel" # A unique identifier for your platform + set platform = "ncrc.intel" # A unique identifier for your platform # set root = $cwd:h:h:h:h # The directory that contains src/ and bin/ set npes = 1 diff --git a/src/preprocessing/generate_grids/atmos/atmos_grid_generator.f90 b/src/preprocessing/generate_grids/atmos/atmos_grid_generator.f90 index caf70b0940..2841df9099 100644 --- a/src/preprocessing/generate_grids/atmos/atmos_grid_generator.f90 +++ b/src/preprocessing/generate_grids/atmos/atmos_grid_generator.f90 @@ -37,7 +37,7 @@ program grid_generator implicit none character(len=128), parameter :: version= '$Id: atmos_grid_generator.f90,v 10.0 2003/10/24 22:01:43 fms Exp $' - character(len=128), parameter :: tagname='$Name: siena_201207 $' + character(len=128), parameter :: tagname='$Name: tikal $' type(atmos_grid_type) :: Hgrid integer :: unit ! output_file io unit diff --git a/src/preprocessing/generate_grids/atmos/atmos_grid_generator.html b/src/preprocessing/generate_grids/atmos/atmos_grid_generator.html deleted file mode 100644 index bfd9de6c6a..0000000000 --- a/src/preprocessing/generate_grids/atmos/atmos_grid_generator.html +++ /dev/null @@ -1,106 +0,0 @@ - - - -Program grid_generator - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
            -

            Program grid_generator

            - - -
            -Contact: Z. Liang -
            -Reviewers: S. M. Griffies -
            -Change History: WebCVS Log -
            -
            -
            - - -
            -

            OVERVIEW

            - -

            - Generate horizontal grid for atmosphere or land model. - The grid is either bgrid or spectral grid. -

            - - - -
            -
            - - -
            -

            MODULES USED

            - -
            -
                   fms_mod
            mpp_mod
            mpp_io_mod
            atmos_grid_mod
            constants_mod
            -
            - - - -
            -

            PUBLIC INTERFACE

            -
            -
            -
            -
            - - -
            -

            PUBLIC ROUTINES

            - -
              - - - - -
              -

              NAMELIST

              - -
              -&atmos_grid_generator_nml -
              -
              -
              -
              -
              -output_file -
              -
              - name of grid file to be created. Default value is "atmos_grid.nc". -
              -[character(len=128)] -
              -
              -
              -
              -
              - - - - -
              -
              -top -
              - - diff --git a/src/preprocessing/generate_grids/grid_transfer/grid_transfer.F90 b/src/preprocessing/generate_grids/grid_transfer/grid_transfer.F90 index 634a403815..228616e562 100644 --- a/src/preprocessing/generate_grids/grid_transfer/grid_transfer.F90 +++ b/src/preprocessing/generate_grids/grid_transfer/grid_transfer.F90 @@ -51,7 +51,7 @@ program grid_transfer !---------version information------------------------------------------- character(len=128) :: version = '$Id: grid_transfer.F90,v 13.0 2006/03/28 21:44:17 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- integer :: nlon, nlat, nk diff --git a/src/preprocessing/generate_grids/grid_transfer/grid_transfer.csh b/src/preprocessing/generate_grids/grid_transfer/grid_transfer.csh index 7e925d6baf..b274bffee3 100755 --- a/src/preprocessing/generate_grids/grid_transfer/grid_transfer.csh +++ b/src/preprocessing/generate_grids/grid_transfer/grid_transfer.csh @@ -18,7 +18,7 @@ ####################################################################### set echo - set platform = "gfdl_ws_64.gnu" # A unique identifier for your platform + set platform = "ncrc.intel" # A unique identifier for your platform set npes = 1 # number of processors # diff --git a/src/preprocessing/generate_grids/grid_transfer/grid_transfer.html b/src/preprocessing/generate_grids/grid_transfer/grid_transfer.html deleted file mode 100644 index fe759e98de..0000000000 --- a/src/preprocessing/generate_grids/grid_transfer/grid_transfer.html +++ /dev/null @@ -1,115 +0,0 @@ - - - -Program grid_transfer - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
              -

              Program grid_transfer

              - - -
              -Contact: Z. Liang -
              -Reviewers: S. M. Griffies -
              -Change History: WebCVS Log -
              -
              -
              - - -
              -

              OVERVIEW

              - -

              - Converts the grid specification netcdf file using old name convention to a netcdf - file with new grid name convention. This program can be applied on any ocean grid - or exchange grid. -

              - - - -
              -
              - - -
              -

              MODULES USED

              - -
              -
                    fms_mod
              mpp_mod
              constants_mod
              -
              - - - -
              -

              PUBLIC INTERFACE

              -
              -
              -
              -
              - - -
              -

              PUBLIC ROUTINES

              - -
                - - - - -
                -

                NAMELIST

                - -
                -&grid_transfer_nml -
                -
                -
                -
                -
                -old_grid -
                -
                - name of input grid file to be converted. -
                -[character(len=128)] -
                -
                -new_grid -
                -
                - name of output grid file converted from old_grid. -
                -[character(len=128)] -
                -
                -
                -
                -
                - - - - -
                -
                -top -
                - - diff --git a/src/preprocessing/generate_grids/make_xgrids/make_xgrids.csh b/src/preprocessing/generate_grids/make_xgrids/make_xgrids.csh index 4d59bfd0ec..0c48b50e74 100755 --- a/src/preprocessing/generate_grids/make_xgrids/make_xgrids.csh +++ b/src/preprocessing/generate_grids/make_xgrids/make_xgrids.csh @@ -15,7 +15,7 @@ ####################################################################### set echo set name = "grid_spec" # name of the grid file will be generated - set platform = "gfdl_ws_64.gnu" # A unique identifier for your platform + set platform = "ncrc.intel" # A unique identifier for your platform set npes = 1 # number of processors # set root = $cwd:h:h:h:h # The directory that contains src/ and bin/ @@ -36,8 +36,7 @@ #--create the executable ----------------------------------------------------------- if( ! -d $executable:h ) mkdir $executable:h cd $executable:h -# cc -O -o $executable:t $xgrids_code -I$netcdf3_inc_dir -L$netcdf3_lib_dir -lnetcdf -lm - cc -O -o $executable:t $xgrids_code -lnetcdf -lm + cc -O -o $executable:t $xgrids_code -I$netcdf3_inc_dir -L$netcdf3_lib_dir -lnetcdf -lm #-------------------------------------------------------------------------------------------------------- # setup directory structure diff --git a/src/preprocessing/generate_grids/make_xgrids/make_xgrids.html b/src/preprocessing/generate_grids/make_xgrids/make_xgrids.html deleted file mode 100644 index a19b0e39f1..0000000000 --- a/src/preprocessing/generate_grids/make_xgrids/make_xgrids.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -File preprocessing/generate_grids/make_xgrids/make_xgrids.c - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                -

                File preprocessing/generate_grids/make_xgrids/make_xgrids.c

                - - -
                -Contact:  -
                -Reviewers:  -
                -Change History: WebCVS Log -
                -
                -
                - - -
                -

                OVERVIEW

                - -

                - - - -
                -
                - - -
                -

                MODULES USED

                - -
                -
                
                -
                - - - -
                -

                PUBLIC INTERFACE

                -
                -
                -
                -
                - - -
                -

                PUBLIC ROUTINES

                - -
                  - - - - - - -
                  -
                  -top -
                  - - diff --git a/src/preprocessing/generate_grids/ocean/check_mask.html b/src/preprocessing/generate_grids/ocean/check_mask.html deleted file mode 100644 index c7bf1e567b..0000000000 --- a/src/preprocessing/generate_grids/ocean/check_mask.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module check_mask_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                  -

                  Module check_mask_mod

                  - - -
                  -Contact:  -
                  -Reviewers:  -
                  -Change History: WebCVS Log -
                  -
                  -
                  - - -
                  -

                  OVERVIEW

                  - -

                  - - - -
                  -
                  - - -
                  -

                  OTHER MODULES USED

                  - -
                  -
                          mpp_mod
                  mpp_domains_mod
                  fms_mod
                  -
                  - - - -
                  -

                  PUBLIC INTERFACE

                  -
                  -
                  -
                  -
                  - - -
                  -

                  PUBLIC ROUTINES

                  - -
                    - - - - - - -
                    -
                    -top -
                    - - diff --git a/src/preprocessing/generate_grids/ocean/check_mask.xml b/src/preprocessing/generate_grids/ocean/check_mask.xml deleted file mode 100644 index 5c254339ac..0000000000 --- a/src/preprocessing/generate_grids/ocean/check_mask.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/src/preprocessing/generate_grids/ocean/compare_grid.f90 b/src/preprocessing/generate_grids/ocean/compare_grid.f90 index e7a4ae1eff..12ae62f066 100644 --- a/src/preprocessing/generate_grids/ocean/compare_grid.f90 +++ b/src/preprocessing/generate_grids/ocean/compare_grid.f90 @@ -72,7 +72,7 @@ program compare_grid !--- version information variables ----------------------------------- character(len=128) :: version = '$Id: compare_grid.f90,v 11.0 2004/09/28 20:07:16 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--- compare_grid_type type compare_grid_type diff --git a/src/preprocessing/generate_grids/ocean/compare_grid.html b/src/preprocessing/generate_grids/ocean/compare_grid.html deleted file mode 100644 index 2151e271b2..0000000000 --- a/src/preprocessing/generate_grids/ocean/compare_grid.html +++ /dev/null @@ -1,142 +0,0 @@ - - - -Program compare_grid - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                    -

                    Program compare_grid

                    - - -
                    -Contact: Z. Liang -
                    -Reviewers: S. M. Griffies -
                    -Change History: WebCVS Log -
                    -
                    -
                    - - -
                    -

                    OVERVIEW

                    - -

                    - compare depth and land/sea mask of two grid_spec file. -

                    - - - -
                    - This program reads in two grid descriptor files (generated via ocean_grid_generator) - and creates a text file output listing line-by-line differences between the - two files. Output file format is the same as the grid_edits file used by - edit_grid.F90. These two files should have same grid size. - - Originally developed by Jeffery B. Greenblatt on 12/11/2001 at Princeton University -
                    -
                    - - -
                    -

                    MODULES USED

                    - -
                    -
                       mpp_mod
                    mpp_io_mod
                    fms_mod
                    -
                    - - - -
                    -

                    PUBLIC INTERFACE

                    -
                    -
                    -
                    -
                    - - -
                    -

                    PUBLIC ROUTINES

                    - -
                      - - - - -
                      -

                      NAMELIST

                      - -
                      -&compare_grid_nml -
                      -
                      -
                      -
                      -
                      -grid_file_1 -
                      -
                      - First grid files to be compared with grid_file_2. -
                      -[character(len=128)] -
                      -
                      -grid_file_2 -
                      -
                      - Second grid files to be compared with grid_file_1. -
                      -[character(len=128)] -
                      -
                      -grid_edits -
                      -
                      - output text file. Each line is in the format as - "i, j, depth_new, #was depth_old ". depth_new is - the depth at point (i,j) of grid_file_2 and depth_old - is the depth at point (i,j) of grid_file_1. -
                      -[character(len=128)] -
                      -
                      -mask_diff -
                      -
                      - output text file. Each line is in the format as - "i, j, wet_new, #was wet_old ". wet_new is - the land/sea mask at point (i,j) of grid_file_2 and wet_old - is the land/sea mask at point (i,j) of grid_file_1. -
                      -[character(len=128)] -
                      -
                      -
                      -
                      -
                      - - - - -
                      -
                      -top -
                      - - diff --git a/src/preprocessing/generate_grids/ocean/compare_grid.xml b/src/preprocessing/generate_grids/ocean/compare_grid.xml deleted file mode 100644 index acf2b9f086..0000000000 --- a/src/preprocessing/generate_grids/ocean/compare_grid.xml +++ /dev/null @@ -1,27 +0,0 @@ - - -Z. Liang S. M. Griffies - compare depth and land/sea mask of two grid_spec file. - - This program reads in two grid descriptor files (generated via ocean_grid_generator) - and creates a text file output listing line-by-line differences between the - two files. Output file format is the same as the grid_edits file used by - edit_grid.F90. These two files should have same grid size. - - Originally developed by Jeffery B. Greenblatt on 12/11/2001 at Princeton University - - First grid files to be compared with grid_file_2. - - Second grid files to be compared with grid_file_1. - - output text file. Each line is in the format as - "i, j, depth_new, #was depth_old ". depth_new is - the depth at point (i,j) of grid_file_2 and depth_old - is the depth at point (i,j) of grid_file_1. - - output text file. Each line is in the format as - "i, j, wet_new, #was wet_old ". wet_new is - the land/sea mask at point (i,j) of grid_file_2 and wet_old - is the land/sea mask at point (i,j) of grid_file_1. - diff --git a/src/preprocessing/generate_grids/ocean/edit_grid.F90 b/src/preprocessing/generate_grids/ocean/edit_grid.F90 index 4fd71a3a13..7cff3c0280 100644 --- a/src/preprocessing/generate_grids/ocean/edit_grid.F90 +++ b/src/preprocessing/generate_grids/ocean/edit_grid.F90 @@ -85,7 +85,7 @@ program edit_grid !--- version information variables ----------------------------------- character(len=128) :: version = '$Id: edit_grid.F90,v 19.0 2012/01/06 22:07:48 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- logical :: tripolar_grid =.false. ! indicate the grid is tripolar grid or not. logical :: cyclic_x =.false. ! true indicate cyclic in x-direction diff --git a/src/preprocessing/generate_grids/ocean/edit_grid.html b/src/preprocessing/generate_grids/ocean/edit_grid.html deleted file mode 100644 index 66b5022c5d..0000000000 --- a/src/preprocessing/generate_grids/ocean/edit_grid.html +++ /dev/null @@ -1,145 +0,0 @@ - - - -Program edit_grid - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                      -

                      Program edit_grid

                      - - -
                      -Contact: Z. Liang -
                      -Reviewers: S. M. Griffies -
                      -Change History: WebCVS Log -
                      -
                      -
                      - - -
                      -

                      OVERVIEW

                      - -

                      - edit grid topography. -

                      - - - -
                      - This program can edit the topography of input grid_spec file "orig_grid" - according to the ascii input file "grid_edits". Then it will output the - new grid_spec file "mod_grid". The program read file "grid_edits" line - by line. Each line contains grid points position and new topography value - of those grid points. The grid points position is specified by the grid - index. You can specify a point or a region at each line. For example, -
                       100, 60, 0 
                      - will set the depth at point (100,60) to 0. 
                      - 40:45, 30:34, 1000
                      - will set the depth at region ( index i from 54 to 50 and j from 30 to 34 ) to 1000.
                      - - -
                      -
                      - - -
                      -

                      MODULES USED

                      - -
                      -
                            mpp_mod
                      mpp_io_mod
                      fms_mod
                      constants_mod
                      topog_mod
                      -
                      - - - -
                      -

                      PUBLIC INTERFACE

                      -
                      -
                      -
                      -
                      - - -
                      -

                      PUBLIC ROUTINES

                      - -
                        - - - - -
                        -

                        NAMELIST

                        - -
                        -&edit_grid_nml -
                        -
                        -
                        -
                        -
                        -mod_grid -
                        -
                        - original grid file -
                        -[character(len=128)] -
                        -
                        -orig_grid -
                        -
                        - output grid file after modification. -
                        -[character(len=128)] -
                        -
                        -grid_edits -
                        -
                        - input text file. Each line is in the format as - "is:ie, js:je, depth", which means set the depth at region - (is:ie, js:je) to value "depth". is and ie can be equal or - different. js and je can be same or different. -
                        -[character(len=128)] -
                        -
                        -debug -
                        -
                        - Control standard output. Default value is false. -
                        -[logical] -
                        -
                        -
                        -
                        -
                        - - - - -
                        -
                        -top -
                        - - diff --git a/src/preprocessing/generate_grids/ocean/edit_grid.xml b/src/preprocessing/generate_grids/ocean/edit_grid.xml deleted file mode 100644 index c8cc5edf48..0000000000 --- a/src/preprocessing/generate_grids/ocean/edit_grid.xml +++ /dev/null @@ -1,29 +0,0 @@ - - -Z. Liang S. M. Griffies - edit grid topography. - - This program can edit the topography of input grid_spec file "orig_grid" - according to the ascii input file "grid_edits". Then it will output the - new grid_spec file "mod_grid". The program read file "grid_edits" line - by line. Each line contains grid points position and new topography value - of those grid points. The grid points position is specified by the grid - index. You can specify a point or a region at each line. For example, -
                         100, 60, 0 
                        - will set the depth at point (100,60) to 0. 
                        - 40:45, 30:34, 1000
                        - will set the depth at region ( index i from 54 to 50 and j from 30 to 34 ) to 1000.
                        - -
                        - original grid file - - output grid file after modification. - - input text file. Each line is in the format as - "is:ie, js:je, depth", which means set the depth at region - (is:ie, js:je) to value "depth". is and ie can be equal or - different. js and je can be same or different. - - Control standard output. Default value is false. -
                        diff --git a/src/preprocessing/generate_grids/ocean/grids_type.html b/src/preprocessing/generate_grids/ocean/grids_type.html deleted file mode 100644 index 0bcd3ca702..0000000000 --- a/src/preprocessing/generate_grids/ocean/grids_type.html +++ /dev/null @@ -1,156 +0,0 @@ - - - -Module grids_type_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                        -

                        Module grids_type_mod

                        - - -
                        -Contact: Z. Liang -
                        -Reviewers: S. M. Griffies -
                        -Change History: WebCVS Log -
                        -
                        -
                        - - -
                        -

                        OVERVIEW

                        - -

                        - Define grid types, including cell type, horizontal grid, vertical grid and topography type -

                        - - - -
                        - From discussions with Robert Hallberg, as a prototype for ESMF -
                        -
                        - - -
                        -

                        OTHER MODULES USED

                        - -
                        -
                        mpp_domains_mod
                        -
                        - - - -
                        -

                        PUBLIC INTERFACE

                        -
                        -
                        -
                        -
                        - - -
                        -

                        PUBLIC ROUTINES

                        - -
                          - - - -
                          -

                          PUBLIC TYPES

                          -
                          - - - - - - - - - - - - - -
                          -
                            type cell_type
                          -     real, dimension(:,:), pointer   :: x => NULL()        ! geographical longitude of cell center
                          -     real, dimension(:,:), pointer   :: y => NULL()        ! geographical latitude of cell center 
                          -     real, dimension(:,:,:), pointer :: x_vert => NULL()   ! geographical longitude of cell vertices
                          -     real, dimension(:,:,:), pointer :: y_vert => NULL()   ! geographical latitude of cell vertices
                          -     real, dimension(:,:), pointer   :: area => NULL()     ! cell area
                          -     real, dimension(:,:), pointer   :: angle => NULL()    ! Angle between i-unit and x-unit vector of cell
                          -     real, dimension(:,:), pointer   :: ds_00_02 => NULL() ! Length of western face of cell
                          -     real, dimension(:,:), pointer   :: ds_20_22 => NULL() ! Length of eastern face of cell
                          -     real, dimension(:,:), pointer   :: ds_02_22 => NULL() ! Length of northern face of cell
                          -     real, dimension(:,:), pointer   :: ds_00_20 => NULL() ! Length of southern face of cell
                          -     real, dimension(:,:), pointer   :: ds_01_21 => NULL() ! width of cell
                          -     real, dimension(:,:), pointer   :: ds_10_12 => NULL() ! height of cell
                          -     real, dimension(:,:), pointer   :: ds_00_01 => NULL() ! Distance from southwest corner to western face center of cell
                          -     real, dimension(:,:), pointer   :: ds_01_02 => NULL() ! Distance from northwest corner to western face center of cell
                          -     real, dimension(:,:), pointer   :: ds_02_12 => NULL() ! Distance from northwest corner to northern face center of cell
                          -     real, dimension(:,:), pointer   :: ds_12_22 => NULL() ! Distance from northeast corner to northern face center of cell
                          -     real, dimension(:,:), pointer   :: ds_21_22 => NULL() ! Distance from northeast corner to eastern face center of cell
                          -     real, dimension(:,:), pointer   :: ds_20_21 => NULL() ! Distance from southeast corner to eastern face center of cell
                          -     real, dimension(:,:), pointer   :: ds_10_20 => NULL() ! Distance from southeast corner to southern face center of cell
                          -     real, dimension(:,:), pointer   :: ds_00_10 => NULL() ! Distance from southwest corner to southern face center of cell
                          -     real, dimension(:,:), pointer   :: ds_01_11 => NULL() ! Distance from center to western face of cell
                          -     real, dimension(:,:), pointer   :: ds_11_12 => NULL() ! Distance from center to northern face of cell
                          -     real, dimension(:,:), pointer   :: ds_11_21 => NULL() ! Distance from center to eastern face of cell 
                          -     real, dimension(:,:), pointer   :: ds_10_11 => NULL() ! Distance from center to southern face of cell
                          -  end type cell_type
                          -
                          -
                            type hgrid_data_type
                          -     type(cell_type) :: T             ! T-cell
                          -     type(cell_type) :: E             ! E-cell
                          -     type(cell_type) :: N             ! N-cell
                          -     type(cell_type) :: C             ! C-cell
                          -     logical         :: tripolar_grid ! true means tripolar grid
                          -     logical         :: cyclic_x      ! true means cyclic in i-direction
                          -     logical         :: cyclic_y      ! true means cyclic in j-direction
                          -     integer         :: ni, nj        ! grid size
                          -     type(domain2d)  :: Domain
                          -  end type hgrid_data_type
                          -
                          -
                            type vgrid_data_type
                          -     real, dimension(:), pointer :: zt => NULL()   ! vertical level at T-cell center 
                          -     real, dimension(:), pointer :: zb => NULL()   ! vertical level at T-cell boundary
                          -  end type vgrid_data_type
                          -
                          -
                            type topog_data_type
                          -     real, dimension(:,:), pointer :: depth_t => NULL()    ! topographic depth of T-cell
                          -     real, dimension(:,:), pointer :: num_levels => NULL() ! number of vertical T-cells
                          -     real, dimension(:,:), pointer :: wet => NULL()        ! wet mask of T-cell
                          -     real, dimension(:,:), pointer :: depth_c => NULL()    ! topographic depth of C-cell
                          -     real, dimension(:,:), pointer :: num_levels_c => NULL() ! number of vertical C-cells
                          -     real, dimension(:,:), pointer :: wet_c => NULL()        ! wet mask of C-cell
                          -  end type topog_data_type
                          -
                          -
                          -
                          - - - - -
                          -
                          -top -
                          - - diff --git a/src/preprocessing/generate_grids/ocean/grids_type.xml b/src/preprocessing/generate_grids/ocean/grids_type.xml deleted file mode 100644 index 1878e22206..0000000000 --- a/src/preprocessing/generate_grids/ocean/grids_type.xml +++ /dev/null @@ -1,53 +0,0 @@ - - -Z. Liang S. M. Griffies - Define grid types, including cell type, horizontal grid, vertical grid and topography type - - From discussions with Robert Hallberg, as a prototype for ESMF - type cell_type - real, dimension(:,:), pointer :: x => NULL() ! geographical longitude of cell center - real, dimension(:,:), pointer :: y => NULL() ! geographical latitude of cell center - real, dimension(:,:,:), pointer :: x_vert => NULL() ! geographical longitude of cell vertices - real, dimension(:,:,:), pointer :: y_vert => NULL() ! geographical latitude of cell vertices - real, dimension(:,:), pointer :: area => NULL() ! cell area - real, dimension(:,:), pointer :: angle => NULL() ! Angle between i-unit and x-unit vector of cell - real, dimension(:,:), pointer :: ds_00_02 => NULL() ! Length of western face of cell - real, dimension(:,:), pointer :: ds_20_22 => NULL() ! Length of eastern face of cell - real, dimension(:,:), pointer :: ds_02_22 => NULL() ! Length of northern face of cell - real, dimension(:,:), pointer :: ds_00_20 => NULL() ! Length of southern face of cell - real, dimension(:,:), pointer :: ds_01_21 => NULL() ! width of cell - real, dimension(:,:), pointer :: ds_10_12 => NULL() ! height of cell - real, dimension(:,:), pointer :: ds_00_01 => NULL() ! Distance from southwest corner to western face center of cell - real, dimension(:,:), pointer :: ds_01_02 => NULL() ! Distance from northwest corner to western face center of cell - real, dimension(:,:), pointer :: ds_02_12 => NULL() ! Distance from northwest corner to northern face center of cell - real, dimension(:,:), pointer :: ds_12_22 => NULL() ! Distance from northeast corner to northern face center of cell - real, dimension(:,:), pointer :: ds_21_22 => NULL() ! Distance from northeast corner to eastern face center of cell - real, dimension(:,:), pointer :: ds_20_21 => NULL() ! Distance from southeast corner to eastern face center of cell - real, dimension(:,:), pointer :: ds_10_20 => NULL() ! Distance from southeast corner to southern face center of cell - real, dimension(:,:), pointer :: ds_00_10 => NULL() ! Distance from southwest corner to southern face center of cell - real, dimension(:,:), pointer :: ds_01_11 => NULL() ! Distance from center to western face of cell - real, dimension(:,:), pointer :: ds_11_12 => NULL() ! Distance from center to northern face of cell - real, dimension(:,:), pointer :: ds_11_21 => NULL() ! Distance from center to eastern face of cell - real, dimension(:,:), pointer :: ds_10_11 => NULL() ! Distance from center to southern face of cell - end type cell_type type hgrid_data_type - type(cell_type) :: T ! T-cell - type(cell_type) :: E ! E-cell - type(cell_type) :: N ! N-cell - type(cell_type) :: C ! C-cell - logical :: tripolar_grid ! true means tripolar grid - logical :: cyclic_x ! true means cyclic in i-direction - logical :: cyclic_y ! true means cyclic in j-direction - integer :: ni, nj ! grid size - type(domain2d) :: Domain - end type hgrid_data_type type vgrid_data_type - real, dimension(:), pointer :: zt => NULL() ! vertical level at T-cell center - real, dimension(:), pointer :: zb => NULL() ! vertical level at T-cell boundary - end type vgrid_data_type type topog_data_type - real, dimension(:,:), pointer :: depth_t => NULL() ! topographic depth of T-cell - real, dimension(:,:), pointer :: num_levels => NULL() ! number of vertical T-cells - real, dimension(:,:), pointer :: wet => NULL() ! wet mask of T-cell - real, dimension(:,:), pointer :: depth_c => NULL() ! topographic depth of C-cell - real, dimension(:,:), pointer :: num_levels_c => NULL() ! number of vertical C-cells - real, dimension(:,:), pointer :: wet_c => NULL() ! wet mask of C-cell - end type topog_data_type diff --git a/src/preprocessing/generate_grids/ocean/grids_util.html b/src/preprocessing/generate_grids/ocean/grids_util.html deleted file mode 100644 index aed8a593cf..0000000000 --- a/src/preprocessing/generate_grids/ocean/grids_util.html +++ /dev/null @@ -1,369 +0,0 @@ - - - -Module grids_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                          -

                          Module grids_util_mod

                          - - -
                          -Contact: Z. Liang -
                          -Reviewers: S. M. Griffies -
                          -Change History: WebCVS Log -
                          -
                          -
                          - - -
                          -

                          OVERVIEW

                          - -

                          - -grids_util_mod contains some public interface used by several modules in - generate_ocean_grid package. -

                          - - - -
                          -
                          - - -
                          -

                          OTHER MODULES USED

                          - -
                          -
                                fms_mod
                          mpp_mod
                          mpp_io_mod
                          constants_mod
                          -
                          - - - -
                          -

                          PUBLIC INTERFACE

                          -
                          -
                          -
                          -write_field_data:
                          -
                          - Write data to corresponding grid file. -
                          -
                          -gcell:
                          -
                          - grid cell construction. -
                          -
                          -get_file_unit:
                          -
                          - returns the io unit corresponding to filename. -
                          -
                          -write_field_meta:
                          -
                          - Write meta data of a field to a netcdf file. -
                          -
                          -set_grid:
                          -
                          - set the axis grid information. -
                          -
                          -
                          -
                          - - -
                          -

                          PUBLIC ROUTINES

                          - -
                            -
                          1. - -

                            write_field_data

                            - - - - -
                            -
                              subroutine write_field_data(filename, fieldname, fielddata)
                            -
                            -
                            -
                            -
                            -DESCRIPTION -
                            -
                            - For the purpose of generating higher resolution grid. There is a - 2 GB limit of each grid file. The interface will allow the grid information - be stored at multiple files. -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - - - - - - - -
                            filename    - The name of the grid file to be generated. If the grid file is - over 2 GB limit, it will break into several files with file name filename, - filename2, filename3 .... -
                               [character(len=*)]
                            fieldname    - name of the field to be written into the file filename -
                               [character(len=*)]
                            fielddata    - data of fieldname to be written to the file filename. -
                               [real, dimension(:,:)] -
                               [real, dimension(:,:,:)]
                            -
                            -
                            -
                            -
                          2. -
                          3. - -

                            gcell

                            -
                            -call gcell (maxlen, n_bounds, bounds, d_bounds, nbpts, num, deltat, deltau, stretch)
                            -
                            -
                            -DESCRIPTION -
                            -
                            - A domain is composed of one or more regions: Build "num" T cells with resolution - "deltat(n) n=1,num" within the domain composed of regions bounded by "bounds". - Also construct "num" C-cells of resolution "deltau(n) n=1,num" with the relation - between T and U cells given by: deltat(n) = 0.5*(deltau(n-1) + deltau(n)). - Resolution may be constant or smoothly varying within each region AND there must - be an integral number of grid cells within each region. The domain is the sum of all regions. -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - - - - - - - - - - - - - - - - - - - -
                            maxlen    - maximum length of "deltat" and "deltau" -
                               [integer]
                            n_bounds    - number of bounds needed to define the regions -
                               [integer]
                            bounds    - latitude, longitude, or depth at each bound -
                               [real, dimension(n_bounds)]
                            d_bounds    - delta (resolution) at each of the "bounds" -
                               [real, dimension(n_bounds)]
                            nbpts    - number of extra boundary cells to add to the domain. (usually one at the beginning and end) -
                               [integer]
                            stretch    - stretching factor for last region (should only be used in the vertical) to provide - increased stretching of grid points. "stretch" = 1.0 gives no increased stretching. - "stretch" = 1.2 gives increased stretching...etc -
                               [real]
                            debug    - flag that controls standard output. -
                               [logical, optional]
                            -
                            -
                            -
                            -OUTPUT -
                            -
                            - - - - - - - - - - -
                            num    - total number of grid cells within the domain -
                               [integer]
                            deltat    - resolution of T grid cells: n=1,num -
                               [real, dimension(1-nbpts:maxlen)]
                            deltau    - resolution of C grid cells: n=1,num -
                               [real, dimension(1-nbpts:maxlen)]
                            -
                            -
                            -
                            -
                          4. -
                          5. - -

                            get_file_unit

                            -
                             
                            -get_file_unit (filename)
                            -
                            -
                            -DESCRIPTION -
                            -
                            - If the file filename is already open, return the io unit of this - opened file. Otherwise will open the file and return the io unit. -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - -
                            filename    - The name of the grid file to be generated. -
                               [character(len=*)]
                            -
                            -
                            -
                            -
                          6. -
                          7. - -

                            write_field_meta

                            -
                            -call write_field_meta (filename, fieldname, units, field_longname, fielddim, x_pos, y_pos)
                            -
                            -
                            -DESCRIPTION -
                            -
                            - It will check if the grid file will over the 2 GB limit. If do, will open - a new file with name filename? (? is 1, 2, 3 ....) and write axis metadata - to the new file. -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - - - - - - - - - - - - - - - - -
                            filename    - The name of the grid file to be generated. If the grid file is - over 2 GB limit, it will break into several files with file name filename, - filename1, filename2, filename3 .... -
                               [character(len=*)]
                            fieldname    - name of the field to be written into the file filename -
                               [character(len=*)]
                            units    - units of field fieldname. -
                               [character(len=*)]
                            field_longname    - longname of fielname. -
                               [character(len=*)]
                            fielddim    - Indicate the dimension of fieldname. fielddim should be either 2 or 3. -
                               [integer]
                            x_pos, y_pos    - To indicate the cell position. its value can be "T" or "C". -
                               [character(len=1)]
                            -
                            -
                            -
                            -
                          8. -
                          9. - -

                            set_grid

                            -
                            -call set_grid (grid_xt, grid_yt, grid_xc, grid_yc)
                            -
                            -
                            -DESCRIPTION -
                            -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - - - - -
                            grid_xt, grid_yt    - longitude and latitude of the T-cell grid. -
                               [real, dimension(:)]
                            grid_xc, grid_yc    - longitude and latitude of the C-cell grid. -
                               [real, dimension(:)]
                            -
                            -
                            -
                            -
                          10. -
                          - - - - - - -
                          -
                          -top -
                          - - diff --git a/src/preprocessing/generate_grids/ocean/hgrid.f90 b/src/preprocessing/generate_grids/ocean/hgrid.f90 index 3c7b830894..9d7a604cc8 100644 --- a/src/preprocessing/generate_grids/ocean/hgrid.f90 +++ b/src/preprocessing/generate_grids/ocean/hgrid.f90 @@ -304,7 +304,7 @@ module hgrid_mod !---------version information------------------------------------------- character(len=128) :: version = '$Id: hgrid.f90,v 14.0 2007/03/15 22:46:29 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !---------public interface---------------------------------------------- public :: generate_hgrid, hgrid_init, hgrid_end, write_hgrid_global_meta diff --git a/src/preprocessing/generate_grids/ocean/hgrid.html b/src/preprocessing/generate_grids/ocean/hgrid.html deleted file mode 100644 index c69e2bd086..0000000000 --- a/src/preprocessing/generate_grids/ocean/hgrid.html +++ /dev/null @@ -1,553 +0,0 @@ - - - -Module hgrid_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                          -

                          Module hgrid_mod

                          - - -
                          -Contact: Z. Liang -
                          -Reviewers: S. M. Griffies -
                          -Change History: WebCVS Log -
                          -
                          -
                          - - -
                          -

                          OVERVIEW

                          - -

                          - -hgrid_mod Generate horizontal grid. The horizontal grid can be conventional lon-lat - spherical grid or a reprojected rotated tripolar grid (R. Murray, "Explicit generation of - orthogonal grids for ocean models", 1996, J.Comp.Phys., v. 126, p. 251-273.). -

                          - - - -
                          - There are four subgrids, labeled T (for tracer), C (corner of T), N (north of T) and E (east of T). - The following schematic describes the grid cell notation. - - -
                                                    Ni,j
                          -               +----------+-----------+Ci,j
                          -               |                      |     
                          -               |                      |
                          -               |                      |
                          -               +          +Ti,j       +Ei,j
                          -               |                      |
                          -               |                      |
                          -               +----------+-----------+
                          - - The grid_spec file would contains all of the following information on each subgrid. - The following example is for T subgrid. Repeated for E, C, and N subgrids. - - -
                             x_T, y_T           = Geographic location of T-cell center
                          -   x_vert_T, y_vert_T = Geographic location of T-cell vertices(each cell has 4 vertices)
                          -   area_T             = area of T-cell
                          -   angle_T            = Angle clockwise between logical and geographic east of T-cell
                          -   ds_00_02_T         = Length of western face of T-cell
                          -   ds_20_22_T         = Length of eastern face of T-cell
                          -   ds_02_22_T         = Length of northern face of T-cell
                          -   ds_00_20_T         = Length of southern face of T-cell
                          -   ds_00_01_T         = Distance from southwest corner to western face center of T-cell
                          -   ds_01_02_T         = Distance from northwest corner to western face center of T-cell
                          -   ds_02_12_T         = Distance from northwest corner to northern face center of T-cell
                          -   ds_12_22_T         = Distance from northeast corner to northern face center of T-cell
                          -   ds_21_22_T         = Distance from northeast corner to eastern face center of T-cell
                          -   ds_20_21_T         = Distance from southeast corner to eastern face center of T-cell
                          -   ds_10_20_T         = Distance from southeast corner to southern face center of T-cell
                          -   ds_00_10_T         = Distance from southwest corner to southern face center of T-cell
                          -   ds_01_11_T         = Distance from center to western face of T-cell
                          -   ds_11_12_T         = Distance from center to northern face of T-cell
                          -   ds_11_21_T         = Distance from center to eastern face of T-cell
                          -   ds_10_11_T         = Distance from center to southern face of T-cell
                          -   ds_01_21_T         = width of T-cell
                          -   ds_10_12_T         = height of T-cell
                          -
                          -  Distances between points are described in the following schematics (for T-cell).
                          -   
                          -
                          -
                          -               +<----ds_02_12_T---->+<----ds_12_22_T---->+
                          -               ^                    ^                    ^
                          -               |                    |                    |
                          -               |                    |                    |
                          -          ds_01_02_T           ds_11_12_T           ds_21_22_T
                          -               |                    |                    |
                          -               |                    |                    |
                          -               v                    v                    v
                          -               +<----ds_01_11_T---->+<----ds_11_21_T---->+
                          -               ^                    ^                    ^
                          -               |                    |                    |
                          -               |                    |                    |
                          -          ds_00_01_T           ds_10_11_T           ds_20_21_T
                          -               |                    |                    |
                          -               |                    |                    |
                          -               v                    v                    v
                          -               +<----ds_00_10_T---->+<----ds_10_20_T---->+
                          -
                          -
                          -
                          -               <-------------- ds_02_22_T---------------->
                          -             ^ +--------------------+--------------------+ ^
                          -             | |                    ^                    | |
                          -             | |                    |                    | |
                          -             | |                    |                    | |
                          -             | |                    |                    | |
                          -             | |                    |                    | |
                          -     ds_00_02_T|<-------------------+--ds_01_21_T------->| ds_20_22_T              
                          -             | |                    |                    | |
                          -             | |               ds_10_12_T                | |
                          -             | |                    |                    | |
                          -             | |                    |                    | |
                          -             | |                    |                    | | 
                          -             | |                    v                    | |
                          -             v +--------------------+--------------------+ v
                          -               <-------------- ds_00_20_T---------------->
                          -
                          -
                          -   The other three subgrids (E, N, C subgrids) have similiar name but replacing T.
                          -
                          - Axis specifications involve specifying the number of regions for varying
                          - resolution, the bondaries of said regions and the nominal resolution in 
                          - the respective regions.  
                          -
                          - For instance, for longitude axis specification:
                          -
                          -        dx_lon(1) = 4                         dx_lon(2) = 6
                          - |<----|----|----|----|----|----|------|------|------|------|------|------>|
                          - |                              |                                          |
                          - x_lon(1)                    x_lon(2)                                   x_lon(3)
                          -
                          - Grid cells are constructed such that
                          - 
                          - dxt(i) = 0.5*(dxu(i-1)+dxu(i))
                          - - -
                          -
                          - - -
                          -

                          OTHER MODULES USED

                          - -
                          -
                                  mpp_mod
                          mpp_io_mod
                          mpp_domains_mod
                          fms_mod
                          constants_mod
                          axis_utils_mod
                          grids_type_mod
                          grids_util_mod
                          -
                          - - - -
                          -

                          PUBLIC INTERFACE

                          -
                          -
                          -
                          -hgrid_init:
                          -
                          - Initialization routine. -
                          -
                          -generate_hgrid:
                          -
                          - Generate horizontal grid. -
                          -
                          -write_hgrid_data:
                          -
                          - write the Hgrid data to netcdf file -
                          -
                          -write_hgrid_meta:
                          -
                          - Write out horizontal grid meta data. -
                          -
                          -hgrid_end:
                          -
                          - Destruction routine. -
                          -
                          -
                          -
                          - - -
                          -

                          PUBLIC ROUTINES

                          - -
                            -
                          1. - -

                            hgrid_init

                            -
                            -call hgrid_init ( )
                            -
                            -
                            -DESCRIPTION -
                            -
                            - Read namelist, write out version and namelist informaiton, generate longitude - and latitude resolution. -
                            -
                            -
                            -
                            -
                          2. -
                          3. - -

                            generate_hgrid

                            -
                            -call generate_hgrid (Hgrid)
                            -
                            -
                            -DESCRIPTION -
                            -
                            - Define geographical locations of center and vertices of - T, C, E, N-cell and also calculate the area, orientation, cell size, face lengths, - half face lengths and center to face size of each T, E, C, N cell. -
                            -
                            -
                            -
                            -INPUT/OUTPUT -
                            -
                            - - - - -
                            Hgrid    - A derived-type variable that contains horizontal grid information. -
                               [hgrid_data_type]
                            -
                            -
                            -
                            -
                          4. -
                          5. - -

                            write_hgrid_data

                            -
                            -call write_hgrid_data (unit,Hgrid)
                            -
                            -
                            -DESCRIPTION -
                            -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - - - - -
                            unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                               [integer]
                            Hgrid    - A derived-type variable that contains horizontal grid information. -
                               [hgrid_data_type]
                            -
                            -
                            -
                            -
                          6. -
                          7. - -

                            write_hgrid_meta

                            -
                            -call write_hgrid_meta (unit, Hgrid, axis_x, axis_y)
                            -
                            -
                            -DESCRIPTION -
                            -
                            -
                            -
                            -
                            -INPUT -
                            -
                            - - - - - - - -
                            unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                               [integer]
                            Hgrid    - A derived-type variable that contains horizontal grid information. -
                               [hgrid_data_type]
                            -
                            -
                            -
                            -OUTPUT -
                            -
                            - - - - -
                            axis_x, axis_y    - axis of T-cell center -
                               [type(axistype), optional]
                            -
                            -
                            -
                            -
                          8. -
                          9. - -

                            hgrid_end

                            -
                            -call hgrid_end ( Hgrid )
                            -
                            -
                            -DESCRIPTION -
                            -
                            - Deallocates memory used by "hgrid_data_type" variables. -
                            -
                            -
                            -
                            -INPUT/OUTPUT -
                            -
                            - - - - -
                            Hgrid    - A derived-type variable that contains horizontal grid information. -
                               [hgrid_data_type]
                            -
                            -
                            -
                            -
                          10. -
                          - - - - -
                          -

                          NAMELIST

                          - -
                          -&hgrid_nml -
                          -
                          -
                          -
                          -
                          -nxlons -
                          -
                          - number of zonal regions for varying resolution -
                          -[integer] -
                          -
                          -nylats -
                          -
                          - number of latitude regions for varying resolution -
                          -[integer] -
                          -
                          -x_lon -
                          -
                          - boundaries for defining zonal regions of varying resolution. When tripolar_grid - is .true., x_lon also defines the longitude of the two new poles. - lon_start = x_lon(1) and lon_end = x_lon(nxlons) are longitude of the two new - poles. In this case, the program will ignore the value x_lon(2:nxlons-1) - and set grid resolution to dx_lon(1). When tripolar_grid is true, you - need to be careful about your choice of x_lon, because there might be ocean - at the grid singularity. The recommended choice of x_lon is x_lon = -280,80, - this will put the singularity over land. -
                          -[real, dimension(nxlons), units: degrees] -
                          -
                          -dx_lon -
                          -
                          - nominal resolution of zonal regions -
                          -[real, dimension(nxlons), units: degrees] -
                          -
                          -cyclic_x -
                          -
                          - True if grid is connected in i-direction -
                          -[logical] -
                          -
                          -cyclic_y -
                          -
                          - True if grid is connected in j-direction -
                          -[logical] -
                          -
                          -y_lat -
                          -
                          - boundaries for defining meridional regions of varying resolution -
                          -[real, dimension(nylats), units: degrees] -
                          -
                          -dy_lat -
                          -
                          - nominal resolution of meridional regions -
                          -[real, dimension(nxlons), units: degrees] -
                          -
                          -tripolar_grid -
                          -
                          - convert portion of spherical grid north of lat_join to a bipolar rotated grid -
                          -[logical] -
                          -
                          -square_grid -
                          -
                          - latitudinal grid spacing matches convergence of meridians -
                          -[logical] -
                          -
                          -extend_square_grid -
                          -
                          - extend square grid to poles -
                          -[logical] -
                          -
                          -lat_join -
                          -
                          - requested latitude for joining spherical and rotated bipolar grid -
                          -[real] -
                          -
                          -read_my_grid -
                          -
                          - read ASCII grid information for supplying user-defined grids. -
                          -[logical] -
                          -
                          -my_grid_file -
                          -
                          - Name of ASCII user grid file -
                          -[character(len=128)] -
                          -
                          -f_plane -
                          -
                          - For setting geometric fractors according to f-plane. -
                          -[logical] -
                          -
                          -beta_plane -
                          -
                          - For setting geometric fractors according to beta plane. -
                          -[logical] -
                          -
                          -f_plane_latitude -
                          -
                          - Central latitude to define f_plane and beta_plane. -
                          -[real] -
                          -
                          -simple_cartesian -
                          -
                          - For setting simple cartesian grid. When set true, simple_cartesian_dx - and simple_cartesian_dy need to be set. The grid box length in x-direction - will be uniform to be simple_cartesian_dx. The grid box length in y-direction - will be uniform to be simple_cartesian_dy. -
                          -[logical] -
                          -
                          -simple_cartesian_dx -
                          -
                          - uniform grid length in x-direction ( units is meter). -
                          -[real] -
                          -
                          -debug -
                          -
                          - uniform grid length in y-direction ( units is meter). -
                          -[logical] -
                          -
                          -
                          -
                          -
                          - - - - -
                          -
                          -top -
                          - - diff --git a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.csh b/src/preprocessing/generate_grids/ocean/ocean_grid_generator.csh index a2d3b59716..38e808d3b7 100755 --- a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.csh +++ b/src/preprocessing/generate_grids/ocean/ocean_grid_generator.csh @@ -21,7 +21,7 @@ ####################################################################### set echo - set platform = "gfdl_ws_64.intel" # A unique identifier for your platform + set platform = "ncrc.intel" # A unique identifier for your platform set npes = 1 # number of processors # # input data file and destination grid diff --git a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.f90 b/src/preprocessing/generate_grids/ocean/ocean_grid_generator.f90 index e617952b50..d231c60dda 100644 --- a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.f90 +++ b/src/preprocessing/generate_grids/ocean/ocean_grid_generator.f90 @@ -56,7 +56,7 @@ program ocean_grid_generator implicit none character(len=128) :: version= '$Id: ocean_grid_generator.f90,v 13.0 2006/03/28 21:44:58 fms Exp $' - character(len=128) :: tagname='$Name: siena_201207 $' + character(len=128) :: tagname='$Name: tikal $' type(hgrid_data_type) :: Hgrid type(vgrid_data_type) :: Vgrid diff --git a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.html b/src/preprocessing/generate_grids/ocean/ocean_grid_generator.html deleted file mode 100644 index 4af96794c1..0000000000 --- a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.html +++ /dev/null @@ -1,130 +0,0 @@ - - - -Program ocean_grid_generator - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                          -

                          Program ocean_grid_generator

                          - - -
                          -Contact: Z. Liang -
                          -Reviewers: S. M. Griffies -
                          -Change History: WebCVS Log -
                          -
                          -
                          - - -
                          -

                          OVERVIEW

                          - -

                          - Generate a grid specification data file for ocean. -

                          - - - -
                          - This program can generate horizontal grid, vertical grid or grids with topography and land/sea mask. . - The namelist option grid_type control the type of grid created. when grid_type equal -
                           1. "hgrid": only horizontal grid will be created.
                          - 2. "vgrid": only vertical grid will be created
                          - 4. "hgrid_topog" : horizontal grid, topography and land/sea mask will be created. 
                          -    Topography is obtained by remapping onto current grid from some topography source data. 
                          -    land/sea mask is determined by the topography. In this case, topography does not depend 
                          -    on vertical grid and no vertical grid will be created. You need to set topog_depend_on_vgrid of 
                          -    topog_nml to .false. .
                          - 5. "hgrid_vgrid_topog": horizontal grid, vertical grid, topography and land/sea mask 
                          -    will be created. The topography is mom4-specific topography (could be idealized or from 
                          -    some source file), which depends on vertical grid. The land/sea mask is determined by 
                          -    topography. In this case, you need to set topog_depend_on_vgrid of topog_nml to .true. .
                          - -
                          -
                          - - -
                          -

                          MODULES USED

                          - -
                          -
                                 fms_mod
                          mpp_mod
                          mpp_io_mod
                          grids_type_mod
                          hgrid_mod
                          vgrid_mod
                          topog_mod
                          constants_mod
                          -
                          - - - -
                          -

                          PUBLIC INTERFACE

                          -
                          -
                          -
                          -
                          - - -
                          -

                          PUBLIC ROUTINES

                          - -
                            - - - - -
                            -

                            NAMELIST

                            - -
                            -&ocean_grid_generator_nml -
                            -
                            -
                            -
                            -
                            -grid_type -
                            -
                            - Control the type of grid will be created. Its value can be hgrid, vgrid, hgrid_mask, - hgrid_topog_mask, hgrid_vgrid_topog_mask. Default value is hgrid_vgrid_topog. - See module description for details. -
                            -[character(len=64)] -
                            -
                            -output_file -
                            -
                            - name of grid file to be created. Default value is "ocean_grid.nc". -
                            -[character(len=128)] -
                            -
                            -
                            -
                            -
                            - - - - -
                            -
                            -top -
                            - - diff --git a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.xml b/src/preprocessing/generate_grids/ocean/ocean_grid_generator.xml deleted file mode 100644 index c22feaaf27..0000000000 --- a/src/preprocessing/generate_grids/ocean/ocean_grid_generator.xml +++ /dev/null @@ -1,26 +0,0 @@ - - -Z. Liang S. M. Griffies - Generate a grid specification data file for ocean. - - This program can generate horizontal grid, vertical grid or grids with topography and land/sea mask. . - The namelist option grid_type control the type of grid created. when grid_type equal -
                             1. "hgrid": only horizontal grid will be created.
                            - 2. "vgrid": only vertical grid will be created
                            - 4. "hgrid_topog" : horizontal grid, topography and land/sea mask will be created. 
                            -    Topography is obtained by remapping onto current grid from some topography source data. 
                            -    land/sea mask is determined by the topography. In this case, topography does not depend 
                            -    on vertical grid and no vertical grid will be created. You need to set topog_depend_on_vgrid of 
                            -    topog_nml to .false. .
                            - 5. "hgrid_vgrid_topog": horizontal grid, vertical grid, topography and land/sea mask 
                            -    will be created. The topography is mom4-specific topography (could be idealized or from 
                            -    some source file), which depends on vertical grid. The land/sea mask is determined by 
                            -    topography. In this case, you need to set topog_depend_on_vgrid of topog_nml to .true. .
                            -
                            - Control the type of grid will be created. Its value can be hgrid, vgrid, hgrid_mask, - hgrid_topog_mask, hgrid_vgrid_topog_mask. Default value is hgrid_vgrid_topog. - See module description for details. - - name of grid file to be created. Default value is "ocean_grid.nc". -
                            diff --git a/src/preprocessing/generate_grids/ocean/topog.f90 b/src/preprocessing/generate_grids/ocean/topog.f90 index b536764e22..d3657c04e4 100644 --- a/src/preprocessing/generate_grids/ocean/topog.f90 +++ b/src/preprocessing/generate_grids/ocean/topog.f90 @@ -200,7 +200,6 @@ module topog_mod ! ! ! minimum vertical thickness allowed. with default value 0.1. Increase or decrease this number as needed. - ! ! ! Control standard output. Default value is true so to show lots of information. ! @@ -298,8 +297,8 @@ module topog_mod namelist /obc_nml/ nobc, direction, is, ie, js, je, nsmooth, name !--- version information --------------------------------------------- - character(len=128) :: version = '$Id: topog.f90,v 17.0.4.3 2012/06/08 13:32:10 Zhi.Liang Exp $' - character(len=128) :: tagname = '$Name: siena_201205_z1l $' + character(len=128) :: version = '$Id: topog.f90,v 20.0 2013/12/14 00:30:50 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--- other variables logical :: module_is_initialized = .false. real :: grid_tol = 1.e-2 diff --git a/src/preprocessing/generate_grids/ocean/topog.html b/src/preprocessing/generate_grids/ocean/topog.html deleted file mode 100644 index 807fd4933a..0000000000 --- a/src/preprocessing/generate_grids/ocean/topog.html +++ /dev/null @@ -1,713 +0,0 @@ - - - -Module topog_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                            -

                            Module topog_mod

                            - - -
                            -Contact: Z. Liang -
                            -Reviewers: S. M. Griffies -
                            -Change History: WebCVS Log -
                            -
                            -
                            - - -
                            -

                            OVERVIEW

                            - -

                            - -topog_mod Generate topography for ocean model. -

                            - - - -
                            - The topography can be idealized or remapped from some source topography data. - The type of topography is specified by the namelist variable "topography" and - "topog_depend_on_vgrid". See the documentation of namelist variable "topography" - and "topog_depend_on_vgrid" for details. -
                            -
                            - - -
                            -

                            OTHER MODULES USED

                            - -
                            -
                                     mpp_mod
                            mpp_domains_mod
                            mpp_io_mod
                            fms_mod
                            axis_utils_mod
                            grids_type_mod
                            grids_util_mod
                            horiz_interp_mod
                            constants_mod
                            check_mask_mod
                            -
                            - - - -
                            -

                            PUBLIC INTERFACE

                            -
                            -
                            -
                            -topog_init:
                            -
                            - Initialization routine. -
                            -
                            -generate_topog:
                            -
                            - generate topography data. -
                            -
                            -write_topog_meta:
                            -
                            - Write out topography meta data. -
                            -
                            -write_topog_data:
                            -
                            - write the topography data to netcdf file -
                            -
                            -topog_end:
                            -
                            - Destruction routine. -
                            -
                            -
                            -
                            - - -
                            -

                            PUBLIC ROUTINES

                            - -
                              -
                            1. - -

                              topog_init

                              -
                              -call topog_init (Topog, Hgrid)
                              -
                              -
                              -DESCRIPTION -
                              -
                              - Read topography namelist. -
                              -
                              -
                              -
                              -INPUT -
                              -
                              - - - - -
                              Hgrid    - A derived-type variable that contains horizontal grid information. -
                                 [type(hgrid_data_type)]
                              -
                              -
                              -
                              -INPUT/OUTPUT -
                              -
                              - - - - -
                              Topog    - A derived-type variable that contains topography. -
                                 [type(topog_data_type)]
                              -
                              -
                              -
                              -
                            2. -
                            3. - -

                              generate_topog

                              -
                              -call generate_topog (Hgrid, Topog, Vgrid)
                              -
                              -
                              -DESCRIPTION -
                              -
                              -Call horiz_interp to calculate regridded topography. -Perform topography checks -
                              -
                              -
                              -
                              -INPUT -
                              -
                              - - - - - - - -
                              Hgrid    - A derived-type variable that contains horizontal grid information. -
                                 [type(hgrid_data_type)]
                              Vgrid    - A derived-type variable that contains vertical grid information. -
                                 [type(vgrid_data_type), optional]
                              -
                              -
                              -
                              -INPUT/OUTPUT -
                              -
                              - - - - -
                              Topog    - A derived-type variable that contains topography data. -
                                 [type(topog_data_type)]
                              -
                              -
                              -
                              -
                            4. -
                            5. - -

                              write_topog_meta

                              -
                              -call write_topog_meta (unit, axis_x, axis_y)
                              -
                              -
                              -DESCRIPTION -
                              -
                              -
                              -
                              -
                              -INPUT -
                              -
                              - - - - - - - -
                              unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                                 [integer]
                              axis_x, axis_y    - axis of T-cell center -
                                 [type(axistype)]
                              -
                              -
                              -
                              -
                            6. -
                            7. - -

                              write_topog_data

                              -
                              -call write_topog_data (unit,Topog)
                              -
                              -
                              -DESCRIPTION -
                              -
                              -
                              -
                              -
                              -INPUT -
                              -
                              - - - - - - - -
                              unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                                 [integer]
                              Topog    - A derived-type variable that contains topography data. -
                                 [type(topog_data_type)]
                              -
                              -
                              -
                              -
                            8. -
                            9. - -

                              topog_end

                              -
                              -call topog_end ( Topog )
                              -
                              -
                              -DESCRIPTION -
                              -
                              - Deallocates memory used by "topog_data_type" variables. -
                              -
                              -
                              -
                              -INPUT/OUTPUT -
                              -
                              - - - - -
                              Topog    - A derived-type variable that contains topography data. -
                                 [type(topog_data_type)]
                              -
                              -
                              -
                              -
                            10. -
                            - - - - -
                            -

                            NAMELIST

                            - -
                            -&topog_nml -
                            -
                            -
                            -
                            -
                            -topography -
                            -
                            - -
                             rectangular_basin : Constructing a rectangular basin with a flat bottom
                            - bowl              : From "Simulation of density-driven frictional downslope 
                            -                     flow in  z-coordinate mocean models"  Winton et al. 
                            -                     JPO, Vol 28, No 11, 2163-2174,  November 1998
                            - gaussian          : sets "kmt" to a gaussian bump on a sloping bottom.
                            - dome              : similar (not identical) to DOME configuration of Legg etal Ocean Modelling (2005) 
                            - idealized         : generates an "idealized" not very realistic topography.
                            - all_land          : constructing a all land topography.
                            - from_file         : Remap the topography onto the current grid from some source data file.
                            - -
                            -[character(len=24)] -
                            -
                            -topog_depend_on_vgrid -
                            -
                            - when topography /= "from_file", topog_depend_on_vgrid must be true (default value). - When it is false, topography is obtained by a simple remapping onto current grid. -
                            -[logical] -
                            -
                            -topog_file -
                            -
                            - name of topograhy file (e.g. scripps, navy_topo, ...) -
                            -[character(len=128)] -
                            -
                            -topog_field -
                            -
                            - name of topography field in file -
                            -[character(len=24)] -
                            -
                            -flat_bottom -
                            -
                            - generate flat bottom over ocean points. Default value is false. -
                            -[logical] -
                            -
                            -full_cell -
                            -
                            - do not generate partial bottom cells. Default value is false. -
                            -[logical] -
                            -
                            -fill_isolated_cells -
                            -
                            - Do not allow non-advective tracer cells (strongly recommended). Default value is true. -
                            -[logical] -
                            -
                            -dont_change_landmask -
                            -
                            - Do not change land/sea mask when filling isolated cells. Default value is false. -
                            -[logical] -
                            -
                            -fill_shallow -
                            -
                            - Make cells less than minimum depth land. Default value is false. -
                            -[logical] -
                            -
                            -fill_first_row -
                            -
                            - if true make first row of ocean model all land points for ice model when - topography is "from_file". It will do nothing when topography is not "from_file". - Default value is true. -
                            -[logical] -
                            -
                            -deepen_shallow -
                            -
                            - Make cells less than minimum depth equal to minimum depth. Default value is false. -
                            -[logical] -
                            -
                            -round_shallow -
                            -
                            - Make cells land if depth is less than 1/2 mimumim depth, otherwise make ocean. Default value is false. -
                            -[logical] -
                            -
                            -gauss_amp -
                            -
                            - height of gaussian bump as percentage of ocean depth -
                            -[real] -
                            -
                            -gauss_scale -
                            -
                            - width of gaussian bump as percentag e of basin width -
                            -[real] -
                            -
                            -slope_x -
                            -
                            - rise of the ocean floor to the east for the gaussian bump -
                            -[real, units: (m/deg)] -
                            -
                            -slope_y -
                            -
                            - rise of the ocean floor to the north for the gaussian bump -
                            -[real, units: (m/deg)] -
                            -
                            -bowl_south -
                            -
                            - southern boundary of Winton bowl -
                            -[real, units: degrees] -
                            -
                            -bowl_north -
                            -
                            - northern boundary of Winton bowl -
                            -[real, units: degrees] -
                            -
                            -bowl_west -
                            -
                            - western boundary of Winton bowl -
                            -[real, units: degrees] -
                            -
                            -bowl_east -
                            -
                            - eastern boundary of Winton bowl -
                            -[real, units: degrees] -
                            -
                            -bowl_min_depth -
                            -
                            - minimum depth of Winton bowl -
                            -[real, units: meters] -
                            -
                            -bowl_max_depth -
                            -
                            - maximum depth of Winton bowl -
                            -[real, units: meters] -
                            -
                            -dome_slope -
                            -
                            - Slope for the dome configuration. Default = 0.01 -
                            -[real, units: radians] -
                            -
                            -dome_bottom -
                            -
                            - Bottom of the dome configuration. Default=3600.0 -
                            -[real, units: m] -
                            -
                            -dome_embayment_west -
                            -
                            - western edge of dome embayment. Default=19.0 -
                            -[real, units: dimensionless] -
                            -
                            -dome_embayment_east -
                            -
                            - eastern edge of dome embayment. Default=21.0 -
                            -[real, units: dimensionless] -
                            -
                            -dome_embayment_south -
                            -
                            - southern edge of dome embayment. Default=69.0 -
                            -[real, units: dimensionless] -
                            -
                            -dome_embayment_depth -
                            -
                            - Depth of the embayment. Default=600.0 -
                            -[real, units: m] -
                            -
                            -kmt_min -
                            -
                            - minimum number of vertical levels -
                            -[integer] -
                            -
                            -filter_topog -
                            -
                            - apply filter to topography. Default value is false. -
                            -[logical] -
                            -
                            -num_filter_pass -
                            -
                            - number of passes of spatial filter -
                            -[integer] -
                            -
                            -adjust_topo -
                            -
                            - adjust topography (enforce_min_depth;remove_isolated_cells;restrict_partial_cells) - Strongly recommended. Default value is true. -
                            -[logical] -
                            -
                            -fraction_full_cell -
                            -
                            - Fraction of the associated full cell that a corresponding partial cell thickness - is no smaller than. That is, we maintain - partial_cell_min_dht(i,j,k) = fraction_full_cell*full_cell_dzt(k) - If fraction_full_cell=0.0, then partial_cell_min_dht = min(zw(1), 50.0) -
                            -[real] -
                            -
                            -scale_factor -
                            -
                            - scaling factor for topography data (e.g. -1 to flip sign or 0.01 to convert from centimeters) -
                            -[real] -
                            -
                            -smooth_topo_allow_deepening -
                            -
                            - allow filter to deepen cells. Default value is false. -
                            -[logical] -
                            -
                            -interp_method -
                            -
                            - specifying the remapping method when remampping topography from source data to current grid. - Its value can be "spherical", " bilinear" or "conservative". Default value is "bilinear". when the source - topography is on the regular grid (nml src_is_spherical is true), "bilinear" interpolation - is recommanded, since bilinear interpolation will provide more smooth results than - "spherical" interpolation (especially when interpolating from coarse grid to fine grid). - Plus bilinear interpolation is much more efficiency than "spherical interpolation". - When the source data is on non-regular grid (nml src_is_spherical is false), "bilinear" - interpolation may not work well because the destination is not inside the source grid, - in this case, you need to set interp_method to "spherical". -
                            -[character(len=64)] -
                            -
                            -num_nbrs -
                            -
                            - Number of nearest neighbors for regridding. -
                            -[integer] -
                            -
                            -max_dist -
                            -
                            - Maximum region of influence around destination grid points. -
                            -[real, units: radians] -
                            -
                            -src_is_spherical -
                            -
                            - Determine if the source grid is spherical grid or not. If true, source grid is spherical grid, - otherwise not. Default value is .true. When src_is_spherical is .true., lon_field and lat_field - need to be set. -
                            -[logical] -
                            -
                            -lon_field -
                            -
                            - name of geographic longitude field in source file -
                            -[character(len=24)] -
                            -
                            -lat_field -
                            -
                            - name of geographic latitude field in source file -
                            -[character(len=24)] -
                            -
                            -output_corner_topog -
                            -
                            - When true, will write topography information on the C-cell cneter to the grid file. - Default value is false. -
                            -[logical] -
                            -
                            -check_mask -
                            -
                            - When true, check the possible masking ( all-land region) for certain layout. The print out message - will provide coupler_nml ( or ocean_solo_nml) entry : nmask, layout_mask and mask_list. - Default value is false. -
                            -[logical] -
                            -
                            -open_very_this_cell -
                            -
                            - When set to false, check which change is larger, opening or closing the cell, and - to do that with smaller effect in depth_t. Default is true, will always - opening the cell. -
                            -[logical] -
                            -
                            -min_thickness -
                            -
                            - minimum vertical thickness allowed. with default value 0.1. Increase or decrease this number as needed. -
                            -[real, units: METERS] -
                            -
                            -debug -
                            -
                            - Control standard output. Default value is true so to show lots of information. -
                            -[logical] -
                            -
                            -
                            -
                            -
                            - - - - -
                            -
                            -top -
                            - - diff --git a/src/preprocessing/generate_grids/ocean/topog.xml b/src/preprocessing/generate_grids/ocean/topog.xml deleted file mode 100644 index 5b7e437bf8..0000000000 --- a/src/preprocessing/generate_grids/ocean/topog.xml +++ /dev/null @@ -1,180 +0,0 @@ - - -Z. Liang S. M. Griffies - topog_mod Generate topography for ocean model. - - The topography can be idealized or remapped from some source topography data. - The type of topography is specified by the namelist variable "topography" and - "topog_depend_on_vgrid". See the documentation of namelist variable "topography" - and "topog_depend_on_vgrid" for details. - -
                             rectangular_basin : Constructing a rectangular basin with a flat bottom
                            - bowl              : From "Simulation of density-driven frictional downslope 
                            -                     flow in  z-coordinate mocean models"  Winton et al. 
                            -                     JPO, Vol 28, No 11, 2163-2174,  November 1998
                            - gaussian          : sets "kmt" to a gaussian bump on a sloping bottom.
                            - dome              : similar (not identical) to DOME configuration of Legg etal Ocean Modelling (2005) 
                            - idealized         : generates an "idealized" not very realistic topography.
                            - all_land          : constructing a all land topography.
                            - from_file         : Remap the topography onto the current grid from some source data file.
                            -
                            - when topography /= "from_file", topog_depend_on_vgrid must be true (default value). - When it is false, topography is obtained by a simple remapping onto current grid. - - name of topograhy file (e.g. scripps, navy_topo, ...) - - name of topography field in file - - generate flat bottom over ocean points. Default value is false. - - do not generate partial bottom cells. Default value is false. - - Do not allow non-advective tracer cells (strongly recommended). Default value is true. - - Do not change land/sea mask when filling isolated cells. Default value is false. - - Make cells less than minimum depth land. Default value is false. - - if true make first row of ocean model all land points for ice model when - topography is "from_file". It will do nothing when topography is not "from_file". - Default value is true. - - Make cells less than minimum depth equal to minimum depth. Default value is false. - - Make cells land if depth is less than 1/2 mimumim depth, otherwise make ocean. Default value is false. - - height of gaussian bump as percentage of ocean depth - - width of gaussian bump as percentag e of basin width - - rise of the ocean floor to the east for the gaussian bump - - rise of the ocean floor to the north for the gaussian bump - - southern boundary of Winton bowl - - northern boundary of Winton bowl - - western boundary of Winton bowl - - eastern boundary of Winton bowl - - minimum depth of Winton bowl - - maximum depth of Winton bowl - - Slope for the dome configuration. Default = 0.01 - - Bottom of the dome configuration. Default=3600.0 - - western edge of dome embayment. Default=19.0 - - eastern edge of dome embayment. Default=21.0 - - southern edge of dome embayment. Default=69.0 - - Depth of the embayment. Default=600.0 - - minimum number of vertical levels - - apply filter to topography. Default value is false. - - number of passes of spatial filter - - adjust topography (enforce_min_depth;remove_isolated_cells;restrict_partial_cells) - Strongly recommended. Default value is true. - - Fraction of the associated full cell that a corresponding partial cell thickness - is no smaller than. That is, we maintain - partial_cell_min_dht(i,j,k) = fraction_full_cell*full_cell_dzt(k) - If fraction_full_cell=0.0, then partial_cell_min_dht = min(zw(1), 50.0) - - scaling factor for topography data (e.g. -1 to flip sign or 0.01 to convert from centimeters) - - allow filter to deepen cells. Default value is false. - - specifying the remapping method when remampping topography from source data to current grid. - Its value can be "spherical", " bilinear" or "conservative". Default value is "bilinear". when the source - topography is on the regular grid (nml src_is_spherical is true), "bilinear" interpolation - is recommanded, since bilinear interpolation will provide more smooth results than - "spherical" interpolation (especially when interpolating from coarse grid to fine grid). - Plus bilinear interpolation is much more efficiency than "spherical interpolation". - When the source data is on non-regular grid (nml src_is_spherical is false), "bilinear" - interpolation may not work well because the destination is not inside the source grid, - in this case, you need to set interp_method to "spherical". - - Number of nearest neighbors for regridding. - - Maximum region of influence around destination grid points. - - Determine if the source grid is spherical grid or not. If true, source grid is spherical grid, - otherwise not. Default value is .true. When src_is_spherical is .true., lon_field and lat_field - need to be set. - - name of geographic longitude field in source file - - name of geographic latitude field in source file - - When true, will write topography information on the C-cell cneter to the grid file. - Default value is false. - - When true, check the possible masking ( all-land region) for certain layout. The print out message - will provide coupler_nml ( or ocean_solo_nml) entry : nmask, layout_mask and mask_list. - Default value is false. - - When set to false, check which change is larger, opening or closing the cell, and - to do that with smaller effect in depth_t. Default is true, will always - opening the cell. - - minimum vertical thickness allowed. with default value 0.1. Increase or decrease this number as needed. - - Control standard output. Default value is true so to show lots of information. -
                            - Initialization routine. - - Read topography namelist. - - A derived-type variable that contains horizontal grid information. - - A derived-type variable that contains topography. - - generate topography data. - -Call horiz_interp to calculate regridded topography. -Perform topography checks - - A derived-type variable that contains horizontal grid information. - - A derived-type variable that contains vertical grid information. - - A derived-type variable that contains topography data. - - Write out topography meta data. - - The unit corresponding the output netcdf file. Always is returned by mpp_open. - - axis of T-cell center - - write the topography data to netcdf file - - The unit corresponding the output netcdf file. Always is returned by mpp_open. - - A derived-type variable that contains topography data. - - Destruction routine. - - Deallocates memory used by "topog_data_type" variables. - - A derived-type variable that contains topography data. -
                            diff --git a/src/preprocessing/generate_grids/ocean/vgrid.f90 b/src/preprocessing/generate_grids/ocean/vgrid.f90 index 1770d003ac..0cf7df70ac 100644 --- a/src/preprocessing/generate_grids/ocean/vgrid.f90 +++ b/src/preprocessing/generate_grids/ocean/vgrid.f90 @@ -140,7 +140,7 @@ module vgrid_mod logical :: module_is_initialized = .false. !---------version information------------------------------------------- character(len=128) :: version = '$Id: vgrid.f90,v 13.0 2006/03/28 21:45:06 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !---------public interface---------------------------------------------- public :: generate_vgrid, vgrid_init, vgrid_end, write_vgrid_meta, write_vgrid_data diff --git a/src/preprocessing/generate_grids/ocean/vgrid.html b/src/preprocessing/generate_grids/ocean/vgrid.html deleted file mode 100644 index acf7cdba93..0000000000 --- a/src/preprocessing/generate_grids/ocean/vgrid.html +++ /dev/null @@ -1,353 +0,0 @@ - - - -Module vgrid_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                            -

                            Module vgrid_mod

                            - - -
                            -Contact: Z. Liang -
                            -Reviewers: S. M. Griffies -
                            -Change History: WebCVS Log -
                            -
                            -
                            - - -
                            -

                            OVERVIEW

                            - -

                            - -vgrid_mod Generate vertical grid. -

                            - - - -
                            - The grid file contains the following information, -
                                   zt = depth of tracer points
                            -       zb = depth of tracer_boundaries
                            -
                            -              +---------------+
                            -              |               |
                            -              |               |
                            -              |               |
                            -              |               |
                            -              |      +zt_k    |
                            -              |               |
                            -              |               |
                            -              |               |
                            -              +------+zb_k----+
                            - -
                            -
                            - - -
                            -

                            OTHER MODULES USED

                            - -
                            -
                                   mpp_mod
                            mpp_io_mod
                            fms_mod
                            grids_type_mod
                            grids_util_mod
                            constants_mod
                            -
                            - - - -
                            -

                            PUBLIC INTERFACE

                            -
                            -
                            -
                            -vgrid_init:
                            -
                            - Initialization routine. -
                            -
                            -generate_vgrid:
                            -
                            - Generate vertical grid. -
                            -
                            -write_vgrid_data:
                            -
                            - write the vertical grid data to netcdf file -
                            -
                            -write_vgrid_meta:
                            -
                            - Write out vertical grid meta data. -
                            -
                            -vgrid_end:
                            -
                            - Destruction routine. -
                            -
                            -
                            -
                            - - -
                            -

                            PUBLIC ROUTINES

                            - -
                              -
                            1. - -

                              vgrid_init

                              -
                              -call vgrid_init ( )
                              -
                              -
                              -DESCRIPTION -
                              -
                              - Read namelist, write out version and namelist informaiton and generate depth resolution. -
                              -
                              -
                              -
                              -
                            2. -
                            3. - -

                              generate_vgrid

                              -
                              -call generate_vgrid (Vgrid)
                              -
                              -
                              -DESCRIPTION -
                              -
                              -
                              -
                              -
                              -INPUT/OUTPUT -
                              -
                              - - - - -
                              Vgrid    - A derived-type variable that contains vertical grid information. -
                                 [vgrid_data_type]
                              -
                              -
                              -
                              -
                            4. -
                            5. - -

                              write_vgrid_data

                              -
                              -call write_vgrid_data (unit)
                              -
                              -
                              -DESCRIPTION -
                              -
                              -
                              -
                              -
                              -INPUT -
                              -
                              - - - - -
                              unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                                 [integer]
                              -
                              -
                              -
                              -
                            6. -
                            7. - -

                              write_vgrid_meta

                              -
                              -call write_vgrid_meta (unit, Vgrid)
                              -
                              -
                              -DESCRIPTION -
                              -
                              -
                              -
                              -
                              -INPUT -
                              -
                              - - - - - - - -
                              unit    - The unit corresponding the output netcdf file. Always is returned by mpp_open. -
                                 [integer]
                              Vgrid    - A derived-type variable that contains vertical grid information. -
                                 [vgrid_data_type]
                              -
                              -
                              -
                              -
                            8. -
                            9. - -

                              vgrid_end

                              -
                              -call vgrid_end ( Vgrid )
                              -
                              -
                              -DESCRIPTION -
                              -
                              - Deallocates memory used by "vgrid_data_type" variables. -
                              -
                              -
                              -
                              -INPUT/OUTPUT -
                              -
                              - - - - -
                              Vgrid    - A derived-type variable that contains vertical grid information. -
                                 [vgrid_data_type]
                              -
                              -
                              -
                              -
                            10. -
                            - - - - -
                            -

                            NAMELIST

                            - -
                            -&vgrid_nml -
                            -
                            -
                            -
                            -
                            -nzdepths -
                            -
                            - number of depth regions for varying resolution -
                            -[integer] -
                            -
                            -z_depth -
                            -
                            - boundaries for defining depth regions of varying resolution -
                            -[real, dimension(nxlons), units: meters] -
                            -
                            -dz_depth -
                            -
                            - nominal resolution of depth regions -
                            -[real, dimension(nxlons), units: meters] -
                            -
                            -stretch_z -
                            -
                            - stretch factor of vertical grids. -
                            -[real] -
                            -
                            -read_my_grid -
                            -
                            - read ASCII grid information for supplying user-defined grids. -
                            -[logical] -
                            -
                            -my_grid_file -
                            -
                            - Name of ASCII or netcdf user grid file -
                            -[character(len=128)] -
                            -
                            -z_axis_t -
                            -
                            - Name of z_t axis, if the file is netcdf -
                            -[character(len=24)] -
                            -
                            -z_axis_b -
                            -
                            - Name of z_b axis, if the file is netcdf -
                            -[character(len=24)] -
                            -
                            -z_axis_b_offset -
                            -
                            - offset of z_b axis, if the file is netcdf - 1 corresponds to an axis starting at k=0, z_b=0 (mom3) -
                            -[integer] -
                            -
                            -debug -
                            -
                            - control standard output. -
                            -[logical] -
                            -
                            -
                            -
                            -
                            - - - - -
                            -
                            -top -
                            - - diff --git a/src/preprocessing/generate_grids/ocean/vgrid.xml b/src/preprocessing/generate_grids/ocean/vgrid.xml deleted file mode 100644 index 5e381c7994..0000000000 --- a/src/preprocessing/generate_grids/ocean/vgrid.xml +++ /dev/null @@ -1,76 +0,0 @@ - - -Z. Liang S. M. Griffies - vgrid_mod Generate vertical grid. - - The grid file contains the following information, -
                                   zt = depth of tracer points
                            -       zb = depth of tracer_boundaries
                            -
                            -              +---------------+
                            -              |               |
                            -              |               |
                            -              |               |
                            -              |               |
                            -              |      +zt_k    |
                            -              |               |
                            -              |               |
                            -              |               |
                            -              +------+zb_k----+
                            -
                            - number of depth regions for varying resolution - - boundaries for defining depth regions of varying resolution - - nominal resolution of depth regions - - stretch factor of vertical grids. - - read ASCII grid information for supplying user-defined grids. - - Name of ASCII or netcdf user grid file - - Name of z_t axis, if the file is netcdf - - Name of z_b axis, if the file is netcdf - - offset of z_b axis, if the file is netcdf - 1 corresponds to an axis starting at k=0, z_b=0 (mom3) - - control standard output. - - Initialization routine. - - Read namelist, write out version and namelist informaiton and generate depth resolution. - - Generate vertical grid. - - A derived-type variable that contains vertical grid information. - - write the vertical grid data to netcdf file - - The unit corresponding the output netcdf file. Always is returned by mpp_open. - - Write out vertical grid meta data. - - The unit corresponding the output netcdf file. Always is returned by mpp_open. - - A derived-type variable that contains vertical grid information. - - Destruction routine. - - Deallocates memory used by "vgrid_data_type" variables. - - A derived-type variable that contains vertical grid information. -
                            diff --git a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.f90 b/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.f90 index e243c0eb91..662694133f 100644 --- a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.f90 +++ b/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.f90 @@ -114,7 +114,7 @@ module idealized_bc_mod !--- version information character(len=128) :: version = '$Id: idealized_bc.f90,v 17.0 2009/07/21 03:22:49 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--- other module variables real, dimension(:,:), allocatable :: xu, yu, xt, yt, h1t, area_t diff --git a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.html b/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.html deleted file mode 100644 index c743dc0e55..0000000000 --- a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.html +++ /dev/null @@ -1,233 +0,0 @@ - - - -Module idealized_bc_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                            -

                            Module idealized_bc_mod

                            - - -
                            -Contact:  Z. Liang -
                            -Reviewers:  S.M. Griffies -
                            -Change History: WebCVS Log -
                            -
                            -
                            - - -
                            -

                            OVERVIEW

                            - -

                            - For preparing idealized mom4 surface boundary conditions -

                            - - - -
                            - This program prepares idealized surface boundary conditions. The generated data - contains some or all of the following, temperature, salinity, water flux, - zonal and meridinal wind stress. The choice of output data is controlled by - namelist option. Results are netcdf files that are then read into mom4. - Various idealized options are available as selected by a namelist. -
                            -
                            - - -
                            -

                            OTHER MODULES USED

                            - -
                            -
                                    fms_mod
                            mpp_domains_mod
                            mpp_io_mod
                            mpp_mod
                            constants_mod
                            -
                            - - - -
                            -

                            PUBLIC INTERFACE

                            - -
                            - - -
                            -

                            PUBLIC ROUTINES

                            - -
                              -
                            1. - -

                              idealized_bc_init

                              -
                              -
                              -DESCRIPTION -
                              -
                              - Initialize the module generating ideal surface boundary conditions. -
                              -
                              -
                              -
                              -
                            2. -
                            3. - -

                              idealized_bc_end

                              -
                              -
                              -DESCRIPTION -
                              -
                              - Release memory. -
                              -
                              -
                              -
                              -
                            4. -
                            5. - -

                              write_idealized_bc_data

                              -
                              -
                              -DESCRIPTION -
                              -
                              - Write the idealized boundary condition to netcdf file. -
                              -
                              -
                              -
                              -
                            6. -
                            - - - - -
                            -

                            NAMELIST

                            - -
                            -&idealized_bc_nml -
                            -
                            -
                            -
                            -
                            -wind_type -
                            -
                            - Control the iealized boundary wind stress condition options. - There are four options available and the default value is - "constant_tau". When temp_type is - 1. = "constant_tau", use space-time constant wind stress. - 2. = "cosine_zonal_winds", compute idealized winds using a cosine in latitude profile. - Makes sense only when running spherical coordinate model. - 3. = "frank_bryan_winds", compute idealized surface wind stress using zonal wind - profile originally used by Frank Bryan. Makes sense only when running spherical coordinate model. - 4. = "frank_bryan_winds_compress", use the full Frank Bryan wind profiled over a - latitudinally compressed domain. Makes sense only when running spherical coordinate model. -
                            -[character(len=128)] -
                            -
                            -taux0 -
                            -
                            - Constant zonal wind stress -
                            -[real] -
                            -
                            -tauy0 -
                            -
                            - Constant meridional wind stress -
                            -[real] -
                            -
                            -qw0 -
                            -
                            - Fresh water flux scaling parameter for idealized surface water flux -
                            -[real, units: meter/sec] -
                            -
                            -generate_wind_bc -
                            -
                            - Control if wind stress data will be generated. When true (default value), idealized surface boundary - wind stress data will be generated. If false, do not generate wind stress data. -
                            -[logical] -
                            -
                            -generate_temp_bc -
                            -
                            - Control if temperature data will be generated. When true (default value), idealized surface boundary - temperature data will be generated. If false, do not generate temperature data. -
                            -[logical] -
                            -
                            -generate_salt_bc -
                            -
                            - Control if salinity data will be generated. When true (default value), idealized surface boundary - salinity data will be generated. If false, do not generate salinity data. -
                            -[logical] -
                            -
                            -generate_water_bc -
                            -
                            - Control if water flux data will be generated. When true (default value), idealized surface boundary - water flux data will be generated. If false, do not generate water flux data. -
                            -[logical] -
                            -
                            -
                            -
                            -
                            - - - - -
                            -
                            -top -
                            - - diff --git a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.xml b/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.xml deleted file mode 100644 index 7b40932f2b..0000000000 --- a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - Z. Liang S.M. Griffies - For preparing idealized mom4 surface boundary conditions - - This program prepares idealized surface boundary conditions. The generated data - contains some or all of the following, temperature, salinity, water flux, - zonal and meridinal wind stress. The choice of output data is controlled by - namelist option. Results are netcdf files that are then read into mom4. - Various idealized options are available as selected by a namelist. - - Control the iealized boundary wind stress condition options. - There are four options available and the default value is - "constant_tau". When temp_type is - 1. = "constant_tau", use space-time constant wind stress. - 2. = "cosine_zonal_winds", compute idealized winds using a cosine in latitude profile. - Makes sense only when running spherical coordinate model. - 3. = "frank_bryan_winds", compute idealized surface wind stress using zonal wind - profile originally used by Frank Bryan. Makes sense only when running spherical coordinate model. - 4. = "frank_bryan_winds_compress", use the full Frank Bryan wind profiled over a - latitudinally compressed domain. Makes sense only when running spherical coordinate model. - - Constant zonal wind stress - - Constant meridional wind stress - - Fresh water flux scaling parameter for idealized surface water flux - - Control if wind stress data will be generated. When true (default value), idealized surface boundary - wind stress data will be generated. If false, do not generate wind stress data. - - Control if temperature data will be generated. When true (default value), idealized surface boundary - temperature data will be generated. If false, do not generate temperature data. - - Control if salinity data will be generated. When true (default value), idealized surface boundary - salinity data will be generated. If false, do not generate salinity data. - - Control if water flux data will be generated. When true (default value), idealized surface boundary - water flux data will be generated. If false, do not generate water flux data. - - Initialize the module generating ideal surface boundary conditions. - - Release memory. - - Write the idealized boundary condition to netcdf file. - diff --git a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc_driver.html b/src/preprocessing/mom4_prep/idealized_bc/idealized_bc_driver.html deleted file mode 100644 index 7fe81fc203..0000000000 --- a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc_driver.html +++ /dev/null @@ -1,83 +0,0 @@ - - - -Program idealized_bc_driver - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                            -

                            Program idealized_bc_driver

                            - - -
                            -Contact: Z. Liang -
                            -Reviewers:  S.M. Griffies -
                            -Change History: WebCVS Log -
                            -
                            -
                            - - -
                            -

                            OVERVIEW

                            - -

                            - Driver for ideal surface boundary conditions -

                            - - - -
                            - The program drives the idealized boundary condition generation routines. -
                            -
                            - - -
                            -

                            MODULES USED

                            - -
                            -
                                     fms_mod
                            idealized_bc_mod
                            constants_mod
                            mpp_mod
                            -
                            - - - -
                            -

                            PUBLIC INTERFACE

                            -
                            -
                            -
                            -
                            - - -
                            -

                            PUBLIC ROUTINES

                            - -
                              - - - - - - -
                              -
                              -top -
                              - - diff --git a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc_driver.xml b/src/preprocessing/mom4_prep/idealized_bc/idealized_bc_driver.xml deleted file mode 100644 index b9953993b6..0000000000 --- a/src/preprocessing/mom4_prep/idealized_bc/idealized_bc_driver.xml +++ /dev/null @@ -1,8 +0,0 @@ - - -Z. Liang S.M. Griffies - Driver for ideal surface boundary conditions - - The program drives the idealized boundary condition generation routines. - diff --git a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.f90 b/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.f90 index 0718b08946..1c44194f01 100644 --- a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.f90 +++ b/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.f90 @@ -336,7 +336,7 @@ module idealized_ic_mod !--- version information character(len=128) :: version = '$Id: idealized_ic.f90,v 14.0 2007/03/15 22:47:01 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--- output data ------------------------------------------------------- real, dimension(:,:,:), allocatable :: temp, salt, age diff --git a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.html b/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.html deleted file mode 100644 index 7190a11c0b..0000000000 --- a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.html +++ /dev/null @@ -1,594 +0,0 @@ - - - -Module idealized_ic_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                              -

                              Module idealized_ic_mod

                              - - -
                              -Contact:  Z. Liang -
                              -Reviewers:  S.M. Griffies -
                              -Change History: WebCVS Log -
                              -
                              -
                              - - -
                              -

                              OVERVIEW

                              - -

                              - For preparing idealized mom4 initial conditions -

                              - - - -
                              - This program prepares idealized initial conditions (active and passive tracer). - Results are netcdf files that are then read into mom4. - Various idealized options are available as selected by a namelist. -
                              -
                              - - -
                              -

                              OTHER MODULES USED

                              - -
                              -
                                      fms_mod
                              mpp_mod
                              mpp_io_mod
                              mpp_domains_mod
                              constants_mod
                              -
                              - - - -
                              -

                              PUBLIC INTERFACE

                              - -
                              - - -
                              -

                              PUBLIC ROUTINES

                              - -
                                -
                              1. - -

                                idealized_ic_init

                                -
                                -
                                -DESCRIPTION -
                                -
                                - Initialize the module generating ideal initial conditions. -
                                -
                                -
                                -
                                -
                              2. -
                              3. - -

                                write_idealized_ic_data

                                -
                                -
                                -DESCRIPTION -
                                -
                                - Write out tracer data to netcdf file -
                                -
                                -
                                -
                                -
                              4. -
                              5. - -

                                idealized_ic_end

                                -
                                -
                                -DESCRIPTION -
                                -
                                - Release memory. -
                                -
                                -
                                -
                                -
                              6. -
                              - - - - -
                              -

                              NAMELIST

                              - -
                              -&idealized_ic_nml -
                              -
                              -
                              -
                              -
                              -temp_type -
                              -
                              - Control the iealized initial temperature condition options. - There are various options available and the default value is - "constant_temp_ic". When temp_type is - 1. = "constant_temp_ic", use spatially constant initial potential temperature. - 2. = "exponential_temp_ic", use initial potential temperature that is - exponential in the vertical. - 3. = "equatorial_temp_ic", use initial temp condition for idealized equatorial studies. - 4. = "shelfbowl_temp_ic", Initial conditions for Winton etal shelf-bowl test case. - Use tanh transition between cold shelf and warm bowl waters, instead of Heaviside. - 5. = "zonal_levitus_temp_ic", use zonal average Levitus temp as initial conditions. - 6. = "zonal_levitus_temp_dome_ic" zonal Levitus, except constant_temp_value in embayment - 7. = "temp_for_dome_ic" linear stratification with special treatment within embayment - 8. = "ideal_thermocline", idealized thermocline with profile from Smith and Vallis (2001). -
                              -[character(len=128)] -
                              -
                              -salt_type -
                              -
                              - Control the idealized initial salinity condition options. - The following options for salt_type are available, with default - "constant_salt_ic". - "constant_salt_ic", use spatially constant initial salinity. - "exponential_salt_ic", use initial salinity that is exponential in the vertical. - "salinity_profile_ic", use initial salinity condition as set by profile in function salt0 - "salinity_for_dome_ic", salinity=1.0 for inflow in dome embayment and 0.0 elsewhere. - "salinity_layer_ic" , salinity=1.0 in a layer and 0.0 elsewhere. For passive salinity experiments. - "salinity_patch_ic" , salinity=1.0 in a patch and 0.0 elsewhere. For passive salinity experiments. - "shelfbowl_salinity_ic", salinity=1.0 on shelf, and 0.0 elsewhere. For passive salinity experiments. -
                              -[character(len=128)] -
                              -
                              -age_type -
                              -
                              - Control the idealized initial age condition options. - There is only one option now available, and the default value is - "constant_age_ic". -
                              -[character(len=128)] -
                              -
                              -constant_temp_value -
                              -
                              - Value for uniform initial temp. -
                              -[real] -
                              -
                              -constant_salt_value -
                              -
                              - Value for uniform initial salinity. -
                              -[real] -
                              -
                              -efold_depth -
                              -
                              - The efolding depth used for exponential temp or salinity profile. - Default=1000.0 -
                              -[real, units: metre] -
                              -
                              -ideal_thermocline_deltaT -
                              -
                              - Difference in temperature between bottom and surface for - the ideal thermocline initial conditions. Default - ideal_thermocline_deltaT=20.0 -
                              -[real, units: degC] -
                              -
                              -ideal_thermocline_scale_thick -
                              -
                              - Dimensionless scale thickness for the ideal thermocline profile. The dimensionful - scale thickness is Hscale = H*ideal_thermocline_scale_thick, with H the ocean bottom. - Default ideal_thermocline_scale_thick=0.10 (range of 0.05 to 0.15 recommended by - Smith and Vallis (2001). -
                              -[real, units: dimensionless] -
                              -
                              -ideal_thermocline_rho0 -
                              -
                              - Density scale for use with the ideal thermocline configuration. - Default ideal_thermocline_rho0=1035. -
                              -[real, units: kg/m3] -
                              -
                              -ideal_thermocline_alpha -
                              -
                              - Linear scaling for thermocline. Default is ideal_thermocline_alpha=0.0005. -
                              -[real, units: dimensionless] -
                              -
                              -ideal_thermocline_alpha_eos -
                              -
                              - Linear equation of state parameter for ideal thermocline, assuming - rho = rho0 - ideal_thermocline_alpha_eos*theta. Default - ideal_thermocline_alpha_eos=0.255. -
                              -[real, units: kg/(m3*C)] -
                              -
                              -ideal_thermocline_offset -
                              -
                              - Offset to make the temperature profile realistic. - Default ideal_thermocline_offset=22.0. -
                              -[real, units: C] -
                              -
                              -linear_theta_strat -
                              -
                              - The linear vertical stratification for theta for reference in DOME configuration. -
                              -[real, units: degreesC/metre] -
                              -
                              -dome_debug -
                              -
                              - For debugging DOME conditions. -
                              -[logical] -
                              -
                              -dome_embayment_west -
                              -
                              - western edge of dome embayment. Default=18.75 -
                              -[real, units: dimensionless] -
                              -
                              -dome_embayment_east -
                              -
                              - eastern edge of dome embayment. Default=20.75 -
                              -[real, units: dimensionless] -
                              -
                              -dome_embayment_north -
                              -
                              - northern edge of dome embayment. Default=69.75. This is a resolution dependent - value, and should be determined for each grid used. -
                              -[real, units: dimensionless] -
                              -
                              -dome_embayment_south -
                              -
                              - southern edge of dome embayment. Default=69.0. This is a resolution dependent - value, and should be determined for each grid used. -
                              -[real, units: dimensionless] -
                              -
                              -dome_embayment_depth -
                              -
                              - Depth of the embayment. Default=600.0 -
                              -[real, units: m] -
                              -
                              -dome_bottom -
                              -
                              - Depth of the deepest water in DOME configuration. Default=3600.0 -
                              -[real, units: m] -
                              -
                              -dome_embayment_interface -
                              -
                              - Depth (m) determining the inflow mass flux. Default=300.0 -
                              -[real, units: m] -
                              -
                              -dome_embayment_coriolis -
                              -
                              - reference Coriolis parameter for determining Rossby radius in - the DOME inflow. Default taken at 70N. -
                              -[real, units: 1/s] -
                              -
                              -dome_crit_richardson -
                              -
                              - Critical Richardson number used for dome. When running with - coarse models, dome_crit_richardson=1/1000 is what Legg recommends, - whereas in refined models (finer than 50km), dome_crit_richardson=1/3. - Default is dome_crit_richardson=.001. -
                              -[real, units: 1/s] -
                              -
                              -dome_drho_inflow -
                              -
                              - Density difference between inflow and reference for DOME - configuration. Default dome_drho_ref=2.0 -
                              -[real, units: kg/m3] -
                              -
                              -salinity_layer_ztop -
                              -
                              - Depth at the top of the salinity layer. -
                              -[real] -
                              -
                              -salinity_layer_zbot -
                              -
                              - Depth at the bottom of the salinity layer. -
                              -[real] -
                              -
                              -salinity_patch_ztop -
                              -
                              - Depth at the top of the salinity patch. -
                              -[real] -
                              -
                              -salinity_patch_zbot -
                              -
                              - Depth at the bottom of the salinity patch. -
                              -[real] -
                              -
                              -salinity_patch_ratio1 -
                              -
                              - For setting position of salinity patch. -
                              -[real] -
                              -
                              -salinity_patch_ratio2 -
                              -
                              - For setting position of salinity patch. -
                              -[real] -
                              -
                              -constant_age_value -
                              -
                              - Value for uniform initial age. -
                              -[real] -
                              -
                              -generate_zonal_velocity_ic -
                              -
                              - For generating the zonal velocity at the t-cell. -
                              -[logical] -
                              -
                              -generate_merid_velocity_ic -
                              -
                              - For generating the meridional velocity at the t-cell. -
                              -[logical] -
                              -
                              -zonal_velocity_name -
                              -
                              - name array of the zonal velocity component - to be generated. Its default value is 'ut_inflow'. -
                              -[character(len=128)] -
                              -
                              -merid_velocity_name -
                              -
                              - name array of the meridional velocity component - to be generated. Its default value is 'vt'. -
                              -[character(len=128)] -
                              -
                              -zonal_velocity_file -
                              -
                              - zonal velocity output file. Default is 'ut.res.nc' -
                              -[character(len=128)] -
                              -
                              -merid_velocity_file -
                              -
                              - meridional velocity output file. Default is 'vt.res.nc' -
                              -[character(len=128)] -
                              -
                              -num_active_tracer -
                              -
                              - Number of active tracers will be generated. Its value should be 0, 1, 2. - Its default value is 2. ( temp and salt ) -
                              -[integer] -
                              -
                              -active_tracer -
                              -
                              - name array of the active tracers will be generated. - Its element value should be 'temp' or 'salt' -
                              -[character(len=128),dimension(2)] -
                              -
                              -active_tracer_file -
                              -
                              - active tracer output file. -
                              -[character(len=128)] -
                              -
                              -num_passive_tracer -
                              -
                              - Number of passive tracers will be generated. Its value should be no more than max_tracer. - Its default value is 1 (age). -
                              -[integer] -
                              -
                              - -
                              -
                              - name array of the passive tracers will be generated. - Its element value should be 'age'. -
                              -[character(len=128),dimension(max_tracer)] -
                              -
                              -passive_tracer_file -
                              -
                              - passive tracer output file. -
                              -[character(len=128)] -
                              -
                              -grid_file -
                              -
                              - grid descriptor file. -
                              -[character(len=128)] -
                              -
                              -t1 -
                              -
                              - For setting idealized vertical profile -
                              -[real] -
                              -
                              -t0 -
                              -
                              - For setting idealized vertical profile -
                              -[real] -
                              -
                              -z0 -
                              -
                              - For setting idealized vertical profile -
                              -[real] -
                              -
                              -thk -
                              -
                              - For setting idealized vertical profile -
                              -[real] -
                              -
                              -write_time_axis -
                              -
                              - For writing a time axis for the IC. This is useful if - wish to use the IC as a static dataset for sponges. - Default write_time_axis=.true. -
                              -[logical] -
                              -
                              -
                              -
                              -
                              - - - - -
                              -
                              -top -
                              - - diff --git a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.xml b/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.xml deleted file mode 100644 index 46d712b007..0000000000 --- a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic.xml +++ /dev/null @@ -1,162 +0,0 @@ - - - Z. Liang S.M. Griffies - For preparing idealized mom4 initial conditions - - This program prepares idealized initial conditions (active and passive tracer). - Results are netcdf files that are then read into mom4. - Various idealized options are available as selected by a namelist. - - Control the iealized initial temperature condition options. - There are various options available and the default value is - "constant_temp_ic". When temp_type is - 1. = "constant_temp_ic", use spatially constant initial potential temperature. - 2. = "exponential_temp_ic", use initial potential temperature that is - exponential in the vertical. - 3. = "equatorial_temp_ic", use initial temp condition for idealized equatorial studies. - 4. = "shelfbowl_temp_ic", Initial conditions for Winton etal shelf-bowl test case. - Use tanh transition between cold shelf and warm bowl waters, instead of Heaviside. - 5. = "zonal_levitus_temp_ic", use zonal average Levitus temp as initial conditions. - 6. = "zonal_levitus_temp_dome_ic" zonal Levitus, except constant_temp_value in embayment - 7. = "temp_for_dome_ic" linear stratification with special treatment within embayment - 8. = "ideal_thermocline", idealized thermocline with profile from Smith and Vallis (2001). - - Control the idealized initial salinity condition options. - The following options for salt_type are available, with default - "constant_salt_ic". - "constant_salt_ic", use spatially constant initial salinity. - "exponential_salt_ic", use initial salinity that is exponential in the vertical. - "salinity_profile_ic", use initial salinity condition as set by profile in function salt0 - "salinity_for_dome_ic", salinity=1.0 for inflow in dome embayment and 0.0 elsewhere. - "salinity_layer_ic" , salinity=1.0 in a layer and 0.0 elsewhere. For passive salinity experiments. - "salinity_patch_ic" , salinity=1.0 in a patch and 0.0 elsewhere. For passive salinity experiments. - "shelfbowl_salinity_ic", salinity=1.0 on shelf, and 0.0 elsewhere. For passive salinity experiments. - - Control the idealized initial age condition options. - There is only one option now available, and the default value is - "constant_age_ic". - - Value for uniform initial temp. - - Value for uniform initial salinity. - - The efolding depth used for exponential temp or salinity profile. - Default=1000.0 - - Difference in temperature between bottom and surface for - the ideal thermocline initial conditions. Default - ideal_thermocline_deltaT=20.0 - - Dimensionless scale thickness for the ideal thermocline profile. The dimensionful - scale thickness is Hscale = H*ideal_thermocline_scale_thick, with H the ocean bottom. - Default ideal_thermocline_scale_thick=0.10 (range of 0.05 to 0.15 recommended by - Smith and Vallis (2001). - - Density scale for use with the ideal thermocline configuration. - Default ideal_thermocline_rho0=1035. - - Linear scaling for thermocline. Default is ideal_thermocline_alpha=0.0005. - - Linear equation of state parameter for ideal thermocline, assuming - rho = rho0 - ideal_thermocline_alpha_eos*theta. Default - ideal_thermocline_alpha_eos=0.255. - - Offset to make the temperature profile realistic. - Default ideal_thermocline_offset=22.0. - - The linear vertical stratification for theta for reference in DOME configuration. - - For debugging DOME conditions. - - western edge of dome embayment. Default=18.75 - - eastern edge of dome embayment. Default=20.75 - - northern edge of dome embayment. Default=69.75. This is a resolution dependent - value, and should be determined for each grid used. - - southern edge of dome embayment. Default=69.0. This is a resolution dependent - value, and should be determined for each grid used. - - Depth of the embayment. Default=600.0 - - Depth of the deepest water in DOME configuration. Default=3600.0 - - Depth (m) determining the inflow mass flux. Default=300.0 - - reference Coriolis parameter for determining Rossby radius in - the DOME inflow. Default taken at 70N. - - Critical Richardson number used for dome. When running with - coarse models, dome_crit_richardson=1/1000 is what Legg recommends, - whereas in refined models (finer than 50km), dome_crit_richardson=1/3. - Default is dome_crit_richardson=.001. - - Density difference between inflow and reference for DOME - configuration. Default dome_drho_ref=2.0 - - Depth at the top of the salinity layer. - - Depth at the bottom of the salinity layer. - - Depth at the top of the salinity patch. - - Depth at the bottom of the salinity patch. - - For setting position of salinity patch. - - For setting position of salinity patch. - - Value for uniform initial age. - - For generating the zonal velocity at the t-cell. - - For generating the meridional velocity at the t-cell. - - name array of the zonal velocity component - to be generated. Its default value is 'ut_inflow'. - - name array of the meridional velocity component - to be generated. Its default value is 'vt'. - - zonal velocity output file. Default is 'ut.res.nc' - - meridional velocity output file. Default is 'vt.res.nc' - - Number of active tracers will be generated. Its value should be 0, 1, 2. - Its default value is 2. ( temp and salt ) - - name array of the active tracers will be generated. - Its element value should be 'temp' or 'salt' - - active tracer output file. - - Number of passive tracers will be generated. Its value should be no more than max_tracer. - Its default value is 1 (age). - - name array of the passive tracers will be generated. - Its element value should be 'age'. - - passive tracer output file. - - grid descriptor file. - - For setting idealized vertical profile - - For setting idealized vertical profile - - For setting idealized vertical profile - - For setting idealized vertical profile - - For writing a time axis for the IC. This is useful if - wish to use the IC as a static dataset for sponges. - Default write_time_axis=.true. - - Initialize the module generating ideal initial conditions. - - Write out tracer data to netcdf file - - Release memory. -

                              diff --git a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic_driver.html b/src/preprocessing/mom4_prep/idealized_ic/idealized_ic_driver.html deleted file mode 100644 index 85acf1b44a..0000000000 --- a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic_driver.html +++ /dev/null @@ -1,83 +0,0 @@ - - - -Program idealized_ic_driver - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                              -

                              Program idealized_ic_driver

                              - - -
                              -Contact: Z. Liang -
                              -Reviewers:  S.M. Griffies -
                              -Change History: WebCVS Log -
                              -
                              -
                              - - -
                              -

                              OVERVIEW

                              - -

                              - Driver for ideal initial conditions -

                              - - - -
                              - The program drives the idealized initial condition generation routines. -
                              -
                              - - -
                              -

                              MODULES USED

                              - -
                              -
                                       mpp_mod
                              fms_mod
                              idealized_ic_mod
                              constants_mod
                              -
                              - - - -
                              -

                              PUBLIC INTERFACE

                              -
                              -
                              -
                              -
                              - - -
                              -

                              PUBLIC ROUTINES

                              - -
                                - - - - - - -
                                -
                                -top -
                                - - diff --git a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic_driver.xml b/src/preprocessing/mom4_prep/idealized_ic/idealized_ic_driver.xml deleted file mode 100644 index cc94eba2f5..0000000000 --- a/src/preprocessing/mom4_prep/idealized_ic/idealized_ic_driver.xml +++ /dev/null @@ -1,8 +0,0 @@ - - -Z. Liang S.M. Griffies - Driver for ideal initial conditions - - The program drives the idealized initial condition generation routines. - diff --git a/src/preprocessing/regrid/regrid.F90 b/src/preprocessing/regrid/regrid.F90 index 4b3c98e6e0..c052d35c2e 100644 --- a/src/preprocessing/regrid/regrid.F90 +++ b/src/preprocessing/regrid/regrid.F90 @@ -171,8 +171,8 @@ program regrid end type regrid_type !--- version information --------------------------------------------- - character(len=128) :: version = '$Id: regrid.F90,v 16.0.4.1 2012/01/24 15:26:18 Zhi.Liang Exp $' - character(len=128) :: tagname = '$Name: siena_201205_z1l $' + character(len=128) :: version = '$Id: regrid.F90,v 20.0 2013/12/14 00:31:05 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' !--- other variables integer :: ntime_src ! number of time levels of src data diff --git a/src/preprocessing/regrid/regrid.html b/src/preprocessing/regrid/regrid.html deleted file mode 100644 index 35a25ba51c..0000000000 --- a/src/preprocessing/regrid/regrid.html +++ /dev/null @@ -1,247 +0,0 @@ - - - -Program regrid - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                -

                                Program regrid

                                - - -
                                -Contact:  Zhi Liang -
                                -Reviewers:  -
                                -Change History: WebCVS Log -
                                -
                                -
                                - - -
                                -

                                OVERVIEW

                                - -

                                - This program remap data from logically rectangular grid to logically rectangular grid. -

                                - - - -
                                - This program expects to read data from a netcdf file, which is specfied - by the namelist variable "src_data". The number of data to be remapped is - specified by num_flds. The name of field to be remapped is specified - by the namelist variable "fld_name". The source data should be on the source - grid which is specified by namelist variable src_grid. The destination grid is - specified by nml dst_grd. The output file is a netcdf file specified - by the namelist variable "dst_data". Each field can be a scalar variable or - a vector field, which is specified by vector_fld. The vector field should - always be paired together. A laplacian extrapolation will be performed when - there is any missing value in the source data to interpolate data onto missing points. -
                                -
                                - - -
                                -

                                MODULES USED

                                - -
                                -
                                         mpp_mod
                                mpp_domains_mod
                                fms_mod
                                fms_io_mod
                                constants_mod
                                horiz_interp_mod
                                axis_utils_mod
                                -
                                - - - -
                                -

                                PUBLIC INTERFACE

                                -
                                -
                                -
                                -
                                - - -
                                -

                                PUBLIC ROUTINES

                                - -
                                  - - - - -
                                  -

                                  NAMELIST

                                  - -
                                  -&regrid_nml -
                                  -
                                  -
                                  -
                                  -
                                  -num_flds -
                                  -
                                  - Number of fields. -
                                  -[integer, default: 0] -
                                  -
                                  -src_data -
                                  -
                                  - Name of input file containing to-be-remapped data. -
                                  -[character(len=128)] -
                                  -
                                  -dst_data -
                                  -
                                  - Name of output file containing after-remapped data. -
                                  -[character(len=128)] -
                                  -
                                  -dst_grid -
                                  -
                                  - Name of grid descriptor file containing target grid information. -
                                  -[character(len=128)] -
                                  -
                                  -src_grid -
                                  -
                                  - Name of grid descriptor file containing source grid information. -
                                  -[character(len=128)] -
                                  -
                                  -fld_name -
                                  -
                                  - Name of runoff field in input file. -
                                  -[character(len=128), dimension(max_flds)] -
                                  -
                                  -fld_pos -
                                  -
                                  - Name of grid where the field located. Valid choices are (T)racer, (C)orner, (E)ast and (N)orth. -
                                  -[character(len=1),dimension(max_flds), default: T] -
                                  -
                                  -vector_field -
                                  -
                                  - True if fields are vector components. All the vector field should be paired together. - That is, if vector_field(n) is .true., then vector_field(n+1) should be true. -
                                  -[logical,dimension(max_flds), default: False] -
                                  -
                                  -stop_crit -
                                  -
                                  - The stopping criteria when extrapping data onto missing points. -
                                  -[character(len=1),dimension(max_flds), default: 0.001] -
                                  -
                                  -num_nbrs -
                                  -
                                  - Number of nearest neighbors for regridding. -
                                  -[integer] -
                                  -
                                  -max_dist -
                                  -
                                  - Maximum region of influence around destination grid points. -
                                  -[real, units: radians] -
                                  -
                                  -use_source_vertical_grid -
                                  -
                                  - when use_source_vertical_grid is set to true, the destination data will - have the same vertical level as the source data. When use_source_vertical_grid - is false, the vertical grid of destination data will come from dest_grid. - a linear vertical interpolation will be done when the source vertical is different - from destination vertical grid. -
                                  -[logical, default: .false.] -
                                  -
                                  -apply_mask -
                                  -
                                  - flag to indicate if the land/sea mask of source/destination grid will be applied - on the output dest_file. When apply_mask is false, the destination data will be - global data, i.e. no missing value in the destination data file. When apply_mask - is true, mask will be applied to the destination data. The mask can be either - source grid or destination grid determined by nml use_source_vertical_grid. - When use_source_vertical_grid is true, source grid mask will be applied, otherwise - destination grid mask will be applied. -
                                  -[logical, default: true] -
                                  -
                                  -interp_method -
                                  -
                                  - specifying the remapping method when remampping data onto current grid. - Its value can be "spherical" or " bilinear". "spherical" interpolation is a - inverse distance weighted interpolation algorithm. Default value is "bilinear". - "bilinear" interpolation is recommanded, since bilinear interpolation will provide - more smooth results than "spherical" interpolation (especially when interpolating - from coarse grid to fine grid). Plus bilinear interpolation is much more efficiency - than "spherical interpolation". Since bilinear interpolation suppose the source grid - is a lat-lon grid, "spherical" need to be used if the source grid is not a lat-lon grid. -
                                  -[character(len=20)] -
                                  -
                                  -debug -
                                  -
                                  - For Debugging. Set true to print out chksum information for debugging reproducing ability - accross processors. default is false. -
                                  -[logical] -
                                  -
                                  -
                                  -
                                  -
                                  - - - - -
                                  -
                                  -top -
                                  - - diff --git a/src/preprocessing/regrid_2d/regrid_2d.f90 b/src/preprocessing/regrid_2d/regrid_2d.f90 index 2e56b2a34a..74d497338f 100644 --- a/src/preprocessing/regrid_2d/regrid_2d.f90 +++ b/src/preprocessing/regrid_2d/regrid_2d.f90 @@ -130,6 +130,7 @@ program regrid_2d apply_dest_mask, stop_crit, interp_method !--------------------------------------------------------------------- + integer :: src_unit, dst_grid_unit integer :: ni_src, nj_src, ni_dst, nj_dst, ntime_src type(axistype) :: time_axis, axes_dst(2) type(fieldtype) :: field_lon_dst, field_lat_dst, src_field(2) @@ -153,8 +154,8 @@ program regrid_2d real, dimension(:,:,:,:), allocatable :: data_dst, data_src !--- version information variables - character(len=128) :: version='CVS $Id: regrid_2d.f90,v 14.0 2007/03/15 22:47:20 fms Exp $' - character(len=128) :: tagname='Tag $Name: siena_201207 $' + character(len=128) :: version='CVS $Id: regrid_2d.f90,v 20.0 2013/12/14 00:31:09 fms Exp $' + character(len=128) :: tagname='Tag $Name: tikal $' ! --- Begin of the program @@ -227,7 +228,7 @@ end subroutine regrid_2d_init !--- open grid file and store grid info subroutine read_dst_grid - integer :: unit, ndim, nvar, natt, ntime, i + integer :: ndim, nvar, natt, ntime, i integer :: len1, siz_in(3) logical :: found_xt, found_yt, found_wet logical :: found_xc, found_yc, found_angle @@ -239,15 +240,15 @@ subroutine read_dst_grid if(.not. file_exist(trim(dest_grid)) ) & call mpp_error(FATAL, 'regrid_2d: file '//trim(dest_grid)//' does not exist') - call mpp_open(unit, trim(dest_grid),& + call mpp_open(dst_grid_unit, trim(dest_grid),& action=MPP_RDONLY, form=MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) - call mpp_get_info(unit, ndim, nvar, natt, ntime) + call mpp_get_info(dst_grid_unit, ndim, nvar, natt, ntime) allocate(fields(nvar), global_atts(natt), axes(ndim) ) - call mpp_get_axes(unit, axes) - call mpp_get_atts(unit, global_atts) - call mpp_get_fields(unit,fields) + call mpp_get_axes(dst_grid_unit, axes) + call mpp_get_atts(dst_grid_unit, global_atts) + call mpp_get_fields(dst_grid_unit,fields) do i=1,natt if (trim(mpp_get_att_name(global_atts(i))) == 'y_boundary_type') & @@ -286,35 +287,35 @@ subroutine read_dst_grid !--- get the land/sea mask if(trim(name) == 'wet') then found_wet = .true. - call mpp_read(unit,fields(i),mask_dst) + call mpp_read(dst_grid_unit,fields(i),mask_dst) endif if(dest_grid_type == 'T') then select case (trim(name)) case ('x_T') found_xt = .true. - call mpp_read(unit,fields(i),lon_dst) + call mpp_read(dst_grid_unit,fields(i),lon_dst) field_lon_dst = fields(i) call mpp_get_atts(fields(i),axes=axes_dst) case ('y_T') found_yt = .true. - call mpp_read(unit,fields(i),lat_dst) + call mpp_read(dst_grid_unit,fields(i),lat_dst) field_lat_dst = fields(i) end select else if ( dest_grid_type == 'C' ) then select case (trim(name)) case ('x_C') found_xc = .true. - call mpp_read(unit,fields(i),lon_dst) + call mpp_read(dst_grid_unit,fields(i),lon_dst) field_lon_dst = fields(i) call mpp_get_atts(fields(i),axes=axes_dst) case('y_C') found_yc = .true. - call mpp_read(unit,fields(i),lat_dst) + call mpp_read(dst_grid_unit,fields(i),lat_dst) field_lat_dst = fields(i) case('angle_C') found_angle = .true. allocate(angle(ni_dst,nj_dst), sin_rot(ni_dst,nj_dst), cos_rot(ni_dst,nj_dst) ) - call mpp_read(unit,fields(i),angle) + call mpp_read(dst_grid_unit,fields(i),angle) sin_rot = sin(angle*D2R) cos_rot = cos(angle*D2R) deallocate(angle) @@ -333,7 +334,6 @@ subroutine read_dst_grid if(.not. apply_dest_mask) mask_dst = 1.0 ! will get global data - call mpp_close(unit) deallocate(fields, axes) end subroutine read_dst_grid @@ -342,7 +342,7 @@ end subroutine read_dst_grid !--- read source grid and source data from src_file subroutine read_src_file - integer :: unit, ndim, nvar, natt, n + integer :: ndim, nvar, natt, n integer :: nt, i, j, k, jj, len1, nk_src logical :: flip_y, found_src_field(2) character(len=1) :: cart @@ -357,12 +357,12 @@ subroutine read_src_file if(.not. file_exist(trim(src_file)) ) & call mpp_error(FATAL, 'regrid_2d: file '//trim(src_file)//' does not exist') - call mpp_open(unit, trim(src_file),& + call mpp_open(src_unit, trim(src_file),& action=MPP_RDONLY, form=MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) - call mpp_get_info(unit, ndim, nvar, natt, ntime_src) + call mpp_get_info(src_unit, ndim, nvar, natt, ntime_src) allocate(fields(nvar)) - call mpp_get_fields(unit, fields) + call mpp_get_fields(src_unit, fields) if (numfields > nvar) call mpp_error(FATAL,'not enough fields in file') found_src_field = .FALSE. @@ -415,7 +415,7 @@ subroutine read_src_file ntime_src = len1 time_axis_exists = .true. allocate(time_in(ntime_src)) - call mpp_get_times(unit, time_in) + call mpp_get_times(src_unit, time_in) time_axis = axes(j) end select enddo @@ -437,7 +437,7 @@ subroutine read_src_file if (level > nk_src) call mpp_error(FATAL,'selected level exceeds size of input array') if (nk_src > 1) write(*,*) 'warning: selecting level ',level,' from 3d array' do nt=1,ntime_src - call mpp_read(unit,src_field(n), tmp3d,nt) + call mpp_read(src_unit,src_field(n), tmp3d,nt) tmp=tmp3d(:,:,level) !--- set up the mask of source data @@ -463,7 +463,6 @@ subroutine read_src_file enddo - call mpp_close(unit) deallocate(fields, axes, tmp, tmp3d) @@ -623,6 +622,8 @@ subroutine write_dst_file enddo enddo + call mpp_close(dst_grid_unit) + call mpp_close(src_unit) call mpp_close(unit) end subroutine write_dst_file diff --git a/src/preprocessing/regrid_2d/regrid_2d.html b/src/preprocessing/regrid_2d/regrid_2d.html deleted file mode 100644 index 8a39834705..0000000000 --- a/src/preprocessing/regrid_2d/regrid_2d.html +++ /dev/null @@ -1,233 +0,0 @@ - - - -Program regrid_2d - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                  -

                                  Program regrid_2d

                                  - - -
                                  -Contact: M.J. Harrison ,  - Zhi Liang -
                                  -Reviewers: Bonnie Samuels -
                                  -Change History: WebCVS Log -
                                  -
                                  -
                                  - - -
                                  -

                                  OVERVIEW

                                  - -

                                  - - - -
                                  - regrid 2-d lat-lon gridded data to logically rectangular grid - described by grid descriptor file. If two fields are specified - for regridding, it is assumed that they represent vector components. - Rotation to the local grid direction on the target grid will be performed. - -
                                  -
                                  - - -
                                  -

                                  MODULES USED

                                  - -
                                  -
                                           mpp_mod
                                  mpp_io_mod
                                  mpp_domains_mod
                                  horiz_interp_mod
                                  axis_utils_mod
                                  fms_mod
                                  constants_mod
                                  -
                                  - - - -
                                  -

                                  PUBLIC INTERFACE

                                  -
                                  -
                                  -
                                  -
                                  - - -
                                  -

                                  PUBLIC ROUTINES

                                  - -
                                    - - - - -
                                    -

                                    NAMELIST

                                    - -
                                    -&regrid_2d_nml -
                                    -
                                    -
                                    -
                                    -
                                    -src_file -
                                    -
                                    - Name of input file containing grid and data to be regridded. -
                                    -[character(len=128), default: src_file.nc] -
                                    -
                                    -src_field_name -
                                    -
                                    - Name of input field(s). -
                                    -[character(len=128),dimension(2)] -
                                    -
                                    -dest_field_name -
                                    -
                                    - Name of output field(s). If it is not specified in the namelist, it will - get the value from src_field_name -
                                    -[character(len=128),dimension(2)] -
                                    -
                                    -dest_grid -
                                    -
                                    - Name of grid descriptor file containing target grid information. -
                                    -[character(len=128), default: dest_grid.nc] -
                                    -
                                    -dest_file -
                                    -
                                    - Name of output file. -
                                    -[character(len=128), default: dest_file.nc] -
                                    -
                                    -numfields -
                                    -
                                    - Number of fields (1 or 2). If numfields=2, then the fields are assumed - to represent vector components. -
                                    -[integer, default: 1] -
                                    -
                                    -dest_grid_type -
                                    -
                                    - Name of target grid type. Valid choices are (T)racer and (C)orner -
                                    -[character(len=1), default: T] -
                                    -
                                    -stop_crit -
                                    -
                                    - The stopping criteria when extrapping data onto missing points. -
                                    -[character(len=1),dimension(2), default: 0.001] -
                                    -
                                    -apply_dest_mask -
                                    -
                                    - flag to indicate if the land/sea mask of destination grid will be applied - on the output dest_file. when true, land/sea mask of destination grid will - be applied on the output dest_file. When false, the output data will be - global data. Default is true. -
                                    -[logical, default: true] -
                                    -
                                    -vector_field -
                                    -
                                    - True if fields are vector components. -
                                    -[logical, default: False] -
                                    -
                                    -level -
                                    -
                                    - Vertical level from the source grid if one exists. -
                                    -[integer, default: 1] -
                                    -
                                    -num_nbrs -
                                    -
                                    - Number of nearest neighbors for regridding -
                                    -[integer, default: 10] -
                                    -
                                    -max_dist -
                                    -
                                    - Maximum radial influence for regridding. -
                                    -[integer, units: radians, default: 0.17] -
                                    -
                                    -scale_factor -
                                    -
                                    - scaling factor for data (e.g. -1 to flip sign or 0.01 to convert from centimeters) -
                                    -[real,dimension(2) ] -
                                    -
                                    -interp_method -
                                    -
                                    - specifying the remapping method when remampping data onto current grid. - Its value can be "spherical" or " bilinear". "spherical" interpolation is a - inverse distance weighted interpolation algorithm. Default value is "bilinear". - "bilinear" interpolation is recommanded, since bilinear interpolation will provide - more smooth results than "spherical" interpolation (especially when interpolating - from coarse grid to fine grid). Plus bilinear interpolation is much more efficiency - than "spherical interpolation". -
                                    -[character(len=20)] -
                                    -
                                    -
                                    -
                                    -
                                    - - - - -
                                    -
                                    -top -
                                    - - diff --git a/src/preprocessing/regrid_2d/regrid_2d.xml b/src/preprocessing/regrid_2d/regrid_2d.xml deleted file mode 100644 index be0a4c793e..0000000000 --- a/src/preprocessing/regrid_2d/regrid_2d.xml +++ /dev/null @@ -1,51 +0,0 @@ - - -M.J. Harrison Zhi LiangBonnie Samuels - regrid 2-d lat-lon gridded data to logically rectangular grid - described by grid descriptor file. If two fields are specified - for regridding, it is assumed that they represent vector components. - Rotation to the local grid direction on the target grid will be performed. - - - Name of input file containing grid and data to be regridded. - - Name of input field(s). - - Name of output field(s). If it is not specified in the namelist, it will - get the value from src_field_name - - Name of grid descriptor file containing target grid information. - - Name of output file. - - Number of fields (1 or 2). If numfields=2, then the fields are assumed - to represent vector components. - - Name of target grid type. Valid choices are (T)racer and (C)orner - - The stopping criteria when extrapping data onto missing points. - - flag to indicate if the land/sea mask of destination grid will be applied - on the output dest_file. when true, land/sea mask of destination grid will - be applied on the output dest_file. When false, the output data will be - global data. Default is true. - - True if fields are vector components. - - Vertical level from the source grid if one exists. - - Number of nearest neighbors for regridding - - Maximum radial influence for regridding. - - scaling factor for data (e.g. -1 to flip sign or 0.01 to convert from centimeters) - - specifying the remapping method when remampping data onto current grid. - Its value can be "spherical" or " bilinear". "spherical" interpolation is a - inverse distance weighted interpolation algorithm. Default value is "bilinear". - "bilinear" interpolation is recommanded, since bilinear interpolation will provide - more smooth results than "spherical" interpolation (especially when interpolating - from coarse grid to fine grid). Plus bilinear interpolation is much more efficiency - than "spherical interpolation". - diff --git a/src/preprocessing/regrid_3d/regrid_3d.f90 b/src/preprocessing/regrid_3d/regrid_3d.f90 index 40aee5dc1a..a98c751974 100644 --- a/src/preprocessing/regrid_3d/regrid_3d.f90 +++ b/src/preprocessing/regrid_3d/regrid_3d.f90 @@ -18,9 +18,9 @@ program regrid_3d ! or see: http://www.gnu.org/licenses/gpl.html !----------------------------------------------------------------------- ! - ! Bonnie Samuels - ! Zhi Liang - ! M.J. Harrison + ! Bonnie Samuels + ! Zhi Liang + ! M.J. Harrison ! ! ! regrid 3-d lat-lon gridded data to logically rectangular grid @@ -148,7 +148,7 @@ program regrid_3d type(axistype) :: depth_axis, time_axis, axes_dst(2) type(fieldtype) :: field_lon_dst, field_lat_dst type(fieldtype) :: dest_field(max_fields) - integer :: dest_unit, dst_grid_unit + integer :: dest_unit, dst_grid_unit logical :: time_axis_exists = .false. real, parameter :: tol = 1.e-10 ! tolerance for detecting missing values real, parameter :: max_val=1.e20 @@ -165,8 +165,8 @@ program regrid_3d real, dimension(:,:), allocatable :: lon_dst, lat_dst real, dimension(:,:,:), allocatable :: mask_dst !--- version information variables - character(len=128) :: version='CVS $Id: regrid_3d.f90,v 18.0.2.1.2.2 2013/09/26 18:21:14 Zhi.Liang Exp $' - character(len=128) :: tagname='Tag $Name: $' + character(len=128) :: version='CVS $Id: regrid_3d.f90,v 20.0 2013/12/14 00:31:13 fms Exp $' + character(len=128) :: tagname='Tag $Name: tikal $' ! --- Begin of the program diff --git a/src/preprocessing/regrid_3d/regrid_3d.html b/src/preprocessing/regrid_3d/regrid_3d.html deleted file mode 100644 index a41381ad97..0000000000 --- a/src/preprocessing/regrid_3d/regrid_3d.html +++ /dev/null @@ -1,249 +0,0 @@ - - - -Program regrid_3d - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                    -

                                    Program regrid_3d

                                    - - -
                                    -Contact: Bonnie Samuels ,  - Zhi Liang -
                                    -Reviewers: M.J. Harrison -
                                    -Change History: WebCVS Log -
                                    -
                                    -
                                    - - -
                                    -

                                    OVERVIEW

                                    - -

                                    - - - -
                                    - regrid 3-d lat-lon gridded data to logically rectangular grid - described by grid descriptor file. Applies only to scalar fields - No missing points allowed on input grid. - -
                                    -
                                    - - -
                                    -

                                    MODULES USED

                                    - -
                                    -
                                             mpp_mod
                                    mpp_io_mod
                                    mpp_domains_mod
                                    horiz_interp_mod
                                    axis_utils_mod
                                    fms_mod
                                    constants_mod
                                    -
                                    - - - -
                                    -

                                    PUBLIC INTERFACE

                                    -
                                    -
                                    -
                                    -
                                    - - -
                                    -

                                    PUBLIC ROUTINES

                                    - -
                                      - - - - -
                                      -

                                      NAMELIST

                                      - -
                                      -&regrid_3d_nml -
                                      -
                                      -
                                      -
                                      -
                                      -src_file -
                                      -
                                      - Name of input file containing grid and data to be regridded. -
                                      -[character(len=128), default: src_file.nc] -
                                      -
                                      -numfields -
                                      -
                                      - Number of fields. -
                                      -[integer, default: 2] -
                                      -
                                      -src_field_name -
                                      -
                                      - Name of input field(s). default is (/'temp', 'salt'/) -
                                      -[character(len=128), dimension(max_fields)] -
                                      -
                                      -dest_field_name -
                                      -
                                      - Name of output field(s). If it is not specified in the namelist, it will - get the value from src_field_name -
                                      -[character(len=128), dimension(max_fields)] -
                                      -
                                      -dest_grid -
                                      -
                                      - Name of grid descriptor file containing target grid information. -
                                      -[character(len=128), default: dest_grid.nc] -
                                      -
                                      -dest_file -
                                      -
                                      - Name of output file. -
                                      -[character(len=128), default: dest_file.nc] -
                                      -
                                      -num_nbrs -
                                      -
                                      - Number of nearest neighbors for regridding -
                                      -[integer, default: 10] -
                                      -
                                      -max_dist -
                                      -
                                      - Maximum radial influence for regridding. -
                                      -[integer, units: radians, default: 0.17] -
                                      -
                                      -scale_factor -
                                      -
                                      - scaling factor for data (e.g. -1 to flip sign or 0.01 to convert from centimeters) -
                                      -[real ] -
                                      -
                                      -stop_crit -
                                      -
                                      - The stopping criteria when extrapping data onto missing points. -
                                      -[character(len=1),dimension(2), default: 0.001] -
                                      -
                                      -use_source_vertical_grid -
                                      -
                                      - when use_source_vertical_grid is set to true, the destination data will - have the same vertical level as the source data. When use_source_vertical_grid - is false, the vertical grid of destination data will come from dest_grid. - A linear vertical interpolation will be done when the source vertical is different - from destination vertical grid. -
                                      -[logical, default: .false.] -
                                      -
                                      -apply_mask -
                                      -
                                      - flag to indicate if the land/sea mask of source/destination grid will be applied - on the output dest_file. When apply_mask is false, the destination data will be - global data, i.e. no missing value in the destination data file. When apply_mask - is true, mask will be applied to the destination data. The mask can be either - source grid or destination grid determined by nml use_source_vertical_grid. - When use_source_vertical_grid is true, source grid mask will be applied, otherwise - destination grid mask will be applied. -
                                      -[logical, default: true] -
                                      -
                                      -interp_method -
                                      -
                                      - specifying the remapping method when remampping data onto current grid. - Its value can be "spherical" or " bilinear". "spherical" interpolation is a - inverse distance weighted interpolation algorithm. Default value is "bilinear". - "bilinear" interpolation is recommanded, since bilinear interpolation will provide - more smooth results than "spherical" interpolation (especially when interpolating - from coarse grid to fine grid). Plus bilinear interpolation is much more efficiency - than "spherical interpolation". -
                                      -[character(len=20)] -
                                      -
                                      -ntimes_saved -
                                      -
                                      - number of time levels to be saved. Its value has to be less than or equal to the number - of time levels in the source data file. -
                                      -[integer] -
                                      -
                                      -timelevel_saved -
                                      -
                                      - specify the selection of time levels to be saved. The number of elements to be specified - should be equal to ntimes_saved. -
                                      -[integer(max_ntimes_saved)] -
                                      -
                                      -debug -
                                      -
                                      - For Debugging. Set true to print out chksum information for debugging reproducing ability - accross processors. default is false. -
                                      -[logical] -
                                      -
                                      -
                                      -
                                      -
                                      - - - - -
                                      -
                                      -top -
                                      - - diff --git a/src/preprocessing/regrid_3d/regrid_3d.xml b/src/preprocessing/regrid_3d/regrid_3d.xml deleted file mode 100644 index 8d6092d6cf..0000000000 --- a/src/preprocessing/regrid_3d/regrid_3d.xml +++ /dev/null @@ -1,61 +0,0 @@ - - -Bonnie Samuels Zhi LiangM.J. Harrison - regrid 3-d lat-lon gridded data to logically rectangular grid - described by grid descriptor file. Applies only to scalar fields - No missing points allowed on input grid. - - - Name of input file containing grid and data to be regridded. - - Number of fields. - - Name of input field(s). default is (/'temp', 'salt'/) - - Name of output field(s). If it is not specified in the namelist, it will - get the value from src_field_name - - Name of grid descriptor file containing target grid information. - - Name of output file. - - Number of nearest neighbors for regridding - - Maximum radial influence for regridding. - - scaling factor for data (e.g. -1 to flip sign or 0.01 to convert from centimeters) - - The stopping criteria when extrapping data onto missing points. - - when use_source_vertical_grid is set to true, the destination data will - have the same vertical level as the source data. When use_source_vertical_grid - is false, the vertical grid of destination data will come from dest_grid. - A linear vertical interpolation will be done when the source vertical is different - from destination vertical grid. - - flag to indicate if the land/sea mask of source/destination grid will be applied - on the output dest_file. When apply_mask is false, the destination data will be - global data, i.e. no missing value in the destination data file. When apply_mask - is true, mask will be applied to the destination data. The mask can be either - source grid or destination grid determined by nml use_source_vertical_grid. - When use_source_vertical_grid is true, source grid mask will be applied, otherwise - destination grid mask will be applied. - - specifying the remapping method when remampping data onto current grid. - Its value can be "spherical" or " bilinear". "spherical" interpolation is a - inverse distance weighted interpolation algorithm. Default value is "bilinear". - "bilinear" interpolation is recommanded, since bilinear interpolation will provide - more smooth results than "spherical" interpolation (especially when interpolating - from coarse grid to fine grid). Plus bilinear interpolation is much more efficiency - than "spherical interpolation". - - number of time levels to be saved. Its value has to be less than or equal to the number - of time levels in the source data file. - - specify the selection of time levels to be saved. The number of elements to be specified - should be equal to ntimes_saved. - - For Debugging. Set true to print out chksum information for debugging reproducing ability - accross processors. default is false. - diff --git a/src/preprocessing/river_regrid/river_regrid.f90 b/src/preprocessing/river_regrid/river_regrid.f90 index a8271e2e44..1914457b56 100644 --- a/src/preprocessing/river_regrid/river_regrid.f90 +++ b/src/preprocessing/river_regrid/river_regrid.f90 @@ -114,7 +114,7 @@ program river_regrid !--- version information --------------------------------------------- character(len=128) :: version = '$ID$' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' !--- other variables type(river_regrid_type),save :: Source diff --git a/src/preprocessing/river_regrid/river_regrid.html b/src/preprocessing/river_regrid/river_regrid.html deleted file mode 100644 index d27655a202..0000000000 --- a/src/preprocessing/river_regrid/river_regrid.html +++ /dev/null @@ -1,156 +0,0 @@ - - - -Program river_regrid - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                      -

                                      Program river_regrid

                                      - - -
                                      -Contact:  Zhi Liang ,  - Kirsten Findell -
                                      -Reviewers:  -
                                      -Change History: WebCVS Log -
                                      -
                                      -
                                      - - -
                                      -

                                      OVERVIEW

                                      - -

                                      - This program can remap river network data from spherical grid onto another - spherical grid. -

                                      - - - -
                                      - The program expects to read river network data from a netcdf file, which - is specified by the namelist variable "river_input_file". This file should - contains field 'cellarea', 'tocell', 'fromcell', 'basin', 'basincells', - 'order', 'travel', 'subL', 'subA','disttomouth', 'disttoocean' and 'dx'. - The program will remap the data in "river_input_file" onto the grid, which - is specified by namelist grid_file. The grid file should contains the same - grid as the land modle to be run. The output is stored in a netcdf file, which - is specified by river_output_file. -
                                      -
                                      - - -
                                      -

                                      MODULES USED

                                      - -
                                      -
                                               mpp_mod
                                      mpp_domains_mod
                                      mpp_io_mod
                                      fms_mod
                                      axis_utils_mod
                                      constants_mod
                                      fms_io_mod
                                      horiz_interp_mod
                                      -
                                      - - - -
                                      -

                                      PUBLIC INTERFACE

                                      -
                                      -
                                      -
                                      -
                                      - - -
                                      -

                                      PUBLIC ROUTINES

                                      - -
                                        - - - - -
                                        -

                                        NAMELIST

                                        - -
                                        -&river_regrid_nml -
                                        -
                                        -
                                        -
                                        -
                                        -river_input_file -
                                        -
                                        - river data source file. -
                                        -[character(len=128)] -
                                        -
                                        -grid_file -
                                        -
                                        - the grid file that contains land and ocean grid information. -
                                        -[character(len=128)] -
                                        -
                                        -river_output_file -
                                        -
                                        - The output river data file after coupled with land grid. -
                                        -[character(len=128)] -
                                        -
                                        -lon_start, lon_end -
                                        -
                                        - starting and ending longitude of the river network to be extended to. Default value is 0 and 360. -
                                        -[real] -
                                        -
                                        -lat_start, lat_end -
                                        -
                                        - starting and ending latitude of the river network to be extended to. Default value is -90 and 90. -
                                        -[real] -
                                        -
                                        -lat_end -
                                        -
                                        - The ending latitude. Default value is 90. Used to extend river network. -
                                        -[real] -
                                        -
                                        -
                                        -
                                        -
                                        - - - - -
                                        -
                                        -top -
                                        - - diff --git a/src/preprocessing/river_regrid/river_regrid.xml b/src/preprocessing/river_regrid/river_regrid.xml deleted file mode 100644 index b72b906e40..0000000000 --- a/src/preprocessing/river_regrid/river_regrid.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - Zhi Liang Kirsten Findell - This program can remap river network data from spherical grid onto another - spherical grid. - - The program expects to read river network data from a netcdf file, which - is specified by the namelist variable "river_input_file". This file should - contains field 'cellarea', 'tocell', 'fromcell', 'basin', 'basincells', - 'order', 'travel', 'subL', 'subA','disttomouth', 'disttoocean' and 'dx'. - The program will remap the data in "river_input_file" onto the grid, which - is specified by namelist grid_file. The grid file should contains the same - grid as the land modle to be run. The output is stored in a netcdf file, which - is specified by river_output_file. - - river data source file. - - the grid file that contains land and ocean grid information. - - The output river data file after coupled with land grid. - - starting and ending longitude of the river network to be extended to. Default value is 0 and 360. - - starting and ending latitude of the river network to be extended to. Default value is -90 and 90. - - The ending latitude. Default value is 90. Used to extend river network. - diff --git a/src/preprocessing/runoff_regrid/create_grid.F90 b/src/preprocessing/runoff_regrid/create_grid.F90 index e590fcf0b3..132a4a662f 100644 --- a/src/preprocessing/runoff_regrid/create_grid.F90 +++ b/src/preprocessing/runoff_regrid/create_grid.F90 @@ -58,7 +58,7 @@ program create_grid !--- version information --------------------------------------------- character(len=128) :: version= '$ID$' - character(len=128) :: tagname= '$Name: siena_201205_z1l $' + character(len=128) :: tagname= '$Name: tikal $' !--- other variables ------------------------------------------------- real, allocatable :: lon(:), lat(:) diff --git a/src/preprocessing/runoff_regrid/create_grid.html b/src/preprocessing/runoff_regrid/create_grid.html deleted file mode 100644 index 9bbb8ffced..0000000000 --- a/src/preprocessing/runoff_regrid/create_grid.html +++ /dev/null @@ -1,122 +0,0 @@ - - - -Program create_grid - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                        -

                                        Program create_grid

                                        - - -
                                        -Contact:  Zhi Liang -
                                        -Reviewers:  -
                                        -Change History: WebCVS Log -
                                        -
                                        -
                                        - - -
                                        -

                                        OVERVIEW

                                        - -

                                        - This program works together with program make_xgrids, runoff_regrid to - remap runoff data from a spherical grid onto any grid. This program can - generate a spherical grid netcdf file that can be used to generate exchange - grid grid_spec.nc with the destination grid file ( ocean grid file). - -

                                        - - - -
                                        - This program expects to get grid data from a netcdf file, which is specfied - by the namelist variable "src_data". The name of the runoff field is specified - by the namelist variable "src_fld_name". The output file is a netcdf file with - name "atmos_grid.nc". -
                                        -
                                        - - -
                                        -

                                        MODULES USED

                                        - -
                                        -
                                        
                                        -
                                        - - - -
                                        -

                                        PUBLIC INTERFACE

                                        -
                                        -
                                        -
                                        -
                                        - - -
                                        -

                                        PUBLIC ROUTINES

                                        - -
                                          - - - - -
                                          -

                                          NAMELIST

                                          - -
                                          -&runoff_regrid_nml -
                                          -
                                          -
                                          -
                                          -
                                          -src_data -
                                          -
                                          - Name of input file containing runoff data. -
                                          -[character(len=128)] -
                                          -
                                          -src_fld_name -
                                          -
                                          - Name of runoff field. -
                                          -[character(len=128),dimension(2)] -
                                          -
                                          -
                                          -
                                          -
                                          - - - - -
                                          -
                                          -top -
                                          - - diff --git a/src/preprocessing/runoff_regrid/create_grid.xml b/src/preprocessing/runoff_regrid/create_grid.xml deleted file mode 100644 index 443bf13537..0000000000 --- a/src/preprocessing/runoff_regrid/create_grid.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - Zhi Liang - This program works together with program make_xgrids, runoff_regrid to - remap runoff data from a spherical grid onto any grid. This program can - generate a spherical grid netcdf file that can be used to generate exchange - grid grid_spec.nc with the destination grid file ( ocean grid file). - - - This program expects to get grid data from a netcdf file, which is specfied - by the namelist variable "src_data". The name of the runoff field is specified - by the namelist variable "src_fld_name". The output file is a netcdf file with - name "atmos_grid.nc". - - Name of input file containing runoff data. - - Name of runoff field. - diff --git a/src/preprocessing/runoff_regrid/runoff_regrid.F90 b/src/preprocessing/runoff_regrid/runoff_regrid.F90 index 18e38032b8..0dc221536f 100644 --- a/src/preprocessing/runoff_regrid/runoff_regrid.F90 +++ b/src/preprocessing/runoff_regrid/runoff_regrid.F90 @@ -79,7 +79,7 @@ program runoff_regrid !--- version information --------------------------------------------- character(len=128) :: version= '$ID$' - character(len=128) :: tagname= '$Name: siena_201205_z1l $' + character(len=128) :: tagname= '$Name: tikal $' !--- other variables ------------------------------------------------- real, allocatable :: time_value(:) real, allocatable :: runoff(:,:,:), runoff_src(:,:,:) diff --git a/src/preprocessing/runoff_regrid/runoff_regrid.html b/src/preprocessing/runoff_regrid/runoff_regrid.html deleted file mode 100644 index 0397ee2d23..0000000000 --- a/src/preprocessing/runoff_regrid/runoff_regrid.html +++ /dev/null @@ -1,151 +0,0 @@ - - - -Program runoff_regrid - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                          -

                                          Program runoff_regrid

                                          - - -
                                          -Contact:  Sergey Malyshev ,  - Zhi Liang -
                                          -Reviewers:  -
                                          -Change History: WebCVS Log -
                                          -
                                          -
                                          - - -
                                          -

                                          OVERVIEW

                                          - -

                                          - This program works together with program make_xgrids, create_grid to - remap runoff data from a spherical grid onto any grid (spherical or tripolar) - using conservative scheme. -

                                          - - - -
                                          - This program expects to read runoff data from a netcdf file, which is specfied - by the namelist variable "src_data". The name of the runoff field in input file is specified - by the namelist variable "src_fld_name". The output file is a netcdf file specified - by the namelist variable "dst_data". The name of the runoff field in output file is specified - by the namelist variable "src_fld_name". Both the source grid and destination grid - are read from netcdf file "grid_spec.nc". The grid_spec.nc is expected contains - field 'x_T' and 'y_T', which is the new name convention used as a prototype for ESMF. - The source grid read from variable "xta" and "yta" of "grid_spec.nc" should match - the grid in "src_data". "grid_spec.nc" is generated by - " make_xgrid -a atmos_grid.nc -l atmos_grid.nc -o dst_grid.nc ", - where dst_grid is the grid which you want remap runoff data on and atmos_grid.nc - is generated through program "create_grid", which is located at the same directory - as this program. make_xgrid is a c program that generates exchange grid between - atmos, ocean and land grid. make_xgrid source code is located at - "../generate_grids/make_xgrids". If there is any land point has runoff data - after remapping runoff data onto destination grid, the runoff value of that land point - will be moved to the nearest ocean point. - -
                                          -
                                          - - -
                                          -

                                          MODULES USED

                                          - -
                                          -
                                          
                                          -
                                          - - - -
                                          -

                                          PUBLIC INTERFACE

                                          -
                                          -
                                          -
                                          -
                                          - - -
                                          -

                                          PUBLIC ROUTINES

                                          - -
                                            - - - - -
                                            -

                                            NAMELIST

                                            - -
                                            -&runoff_regrid_nml -
                                            -
                                            -
                                            -
                                            -
                                            -src_data -
                                            -
                                            - Name of input file containing runoff data. -
                                            -[character(len=128)] -
                                            -
                                            -src_fld_name -
                                            -
                                            - Name of runoff field in input file. -
                                            -[character(len=128)] -
                                            -
                                            -dst_fld_name -
                                            -
                                            - Name of runoff field in output file. -
                                            -[character(len=128)] -
                                            -
                                            -dst_data -
                                            -
                                            - Name of output file containing runoff data. -
                                            -[character(len=128)] -
                                            -
                                            -
                                            -
                                            -
                                            - - - - -
                                            -
                                            -top -
                                            - - diff --git a/src/preprocessing/runoff_regrid/runoff_regrid.xml b/src/preprocessing/runoff_regrid/runoff_regrid.xml deleted file mode 100644 index 7d2048a424..0000000000 --- a/src/preprocessing/runoff_regrid/runoff_regrid.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - Sergey Malyshev Zhi Liang - This program works together with program make_xgrids, create_grid to - remap runoff data from a spherical grid onto any grid (spherical or tripolar) - using conservative scheme. - - This program expects to read runoff data from a netcdf file, which is specfied - by the namelist variable "src_data". The name of the runoff field in input file is specified - by the namelist variable "src_fld_name". The output file is a netcdf file specified - by the namelist variable "dst_data". The name of the runoff field in output file is specified - by the namelist variable "src_fld_name". Both the source grid and destination grid - are read from netcdf file "grid_spec.nc". The grid_spec.nc is expected contains - field 'x_T' and 'y_T', which is the new name convention used as a prototype for ESMF. - The source grid read from variable "xta" and "yta" of "grid_spec.nc" should match - the grid in "src_data". "grid_spec.nc" is generated by - " make_xgrid -a atmos_grid.nc -l atmos_grid.nc -o dst_grid.nc ", - where dst_grid is the grid which you want remap runoff data on and atmos_grid.nc - is generated through program "create_grid", which is located at the same directory - as this program. make_xgrid is a c program that generates exchange grid between - atmos, ocean and land grid. make_xgrid source code is located at - "../generate_grids/make_xgrids". If there is any land point has runoff data - after remapping runoff data onto destination grid, the runoff value of that land point - will be moved to the nearest ocean point. - - - Name of input file containing runoff data. - - Name of runoff field in input file. - - Name of runoff field in output file. - - Name of output file containing runoff data. - diff --git a/src/shared/amip_interp/amip_interp.F90 b/src/shared/amip_interp/amip_interp.F90 index aa9e98d5fe..4c3b79ef9b 100644 --- a/src/shared/amip_interp/amip_interp.F90 +++ b/src/shared/amip_interp/amip_interp.F90 @@ -101,7 +101,7 @@ module amip_interp_mod ! ---- version number ----- character(len=128) :: version = '$Id: amip_interp.F90,v 19.0 2012/01/06 21:54:21 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' real, allocatable:: temp1(:,:), temp2(:,:) diff --git a/src/shared/astronomy/astronomy.F90 b/src/shared/astronomy/astronomy.F90 index 9c28fe1fce..b41b00932c 100644 --- a/src/shared/astronomy/astronomy.F90 +++ b/src/shared/astronomy/astronomy.F90 @@ -45,8 +45,8 @@ module astronomy_mod !--------------------------------------------------------------------- !----------- version number for this module -------------------------- -character(len=128) :: version = '$Id: astronomy.F90,v 19.0 2012/01/06 21:54:23 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: astronomy.F90,v 20.0 2013/12/14 00:18:17 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' !--------------------------------------------------------------------- @@ -169,7 +169,7 @@ module astronomy_mod logical :: module_is_initialized= & .false. ! has the module been initialized ? -real, dimension(:), allocatable :: & +real, dimension(:,:), allocatable :: & cosz_ann, & ! annual mean cos of zenith angle solar_ann, & ! annual mean solar factor fracday_ann ! annual mean daylight fraction @@ -273,6 +273,7 @@ subroutine astronomy_init (latb, lonb) !----------------------------------------------------------------------- #ifdef INTERNAL_FILE_NML read (input_nml_file, astronomy_nml, iostat=io) + ierr = check_nml_error(io,'astronomy_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file ( ) @@ -345,9 +346,9 @@ subroutine astronomy_init (latb, lonb) if (present(latb)) then jd = size(latb,2) - 1 id = size(lonb,1) - 1 - allocate (cosz_ann(jd)) - allocate (solar_ann(jd)) - allocate (fracday_ann(jd)) + allocate (cosz_ann(id, jd)) + allocate (solar_ann(id, jd)) + allocate (fracday_ann(id, jd)) total_pts = jd*id endif @@ -2723,9 +2724,9 @@ subroutine annual_mean_solar_2d (js, je, lat, cosz, solar, fracday, & ! those variables are present; i.e., not the spectral 2-layer model. !--------------------------------------------------------------------- if (allocated (cosz_ann)) then - cosz_ann(js:je) = cosz(1,:) - solar_ann(js:je) = solar(1,:) - fracday_ann(js:je) = fracday(1,:) + cosz_ann = cosz + solar_ann = solar + fracday_ann = fracday rrsun_ann = rrsun !-------------------------------------------------------------------- @@ -2743,11 +2744,9 @@ subroutine annual_mean_solar_2d (js, je, lat, cosz, solar, fracday, & !-------------------------------------------------------------------- else if (allocated (cosz_ann)) then - do i=1, size(lat,1) - cosz(i,:) = cosz_ann(js:je) - solar(i,:) = solar_ann(js:je) - fracday(i,:) = fracday_ann(js:je) - end do + cosz = cosz_ann + solar = solar_ann + fracday = fracday_ann rrsun = rrsun_ann endif endif @@ -2855,9 +2854,9 @@ subroutine annual_mean_solar_1d (jst, jnd, lat, cosz, solar, & ! variables contain the results at the desired latitudes. !-------------------------------------------------------------------- else - cosz(:) = cosz_ann(jst:jnd) - solar(:) = solar_ann(jst:jnd) - fracday(:) = fracday_ann(jst:jnd) + cosz(:) = cosz_ann(1,jst:jnd) + solar(:) = solar_ann(1,jst:jnd) + fracday(:) = fracday_ann(1,jst:jnd) rrsun = rrsun_ann endif diff --git a/src/shared/axis_utils/axis_utils.F90 b/src/shared/axis_utils/axis_utils.F90 index 8f4f7bb459..59f3b42db6 100644 --- a/src/shared/axis_utils/axis_utils.F90 +++ b/src/shared/axis_utils/axis_utils.F90 @@ -43,8 +43,8 @@ module axis_utils_mod integer, parameter :: maxatts = 100 real, parameter :: epsln= 1.e-10 real, parameter :: fp5 = 0.5, f360 = 360.0 - character(len=256) :: version = '$Id: axis_utils.F90,v 19.0 2012/01/06 21:54:25 fms Exp $' - character(len=256) :: tagname = '$Name: siena_201207 $' + character(len=256) :: version = '$Id: axis_utils.F90,v 20.0 2013/12/14 00:18:21 fms Exp $' + character(len=256) :: tagname = '$Name: tikal $' interface interp_1d module procedure interp_1d_1d @@ -833,6 +833,7 @@ program test !---reading namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, test_axis_utils_nml, iostat=io) + ierr = check_nml_error(io,'test_axis_utils_nml') #else if(file_exist('input.nml')) then unit = open_namelist_file() diff --git a/src/shared/column_diagnostics/column_diagnostics.F90 b/src/shared/column_diagnostics/column_diagnostics.F90 index 4f814c919d..6e8652767d 100644 --- a/src/shared/column_diagnostics/column_diagnostics.F90 +++ b/src/shared/column_diagnostics/column_diagnostics.F90 @@ -34,8 +34,8 @@ module column_diagnostics_mod !----------- ****** VERSION NUMBER ******* --------------------------- -character(len=128) :: version = '$Id: column_diagnostics.F90,v 19.0 2012/01/06 21:54:27 fms Exp $' -character(len=128) :: tag = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: column_diagnostics.F90,v 20.0 2013/12/14 00:18:24 fms Exp $' +character(len=128) :: tag = '$Name: tikal $' @@ -131,6 +131,7 @@ subroutine column_diagnostics_init !--------------------------------------------------------------------- #ifdef INTERNAL_FILE_NML read (input_nml_file, column_diagnostics_nml, iostat=io) + ierr = check_nml_error (io, 'column_diagnostics_nml') #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/constants/constants.F90 b/src/shared/constants/constants.F90 index b23340d485..7f02965fb6 100644 --- a/src/shared/constants/constants.F90 +++ b/src/shared/constants/constants.F90 @@ -19,7 +19,7 @@ module constants_mod private character(len=128) :: version='$Id: constants.F90,v 17.0 2009/07/21 03:18:26 fms Exp $' -character(len=128) :: tagname='$Name: siena_201207 $' +character(len=128) :: tagname='$Name: tikal $' !dummy variable to use in HUGE initializations real :: realnumber diff --git a/src/shared/coupler/atmos_ocean_fluxes.F90 b/src/shared/coupler/atmos_ocean_fluxes.F90 index 2f6bf7a6c5..35c2053af2 100644 --- a/src/shared/coupler/atmos_ocean_fluxes.F90 +++ b/src/shared/coupler/atmos_ocean_fluxes.F90 @@ -189,7 +189,7 @@ module atmos_ocean_fluxes_mod !{ ! character(len=128) :: version = '$Id: atmos_ocean_fluxes.F90,v 18.0 2010/03/02 23:55:03 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' ! !----------------------------------------------------------------------- diff --git a/src/shared/coupler/coupler_types.F90 b/src/shared/coupler/coupler_types.F90 index 978ede14e0..8cf23970df 100644 --- a/src/shared/coupler/coupler_types.F90 +++ b/src/shared/coupler/coupler_types.F90 @@ -172,7 +172,7 @@ module coupler_types_mod !{ ! !----------------------------------------------------------------------- character(len=128) :: version = '$Id: coupler_types.F90,v 18.0 2010/03/02 23:55:06 fms Exp $' - character(len=128) :: tag = '$Name: siena_201207 $' + character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- real, parameter :: bound_tol = 1e-7 diff --git a/src/shared/coupler/ensemble_manager.F90 b/src/shared/coupler/ensemble_manager.F90 index 1bc02a0f95..394ceed49f 100644 --- a/src/shared/coupler/ensemble_manager.F90 +++ b/src/shared/coupler/ensemble_manager.F90 @@ -38,7 +38,7 @@ module ensemble_manager_mod subroutine ensemble_manager_init() - integer :: i, io_status, ioun, npes + integer :: i, io_status, ioun, npes, ierr namelist /ensemble_nml/ ensemble_size @@ -49,6 +49,7 @@ subroutine ensemble_manager_init() read(ioun,nml=ensemble_nml,iostat = io_status) call close_file(ioun) #endif + ierr = check_nml_error(io_status, 'ensemble_nml') if(ensemble_size < 1) call mpp_error(FATAL, & 'ensemble_manager_mod: ensemble_nml variable ensemble_size must be a positive integer') @@ -222,9 +223,8 @@ subroutine ensemble_pelist_setup(concurrent, atmos_npes, ocean_npes, land_npes, ensemble_pelist_land (n, 1:land_npes) = (/(i,i=land_pe_start, land_pe_end)/) ensemble_pelist_ice (n, 1:ice_npes) = (/(i,i=ice_pe_start, ice_pe_end)/) ensemble_pelist(n, 1:atmos_npes) = ensemble_pelist_atmos(n, 1:atmos_npes) - if( concurrent .OR. atmos_npes+ocean_npes == npes ) then - ensemble_pelist(n, atmos_npes+1:npes) = ensemble_pelist_ocean(n, 1:ocean_npes) - endif + if( concurrent .OR. atmos_npes+ocean_npes == npes ) & + ensemble_pelist(n, atmos_npes+1:npes) = ensemble_pelist_ocean(n, 1:ocean_npes) if(ANY(ensemble_pelist(n,:) == pe)) ensemble_id = n write(pelist_name,'(a,i2.2)') '_ens',n call mpp_declare_pelist(ensemble_pelist(n,:), trim(pelist_name)) diff --git a/src/shared/data_override/data_override.F90 b/src/shared/data_override/data_override.F90 index 11e934e55d..2cbbc0b7d4 100644 --- a/src/shared/data_override/data_override.F90 +++ b/src/shared/data_override/data_override.F90 @@ -67,7 +67,7 @@ module data_override_mod init_external_field, get_external_field_size, & NO_REGION, INSIDE_REGION, OUTSIDE_REGION, & set_override_region, reset_src_data_region -use fms_io_mod, only: field_size, read_data, fms_io_init,get_mosaic_tile_grid +use fms_io_mod, only: field_size, read_data, fms_io_init,get_mosaic_tile_grid, get_mosaic_tile_file use fms_mod, only: write_version_number, field_exist, lowercase, file_exist, open_namelist_file, check_nml_error, close_file use axis_utils_mod, only: get_axis_bounds, nearest_index use mpp_domains_mod, only : domain2d, mpp_get_compute_domain, NULL_DOMAIN2D,operator(.NE.),operator(.EQ.) @@ -80,8 +80,8 @@ module data_override_mod implicit none private -character(len=128) :: version = '$Id: data_override.F90,v 18.0.4.1.2.1.2.2.2.1.2.1.2.3 2012/04/20 18:08:09 Zhi.Liang Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: data_override.F90,v 20.0 2013/12/14 00:18:34 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' type data_type character(len=3) :: gridname @@ -562,7 +562,7 @@ subroutine data_override_3d(gridname,fieldname_code,data,time,override,data_inde integer, optional, intent(in) :: is_in, ie_in, js_in, je_in logical, dimension(:,:,:), allocatable :: mask_out - character(len=512) :: filename !file containing source data + character(len=512) :: filename, filename2 !file containing source data character(len=128) :: fieldname ! fieldname used in the data file integer :: i,j integer :: dims(4) @@ -588,6 +588,7 @@ subroutine data_override_3d(gridname,fieldname_code,data,time,override,data_inde logical :: need_compute real :: lat_min, lat_max integer :: is_src, ie_src, js_src, je_src + logical :: exists use_comp_domain = .false. if(.not.module_is_initialized) & @@ -688,6 +689,14 @@ subroutine data_override_3d(gridname,fieldname_code,data,time,override,data_inde if( data_table(index1)%region_type .NE. NO_REGION ) then call mpp_error(FATAL,'data_override: ongrid must be false when region_type .NE. NO_REGION') endif + +! Allow on-grid data_overrides on cubed sphere grid + inquire(file=trim(filename),EXIST=exists) + if (.not. exists) then + call get_mosaic_tile_file(filename,filename2,.false.,domain) + filename = filename2 + endif + !--- we always only pass data on compute domain id_time = init_external_field(filename,fieldname,domain=domain,verbose=.false., & use_comp_domain=use_comp_domain, nwindows=nwindows) @@ -1329,6 +1338,7 @@ program test #ifdef INTERNAL_FILE_NML read (input_nml_file, test_data_override_nml, iostat=io) + ierr = check_nml_error(io, 'test_data_override_nml') #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/data_override/data_override.html b/src/shared/data_override/data_override.html deleted file mode 100644 index c7a5d52f76..0000000000 --- a/src/shared/data_override/data_override.html +++ /dev/null @@ -1,296 +0,0 @@ - - - -Module data_override_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                            -

                                            Module data_override_mod

                                            - - -
                                            -Contact:  - G.T. Nong - ,  - - M.J. Harrison - ,  - - M. Winton - -
                                            -Reviewers:  -
                                            -Change History: WebCVS Log -
                                            -
                                            -
                                            - - -
                                            -

                                            OVERVIEW

                                            - -

                                            - Given a gridname, fieldname and model time this routine will get data in a file whose - path is described in a user-provided data_table, do spatial and temporal interpolation if - necessary to convert data to model's grid and time. - - Before using data_override a data_table must be created with the following entries: - gridname, fieldname_code, fieldname_file, file_name, ongrid, factor. - - More explainations about data_table entries can be found in the source code (defining data_type) - - If user wants to override fieldname_code with a const, set fieldname_file in data_table = "" - and factor = const - - If user wants to override fieldname_code with data from a file, set fieldname_file = name in - the netCDF data file, factor then will be for unit conversion (=1 if no conversion required) - - A field can be overriden globally (by default) or users can specify one or two regions in which - data_override will take place, field values outside the region will not be affected. -

                                            - - - -
                                            -
                                            - - -
                                            -

                                            OTHER MODULES USED

                                            - -
                                            -
                                                        platform_mod
                                            constants_mod
                                            mpp_io_mod
                                            mpp_mod
                                            horiz_interp_mod
                                            time_interp_external_mod
                                            fms_io_mod
                                            fms_mod
                                            axis_utils_mod
                                            mpp_domains_mod
                                            time_manager_mod
                                            -
                                            - - - -
                                            -

                                            PUBLIC INTERFACE

                                            - -
                                            - - -
                                            -

                                            PUBLIC ROUTINES

                                            - -
                                              -
                                            1. - -

                                              data_override_init

                                              -
                                              -call data_override_init 
                                              -
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Assign default values for default_table, get domain of component models, - get global grids of component models. - Users should call data_override_init before calling data_override -
                                              -
                                              -
                                              -
                                              -NOTE -
                                              -
                                              - This subroutine should be called in coupler_init after - (ocean/atmos/land/ice)_model_init have been called. - - data_override_init can be called more than once, in one call the user can pass - up to 4 domains of component models, at least one domain must be present in - any call - - Data_table is initialized here with default values. Users should provide "real" values - that will override the default values. Real values can be given using data_table, each - line of data_table contains one data_entry. Items of data_entry are comma separated. - -
                                              -
                                              -
                                              -
                                              -
                                            2. -
                                            3. - -

                                              data_override_2d

                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - This routine performs data override for 2D fields; for usage, see data_override_3d. -
                                              -
                                              -
                                              -
                                              -
                                            4. -
                                            5. - -

                                              data_override_3d

                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - This routine performs data override for 3D fields -
                                              -call  call data_override(gridname,fieldname,data,time,override)
                                              - -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - - - - - - - - - - -
                                              gridname    - Grid name (Ocean, Ice, Atmosphere, Land) -
                                                 [character, dimension(*)]
                                              fieldname_code    - Field name as used in the code (may be different from the name in NetCDF data file) -
                                                 [character, dimension(*)]
                                              time    - model time -
                                                 [time_type]
                                              data_index    - -
                                                 [integer]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - - - - -
                                              data    - array containing output data -
                                                 [real, dimension(:,:,:)]
                                              override    - TRUE if the field is overriden, FALSE otherwise -
                                                 [logical]
                                              -
                                              -
                                              -
                                              -
                                            6. -
                                            7. - -

                                              data_override_0d

                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - This routine performs data override for scalar fields -
                                              -call  call data_override(fieldname,data,time,override)
                                              - -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - - - - - - - - - - -
                                              gridname    - Grid name (Ocean, Ice, Atmosphere, Land) -
                                                 [character, dimension(*)]
                                              fieldname_code    - Field name as used in the code (may be different from the name in NetCDF data file) -
                                                 [character, dimension(*)]
                                              time    - model time -
                                                 [time_type]
                                              data_index    - -
                                                 [integer]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - - - - -
                                              data    - array containing output data -
                                                 [real, dimension(:,:,:)]
                                              override    - TRUE if the field is overriden, FALSE otherwise -
                                                 [logical]
                                              -
                                              -
                                              -
                                              -
                                            8. -
                                            - - - - - - -
                                            -
                                            -top -
                                            - - diff --git a/src/shared/diag_manager/diag_axis.F90 b/src/shared/diag_manager/diag_axis.F90 index 824b387d92..e40635abd4 100644 --- a/src/shared/diag_manager/diag_axis.F90 +++ b/src/shared/diag_manager/diag_axis.F90 @@ -33,9 +33,9 @@ MODULE diag_axis_mod ! Module variables ! Parameters CHARACTER(len=128), PARAMETER :: version =& - & '$Id: diag_axis.F90,v 19.0.2.2 2012/04/13 16:27:46 sdu Exp $' + & '$Id: diag_axis.F90,v 20.0 2013/12/14 00:18:37 fms Exp $' CHARACTER(len=128), PARAMETER :: tagname =& - & '$Name: siena_201207 $' + & '$Name: tikal $' ! counter of number of axes defined INTEGER, DIMENSION(:), ALLOCATABLE :: num_subaxes @@ -456,7 +456,7 @@ SUBROUTINE get_diag_axis(id, name, units, long_name, cart_name,& ! array data is too small. CALL error_mesg('diag_axis_mod::get_diag_axis', 'array data is too small', FATAL) ELSE - DATA(1:Axes(id)%length) = Axes(id)%data + DATA(1:Axes(id)%length) = Axes(id)%data(1:Axes(id)%length) END IF END SUBROUTINE get_diag_axis !
                                            diff --git a/src/shared/diag_manager/diag_axis.html b/src/shared/diag_manager/diag_axis.html deleted file mode 100644 index e3ac172fc7..0000000000 --- a/src/shared/diag_manager/diag_axis.html +++ /dev/null @@ -1,820 +0,0 @@ - - - -Module diag_axis_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ ERROR MESSAGES -
                                            -

                                            Module diag_axis_mod

                                            - - -
                                            -Contact:  - Seth Underwood - -
                                            -Reviewers:  -
                                            -Change History: WebCVS Log -
                                            -
                                            -
                                            - - -
                                            -

                                            OVERVIEW

                                            - -

                                            -diag_axis_mod is an integral part - of diag_manager_mod. It helps to create axis IDs - that are used in register_diag_field. -

                                            - - - -
                                            Users first create axis ID by calling - diag_axis_init, then use this axis ID in - register_diag_field. -
                                            -
                                            - - -
                                            -

                                            OTHER MODULES USED

                                            - -
                                            -
                                            mpp_domains_mod
                                            fms_mod
                                            diag_data_mod
                                            -
                                            - - - -
                                            -

                                            PUBLIC INTERFACE

                                            -
                                            -
                                            -
                                            -diag_axis_init:
                                            -
                                            - Initialize the axis, and return the axis ID. -
                                            -
                                            -diag_subaxes_init:
                                            -
                                            - Create a subaxis on a parent axis. -
                                            -
                                            -get_diag_axis:
                                            -
                                            - Return information about the axis with index ID -
                                            -
                                            -get_diag_axis_cart:
                                            -
                                            - Return the axis cartesian. -
                                            -
                                            -get_diag_axis_data:
                                            -
                                            - Return the axis data. -
                                            -
                                            -get_diag_axis_name:
                                            -
                                            - Return the short name of the axis. -
                                            -
                                            -get_diag_axis_domain_name:
                                            -
                                            - Return the name of the axis' domain -
                                            -
                                            -get_axis_length:
                                            -
                                            - Return the length of the axis. -
                                            -
                                            -get_axis_aux:
                                            -
                                            - Return the auxiliary name for the axis. -
                                            -
                                            -get_axis_global_length:
                                            -
                                            - Return the global length of the axis. -
                                            -
                                            -get_tile_count:
                                            -
                                            - Return the tile count for the axis. -
                                            -
                                            -get_domain1d:
                                            -
                                            - Return the 1D domain. -
                                            -
                                            -get_domain2d:
                                            -
                                            - Return the 2D domain. -
                                            -
                                            -get_axes_shift:
                                            -
                                            - Return the value of the shift. -
                                            -
                                            -
                                            -
                                            - - -
                                            -

                                            PUBLIC ROUTINES

                                            - -
                                              -
                                            1. - -

                                              diag_axis_init

                                              -
                                              INTEGER FUNCTION diag_axis_init (name, data, units, cart_name, long_name, direction, set_name, edges, Domain, Domain2, aux, tile_count)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - -diag_axis_init initializes an axis and returns the axis ID that - is to be used with register_diag_field. This function also - increments the axis counter and fills in the axes -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                              name   Short name for axis
                                                 [CHARACTER(len=*)]
                                              data   Array of coordinate values
                                                 [REAL, DIMENSION(:)]
                                              units   Units for the axis
                                                 [CHARACTER(len=*)]
                                              cart_name    - Cartesian axis ("X", "Y", "Z", "T") -
                                                 [CHARACTER(len=*)]
                                              direction    - Indicates the direction of the axis: -
                                                - -
                                              • Up if +1
                                              • - -
                                              • Down if -1
                                              • - -
                                              • Neither up or down if 0
                                              • - -
                                              - -
                                                 [INTEGER, OPTIONAL] [Default: 0]
                                              long_name    - Long name for the axis. -
                                                 [CHARACTER(len=*), OPTIONAL] [Default: name]
                                              edges    - Axis ID for the previously defined "edges axis" -
                                                 [INTEGER, OPTIONAL]
                                              Domain    -
                                                 [TYPE(domain1d), OPTIONAL]
                                              Domain2    -
                                                 [TYPE(domain2d), OPTIONAL]
                                              aux    - Auxiliary name, can only be geolon_t or geolat_t - -
                                                 [CHARACTER(len=*), OPTIONAL]
                                              tile_count    -
                                                 [INTEGER, OPTIONAL]
                                              -
                                              -
                                              -
                                              -
                                            2. -
                                            3. - -

                                              diag_subaxes_init

                                              -
                                              INTEGER FUNCTION diag_subaxes_init (axis, subdata, start_indx, end_indx, domain_1d, domain_2d)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Given the ID of a parent axis, create a subaxis and fill it with data, - and return the ID of the corresponding subaxis. - - The subaxis is defined on the parent axis from start_indx - to end_indx. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - - - - - - - - - - - - - - - - -
                                              axis   ID of the parent axis
                                                 [INTEGER]
                                              subdata   Data of the subaxis
                                                 [REAL, DIMENSION(:)]
                                              start_indx   Start index of the subaxis
                                                 [INTEGER]
                                              end_indx   End index of the subaxis
                                                 [INTEGER]
                                              domain_1d    -
                                                 [TYPE(domain1d), OPTIONAL]
                                              domain_2d    -
                                                 [TYPE(domain2d), OPTIONAL]
                                              -
                                              -
                                              -
                                              -
                                            4. -
                                            5. - -

                                              get_diag_axis

                                              -
                                              SUBROUTINE get_diag_axis (id, name, units, long_name, cart_name, direction, edges, Domain, data)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return information about the axis with index ID -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - - - - - - - - - - - - - - - - - - - - - - -
                                              name   Short name for axis
                                                 [CHARACTER(len=*)]
                                              units   Units for axis
                                                 [CHARACTER(len=*)]
                                              long_name   Long name for axis
                                                 [CHARACTER(len=*)]
                                              cart_name    - Cartesian axis ("x", "y", "z", "t"). -
                                                 [CHARACTER(len=*)]
                                              direction    - Direction of data. (See diag_axis_init for a description of - allowed values) -
                                                 [INTEGER]
                                              edges    - Axis ID for the previously defined "edges axis". -
                                                 [INTEGER]
                                              Domain    -
                                                 [TYPE(domain1d)]
                                              data    - Array of coordinate values for this axis. -
                                                 [REAL, DIMENSION(:)]
                                              -
                                              -
                                              -
                                              -
                                            6. -
                                            7. - -

                                              get_diag_axis_cart

                                              -
                                              SUBROUTINE get_diag_axis_cart (id, cart_name)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the axis cartesian ('X', 'Y', 'Z' or 'T') for the axis ID given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - -
                                              cart_name   Cartesian axis
                                                 [CHARACTER(len=*)]
                                              -
                                              -
                                              -
                                              -
                                            8. -
                                            9. - -

                                              get_diag_axis_data

                                              -
                                              SUBROUTINE get_diag_axis_data (id, data)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the axis data for the axis ID given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - -
                                              data   Axis data
                                                 [REAL, DIMENSION(:)]
                                              -
                                              -
                                              -
                                              -
                                            10. -
                                            11. - -

                                              get_diag_axis_name

                                              -
                                              SUBROUTINE get_diag_axis_name (id, name)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the short name for the axis ID given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - -
                                              name   Axis short name
                                                 [CHARACTER(len=*)]
                                              -
                                              -
                                              -
                                              -
                                            12. -
                                            13. - -

                                              get_diag_axis_domain_name

                                              -
                                              SUBROUTINE get_diag_axis_domain_name (id, name)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Retruns the name of the axis' domain. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - -
                                              name   Axis' domain name
                                                 [CHARACTER(len=*)]
                                              -
                                              -
                                              -
                                              -
                                            14. -
                                            15. - -

                                              get_axis_length

                                              -
                                              INTEGER FUNCTION get_axis_length (id)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the length of the axis ID given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -
                                            16. -
                                            17. - -

                                              get_axis_aux

                                              -
                                              CHARACTER(len=128) FUNCTION get_axis_aux (id)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Returns the auxiliary name for the axis. The only possible values for - the auxiliary names is geolon_t or geolat_t. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -
                                            18. -
                                            19. - -

                                              get_axis_global_length

                                              -
                                              INTEGER FUNCTION get_axis_global_length (id)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Returns the global length of the axis ID given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -
                                            20. -
                                            21. - -

                                              get_tile_count

                                              -
                                              INTEGER FUNCTION get_tile_count (ids)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the tile count for the axis IDs given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              ids    - Axis IDs. Possible dimensions: 1 <= size(ids(:)) <= 4. -
                                                 [INTEGER, DIMENSION(:)]
                                              -
                                              -
                                              -
                                              -
                                            22. -
                                            23. - -

                                              get_domain1d

                                              -
                                              TYPE(domain1d) FUNCTION get_domain1d (id)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Retrun the 1D domain for the axis ID given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              id   Axis ID
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -
                                            24. -
                                            25. - -

                                              get_domain2d

                                              -
                                              TYPE(domain2d) FUNCTION get_domain2d (ids)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the 2D domain for the axis IDs given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              ids    - Axis IDs. Possible dimensions: 1 <= size(ids(:)) <= 4. -
                                                 [INTEGER, DIMENSION(:)]
                                              -
                                              -
                                              -
                                              -
                                            26. -
                                            27. - -

                                              get_axes_shift

                                              -
                                              SUBROUTINE get_axes_shift (ids, ishift, jshift)
                                              -
                                              -
                                              -DESCRIPTION -
                                              -
                                              - Return the value of the shift for the axis IDs given. -
                                              -
                                              -
                                              -
                                              -INPUT -
                                              -
                                              - - - - -
                                              ids    - Axis IDs. Possible dimensions: 1 <= size(ids(:)) <= 4 -
                                                 [INTEGER, DIMENSION(:)]
                                              -
                                              -
                                              -
                                              -OUTPUT -
                                              -
                                              - - - - - - - -
                                              ishift   X shift value.
                                                 [INTEGER]
                                              jshift   Y shift value.
                                                 [INTEGER]
                                              -
                                              -
                                              -
                                              -
                                            28. -
                                            - - - - - - -
                                            -

                                            ERROR MESSAGES

                                            - -
                                            -
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            - num_axis_sets (<num_axis_sets>) exceeds max_num_axis_sets(<num_axis_sets>). - Increase max_num_axis_sets via diag_manager_nml. -
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            axis_name <NAME> and axis_set already exist.
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            max_axes exceeded, increase it via diag_manager_nml
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            Invalid cart_name name.
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            direction must be 0, +1, or -1
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            Presence of both Domain and Domain2 at the same time is prohibited
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            Domain must not be present for an axis which is not in the X or Y direction.
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            Edges axis does not match axis (code <CODE>).
                                            -
                                            -FATAL in diag_axis_init -
                                            -
                                            - -
                                            -
                                            Edges axis is not defined.
                                            -
                                            -FATAL in diag_subaxes_init -
                                            -
                                            - -
                                            -
                                            max_subaxes (value <VALUE>) is too small. Consider increasing max_subaxes.
                                            -
                                            -FATAL in get_diag_axis -
                                            -
                                            - -
                                            -
                                            array data is too small.
                                            -
                                            -FATAL in get_diag_axis_data -
                                            -
                                            - -
                                            -
                                            array data is too small
                                            -
                                            -FATAL in get_tile_count -
                                            -
                                            - -
                                            -
                                            input argument has incorrect size.
                                            -
                                            -FATAL in get_domain2d -
                                            -
                                            - -
                                            -
                                            input argument has incorrect size.
                                            -
                                            -
                                            -
                                            - -
                                            -
                                            -top -
                                            - - diff --git a/src/shared/diag_manager/diag_data.F90 b/src/shared/diag_manager/diag_data.F90 index 80b0e60e9d..d3d9a4e29c 100644 --- a/src/shared/diag_manager/diag_data.F90 +++ b/src/shared/diag_manager/diag_data.F90 @@ -51,9 +51,6 @@ MODULE diag_data_mod ! ! Maximum number of fields per file. ! - ! - ! Maximum number of output_fields per input_field. - ! ! ! ! @@ -72,7 +69,6 @@ MODULE diag_data_mod ! Specify storage limits for fixed size tables used for pointers, etc. INTEGER, PARAMETER :: MAX_FIELDS_PER_FILE = 300 !< Maximum number of fields per file. - INTEGER, PARAMETER :: MAX_OUT_PER_IN_FIELD = 150 !< Maximum number of output_fields per input_field INTEGER, PARAMETER :: DIAG_OTHER = 0 INTEGER, PARAMETER :: DIAG_OCEAN = 1 INTEGER, PARAMETER :: DIAG_ALL = 2 @@ -306,7 +302,7 @@ MODULE diag_data_mod LOGICAL :: missing_value_present, range_present REAL :: missing_value REAL, DIMENSION(2) :: range - INTEGER, DIMENSION(max_out_per_in_field) :: output_fields + INTEGER, _ALLOCATABLE, dimension(:) :: output_fields INTEGER :: num_output_fields INTEGER, DIMENSION(3) :: size LOGICAL :: static, register, mask_variant, local @@ -515,9 +511,9 @@ MODULE diag_data_mod ! Private CHARACTER Arrays for the CVS version and tagname. CHARACTER(len=128),PRIVATE :: version =& - & '$Id: diag_data.F90,v 19.0.2.3 2012/05/14 18:40:11 Seth.Underwood Exp $' + & '$Id: diag_data.F90,v 20.0 2013/12/14 00:18:41 fms Exp $' CHARACTER(len=128),PRIVATE :: tagname =& - & '$Name: siena_201207 $' + & '$Name: tikal $' ! ! @@ -547,6 +543,9 @@ MODULE diag_data_mod ! ! Maximum number of input fields. Increase via the diag_manager_nml namelist. ! + ! + ! Maximum number of output_fields per input_field. + ! ! ! Maximum number of independent axes. ! @@ -570,6 +569,7 @@ MODULE diag_data_mod INTEGER :: max_files = 31 !< Maximum number of output files allowed. Increase via diag_manager_nml. INTEGER :: max_output_fields = 300 !< Maximum number of output fields. Increase via diag_manager_nml. INTEGER :: max_input_fields = 300 !< Maximum number of input fields. Increase via diag_manager_nml. + INTEGER :: MAX_OUT_PER_IN_FIELD = 150 !< Maximum number of output_fields per input_field. Increase via diag_manager_nml. INTEGER :: max_axes = 60 !< Maximum number of independent axes. LOGICAL :: do_diag_field_log = .FALSE. LOGICAL :: write_bytes_in_file = .FALSE. diff --git a/src/shared/diag_manager/diag_data.html b/src/shared/diag_manager/diag_data.html deleted file mode 100644 index 7a3a46f700..0000000000 --- a/src/shared/diag_manager/diag_data.html +++ /dev/null @@ -1,1396 +0,0 @@ - - - -Module diag_data_mod - - - - -PUBLIC INTERFACE - ~ PUBLIC DATA - - ~ PUBLIC ROUTINES -
                                            -

                                            Module diag_data_mod

                                            - - -
                                            -Contact:  - Seth Underwood - -
                                            -Reviewers:  -
                                            -Change History: WebCVS Log -
                                            -
                                            -
                                            - - -
                                            -

                                            OVERVIEW

                                            - -

                                            - Type descriptions and global variables for the diag_manager modules. -

                                            - - - -
                                            - Notation: -
                                            - -
                                            input field
                                            - -
                                            The data structure describing the field as - registered by the model code.
                                            - - -
                                            output field
                                            - -
                                            The data structure describing the actual - diagnostic output with requested frequency and - other options.
                                            - -
                                            - - Input fields, output fields, and output files are gathered in arrays called - "input_fields", "output_fields", and "files", respectively. Indices in these - arrays are used as pointers to create associations between various data - structures. - - Each input field associated with one or several output fields via array of - indices output_fields; each output field points to the single "parent" input - field with the input_field index, and to the output file with the output_file - index -
                                            -
                                            - - -
                                            -

                                            OTHER MODULES USED

                                            - -
                                            -
                                            time_manager_mod
                                            mpp_domains_mod
                                            mpp_io_mod
                                            fms_mod
                                            netcdf
                                            -
                                            - - - -
                                            -

                                            PUBLIC INTERFACE

                                            -
                                            -
                                            -
                                            -
                                            - - -
                                            -

                                            PUBLIC DATA

                                            - -
                                            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                            Name Type Value Units Description
                                            MAX_FIELDS_PER_FILE INTEGER, PARAMETER 300 --- - Maximum number of fields per file. -
                                            MAX_OUT_PER_IN_FIELD INTEGER, PARAMETER 150 --- - Maximum number of output_fields per input_field. -
                                            DIAG_OTHER INTEGER, PARAMETER 0 --- ---
                                            DIAG_OCEAN INTEGER, PARAMETER 1 --- ---
                                            DIAG_ALL INTEGER, PARAMETER 2 --- ---
                                            VERY_LARGE_FILE_FREQ INTEGER, PARAMETER 100000 --- ---
                                            VERY_LARGE_AXIS_LENGTH INTEGER, PARAMETER --- --- ---
                                            EVERY_TIME INTEGER, PARAMETER 0 --- ---
                                            END_OF_RUN INTEGER, PARAMETER -1 --- ---
                                            DIAG_SECONDS INTEGER, PARAMETER 1 --- ---
                                            DIAG_MINUTES INTEGER, PARAMETER 2 --- ---
                                            DIAG_HOURS INTEGER, PARAMETER 3 --- ---
                                            DIAG_DAYS INTEGER, PARAMETER 4 --- ---
                                            DIAG_MONTHS INTEGER, PARAMETER 5 --- ---
                                            DIAG_YEARS INTEGER, PARAMETER 6 --- ---
                                            MAX_SUBAXES INTEGER, PARAMETER 10 --- ---
                                            CMOR_MISSING_VALUE REAL, PARAMETER 1.0e20 --- ---
                                            num_files INTEGER 0 --- - Number of output files currenly in use by the diag_manager. -
                                            num_input_fields INTEGER 0 --- - Number of input fields in use. -
                                            num_output_fields INTEGER 0 --- - Number of output fields in use. -
                                            null_axis_id INTEGER --- --- ---
                                            append_pelist_name LOGICAL .FALSE. --- ---
                                            mix_snapshot_average_fields LOGICAL .FALSE. --- ---
                                            max_files INTEGER 31 --- - Maximum number of output files allowed. Increase via the diag_manager_nml namelist. -
                                            max_output_fields INTEGER 300 --- - Maximum number of output fields. Increase via the diag_manager_nml namelist. -
                                            max_input_fields INTEGER 300 --- - Maximum number of input fields. Increase via the diag_manager_nml namelist. -
                                            max_axes INTEGER 60 --- - Maximum number of independent axes. -
                                            do_diag_field_log LOGICAL .FALSE. --- ---
                                            write_bytes_in_file LOGICAL .FALSE. --- ---
                                            debug_diag_manager LOGICAL .FALSE. --- ---
                                            max_num_axis_sets INTEGER 25 --- ---
                                            use_cmor LOGICAL .FALSE. --- - Indicates if we should overwrite the MISSING_VALUE to use the CMOR missing value. -
                                            ISSUE_OOR_WARNINGS LOGICAL .TRUE. --- - Issue warnings if the output field has values outside the given - range for a variable. -
                                            OOR_WARNINGS_FATAL LOGICAL .FALSE. --- - Cause a fatal error if the output field has a value outside the - given range for a variable. -
                                            FILL_VALUE REAL NF90_FILL_REAL --- - Fill value used. Value will be if using the - netCDF module, otherwise will be 9.9692099683868690e+36. -
                                            EMPTY REAL 0.0 --- ---
                                            MAX_VALUE REAL --- --- ---
                                            MIN_VALUE REAL --- --- ---
                                            base_time TYPE(time_type) --- --- ---
                                            base_year INTEGER --- --- ---
                                            base_month INTEGER --- --- ---
                                            base_day INTEGER --- --- ---
                                            base_hour INTEGER --- --- ---
                                            base_minute INTEGER --- --- ---
                                            base_second INTEGER --- --- ---
                                            global_descriptor CHARACTER(len=256) --- --- ---
                                            files TYPE(file_type), DIMENSION(:), SAVE, ALLOCATABLE --- --- ---
                                            input_fields TYPE(input_field_type), DIMENSION(:), ALLOCATABLE --- --- ---
                                            output_fields TYPE(output_field_type), DIMENSION(:), ALLOCATABLE --- --- ---
                                            time_zero TYPE(time_type) --- --- ---
                                            first_send_data_call LOGICAL .TRUE. --- ---
                                            module_is_initialized LOGICAL .FALSE. --- ---
                                            diag_log_unit INTEGER --- --- ---
                                            time_unit_list CHARACTER(len=10), DIMENSION(6) (/'seconds ', 'minutes ', 'hours ', 'days ', 'months ', 'years '/) --- ---
                                            filename_appendix CHARACTER(len=32) --- ---
                                            pelist_name CHARACTER(len=32) --- --- ---
                                            -
                                            -
                                            - - -
                                            -

                                            PUBLIC ROUTINES

                                            - -
                                              - - - -
                                              -

                                              PUBLIC TYPES

                                              -
                                              -diag_grid -
                                              -
                                              -
                                              -
                                              - Contains the coordinates of the local domain to output. -
                                              -
                                              -
                                              -start -
                                              -
                                              - Start coordinates (Lat, Lon, Depth) of the local domain to output. -
                                              -[REAL, DIMENSION(3)] -
                                              -
                                              -end -
                                              -
                                              - End coordinates (Lat, Lon, Depth) of the local domain to output. -
                                              -[REAL, DIMENSION(3)] -
                                              -
                                              -l_start_indx -
                                              -
                                              - Start indices at each local PE. -
                                              -[INTEGER, DIMENSION(3)] -
                                              -
                                              -l_end_indx -
                                              -
                                              - End indices at each local PE. -
                                              -[INTEGER, DIMENSION(3)] -
                                              -
                                              -subaxes -
                                              -
                                              - ID returned from diag_subaxes_init of 3 subaces. -
                                              -[INTEGER, DIMENSION(3)] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -diag_fieldtype -
                                              -
                                              -
                                              -
                                              - Diagnostic field type -
                                              -
                                              -
                                              -Field -
                                              -
                                              - -
                                              -[TYPE(fieldtype)] -
                                              -
                                              -Domain -
                                              -
                                              - -
                                              -[TYPE(domain2d)] -
                                              -
                                              -miss -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -miss_pack -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -miss_present -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -miss_pack_present -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -tile_count -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -coord_type -
                                              -
                                              -
                                              -
                                              - Define the region for field output. -
                                              -
                                              -
                                              -xbegin -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -xend -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -ybegin -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -yend -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -zbegin -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -zend -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -file_type -
                                              -
                                              -
                                              -
                                              - Type to define the diagnostic files that will be written as defined by the diagnostic table. -
                                              -
                                              -
                                              -name -
                                              -
                                              - Name of the output file. -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -long_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -fields -
                                              -
                                              - -
                                              -[INTEGER, dimension(max_fields_per_file)] -
                                              -
                                              -num_fields -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -output_freq -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -output_units -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -format -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -time_units -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -file_unit -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -bytes_written -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -time_axis_id -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -time_bounds_id -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -new_file_freq -
                                              -
                                              - Frequency to create a new file. -
                                              -[INTEGER] -
                                              -
                                              -new_file_freq_units -
                                              -
                                              - Time units of new_file_freq ( days, hours, years, ...) -
                                              -[INTEGER] -
                                              -
                                              -duration -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -duration_units -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -tile_count -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -local -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -last_flush -
                                              -
                                              - -
                                              -[TYPE(time_type)] -
                                              -
                                              -next_open -
                                              -
                                              - Time to open next file. -
                                              -[TYPE(time_type)] -
                                              -
                                              -start_time -
                                              -
                                              - Time file opened -
                                              -[TYPE(time_type)] -
                                              -
                                              -close_time -
                                              -
                                              - Time file closed. File does not allow data after close time -
                                              -[TYPE(time_type)] -
                                              -
                                              -f_avg_start -
                                              -
                                              - -
                                              -[TYPE(diag_fieldtype)] -
                                              -
                                              -f_avg_end -
                                              -
                                              - -
                                              -[TYPE(diag_fieldtype)] -
                                              -
                                              -f_avg_nitems -
                                              -
                                              - -
                                              -[TYPE(diag_fieldtype)] -
                                              -
                                              -f_bounds -
                                              -
                                              - -
                                              -[TYPE(diag_fieldtype)] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -input_field_type -
                                              -
                                              -
                                              -
                                              - Type to hold the input field description -
                                              -
                                              -
                                              -module_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -field_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -long_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -units -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -standard_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -interp_method -
                                              -
                                              - -
                                              -[CHARACTER(len=64)] -
                                              -
                                              -axes -
                                              -
                                              - -
                                              -[INTEGER, DIMENSION(3)] -
                                              -
                                              -num_axes -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -missing_value_present -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -range_present -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -missing_value -
                                              -
                                              - -
                                              -[REAL] -
                                              -
                                              -range -
                                              -
                                              - -
                                              -[REAL, DIMENSION(2)] -
                                              -
                                              -output_fields -
                                              -
                                              - -
                                              -[INTEGER, DIMENSION(max_out_per_in_field)] -
                                              -
                                              -num_output_fields -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -size -
                                              -
                                              - -
                                              -[INTEGER, DIMENSION(3)] -
                                              -
                                              -static -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -register -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -mask_variant -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -local -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -tile_count -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -local_coord -
                                              -
                                              - -
                                              -[TYPE(coord_type)] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -output_field_type -
                                              -
                                              -
                                              -
                                              - Type to hold the output field description. -
                                              -
                                              -
                                              -input_field -
                                              -
                                              - Index of the corresponding input field in the table -
                                              -[INTEGER] -
                                              -
                                              -output_file -
                                              -
                                              - Index of the output file in the table -
                                              -[INTEGER] -
                                              -
                                              -output_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -static -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -time_max -
                                              -
                                              - .TRUE. if the output field is maximum over time interval -
                                              -[LOGICAL] -
                                              -
                                              -time_min -
                                              -
                                              - .TRUE. if the output field is minimum over time interval -
                                              -[LOGICAL] -
                                              -
                                              -time_average -
                                              -
                                              - .TRUE. if the output field is averaged over time interval. -
                                              -[LOGICAL] -
                                              -
                                              -time_ops -
                                              -
                                              - .TRUE. if any of time_min, time_max, or time_average is true -
                                              -[LOGICAL] -
                                              -
                                              -pack -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -time_method -
                                              -
                                              - Time method field from the input file -
                                              -[CHARACTER(len=50)] -
                                              -
                                              -buffer -
                                              -
                                              - Coordinates of buffer are (x, y, z, time-of-day) -
                                              -[REAL, _ALLOCATABLE, DIMENSION(:,:,:,:), default: _NULL] -
                                              -
                                              -counter -
                                              -
                                              - Coordinates of buffer are (x, y, z, time-of-day) -
                                              -[REAL, _ALLOCATABLE, DIMENSION(:,:,:,:), default: _NULL] -
                                              -
                                              -count_0d -
                                              -
                                              - -
                                              -[REAL, _ALLOCATABLE, DIMENSION(:)] -
                                              -
                                              -num_elements -
                                              -
                                              - -
                                              -[REAL, _ALLOCATABLE, DIMENSION(:)] -
                                              -
                                              -last_output -
                                              -
                                              - -
                                              -[TYPE(time_type)] -
                                              -
                                              -next_output -
                                              -
                                              - -
                                              -[TYPE(time_type)] -
                                              -
                                              -next_next_output -
                                              -
                                              - -
                                              -[TYPE(time_type)] -
                                              -
                                              -f_type -
                                              -
                                              - -
                                              -[TYPE(diag_fieldtype)] -
                                              -
                                              -axes -
                                              -
                                              - -
                                              -[INTEGER, DIMENSION(4)] -
                                              -
                                              -num_axes -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -total_elements -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -region_elements -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -n_diurnal_samples -
                                              -
                                              - Number of diurnal sample intervals, 1 or more -
                                              -[INTEGER] -
                                              -
                                              -output_grid -
                                              -
                                              - -
                                              -[TYPE(diag_grid)] -
                                              -
                                              -local_output -
                                              -
                                              - .TRUE. if this field is written out on a region and not globally. -
                                              -[LOGICAL] -
                                              -
                                              -need_compute -
                                              -
                                              - .TRUE. if this field is written out on a region, not global. -
                                              -[LOGICAL] -
                                              -
                                              -phys_window -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -written_once -
                                              -
                                              - -
                                              -[LOGICAL] -
                                              -
                                              -reduced_k_range -
                                              -
                                              - .TRUE. if dealing with vertical sub-level output. -
                                              -[LOGICAL] -
                                              -
                                              -imin -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -imax -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -jmin -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -jmax -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -kmin -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -kmax -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -Time_of_prev_field_data -
                                              -
                                              - -
                                              -[TYPE(time_type)] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -diag_axis_type -
                                              -
                                              -
                                              -
                                              - Type to hold the diagnostic axis description. -
                                              -
                                              -
                                              -name -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -units -
                                              -
                                              - -
                                              -[CHARACTER(len=256)] -
                                              -
                                              -long_name -
                                              -
                                              - -
                                              -[CHARACTER(len=256)] -
                                              -
                                              -cart_name -
                                              -
                                              - -
                                              -[CHARACTER(len=1)] -
                                              -
                                              -data -
                                              -
                                              - -
                                              -[REAL, DIMENSION(:), POINTER] -
                                              -
                                              -start -
                                              -
                                              - -
                                              -[INTEGER, DIMENSION(MAX_SUBAXES)] -
                                              -
                                              -end -
                                              -
                                              - -
                                              -[INTEGER, DIMENSION(MAX_SUBAXES)] -
                                              -
                                              -subaxis_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128), DIMENSION(MAX_SUBAXES)] -
                                              -
                                              -length -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -direction -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -edges -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -set -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -shift -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -Domain -
                                              -
                                              - -
                                              -[TYPE(domain1d)] -
                                              -
                                              -Domain2 -
                                              -
                                              - -
                                              -[TYPE(domain2d)] -
                                              -
                                              -subaxis_domain2 -
                                              -
                                              - -
                                              -[TYPE(domain2d), dimension(MAX_SUBAXES)] -
                                              -
                                              -aux -
                                              -
                                              - -
                                              -[CHARACTER(len=128)] -
                                              -
                                              -tile_count -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -diag_global_att_type -
                                              -
                                              -
                                              -
                                              - -
                                              -
                                              -
                                              -grid_type -
                                              -
                                              - -
                                              -[CHARACTER(len=128), default: regular] -
                                              -
                                              -tile_name -
                                              -
                                              - -
                                              -[CHARACTER(len=128), default: N/A] -
                                              -
                                              -
                                              -
                                              -
                                              - - - - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/diag_manager/diag_grid.F90 b/src/shared/diag_manager/diag_grid.F90 index a358130bf5..d78c8af522 100644 --- a/src/shared/diag_manager/diag_grid.F90 +++ b/src/shared/diag_manager/diag_grid.F90 @@ -60,9 +60,9 @@ MODULE diag_grid_mod ! Parameters CHARACTER(len=128), PARAMETER :: version =& - & '$Id: diag_grid.F90,v 19.0.2.2 2012/05/22 20:18:20 Seth.Underwood Exp $' + & '$Id: diag_grid.F90,v 20.0 2013/12/14 00:18:45 fms Exp $' CHARACTER(len=128), PARAMETER :: tagname =& - & '$Name: siena_201207 $' + & '$Name: tikal $' ! Derived data types ! diff --git a/src/shared/diag_manager/diag_grid.html b/src/shared/diag_manager/diag_grid.html deleted file mode 100644 index c2d7aaf036..0000000000 --- a/src/shared/diag_manager/diag_grid.html +++ /dev/null @@ -1,414 +0,0 @@ - - - -Module diag_grid_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                              -

                                              Module diag_grid_mod

                                              - - -
                                              -Contact:  - Seth Underwood - -
                                              -Reviewers:  -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - -diag_grid_mod is a set of procedures to work with the - model's global grid to allow regional output. -

                                              - - - -
                                              - -diag_grid_mod contains useful utilities for dealing - with, mostly, regional output for grids other than the standard - lat/lon grid. This module contains three public procedures - diag_grid_init, which is shared globably in the - diag_manager_mod, diag_grid_end which will free - up memory used during the register field calls, and - get_local_indexes. The send_global_grid - procedure is called by the model that creates the global grid. - send_global_grid needs to be called before any fields - are registered that will output only regions. get_local_indexes - is to be called by the diag_manager_mod to discover the - global indexes defining a subregion on the tile. - - Change Log - -
                                              - -
                                              September 2009
                                              - -
                                              - -
                                                - -
                                              • Single point region in Cubed Sphere
                                              • - -
                                              • Single tile regions in the cubed sphere
                                              • - -
                                              - -
                                              - -
                                              - -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                                constants_mod
                                              fms_mod
                                              mpp_mod
                                              mpp_domains_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -diag_grid_init:
                                              -
                                              - Send the global grid to the diag_manager_mod for - regional output. -
                                              -
                                              -diag_grid_end:
                                              -
                                              - Unallocate the diag_global_grid variable. -
                                              -
                                              -get_local_indexes:
                                              -
                                              - Find the local start and local end indexes on the local PE - for regional output. -
                                              -
                                              -get_local_indexes2:
                                              -
                                              - Find the indices of the nearest grid point of the a-grid to the - specified (lon,lat) location on the local PE. if desired point not - within domain of local PE, return (0,0) as the indices. -
                                              -
                                              -gCirDistance:
                                              -
                                              - Find the distance, along the geodesic, between two points. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                diag_grid_init

                                                -
                                                SUBROUTINE diag_grid_init (domain, glo_lat, glo_lon, aglo_lat, aglo_lon)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - In order for the diag_manager to do regional output for grids - other than the standard lat/lon grid, the - diag_manager_mod needs to know the the latitude and - longitude values for the entire global grid. This procedure - is the mechanism the models will use to share their grid with - the diagnostic manager. - - This procedure needs to be called after the grid is created, - and before the first call to register the fields. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - -
                                                domain    - The domain to which the grid data corresponds. -
                                                   [INTEGER]
                                                glo_lat    - The latitude information for the grid tile. -
                                                   [REAL, DIMENSION(:,:)]
                                                glo_lon    - The longitude information for the grid tile. -
                                                   [REAL, DIMENSION(:,:)]
                                                aglo_lat    - The latitude information for the a-grid tile. -
                                                   [REAL, DIMENSION(:,:)]
                                                aglo_lon    - The longitude information for the a-grid tile. -
                                                   [REAL, DIMENSION(:,:)]
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              3. - -

                                                diag_grid_end

                                                -
                                                SUBROUTINE diag_grid_end ()
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - The diag_global_grid variable is only needed during - the register field calls, and then only if there are fields - requestion regional output. Once all the register fields - calls are complete (before the first send_data call - this procedure can be called to free up memory. -
                                                -
                                                -
                                                -
                                                -
                                              4. -
                                              5. - -

                                                get_local_indexes

                                                -
                                                SUBROUTINE get_local_indexes (latStart, latEnd, lonStart, lonEnd, istart, iend, jstart, jend)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Given a defined region, find the local indexes on the local - PE surrounding the region. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - -
                                                latStart    - The minimum latitude value defining the region. This value - must be less than latEnd, and be in the range [-90,90] -
                                                   [REAL]
                                                latEnd    - The maximum latitude value defining the region. This value - must be greater than latStart, and be in the range [-90,90] -
                                                   [REAL]
                                                lonStart    - The western most longitude value defining the region. - Possible ranges are either [-180,180] or [0,360]. -
                                                   [REAL]
                                                lonEnd    - The eastern most longitude value defining the region. - Possible ranges are either [-180,180] or [0,360]. -
                                                   [REAL]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - - - - - - - -
                                                istart    - The local start index on the local PE in the 'i' direction. -
                                                   [INTEGER]
                                                iend    - The local end index on the local PE in the 'i' direction. -
                                                   [INTEGER]
                                                jstart    - The local start index on the local PE in the 'j' direction. -
                                                   [INTEGER]
                                                jend    - The local end index on the local PE in the 'j' direction. -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              6. -
                                              7. - -

                                                get_local_indexes2

                                                -
                                                SUBROUTINE get_local_indexes2 (lat, lon, iindex, jindex)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Given a specified location, find the nearest a-grid indices on - the local PE. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                lat    - The requested latitude. This value must be in the range [-90,90] -
                                                   [REAL]
                                                lon    - The requested longitude. - Possible ranges are either [-180,180] or [0,360]. -
                                                   [REAL]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - -
                                                iindex    - The local index on the local PE in the 'i' direction. -
                                                   [INTEGER]
                                                jindex    - The local index on the local PE in the 'j' direction. -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              8. -
                                              9. - -

                                                gCirDistance

                                                -
                                                PURE ELEMENTAL REAL FUNCTION gCirDistance (lat1, lon1, lat2, lon2)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -aCirDistance will find the distance, along the geodesic, between two points defined by the (lat,lon) position of - each point. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - -
                                                lat1   Latitude of the first point
                                                   [REAL]
                                                lon1   Longitude of the first point
                                                   [REAL]
                                                lat2   Latitude of the second point
                                                   [REAL]
                                                lon2   Longitude of the second point
                                                   [REAL]
                                                -
                                                -
                                                -
                                                -
                                              10. -
                                              - - - - - - -
                                              -

                                              FUTURE PLANS

                                              - -
                                              -
                                                -
                                              • - Multi-tile regional output in the cubed sphere. -
                                              • -
                                              • - Single grid in the tri-polar grid. -
                                              • -
                                              • - Multi-tile regional output in the tri-polar grid. -
                                              • -
                                              • - Regional output using array masking. This should allow - regional output to work on any current or future grid. -
                                              • -
                                              -
                                              -
                                              - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/diag_manager/diag_manager.F90 b/src/shared/diag_manager/diag_manager.F90 index 6e9178c1ac..3e8b6128b2 100644 --- a/src/shared/diag_manager/diag_manager.F90 +++ b/src/shared/diag_manager/diag_manager.F90 @@ -176,7 +176,7 @@ MODULE diag_manager_mod USE fms_mod, ONLY: error_mesg, FATAL, WARNING, NOTE, stdout, stdlog, write_version_number,& & file_exist, fms_error_handler, check_nml_error - USE diag_axis_mod, ONLY: diag_axis_init, get_axis_length, max_axes, get_axis_num + USE diag_axis_mod, ONLY: diag_axis_init, get_axis_length, get_axis_num USE diag_util_mod, ONLY: get_subfield_size, log_diag_field_info, update_bounds,& & check_out_of_bounds, check_bounds_are_exact_dynamic, check_bounds_are_exact_static,& & diag_time_inc, find_input_field, init_input_field, init_output_field,& @@ -188,9 +188,9 @@ MODULE diag_manager_mod & base_hour, base_minute, base_second, global_descriptor, coord_type, files, input_fields,& & output_fields, Time_zero, append_pelist_name, mix_snapshot_average_fields,& & first_send_data_call, do_diag_field_log, write_bytes_in_file, debug_diag_manager,& - & diag_log_unit, time_unit_list, pelist_name, module_is_initialized, max_num_axis_sets,& + & diag_log_unit, time_unit_list, pelist_name, max_axes, module_is_initialized, max_num_axis_sets,& & use_cmor, issue_oor_warnings, oor_warnings_fatal, oor_warning, filename_appendix, pack_size,& - & conserve_water + & max_out_per_in_field, conserve_water USE diag_table_mod, ONLY: parse_diag_table USE diag_output_mod, ONLY: get_diag_global_att, set_diag_global_att USE diag_grid_mod, ONLY: diag_grid_init, diag_grid_end @@ -211,9 +211,9 @@ MODULE diag_manager_mod ! version number of this module CHARACTER(len=128), PARAMETER :: version =& - & '$Id: diag_manager.F90,v 19.0.4.8 2012/05/21 14:06:11 Seth.Underwood Exp $' + & '$Id: diag_manager.F90,v 20.0 2013/12/14 00:18:48 fms Exp $' CHARACTER(len=128), PARAMETER :: tagname =& - & '$Name: siena_201207 $' + & '$Name: tikal $' type(time_type) :: Time_end @@ -253,18 +253,19 @@ MODULE diag_manager_mod ! ! "ocean_mod","Vorticity","vorticity_local","file2","all",.false.,"0.5 53.5 -89.5 -28.5 -1 -1",2 ! - ! The format of region is "xbegin xend ybegin yend zbegin zend". - ! If it is a 2D field use (-1 -1) for (zbegin zend) as in the example - ! above. For a 3D field use (-1 -1) for (zbegin zend) when you want to - ! write the entire vertical extent, otherwise specify real coordinates. - ! The units used for region are the actual units used in grid_spec.nc - ! (for example degrees for lat, lon). a FATAL error will occur if the - ! region's boundaries are not found in grid_spec.nc. + ! The format of a region is "xbegin xend ybegin yend zbegin zend". + ! If it is a 2D field use (-1 -1) for (zbegin zend) as in the example above. + ! For a 3D field use (-1 -1) for (zbegin zend) when you want to write the + ! entire vertical extent, otherwise specify real coordinates. The units + ! used for region are the actual units used in grid_spec.nc (for example + ! degrees for lat, lon). NOTE: A FATAL error will occur if + ! the region's boundaries are not found in grid_spec.nc. ! - ! Regional output on the cubed sphere is also supported. To use regional output on the cubed sphere, first the grid - ! information needs to be sent to diag_manager_mod using the - ! diag_grid_init subroutine. NOTE: Regions must be confined to a single tile. Regions spanning - ! tiles will be ignored. A future release will allow multi-tile regions. + ! Regional output on the cubed sphere grid is also supported. To use regional + ! output on the cubed sphere grid, first the grid information needs to be sent to + ! diag_manager_mod using the diag_grid_init + ! subroutine. ! ! NOTE: When using regional output the files containing regional ! outputs should be different from files containing global (default) output. @@ -275,17 +276,15 @@ MODULE diag_manager_mod ! Time averaging is supported in regional output. ! ! Physical fields (written in "physics windows" of atmospheric code) are - ! currently fully supported for regional outputs. + ! fully supported for regional outputs. ! - ! Note of dimension of field in send_data - ! - ! Most fields are defined in data_domain but used in compute domain. In - ! send_data users can pass EITHER field in data domain OR field in - ! compute domain. If data domain is used, users should also pass the starting and - ! ending indices of compute domain (isc, iec ...). If compute domain is used no - ! indices are needed. These indices are for determining halo exclusively. If - ! users want to ouput the field partially they should use regional output as - ! mentioned above. + ! NOTE: Most fields are defined in the data domain but use the + ! compute domain. In send_data the field can be passed in either + ! the data domain or in the compute domain. If the data domain is used, the + ! start and end indicies of the compute domain (isc, iec, . . .) should be + ! passed. If the compute domain is used no indices are needed. The indices + ! are for determining halo exclusively. If users want to output the field + ! partially they should use regional output as mentioned above. ! ! Weight in Time averaging is now supported, each time level may have a ! different weight. The default of weight is 1. @@ -722,7 +721,8 @@ INTEGER FUNCTION register_static_field(module_name, field_name, axes, long_name, IF ( PRESENT(range) ) THEN input_fields(field)%range = range - input_fields(field)%range_present = .TRUE. + ! don't use the range if it is not a valid range + input_fields(field)%range_present = range(2) .gt. range(1) ELSE input_fields(field)%range = (/ 1., 0. /) input_fields(field)%range_present = .FALSE. @@ -1124,7 +1124,7 @@ LOGICAL FUNCTION send_data_3d(diag_field_id, field, time, is_in, js_in, ks_in, & ! oor_mask is only used for checking out of range values. ALLOCATE(oor_mask(SIZE(field,1),SIZE(field,2),SIZE(field,3)), STAT=status) IF ( status .NE. 0 ) THEN - WRITE (err_msg_local, FMT='("Unable to allocate oor_mask(",I5,",",I5,",",I5"). (STAT: ",I5,")")')& + WRITE (err_msg_local, FMT='("Unable to allocate oor_mask(",I5,",",I5,",",I5,"). (STAT: ",I5,")")')& & SIZE(field,1), SIZE(field,2), SIZE(field,3), status IF ( fms_error_handler('diag_manager_mod::send_data_3d', err_msg_local, err_msg) ) RETURN END IF @@ -2613,7 +2613,8 @@ SUBROUTINE diag_send_complete(time_step, err_msg) WRITE (error_string,'(a,"/",a)')& & TRIM(input_fields(in_num)%module_name), & & TRIM(output_fields(out_num)%output_name) - IF ( fms_error_handler('diag_manager_mod::diag_send_complete', 'module/output_field '//TRIM(error_string)//& + IF ( fms_error_handler('diag_send_complete',& + & 'module/output_field '//TRIM(error_string)//& & ' is skipped one time level in output data', err_msg)) RETURN END IF END IF @@ -2699,7 +2700,8 @@ SUBROUTINE closing_file(file, time) IF ( .NOT.input_fields(input_num)%register ) CYCLE freq = files(file)%output_freq IF ( freq /= END_OF_RUN .AND. files(file)%file_unit < 0 & - & .AND. ALL(output_fields(i)%num_elements(:) == 0) .AND. ALL(output_fields(i)%count_0d(:) == 0) ) CYCLE + & .AND. ALL(output_fields(i)%num_elements(:) == 0)& + & .AND. ALL(output_fields(i)%count_0d(:) == 0) ) CYCLE ! Is it time to output for this field; CAREFUL ABOUT >= vs > HERE ! For end should be >= because no more data is coming IF ( time >= output_fields(i)%next_output .OR. freq == END_OF_RUN ) THEN @@ -2713,16 +2715,16 @@ SUBROUTINE closing_file(file, time) IF ( mpp_pe() .EQ. mpp_root_pe() ) & & CALL error_mesg('diag_manager_mod::closing_file', 'module/output_field ' //& & TRIM(message)//', skip one time level, maybe send_data never called', WARNING) + ELSE + status = writing_field(i, .TRUE., message, time) END IF - - status = writing_field(i, .TRUE., message, time) - ELSEIF ( .NOT.output_fields(i)%written_once ) THEN ! ! runlength. ! NetCDF fill_values are written ! - CALL error_mesg('Potential error in diag_manager_end ',TRIM(output_fields(i)%output_name)//' NOT available,'//& + CALL error_mesg('Potential error in diag_manager_end ',& + & TRIM(output_fields(i)%output_name)//' NOT available,'//& & ' check if output interval > runlength. Netcdf fill_values are written', NOTE) output_fields(i)%buffer = FILL_VALUE CALL diag_data_out(file, i, output_fields(i)%buffer, time, .TRUE.) @@ -2734,7 +2736,8 @@ SUBROUTINE closing_file(file, time) ! Write out the number of bytes of data saved to this file IF ( write_bytes_in_file ) THEN CALL mpp_sum (files(file)%bytes_written) - IF ( mpp_pe() == mpp_root_pe() ) WRITE (stdout_unit,'(a,i12,a,a)') 'Diag_Manager: ',files(file)%bytes_written, & + IF ( mpp_pe() == mpp_root_pe() )& + & WRITE (stdout_unit,'(a,i12,a,a)') 'Diag_Manager: ',files(file)%bytes_written, & & ' bytes of data written to file ',TRIM(files(file)%name) END IF END SUBROUTINE closing_file @@ -2764,6 +2767,7 @@ SUBROUTINE diag_manager_init(diag_model_subset, err_msg) INTEGER :: mystat INTEGER, ALLOCATABLE, DIMENSION(:) :: pelist INTEGER :: stdlog_unit, stdout_unit + integer :: j #ifndef INTERNAL_FILE_NML INTEGER :: nml_unit #endif @@ -2772,7 +2776,7 @@ SUBROUTINE diag_manager_init(diag_model_subset, err_msg) NAMELIST /diag_manager_nml/ append_pelist_name, mix_snapshot_average_fields, max_output_fields, & & max_input_fields, max_axes, do_diag_field_log, write_bytes_in_file, debug_diag_manager,& & max_num_axis_sets, max_files, use_cmor, issue_oor_warnings,& - & oor_warnings_fatal, conserve_water + & oor_warnings_fatal, max_out_per_in_field, conserve_water ! If the module was already initialized do nothing IF ( module_is_initialized ) RETURN @@ -2861,6 +2865,9 @@ SUBROUTINE diag_manager_init(diag_model_subset, err_msg) END IF ALLOCATE(output_fields(max_output_fields)) ALLOCATE(input_fields(max_input_fields)) + do j = 1, max_input_fields + allocate(input_fields(j)%output_fields(MAX_OUT_PER_IN_FIELD)) + enddo ALLOCATE(files(max_files)) ALLOCATE(pelist(mpp_npes())) CALL mpp_get_current_pelist(pelist, pelist_name) diff --git a/src/shared/diag_manager/diag_manager.html b/src/shared/diag_manager/diag_manager.html deleted file mode 100644 index 9c937f62c7..0000000000 --- a/src/shared/diag_manager/diag_manager.html +++ /dev/null @@ -1,1393 +0,0 @@ - - - -Module diag_manager_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST - ~ ERROR MESSAGES -
                                              -

                                              Module diag_manager_mod

                                              - - -
                                              -Contact:  - Matt Harrison - ,  - - Giang Nong - ,  - - Seth Underwood - -
                                              -Reviewers:  -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - -diag_manager_mod is a set of simple calls for parallel diagnostics - on distributed systems. It is geared toward the writing of data in netCDF - format. -

                                              - - - -
                                              - -diag_manager_mod provides a convenient set of interfaces for - writing data to disk. It is built upon the parallel I/O interface of FMS - code /shared/mpp/mpp_io.F90. - - A single group of calls to the diag_manager_mod interfaces - provides data to disk at any number of sampling and/or averaging intervals - specified at run-time. Run-time specification of diagnostics are input - through the diagnostics table. - -

                                              Usage

                                              - Use of diag_manager includes the following steps: -
                                                - -
                                              1. Create diag_table as described in the - diag_table.F90 - documentation.
                                              2. - -
                                              3. Call diag_manager_init to initialize - diag_manager_mod.
                                              4. - -
                                              5. Call register_diag_field to register the field to be - output. - NOTE: ALL fields in diag_table should be registered BEFORE - the first send_data call
                                              6. - -
                                              7. Call send_data to send data to output fields
                                              8. - -
                                              9. Call diag_manager_end to exit diag_manager
                                              10. - -
                                              - - -

                                              Features

                                              - Features of diag_manager_mod: -
                                                - -
                                              1. Ability to output from 0D arrays (scalars) to 3D arrays.
                                              2. - -
                                              3. Ability to output time average of fields that have time dependent - mask.
                                              4. - -
                                              5. Give optional warning if register_diag_field fails due to - misspelled module name or field name.
                                              6. - -
                                              7. Check if a field is registered twice.
                                              8. - -
                                              9. Check for duplicate lines in diag_table.
                                              10. - -
                                              11. -diag_table can contain fields - that are NOT written to any files. The file name in diag_table of - these fields is null.
                                              12. - -
                                              13. By default, a field is output in its global grid. The user can now - output a field in a specified region. See - send_data for more details.
                                              14. - -
                                              15. To check if the diag table is set up correctly, user should set - debug_diag_manager=.true. in diag_manager namelist, then - the the content of diag_table is printed in stdout.
                                              16. - -
                                              17. New optional format of file information in diag_table.It is possible to have just - one file name and reuse it many times. A time string will be appended to the base file name each time a new file is - opened. The time string can be any combination from year to second of current model time. - - Here is an example file line:
                                                - -
                                                "file2_yr_dy%1yr%3dy",2,"hours",1,"hours","Time", 10, "days", "1 1 7 0 0 0", 6, "hours"
                                                - -
                                                - - From left to right we have: -
                                                  - -
                                                • file name
                                                • - -
                                                • output frequency
                                                • - -
                                                • output frequency unit
                                                • - -
                                                • Format (should always be 1)
                                                • - -
                                                • time axis unit
                                                • - -
                                                • time axis name
                                                • - -
                                                • frequency for creating new file
                                                • - -
                                                • unit for creating new file
                                                • - -
                                                • start time of the new file
                                                • - -
                                                • file duration
                                                • - -
                                                • file duration unit.
                                                • - -
                                                - The 'file duration', if absent, will be equal to frequency for creating a new file. - - Thus, the above means: create a new file every 10 days, each file will last 6 hours from creation time, no files will - be created before time "1 1 7 0 0 0". - - In this example the string - 10, "days", "1 1 7 0 0 0", 6, "hours" is optional. - - Keywords for the time string suffix is - %xyr,%xmo,%xdy,%xhr,%xmi,%xsc where x is a - mandatory 1 digit number specifying the width of field used in - writing the string
                                              18. - -
                                              19. New time axis for time averaged fields. Users can use a namelist option to handle the time value written - to time axis for time averaged fields. - - If mix_snapshot_average_fields=.true. then a time averaged file will have time values corresponding to - ending time_bound e.g. January monthly average is labeled Feb01. Users can have both snapshot and averaged fields in - one file. - - If mix_snapshot_average_fields=.false. The time value written to time axis for time averaged fields is the - middle on the averaging time. For example, January monthly mean will be written at Jan 16 not Feb 01 as - before. However, to use this new feature users should separate snapshot fields and time averaged fields in - different files or a fatal error will occur. - - The namelist default value is mix_snapshot_average_fields=.false. -
                                              20. - -
                                              21. Time average, Max and Min, and diurnal. In addition to time average users can also get then Max or Min value - during the same interval of time as time average. For this purpose, in the diag table users must replace - .true. or .false. by "max" or "min". Note: Currently, max - and min are not available for regional output. - - A diurnal average can also be requested using diurnal## where ## are the number of diurnal - sections to average.
                                              22. - -
                                              23. -standard_name is added as optional argument in register_diag_field - .
                                              24. - -
                                              25. When namelist variable debug_diag_manager = .true. array - bounds are checked in send_data.
                                              26. - -
                                              27. Coordinate attributes can be written in the output file if the - argument "aux" is given in diag_axis_init. The - corresponding fields (geolat/geolon) should also be written to the - same file.
                                              28. - -
                                              - - -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                              time_manager_mod
                                              mpp_io_mod
                                              mpp_mod
                                              fms_mod
                                              diag_axis_mod
                                              diag_util_mod
                                              diag_data_mod
                                              diag_table_mod
                                              diag_output_mod
                                              diag_grid_mod
                                              constants_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -send_data:
                                              -
                                              - Send data over to output fields. -
                                              -
                                              -register_diag_field:
                                              -
                                              - Register Diagnostic Field. -
                                              -
                                              -send_tile_averaged_data:
                                              -
                                              - Send tile-averaged data over to output fields. -
                                              -
                                              -register_static_field:
                                              -
                                              - Register Static Field. -
                                              -
                                              -average_tiles:
                                              -
                                              - -
                                              -
                                              -diag_manager_end:
                                              -
                                              - Exit Diagnostics Manager. -
                                              -
                                              -closing_file:
                                              -
                                              - Replaces diag_manager_end; close just one file: files(file) -
                                              -
                                              -diag_manager_init:
                                              -
                                              - Initialize Diagnostics Manager. -
                                              -
                                              -get_base_time:
                                              -
                                              - Return base time for diagnostics. -
                                              -
                                              -get_base_date:
                                              -
                                              - Return base date for diagnostics. -
                                              -
                                              -need_data:
                                              -
                                              - Determine whether data is needed for the current model time step. -
                                              -
                                              -set_diag_filename_appendix:
                                              -
                                              - -
                                              -
                                              -init_diurnal_axis:
                                              -
                                              - Finds or initializes a diurnal time axis and returns its' ID. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                send_data

                                                -
                                                 
                                                -send_data (diag_field_id, field, time, is_in, js_in, ks_in, mask, rmask, ie_in, je_in, ke_in, weight)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -send_data is overloaded for fields having zero dimension - (scalars) to 3 dimension. diag_field_id corresponds to the id - returned from a previous call to register_diag_field. The field - array is restricted to the computational range of the array. Optional - argument is_in can be used to update sub-arrays of the entire - field. Additionally, an optional logical or real mask can be used to - apply missing values to the array. - - If a field is declared to be mask_variant in - register_diag_field logical mask should be mandatory. - - For the real mask, the mask is applied if the mask value is less than - 0.5. - - By default, a field will be written out entirely in its global grid. - Users can also specify regions in which the field will be output. The - region is specified in diag-table just before the end of output_field - replacing "none". - - For example, by default: - - "ocean_mod","Vorticity","vorticity","file1","all",.false.,"none",2 - - for regional output: - - "ocean_mod","Vorticity","vorticity_local","file2","all",.false.,"0.5 53.5 -89.5 -28.5 -1 -1",2 - - The format of region is "xbegin xend ybegin yend zbegin zend". - If it is a 2D field use (-1 -1) for (zbegin zend) as in the example - above. For a 3D field use (-1 -1) for (zbegin zend) when you want to - write the entire vertical extent, otherwise specify real coordinates. - The units used for region are the actual units used in grid_spec.nc - (for example degrees for lat, lon). a FATAL error will occur if the - region's boundaries are not found in grid_spec.nc. - - Regional output on the cubed sphere is also supported. To use regional output on the cubed sphere, first the grid - information needs to be sent to diag_manager_mod using the - diag_grid_init subroutine. NOTE: Regions must be confined to a single tile. Regions spanning - tiles will be ignored. A future release will allow multi-tile regions. - - NOTE: When using regional output the files containing regional - outputs should be different from files containing global (default) output. - It is a FATAL error to have one file containing both regional and global - results. For maximum flexibility and independence from PE counts one file - should contain just one region. - - Time averaging is supported in regional output. - - Physical fields (written in "physics windows" of atmospheric code) are - currently fully supported for regional outputs. - - Note of dimension of field in send_data - - Most fields are defined in data_domain but used in compute domain. In - send_data users can pass EITHER field in data domain OR field in - compute domain. If data domain is used, users should also pass the starting and - ending indices of compute domain (isc, iec ...). If compute domain is used no - indices are needed. These indices are for determining halo exclusively. If - users want to ouput the field partially they should use regional output as - mentioned above. - - Weight in Time averaging is now supported, each time level may have a - different weight. The default of weight is 1. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                diag_field_id    -
                                                   [INTEGER] -
                                                   [INTEGER] -
                                                   [INTEGER] -
                                                   [INTEGER]
                                                field    -
                                                   [REAL] -
                                                   [REAL, DIMENSION(:)] -
                                                   [REAL, DIMENSION(:,:)] -
                                                   [REAL, DIMENSION(:,:,:)]
                                                time    -
                                                   [TYPE(time_type), OPTIONAL] -
                                                   [TYPE(time_type)] -
                                                   [TYPE(time_type)] -
                                                   [TYPE(time_type)]
                                                is_in    -
                                                   [Not Applicable] -
                                                   [INTEGER, OPTIONAL] -
                                                   [INTEGER, OPTIONAL] -
                                                   [INTEGER, OPTIONAL]
                                                js_in    -
                                                   [Not Applicable] -
                                                   [Not Applicable] -
                                                   [INTEGER, OPTIONAL] -
                                                   [INTEGER, OPTIONAL]
                                                ks_in    -
                                                   [Not Applicable] -
                                                   [Not Applicable] -
                                                   [Not Applicable] -
                                                   [INTEGER, OPTIONAL]
                                                mask    -
                                                   [Not Applicable] -
                                                   [LOGICAL, DIMENSION(:), OPTIONAL] -
                                                   [LOGICAL, DIMENSION(:,:), OPTIONAL] -
                                                   [LOGICAL, DIMENSION(:,:,:), OPTIONAL]
                                                rmask    -
                                                   [Not Applicable] -
                                                   [REAL, DIMENSION(:), OPTIONAL] -
                                                   [REAL, DIMENSION(:,:), OPTIONAL] -
                                                   [REAL, DIMENSION(:,:,:), OPTIONAL]
                                                ie_in    -
                                                   [Not Applicable] -
                                                   [INTEGER, OPTIONAL] -
                                                   [INTEGER, OPTIONAL] -
                                                   [INTEGER, OPTIONAL]
                                                je_in    -
                                                   [Not Applicable] -
                                                   [Not Applicable] -
                                                   [INTEGER, OPTIONAL] -
                                                   [INTEGER, OPTIONAL]
                                                ke_in    -
                                                   [Not Applicable] -
                                                   [Not Applicable] -
                                                   [Not Applicable] -
                                                   [INTEGER, OPTIONAL]
                                                weight    -
                                                   [Not Applicable] -
                                                   [REAL, OPTIONAL] -
                                                   [REAL, OPTIONAL] -
                                                   [REAL, OPTIONAL]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg    -
                                                   [CHARACTER(len=*), OPTIONAL] -
                                                   [CHARACTER(len=*), OPTIONAL] -
                                                   [CHARACTER(len=*), OPTIONAL] -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              3. - -

                                                register_diag_field

                                                -
                                                INTEGER FUNCTION register_diag_field (module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return field index for subsequent calls to - send_data. - - axes are the axis ID returned from diag_axis_init, - axes are required for fields of 1-3 dimension and NOT required - for scalars. - - For a static scalar (constant) init_time is not needed. - - Optional mask_variant is for fields that have a time-dependent - mask. If mask_variant is true then mask must be - present in argument list of send_data. - - The pair (module_name, fieldname) should be registered - only once or a FATAL error will occur. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                module_name    -
                                                   [CHARACTER(len=*)] -
                                                   [CHARACTER(len=*)]
                                                field_name    -
                                                   [CHARACTER(len=*)] -
                                                   [CHARACTER(len=*)]
                                                axes    -
                                                   [Not Applicable] -
                                                   [INTEGER, DIMENSION(:)]
                                                init_time    -
                                                   [TYPE(time_type), OPTIONAL] -
                                                   [TYPE(time_type)]
                                                long_name    -
                                                   [CHARACTER(len=*), OPTIONAL] -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                units    -
                                                   [CHARACTER(len=*), OPTIONAL] -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                missing_value    -
                                                   [REAL, OPTIONAL] -
                                                   [REAL, OPTIONAL]
                                                range    -
                                                   [REAL, DIMENSION(2), OPTIONAL] -
                                                   [REAL, DIMENSION(2), OPTIONAL]
                                                mask_variant    -
                                                   [Not Applicable] -
                                                   [LOGICAL, OPTIONAL]
                                                standard_name    -
                                                   [CHARACTER(len=*), OPTIONAL] -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              4. -
                                              5. - -

                                                send_tile_averaged_data

                                                -
                                                LOGICAL send_tile_averaged_data (diag_field_id, field, area, time, mask)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -send_tile_averaged_data is overloaded for 3D and 4D arrays. - diag_field_id corresponds to the ID returned by previous call - to register_diag_field. Logical masks can be used to mask out - undefined and/or unused values. Note that the dimension of output field - is smaller by one than the dimension of the data, since averaging over - tiles (3D dimension) is performed. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - -
                                                diag_field_id    -
                                                   [INTEGER] -
                                                   [INTEGER]
                                                field    -
                                                   [REAL, DIMENSION(:,:,:)] -
                                                   [REAL, DIMENSION(:,:,:,:)]
                                                area    -
                                                   [REAL, DIMENSION(:,:,:)] -
                                                   [REAL, DIMENSION(:,:,:)]
                                                time    -
                                                   [TYPE(time_type)] -
                                                   [TYPE(time_type)]
                                                mask    -
                                                   [LOGICAL, DIMENSION(:,:,:), OPTIONAL] -
                                                   [LOGICAL, DIMENSION(:,:,:), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              6. -
                                              7. - -

                                                register_static_field

                                                -
                                                INTEGER FUNCTION register_static_field (module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, dynamic, do_not_log, interp_method, tile_count)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return field index for subsequent call to send_data. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                module_name    -
                                                   [CHARACTER(len=*)]
                                                field_name    -
                                                   [CHARACTER(len=*)]
                                                axes    -
                                                   [INTEGER, DIMENSION(:)]
                                                long_name    -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                units    -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                missing_value    -
                                                   [REAL, OPTIONAL]
                                                range    -
                                                   [REAL, DIMENSION(2), OPTIONAL]
                                                mask_variang    -
                                                   [LOGICAL, OPTIONAL] [Default: .FALSE.]
                                                standard_name    -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                dynamic    -
                                                   [LOGICAL, OPTIONAL] [Default: .FALSE.]
                                                do_not_log    -
                                                   [LOGICAL, OPTIONAL] [Default: .TRUE.]
                                                interp_method    -
                                                   [CHARACTER(len=*), OPTIOANL]
                                                tile_count    -
                                                   [INTEGER, OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              8. -
                                              9. - -

                                                average_tiles

                                                -
                                                SUBROUTINE average_tiles (diag_field_id, x, area, mask, out)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - -
                                                diag_field_id    -
                                                   [INTEGER]
                                                x   (lon, lat, tile) field to average
                                                   [REAL, DIMENSION(:,:,:)]
                                                area   (lon, lat, tile) fractional area
                                                   [REAL, DIMENSION(:,:,:)]
                                                mask   (lon, lat, tile) land mask
                                                   [LOGICAL, DIMENSION(:,:,:)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                out   (lon, lat) result of averaging
                                                   [REAL, DIMENSION(:,:)]
                                                -
                                                -
                                                -
                                                -
                                              10. -
                                              11. - -

                                                diag_manager_end

                                                -
                                                SUBROUTINE diag_manager_end (time)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Flushes diagnostic buffers where necessary. Close diagnostics files. - - A warning will be issued here if a field in diag_table is not registered -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                TIME    -
                                                   [time_type]
                                                -
                                                -
                                                -
                                                -
                                              12. -
                                              13. - -

                                                closing_file

                                                -
                                                SUBROUTINE closing_file (file, time)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                file    -
                                                   [INTEGER]
                                                tile    -
                                                   [TYPE(time_type)]
                                                -
                                                -
                                                -
                                                -
                                              14. -
                                              15. - -

                                                diag_manager_init

                                                -
                                                SUBROUTINE diag_manager_init (diag_model_subset, err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Open and read diag_table. Select fields and files for diagnostic output. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                diag_model_subset    -
                                                   [INTEGER, OPTIONAL]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg    -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              16. -
                                              17. - -

                                                get_base_time

                                                -
                                                TYPE(time_type) FUNCTION get_base_time ()
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return base time for diagnostics (note: base time must be >= model time). -
                                                -
                                                -
                                                -
                                                -
                                              18. -
                                              19. - -

                                                get_base_date

                                                -
                                                SUBROUTINE get_base_date (year, month, day, hour, minute, second)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return date information for diagnostic reference time. -
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - -
                                                year    -
                                                   [INTEGER]
                                                month    -
                                                   [INTEGER]
                                                day    -
                                                   [INTEGER]
                                                hour    -
                                                   [INTEGER]
                                                minute    -
                                                   [INTEGER]
                                                second    -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              20. -
                                              21. - -

                                                need_data

                                                -
                                                LOGICAL need_data (diag_field_id, next_model_time)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Determine whether data is needed for the current model time step. - Since diagnostic data are buffered, the "next" model time is passed - instead of the current model time. This call can be used to minimize - overhead for complicated diagnostics. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                next_model_time    - next_model_time = current model time + model time_step -
                                                   [TYPE(time_type)]
                                                diag_field_id    -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              22. -
                                              23. - -

                                                set_diag_filename_appendix

                                                -
                                                SUBROUTINE set_diag_filename_appendix (string_in)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                string_in    -
                                                   [CHARACTER(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              24. -
                                              25. - -

                                                init_diurnal_axis

                                                -
                                                INTEGER FUNCTION init_diurnal_axis (n_samples)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Given number of time intervals in the day, finds or initializes a diurnal time axis - and returns its ID. It uses get_base_date, so should be in the file where it's accessible. - The units are 'days since BASE_DATE', all diurnal axes belong to the set 'diurnal' -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                n_samples   Number of intervals during the day
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              26. -
                                              - - - - -
                                              -

                                              NAMELIST

                                              - -
                                              -&diag_manager_nml -
                                              -
                                              -
                                              -
                                              -
                                              -append_pelist_name -
                                              -
                                              - -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -mix_snapshot_average_fields -
                                              -
                                              - Set to .TRUE. to allow both time average and instantaneous fields in the same output file. -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -max_files -
                                              -
                                              - -
                                              -[INTEGER] -
                                              -
                                              -max_output_fields -
                                              -
                                              - -
                                              -[INTEGER, default: 300] -
                                              -
                                              -max_input_fields -
                                              -
                                              - -
                                              -[INTEGER, default: 300] -
                                              -
                                              -max_axes -
                                              -
                                              - -
                                              -[INTEGER, default: 60] -
                                              -
                                              -do_diag_field_log -
                                              -
                                              - -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -write_bytes_in_files -
                                              -
                                              - -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -debug_diag_manager -
                                              -
                                              - -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -max_num_axis_sets -
                                              -
                                              - -
                                              -[INTEGER, default: 25] -
                                              -
                                              -use_cmor -
                                              -
                                              - Let the diag_manager know if the missing value (if supplied) should be overridden to be the - CMOR standard value of -1.0e20. -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -issue_oor_warnings -
                                              -
                                              - If .TRUE., then the diag_manager will check for values outside the valid range. This range is defined in - the model, and passed to the diag_manager_mod via the OPTIONAL variable range in the register_diag_field - function. -
                                              -[LOGICAL, default: .TRUE.] -
                                              -
                                              -oor_warnings_fatal -
                                              -
                                              - If .TRUE. then diag_manager_mod will issue a FATAL error if any values for the output field are - outside the given range. -
                                              -[LOGICAL, default: .FALSE.] -
                                              -
                                              -
                                              -
                                              -
                                              - - - - -
                                              -

                                              ERROR MESSAGES

                                              - -
                                              -
                                              -
                                              -WARNING in register_diag_field -
                                              -
                                              - -
                                              -
                                              - module/output_field <module_name>/<field_name> registered AFTER first - send_data call, TOO LATE -
                                              -
                                              -WARNING in register_diag_field -
                                              -
                                              - -
                                              -
                                              - module/output_field <modul_name>/<field_name> NOT found in diag_table -
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              diag_manager has NOT been initialized
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              - module/output_field <module_name>/<field_name> is not registered for tile_count = 1, - should not register for tile_count > 1 -
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              - module/output_field <module_name>/<field_name> ALREADY Registered, should - not register twice -
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              - when registering module/output_field <module_name>/<field_name> then optional - argument interp_method = <interp_method>, but it should be "conserve_order1" -
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              - module/output_field <module_name>/<field_name> has non-positive axis_id -
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              - output_field <field_name> has pack >= 4, range is REQUIRED in register_diag_field -
                                              -
                                              -FATAL in register_static_field -
                                              -
                                              - -
                                              -
                                              axes of <field_name> must >= 2 for local output
                                              -
                                              -WARNING in register_static_field -
                                              -
                                              - -
                                              -
                                              - module/field <module_name>/<field_name> is STATIC. - Cannot perform time operations average, maximum or - minimum on static fields. Setting the time operation to 'NONE' - for this field. -
                                              -
                                              -WARNING/FATAL in send_data -
                                              -
                                              - -
                                              -
                                              - A value for <module_name> in field <field_name> (Min: <min_val>, Max: <max_val>) - is outside the range [<lower_val>,<upper_val>] and not equal to the missing - value. -
                                              -
                                              -WARNING/FATAL in send_data -
                                              -
                                              - -
                                              -
                                              - A value for <module_name> in field <field_name> (Min: <min_val>, Max: <max_val>) - is outside the range [<lower_val>,<upper_val>]. -
                                              -
                                              -WARNING in send_data -
                                              -
                                              - -
                                              -
                                              - Mask will be ignored since missing values were not specified for field <field_name> - in module <module_name> -
                                              -
                                              -WARNING in closing_file -
                                              -
                                              - -
                                              -
                                              - <input_fields(input_num)%module_name>/<output_fields(i)%output_name> skip one time - level, maybe send_data never called -
                                              -
                                              -NOTE in closing_file -
                                              -
                                              - -
                                              -
                                              - <output_fields(i)%output_name) NOT available, check if output interval > runlength. - NetCDF fill_values are written -
                                              -
                                              -FATAL in get_base_time -
                                              -
                                              - -
                                              -
                                              - MODULE has not been initialized -
                                              -
                                              -FATAL in get_base_date -
                                              -
                                              - -
                                              -
                                              module has not been initialized
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              COMPILER SPECIFICS

                                              - -
                                              -
                                              -
                                              PORTABILITY
                                              -
                                              - -diag_manager_mod uses standard Fortran 90. -
                                              -
                                              ACQUIRING SOURCE
                                              -
                                              - Use the following commands to check out the source at GFDL. -
                                                     setenv CVSROOT '/home/fms/cvs'
                                              -       cvs co diag_manager
                                              - -
                                              -
                                              COMPILING AND LINKING SOURCE
                                              -
                                              - Any module or program unit using diag_manager_mod must contain the line -
                                                   use diag_manager_mod
                                              - If netCDF output is desired, the cpp flag -Duse_netCDF - must be turned on. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PRECOMPILER OPTIONS

                                              - -
                                              -
                                              -
                                              -Duse_netCDF -
                                              -
                                              - Used to write out NetCDF files. -
                                              -
                                              -Dtest_diag_manager -
                                              -
                                              - Used to build the unit test suite for the diag_manager_mod. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              LOADER OPTIONS

                                              - -
                                              -

                                              - Link in the NetCDF libraries. -

                                              -
                                                      -lnetcdf
                                              -
                                              -
                                              - - -
                                              -

                                              TEST PROGRAM

                                              - -
                                              -
                                              -
                                              test
                                              -
                                              - Unit test for the diag_manager_mod. Each test must be run separately, and ends with an intentional fatal error. - Each test has its own diag_table, see the source of diag_manager.F90 for the list of diag_tables - for the unit tests. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              FUTURE PLANS

                                              - -
                                              -
                                                -
                                              • - Regional output for the cubed-sphere grid. -
                                              • -
                                              -
                                              -
                                              - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/diag_manager/diag_output.F90 b/src/shared/diag_manager/diag_output.F90 index e950141b19..83ffb8d1e2 100644 --- a/src/shared/diag_manager/diag_output.F90 +++ b/src/shared/diag_manager/diag_output.F90 @@ -46,9 +46,9 @@ MODULE diag_output_mod LOGICAL :: module_is_initialized = .FALSE. CHARACTER(len=128), PRIVATE :: version= & - '$Id: diag_output.F90,v 19.0 2012/01/06 21:55:50 fms Exp $' + '$Id: diag_output.F90,v 20.0 2013/12/14 00:18:52 fms Exp $' CHARACTER(len=128), PRIVATE :: tagname= & - '$Name: siena_201207 $' + '$Name: tikal $' CONTAINS @@ -145,7 +145,6 @@ SUBROUTINE write_axis_meta_data(file_unit, axes, time_ops) LOGICAL, INTENT(in), OPTIONAL :: time_ops TYPE(domain1d) :: Domain - TYPE(domain1d) :: Edge_Domain CHARACTER(len=mxch) :: axis_name, axis_units CHARACTER(len=mxchl) :: axis_long_name @@ -279,11 +278,9 @@ SUBROUTINE write_axis_meta_data(file_unit, axes, time_ops) IF ( ALLOCATED(pelist) ) DEALLOCATE(pelist) ALLOCATE(pelist(0:ndivs-1)) CALL mpp_get_pelist(Domain,pelist) - CALL mpp_define_domains((/gbegin,gend/),ndivs,Edge_Domain,& - & pelist=pelist(0:ndivs-1), extent=axis_extent(0:ndivs-1)) CALL mpp_write_meta(file_unit, Axis_types(num_axis_in_file),& & axis_name, axis_units, axis_long_name, axis_cart_name,& - & axis_direction, Edge_Domain, DATA=axis_data) + & axis_direction, Domain, DATA=axis_data) END IF ELSE CALL mpp_write_meta(file_unit, Axis_types(num_axis_in_file), axis_name, axis_units,& @@ -565,7 +562,13 @@ SUBROUTINE diag_field_out(file_unit, Field, DATA, time) !---- output data ---- IF ( Field%Domain .NE. null_domain2d ) THEN - CALL mpp_write(file_unit, Field%Field, Field%Domain, DATA, time, tile_count=Field%tile_count) + IF( Field%miss_present ) THEN + CALL mpp_write(file_unit, Field%Field, Field%Domain, DATA, time, & + tile_count=Field%tile_count, default_data=Field%miss_pack) + ELSE + CALL mpp_write(file_unit, Field%Field, Field%Domain, DATA, time, & + tile_count=Field%tile_count, default_data=CMOR_MISSING_VALUE) + END IF ELSE CALL mpp_write(file_unit, Field%Field, DATA, time) END IF diff --git a/src/shared/diag_manager/diag_output.html b/src/shared/diag_manager/diag_output.html deleted file mode 100644 index 4e5f54428c..0000000000 --- a/src/shared/diag_manager/diag_output.html +++ /dev/null @@ -1,544 +0,0 @@ - - - -Module diag_output_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ ERROR MESSAGES -
                                              -

                                              Module diag_output_mod

                                              - - -
                                              -Contact:  - Seth Underwood - -
                                              -Reviewers:  -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              -diag_output_mod is an integral part of - diag_manager_mod. Its function is to write axis-meta-data, - field-meta-data and field data -

                                              - - - -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                                    mpp_io_mod
                                              mpp_domains_mod
                                              mpp_mod
                                              diag_axis_mod
                                              diag_data_mod
                                              time_manager_mod
                                              fms_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -diag_output_init:
                                              -
                                              - Registers the time axis and opens the output file. -
                                              -
                                              -write_axis_meta_data:
                                              -
                                              - Write the axes meta data to file. -
                                              -
                                              -write_field_meta_data:
                                              -
                                              - Write the field meta data to file. -
                                              -
                                              -done_meta_data:
                                              -
                                              - Writes axis data to file. -
                                              -
                                              -diag_field_out:
                                              -
                                              - Writes field data to an output file. -
                                              -
                                              -diag_flush:
                                              -
                                              - Flush buffer and insure data is not lost. -
                                              -
                                              -get_axis_index:
                                              -
                                              - Return the axis index number. -
                                              -
                                              -get_diag_global_att:
                                              -
                                              - Return the global attribute type. -
                                              -
                                              -set_diag_global_att:
                                              -
                                              - Set the global attribute type. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                diag_output_init

                                                -
                                                SUBROUTINE diag_output_init (file_name, format, file_title, file_unit, all_scalar_or_1d, domain)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Registers the time axis, and opens the file for output. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - -
                                                file_name   Output file name
                                                   [CHARACTER(len=*)]
                                                format   File format (Currently only 'NETCDF' is valid)
                                                   [INTEGER]
                                                file_title   Descriptive title for the file
                                                   [CHARACTER(len=*)]
                                                all_scalar_or_1d    -
                                                   [LOGICAL]
                                                domain    -
                                                   [TYPE(domain2d)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                file_unit    - File unit number assigned to the output file. Needed for subsuquent calls to - diag_output_mod - -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              3. - -

                                                write_axis_meta_data

                                                -
                                                SUBROUTINE write_axis_meta_data (file_unit, axes, time_ops)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                file_unit   File unit number
                                                   [INTEGER]
                                                axes   Array of axis ID's, including the time axis
                                                   [INTEGER, DIMENSION(:)]
                                                time_ops    - .TRUE. if this file contains any min, max, or time_average -
                                                   [LOGICAL, OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              4. -
                                              5. - -

                                                write_field_meta_data

                                                -
                                                TYPE(diag_fieldtype) FUNCTION write_field_meta_data (file_unit, name, axes, units, long_name, rnage, pack, mval, avg_name, time_method, standard_name, interp_method)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - The meta data for the field is written to the file indicated by file_unit -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                file_unit   Output file unit number
                                                   [INTEGER]
                                                name   Field name
                                                   [CHARACTER(len=*)]
                                                axes   Array of axis IDs
                                                   [INTEGER, DIMENSION(:)]
                                                units   Field units
                                                   [CHARACTER(len=*)]
                                                long_name   Field's long name
                                                   [CHARACTER(len=*)]
                                                range    - Valid range (min, max). If min > max, the range will be ignored -
                                                   [REAL, DIMENSION(2), OPTIONAL]
                                                pack    - Packing flag. Only valid when range specified. Valid values: -
                                                  - -
                                                • 1 = 64bit
                                                • - -
                                                • 2 = 32bit
                                                • - -
                                                • 4 = 16bit
                                                • - -
                                                • 8 = 8bit
                                                • - -
                                                - -
                                                   [INTEGER, OPTIONAL] [Default: 2]
                                                mval   Missing value, must be within valid range
                                                   [REAL, OPTIONAL]
                                                avg_name    - Name of variable containing time averaging info -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                time_method    - Name of transformation applied to the time-varying data, i.e. "avg", "min", "max" -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                standard_name   Standard name of field
                                                   [CHARACTER(len=*), OPTIONAL]
                                                interp_method    -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              6. -
                                              7. - -

                                                done_meta_data

                                                -
                                                SUBROUTINE done_meta_data (file_unit)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Writes axis data to file. This subroutine is to be called once per file - after all write_meta_data calls, and before the first - diag_field_out call. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                file_unit   Output file unit number
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              8. -
                                              9. - -

                                                diag_field_out

                                                -
                                                SUBROUTINE diag_field_out (file_unit, field, data, time)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Writes field data to an output file. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                file_unit   Output file unit number
                                                   [INTEGER]
                                                time    -
                                                   [REAL, OPTIONAL]
                                                -
                                                -
                                                -
                                                -INPUT/OUTPUT -
                                                -
                                                - - - - - - - -
                                                field    -
                                                   [TYPE(diag_fieldtype)]
                                                data    -
                                                   [REAL, DIMENSIONS(:,:,:,:)]
                                                -
                                                -
                                                -
                                                -
                                              10. -
                                              11. - -

                                                diag_flush

                                                -
                                                -call diag_flush (file_unit)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This subroutine can be called periodically to flush the buffer, and - insure that data is not lost if the execution fails. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                file_unit   Output file unit number to flush
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              12. -
                                              13. - -

                                                get_axis_index

                                                -
                                                INTEGER FUNCTION get_axis_index (num)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return the axis index number. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                num    -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              14. -
                                              15. - -

                                                get_diag_global_att

                                                -
                                                -call get_diag_global_att (gAtt)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return the global attribute type. -
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                gAtt    -
                                                   [TYPE(diag_global_att_type]
                                                -
                                                -
                                                -
                                                -
                                              16. -
                                              17. - -

                                                set_diag_global_att

                                                -
                                                -call set_diag_global_att (component, gridType, timeName)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set the global attribute type. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                component    -
                                                   [CHARACTER(len=*)]
                                                gridType    -
                                                   [CHARACTER(len=*)]
                                                tileName    -
                                                   [CHARACTER(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              18. -
                                              - - - - - - -
                                              -

                                              ERROR MESSAGES

                                              - -
                                              -
                                              -
                                              -FATAL in diag_output_init -
                                              -
                                              - -
                                              -
                                              invalid format
                                              -
                                              -FATAL in write_axis_meta_data -
                                              -
                                              - -
                                              -
                                              number of axes < 1
                                              -
                                              -FATAL in write_axis_meta_data -
                                              -
                                              - -
                                              -
                                              writing meta data out-of-order to different files.
                                              -
                                              -FATAL in write_field_meta_data -
                                              -
                                              - -
                                              -
                                              number of axes < 1
                                              -
                                              -FATAL in write_field_meta_data -
                                              -
                                              - -
                                              -
                                              writing meta data out-of-order to different files
                                              -
                                              -FATAL in write_field_meta_data -
                                              -
                                              - -
                                              -
                                              axis data not written for field
                                              -
                                              -
                                              -
                                              - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/diag_manager/diag_table.F90 b/src/shared/diag_manager/diag_table.F90 index c6a37c89cd..7e8c0414a5 100644 --- a/src/shared/diag_manager/diag_table.F90 +++ b/src/shared/diag_manager/diag_table.F90 @@ -210,7 +210,7 @@ MODULE diag_table_mod ! A simple utility has been created to help discover ! USE mpp_io_mod, ONLY: mpp_open, MPP_RDONLY - USE mpp_mod, ONLY: read_ascii_file + USE mpp_mod, ONLY: read_ascii_file, get_ascii_file_num_lines USE fms_mod, ONLY: fms_error_handler, error_mesg, file_exist, stdlog, mpp_pe, mpp_root_pe, FATAL, WARNING, lowercase, close_file USE time_manager_mod, ONLY: get_calendar_type, NO_CALENDAR, set_date, set_time, month_name, time_type USE constants_mod, ONLY: SECONDS_PER_HOUR, SECONDS_PER_MINUTE @@ -373,8 +373,10 @@ SUBROUTINE parse_diag_table(diag_subset, istat, err_msg) ! get the stdlog unit number stdlog_unit = stdlog() + num_lines = get_ascii_file_num_lines('diag_table', DT_LINE_LENGTH) + allocate(diag_table(num_lines)) - call read_ascii_file('diag_table', DT_LINE_LENGTH, diag_table, num_lines) + call read_ascii_file('diag_table', DT_LINE_LENGTH, diag_table) ! Read in the global file labeling string READ (UNIT=diag_table(1), FMT=*, IOSTAT=mystat) global_descriptor @@ -665,6 +667,7 @@ TYPE(file_description_type) FUNCTION parse_file_line(line, istat, err_msg) & 'Unallowed character in file_duration_units in the diag_table.', err_msg) ) RETURN END IF + ! Fix the file name parse_file_line%file_name = fix_file_name(TRIM(parse_file_line%file_name)) diff --git a/src/shared/diag_manager/diag_table.html b/src/shared/diag_manager/diag_table.html deleted file mode 100644 index dd20e996af..0000000000 --- a/src/shared/diag_manager/diag_table.html +++ /dev/null @@ -1,679 +0,0 @@ - - - -Module diag_table_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ ERROR MESSAGES -
                                              -

                                              Module diag_table_mod

                                              - - -
                                              -Contact:  - Seth Underwood - -
                                              -Reviewers:  -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - -diag_table_mod is a set of subroutines use to parse out the data from a diag_table. This module - will also setup the arrays required to store the information by counting the number of input fields, output files, and - files. -

                                              - - - -
                                              - -diag_table_mod parses the diag_table file, and sets up the required arrays to hold the information - needed for the diag_manager_mod to correctly write out the model history files. - - The diagnostics table allows users to specify sampling rates and the choice of fields at run time. The - diag_table file consists of comma-separated ASCII values. The diag_table essentially has three sections: - Global, File, and Field sections. The Global section must be the first two lines of the file, - whereas the File and Field sections can be inter mixed to allow the file to be organized as desired. - Comments can be added to the diag_table file by using the hash symbol (#) as the first character in the line. - - All errors in the diag_table will throw a FATAL error. A simple utility diag_table_chkhas been - added to the FRE tools suite to check a diag_table for errors. A brief usage statement can be obtained by running - diag_table_chk --help, and a man page like description can views by running perldoc diag_table_chk. - - Below is a description of the three sections. -
                                                - -
                                              1. - -Global Section: The first two lines of the diag_table must contain the title and the base - date of the experiment respectively. The title must be a Fortran CHARACTER string. The base date - is the reference time used for the time units, and must be greater than or equal to the model start time. - The base date consists of six space-separated integer in the following format.
                                                - -year month day hour minute second -
                                                - -
                                              2. - -
                                              3. - -File Section: File lines contain 6 required and 5 optional fields (optional fields are surrounded with - square brackets ([]). File lines can be intermixed with the field lines, but the file must be defined before any - fields that are to be written to the file. File lines have the following format:
                                                - - - "file_name", output_freq, "output_freq_units", file_format, "time_axis_units", "time_axis_name" - [, new_file_freq, "new_file_freq_units"[, "start_time"[, file_duration, "file_duration_units"]]] - - -
                                                - with the following descriptions. -
                                                - -
                                                -CHARACTER(len=128) :: file_name -
                                                - -
                                                - Output file name without the trailing ".nc". - - A single file description can produce multiple files using special time string suffix keywords. This time string - will append the time strings to the base file name each time a new file is opened. They syntax for the time string - suffix keywords are %#tt Where # is a mandatory single digit number specifying the width of the - field, and tt can be as follows: -
                                                  - -
                                                1. -yr - – - Years
                                                2. - -
                                                3. -mo - – - Months
                                                4. - -
                                                5. -dy - – - Days
                                                6. - -
                                                7. -hr - – - Hours
                                                8. - -
                                                9. -mi - – - Minutes
                                                10. - -
                                                11. -sc - – - Seconds
                                                12. - -
                                                - Thus, a file name of file2_yr_dy%1yr%3dy will have a base file name of file2_yr_dy_1_001 if the - file is created on year 1 day 1 of the model run. NOTE: The time suffix keywords must be used if the - optional fields new_file_freq and new_file_freq_units are used, otherwise a FATAL error - will occur. -
                                                - - -
                                                -INTEGER :: output_freq -
                                                - -
                                                How often to write fields to file. -
                                                  - -
                                                1. -> 0 - – - Output frequency in output_freq_units.
                                                2. - -
                                                3. -= 0 - – - Output frequency every time set. (output_freq_units is ignored.)
                                                4. - -
                                                5. -=-1 - – - Output at end of run only. (output_freq_units is ignored.)
                                                6. - -
                                                - -
                                                - -
                                                -CHARACTER(len=10) :: output_freq_units -
                                                - -
                                                - Time units for output. Can be either years, months, days, minutes, - hours, or seconds. -
                                                - -
                                                -INTEGER :: file_format -
                                                - -
                                                - Output file format. Currently only the netCDF file format is supported. -
                                                  - -
                                                1. -= 1 - – - netCDF
                                                2. - -
                                                - -
                                                - -
                                                -CHARACTER(len=10) :: time_axis_units -
                                                - -
                                                - Time units for the output file time axis. Can be either years, months, days, - minutes, hours, or seconds. -
                                                - -
                                                -CHARACTER(len=128) :: time_axis_name -
                                                - -
                                                - Axis name for the output file time axis. The character sting must contain the string 'time'. (mixed upper and - lowercase allowed.) -
                                                - -
                                                -INTEGER, OPTIONAL :: new_file_freq -
                                                - -
                                                - Frequency for closing the existing file, and creating a new file in new_file_freq_units. -
                                                - -
                                                -CHARACTER(len=10), OPTIONAL :: new_file_freq_units -
                                                - -
                                                - Time units for creating a new file. Can be either years, months, days, - minutes, hours, or seconds. NOTE: If the new_file_freq field is - present, then this field must also be present. -
                                                - -
                                                -CHARACTER(len=25), OPTIONAL :: start_time -
                                                - -
                                                - Time to start the file for the first time. The format of this string is the same as the global date. - NOTE: The new_file_freq and the new_file_freq_units fields must be present to use this field. -
                                                - -
                                                -INTEGER, OPTIONAL :: file_duration -
                                                - -
                                                - How long file should receive data after start time in file_duration_units. This optional field can only - be used if the start_time field is present. If this field is absent, then the file duration will be equal - to the frequency for creating new files. NOTE: The file_duration_units field must also be - present if this field is present. -
                                                - -
                                                -CHARACTER(len=10), OPTIONAL :: file_duration_units -
                                                - -
                                                - File duration units. Can be either years, months, days, - minutes, hours, or seconds. NOTE: If the file_duration field is - present, then this field must also be present. -
                                                - -
                                                - -
                                              4. - -
                                              5. - -Field Section: Field lines contain 8 fields. Field lines can be intermixed with file lines, but the file must - be defined before any fields that are to be written to the file. Fields line can contain fields that are not written - to any files. The file name for these fields is null. - - Field lines have the following format:
                                                - -
                                                 "module_name", "field_name", "output_name", "file_name", "time_sampling", "reduction_method", "regional_section", packing
                                                - with the following descriptions. -
                                                - -
                                                -CHARACTER(len=128) :: module_name -
                                                - -
                                                Module that contains the field_name variable. (e.g. atmos_mod, land_mod)
                                                - -
                                                -CHARACTER(len=128) :: field_name -
                                                - -
                                                Module variable name that has data to be written to file.
                                                - -
                                                -CHARACTER(len=128) :: output_name -
                                                - -
                                                Name of the field as written in file_name.
                                                - -
                                                -CHARACTER(len=128) :: file_name -
                                                - -
                                                - Name of the file where the field is to be written. NOTE: The file file_name must be - defined first. -
                                                - -
                                                -CHARACTER(len=50) :: time_sampling -
                                                - -
                                                Currently not used. Please use the string "all".
                                                - -
                                                -CHARACTER(len=50) :: reduction_method -
                                                - -
                                                - The data reduction method to perform prior to writing data to disk. Valid options are (redundant names are - separated with commas): -
                                                - -
                                                -.TRUE., average
                                                - -
                                                Average from the last time written to the current time.
                                                - -
                                                -.FALSE., none
                                                - -
                                                No reduction performed. Write current time step value only.
                                                - -
                                                min
                                                -
                                                Minimum value from last write to current time.
                                                - -
                                                max
                                                -
                                                Maximum value from last write to current time.
                                                - -
                                                diurnal##
                                                -
                                                ## diurnal averages
                                                - -
                                                - -
                                                - -
                                                -CHARACTER(len=50) :: regional_section -
                                                - -
                                                - Bounds of the regional section to capture. A value of none indicates a global region. The regional - section has the following format:
                                                - -lat_min, lat_max, lon_min, lon_max, vert_min, vert_max -
                                                - Use vert_min = -1 and vert_max = -1 to get the entire vertical axis. NOTE: - Currently, the defined region MUST be confined to a single tile. -
                                                - -
                                                -INTEGER :: packing -
                                                - -
                                                - Fortran number KIND of the data written. Valid values: -
                                                  - -
                                                1. -= 1 - – - double precision
                                                2. - -
                                                3. -= 2 - – - float
                                                4. - -
                                                5. -= 4 - – - packed 16-bit integers
                                                6. - -
                                                7. -= 8 - – - packed 1-byte (not tested).
                                                8. - -
                                                - -
                                                - -
                                                - -
                                              6. - -
                                              - - -

                                              -Sample diag_table -

                                              - -
                                                - -
                                              1. - -
                                                 "diag manager test"
                                                - 1999 1 1 0 0 0
                                                -
                                                - #output files
                                                - 10_days,               10, "days", 1, "hours", "Time"
                                                - "file1_hr%hr3",         5, "days", 1, "hours", "Time", 15, "days"
                                                - "file2_yr_dy%yr1%dy3",  5, "days", 1, "hours", "Time", 10, "days", "1 1 7 0 0 0"
                                                - "file3_yr_dy%yr1%dy3",  5, "days", 1, "hours", "Time", 20, "days", "1 1 7 0 0 0", 5, "years"
                                                -
                                                - #output variables
                                                - "ice_mod", "ice", "ice", "10_days", "all", .false., "none", 2
                                                -
                                                - # temp_local file and fields.
                                                - temp_local, 1, "days", 1, "hours", "Time"
                                                - "ocean_mod", "temp", "temp", "temp_local", "all", .FALSE., "5 259.5 -59.5 59.5 1 1", 2
                                                - -
                                              2. - -
                                              - - -

                                              Useful Additional Utility

                                              - A simple utility has been created to help discover -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                                    mpp_io_mod
                                              mpp_mod
                                              fms_mod
                                              time_manager_mod
                                              constants_mod
                                              diag_data_mod
                                              diag_util_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -parse_diag_table:
                                              -
                                              - Parse the diag_table in preparation for diagnostic output. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                parse_diag_table

                                                -
                                                SUBROUTINE parse_diag_table (diag_subset, istat, err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -parse_diag_table is the public interface to parse the diag_table, and setup the arrays needed to store the - requested diagnostics from the diag_table. parse_diag_table will return a non-zero istat if - a problem parsing the diag_table. - - NOT YET IMPLEMENTED: parse_diag_table will parse through the diag_table twice. The first pass, will be - to get a good "guess" of array sizes. These arrays, that will hold the requested diagnostic fields and files, will then be - allocated to the size of the "guess" plus a slight increase. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                diag_subset    - Diagnostic sampling subset. -
                                                   [INTEGER, OPTIONAL]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - -
                                                iunit    - Status of parsing the diag_table. A non-zero status indicates a problem parsing the table. -
                                                   [INTEGER, OPTIONAL]
                                                err_msg    - Error message corresponding to the istat return value. -
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              - - - - - - -
                                              -

                                              ERROR MESSAGES

                                              - -
                                              -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - diag_table file does not exist. -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Error reading the global descriptor from the diagnostic table. -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Error reading the base date from the diagnostic table. -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - The base_year/month/day can not equal zero -
                                              -
                                              -WARNING in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Problem reading diag_table, line numbers in errors may be incorrect. -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Problem reading the diag_table (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Incorrect file description FORMAT in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Invalid file FORMAT for file description in the diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Invalid time axis units in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Invalid output frequency units in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Invalid NEW file frequency units in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Invalid file duration units in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Invalid start time in the file description in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Field description FORMAT is incorrect in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Packing is out of range for the field description in diag_table. (line: <line_number>) -
                                              -
                                              -FATAL in parse_diag_table -
                                              -
                                              - -
                                              -
                                              - Error in regional output description for field description in diag_table. (line: <line_number>) -
                                              -
                                              -
                                              -
                                              - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/diag_manager/diag_util.F90 b/src/shared/diag_manager/diag_util.F90 index 32865a30d3..a471d618bf 100644 --- a/src/shared/diag_manager/diag_util.F90 +++ b/src/shared/diag_manager/diag_util.F90 @@ -58,9 +58,9 @@ MODULE diag_util_mod & check_duplicate_output_fields, get_date_dif, get_subfield_vert_size, sync_file_times CHARACTER(len=128),PRIVATE :: version =& - & '$Id: diag_util.F90,v 19.0.2.2 2012/04/03 18:41:44 sdu Exp $' + & '$Id: diag_util.F90,v 20.0 2013/12/14 00:18:58 fms Exp $' CHARACTER(len=128),PRIVATE :: tagname =& - & '$Name: siena_201207 $' + & '$Name: tikal $' CONTAINS @@ -1310,12 +1310,12 @@ SUBROUTINE init_output_field(module_name, field_name, output_name, output_file,& IF ( input_fields(in_num)%num_output_fields > max_out_per_in_field ) THEN ! ! MAX_OUT_PER_IN_FIELD = exceeded for /, increase MAX_OUT_PER_IN_FIELD - ! in diag_data.F90. + ! in the diag_manager_nml namelist. ! WRITE (UNIT=error_msg,FMT=*) MAX_OUT_PER_IN_FIELD CALL error_mesg('diag_util_mod::init_output_field',& & 'MAX_OUT_PER_IN_FIELD exceeded for '//TRIM(module_name)//"/"//TRIM(field_name)//& - &', increase MAX_OUT_PER_IN_FIELD in diag_data.F90', FATAL) + &', increase MAX_OUT_PER_IN_FIELD in the diag_manager_nml namelist', FATAL) END IF input_fields(in_num)%output_fields(input_fields(in_num)%num_output_fields) = out_num @@ -2058,7 +2058,7 @@ SUBROUTINE diag_data_out(file, field, dat, time, final_call_in, static_write_in) ! get file_unit, open new file and close curent file if necessary IF ( .NOT.static_write .OR. files(file)%file_unit < 0 ) CALL check_and_open(file, time, do_write) IF ( .NOT.do_write ) RETURN ! no need to write data - CALL diag_field_out(files(file)%file_unit,output_fields(field)%f_type, dat, dif) + CALL diag_field_out(files(file)%file_unit, output_fields(field)%f_type, dat, dif) ! record number of bytes written to this file files(file)%bytes_written = files(file)%bytes_written +& & (SIZE(dat,1)*SIZE(dat,2)*SIZE(dat,3))*(8/output_fields(field)%pack) diff --git a/src/shared/diag_manager/diag_util.html b/src/shared/diag_manager/diag_util.html deleted file mode 100644 index 8cb1bbfd05..0000000000 --- a/src/shared/diag_manager/diag_util.html +++ /dev/null @@ -1,1185 +0,0 @@ - - - -Module diag_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ ERROR MESSAGES -
                                              -

                                              Module diag_util_mod

                                              - - -
                                              -Contact:  - Seth Underwood - -
                                              -Reviewers:  -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - Functions and subroutines necessary for the diag_manager_mod. -

                                              - - - -
                                              - -diag_util_mod is a set of Fortran functions and subroutines used by the diag_manager_mod. -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                                 diag_data_mod
                                              diag_axis_mod
                                              diag_output_mod
                                              diag_grid_mod
                                              fms_mod
                                              fms_io_mod
                                              mpp_domains_mod
                                              time_manager_mod
                                              mpp_io_mod
                                              mpp_mod
                                              constants_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -get_subfield_size:
                                              -
                                              - Get the size, start, and end indices for output fields. -
                                              -
                                              -get_subfield_vert_size:
                                              -
                                              - Get size, start and end indices for output fields. -
                                              -
                                              -log_diag_field_info:
                                              -
                                              - Writes brief diagnostic field info to the log file. -
                                              -
                                              -update_bounds:
                                              -
                                              - Update the output_fields min and max boundaries. -
                                              -
                                              -check_out_of_bounds:
                                              -
                                              - Checks if the array indices for output_fields(out_num) are outside the output_fields(out_num)%buffer upper - and lower bounds. -
                                              -
                                              -check_bounds_are_exact_dynamic:
                                              -
                                              - Check if the array indices for output_fields(out_num) are equal to the output_fields(out_num)%buffer - upper and lower bounds. -
                                              -
                                              -check_bounds_are_exact_static:
                                              -
                                              - Check if the array indices for output_fields(out_num) are equal to the output_fields(out_num)%buffer - upper and lower bounds. -
                                              -
                                              -init_file:
                                              -
                                              - Initialize the output file. -
                                              -
                                              -sync_file_times:
                                              -
                                              - Synchronize the file's start and close times with the model start and end times. -
                                              -
                                              -diag_time_inc:
                                              -
                                              - Return the next time data/file is to be written based on the frequency and units. -
                                              -
                                              -find_input_field:
                                              -
                                              - Return the field number for the given module name, field name, and tile number. -
                                              -
                                              -init_input_field:
                                              -
                                              - Initialize the input field. -
                                              -
                                              -init_output_field:
                                              -
                                              - Initialize the output field. -
                                              -
                                              -get_date_dif:
                                              -
                                              - Return the difference between two times in units. -
                                              -
                                              -diag_data_out:
                                              -
                                              - Write data out to file. -
                                              -
                                              -write_static:
                                              -
                                              - Output all static fields in this file -
                                              -
                                              -check_duplicate_output_fields:
                                              -
                                              - Checks to see if output_name and output_file are unique in output_fields. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                get_subfield_size

                                                -
                                                SUBROUTINE get_subfield_size (axes, outnum)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get the size, start and end indices for output_fields(outnum), then - fill in output_fields(outnum)%output_grid%(start_indx, end_indx) - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                axes   Axes of the input_field.
                                                   [INTEGER, DIMENSION(:)]
                                                outnum   Position in array output_fields.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              3. - -

                                                get_subfield_vert_size

                                                -
                                                SUBROUTINE get_subfield_vert_size (axes, outnum)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get size, start and end indices for output_fields(outnum), fill in - output_fields(outnum)%output_grid%(start_indx, end_indx). -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                axes   Axes of the input_field -
                                                   [INTEGER, DIMENSION(:)]
                                                outnum   Position in array output_fields.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              4. -
                                              5. - -

                                                log_diag_field_info

                                                -
                                                SUBROUTINE log_diag_field_info (module_name, field_name, axes, long_name, units, missing_value, range, dynamic)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - If the do_diag_field_log namelist parameter is .TRUE., - then a line briefly describing diagnostic field is added to - the log file. Normally users should not call this subroutine - directly, since it is called by register_static_field and - register_diag_field if do_not_log is not set to .TRUE.. It is - used, however, in LM3 to avoid excessive logs due to the - number of fields registered for each of the tile types. LM3 - code uses a do_not_log parameter in the registration calls, - and subsequently calls this subroutine to log field information - under a generic name. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                module_name   Module name.
                                                   [CHARACTER(len=*)]
                                                field_name   Field name.
                                                   [CHARACTER(len=*)]
                                                axes   Axis IDs.
                                                   [INTEGER, DIMENSION(:)]
                                                long_name   Long name for field.
                                                   [CHARACTER(len=*), OPTIONAL]
                                                units   Unit of field.
                                                   [CHARACTER(len=*), OPTIONAL]
                                                missing_value   Missing value value.
                                                   [REAL, OPTIONAL]
                                                range   Valid range of values for field.
                                                   [REAL, DIMENSION(2), OPTIONAL]
                                                dynamic   .TRUE. if field is not static.
                                                   [LOGICAL, OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              6. -
                                              7. - -

                                                update_bounds

                                                -
                                                SUBROUTINE update_bounds (out_num, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Update the output_fields x, y, and z min and max boundaries (array indices). -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - -
                                                out_num   output_field ID.
                                                   [INTEGER]
                                                lower_i   Lower i bound.
                                                   [INTEGER]
                                                upper_i   Upper i bound.
                                                   [INTEGER]
                                                lower_j   Lower j bound.
                                                   [INTEGER]
                                                upper_j   Upper j bound.
                                                   [INTEGER]
                                                lower_k   Lower k bound.
                                                   [INTEGER]
                                                upper_k   Upper k bound.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              8. -
                                              9. - -

                                                check_out_of_bounds

                                                -
                                                SUBROUTINE check_out_of_bounds (out_num, diag_field_id, err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -check_out_of_bounds verifies the array min and max indices in the x, y, and z directions of - output_fields(out_num) are not outside the upper and lower array boundaries of - output_fields(out_num)%buffer. If the min and max indices are outside the upper and lower bounds of the buffer - array, then check_out_of_bounds returns an error string. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                out_num    - Output field ID number. -
                                                   [INTEGER]
                                                diag_field_id    - Input field ID number. -
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg    - Return status of check_out_of_bounds. An empty error string indicates the x, y, and z indices are not outside the - buffer array boundaries. -
                                                   [CHARACTER(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              10. -
                                              11. - -

                                                check_bounds_are_exact_dynamic

                                                -
                                                SUBROUTINE check_bounds_are_exact_dynamic (out_num, diag_field_id, Time, err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -check_bounds_are_exact_dynamic checks if the min and max array indices for output_fields(out_num) are - equal to the upper and lower bounds of output_fields(out_num)%buffer. This check is only performed if - output_fields(out_num)%Time_of_prev_field_data doesn't equal Time or Time_zero. - check_bounds_are_exact_dynamic returns an error string if the array indices do not match the buffer bounds. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                out_num    - Output field ID number. -
                                                   [INTEGER]
                                                diag_field_id    - Input field ID number. -
                                                   [INTEGER]
                                                Time    - Time to use in check. The check is only performed if output_fields(out_num)%Time_of_prev_field_data is not - equal to Time or Time_zero. -
                                                   [TYPE(time_type)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg    - Return status of check_bounds_are_exact_dynamic. An empty error string indicates the x, y, and z indices are - equal to the buffer array boundaries. -
                                                   [CHARACTER(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              12. -
                                              13. - -

                                                check_bounds_are_exact_static

                                                -
                                                SUBROUTINE check_bounds_are_exact_static (out_num, diag_field_id, err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                out_num   Output field ID
                                                   [INTEGER]
                                                diag_field_id   Input field ID.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg    -
                                                   [CHARACTER(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              14. -
                                              15. - -

                                                init_file

                                                -
                                                SUBROUTINE init_file (name, output_freq, output_units, format, time_units long_name, tile_count, new_file_freq, new_file_freq_units, start_time, file_duration, file_duration_units)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Initialize the output file. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                name   File name.
                                                   [CHARACTER(len=*)]
                                                output_freq   How often data is to be written to the file.
                                                   [INTEGER]
                                                output_units   The output frequency unit. (MIN, HOURS, DAYS, etc.)
                                                   [INTEGER]
                                                format   Number type/kind the data is to be written out to the file.
                                                   [INTEGER]
                                                time_units   Time axis units.
                                                   [INTEGER]
                                                log_name   Long name for time axis.
                                                   [CHARACTER(len=*)]
                                                tile_count   Tile number.
                                                   [INTEGER]
                                                new_file_freq   How often a new file is to be created.
                                                   [INTEGER, OPTIONAL]
                                                new_file_freq_units   The new file frequency unit. (MIN, HOURS, DAYS, etc.)
                                                   [INTEGER, OPTIONAL]
                                                start_time   Time when the file is to start
                                                   [TYPE(time_type), OPTIONAL]
                                                file_duration   How long file is to be used.
                                                   [INTEGER, OPTIONAL]
                                                file_duration_units   File duration unit. (MIN, HOURS, DAYS, etc.)
                                                   [INTEGER, OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              16. -
                                              17. - -

                                                sync_file_times

                                                -
                                                SUBROUTINE sync_file_times (init_time)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -sync_file_times checks to see if the file start time is less than the - model's init time (passed in as the only argument). If it is less, then the - both the file start time and end time are synchronized using the passed in initial time - and the duration as calculated by the diag_time_inc function. sync_file_times - will also increase the next_open until it is greater than the init_time. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                file_id   The file ID
                                                   [INTEGER]
                                                init_time   Initial time use for the synchronization.
                                                   [TYPE(time_type)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg   Return error message
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              18. -
                                              19. - -

                                                diag_time_inc

                                                -
                                                TYPE(time_type) FUNCTION diag_time_inc (time, output_freq, output_units, err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return the next time data/file is to be written. This value is based on the current time and the frequency and units. - Function completed successful if the optional err_msg is empty. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                time   Current model time.
                                                   [TYPE(time_type)]
                                                output_freq   Output frequency number value.
                                                   [INTEGER]
                                                output_units   Output frequency unit.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg    - Function error message. An empty string indicates the next output time was found successfully. -
                                                   [CHARACTER, OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              20. -
                                              21. - -

                                                find_input_field

                                                -
                                                INTEGER FUNCTION find_input_field (module_name, field_name, tile_count)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return the field number for the given module name, field name and tile number. A return value of -1 indicates - the field was not found. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                module_name   Module name.
                                                   [CHARACTER(len=*)]
                                                field_name   field name.
                                                   [CHARACTER(len=*)]
                                                tile_count   Tile number.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              22. -
                                              23. - -

                                                init_input_field

                                                -
                                                SUBROUTINE init_input_field (module_name, field_name, tile_count)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                module_name   Module name.
                                                   [CHARACTER(len=*)]
                                                field_name   Input field name.
                                                   [CHARACTER(len=*)]
                                                tile_count   Tile number.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              24. -
                                              25. - -

                                                init_output_field

                                                -
                                                SUBROUTINE init_output_field (module_name, field_name, output_name, output_file time_method, pack, tile_count, local_coord)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Initialize the output field. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                module_name   Module name.
                                                   [CHARACTER(len=*)]
                                                field_name   Output field name.
                                                   [CHARACTER(len=*)]
                                                output_name   Output name written to file.
                                                   [CHARACTER(len=*)]
                                                output_file   File where field should be written.
                                                   [CHARACTER(len=*)]
                                                time_method    - Data reduction method. See diag_manager_mod for valid methods.
                                                   [CHARACTER(len=*)]
                                                pack   Packing method.
                                                   [INTEGER]
                                                tile_count   Tile number.
                                                   [INTEGER]
                                                local_coord   Region to be written. If missing, then all data to be written.
                                                   [INTEGER, OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              26. -
                                              27. - -

                                                get_date_dif

                                                -
                                                REAL FUNCTION get_date_dif (t2, t1, units)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Calculate and return the difference between the two times given in the unit given using the function t2 - t1. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                t2   Most recent time.
                                                   [TYPE(time_type)]
                                                t1   Most distant time.
                                                   [TYPE(time_type)]
                                                units   Unit of return value.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              28. -
                                              29. - -

                                                diag_data_out

                                                -
                                                SUBROUTINE diag_data_out (file, field, dat, time, fianl_call_in, static_write_in)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Write data out to file, and if necessary flush the buffers. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - -
                                                file   File ID.
                                                   [INTEGER]
                                                field   Field ID.
                                                   [INTEGER]
                                                time   Current model time.
                                                   [TYPE(time_type)]
                                                final_call_in   .TRUE. if this is the last write for file.
                                                   [LOGICAL, OPTIONAL]
                                                static_write_in   .TRUE. if static fields are to be written to file.
                                                   [LOGICAL, OPTIONAL]
                                                -
                                                -
                                                -
                                                -INPUT/OUTPUT -
                                                -
                                                - - - - -
                                                dat   Data to write out.
                                                   [REAL, DIMENSION(:,:,:,:)]
                                                -
                                                -
                                                -
                                                -
                                              30. -
                                              31. - -

                                                write_static

                                                -
                                                SUBROUTINE write_static (file)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Write the static data to the file. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                file   File ID.
                                                   [INTEGER]
                                                -
                                                -
                                                -
                                                -
                                              32. -
                                              33. - -

                                                check_duplicate_output_fields

                                                -
                                                SUBROUTINE check_duplicate_output_fields (err_msg)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Check to see if output_name and output_file are unique in output_fields. An empty - err_msg indicates no duplicates found. -
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                err_msg   Error message. If empty, then no duplicates found.
                                                   [CHARACTER(len=*), OPTIONAL]
                                                -
                                                -
                                                -
                                                -
                                              34. -
                                              - - - - - - -
                                              -

                                              ERROR MESSAGES

                                              - -
                                              -
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              wrong order of axes. X should come first.
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              wrong order of axes, Y should come second.
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              wrong values in vertical axis of region
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              i should equal 3 for z axis
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              Wrong axis_cart
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              - can not find gstart_indx/gend_indx for <output_fields(outnum)%output_name>, - check region bounds for axis <i>. -
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              - axis(3) should be Z-axis -
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              - wrong values in vertical axis of region -
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              No domain available
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              wrong compute domain indices
                                              -
                                              -FATAL in get_subfield_size -
                                              -
                                              - -
                                              -
                                              - <output_fields(outnum)%output_name> error at i = <i> -
                                              -
                                              -FATAL in get_subfield_vert_size -
                                              -
                                              - -
                                              -
                                              wrong order of axes, X should come first
                                              -
                                              -FATAL in get_subfield_vert_size -
                                              -
                                              - -
                                              -
                                              wrong order of axes, Y should come second
                                              -
                                              -FATAL in get_subfield_vert_size -
                                              -
                                              - -
                                              -
                                              wrong values in vertical axis of region
                                              -
                                              -FATAL in get_subfield_vert_size -
                                              -
                                              - -
                                              -
                                              i should equal 3 for z axis
                                              -
                                              -FATAL in get_subfield_vert_size -
                                              -
                                              - -
                                              -
                                              Wrong axis_cart
                                              -
                                              -FATAL in get_subfield_vert_size -
                                              -
                                              - -
                                              -
                                              - can not find gstart_indx/gend_indx for <output_fields(outnum)%output_name> - check region bounds for axis -
                                              -
                                              -FATAL in init_file -
                                              -
                                              - -
                                              -
                                              - max_files exceeded, increase max_files via the max_files variable - in the namelist diag_manager_nml. -
                                              -
                                              -FATAL in init_file -
                                              -
                                              - -
                                              -
                                              - close time GREATER than next_open time, check file duration, - file frequency in <files(num_files)%name> -
                                              -
                                              -FATAL in init_input_field -
                                              -
                                              - -
                                              -
                                              max_input_fields exceeded, increase it via diag_manager_nml
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              max_output_fields = <max_output_fields> exceeded. Increase via diag_manager_nml
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              module_name/field_name <module_name>/<field_name>[/tile_count=<tile_count>] NOT registered
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - MAX_OUT_PER_IN_FIELD = <MAX_OUT_PER_IN_FIELD> exceeded for <module_name>/<field_name>, increase MAX_OUT_PER_IN_FIELD - in diag_data.F90. -
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - file <file_name> is NOT found in the diag_table. -
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - file <output_file> is not initialized for tile_count = <tile_count> -
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - MAX_FIELDS_PER_FILE = <MAX_FIELDS_PER_FILE> exceeded. Increase MAX_FIELDS_PER_FILE in diag_data.F90. -
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - could not find integer number of diurnal samples in string "<t_method>" -
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - The integer value of diurnal samples must be greater than zero. -
                                              -
                                              -FATAL in init_output_field -
                                              -
                                              - -
                                              -
                                              - improper time method in diag_table for output field <output_name> -
                                              -
                                              -FATAL in get_date_dif -
                                              -
                                              - -
                                              -
                                              - variable t2 is less than in variable t1 -
                                              -
                                              -FATAL in get_date_dif -
                                              -
                                              - -
                                              -
                                              - months not supported as output units -
                                              -
                                              -FATAL in get_date_dif -
                                              -
                                              - -
                                              -
                                              - years not suppored as output units -
                                              -
                                              -FATAL in get_date_dif -
                                              -
                                              - -
                                              -
                                              - illegal time units -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              FUTURE PLANS

                                              - -
                                              -
                                                -
                                              • - Make an interface check_bounds_are_exact for the subroutines check_bounds_are_exact_static and - check_bounds_are_exact_dynamic. -
                                                       INTERFACE check_bounds_are_exact
                                                -         MODULE PROCEDURE check_bounds_are_exact_static
                                                -         MODULE PROCEDURE check_bounds_are_exact_dynamic
                                                -       END INTERFACE check_bounds_are_exact
                                                - -
                                              • -
                                              -
                                              -
                                              - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/drifters/drifters.F90 b/src/shared/drifters/drifters.F90 index b26ea1fdfe..bc40760037 100644 --- a/src/shared/drifters/drifters.F90 +++ b/src/shared/drifters/drifters.F90 @@ -1,5 +1,5 @@ !FDOC_TAG_GFDL fdoc.pl generated xml skeleton -! $Id: drifters.F90,v 17.0.10.1 2012/03/20 13:03:22 z1l Exp $ +! $Id: drifters.F90,v 20.0 2013/12/14 00:19:02 fms Exp $ #include #include "fms_switches.h" @@ -109,7 +109,7 @@ module drifters_mod public :: drifters_print_checksums, drifters_save, drifters_write_restart, drifters_distribute integer, parameter, private :: MAX_STR_LEN = 128 - character(len=MAX_STR_LEN), parameter, private :: version = '$Id: drifters.F90,v 17.0.10.1 2012/03/20 13:03:22 z1l Exp $' + character(len=MAX_STR_LEN), parameter, private :: version = '$Id: drifters.F90,v 20.0 2013/12/14 00:19:02 fms Exp $' real :: DRFT_EMPTY_ARRAY(0) type drifters_type diff --git a/src/shared/drifters/drifters_comm.F90 b/src/shared/drifters/drifters_comm.F90 index eae3eccb0c..c60dec4c02 100644 --- a/src/shared/drifters/drifters_comm.F90 +++ b/src/shared/drifters/drifters_comm.F90 @@ -1,7 +1,7 @@ #include #include "fms_switches.h" -! $Id: drifters_comm.F90,v 19.0.2.2 2012/05/14 19:29:27 Zhi.Liang Exp $ +! $Id: drifters_comm.F90,v 20.0 2013/12/14 00:19:06 fms Exp $ module drifters_comm_mod diff --git a/src/shared/exchange/test_xgrid.F90 b/src/shared/exchange/test_xgrid.F90 index 723534c9c9..924f8ac77c 100644 --- a/src/shared/exchange/test_xgrid.F90 +++ b/src/shared/exchange/test_xgrid.F90 @@ -5,7 +5,6 @@ program xgrid_test use mpp_mod, only : mpp_pe, mpp_npes, mpp_error, FATAL, mpp_chksum, mpp_min, mpp_max use mpp_mod, only : mpp_set_current_pelist, mpp_declare_pelist - use mpp_mod, only : mpp_clock_begin, mpp_clock_end, mpp_clock_id, MPP_CLOCK_SYNC use mpp_domains_mod, only : mpp_define_domains, mpp_define_layout, mpp_domains_exit use mpp_domains_mod, only : mpp_get_compute_domain, domain2d, mpp_domains_init use mpp_domains_mod, only : mpp_define_mosaic_pelist, mpp_define_mosaic, mpp_global_sum @@ -93,7 +92,6 @@ program xgrid_test integer :: npes_per_tile integer :: id_put_side1_to_xgrid, id_get_side1_from_xgrid integer :: id_put_side2_to_xgrid, id_get_side2_from_xgrid - integer :: id_setup_xmap integer :: ens_siz(6), ensemble_size integer :: atm_root_pe, lnd_root_pe, ocn_root_pe, ice_root_pe, atm_nest_root_pe integer :: atm_global_npes, ntile_atm_global, ncontact_global @@ -104,11 +102,6 @@ program xgrid_test integer, allocatable :: tile_id(:) call fms_init - id_setup_xmap = mpp_clock_id("setup_xmap", flags=MPP_CLOCK_SYNC) - id_put_side1_to_xgrid = mpp_clock_id("put_side1_to_xgrid", flags=MPP_CLOCK_SYNC) - id_get_side1_from_xgrid = mpp_clock_id("get_side1_from_xgrid", flags=MPP_CLOCK_SYNC) - id_put_side2_to_xgrid = mpp_clock_id("put_side2_to_xgrid", flags=MPP_CLOCK_SYNC) - id_get_side2_from_xgrid = mpp_clock_id("get_side2_from_xgrid", flags=MPP_CLOCK_SYNC) call mpp_domains_init @@ -119,6 +112,10 @@ program xgrid_test pe = mpp_pe() out_unit = stdout() +#ifdef INTERNAL_FILE_NML + read (input_nml_file, xgrid_test_nml, iostat=io) + ierr = check_nml_error(io, 'xgrid_test_nml') +#else if (file_exist('input.nml')) then ierr=1 nml_unit = open_namelist_file() @@ -128,6 +125,7 @@ program xgrid_test enddo 10 call close_file(nml_unit) endif +#endif !--- get ensemble size ens_siz = get_ensemble_size() @@ -441,10 +439,8 @@ program xgrid_test call mpp_set_current_pelist() !--- conservation check is done in setup_xmap. - call mpp_clock_begin(id_setup_xmap) call setup_xmap(Xmap, (/ 'ATM', 'OCN', 'LND' /), (/ Atm_domain, Ice_domain, Lnd_domain /), grid_file, atm_grid) call setup_xmap(Xmap_runoff, (/ 'LND', 'OCN'/), (/ Lnd_domain, Ice_domain/), grid_file ) - call mpp_clock_end(id_setup_xmap) !--- set frac area if nk_lnd or nk_ocn is greater than 1. if(nk_lnd > 0 .AND. lnd_pe) then allocate(lnd_frac(isc_lnd:iec_lnd, jsc_lnd:jec_lnd, nk_lnd)) @@ -659,23 +655,15 @@ program xgrid_test call get_xmap_grid_area("OCN", Xmap, ice_area) do n = 1, num_iter call random_number(atm_data_in) - call mpp_clock_begin(id_put_side1_to_xgrid) call put_to_xgrid(atm_data_in, 'ATM', x_1, Xmap, remap_method=remap_method) - call mpp_clock_end(id_put_side1_to_xgrid) - call mpp_clock_begin(id_get_side2_from_xgrid) call get_from_xgrid(lnd_data_out, 'LND', x_1, xmap) call get_from_xgrid(ice_data_out, 'OCN', x_1, xmap) - call mpp_clock_end(id_get_side2_from_xgrid) - call mpp_clock_begin(id_put_side2_to_xgrid) call put_to_xgrid(lnd_data_out, 'LND', x_2, xmap) call put_to_xgrid(ice_data_out, 'OCN', x_2, xmap) - call mpp_clock_end(id_put_side2_to_xgrid) - call mpp_clock_begin(id_get_side1_from_xgrid) call get_from_xgrid(atm_data_out, 'ATM', x_2, xmap) - call mpp_clock_end(id_get_side1_from_xgrid) sum_atm_in = mpp_global_sum(atm_domain, atm_area * atm_data_in) sum_lnd_out = 0 do k = 1, nk_lnd diff --git a/src/shared/exchange/xgrid.F90 b/src/shared/exchange/xgrid.F90 index d3c23db2b9..d59f9ba09e 100644 --- a/src/shared/exchange/xgrid.F90 +++ b/src/shared/exchange/xgrid.F90 @@ -117,7 +117,7 @@ module xgrid_mod COMM_TAG_1, COMM_TAG_2, COMM_TAG_3, COMM_TAG_4, & COMM_TAG_5, COMM_TAG_6, COMM_TAG_7, COMM_TAG_8, & COMM_TAG_9, COMM_TAG_10 -use mpp_mod, only: input_nml_file, mpp_set_current_pelist, mpp_sum +use mpp_mod, only: input_nml_file, mpp_set_current_pelist, mpp_sum, mpp_sync use mpp_domains_mod, only: mpp_get_compute_domain, mpp_get_compute_domains, & Domain2d, mpp_global_sum, mpp_update_domains, & mpp_modify_domain, mpp_get_data_domain, XUPDATE, & @@ -127,7 +127,7 @@ module xgrid_mod mpp_deallocate_domain, mpp_define_domains, & mpp_get_domain_npes, mpp_get_domain_root_pe, & mpp_domain_is_initialized, mpp_broadcast_domain, & - mpp_get_domain_pelist + mpp_get_domain_pelist, mpp_compute_extent use mpp_io_mod, only: mpp_open, MPP_MULTI, MPP_SINGLE, MPP_OVERWR use constants_mod, only: PI, RADIUS use mosaic_mod, only: get_mosaic_xgrid, get_mosaic_xgrid_size, & @@ -167,14 +167,23 @@ module xgrid_mod ! ! Outputs exchange grid information to xgrid.out. for debug/diag purposes. ! +! +! number of processors to read exchange grid information. Those processors that read +! the exchange grid information will send data to other processors to prepare for flux exchange. +! Default value is 0. When nsubset is 0, each processor will read part of the exchange grid +! information. The purpose of this namelist is to improve performance of setup_xmap when running +! on highr processor count and solve receiving size mismatch issue on high processor count. +! Try to set nsubset = mpp_npes/MPI_rank_per_node. +! logical :: make_exchange_reproduce = .false. ! exactly same on different # PEs logical :: xgrid_log = .false. character(len=64) :: interp_method = 'first_order' logical :: debug_stocks = .false. logical :: xgrid_clocks_on = .false. logical :: monotonic_exchange = .false. +integer :: nsubset = 0 ! 0 means mpp_npes() namelist /xgrid_nml/ make_exchange_reproduce, interp_method, debug_stocks, xgrid_log, xgrid_clocks_on, & - monotonic_exchange + monotonic_exchange, nsubset ! logical :: init = .true. integer :: remapping_method @@ -335,6 +344,7 @@ module xgrid_mod type overlap_type integer :: count integer :: pe + integer :: buffer_pos integer, pointer :: i(:) =>NULL() integer, pointer :: j(:) =>NULL() integer, pointer :: tile(:) =>NULL() @@ -345,6 +355,7 @@ module xgrid_mod type comm_type integer :: nsend, nrecv integer :: sendsize, recvsize + integer, pointer, dimension(:) :: unpack_ind=>NULL() type(overlap_type), pointer, dimension(:) :: send=>NULL() type(overlap_type), pointer, dimension(:) :: recv=>NULL() end type comm_type @@ -361,6 +372,10 @@ module xgrid_mod logical, pointer, dimension(:) :: your2my1 =>NULL() ! true if a side 2 domain on ! indexed pe overlaps side 1 ! domain on this pe + integer, pointer, dimension(:) :: your2my1_size=>NULL() ! number of exchange grid of + ! a side 2 domain on + ! indexed pe overlaps side 1 + ! domain on this pe type (grid_type), pointer, dimension(:) :: grids =>NULL() ! 1st grid is side 1; ! rest on side 2 @@ -385,8 +400,8 @@ module xgrid_mod end type xmap_type !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: xgrid.F90,v 19.0.2.2.4.3 2012/05/16 18:29:28 Zhi.Liang Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: xgrid.F90,v 20.0 2013/12/14 00:19:20 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' real, parameter :: EPS = 1.0e-10 real, parameter :: LARGE_NUMBER = 1.e20 @@ -397,6 +412,10 @@ module xgrid_mod integer :: id_get_2_from_xgrid = 0 integer :: id_put_2_to_xgrid = 0 integer :: id_setup_xmap = 0 + integer :: id_load_xgrid1, id_load_xgrid2, id_load_xgrid3 + integer :: id_load_xgrid4, id_load_xgrid5 + integer :: id_load_xgrid, id_set_comm, id_regen, id_conservation_check + ! The following is for nested model integer :: nnest=0, tile_nest, tile_parent @@ -451,6 +470,7 @@ subroutine xgrid_init(remap_method) #ifdef INTERNAL_FILE_NML read (input_nml_file, xgrid_nml, iostat=io) + ierr = check_nml_error ( io, 'xgrid_nml' ) #else if ( file_exist( 'input.nml' ) ) then unit = open_namelist_file ( ) @@ -500,6 +520,15 @@ subroutine xgrid_init(remap_method) id_get_2_from_xgrid = mpp_clock_id("get_2_from_xgrid", flags=MPP_CLOCK_SYNC) id_put_2_to_xgrid = mpp_clock_id("put_2_to_xgrid", flags=MPP_CLOCK_SYNC) id_setup_xmap = mpp_clock_id("setup_xmap", flags=MPP_CLOCK_SYNC) + id_set_comm = mpp_clock_id("set_comm") + id_regen = mpp_clock_id("regen") + id_conservation_check = mpp_clock_id("conservation_check") + id_load_xgrid = mpp_clock_id("load_xgrid") + id_load_xgrid1 = mpp_clock_id("load_xgrid1") + id_load_xgrid2 = mpp_clock_id("load_xgrid2") + id_load_xgrid3 = mpp_clock_id("load_xgrid3") + id_load_xgrid4 = mpp_clock_id("load_xgrid4") + id_load_xgrid5 = mpp_clock_id("load_xgrid5") endif remapping_method = remap_method @@ -531,8 +560,6 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u real, pointer, dimension(:) :: area_side1 =>NULL() real, allocatable, dimension(:,:) :: tmp - integer, allocatable, dimension(:) :: nsend1, nsend2, nrecv1, nrecv2 - integer, allocatable, dimension(:) :: pelist real, allocatable, dimension(:) :: send_buffer, recv_buffer type (grid_type), pointer, save :: grid1 =>NULL() integer :: l, ll, ll_repro, p, siz(4), nxgrid, size_prev @@ -542,19 +569,39 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u logical :: is_distribute = .false. real, allocatable, dimension(:) :: scale real :: garea - integer :: npes, isc, iec, nxgrid_local - integer :: nxgrid1, nxgrid2, nset1, nset2 - integer :: pos, nsend, nrecv, l1, l2, n + integer :: npes, isc, iec, nxgrid_local, pe, nxgrid_local_orig + integer :: nxgrid1, nxgrid2, nset1, nset2, ndivs, cur_ind + integer :: pos, nsend, nrecv, l1, l2, n, mypos, m integer :: start(4), nread(4) - type(domain1d) :: domain - integer, allocatable, dimension(:,:) :: ibuf1, ibuf2 logical :: found character(len=128) :: attvalue + integer, dimension(0:xmap%npes-1) :: pelist + logical, dimension(0:xmap%npes-1) :: subset_rootpe + integer, dimension(0:xmap%npes-1) :: nsend1, nsend2, nrecv1, nrecv2 + integer, dimension(0:xmap%npes-1) :: send_buffer_pos, recv_buffer_pos + integer, dimension(0:xmap%npes-1) :: ibegin, iend, pebegin, peend + integer, dimension(2,0:xmap%npes-1) :: ibuf1, ibuf2 + integer, dimension(0:xmap%npes-1) :: pos_x, y2m1_size + integer, allocatable, dimension(:) :: y2m1_pe + integer, pointer, save :: iarray(:), jarray(:) + integer, allocatable, save :: pos_s(:) + integer, pointer, dimension(:) :: iarray2(:)=>NULL(), jarray2(:)=>NULL() + logical :: last_grid + integer :: nxgrid1_old scale_exist = .false. grid1 => xmap%grids(1) out_unit = stdout() npes = xmap%npes + pe = mpp_pe() + mypos = mpp_pe()-mpp_root_pe() + + call mpp_get_current_pelist(pelist) + !--- make sure npes = pelist(npes-1) - pelist(0) + 1 + if( npes .NE. pelist(npes-1) - pelist(0) + 1 ) then + print*, "npes =", npes, ", pelist(npes-1)=", pelist(npes-1), ", pelist(0)=", pelist(0) + call error_mesg('xgrid_mod', 'npes .NE. pelist(npes-1) - pelist(0)', FATAL) + endif select case(xmap%version) case(VERSION1) @@ -569,85 +616,40 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u !--- define a domain to read exchange grid. if(nxgrid > npes) then + ndivs = npes + if(nsubset >0 .AND. nsubset < npes) ndivs = nsubset + call mpp_compute_extent( 1, nxgrid, ndivs, ibegin, iend) + if(npes == ndivs) then + p = mpp_pe()-mpp_root_pe() + isc = ibegin(p) + iec = iend(p) + subset_rootpe(:) = .true. + else + isc = 0; iec = -1 + call mpp_compute_extent(pelist(0), pelist(npes-1), ndivs, pebegin, peend) + do n = 0, ndivs-1 + if(pe == pebegin(n)) then + isc = ibegin(n) + iec = iend(n) + exit + endif + enddo + cur_ind = 0 + subset_rootpe(:) = .false. + + do n = 0, npes-1 + if(pelist(n) == pebegin(cur_ind)) then + subset_rootpe(n) = .true. + cur_ind = cur_ind+1 + if(cur_ind == ndivs) exit + endif + enddo + endif is_distribute = .true. - call mpp_define_domains((/1,nxgrid/), npes, domain) - call mpp_get_compute_domain(domain, isc, iec) else is_distribute = .false. isc = 1; iec = nxgrid endif - nxgrid_local = iec - isc + 1 - allocate(i1_tmp(isc:iec), j1_tmp(isc:iec), i2_tmp(isc:iec), j2_tmp(isc:iec), area_tmp(isc:iec) ) - if(use_higher_order) allocate(di_tmp(isc:iec), dj_tmp(isc:iec)) - - start = 1; nread = 1 - - select case(xmap%version) - case(VERSION1) - start(1) = isc; nread(1) = nxgrid_local - allocate(tmp(nxgrid_local,1)) - call read_data(grid_file, 'I_'//grid1_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - i1_tmp = tmp(:,1) - call read_data(grid_file, 'J_'//grid1_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - j1_tmp = tmp(:,1) - call read_data(grid_file, 'I_'//grid_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - i2_tmp = tmp(:,1) - call read_data(grid_file, 'J_'//grid_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - j2_tmp = tmp(:,1) - call read_data(grid_file, 'AREA_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - area_tmp = tmp(:,1) - if(use_higher_order) then - call read_data(grid_file, 'DI_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - di_tmp = tmp(:,1) - call read_data(grid_file, 'DJ_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) - dj_tmp = tmp(:,1) - end if - deallocate(tmp) - case(VERSION2) - nread(1) = 2; start(2) = isc; nread(2) = nxgrid_local - allocate(tmp(2, isc:iec)) - call read_data(grid_file, "tile1_cell", tmp, start, nread, no_domain=.TRUE.) - i1_tmp(isc:iec) = tmp(1, isc:iec) - j1_tmp(isc:iec) = tmp(2, isc:iec) - call read_data(grid_file, "tile2_cell", tmp, start, nread, no_domain=.TRUE.) - i2_tmp(isc:iec) = tmp(1, isc:iec) - j2_tmp(isc:iec) = tmp(2, isc:iec) - if(use_higher_order) then - call read_data(grid_file, "tile1_distance", tmp, start, nread, no_domain=.TRUE.) - di_tmp(isc:iec) = tmp(1, isc:iec) - dj_tmp(isc:iec) = tmp(2, isc:iec) - end if - start = 1; nread = 1 - start(1) = isc; nread(1) = nxgrid_local - deallocate(tmp) - allocate(tmp(isc:iec,1) ) - call read_data(grid_file, "xgrid_area", tmp(:,1:1), start, nread, no_domain=.TRUE.) - ! check the units of "xgrid_area - call get_var_att_value(grid_file, "xgrid_area", "units", attvalue) - if( trim(attvalue) == 'm2' ) then - garea = 4*PI*RADIUS*RADIUS; - area_tmp = tmp(:,1)/garea - else if( trim(attvalue) == 'none' ) then - area_tmp = tmp(:,1) - else - call error_mesg('xgrid_mod', 'In file '//trim(grid_file)//', xgrid_area units = '// & - trim(attvalue)//' should be "m2" or "none"', FATAL) - endif - - !--- if field "scale" exist, read this field. Normally this - !--- field only exist in landXocean exchange grid cell. - if(grid1_id == 'LND' .AND. grid_id == 'OCN') then - if(field_exist(grid_file, "scale")) then - allocate(scale(isc:iec)) - write(out_unit, *)"NOTE from load_xgrid(xgrid_mod): field 'scale' exist in the file "// & - trim(grid_file)//", this field will be read and the exchange grid cell area will be multiplied by scale" - call read_data(grid_file, "scale", tmp, start, nread, no_domain=.TRUE.) - scale = tmp(:,1) - scale_exist = .true. - endif - endif - deallocate(tmp) - end select nset1 = 5 nset2 = 5 @@ -657,119 +659,222 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u end if if(scale_exist) nset2 = nset1 + 1 - !---z1l: The following change is for the situation that some processor is masked out. - !---loop through all the pe to see if side 1 and side of each exchange grid is on some processor - allocate(i1(isc:iec), j1(isc:iec), i2(isc:iec), j2(isc:iec), area(isc:iec) ) - if(use_higher_order) allocate(di(isc:iec), dj(isc:iec)) - pos = isc-1 - - do l = isc, iec - found = .false. - !--- first check if the exchange grid is on one of side 1 processor - do p = 0, npes - 1 - if(grid1%tile(p) == tile1) then - if (in_box(i1_tmp(l), j1_tmp(l), grid1%is(p), grid1%ie(p), grid1%js(p), grid1%je(p))) then - found = .true. - exit + call mpp_clock_begin(id_load_xgrid1) + if(iec .GE. isc) then + nxgrid_local = iec - isc + 1 + allocate(i1_tmp(isc:iec), j1_tmp(isc:iec), i2_tmp(isc:iec), j2_tmp(isc:iec), area_tmp(isc:iec) ) + if(use_higher_order) allocate(di_tmp(isc:iec), dj_tmp(isc:iec)) + + start = 1; nread = 1 + + select case(xmap%version) + case(VERSION1) + start(1) = isc; nread(1) = nxgrid_local + allocate(tmp(nxgrid_local,1)) + call read_data(grid_file, 'I_'//grid1_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + i1_tmp = tmp(:,1) + call read_data(grid_file, 'J_'//grid1_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + j1_tmp = tmp(:,1) + call read_data(grid_file, 'I_'//grid_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + i2_tmp = tmp(:,1) + call read_data(grid_file, 'J_'//grid_id//'_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + j2_tmp = tmp(:,1) + call read_data(grid_file, 'AREA_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + area_tmp = tmp(:,1) + if(use_higher_order) then + call read_data(grid_file, 'DI_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + di_tmp = tmp(:,1) + call read_data(grid_file, 'DJ_'//grid1_id//'x'//grid_id, tmp, start, nread, no_domain=.TRUE.) + dj_tmp = tmp(:,1) + end if + deallocate(tmp) + case(VERSION2) + nread(1) = 2; start(2) = isc; nread(2) = nxgrid_local + allocate(tmp(2, isc:iec)) + call read_data(grid_file, "tile1_cell", tmp, start, nread, no_domain=.TRUE.) + i1_tmp(isc:iec) = tmp(1, isc:iec) + j1_tmp(isc:iec) = tmp(2, isc:iec) + call read_data(grid_file, "tile2_cell", tmp, start, nread, no_domain=.TRUE.) + i2_tmp(isc:iec) = tmp(1, isc:iec) + j2_tmp(isc:iec) = tmp(2, isc:iec) + if(use_higher_order) then + call read_data(grid_file, "tile1_distance", tmp, start, nread, no_domain=.TRUE.) + di_tmp(isc:iec) = tmp(1, isc:iec) + dj_tmp(isc:iec) = tmp(2, isc:iec) + end if + start = 1; nread = 1 + start(1) = isc; nread(1) = nxgrid_local + deallocate(tmp) + allocate(tmp(isc:iec,1) ) + call read_data(grid_file, "xgrid_area", tmp(:,1:1), start, nread, no_domain=.TRUE.) + ! check the units of "xgrid_area + call get_var_att_value(grid_file, "xgrid_area", "units", attvalue) + if( trim(attvalue) == 'm2' ) then + garea = 4*PI*RADIUS*RADIUS; + area_tmp = tmp(:,1)/garea + else if( trim(attvalue) == 'none' ) then + area_tmp = tmp(:,1) + else + call error_mesg('xgrid_mod', 'In file '//trim(grid_file)//', xgrid_area units = '// & + trim(attvalue)//' should be "m2" or "none"', FATAL) + endif + + !--- if field "scale" exist, read this field. Normally this + !--- field only exist in landXocean exchange grid cell. + if(grid1_id == 'LND' .AND. grid_id == 'OCN') then + if(field_exist(grid_file, "scale")) then + allocate(scale(isc:iec)) + write(out_unit, *)"NOTE from load_xgrid(xgrid_mod): field 'scale' exist in the file "// & + trim(grid_file)//", this field will be read and the exchange grid cell area will be multiplied by scale" + call read_data(grid_file, "scale", tmp, start, nread, no_domain=.TRUE.) + scale = tmp(:,1) + scale_exist = .true. endif endif - enddo - !--- Then check if the exchange grid is on one of side 2 processor - if( found ) then + deallocate(tmp) + end select + + !---z1l: The following change is for the situation that some processor is masked out. + !---loop through all the pe to see if side 1 and side of each exchange grid is on some processor + nxgrid_local_orig = nxgrid_local + allocate(i1(isc:iec), j1(isc:iec), i2(isc:iec), j2(isc:iec), area(isc:iec) ) + if(use_higher_order) allocate(di(isc:iec), dj(isc:iec)) + pos = isc-1 + + do l = isc, iec + found = .false. + !--- first check if the exchange grid is on one of side 1 processor do p = 0, npes - 1 - if(grid%tile(p) == tile2) then - if (in_box(i2_tmp(l), j2_tmp(l), grid%is(p), grid%ie(p), grid%js(p), grid%je(p))) then - pos = pos+1 - i1(pos) = i1_tmp(l) - j1(pos) = j1_tmp(l) - i2(pos) = i2_tmp(l) - j2(pos) = j2_tmp(l) - area(pos) = area_tmp(l) - if(use_higher_order) then - di(pos) = di_tmp(l) - dj(pos) = dj_tmp(l) - endif + if(grid1%tile(p) == tile1) then + if (in_box(i1_tmp(l), j1_tmp(l), grid1%is(p), grid1%ie(p), grid1%js(p), grid1%je(p))) then + found = .true. exit endif endif enddo + !--- Then check if the exchange grid is on one of side 2 processor + if( found ) then + do p = 0, npes - 1 + if(grid%tile(p) == tile2) then + if (in_box(i2_tmp(l), j2_tmp(l), grid%is(p), grid%ie(p), grid%js(p), grid%je(p))) then + pos = pos+1 + i1(pos) = i1_tmp(l) + j1(pos) = j1_tmp(l) + i2(pos) = i2_tmp(l) + j2(pos) = j2_tmp(l) + area(pos) = area_tmp(l) + if(use_higher_order) then + di(pos) = di_tmp(l) + dj(pos) = dj_tmp(l) + endif + exit + endif + endif + enddo + endif + enddo + + deallocate(i1_tmp, i2_tmp, j1_tmp, j2_tmp, area_tmp) + if(use_higher_order) deallocate( di_tmp, dj_tmp) + iec = pos + if(iec .GE. isc) then + nxgrid_local = iec - isc + 1 + else + nxgrid_local = 0 endif - enddo - deallocate(i1_tmp, i2_tmp, j1_tmp, j2_tmp, area_tmp) - if(use_higher_order) deallocate( di_tmp, dj_tmp) - iec = pos - nxgrid_local = iec - isc + 1 + else + nxgrid_local = 0 + nxgrid_local_orig = 0 + endif + + call mpp_clock_end(id_load_xgrid1) if(is_distribute) then !--- Since the xgrid is distributed according to side 2 grid. Send all the xgrid to its own side 2. !--- Also need to send the xgrid to its own side 1 for the reproducing ability between processor count. !--- first find out number of points need to send to other pe and fill the send buffer. - allocate(pelist(0:npes-1)) - call mpp_get_current_pelist(pelist) - allocate(nsend1(0:npes-1), nsend2(0:npes-1)) - allocate(nrecv1(0:npes-1), nrecv2(0:npes-1)) - nsend1 = 0; nrecv1 = 0 - nsend2 = 0; nrecv2 = 0 - - allocate( send_buffer(nxgrid_local * (nset1+nset2)) ) - pos = 0 - do p = 0, npes - 1 - - if(grid%tile(p) == tile2) then - do l = isc, iec - if (in_box(i2(l), j2(l), grid%is(p), grid%ie(p), grid%js(p), grid%je(p))) then - nsend2(p) = nsend2(p) + 1 - send_buffer(pos+1) = i1(l) - send_buffer(pos+2) = j1(l) - send_buffer(pos+3) = i2(l) - send_buffer(pos+4) = j2(l) - send_buffer(pos+5) = area(l) - if(use_higher_order) then - send_buffer(pos+6) = di(l) - send_buffer(pos+7) = dj(l) + nsend1(:) = 0; nrecv1(:) = 0 + nsend2(:) = 0; nrecv2(:) = 0 + ibuf1(:,:)= 0; ibuf2(:,:)= 0 + + call mpp_clock_begin(id_load_xgrid2) + + if(nxgrid_local>0) then + allocate( send_buffer(nxgrid_local * (nset1+nset2)) ) + pos = 0 + do p = 0, npes - 1 + send_buffer_pos(p) = pos + if(grid%tile(p) == tile2) then + do l = isc, iec + if (in_box(i2(l), j2(l), grid%is(p), grid%ie(p), grid%js(p), grid%je(p))) then + nsend2(p) = nsend2(p) + 1 + send_buffer(pos+1) = i1(l) + send_buffer(pos+2) = j1(l) + send_buffer(pos+3) = i2(l) + send_buffer(pos+4) = j2(l) + send_buffer(pos+5) = area(l) + if(use_higher_order) then + send_buffer(pos+6) = di(l) + send_buffer(pos+7) = dj(l) + endif + if(scale_exist) send_buffer(pos+nset2) = scale(l) + pos = pos + nset2 endif - if(scale_exist) send_buffer(pos+nset2) = scale(l) - pos = pos + nset2 - endif - enddo - endif - if(grid1%tile(p) == tile1) then - do l = isc, iec - if (in_box(i1(l), j1(l), grid1%is(p), grid1%ie(p), grid1%js(p), grid1%je(p))) then - nsend1(p) = nsend1(p) + 1 - send_buffer(pos+1) = i1(l) - send_buffer(pos+2) = j1(l) - send_buffer(pos+3) = i2(l) - send_buffer(pos+4) = j2(l) - send_buffer(pos+5) = area(l) - if(use_higher_order) then - send_buffer(pos+6) = di(l) - send_buffer(pos+7) = dj(l) + enddo + endif + if(grid1%tile(p) == tile1) then + do l = isc, iec + if (in_box(i1(l), j1(l), grid1%is(p), grid1%ie(p), grid1%js(p), grid1%je(p))) then + nsend1(p) = nsend1(p) + 1 + send_buffer(pos+1) = i1(l) + send_buffer(pos+2) = j1(l) + send_buffer(pos+3) = i2(l) + send_buffer(pos+4) = j2(l) + send_buffer(pos+5) = area(l) + if(use_higher_order) then + send_buffer(pos+6) = di(l) + send_buffer(pos+7) = dj(l) + endif + pos = pos + nset1 endif - pos = pos + nset1 - endif - enddo - endif - enddo + enddo + endif + enddo + endif !--- send the size of the data on side 1 to be sent over. - allocate(ibuf1(2, 0:npes-1), ibuf2(2, 0:npes-1)) - do p = 0, npes - 1 + + do n = 0, npes-1 + p = mod(mypos+npes-n, npes) + if(.not. subset_rootpe(p)) cycle call mpp_recv( ibuf2(1,p), glen=2, from_pe=pelist(p), block=.FALSE., tag=COMM_TAG_1) enddo - do p = 0, npes-1 - ibuf1(1,p) = nsend1(p) - ibuf1(2,p) = nsend2(p) - call mpp_send( ibuf1(1, p), plen=2, to_pe=pelist(p), tag=COMM_TAG_1) - enddo + + + if(nxgrid_local_orig>0) then + do n = 0, npes-1 + p = mod(mypos+n, npes) + ibuf1(1,p) = nsend1(p) + ibuf1(2,p) = nsend2(p) + call mpp_send( ibuf1(1, p), plen=2, to_pe=pelist(p), tag=COMM_TAG_1) + enddo + endif + call mpp_clock_end(id_load_xgrid2) + call mpp_clock_begin(id_load_xgrid3) + call mpp_sync_self(check=EVENT_RECV) + call mpp_clock_end(id_load_xgrid3) + call mpp_clock_begin(id_load_xgrid4) + pos = 0 do p = 0, npes-1 + recv_buffer_pos(p) = pos nrecv1(p) = ibuf2(1,p) - nrecv2(p) = ibuf2(2,p) + nrecv2(p) = ibuf2(2,p) + pos = pos + nrecv1(p)*nset1+nrecv2(p)*nset2 enddo call mpp_sync_self() @@ -777,24 +882,27 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u nxgrid1 = sum(nrecv1) nxgrid2 = sum(nrecv2) if(nxgrid1>0 .OR. nxgrid2>0) allocate(recv_buffer(nxgrid1*nset1+nxgrid2*nset2)) - pos = 0 - do p = 0,npes-1 + do n = 0, npes-1 + p = mod(mypos+npes-n, npes) nrecv = nrecv1(p)*nset1+nrecv2(p)*nset2 if(nrecv==0) cycle + pos = recv_buffer_pos(p) call mpp_recv(recv_buffer(pos+1), glen=nrecv, from_pe=pelist(p), block=.FALSE., tag=COMM_TAG_2) - pos = pos + nrecv enddo - pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+n, npes) nsend = nsend1(p)*nset1 + nsend2(p)*nset2 if(nsend==0) cycle + pos = send_buffer_pos(p) call mpp_send( send_buffer(pos+1), plen=nsend, to_pe=pelist(p), tag=COMM_TAG_2) - pos = pos + nsend enddo call mpp_sync_self(check=EVENT_RECV) !--- unpack buffer. - deallocate(i1, j1, i2, j2, area) + if( nxgrid_local>0) then + deallocate(i1,j1,i2,j2,area) + endif + allocate(i1(nxgrid2), j1(nxgrid2)) allocate(i2(nxgrid2), j2(nxgrid2)) allocate(area(nxgrid2)) @@ -802,12 +910,12 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u allocate(i2_side1(nxgrid1), j2_side1(nxgrid1)) allocate(area_side1(nxgrid1)) if(use_higher_order) then - deallocate(di,dj) + if(nxgrid_local>0) deallocate(di,dj) allocate(di (nxgrid2), dj (nxgrid2)) allocate(di_side1(nxgrid1), dj_side1(nxgrid1)) endif if(scale_exist) then - deallocate(scale) + if(nxgrid_local>0)deallocate(scale) allocate(scale(nxgrid2)) endif pos = 0 @@ -842,11 +950,10 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u enddo enddo call mpp_sync_self() - deallocate(pelist) - deallocate(nsend1, nsend2, nrecv1, nrecv2) - deallocate(send_buffer) + if(allocated(send_buffer)) deallocate(send_buffer) if(allocated(recv_buffer)) deallocate(recv_buffer) - deallocate(ibuf1, ibuf2) + call mpp_clock_end(id_load_xgrid4) + else nxgrid1 = nxgrid nxgrid2 = nxgrid @@ -859,14 +966,18 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u endif endif + call mpp_clock_begin(id_load_xgrid5) + + size_prev = grid%size if(grid%tile_me == tile2) then do l=1,nxgrid2 if (in_box(i2(l), j2(l), grid%is_me, grid%ie_me, grid%js_me, grid%je_me) ) then grid%size = grid%size + 1 - /* exclude the area overlapped with parent grid */ - if( tile1 .NE. tile_parent .OR. .NOT. in_box(i1(l), j1(l), is_parent, ie_parent, js_parent, je_parent) ) then + ! exclude the area overlapped with parent grid + if( grid1_id .NE. "ATM" .OR. tile1 .NE. tile_parent .OR. & + .NOT. in_box(i1(l), j1(l), is_parent, ie_parent, js_parent, je_parent) ) then grid%area(i2(l),j2(l)) = grid%area(i2(l),j2(l))+area(l) endif do p=0,xmap%npes-1 @@ -929,8 +1040,31 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u end do end if + if(grid%id == xmap%grids(size(xmap%grids(:)))%id) then + last_grid = .true. + else + last_grid = .false. + endif + size_repro = 0 if(grid1%tile_me == tile1) then + if(associated(iarray)) then + nxgrid1_old = size(iarray(:)) + else + nxgrid1_old = 0 + endif + + allocate(y2m1_pe(nxgrid1)) + if(.not. last_grid ) allocate(pos_s(0:xmap%npes-1)) + y2m1_pe = -1 + if(nxgrid1_old > 0) then + do p=0,xmap%npes-1 + y2m1_size(p) = xmap%your2my1_size(p) + enddo + else + y2m1_size = 0 + endif + do l=1,nxgrid1 if (in_box(i1_side1(l), j1_side1(l), grid1%is_me, grid1%ie_me, grid1%js_me, grid1%je_me) ) then grid1%area(i1_side1(l),j1_side1(l)) = grid1%area(i1_side1(l),j1_side1(l))+area_side1(l) @@ -938,12 +1072,73 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u if (grid%tile(p) == tile2) then if (in_box(i2_side1(l), j2_side1(l), grid%is(p), grid%ie(p), grid%js(p), grid%je(p))) then xmap%your2my1(p) = .true. - end if - end if - end do + y2m1_pe(l) = p + y2m1_size(p) = y2m1_size(p) + 1 + endif + endif + enddo size_repro = size_repro + 1 - end if + endif + enddo + pos_x = 0 + do p = 1, npes-1 + pos_x(p) = pos_x(p-1) + y2m1_size(p-1) + enddo + + if(.not. last_grid) pos_s(:) = pos_x(:) + + if(nxgrid1_old > 0) then + y2m1_size(:) = xmap%your2my1_size(:) + iarray2 => iarray + jarray2 => jarray + allocate(iarray(nxgrid1+nxgrid1_old), jarray(nxgrid1+nxgrid1_old)) + ! copy the i-j index + do p=0,xmap%npes-1 + do n = 1, xmap%your2my1_size(p) + iarray(pos_x(p)+n) = iarray2(pos_s(p)+n) + jarray(pos_x(p)+n) = jarray2(pos_s(p)+n) + enddo + enddo + deallocate(iarray2, jarray2) + else + allocate(iarray(nxgrid1), jarray(nxgrid1)) + iarray(:) = 0 + jarray(:) = 0 + y2m1_size(:) = 0 + endif + + do l=1,nxgrid1 + p = y2m1_pe(l) + if(p<0) cycle + found = .false. + if(y2m1_size(p) > 0) then + pos = pos_x(p)+y2m1_size(p) + if( i1_side1(l) == iarray(pos) .AND. j1_side1(l) == jarray(pos) ) then + found = .true. + else + !---may need to replace with a fast search algorithm + do n = 1, y2m1_size(p) + pos = pos_x(p)+n + if(i1_side1(l) == iarray(pos) .AND. j1_side1(l) == jarray(pos)) then + found = .true. + exit + endif + enddo + endif + endif + if( (.NOT. found) .OR. monotonic_exchange ) then + y2m1_size(p) = y2m1_size(p)+1 + pos = pos_x(p)+y2m1_size(p) + iarray(pos) = i1_side1(l) + jarray(pos) = j1_side1(l) + endif end do + xmap%your2my1_size(:) = y2m1_size(:) + deallocate(y2m1_pe) + if(last_grid) then + deallocate(iarray, jarray) + if(allocated(pos_s)) deallocate(pos_s) + end if end if if (grid1%tile_me == tile1 .and. size_repro > 0) then @@ -990,10 +1185,10 @@ subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, u if(is_distribute) then deallocate(i1_side1, j1_side1, i2_side1, j2_side1, area_side1) if(use_higher_order) deallocate(di_side1, dj_side1) - call mpp_deallocate_domain(domain) endif i1=>NULL(); j1=>NULL(); i2=>NULL(); j2=>NULL() + call mpp_clock_end(id_load_xgrid5) @@ -1074,7 +1269,7 @@ subroutine get_grid(grid, grid_id, grid_file, grid_version) if(nlon .NE. grid%im .OR. nlat .NE. grid%jm) call error_mesg('xgrid_mod', & 'grid size in tile_file does not match the global grid size', FATAL) - if( grid_id == 'LND' .or. grid_id == 'ATM') then + if( grid_id == 'LND' .or. grid_id == 'ATM' .or. grid_id == 'WAV' ) then isc2 = 2*grid%is_me-1; iec2 = 2*grid%ie_me+1 jsc2 = 2*grid%js_me-1; jec2 = 2*grid%je_me+1 allocate(tmpx(isc2:iec2, jsc2:jec2) ) @@ -1245,8 +1440,10 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) allocate( xmap%grids(1:size(grid_ids(:))) ) allocate ( xmap%your1my2(0:xmap%npes-1), xmap%your2my1(0:xmap%npes-1) ) + allocate ( xmap%your2my1_size(0:xmap%npes-1) ) xmap%your1my2 = .false.; xmap%your2my1 = .false.; + xmap%your2my1_size = 0 ! check the exchange grid file version to be used by checking the field in the file if(field_exist(grid_file, "AREA_ATMxOCN" ) ) then @@ -1263,6 +1460,7 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) call error_mesg('xgrid_mod', 'reading exchange grid information from mosaic grid file', NOTE) end if + call mpp_clock_begin(id_load_xgrid) do g=1,size(grid_ids(:)) grid => xmap%grids(g) if (g==1) grid1 => xmap%grids(g) @@ -1341,7 +1539,7 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) grid%jm = grid%nj call mpp_max(grid%ni) call mpp_max(grid%nj) - + grid%is_me => grid%is(xmap%me-xmap%root_pe); grid%ie_me => grid%ie(xmap%me-xmap%root_pe) grid%js_me => grid%js(xmap%me-xmap%root_pe); grid%je_me => grid%je(xmap%me-xmap%root_pe) grid%nxc_me = grid%ie_me - grid%is_me + 1 @@ -1459,16 +1657,20 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) xgrid_name = 'a' case( 'LND' ) xgrid_name = 'l' + case( 'WAV' ) + xgrid_name = 'w' case default - call error_mesg('xgrid_mod', 'grid_ids(1) should be ATM or LND', FATAL) + call error_mesg('xgrid_mod', 'grid_ids(1) should be ATM, LND or WAV', FATAL) end select select case(grid_ids(g)) case( 'LND' ) xgrid_name = trim(xgrid_name)//'Xl_file' case( 'OCN' ) xgrid_name = trim(xgrid_name)//'Xo_file' + case( 'WAV' ) + xgrid_name = trim(xgrid_name)//'Xw_file' case default - call error_mesg('xgrid_mod', 'grid_ids(g) should be LND or OCN', FATAL) + call error_mesg('xgrid_mod', 'grid_ids(g) should be LND, OCN or WAV', FATAL) end select ! get the tile list for each mosaic call read_data(grid_file, lowercase(grid_ids(1))//'_mosaic_file', mosaic1) @@ -1520,6 +1722,7 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) trim(tile1_name)//' is not a tile of mosaic '//trim(mosaic1), FATAL) if(tile2 == 0) call error_mesg('xgrid_mod', & trim(tile2_name)//' is not a tile of mosaic '//trim(mosaic2), FATAL) + call load_xgrid (xmap, grid, xgrid_file, grid_ids(1), grid_ids(g), tile1, tile2, & use_higher_order) end do @@ -1533,6 +1736,8 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) end if end do + call mpp_clock_end(id_load_xgrid) + grid1%area_inv = 0.0; where (grid1%area>0.0) grid1%area_inv = 1.0/grid1%area @@ -1582,10 +1787,19 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) !--- The following will setup indx to be used in regen allocate(xmap%get1, xmap%put1) + call mpp_clock_begin(id_set_comm) + call set_comm_get1(xmap) + call set_comm_put1(xmap) + call mpp_clock_end(id_set_comm) + + call mpp_clock_begin(id_regen) call regen(xmap) + call mpp_clock_end(id_regen) + + call mpp_clock_begin(id_conservation_check) xxx = conservation_check(grid1%area*0+1.0, grid1%id, xmap) write(out_unit,* )"Checked data is array of constant 1" @@ -1616,6 +1830,7 @@ subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid) deallocate( check_data_3d) end do endif + call mpp_clock_end(id_conservation_check) call mpp_clock_end(id_setup_xmap) @@ -1729,14 +1944,16 @@ subroutine set_comm_get1(xmap) type (grid_type), pointer, save :: grid1 =>NULL() integer, allocatable :: send_size(:) integer, allocatable :: recv_size(:) - integer :: max_size, g, npes, l, ll, nset - integer :: i1, j1, tile1, p, n, pos, buffer_pos + integer :: max_size, g, npes, l, ll, nset, m + integer :: i1, j1, tile1, p, n, pos, buffer_pos, mypos integer :: nsend, nrecv, rbuf_size, sbuf_size, msgsize logical :: found real, allocatable :: recv_buf(:), send_buf(:) real, allocatable :: diarray(:), djarray(:) integer, allocatable :: iarray(:), jarray(:), tarray(:) integer, allocatable :: pos_x(:), pelist(:), size_pe(:), pe_side1(:) + integer :: recv_buffer_pos(0:xmap%npes) + integer :: send_buffer_pos(0:xmap%npes) type(comm_type), pointer, save :: comm => NULL() max_size = 0 @@ -1857,17 +2074,35 @@ subroutine set_comm_get1(xmap) enddo endif - do p = 0, npes-1 - call mpp_recv(recv_size(p), glen=1, from_pe=pelist(p), block=.false., tag=COMM_TAG_3) - enddo + + mypos = mpp_pe()-mpp_root_pe() +! do n = 0, npes-1 +! p = mod(mypos+npes-n, npes) +! call mpp_recv(recv_size(p), glen=1, from_pe=pelist(p), block=.false., tag=COMM_TAG_3) +! enddo !--- send data - do p = 0, npes-1 - call mpp_send(send_size(p), plen=1, to_pe=pelist(p), tag=COMM_TAG_3) - enddo +! do n = 0, npes-1 +! p = mod(mypos+n, npes) +! call mpp_send(send_size(p), plen=1, to_pe=pelist(p), tag=COMM_TAG_3) +! enddo + +! call mpp_sync_self(check=EVENT_RECV) +! call mpp_sync_self() + +! call mpp_sync() + +! do p = 0, npes-1 + +! if(recv_size(p) .NE. xmap%your2my1_size(p)) then +! print*, "My = ", mpp_pe(), p, recv_size(p), xmap%your2my1_size(p) +! call error_mesg("xgrid_mod", & +! "recv_size(p) .NE. xmap%your2my1_size(p)", FATAL) +! endif +! end do + + recv_size(:) = xmap%your2my1_size(:) - call mpp_sync_self(check=EVENT_RECV) - call mpp_sync_self() !--- set up for send for get_1_from_xgrid, also is recv for put_1_to_xgrid nsend = count( send_size> 0) @@ -1876,12 +2111,21 @@ subroutine set_comm_get1(xmap) allocate(comm%send(nsend)) comm%send(:)%count = 0 endif + pos = 0 - comm%sendsize = 0 do p = 0, npes-1 + send_buffer_pos(p) = pos + pos = pos + send_size(p) + enddo + + pos = 0 + comm%sendsize = 0 + do n = 0, npes-1 + p = mod(mypos+n, npes) if(send_size(p)>0) then pos = pos + 1 allocate(comm%send(pos)%i(send_size(p))) + comm%send(pos)%buffer_pos = send_buffer_pos(p) comm%send(pos)%count = send_size(p) comm%send(pos)%pe = pelist(p) comm%sendsize = comm%sendsize + send_size(p) @@ -1896,7 +2140,8 @@ subroutine set_comm_get1(xmap) if(sbuf_size>0) allocate(send_buf(sbuf_size)) pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+npes-n, npes) if(recv_size(p) ==0) cycle msgsize = recv_size(p)*nset call mpp_recv(recv_buf(pos+1), glen=msgsize, from_pe=pelist(p), block=.false., tag=COMM_TAG_4) @@ -1909,7 +2154,8 @@ subroutine set_comm_get1(xmap) enddo ll = 0 pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+n, npes) do l = 1, send_size(p) send_buf(pos+1) = iarray(pos_x(p)+l) send_buf(pos+2) = jarray(pos_x(p)+l) @@ -1923,7 +2169,8 @@ subroutine set_comm_get1(xmap) enddo pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+n, npes) if(send_size(p) ==0) cycle msgsize = send_size(p)*nset call mpp_send(send_buf(pos+1), plen=msgsize, to_pe=pelist(p), tag=COMM_TAG_4 ) @@ -1938,14 +2185,22 @@ subroutine set_comm_get1(xmap) if(nrecv >0) then allocate(comm%recv(nrecv)) comm%recv(:)%count = 0 - pos = 0 + !--- set up the buffer pos for each receiving buffer_pos = 0 - do p=0,npes-1 + do p = 0, npes-1 + recv_buffer_pos(p) = buffer_pos + buffer_pos = buffer_pos + recv_size(p) + enddo + pos = 0 + buffer_pos = 0 + do m=0,npes-1 + p = mod(mypos+npes-m, npes) if(recv_size(p)>0) then pos = pos + 1 allocate(comm%recv(pos)%i(recv_size(p))) allocate(comm%recv(pos)%j(recv_size(p))) allocate(comm%recv(pos)%tile(recv_size(p))) + comm%recv(pos)%buffer_pos = recv_buffer_pos(p) comm%recv(pos)%pe = pelist(p) comm%recv(pos)%count = recv_size(p) comm%recvsize = comm%recvsize + recv_size(p) @@ -1965,6 +2220,19 @@ subroutine set_comm_get1(xmap) enddo endif enddo + allocate(comm%unpack_ind(nrecv)) + pos = 0 + do p = 0, npes-1 + if(recv_size(p)>0) then + pos = pos + 1 + do m = 1, nrecv + if(comm%recv(m)%pe == pelist(p)) then + comm%unpack_ind(pos) = m + exit + endif + enddo + endif + enddo endif call mpp_sync_self() @@ -1986,7 +2254,7 @@ subroutine set_comm_put1(xmap) type (grid_type), pointer, save :: grid1 =>NULL() integer, allocatable :: send_size(:) integer, allocatable :: recv_size(:) - integer :: max_size, g, npes, l, ll + integer :: max_size, g, npes, l, ll, m, mypos integer :: i1, j1, tile1, p, n, pos, buffer_pos integer :: nsend, nrecv, msgsize, nset, rbuf_size, sbuf_size logical :: found @@ -1995,6 +2263,7 @@ subroutine set_comm_put1(xmap) integer, allocatable :: iarray(:), jarray(:), tarray(:) integer, allocatable :: pos_x(:), pelist(:), size_pe(:), pe_put1(:) integer :: root_pe, recvsize, sendsize + integer :: recv_buffer_pos(0:xmap%npes) type(comm_type), pointer, save :: comm => NULL() @@ -2126,12 +2395,15 @@ subroutine set_comm_put1(xmap) enddo endif - do p = 0, npes-1 + mypos = mpp_pe()-mpp_root_pe() + do n = 0, npes-1 + p = mod(mypos+npes-n, npes) call mpp_recv(recv_size(p), glen=1, from_pe=pelist(p), block=.false., tag=COMM_TAG_5) enddo !--- send data - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+n, npes) call mpp_send(send_size(p), plen=1, to_pe=pelist(p), tag=COMM_TAG_5) enddo @@ -2148,9 +2420,17 @@ subroutine set_comm_put1(xmap) pos = 0 comm%recvsize = 0 do p = 0, npes-1 + recv_buffer_pos(p) = pos + pos = pos + send_size(p) + enddo + + pos = 0 + do n = 0, npes-1 + p = mod(mypos+npes-n, npes) if(send_size(p)>0) then pos = pos + 1 allocate(comm%recv(pos)%i(send_size(p))) + comm%recv(pos)%buffer_pos = recv_buffer_pos(p) comm%recv(pos)%count = send_size(p) comm%recv(pos)%pe = pelist(p) comm%recvsize = comm%recvsize + send_size(p) @@ -2165,7 +2445,8 @@ subroutine set_comm_put1(xmap) if(sbuf_size>0) allocate(send_buf(sbuf_size)) pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+npes-n, npes) if(recv_size(p) ==0) cycle msgsize = recv_size(p)*nset call mpp_recv(recv_buf(pos+1), glen=msgsize, from_pe=pelist(p), block=.false., tag=COMM_TAG_6) @@ -2178,7 +2459,8 @@ subroutine set_comm_put1(xmap) enddo ll = 0 pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+n, npes) do l = 1, send_size(p) send_buf(pos+1) = iarray(pos_x(p)+l) send_buf(pos+2) = jarray(pos_x(p)+l) @@ -2192,7 +2474,8 @@ subroutine set_comm_put1(xmap) enddo pos = 0 - do p = 0, npes-1 + do n = 0, npes-1 + p = mod(mypos+n, npes) if(send_size(p) ==0) cycle msgsize = send_size(p)*nset call mpp_send(send_buf(pos+1), plen=msgsize, to_pe=pelist(p), tag=COMM_TAG_6 ) @@ -2209,7 +2492,8 @@ subroutine set_comm_put1(xmap) comm%send(:)%count = 0 pos = 0 buffer_pos = 0 - do p=0,npes-1 + do m=0,npes-1 + p = mod(mypos+npes-m, npes) if(recv_size(p)>0) then pos = pos + 1 allocate(comm%send(pos)%i(recv_size(p))) @@ -2341,7 +2625,8 @@ subroutine regen(xmap) tile1 = xmap%grids(g)%x(l)%tile ll = ll + 1 overlap_with_nest = .false. - if( tile1 == tile_parent .AND. in_box(i1, j1, is_parent, ie_parent, js_parent, je_parent) ) overlap_with_nest = .true. + if( xmap%grids(1)%id == "ATM" .AND. tile1 == tile_parent .AND. & + in_box(i1, j1, is_parent, ie_parent, js_parent, je_parent) ) overlap_with_nest = .true. do k=1,xmap%grids(g)%km if (xmap%grids(g)%frac_area(i2,j2,k)/=0.0) then xmap%size_put1 = xmap%size_put1+1 @@ -2797,7 +3082,7 @@ subroutine put_1_to_xgrid_order_1(d_addrs, x_addrs, xmap, isize, jsize, xsize, l integer :: i, j, p, buffer_pos, msgsize integer :: from_pe, to_pe, pos, n, l, count - integer :: ibegin, istart, iend + integer :: ibegin, istart, iend, start_pos type (comm_type), pointer, save :: comm =>NULL() real :: recv_buffer(xmap%put1%recvsize*lsize) real :: send_buffer(xmap%put1%sendsize*lsize) @@ -2811,13 +3096,12 @@ subroutine put_1_to_xgrid_order_1(d_addrs, x_addrs, xmap, isize, jsize, xsize, l call mpp_clock_begin(id_put_1_to_xgrid_order_1) !--- pre-post receiving - buffer_pos = 0 comm => xmap%put1 do p = 1, comm%nrecv msgsize = comm%recv(p)%count*lsize from_pe = comm%recv(p)%pe + buffer_pos = comm%recv(p)%buffer_pos*lsize call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = from_pe, block=.false., tag=COMM_TAG_7) - buffer_pos = buffer_pos + msgsize enddo !--- send the data @@ -2848,23 +3132,23 @@ subroutine put_1_to_xgrid_order_1(d_addrs, x_addrs, xmap, isize, jsize, xsize, l x(l) = recv_buffer(xmap%x1_put(l)%pos) end do else + start_pos = 0 do l = 1, lsize ptr_x = x_addrs(l) - pos = 0 - ibegin = 1 do p = 1, comm%nrecv count = comm%recv(p)%count + ibegin = comm%recv(p)%buffer_pos*lsize + 1 istart = ibegin + (l-1)*count iend = istart + count - 1 + pos = comm%recv(p)%buffer_pos do n = istart, iend pos = pos + 1 unpack_buffer(pos) = recv_buffer(n) enddo - ibegin = ibegin + lsize*count enddo do i=1,xmap%size_put1 x(i) = unpack_buffer(xmap%x1_put(i)%pos) - end do + end do enddo endif @@ -2904,7 +3188,7 @@ subroutine put_1_to_xgrid_order_2(d_addrs, x_addrs, xmap, isize, jsize, xsize, l pointer(ptr_d, d) pointer(ptr_x, x) - call mpp_clock_begin(id_put_1_to_xgrid_order_1) + call mpp_clock_begin(id_put_1_to_xgrid_order_2) grid1 => xmap%grids(1) is = grid1%is_me; ie = grid1%ie_me @@ -2940,10 +3224,13 @@ subroutine put_1_to_xgrid_order_2(d_addrs, x_addrs, xmap, isize, jsize, xsize, l comm => xmap%put1 do p = 1, comm%nrecv msgsize = comm%recv(p)%count*lsize - if(.NOT. monotonic_exchange) msgsize = msgsize*3 + buffer_pos = comm%recv(p)%buffer_pos*lsize + if(.NOT. monotonic_exchange) then + msgsize = msgsize*3 + buffer_pos = buffer_pos*3 + endif from_pe = comm%recv(p)%pe call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = from_pe, block=.false., tag=COMM_TAG_8) - buffer_pos = buffer_pos + msgsize enddo !--- compute d_bar_max and d_bar_min. @@ -3044,16 +3331,16 @@ subroutine put_1_to_xgrid_order_2(d_addrs, x_addrs, xmap, isize, jsize, xsize, l do l = 1, lsize ptr_x = x_addrs(l) pos = 0 - ibegin = 1 do p = 1, comm%nsend count = comm%send(p)%count + ibegin = comm%recv(p)%buffer_pos*lsize + 1 istart = ibegin + (l-1)*count iend = istart + count - 1 + pos = comm%recv(p)%buffer_pos do n = istart, iend pos = pos + 1 unpack_buffer(pos) = recv_buffer(n) enddo - ibegin = ibegin + lsize*count enddo do i=1,xmap%size_put1 pos = xmap%x1_put(i)%pos @@ -3075,13 +3362,14 @@ subroutine put_1_to_xgrid_order_2(d_addrs, x_addrs, xmap, isize, jsize, xsize, l ibegin = 1 do p = 1, comm%nrecv count = comm%recv(p)%count*3 + ibegin = comm%recv(p)%buffer_pos*lsize*3 + 1 istart = ibegin + (l-1)*count iend = istart + count - 1 + pos = comm%recv(p)%buffer_pos*3 do n = istart, iend pos = pos + 1 unpack_buffer(pos) = recv_buffer(n) enddo - ibegin = ibegin + lsize*count enddo do i=1,xmap%size_put1 pos = xmap%x1_put(i)%pos @@ -3105,7 +3393,7 @@ subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize) integer, intent(in) :: isize, jsize, xsize, lsize real, dimension(xmap%size), target :: dg(xmap%size, lsize) - integer :: i, j, l, p, n + integer :: i, j, l, p, n, m integer :: msgsize, buffer_pos, pos integer :: istart, iend, count real , pointer, save :: dgp =>NULL() @@ -3126,12 +3414,12 @@ subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize) comm => xmap%get1 grid1 => xmap%grids(1) - buffer_pos = 0 + do p = 1, comm%nrecv recv => comm%recv(p) msgsize = recv%count*lsize + buffer_pos = recv%buffer_pos*lsize call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = recv%pe, block=.false., tag=COMM_TAG_9) - buffer_pos = buffer_pos + msgsize enddo dg = 0.0; @@ -3150,6 +3438,7 @@ subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize) send => comm%send(p) msgsize = send%count*lsize pos = buffer_pos + istart = send%buffer_pos+1 iend = istart + send%count - 1 do l = 1, lsize do n = istart, iend @@ -3170,11 +3459,11 @@ subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize) d = 0 enddo !--- To bitwise reproduce old results, first copy the data onto its own pe. - pos = 0 do p = 1, comm%nrecv recv => comm%recv(p) count = recv%count + pos = recv%buffer_pos*lsize if( recv%pe == xmap%me ) then do l = 1, lsize ptr_d = d_addrs(l) @@ -3187,16 +3476,16 @@ subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize) enddo exit endif - pos = pos + count*lsize enddo pos = 0 - do p = 1, comm%nrecv + do m = 1, comm%nrecv + p = comm%unpack_ind(m) recv => comm%recv(p) if( recv%pe == xmap%me ) then - pos = pos + recv%count*lsize cycle endif + pos = recv%buffer_pos*lsize do l = 1, lsize ptr_d = d_addrs(l) do n = 1, recv%count @@ -3346,6 +3635,8 @@ function conservation_check_side1(d, grid_id, xmap,remap_method) ! this one for grid1 => xmap%grids(1) conservation_check_side1 = 0.0 if(grid1%tile_me .NE. tile_nest) conservation_check_side1(1) = sum(grid1%area*d) +! if(grid1%tile_me .NE. tile_parent .OR. grid1%id .NE. "ATM") & +! conservation_check_side1(1) = sum(grid1%area*d) call put_to_xgrid (d, grid1%id, x_over, xmap, remap_method) ! put from side 1 do g=2,size(xmap%grids(:)) @@ -3362,6 +3653,8 @@ function conservation_check_side1(d, grid_id, xmap,remap_method) ! this one for end do call get_from_xgrid(d1, grid1%id, x_back, xmap) ! get onto side 1 if(grid1%tile_me .NE. tile_nest) conservation_check_side1(3) = sum(grid1%area*d1) +! if(grid1%tile_me .NE. tile_parent .OR. grid1%id .NE. "ATM") & +! conservation_check_side1(3) = sum(grid1%area*d1) call mpp_sum(conservation_check_side1,3) end function conservation_check_side1 diff --git a/src/shared/fft/fft.F90 b/src/shared/fft/fft.F90 index b66e3e1dad..4b0a4a028f 100644 --- a/src/shared/fft/fft.F90 +++ b/src/shared/fft/fft.F90 @@ -181,7 +181,7 @@ module fft_mod ! cvs version and tag name character(len=128) :: version = '$Id: fft.F90,v 13.0 2006/03/28 21:38:54 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' !----------------------------------------------------------------------- ! diff --git a/src/shared/field_manager/field_manager.F90 b/src/shared/field_manager/field_manager.F90 index 5d078505ed..e1a7a3b111 100644 --- a/src/shared/field_manager/field_manager.F90 +++ b/src/shared/field_manager/field_manager.F90 @@ -181,8 +181,8 @@ module field_manager_mod private -character(len=128) :: version = '$Id: field_manager.F90,v 19.0 2012/01/06 21:57:10 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: field_manager.F90,v 20.0 2013/12/14 00:19:26 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -347,7 +347,7 @@ module field_manager_mod character(len=fm_string_len) :: method_type character(len=fm_string_len) :: method_name character(len=fm_string_len) :: method_control -end type method_type +end type ! NAME="method_type" ! @@ -367,7 +367,7 @@ module field_manager_mod !
                                              character(len=fm_string_len) :: method_type character(len=fm_string_len) :: method_name -end type method_type_short +end type ! NAME="method_type_short" ! @@ -382,7 +382,7 @@ module field_manager_mod ! see method_type :: method_type above. !
                                              character(len=fm_string_len) :: method_type -end type method_type_very_short +end type ! NAME="method_type_very_short" @@ -462,12 +462,12 @@ module field_manager_mod ! Private type definitions !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -type, private :: field_type +type, private :: field_mgr_type !{ character(len=fm_field_name_len) :: field_type - character(len=fm_string_len) :: field_name + character(len=fm_string_len) :: field_name integer :: model, num_methods type(method_type) :: methods(MAX_FIELD_METHODS) -end type field_type +end type field_mgr_type !} type, private :: field_names_type !{ character(len=fm_field_name_len) :: fld_type @@ -502,7 +502,7 @@ module field_manager_mod ! Private types !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -type(field_type), private :: fields(MAX_FIELDS) +type(field_mgr_type), private :: fields(MAX_FIELDS) !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -3930,7 +3930,7 @@ function fm_intersection(lists, dim) & character (len=fm_field_name_len) :: name character (len=fm_field_name_len), & dimension(:), allocatable :: names -character (len=fm_type_name_len) :: field_type_s +character (len=fm_type_name_len) :: field_type integer :: count integer :: error integer :: index @@ -4019,7 +4019,7 @@ function fm_intersection(lists, dim) & return endif !} count = 0 - do while (fm_loop_over_list(lists(1), name, field_type_s, index)) !{ + do while (fm_loop_over_list(lists(1), name, field_type, index)) !{ count = count + 1 return_p%names(count) = name enddo !} @@ -4040,7 +4040,7 @@ function fm_intersection(lists, dim) & ! occur in all of the other lists. If so, then save the name ! count = 0 -do while (fm_loop_over_list(lists(shortest), name, field_type_s, index)) !{ +do while (fm_loop_over_list(lists(shortest), name, field_type, index)) !{ found = .true. do n = 1, dim !{ if (n .ne. shortest) then !{ @@ -4093,10 +4093,10 @@ end function fm_intersection !} ! of the next field. Return false at the end of the loop. ! ! ! -function fm_loop_over_list(list, name, field_type_s, index) & +function fm_loop_over_list(list, name, field_type, index) & result (success) !{ ! ! A flag to indicate whether the function operated with (FALSE) or @@ -4108,7 +4108,7 @@ function fm_loop_over_list(list, name, field_type_s, index) & ! ! The name of a field from list. ! -! +! ! The type of a list entry. ! ! @@ -4123,7 +4123,7 @@ function fm_loop_over_list(list, name, field_type_s, index) & ! character(len=*), intent(in) :: list character(len=*), intent(out) :: name -character(len=fm_type_name_len), intent(out) :: field_type_s +character(len=fm_type_name_len), intent(out) :: field_type integer, intent(out) :: index !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -4209,12 +4209,12 @@ function set_list_stuff() & ! if (associated(loop_list_p)) then !{ name = loop_list_p%name - field_type_s = field_type_name(loop_list_p%field_type) + field_type = field_type_name(loop_list_p%field_type) index = loop_list_p%index success = .true. else !}{ name = ' ' - field_type_s = ' ' + field_type = ' ' index = 0 success = .false. loop_list = ' ' @@ -6617,7 +6617,7 @@ program test integer :: i, j, nfields, num_methods, model -character(len=fm_string_len) :: field_name, str, name_field_type, path +character(len=fm_string_len) :: field_type, field_name, str, name_field_type, path character(len=512) :: method_name, method_control real :: param integer :: flag, index diff --git a/src/shared/field_manager/field_manager.html b/src/shared/field_manager/field_manager.html deleted file mode 100644 index 42015e108c..0000000000 --- a/src/shared/field_manager/field_manager.html +++ /dev/null @@ -1,1990 +0,0 @@ - - - -Module field_manager_mod - - - - -PUBLIC INTERFACE - ~ PUBLIC DATA - - ~ PUBLIC ROUTINES - ~ ERROR MESSAGES -
                                              -

                                              Module field_manager_mod

                                              - - -
                                              -Contact:  William Cooke - -
                                              -Reviewers:  Richard D. Slater - ,  - Matthew Harrison - ,  - John P. Dunne - -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - The field manager reads entries from a field table and stores this - information along with the type of field it belongs to. This allows - the component models to query the field manager to see if non-default - methods of operation are desired. In essence the field table is a - powerful type of namelist. Default values can be provided for all the - fields through a namelist, individual fields can be modified through - the field table however. -

                                              - - - -
                                              - - An example of field table entries could be -
                                              "tracer","atmos_mod","sphum"/
                                              -
                                              -"tracer","atmos_mod","sf6"
                                              -"longname","sulf_hex"
                                              -"advection_scheme_horiz","2nd_order"
                                              -"Profile_type","Fixed","surface_value = 0.0E+00"/
                                              -
                                              -"prog_tracers","ocean_mod","age_global"
                                              -horizontal-advection-scheme = mdfl_sweby
                                              -vertical-advection-scheme = mdfl_sweby
                                              -restart_file = ocean_age.res.nc
                                              - - The field table consists of entries in the following format. - - The first line of an entry should consist of three quoted strings. - - The first quoted string will tell the field manager what type of - field it is. - - The second quoted string will tell the field manager which model the - field is being applied to. - The supported types at present are -
                                                    "coupler_mod" for the coupler,
                                              -      "atmos_mod" for the atmosphere model,
                                              -      "ocean_mod" for the ocean model,
                                              -      "land_mod" for the land model, and,
                                              -      "ice_mod" for the ice model.
                                              - The third quoted string should be a unique name that can be used as a - query. - - The second and following lines of each entry are called methods in - this context. Methods can be developed within any module and these - modules can query the field manager to find any methods that are - supplied in the field table. - - These lines can be coded quite flexibly. - - The line can consist of two or three quoted strings or a simple unquoted - string. - - If the line consists two or three quoted strings, then the first string will - be an identifier that the querying module will ask for. - - The second string will be a name that the querying module can use to - set up values for the module. - - The third string, if present, can supply parameters to the calling module that can be - parsed and used to further modify values. - - If the line consists of a simple unquoted string then quotes are not allowed - in any part of the line. - - An entry is ended with a backslash (/) as the final character in a - row. - - Comments can be inserted in the field table by having a # as the - first character in the line. - - In the example above we have three field entries. - - The first is a simple declaration of a tracer called "sphum". - - The second is for a tracer called "sf6". In this case a field named - "longname" will be given the value "sulf_hex". A field named - "advection_scheme_horiz" will be given the value "2nd_order". Finally a field - name "Profile_type" will be given a child field called "Fixed", and that field - will be given a field called "surface_value" with a real value of 0.0E+00. - - The third entry is an example of a oceanic age tracer. Note that the - method lines are formatted differently here. This is the flexibility mentioned - above. - - With these formats, a number of restrictions are required. - - The following formats are equally valid. -
                                                    "longname","sulf_hex"
                                              -      "longname = sulf_hex"
                                              -      longname = sulf_hex
                                              - However the following is not valid. -
                                                    longname = "sulf_hex"
                                              - - In the SF6 example above the last line of the entry could be written in the - following ways. -
                                                    "Profile_type","Fixed","surface_value = 0.0E+00"/
                                              -      Profile_type/Fixed/surface_value = 0.0E+00/
                                              - - Values supplied with fields are converted to the various types with the - following assumptions. -
                                               Real values : These values contain a decimal point or are in exponential format.
                                              -    These values only support e or E format for exponentials.
                                              -    e.g. 10.0, 1e10 and 1E10 are considered to be real numbers.
                                              -
                                              - Integer values : These values only contain numbers. 
                                              -    e.g 10 is an integer. 10.0 and 1e10 are not.
                                              -
                                              - Logical values : These values are supplied as one of the following formats.
                                              -    T, .T., TRUE, .TRUE.
                                              -    t, .t., true, .true.
                                              -    F, .F., FALSE, .FALSE.
                                              -    f, .f., false, .false.
                                              -    These will be converted to T or F in a dump of the field.
                                              -
                                              - Character strings : These values are assumed to be strings if a character 
                                              -    other than an e (or E) is in the value. Numbers can be suppled in the value.
                                              -    If the value does not meet the criteria for a real, integer or logical type,
                                              -    it is assumed to be a character type.
                                              - The entries within the field table can be designed by the individual - authors of code to allow modification of their routines. - -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                                 mpp_mod
                                              mpp_io_mod
                                              fms_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -field_manager_init:
                                              -
                                              - Routine to initialize the field manager. -
                                              -
                                              -field_manager_end:
                                              -
                                              - Destructor for field manager. -
                                              -
                                              -strip_front_blanks:
                                              -
                                              - A routine to strip whitespace from the start of character strings. -
                                              -
                                              -find_field_index:
                                              -
                                              - Function to return the index of the field. -
                                              -
                                              -get_field_info:
                                              -
                                              - This routine allows access to field information given an index. -
                                              -
                                              -get_field_method:
                                              -
                                              - A routine to get a specified method. -
                                              -
                                              -get_field_methods:
                                              -
                                              - A routine to obtain all the methods associated with a field. -
                                              -
                                              -parse:
                                              -
                                              - A function to parse an integer or an array of integers, - a real or an array of reals, a string or an array of strings. -
                                              -
                                              -fm_change_list:
                                              -
                                              - Change the current list. Return true on success, - false otherwise -
                                              -
                                              -fm_change_root:
                                              -
                                              - Change the root list -
                                              -
                                              -fm_dump_list:
                                              -
                                              - A function to list properties associated with a field. -
                                              -
                                              -fm_exists:
                                              -
                                              - A function to test whether a named field exists. -
                                              -
                                              -fm_get_index:
                                              -
                                              - A function to return the index of a named field. -
                                              -
                                              -fm_get_current_list:
                                              -
                                              - A function to return the full path of the current list. -
                                              -
                                              -fm_get_length:
                                              -
                                              - A function to return how many elements are contained within the named - list or entry. -
                                              -
                                              -fm_get_type:
                                              -
                                              - A function to return the type of the named field. -
                                              -
                                              -fm_get_value:
                                              -
                                              - An overloaded function to find and extract a value for a named field. -
                                              -
                                              -fm_intersection:
                                              -
                                              - A function to find the common names of the sub-fields in a list - of fields. -
                                              -
                                              -fm_loop_over_list:
                                              -
                                              - A function for looping over a list. -
                                              -
                                              -fm_new_list:
                                              -
                                              - A function to create a new list. -
                                              -
                                              -fm_new_value:
                                              -
                                              - An overloaded function to assign a value to a field. -
                                              -
                                              -fm_reset_loop:
                                              -
                                              - Resets the loop variable. For use in conjunction with fm_loop_over_list. -
                                              -
                                              -fm_return_root:
                                              -
                                              - Return the root list to the value at initialization -
                                              -
                                              -fm_modify_name:
                                              -
                                              - This function allows a user to rename a field without modifying the - contents of the field. -
                                              -
                                              -fm_query_method:
                                              -
                                              - This is a function that provides the capability to return parameters - associated with a field in a pair of strings. -
                                              -
                                              -fm_copy_list:
                                              -
                                              - A function that allows the user to copy a field and add a suffix to - the name of the new field. -
                                              -
                                              -fm_find_methods:
                                              -
                                              - This function retrieves all the methods associated with a field. -
                                              -
                                              -fm_set_verbosity:
                                              -
                                              - A subroutine to set the verbosity of the field manager output. -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC DATA

                                              - -
                                              - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                              Name Type Value Units Description
                                              fm_field_name_len integer, parameter 48 --- - The length of a character string representing the field name. -
                                              fm_path_name_len integer, parameter 512 --- - The length of a character string representing the field path. -
                                              fm_string_len integer, parameter 128 --- - The length of a character string representing character values for the field. -
                                              fm_type_name_len integer, parameter 8 --- - The length of a character string representing the various types that the values of the field can take. -
                                              NUM_MODELS integer, parameter 5 --- - Number of models (ATMOS, OCEAN, LAND, ICE, COUPLER). -
                                              NO_FIELD integer, parameter -1 --- - The value returned if a field is not defined. -
                                              MODEL_ATMOS integer, parameter 1 --- - Atmospheric model. -
                                              MODEL_OCEAN integer, parameter 2 --- - Ocean model. -
                                              MODEL_LAND integer, parameter 3 --- - Land model. -
                                              MODEL_ICE integer, parameter 4 --- - Ice model. -
                                              MODEL_COUPLER integer, parameter 5 --- - Ice model. -
                                              MODEL_NAMES character(len=11), parameter --- --- - Model names, e.g. MODEL_NAMES(MODEL_OCEAN) is 'oceanic' -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                field_manager_init

                                                -
                                                -call field_manager_init (nfields, table_name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This routine reads from a file containing formatted strings. - These formatted strings contain information on which schemes are - needed within various modules. The field manager does not - initialize any of those schemes however. It simply holds the - information and is queried by the appropriate module. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                table_name    - The name of the field table. The default name is field_table. -
                                                   [character, optional, dimension(len=128)] [Default: field_table]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                nfields    - The number of fields. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              3. - -

                                                field_manager_end

                                                -
                                                -call field_manager_end 
                                                -
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This subroutine writes to the logfile that the user is exiting field_manager and - changes the initialized flag to false. -
                                                -
                                                -
                                                -
                                                -
                                              4. -
                                              5. - -

                                                strip_front_blanks

                                                -
                                                -call strip_front_blanks (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This subroutine removes spaces and tabs from the start of a character string. -
                                                -
                                                -
                                                -
                                                -
                                              6. -
                                              7. - -

                                                find_field_index

                                                -
                                                value= find_field_index ( model, field_name ) value=find_field_index( field_name )
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function when passed a model number and a field name will - return the index of the field within the field manager. This index - can be used to access other information from the field manager. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                model    - The number indicating which model is used. -
                                                   [integer]
                                                field_name    - The name of the field that an index is being requested for. -
                                                   [character]
                                                field_name    - The path to the name of the field that an index is being requested for. -
                                                   [character]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - -
                                                find_field_index    - The index of the field corresponding to field_name. -
                                                   [integer]
                                                find_field_index    - The index of the field corresponding to field_name. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              8. -
                                              9. - -

                                                get_field_info

                                                -
                                                -call get_field_info ( n,fld_type,fld_name,model,num_methods )
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - When passed an index, this routine will return the type of field, - the name of the field, the model which the field is associated and - the number of methods associated with the field. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                n    - The field index. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - - - - - - - -
                                                fld_type    - The field type. -
                                                   [character, dimension(*)]
                                                fld_name    - The name of the field. -
                                                   [character, dimension(*)]
                                                model    - The number indicating which model is used. -
                                                   [integer]
                                                num_methods    - The number of methods. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              10. -
                                              11. - -

                                                get_field_method

                                                -
                                                -call get_field_method ( n,m,method )
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This routine, when passed a field index and a method index will - return the method text associated with the field(n) method(m). -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                n    - The field index. -
                                                   [integer]
                                                m    - The method index. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                method    - The m-th method of field with index n. -
                                                   [type(method_type)]
                                                -
                                                -
                                                -
                                                -
                                              12. -
                                              13. - -

                                                get_field_methods

                                                -
                                                -call get_field_methods ( n,methods )
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - When passed a field index, this routine will return the text - associated with all the methods attached to the field. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                n    - The field index. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                method    - An array of methods for field with index n. -
                                                   [type(method_type), dimension(:)]
                                                -
                                                -
                                                -
                                                -
                                              14. -
                                              15. - -

                                                parse

                                                -
                                                number = parse (text, label, value)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Parse is an integer function that decodes values from a text string. - The text string has the form: "label=list" where "label" is an - arbitrary user defined label describing the values being decoded, - and "list" is a list of one or more values separated by commas. - The values may be integer, real, or character. - Parse returns the number of values decoded. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                text    - The text string from which the values will be parsed. -
                                                   [character(len=*)]
                                                label    - A label which describes the values being decoded. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - -
                                                value    - The value or values that have been decoded. -
                                                   [integer, real, character(len=*)]
                                                parse    - The number of values that have been decoded. This allows - a user to define a large array and fill it partially with - values from a list. This should be the size of the value array. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              16. -
                                              17. - -

                                                fm_change_list

                                                -
                                                success = fm_change_list (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function changes the currect list to correspond to the list named name. - If the first character of name is the list separator (/) then the list will - search for "name" starting from the root of the field tree. Otherwise it - will search for name starting from the current list. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of a list that the user wishes to change to. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                -
                                                -
                                                -
                                                -
                                              18. -
                                              19. - -

                                                fm_change_root

                                                -
                                                success = fm_change_root (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function changes the root of the field tree to correspond to the - field named name. An example of a use of this would be if code is - interested in a subset of fields with a common base. This common base - could be set using fm_change_root and fields could be referenced using - this root. - - This function should be used in conjunction with fm_return_root. - -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of the field which the user wishes to become the root. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                -
                                                -
                                                -
                                                -
                                              20. -
                                              21. - -

                                                fm_dump_list

                                                -
                                                success = fm_dump_list (name, recursive = .true.)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function writes the contents of the field named "name" to stdout. - If recursive is present and .true., then this function writes out the - contents of any subfields associated with the field named "name". -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                name    - The name of the field for which output is requested. -
                                                   [character(len=*)]
                                                recursive    - If present and .true., then a recursive listing of fields will be - performed. -
                                                   [logical, optional]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                -
                                                -
                                                -
                                                -
                                              22. -
                                              23. - -

                                                fm_exists

                                                -
                                                success = fm_exists (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function determines is a field exists, relative to the current list, - and returns true if the list exists, false otherwise. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of the field that is being queried. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                -
                                                -
                                                -
                                                -
                                              24. -
                                              25. - -

                                                fm_get_index

                                                -
                                                index = fm_get_index (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Returns the index for name, returns the parameter NO_FIELD if it does not - exist. If the first character of the named field is the list peparator, - then the named field will be relative to the root of the field tree. - Otherwise the named field will be relative to the current list. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of a field that the user wishes to get an index for. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                index    - The index of the named field if it exists. - Otherwise the parameter NO_FIELD. -
                                                   [index]
                                                -
                                                -
                                                -
                                                -
                                              26. -
                                              27. - -

                                                fm_get_current_list

                                                -
                                                path = fm_get_current_list ()
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function returns the full path for the current list. A blank - path indicates an error condition has occurred. -
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                path    - The path corresponding to the current list. -
                                                   [character(len=fm_path_name_len)]
                                                -
                                                -
                                                -
                                                -
                                              28. -
                                              29. - -

                                                fm_get_length

                                                -
                                                length = fm_get_length (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function returns the list or entry length for the named list or entry. - If the named field or entry does not exist, a value of 0 is returned. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of a list or entry that the user wishes to get the length of. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                length    - The number of elements that the field name has. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              30. -
                                              31. - -

                                                fm_get_type

                                                -
                                                name_field_type = fm_get_type (name)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function returns the type of the field for name. - This indicates whether the named field is a "list" (has children fields), - or has values of type "integer", "real", "logical" or "string". - If it does not exist it returns a blank string. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of a field that the user wishes to find the type of. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                name_field_type    - A string containing the type of the named field. -
                                                   [character(len=8)]
                                                -
                                                -
                                                -
                                                -
                                              32. -
                                              33. - -

                                                fm_get_value

                                                -
                                                success = fm_get_value (name, value, index)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Find and extract the value for name. The value may be of type real, - integer, logical or character. If a single value from an array of values - is required, an optional index can be supplied. - Return true for success and false for failure -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                name    - The name of a field that the user wishes to get a value for. -
                                                   [character(len=*)]
                                                index    - An optional index to retrieve a single value from an array. -
                                                   [integer, optional]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                value    - The value associated with the named field. -
                                                   [integer, real, logical or character]
                                                -
                                                -
                                                -
                                                -
                                              34. -
                                              35. - -

                                                fm_intersection

                                                -
                                                return_p => fm_intersection (lists,dim)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return a pointer to an fm_array_list of the intersection - of an array of lists, ignoring the contents of the values, - but just returning the names. - Return false on the end of the intersection. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                dim    - The dimension of lists. -
                                                   [dim]
                                                lists    - A list of fields that the user wishes to find the common fields of. -
                                                   [character(len=*), dimension(dim)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                return_p    - A pointer to a list of names that are common to the fields provided in - lists. -
                                                   [type (fm_array_list_def), pointer]
                                                -
                                                -
                                                -
                                                -
                                              36. -
                                              37. - -

                                                fm_loop_over_list

                                                -
                                                success = fm_loop_over_list (list, name, field_type, index)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Loop over the list, setting the name, type and index - of the next field. Return false at the end of the loop. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                list    - The name of a list to loop over. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - - - - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                name    - The name of a field from list. -
                                                   [character(len=*)]
                                                field_type    - The type of a list entry. -
                                                   [character(len=fm_type_name_len)]
                                                index    - The index of tje field within the list. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              38. -
                                              39. - -

                                                fm_new_list

                                                -
                                                index = fm_new_list (name, create, keep)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Allocate and initialize a new list and return the index of the list. - If an error occurs return the parameter NO_FIELD. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - -
                                                name    - The name of a list that the user wishes to create. -
                                                   [character(len=*)]
                                                create    - If present and .true., create the list if it does not exist. -
                                                   [logical, optional]
                                                keep    - If present and .true., make this list the current list. -
                                                   [logical, optional]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                index    - The index of the newly created list. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              40. -
                                              41. - -

                                                fm_new_value

                                                -
                                                field_index = fm_new_value (name, value, [create], [index], [append])
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Allocate and initialize a new value and return the index. - If an error condition occurs the parameter NO_FIELD is returned. - - If the type of the field is changing (e.g. real values being transformed to - integers), then any previous values for the field are removed and replaced - by the value passed in the present call to this function. - - If append is present and .true., then index cannot be greater than 0 if - it is present. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - - - - - - - - - - -
                                                name    - The name of a field that the user wishes to create a value for. -
                                                   [character(len=*)]
                                                value    - The value that the user wishes to apply to the named field. -
                                                   [integer, real, logical, or character(len=*)]
                                                create    - If present and .true., then a value for this field will be created. -
                                                   [logical, optional]
                                                index    - The index to an array of values that the user wishes to apply a new value. -
                                                   [integer, optional]
                                                append    - If present and .true., then append the value to an array of the present - values. If present and .true., then index cannot be greater than 0. -
                                                   [logical, optional]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                field_index    - An index for the named field. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              42. -
                                              43. - -

                                                fm_reset_loop

                                                -
                                                -call fm_reset_loop 
                                                -
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Resets the loop variable. For use in conjunction with fm_loop_over_list. -
                                                -
                                                -
                                                -
                                                -
                                              44. -
                                              45. - -

                                                fm_return_root

                                                -
                                                -call fm_return_root 
                                                -
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Return the root list to the value at initialization. - For use in conjunction with fm_change_root. - - Users should use this routine before leaving their routine if they - previously used fm_change_root. -
                                                -
                                                -
                                                -
                                                -
                                              46. -
                                              47. - -

                                                fm_modify_name

                                                -
                                                success = fm_modify_name (oldname, newname)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Function to modify the name of a field. - Should be used with caution. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                oldname    - The name of a field that the user wishes to change the name of. -
                                                   [character(len=*)]
                                                newname    - The name that the user wishes to change the name of the field to. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                -
                                                -
                                                -
                                                -
                                              48. -
                                              49. - -

                                                fm_query_method

                                                -
                                                success = fm_query_method (name, method_name, method_control)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Given a name return a list of method names and control strings. - This function should return strings similar to those in the field - table if a comma delimited format is being used. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                name    - The name of a list that the user wishes to change to. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                method_name    - The name of a parameter associated with the named field. -
                                                   [character(len=*)]
                                                method_control    - The value of parameters associated with the named field. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              50. -
                                              51. - -

                                                fm_copy_list

                                                -
                                                index = fm_copy_list (list_name, suffix, create)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Given the name of a pre-existing field and a suffix, this function - will create a new field. The name of the new field will be that of - the old field with a suffix supplied by the user. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - - - - -
                                                list_name    - The name of a field that the user wishes to copy.. -
                                                   [character(len=*)]
                                                suffix    - The suffix that will be added to list_name when the field is copied. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - -
                                                index    - The index of the field that has been created by the copy. -
                                                   [integer]
                                                -
                                                -
                                                -
                                                -
                                              52. -
                                              53. - -

                                                fm_find_methods

                                                -
                                                success = fm_find_methods (list_name, methods, control )
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This function retrieves all the methods associated with a field. - This is different from fm_query_method in that this function gets all - the methods associated as opposed to 1 method. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                list_name    - The name of a list that the user wishes to find methods for. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -OUTPUT -
                                                -
                                                - - - - - - - - - - -
                                                success    - A flag to indicate whether the function operated with (FALSE) or - without (TRUE) errors. -
                                                   [logical]
                                                methods    - An array of the methods associated with list_name. -
                                                   [character(len=*)]
                                                control    - An array of the parameters associated with methods. -
                                                   [character(len=*)]
                                                -
                                                -
                                                -
                                                -
                                              54. -
                                              55. - -

                                                fm_set_verbosity

                                                -
                                                -call fm_set_verbosity (verbosity)
                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - This subroutine will set the level of verbosity in the module. - Currently, verbosity is either on (1) or off (0). However, - in the future, "on" may have more granularity. If no argument - is given, then, if verbosity is on it will be turned off, and - is off, will be turned to the default on level. - If verbosity is negative then it is turned off. - Values greater than the maximum will be set to the maximum. -
                                                -
                                                -
                                                -
                                                -INPUT -
                                                -
                                                - - - - -
                                                verbosity    - The level of verbosity required by the user. -
                                                   [integer, optional]
                                                -
                                                -
                                                -
                                                -
                                              56. -
                                              - - - -
                                              -

                                              PUBLIC TYPES

                                              -
                                              -method_type -
                                              -
                                              -
                                              -
                                              - This method_type is a way to allow a component module to alter the parameters it needs - for various tracers. In essence this is a way to modify a namelist. A namelist can supply - default parameters for all tracers. This method will allow the user to modify these - default parameters for an individual tracer. An example could be that the user wishes to - use second order advection on a tracer and also use fourth order advection on a second - tracer within the same model run. The default advection could be second order and the - field table would then indicate that the second tracer requires fourth order advection. - This would be parsed by the advection routine. - -
                                              -
                                              -
                                              -method_type :: method_type -
                                              -
                                              - - This string represents a tag that a module using this method can - key on. Typically this should contain some reference to the module - that is calling it. -
                                              -[character, dimension(128)] -
                                              -
                                              -method_type :: method_name -
                                              -
                                              - This is the name of a method which the module can parse and use - to assign different default values to a field method. -
                                              -[character, dimension(128)] -
                                              -
                                              -method_type :: method_control -
                                              -
                                              - This is the string containing parameters that the module can use - as values for a field method. These should override default - values within the module. -
                                              -[character, dimension(256)] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -method_type_short -
                                              -
                                              -
                                              -
                                              - This method_type is the same as method_type except that the - method_control string is not present. This is used when you wish to - change to a scheme within a module but do not need to pass - parameters. -
                                              -
                                              -
                                              -method_type_short :: method_type -
                                              -
                                              - see method_type :: method_type above. -
                                              -[character, dimension(128)] -
                                              -
                                              -method_type_short :: method_name -
                                              -
                                              - see method_type :: method_name above. -
                                              -[character, dimension(128)] -
                                              -
                                              -
                                              -
                                              -
                                              -
                                              -method_type_very_short -
                                              -
                                              -
                                              -
                                              - This method_type is the same as method_type except that the - method_control and method_name strings are not present. This is used - when you wish to change to a scheme within a module but do not need - to pass parameters. -
                                              -
                                              -
                                              -method_type_short :: method_type -
                                              -
                                              - see method_type :: method_type above. -
                                              -[character, dimension(128)] -
                                              -
                                              -
                                              -
                                              -
                                              - - - - -
                                              -

                                              ERROR MESSAGES

                                              - -
                                              -
                                              -
                                              -NOTE in field_manager_init -
                                              -
                                              -No field table available, so no fields are being registered. -
                                              -
                                              - The field table does not exist. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Too many fields in field table header entry. -
                                              -
                                              - There are more that 3 fields in the field table header entry. - The entry should look like - "Field_Type","Model_Type","Field_Name" - or - "Field_Type","Model_Type" -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Unterminated field in field table header entry. -
                                              -
                                              - There is an unterminated or unquoted string in the field table entry. - call mpp_error(FATAL,trim(error_header)//'Unterminated field in field_table header entry.'//trim(record)) -
                                              -
                                              -NOTE in field_manager_init -
                                              -
                                              -Creating list name = list_name. -
                                              -
                                              - A field is being created called list_name. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Could not set field list for list_name. -
                                              -
                                              - A field called list_name could not be created. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -The model name is unrecognised : model_name -
                                              -
                                              - The model name being supplied in the field entry is unrecognised. - This should be the second string in the first line of the field entry. - Recognised names are atmos_mod, ice_mod, land_mod and ocean_mod. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -max fields exceeded -
                                              -
                                              - Maximum number of fields for this module has been exceeded. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Too many fields in field entry. -
                                              -
                                              - There are more that 3 fields in the tracer entry. This is probably due - to separating the parameters entry into multiple strings. - The entry should look like - "Type","Name","Control1=XXX,Control2=YYY" - and not like - "Type","Name","Control1=XXX","Control2=YYY" -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Unterminated field in field entry. -
                                              -
                                              - There is an unterminated or unquoted string in the field table entry. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Unterminated field in field entry. -
                                              -
                                              - Bad format for field entry (comma without equals sign) -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Unterminated field in field entry. -
                                              -
                                              - Too many fields in field entry -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -Maximum number of methods for field exceeded -
                                              -
                                              - Maximum number of methods allowed for entries in the field table has been exceeded. -
                                              -
                                              -NOTE in field_manager_init -
                                              -
                                              -Field with identical name and model name duplicate found, skipping -
                                              -
                                              - The name of the field and the model name are identical. Skipping that field. -
                                              -
                                              -FATAL in field_manager_init -
                                              -
                                              -error reading field table -
                                              -
                                              - There is an error in reading the field table. -
                                              -
                                              -FATAL in get_field_info -
                                              -
                                              -invalid field index -
                                              -
                                              - The field index is invalid because it is less than 1 or greater than the - number of fields. -
                                              -
                                              -FATAL in get_field_method -
                                              -
                                              -invalid field index -
                                              -
                                              - The field index is invalid because it is less than 1 or greater than the - number of fields. -
                                              -
                                              -FATAL in get_field_method -
                                              -
                                              -invalid method index -
                                              -
                                              - The method index is invalid because it is less than 1 or greater than - the number of methods. -
                                              -
                                              -FATAL in get_field_methods -
                                              -
                                              -invalid field index -
                                              -
                                              - The field index is invalid because it is less than 1 or greater than the - number of fields. -
                                              -
                                              -FATAL in get_field_methods -
                                              -
                                              -method array too small -
                                              -
                                              - The method array is smaller than the number of methods. -
                                              -
                                              -
                                              -
                                              - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/field_manager/fm_util.F90 b/src/shared/field_manager/fm_util.F90 index 0e83b3f78d..578c1dff6b 100644 --- a/src/shared/field_manager/fm_util.F90 +++ b/src/shared/field_manager/fm_util.F90 @@ -88,7 +88,7 @@ module fm_util_mod !{ character(len=fm_path_name_len) :: save_path character(len=fm_path_name_len) :: save_name character(len=128) :: version = '$Id: fm_util.F90,v 17.0 2009/07/21 03:19:16 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: tagname = '$Name: tikal $' ! ! Interface definitions for overloaded routines diff --git a/src/shared/field_manager/fm_util.html b/src/shared/field_manager/fm_util.html deleted file mode 100644 index 084ab65853..0000000000 --- a/src/shared/field_manager/fm_util.html +++ /dev/null @@ -1,579 +0,0 @@ - - - -Module fm_util_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                              -

                                              Module fm_util_mod

                                              - - -
                                              -Contact:  Richard D. Slater - -
                                              -Reviewers:  John P. Dunne - -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - Utility routines for the field manager -

                                              - - - -
                                              - This module provides utility routines for the field manager. - Basically, it provides for error catching, reporting and - termination while interfacing with the field manager. -
                                              -
                                              - - -
                                              -

                                              OTHER MODULES USED

                                              - -
                                              -
                                              field_manager_mod
                                              fms_mod
                                              mpp_mod
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -fm_util_set_caller:
                                              -
                                              -
                                              -fm_util_reset_caller:
                                              -
                                              -
                                              -fm_util_set_good_name_list:
                                              -
                                              -
                                              -fm_util_reset_good_name_list:
                                              -
                                              -
                                              -fm_util_set_no_overwrite:
                                              -
                                              -
                                              -fm_util_reset_no_overwrite:
                                              -
                                              -
                                              -fm_util_check_for_bad_fields:
                                              -
                                              -
                                              -fm_util_get_length:
                                              -
                                              -
                                              -fm_util_get_index_string:
                                              -
                                              -
                                              -fm_util_get_index_list:
                                              -
                                              -
                                              -fm_util_get_integer_array:
                                              -
                                              -
                                              -fm_util_get_logical_array:
                                              -
                                              -
                                              -fm_util_get_real_array:
                                              -
                                              -
                                              -fm_util_get_string_array:
                                              -
                                              -
                                              -fm_util_get_integer:
                                              -
                                              -
                                              -fm_util_get_logical:
                                              -
                                              -
                                              -fm_util_get_real:
                                              -
                                              -
                                              -fm_util_get_string:
                                              -
                                              -
                                              -fm_util_set_value_integer_array:
                                              -
                                              -
                                              -fm_util_set_value_logical_array:
                                              -
                                              -
                                              -fm_util_set_value_real_array:
                                              -
                                              -
                                              -fm_util_set_value_string_array:
                                              -
                                              -
                                              -fm_util_set_value_integer:
                                              -
                                              -
                                              -fm_util_set_value_logical:
                                              -
                                              -
                                              -fm_util_set_value_real:
                                              -
                                              -
                                              -fm_util_set_value_string:
                                              -
                                              -
                                              -fm_util_start_namelist:
                                              -
                                              -
                                              -fm_util_end_namelist:
                                              -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                -
                                              1. - -

                                                fm_util_set_caller

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set the default value for the optional "caller" variable used in many of these - subroutines. If the argument is blank, then set the default to blank, otherwise - the deault will have brackets placed around the argument. - -
                                                -
                                                -
                                                -
                                                -
                                              2. -
                                              3. - -

                                                fm_util_reset_caller

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Reset the default value for the optional "caller" variable used in many of these - subroutines to blank. - -
                                                -
                                                -
                                                -
                                                -
                                              4. -
                                              5. - -

                                                fm_util_set_good_name_list

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set the default value for the optional "good_name_list" variable used in many of these - subroutines. - -
                                                -
                                                -
                                                -
                                                -
                                              6. -
                                              7. - -

                                                fm_util_reset_good_name_list

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Reset the default value for the optional "good_name_list" variable used in many of these - subroutines to the saved value. - -
                                                -
                                                -
                                                -
                                                -
                                              8. -
                                              9. - -

                                                fm_util_set_no_overwrite

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set the default value for the optional "no_overwrite" variable used in some of these - subroutines. - -
                                                -
                                                -
                                                -
                                                -
                                              10. -
                                              11. - -

                                                fm_util_reset_no_overwrite

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Reset the default value for the optional "no_overwrite" variable used in some of these - subroutines to false. - -
                                                -
                                                -
                                                -
                                                -
                                              12. -
                                              13. - -

                                                fm_util_check_for_bad_fields

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Check for unrecognized fields in a list - -
                                                -
                                                -
                                                -
                                                -
                                              14. -
                                              15. - -

                                                fm_util_get_length

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get the length of an element of the Field Manager tree -
                                                -
                                                -
                                                -
                                                -
                                              16. -
                                              17. - -

                                                fm_util_get_index_string

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get the index of an element of a string in the Field Manager tree -
                                                -
                                                -
                                                -
                                                -
                                              18. -
                                              19. - -

                                                fm_util_get_index_list

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get the length of an element of the Field Manager tree -
                                                -
                                                -
                                                -
                                                -
                                              20. -
                                              21. - -

                                                fm_util_get_integer_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get an integer value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              22. -
                                              23. - -

                                                fm_util_get_logical_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get a logical value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              24. -
                                              25. - -

                                                fm_util_get_real_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get a real value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              26. -
                                              27. - -

                                                fm_util_get_string_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get a string value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              28. -
                                              29. - -

                                                fm_util_get_integer

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get an integer value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              30. -
                                              31. - -

                                                fm_util_get_logical

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get a logical value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              32. -
                                              33. - -

                                                fm_util_get_real

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get a real value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              34. -
                                              35. - -

                                                fm_util_get_string

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Get a string value from the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              36. -
                                              37. - -

                                                fm_util_set_value_integer_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set an integer array in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              38. -
                                              39. - -

                                                fm_util_set_value_logical_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set a logical array in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              40. -
                                              41. - -

                                                fm_util_set_value_real_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set a real array in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              42. -
                                              43. - -

                                                fm_util_set_value_string_array

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set a string array in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              44. -
                                              45. - -

                                                fm_util_set_value_integer

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set an integer value in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              46. -
                                              47. - -

                                                fm_util_set_value_logical

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set a logical value in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              48. -
                                              49. - -

                                                fm_util_set_value_real

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set a real value in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              50. -
                                              51. - -

                                                fm_util_set_value_string

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Set a string value in the Field Manager tree. -
                                                -
                                                -
                                                -
                                                -
                                              52. -
                                              53. - -

                                                fm_util_start_namelist

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Start processing a namelist -
                                                -
                                                -
                                                -
                                                -
                                              54. -
                                              55. - -

                                                fm_util_end_namelist

                                                -
                                                -
                                                -DESCRIPTION -
                                                -
                                                - Finish up processing a namelist -
                                                -
                                                -
                                                -
                                                -
                                              56. -
                                              - - - - - - -
                                              -
                                              -top -
                                              - - diff --git a/src/shared/field_manager/parse.inc b/src/shared/field_manager/parse.inc index 5480ba7099..48433b0ad7 100644 --- a/src/shared/field_manager/parse.inc +++ b/src/shared/field_manager/parse.inc @@ -1,17 +1,28 @@ -integer :: parse -integer :: is, ie, id, k, last - - parse = 0 - - last = len_trim(text) - is = index( trim(text), trim(label) ) - if (is == 0) return - -! position of initial starting pointer - is = is + len_trim(label) ! move starting pointer after label - is = is + scan( text(is:last), '=' ) ! move starting pointer after "=" + character(*), parameter :: SPACE = ' ' + character(*), parameter :: DELIM = SPACE//',' + integer :: parse + integer :: is, ie, id, k + integer :: ts, last, i + + parse = 0; ts = 1; last=len_trim(text) + do + i=scan(text(ts:last),'=') ! location of the next equal sign in the input test + if (i == 0) return + ! find the last non-space character before the equal sign + do ie = ts+i-2,ts,-1 + if (scan(text(ie:ie),SPACE)==0) exit + enddo + ! find the last delimeter preceding spaces and equal sign + do is = ie,ts,-1 + if (scan(text(is:is),DELIM)>0) exit + enddo + if (trim(label)==text(is+1:ie)) exit ! from outer loop: found the label + ! for the next iteration of the loop + ts = ts+i+1 ! shift the beginning of the line + enddo + is = ts+i do k = 1, size(values(:)) ! position of ending pointer @@ -25,7 +36,7 @@ integer :: is, ie, id, k, last ! decode value ! print *, 'k,is,ie,id,last=',k,is,ie,id,last ! print *, 'DECODE: ', text(is:ie) - read ( text(is:ie), *, err=99 ) values(k) + read ( text(is:ie), *, err=99, end=99 ) values(k) parse = parse+1 ! parse is the number of values decoded if (ie == last) exit ! end of text string ... DONE @@ -33,7 +44,6 @@ integer :: is, ie, id, k, last if (is > last) exit ! end of text string ... DONE enddo return - + 99 continue - call mpp_error (FATAL,'in parse, error decoding data') - + call mpp_error (FATAL,'in parse, error decoding "'//trim(label)//'" in text "'//text//'"') diff --git a/src/shared/fms/fms.F90 b/src/shared/fms/fms.F90 index cc3a18d321..204e139d99 100644 --- a/src/shared/fms/fms.F90 +++ b/src/shared/fms/fms.F90 @@ -194,6 +194,7 @@ module fms_mod INTEGER :: badType1 INTEGER :: badType2 INTEGER :: missingVar + INTEGER :: NotInFile END TYPE nml_errors_type TYPE(nml_errors_type), SAVE :: nml_errors @@ -276,8 +277,8 @@ module fms_mod ! ---- version number ----- - character(len=128) :: version = '$Id: fms.F90,v 19.0 2012/01/06 21:57:13 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: fms.F90,v 20.0 2013/12/14 00:20:05 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. @@ -339,6 +340,7 @@ subroutine fms_init (localcomm ) #ifdef INTERNAL_FILE_NML read (input_nml_file, fms_nml, iostat=io) + ierr = check_nml_error(io,'fms_nml') #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) @@ -633,20 +635,18 @@ INTEGER FUNCTION check_nml_error(IOSTAT, NML_NAME) check_nml_error = IOSTAT ! Return on valid IOSTAT values - IF ( IOSTAT <= 0 .OR. IOSTAT == nml_errors%multipleNMLSinFile ) RETURN + IF ( IOSTAT <= 0 .OR.& + & IOSTAT == nml_errors%multipleNMLSinFile .OR.& + & IOSTAT == nml_errors%NotInFile) RETURN ! Everything else is a FATAL - IF ( mpp_pe() == mpp_root_pe() ) THEN - IF ( (IOSTAT == nml_errors%badType1 .OR. IOSTAT == nml_errors%badType2) .OR. IOSTAT == nml_errors%missingVar ) THEN - WRITE (err_str,*) 'Unknown namelist, or mistyped namelist variable in namelist ',TRIM(NML_NAME),', (IOSTAT = ',IOSTAT,')' - CALL error_mesg ('check_nml_error in fms_mod', err_str, FATAL) - CALL mpp_sync() - ELSE - WRITE (err_str,*) 'Unknown error while reading namelist ',TRIM(NML_NAME),', (IOSTAT = ',IOSTAT,')' - CALL error_mesg ('check_nml_error in fms_mod', err_str, FATAL) - CALL mpp_sync() - END IF - ELSE + IF ( (IOSTAT == nml_errors%badType1 .OR. IOSTAT == nml_errors%badType2) .OR. IOSTAT == nml_errors%missingVar ) THEN + WRITE (err_str,*) 'Unknown namelist, or mistyped namelist variable in namelist ',TRIM(NML_NAME),', (IOSTAT = ',IOSTAT,')' + CALL error_mesg ('check_nml_error in fms_mod', err_str, FATAL) + CALL mpp_sync() + ELSE + WRITE (err_str,*) 'Unknown error while reading namelist ',TRIM(NML_NAME),', (IOSTAT = ',IOSTAT,')' + CALL error_mesg ('check_nml_error in fms_mod', err_str, FATAL) CALL mpp_sync() END IF END FUNCTION check_nml_error @@ -661,7 +661,7 @@ SUBROUTINE nml_error_init ! multiple namelist records in a single file. INTEGER, PARAMETER :: unit_begin = 20, unit_end = 1024 INTEGER :: fileunit, io_stat - INTEGER, DIMENSION(4) :: nml_iostats + INTEGER, DIMENSION(5) :: nml_iostats LOGICAL :: opened ! Variables for sample namelists @@ -673,6 +673,7 @@ SUBROUTINE nml_error_init NAMELIST /badType1_nml/ i1, r1 NAMELIST /badType2_nml/ i1, r1 NAMELIST /missingVar_nml/ i2, r2 + NAMELIST /not_in_file_nml/ i2, r2 ! Initialize the sample namelist variables i1 = 1 @@ -689,7 +690,7 @@ SUBROUTINE nml_error_init IF ( .NOT.opened ) EXIT file_opened END DO file_opened -#if defined __PGI +#if defined(__PGI) || defined(_CRAYFTN) OPEN (UNIT=fileunit, FILE='_read_error.nml', IOSTAT=io_stat) #else OPEN (UNIT=fileunit, STATUS='SCRATCH', IOSTAT=io_stat) @@ -719,6 +720,10 @@ SUBROUTINE nml_error_init ! Read in missing variable/misstyped READ (UNIT=fileunit, NML=missingVar_nml, IOSTAT=nml_iostats(4)) + REWIND(UNIT=fileunit) + + ! Code for namelist not in file + READ (UNIT=fileunit, NML=not_in_file_nml, IOSTAT=nml_iostats(5)) ! Done, close file CLOSE (UNIT=fileunit) @@ -737,11 +742,12 @@ SUBROUTINE nml_error_init END IF ! Broadcast nml_errors - CALL mpp_broadcast(nml_iostats,4,mpp_root_pe()) + CALL mpp_broadcast(nml_iostats,5,mpp_root_pe()) nml_errors%multipleNMLSinFile = nml_iostats(1) nml_errors%badType1 = nml_iostats(2) nml_errors%badType2 = nml_iostats(3) nml_errors%missingVar = nml_iostats(4) + nml_errors%NotInFile = nml_iostats(5) do_nml_error_init = .FALSE. END SUBROUTINE nml_error_init diff --git a/src/shared/fms/fms_io.F90 b/src/shared/fms/fms_io.F90 index 89f3f8bc20..cee4b0f52c 100644 --- a/src/shared/fms/fms_io.F90 +++ b/src/shared/fms/fms_io.F90 @@ -84,13 +84,23 @@ module fms_io_mod ! ! set debug_mask_list (default is false) to true to print out mask_list reading from mask_table. ! +! +! Set checksum_required (default is true) to true to compare checksums stored in the attribute of a +! field against the checksum after reading in the data. This check mitigates the possibility of data +! that gets corrupted on write or read from being used in a n ongoing fashion. The checksum is across +! all the processors, so there will be only one checksum even if there are multiple-tiles in the +! grid. For the decomposed file case, the filename appearing in the message will contain tile1 +! because the message is printed out from the root pe and on root pe the tile id is tile1. +! +! Set checksum_required to false if you do not want to compare checksums. +! ! use mpp_io_mod, only: mpp_open, mpp_close, mpp_io_init, mpp_io_exit, mpp_read, mpp_write use mpp_io_mod, only: mpp_write_meta, mpp_get_info, mpp_get_atts, mpp_get_fields use mpp_io_mod, only: mpp_get_axes, mpp_get_axis_data, mpp_get_att_char, mpp_get_att_name -use mpp_io_mod, only: mpp_get_att_real_scalar +use mpp_io_mod, only: mpp_get_att_real_scalar, mpp_attribute_exist use mpp_io_mod, only: fieldtype, axistype, atttype, default_field, default_axis, default_att use mpp_io_mod, only: MPP_NETCDF, MPP_ASCII, MPP_MULTI, MPP_SINGLE, MPP_OVERWR, MPP_RDONLY use mpp_io_mod, only: MPP_IEEE32, MPP_NATIVE, MPP_DELETE, MPP_APPEND, MPP_SEQUENTIAL, MPP_DIRECT @@ -102,7 +112,7 @@ module fms_io_mod use mpp_domains_mod, only: mpp_get_io_domain use mpp_mod, only: mpp_error, FATAL, NOTE, WARNING, mpp_pe, mpp_root_pe, mpp_npes, stdlog, stdout use mpp_mod, only: mpp_broadcast, ALL_PES, mpp_chksum, mpp_get_current_pelist, mpp_npes, lowercase -use mpp_mod, only: input_nml_file +use mpp_mod, only: input_nml_file, mpp_get_current_pelist_name, uppercase use platform_mod, only: r8_kind @@ -275,6 +285,14 @@ module fms_io_mod module procedure query_initialized_id module procedure query_initialized_name module procedure query_initialized_r2d + module procedure query_initialized_r3d +end interface + +interface set_initialized + module procedure set_initialized_id + module procedure set_initialized_name + module procedure set_initialized_r2d + module procedure set_initialized_r3d end interface interface get_global_att_value @@ -297,8 +315,8 @@ module fms_io_mod character(len=32) :: pelist_name character(len=7) :: pe_name character(len=128):: error_msg +logical :: great_circle_algorithm=.FALSE. - !------ private data, pointer to current 2d domain ------ ! entrained from fms_mod. This will be deprecated in the future. type(domain2D), pointer, private :: Current_domain =>NULL() @@ -320,12 +338,13 @@ module fms_io_mod public :: get_global_att_value, get_var_att_value public :: file_exist, field_exist public :: register_restart_field, save_restart, restore_state -public :: restart_file_type, query_initialized +public :: restart_file_type, query_initialized, set_initialized public :: reset_field_name, reset_field_pointer private :: lookup_field_r, lookup_axis, unique_axes public :: set_filename_appendix, get_instance_filename public :: parse_mask_table +public :: get_great_circle_algorithm character(len=32), save :: filename_appendix = '' !--- public interface --- @@ -350,16 +369,17 @@ module fms_io_mod logical :: print_chksum = .false. logical :: show_open_namelist_file_warning = .false. logical :: debug_mask_list = .false. +logical :: checksum_required = .true. namelist /fms_io_nml/ fms_netcdf_override, fms_netcdf_restart, & threading_read, threading_write, & fileset_write, format, read_all_pe, iospec_ieee32,max_files_w,max_files_r, & read_data_bug, time_stamp_restart, print_chksum, show_open_namelist_file_warning, & - debug_mask_list + debug_mask_list, checksum_required integer :: pack_size ! = 1 for double = 2 for float -character(len=128) :: version = '$Id: fms_io.F90,v 19.0.6.1.4.1 2012/05/15 18:36:14 z1l Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: fms_io.F90,v 20.0 2013/12/14 00:20:08 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' contains @@ -406,12 +426,18 @@ subroutine fms_io_init() integer, allocatable, dimension(:) :: pelist real(DOUBLE_KIND) :: doubledata = 0 real :: realarray(4) + character(len=256) :: grd_file, filename + logical :: is_mosaic_grid + character(len=4096) :: attvalue if (module_is_initialized) return call mpp_io_init() #ifdef INTERNAL_FILE_NML - read (input_nml_file, fms_io_nml, iostat=io_status) + read (input_nml_file, fms_io_nml, iostat=io_status) + if (io_status > 0) then + call mpp_error(FATAL,'=>fms_io_init: Error reading input.nml') + endif #else call mpp_open(unit, 'input.nml',form=MPP_ASCII,action=MPP_RDONLY) read(unit,fms_io_nml,iostat=io_status) @@ -484,8 +510,43 @@ subroutine fms_io_init() enddo !---- initialize module domain2d pointer ---- nullify (Current_domain) + + !This is set here instead of at the end of the routine to prevent the read_data call below from stopping the model module_is_initialized = .TRUE. + !--- read INPUT/grid_spec.nc to decide the value of great_circle_algorithm + !--- great_circle_algorithm could be true only for mosaic grid. + great_circle_algorithm = .false. + grd_file = "INPUT/grid_spec.nc" + + is_mosaic_grid = .FALSE. + if (file_exist(grd_file)) then + if(field_exist(grd_file, 'atm_mosaic_file')) then ! coupled grid + is_mosaic_grid = .TRUE. + else if(field_exist(grd_file, "gridfiles")) then + call read_data(grd_file, "gridfiles", filename, level=1) + grd_file = 'INPUT/'//trim(filename) + is_mosaic_grid = .TRUE. + endif + endif + + if(is_mosaic_grid) then + if( get_global_att_value(grd_file, "great_circle_algorithm", attvalue) ) then + if(trim(attvalue) == "TRUE") then + great_circle_algorithm = .true. + else if(trim(attvalue) == "FALSE") then + great_circle_algorithm = .false. + else + call mpp_error(FATAL, "fms_io(fms_io_init: value of global attribute great_circle_algorithm in file"// & + trim(grd_file)//" should be TRUE of FALSE") + endif + endif + endif + + if(great_circle_algorithm .AND. (mpp_pe() == mpp_root_pe()) ) then + call mpp_error(NOTE,"fms_io_mod: great_circle algorithm will be used in the model run") + endif + end subroutine fms_io_init !
                                              @@ -1054,6 +1115,7 @@ function register_restart_field_r2d(fileObj, filename, fieldname, data, domain, integer, optional, intent(in) :: position, tile_count logical, optional, intent(in) :: mandatory character(len=*), optional, intent(in) :: longname, units + integer :: index_field integer :: register_restart_field_r2d @@ -1506,6 +1568,7 @@ subroutine save_restart(fileObj, time_stamp, directory ) ! (in) time_stamp - character format of the time of this restart file. character(len=256) :: dir character(len=256) :: restartpath ! The restart file path (dir/file). + character(len=258) :: restartpath_var ! The restart file path for the current variable character(len=80) :: restartname ! The restart file name (no dir). character(len=8) :: suffix ! A suffix (like _2) that is appended to the name of files after the first. integer :: var_sz, size_in_file ! The size in bytes of each variable and of the variables already in a file. @@ -1528,11 +1591,17 @@ subroutine save_restart(fileObj, time_stamp, directory ) real :: tlev character(len=10) :: axisname integer :: meta_size + type(domain2d) :: domain real, allocatable, dimension(:,:,:) :: r3d real, allocatable, dimension(:,:) :: r2d, global_r2d real, allocatable, dimension(:) :: r1d real :: r0d + integer(LONG_KIND), allocatable, dimension(:) :: check_val + character(len=256) :: checksum_char +integer :: isc, iec, jsc, jec +integer :: isg, ieg, jsg, jeg +integer :: ishift, jshift, iadd, jadd if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(save_restart): " // & "restart_file_type data must be initialized by calling register_restart_field before using it") @@ -1584,6 +1653,7 @@ subroutine save_restart(fileObj, time_stamp, directory ) do while (next_var <= fileObj%nvar ) start_var = next_var size_in_file = meta_size + restartpath_var = restartpath do j=start_var,fileObj%nvar cur_var => fileObj%var(j) var_sz = 8*cur_var%csiz(1)*cur_var%csiz(2)*cur_var%csiz(3) @@ -1608,16 +1678,16 @@ subroutine save_restart(fileObj, time_stamp, directory ) !--- remove .nc from restartpath and attach suffix. siz = len_trim(restartpath) if(restartpath(siz-2:siz) == ".nc") then - restartpath = restartpath(1:siz-3)//trim(suffix) + restartpath_var = restartpath(1:siz-3)//trim(suffix) else - restartpath = trim(restartpath) // trim(suffix) + restartpath_var = trim(restartpath) // trim(suffix) end if end if if( domain_present ) then - call mpp_open(unit,trim(restartpath),action=MPP_OVERWR,form=form,threading=thread_w,& + call mpp_open(unit,trim(restartpath_var),action=MPP_OVERWR,form=form,threading=thread_w,& fileset=fset_w, is_root_pe=fileObj%is_root_pe, domain=array_domain(fileObj%var(ind_dom)%domain_idx) ) else ! global data - call mpp_open(unit,trim(restartpath),action=MPP_OVERWR,form=form,threading=MPP_SINGLE,& + call mpp_open(unit,trim(restartpath_var),action=MPP_OVERWR,form=form,threading=MPP_SINGLE,& fileset=MPP_SINGLE, is_root_pe=fileObj%is_root_pe) end if @@ -1730,8 +1800,58 @@ subroutine save_restart(fileObj, time_stamp, directory ) var_axes(4) = t_axes end if end if + + if ( cur_var%domain_idx > 0) then + call mpp_get_compute_domain(array_domain(cur_var%domain_idx), isc, iec, jsc, jec) + call mpp_get_global_domain(array_domain(cur_var%domain_idx), isg, ieg, jsg, jeg) + call mpp_get_domain_shift(array_domain(cur_var%domain_idx), ishift, jshift, cur_var%position) + else if (ASSOCIATED(Current_domain)) then + call mpp_get_compute_domain(Current_domain, isc, iec, jsc, jec) + call mpp_get_global_domain(Current_domain, isg, ieg, jsg, jeg) + call mpp_get_domain_shift(Current_domain, ishift, jshift, cur_var%position) + else + iec = cur_var%ie + isc = cur_var%is + ieg = cur_var%ie + jec = cur_var%je + jsc = cur_var%js + jeg = cur_var%je + ishift = 0 + jshift = 0 + endif +! call return_domain(domain) + iadd = iec-isc ! Size of the i-dimension on this processor (-1 as it is an increment) + jadd = jec-jsc ! Size of the j-dimension on this processor + if(iec == ieg) iadd = iadd + ishift + if(jec == jeg) jadd = jadd + jshift + + + allocate(check_val(max(1,cur_var%siz(4)))) + do k = 1, cur_var%siz(4) + if ( Associated(fileObj%p0dr(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p0dr(k,j)%p, (/mpp_pe()/) ) + else if ( Associated(fileObj%p1dr(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p1dr(k,j)%p, (/mpp_pe()/) ) + else if ( Associated(fileObj%p2dr(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%is+iadd, cur_var%js:cur_var%js+jadd) ) + else if ( Associated(fileObj%p3dr(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%is+iadd, cur_var%js:cur_var%js+jadd, :) ) + else if ( Associated(fileObj%p0di(k,j)%p) ) then + check_val(k) = fileObj%p0di(k,j)%p + else if ( Associated(fileObj%p1di(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p1di(k,j)%p, (/mpp_pe()/) ) + else if ( Associated(fileObj%p2di(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%is+iadd, cur_var%js:cur_var%js+jadd) ) + else if ( Associated(fileObj%p3di(k,j)%p) ) then + check_val(k) = mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%is+iadd, cur_var%js:cur_var%js+jadd, :)) + else + call mpp_error(FATAL, "fms_io(save_restart): There is no pointer associated with the data of field "// & + trim(cur_var%name)//" of file "//trim(fileObj%name) ) + end if + enddo call mpp_write_meta(unit,cur_var%field, var_axes(1:num_var_axes), cur_var%name, & - cur_var%units,cur_var%longname,pack=pack_size) + cur_var%units,cur_var%longname,pack=pack_size,checksum=check_val) + deallocate(check_val) enddo ! write values for ndim of spatial axes @@ -1831,6 +1951,9 @@ subroutine write_chksum(fileObj, action) integer, intent(in) :: action integer(LONG_KIND) :: data_chksum integer :: j, k, outunit + integer :: isc, iec, jsc, jec + integer :: isg, ieg, jsg, jeg + integer :: ishift, jshift, iadd, jadd type(var_type), pointer, save :: cur_var=>NULL() character(len=32) :: routine_name @@ -1844,6 +1967,30 @@ subroutine write_chksum(fileObj, action) do j=1,fileObj%nvar cur_var => fileObj%var(j) + + if ( cur_var%domain_idx > 0) then + call mpp_get_compute_domain(array_domain(cur_var%domain_idx), isc, iec, jsc, jec) + call mpp_get_global_domain(array_domain(cur_var%domain_idx), isg, ieg, jsg, jeg) + call mpp_get_domain_shift(array_domain(cur_var%domain_idx), ishift, jshift, cur_var%position) + else if (ASSOCIATED(Current_domain)) then + call mpp_get_compute_domain(Current_domain, isc, iec, jsc, jec) + call mpp_get_global_domain(Current_domain, isg, ieg, jsg, jeg) + call mpp_get_domain_shift(Current_domain, ishift, jshift, cur_var%position) + else + iec = cur_var%ie + isc = cur_var%is + ieg = cur_var%ie + jec = cur_var%je + jsc = cur_var%js + jeg = cur_var%je + ishift = 0 + jshift = 0 + endif + iadd = iec-isc ! Size of the i-dimension on this processor (-1 as it is an increment) + jadd = jec-jsc ! Size of the j-dimension on this processor + if(iec == ieg) iadd = iadd + ishift + if(jec == jeg) jadd = jadd + jshift + if(action == MPP_OVERWR .OR. (action == MPP_RDONLY .AND. cur_var%initialized) ) then do k = 1, cur_var%siz(4) if ( Associated(fileObj%p0dr(k,j)%p) ) then @@ -1851,23 +1998,23 @@ subroutine write_chksum(fileObj, action) else if ( Associated(fileObj%p1dr(k,j)%p) ) then data_chksum = mpp_chksum(fileObj%p1dr(k,j)%p, (/mpp_pe()/) ) else if ( Associated(fileObj%p2dr(k,j)%p) ) then - data_chksum = mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%ie,cur_var%js:cur_var%je) ) + data_chksum = mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) else if ( Associated(fileObj%p3dr(k,j)%p) ) then - data_chksum = mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%ie,cur_var%js:cur_var%je, :) ) + data_chksum = mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :) ) else if ( Associated(fileObj%p0di(k,j)%p) ) then data_chksum = fileObj%p0di(k,j)%p else if ( Associated(fileObj%p1di(k,j)%p) ) then data_chksum = mpp_chksum(fileObj%p1di(k,j)%p, (/mpp_pe()/) ) else if ( Associated(fileObj%p2di(k,j)%p) ) then - data_chksum = mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%ie,cur_var%js:cur_var%je) ) + data_chksum = mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) else if ( Associated(fileObj%p3di(k,j)%p) ) then - data_chksum = mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%ie,cur_var%js:cur_var%je, :)) + data_chksum = mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :)) else call mpp_error(FATAL, "fms_io(write_chksum): There is no pointer associated with the data of field "// & trim(cur_var%name)//" of file "//trim(fileObj%name) ) end if outunit = stdout() - write(outunit,'(a, I1, a, I16)')'fms_io('//trim(routine_name)//'): At time level = ', k, ', chksum for "'// & + write(outunit,'(a, I1, a, Z16)')'fms_io('//trim(routine_name)//'): At time level = ', k, ', chksum for "'// & trim(cur_var%name)// '" of "'// trim(fileObj%name)// '" = ', data_chksum enddo @@ -1898,6 +2045,7 @@ subroutine restore_state_all(fileObj, directory) ! additional restart files. character(len=80) :: varname ! A variable's name. character(len=256) :: filename + character(len=256) :: mesg ! Message to be constructed for checksum error. integer :: num_restart ! The number of restart files that have already ! been opened. integer :: nfile ! The number of files (restart files and others @@ -1914,7 +2062,12 @@ subroutine restore_state_all(fileObj, directory) real, allocatable, dimension(:) :: r1d real :: r0d type(domain2d), pointer, save :: io_domain=>NULL() - integer :: isc, iec, jsc, jec + integer :: isc, iec, jsc, jec, check_exist + integer :: isg, ieg, jsg, jeg + integer :: ishift, jshift, iadd, jadd + integer(LONG_KIND), dimension(3) :: checksum_file + integer(LONG_KIND) :: checksum_data + logical :: is_there_a_checksum if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(restore_state_all): " // & "restart_file_type data must be initialized by calling register_restart_field before using it") @@ -1947,12 +2100,12 @@ subroutine restore_state_all(fileObj, directory) io_domain => mpp_get_io_domain(array_domain(domain_idx)) if(associated(io_domain)) then tile_id = mpp_get_tile_id(io_domain) - if(mpp_npes() > 10000) then + write(filename, '(a,i4.4)' ) trim(restartpath)//'.', tile_id(1) + inquire (file=trim(filename), exist = fexist) + if( .NOT. fexist ) then write(filename, '(a,i6.6)' ) trim(restartpath)//'.', tile_id(1) - else - write(filename, '(a,i4.4)' ) trim(restartpath)//'.', tile_id(1) + inquire (file=trim(filename), exist = fexist) endif - inquire (file=trim(filename), exist = fexist) endif io_domain => NULL() endif @@ -2011,46 +2164,91 @@ subroutine restore_state_all(fileObj, directory) do j=1,fileObj%nvar cur_var => fileObj%var(j) + domain_present = cur_var%domain_present + domain_idx = cur_var%domain_idx + + if ( cur_var%domain_idx > 0) then + call mpp_get_compute_domain(array_domain(cur_var%domain_idx), isc, iec, jsc, jec) + call mpp_get_global_domain(array_domain(cur_var%domain_idx), isg, ieg, jsg, jeg) + call mpp_get_domain_shift(array_domain(cur_var%domain_idx), ishift, jshift, cur_var%position) + else if (ASSOCIATED(Current_domain)) then + call mpp_get_compute_domain(Current_domain, isc, iec, jsc, jec) + call mpp_get_global_domain(Current_domain, isg, ieg, jsg, jeg) + call mpp_get_domain_shift(Current_domain, ishift, jshift, cur_var%position) + else + iec = cur_var%ie + isc = cur_var%is + ieg = cur_var%ie + jec = cur_var%je + jsc = cur_var%js + jeg = cur_var%je + ishift = 0 + jshift = 0 + endif + iadd = iec-isc ! Size of the i-dimension on this processor (-1 as it is an increment) + jadd = jec-jsc ! Size of the j-dimension on this processor + if(iec == ieg) iadd = iadd + ishift + if(jec == jeg) jadd = jadd + jshift + isc = cur_var%is iec = cur_var%ie jsc = cur_var%js jec = cur_var%je - domain_present = cur_var%domain_present - domain_idx = cur_var%domain_idx do l=1, nvar call mpp_get_atts(fields(l),name=varname) if (lowercase(trim(varname)) == lowercase(trim(cur_var%name))) then cur_var%initialized = .true. + check_exist = mpp_attribute_exist(fields(l),"checksum") + checksum_file = 0 + is_there_a_checksum = .false. + if ( check_exist > 0 ) then + call mpp_get_atts(fields(l),checksum=checksum_file) + is_there_a_checksum = .true. + endif + if (.NOT. checksum_required ) is_there_a_checksum = .false. ! Do not need to do data checksumming. + do k = 1, cur_var%siz(4) tlev = k if(domain_present) then if( Associated(fileObj%p0dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p0dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p0dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p1dr(k,j)%p) ) then - call mpp_read(unit(n), fields(l), fileObj%p1dr(k,j)%p, tlev) + call mpp_read(unit(n), fields(l), fileObj%p1dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p2dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), array_domain(domain_idx), fileObj%p2dr(k,j)%p, tlev) + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) else if( Associated(fileObj%p3dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), array_domain(domain_idx), fileObj%p3dr(k,j)%p, tlev) + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :) ) else if( Associated(fileObj%p0di(k,j)%p) ) then call mpp_read(unit(n), fields(l), r0d, tlev) fileObj%p0di(k,j)%p = r0d + if ( is_there_a_checksum ) checksum_data = fileObj%p0di(k,j)%p else if( Associated(fileObj%p1di(k,j)%p) ) then allocate(r1d(cur_var%siz(1))) call mpp_read(unit(n), fields(l), r1d, tlev) fileObj%p1di(k,j)%p = r1d + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1di(k,j)%p, (/mpp_pe()/) ) deallocate(r1d) else if( Associated(fileObj%p2di(k,j)%p) ) then allocate(r2d(cur_var%siz(1), cur_var%siz(2)) ) r2d = 0 call mpp_read(unit(n), fields(l), array_domain(domain_idx), r2d, tlev) fileObj%p2di(k,j)%p(isc:iec,jsc:jec) = r2d(isc:iec,jsc:jec) + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) deallocate(r2d) else if( Associated(fileObj%p3di(k,j)%p) ) then allocate(r3d(cur_var%siz(1), cur_var%siz(2), cur_var%siz(3)) ) r3d = 0 call mpp_read(unit(n), fields(l), array_domain(domain_idx), r3d, tlev) fileObj%p3di(k,j)%p(isc:iec,jsc:jec,:) = r3d(isc:iec,jsc:jec,:) + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :)) deallocate(r3d) else call mpp_error(FATAL, "fms_io(restore_state_all): domain is present for the field "//trim(varname)// & @@ -2059,37 +2257,54 @@ subroutine restore_state_all(fileObj, directory) else if( Associated(fileObj%p0dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p0dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p0dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p1dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p1dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p2dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p2dr(k,j)%p, tlev) + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) else if( Associated(fileObj%p3dr(k,j)%p) ) then - call mpp_read(unit(n), fields(l), fileObj%p3dr(k,j)%p, tlev) + call mpp_read(unit(n), fields(l), fileObj%p3dr(k,j)%p, tlev) + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :) ) else if( Associated(fileObj%p0di(k,j)%p) ) then call mpp_read(unit(n), fields(l), r0d, tlev) fileObj%p0di(k,j)%p = r0d + if ( is_there_a_checksum ) checksum_data = fileObj%p0di(k,j)%p else if( Associated(fileObj%p1di(k,j)%p) ) then allocate(r1d(cur_var%siz(1)) ) call mpp_read(unit(n), fields(l), r1d, tlev) fileObj%p1di(k,j)%p = r1d + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1di(k,j)%p, (/mpp_pe()/) ) deallocate(r1d) else if( Associated(fileObj%p2di(k,j)%p) ) then allocate(r2d(cur_var%siz(1), cur_var%siz(2)) ) r2d = 0 call mpp_read(unit(n), fields(l), r2d, tlev) fileObj%p2di(k,j)%p = r2d + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) deallocate(r2d) else if( Associated(fileObj%p3di(k,j)%p) ) then allocate(r3d(cur_var%siz(1), cur_var%siz(2), cur_var%siz(3)) ) r3d = 0 call mpp_read(unit(n), fields(l), r3d, tlev) fileObj%p3di(k,j)%p = r3d + if ( is_there_a_checksum ) & + checksum_data = mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :)) deallocate(r3d) else call mpp_error(FATAL, "fms_io(restore_state_all): There is no pointer "//& "associated with the data of field "// trim(varname)//" of file "//trim(fileObj%name) ) end if end if + if ( ( is_there_a_checksum ) .and. (checksum_file(k) /= checksum_data) ) then + write (mesg,'(a,Z16,a,Z16,a)') "Checksum of input field "// uppercase(trim(varname))//" ", checksum_data,& + " does not match value ", checksum_file(k), " stored in "//uppercase(trim(fileObj%name)//"." ) + call mpp_error(FATAL, "fms_io(restore_state_all): "//trim(mesg) ) + endif end do exit ! Start search for next restart variable. endif @@ -2142,6 +2357,7 @@ subroutine restore_state_one_field(fileObj, id_field, directory) ! additional restart files. character(len=80) :: varname ! A variable's name. character(len=256) :: filename + character(len=256) :: mesg ! Message to be constructed for checksum error. integer :: num_restart ! The number of restart files that have already ! been opened. integer :: nfile ! The number of files (restart files and others @@ -2158,8 +2374,12 @@ subroutine restore_state_one_field(fileObj, id_field, directory) real, allocatable, dimension(:) :: r1d real :: r0d type(domain2d), pointer, save :: io_domain=>NULL() - integer :: isc, iec, jsc, jec - + integer :: isc, iec, jsc, jec, check_exist + integer :: isg, ieg, jsg, jeg + integer :: ishift, jshift, iadd, jadd + integer(LONG_KIND), dimension(3) :: checksum_file ! There should be no more than 3 timelevels in a restart file. + integer(LONG_KIND) :: checksum_data + logical :: is_there_a_checksum if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(restore_state_one_field): " // & "restart_file_type data must be initialized by calling register_restart_field before using it") @@ -2170,6 +2390,29 @@ subroutine restore_state_one_field(fileObj, id_field, directory) domain_present = cur_var%domain_present domain_idx = cur_var%domain_idx + if ( cur_var%domain_idx > 0) then + call mpp_get_compute_domain(array_domain(cur_var%domain_idx), isc, iec, jsc, jec) + call mpp_get_global_domain(array_domain(cur_var%domain_idx), isg, ieg, jsg, jeg) + call mpp_get_domain_shift(array_domain(cur_var%domain_idx), ishift, jshift, cur_var%position) + else if (ASSOCIATED(Current_domain)) then + call mpp_get_compute_domain(Current_domain, isc, iec, jsc, jec) + call mpp_get_global_domain(Current_domain, isg, ieg, jsg, jeg) + call mpp_get_domain_shift(Current_domain, ishift, jshift, cur_var%position) + else + iec = cur_var%ie + isc = cur_var%is + ieg = cur_var%ie + jec = cur_var%je + jsc = cur_var%js + jeg = cur_var%je + ishift = 0 + jshift = 0 + endif + iadd = iec-isc ! Size of the i-dimension on this processor (-1 as it is an increment) + jadd = jec-jsc ! Size of the j-dimension on this processor + if(iec == ieg) iadd = iadd + ishift + if(jec == jeg) jadd = jadd + jshift + num_restart = 0 nfile = 0 if(len_trim(dir) > 0) then @@ -2184,12 +2427,12 @@ subroutine restore_state_one_field(fileObj, id_field, directory) io_domain => mpp_get_io_domain(array_domain(domain_idx)) if(associated(io_domain)) then tile_id = mpp_get_tile_id(io_domain) - if(mpp_npes()>10000) then + write(filename, '(a,i4.4)' ) trim(restartpath)//'.', tile_id(1) + inquire (file=trim(filename), exist = fexist) + if( .NOT. fexist ) then write(filename, '(a,i6.6)' ) trim(restartpath)//'.', tile_id(1) - else - write(filename, '(a,i4.4)' ) trim(restartpath)//'.', tile_id(1) + inquire (file=trim(filename), exist = fexist) endif - inquire (file=trim(filename), exist = fexist) endif io_domain=>NULL() endif @@ -2251,6 +2494,14 @@ subroutine restore_state_one_field(fileObj, id_field, directory) call mpp_get_atts(fields(l),name=varname) if (lowercase(trim(varname)) == lowercase(trim(cur_var%name))) then cur_var%initialized = .true. + check_exist = mpp_attribute_exist(fields(l),"checksum") + checksum_file = 0 + is_there_a_checksum = .false. + if ( check_exist > 0 ) then + call mpp_get_atts(fields(l),checksum=checksum_file) + is_there_a_checksum = .true. + endif + if (.NOT. checksum_required ) is_there_a_checksum = .false. ! Do not need to do data checksumming. isc = cur_var%is iec = cur_var%ie jsc = cur_var%js @@ -2260,31 +2511,43 @@ subroutine restore_state_one_field(fileObj, id_field, directory) if(domain_present) then if( Associated(fileObj%p0dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p0dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p0dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p1dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p1dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p2dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), array_domain(domain_idx), fileObj%p2dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) else if( Associated(fileObj%p3dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), array_domain(domain_idx), fileObj%p3dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :) ) else if( Associated(fileObj%p0di(k,j)%p) ) then call mpp_read(unit(n), fields(l), r0d, tlev) fileObj%p0di(k,j)%p = r0d + if ( is_there_a_checksum ) checksum_data = fileObj%p0di(k,j)%p else if( Associated(fileObj%p1di(k,j)%p) ) then allocate(r1d(cur_var%siz(1))) call mpp_read(unit(n), fields(l), r1d, tlev) fileObj%p1di(k,j)%p = r1d + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1di(k,j)%p, (/mpp_pe()/) ) deallocate(r1d) else if( Associated(fileObj%p2di(k,j)%p) ) then allocate(r2d(cur_var%siz(1), cur_var%siz(2)) ) r2d = 0 call mpp_read(unit(n), fields(l), array_domain(domain_idx), r2d, tlev) fileObj%p2di(k,j)%p(isc:iec,jsc:jec) = r2d(isc:iec,jsc:jec) + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) deallocate(r2d) else if( Associated(fileObj%p3di(k,j)%p) ) then allocate(r3d(cur_var%siz(1), cur_var%siz(2), cur_var%siz(3)) ) r3d = 0 call mpp_read(unit(n), fields(l), array_domain(domain_idx), r3d, tlev) fileObj%p3di(k,j)%p(isc:iec,jsc:jec,:) = r3d(isc:iec,jsc:jec,:) + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :)) deallocate(r3d) else call mpp_error(FATAL, "fms_io(restore_state_one_field): domain is present for the field "//trim(varname)// & @@ -2293,38 +2556,55 @@ subroutine restore_state_one_field(fileObj, id_field, directory) else if( Associated(fileObj%p0dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p0dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p0dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p1dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p1dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data = mpp_chksum(fileObj%p1dr(k,j)%p, (/mpp_pe()/) ) else if( Associated(fileObj%p2dr(k,j)%p) ) then call mpp_read(unit(n), fields(l), fileObj%p2dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p2dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) else if( Associated(fileObj%p3dr(k,j)%p) ) then - call mpp_read(unit(n), fields(l), fileObj%p3dr(k,j)%p, tlev) + call mpp_read(unit(n), fields(l), fileObj%p3dr(k,j)%p, tlev) + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p3dr(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :) ) else if( Associated(fileObj%p0di(k,j)%p) ) then call mpp_read(unit(n), fields(l), r0d, tlev) fileObj%p0di(k,j)%p = r0d + if ( is_there_a_checksum ) checksum_data = fileObj%p0di(k,j)%p else if( Associated(fileObj%p1di(k,j)%p) ) then allocate(r1d(cur_var%siz(1)) ) call mpp_read(unit(n), fields(l), r1d, tlev) fileObj%p1di(k,j)%p = r1d + if ( is_there_a_checksum ) checksum_data = fileObj%p0di(k,j)%p deallocate(r1d) else if( Associated(fileObj%p2di(k,j)%p) ) then allocate(r2d(cur_var%siz(1), cur_var%siz(2)) ) r2d = 0 call mpp_read(unit(n), fields(l), r2d, tlev) fileObj%p2di(k,j)%p = r2d + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p2di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd) ) deallocate(r2d) else if( Associated(fileObj%p3di(k,j)%p) ) then allocate(r3d(cur_var%siz(1), cur_var%siz(2), cur_var%siz(3)) ) r3d = 0 call mpp_read(unit(n), fields(l), r3d, tlev) fileObj%p3di(k,j)%p = r3d + if ( is_there_a_checksum ) checksum_data =& + & mpp_chksum(fileObj%p3di(k,j)%p(cur_var%is:cur_var%is+iadd,cur_var%js:cur_var%js+jadd, :)) deallocate(r3d) else call mpp_error(FATAL, "fms_io(restore_state_one_field): There is no pointer "// & "associated with the data of field "//trim(varname)//" of file "//trim(fileObj%name) ) end if end if - end do + if ( (is_there_a_checksum ) .and. (checksum_file(k) /= checksum_data) ) then + write (mesg,'(a,Z16,a,Z16,a)') "Checksum of input field "// uppercase(trim(varname)), checksum_data,& + " does not match value ", checksum_file(k), "stored in "//uppercase(trim(fileObj%name)//"." ) + call mpp_error(FATAL, "fms_io(restore_state_one_field): "//trim(mesg) ) + endif + end do exit ! Start search for next restart variable. endif enddo @@ -2770,14 +3050,15 @@ subroutine field_size(filename, fieldname, siz, field_found, domain, no_domain ) endif if(.not.found .AND. .not. is_no_domain) then - found_file = get_file_name(filename, actual_file, read_dist, io_domain_exist, no_domain=.true.) - !--- when is_no_domain is true and file is not found, send out error message. - if(.NOT. found_file) call mpp_error(FATAL, 'fms_io_mod(field_size): file ' //trim(filename)// & - '(with the consideration of tile number) and corresponding distributed file are not found') - call get_file_unit(actual_file, unit, nfile, read_dist, io_domain_exist, domain=domain) - call get_size(unit,fieldname,siz,found) + found_file = get_file_name(filename, actual_file, read_dist, io_domain_exist, no_domain=.true.) + if(found_file) then + call get_file_unit(actual_file, unit, nfile, read_dist, io_domain_exist, domain=domain) + call get_size(unit,fieldname,siz,found) + endif endif +! If field_found is present we assume that it is being checked on exit. +! If not present and the field was not found, exit with a FATAL error. if( PRESENT(field_found) )then field_found = found else if (.not. found )then @@ -2876,50 +3157,53 @@ end subroutine get_size ! !===================================================================================== subroutine read_data_i3d_new(filename,fieldname,data,domain,timelevel, & - no_domain,position, tile_count) + no_domain,position, tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname integer, dimension(:,:,:), intent(inout) :: data ! 3 dimensional data type(domain2d), intent(in), optional :: domain integer, intent(in), optional :: timelevel - logical, intent(in), optional :: no_domain + logical, intent(in), optional :: no_domain integer, intent(in) , optional :: position, tile_count + logical, intent(in), optional :: is_compressed real, dimension(size(data,1),size(data,2),size(data,3)) :: r_data r_data = 0 call read_data_3d_new(filename,fieldname,r_data,domain,timelevel, & - no_domain, .false., position, tile_count) + no_domain, .false., position, tile_count, is_compressed) data = CEILING(r_data) end subroutine read_data_i3d_new subroutine read_data_i2d_new(filename,fieldname,data,domain,timelevel, & - no_domain,position, tile_count) + no_domain,position, tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname integer, dimension(:,:), intent(inout) :: data ! 2 dimensional data type(domain2d), intent(in), optional :: domain integer, intent(in), optional :: timelevel logical, intent(in), optional :: no_domain integer, intent(in) , optional :: position, tile_count + logical, intent(in), optional :: is_compressed real, dimension(size(data,1),size(data,2)) :: r_data r_data = 0 call read_data_2d_new(filename,fieldname,r_data,domain,timelevel, & - no_domain, position, tile_count) + no_domain, position, tile_count, is_compressed) data = CEILING(r_data) end subroutine read_data_i2d_new !..................................................................... subroutine read_data_i1d_new(filename,fieldname,data,domain,timelevel, & - no_domain, tile_count) + no_domain, tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname integer, dimension(:), intent(inout) :: data ! 1 dimensional data type(domain2d), intent(in), optional :: domain integer, intent(in) , optional :: timelevel - logical, intent(in), optional :: no_domain + logical, intent(in), optional :: no_domain integer, intent(in), optional :: tile_count + logical, intent(in), optional :: is_compressed real, dimension(size(data,1)) :: r_data call read_data_1d_new(filename,fieldname,r_data,domain,timelevel, & - no_domain, tile_count) + no_domain, tile_count, is_compressed) data = CEILING(r_data) end subroutine read_data_i1d_new !..................................................................... @@ -2939,7 +3223,7 @@ subroutine read_data_iscalar_new(filename,fieldname,data,domain,timelevel, & end subroutine read_data_iscalar_new !===================================================================================== subroutine read_data_3d_new(filename,fieldname,data,domain,timelevel, & - no_domain, scalar_or_1d, position, tile_count, is_2d) + no_domain, scalar_or_1d, position, tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname real, dimension(:,:,:), intent(inout) :: data ! 3 dimensional data type(domain2d), target, optional, intent(in) :: domain @@ -2947,7 +3231,7 @@ subroutine read_data_3d_new(filename,fieldname,data,domain,timelevel, & logical, optional, intent(in) :: no_domain logical, optional, intent(in) :: scalar_or_1d integer, optional, intent(in) :: position, tile_count - logical, optional, intent(in) :: is_2d + logical, optional, intent(in) :: is_compressed character(len=256) :: fname integer :: unit, siz_in(4) @@ -2960,6 +3244,7 @@ subroutine read_data_3d_new(filename,fieldname,data,domain,timelevel, & integer :: ishift, jshift logical :: is_scalar_or_1d = .false. logical :: is_no_domain = .false. + logical :: compressed logical :: read_dist, io_domain_exist, found_file type(domain2d), pointer, save :: d_ptr =>NULL() type(domain2d), pointer, save :: io_domain =>NULL() @@ -2989,6 +3274,9 @@ subroutine read_data_3d_new(filename,fieldname,data,domain,timelevel, & is_scalar_or_1d = .false. if(present(scalar_or_1d)) is_scalar_or_1d = scalar_or_1d + compressed = .false. + if(present(is_compressed)) compressed = is_compressed + if(.not. PRESENT(domain) .and. .not. ASSOCIATED(Current_domain) ) is_no_domain = .true. found_file = get_file_name(filename, fname, read_dist, io_domain_exist, is_no_domain, domain, tile_count) @@ -2997,7 +3285,7 @@ subroutine read_data_3d_new(filename,fieldname,data,domain,timelevel, & call get_file_unit(fname, unit, file_index, read_dist, io_domain_exist, domain=domain) siz_in(3) = size(data,3) - if(is_no_domain .or. .NOT. associated(d_ptr) .or. is_scalar_or_1d) then + if(is_no_domain .or. .NOT. associated(d_ptr) .or. is_scalar_or_1d .or. compressed) then gxsize = size(data,1) gysize = size(data,2) else if(read_dist) then @@ -3050,7 +3338,7 @@ subroutine read_data_3d_new(filename,fieldname,data,domain,timelevel, & endif - if(is_no_domain .OR. is_scalar_or_1d) then + if(is_no_domain .OR. is_scalar_or_1d .or. compressed) then if (files_read(file_index)%var(index_field)%is_dimvar) then call mpp_get_axis_data(files_read(file_index)%var(index_field)%axis,data(:,1,1)) else @@ -3069,13 +3357,14 @@ end subroutine read_data_3d_new !===================================================================================== subroutine read_data_2d_region(filename,fieldname,data,start,nread,domain, & - no_domain, tile_count) + no_domain, tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname real, dimension(:,:), intent(inout) :: data ! 3 dimensional data integer, dimension(:), intent(in) :: start, nread type(domain2d), target, optional, intent(in) :: domain - logical, optional, intent(in) :: no_domain + logical, optional, intent(in) :: no_domain integer, optional, intent(in) :: tile_count + logical, optional, intent(in) :: is_compressed character(len=256) :: fname integer :: unit, siz_in(4) integer :: file_index ! index of the opened file in array files @@ -3161,32 +3450,39 @@ end subroutine read_data_text !.............................................................. !
                                              subroutine read_data_2d_new(filename,fieldname,data,domain,timelevel,& - no_domain,position,tile_count) + no_domain,position,tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname real, dimension(:,:), intent(inout) :: data !2 dimensional data real, dimension(size(data,1),size(data,2),1) :: data_3d type(domain2d), intent(in), optional :: domain integer, intent(in) , optional :: timelevel - logical, intent(in), optional :: no_domain + logical, intent(in), optional :: no_domain integer, intent(in) , optional :: position, tile_count + logical, intent(in), optional :: is_compressed + integer :: isc,iec,jsc,jec,isd,ied,jsd,jed - integer :: isg,ieg,jsg,jeg + integer :: isg,ieg,jsg,jeg integer :: xsize_c,ysize_c,xsize_d,ysize_d integer :: xsize_g,ysize_g, ishift, jshift + logical :: compressed !#ifdef use_CRI_pointers ! pointer( p, data_3d ) ! p = LOC(data) !#endif - call read_data_3d_new(filename,fieldname,data_3d,domain,timelevel,& - no_domain,.false., position,tile_count) + compressed= .false. + if (PRESENT(is_compressed)) compressed=is_compressed + + call read_data_3d_new(filename,fieldname,data_3d,domain,timelevel,& + no_domain,.false., position,tile_count,is_compressed=compressed) + if(PRESENT(domain)) then call mpp_get_global_domain( domain,isg,ieg,jsg,jeg,xsize=xsize_g,ysize=ysize_g, tile_count=tile_count, position=position) call mpp_get_compute_domain( domain,isc,iec,jsc,jec,xsize=xsize_c,ysize=ysize_c, tile_count=tile_count, position=position) call mpp_get_data_domain( domain,isd,ied,jsd,jed,xsize=xsize_d,ysize=ysize_d, tile_count=tile_count, position=position) call mpp_get_domain_shift (domain, ishift, jshift, position) - if((size(data,1)==xsize_c) .and. (size(data,2)==ysize_c)) then !on_comp_domain + if(((size(data,1)==xsize_c) .and. (size(data,2)==ysize_c)) .or. compressed) then !on_comp_domain data(:,:) = data_3d(:,:,1) else if((size(data,1)==xsize_d) .and. (size(data,2)==ysize_d)) then !on_data_domain data(isc-isd+1:iec-isd+1,jsc-jsd+1:jec-jsd+1) = data_3d(isc-isd+1:iec-isd+1,jsc-jsd+1:jec-jsd+1,1) @@ -3203,21 +3499,22 @@ subroutine read_data_2d_new(filename,fieldname,data,domain,timelevel,& end subroutine read_data_2d_new !..................................................................... subroutine read_data_1d_new(filename,fieldname,data,domain,timelevel,& - no_domain, tile_count) + no_domain, tile_count, is_compressed) character(len=*), intent(in) :: filename, fieldname real, dimension(:), intent(inout) :: data !1 dimensional data real, dimension(size(data,1),1,1) :: data_3d type(domain2d), intent(in), optional :: domain integer, intent(in) , optional :: timelevel - logical, intent(in), optional :: no_domain + logical, intent(in), optional :: no_domain integer, intent(in), optional :: tile_count + logical, intent(in), optional :: is_compressed #ifdef use_CRI_pointers pointer( p, data_3d ) p = LOC(data) #endif call read_data_3d_new(filename,fieldname,data_3d,domain,timelevel,& - no_domain=no_domain, scalar_or_1d=.true., tile_count=tile_count) + no_domain=no_domain, scalar_or_1d=.true., tile_count=tile_count, is_compressed=is_compressed) end subroutine read_data_1d_new !..................................................................... @@ -3231,7 +3528,7 @@ subroutine read_data_scalar_new(filename,fieldname,data,domain,timelevel,& real, dimension(1,1,1) :: data_3d type(domain2d), intent(in), optional :: domain integer, intent(in) , optional :: timelevel - logical, intent(in), optional :: no_domain + logical, intent(in), optional :: no_domain integer, intent(in), optional :: tile_count if(present(no_domain)) then @@ -3994,16 +4291,14 @@ function query_initialized_name(fileObj, name) enddo ! Assume that you are going to initialize it now, so set flag to initialized if ! queried again. - if (m<=fileObj%nvar) then - fileObj%var(m)%initialized = .true. - else if(mpp_pe() == mpp_root_pe()) then + if ((m>fileObj%nvar) .and. (mpp_pe() == mpp_root_pe())) then call mpp_error(NOTE,"fms_io(query_initialized_name): Unknown restart variable "//name// & " queried for initialization.") end if end function query_initialized_name - +!######################################################################### ! This function returns 1 if the field pointed to by f_ptr has ! initialized from a restart file, and 0 otherwise. If f_ptr is ! NULL, it tests whether the entire restart file has been success- @@ -4033,10 +4328,7 @@ function query_initialized_r2d(fileObj, f_ptr, name) enddo ! Assume that you are going to initialize it now, so set flag to initialized if ! queried again. - if (m<=fileObj%nvar) then - fileObj%var(m)%initialized = .true. - else - query_initialized_r2d = query_initialized_name(fileObj, name) + if (m>fileObj%nvar) then if (mpp_pe() == mpp_root_pe() ) call mpp_error(NOTE, "fms_io(query_initialized_r2d): Unable to find "// & trim(name)//" queried by pointer, "//"probably because of the suspect comparison of pointers by ASSOCIATED.") query_initialized_r2d = query_initialized_name(fileObj, name) @@ -4048,6 +4340,205 @@ function query_initialized_r2d(fileObj, f_ptr, name) end function query_initialized_r2d +!######################################################################### +! This function returns 1 if the field pointed to by f_ptr has +! initialized from a restart file, and 0 otherwise. If f_ptr is +! NULL, it tests whether the entire restart file has been success- +! fully read. +! +! Arguments: f_ptr - A pointer to the field that is being queried. +! (in) name - The name of the field that is being queried. +! (in) CS - The control structure returned by a previous call to +! restart_init. +function query_initialized_r3d(fileObj, f_ptr, name) + type(restart_file_type), intent(inout) :: fileObj + real, dimension(:,:,:), target, intent(in) :: f_ptr + character(len=*), intent(in) :: name + + logical :: query_initialized_r3d + integer :: m + + if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(query_initialized_r3d): " // & + "restart_file_type data must be initialized by calling register_restart_field before using it") + + query_initialized_r3d = .false. + do m=1, fileObj%nvar + if (ASSOCIATED(fileObj%p3dr(1,m)%p,f_ptr)) then + if (fileObj%var(m)%initialized) query_initialized_r3d = .true. + exit + endif + enddo + ! Assume that you are going to initialize it now, so set flag to initialized if + ! queried again. + if (m>fileObj%nvar) then + if (mpp_pe() == mpp_root_pe() ) call mpp_error(NOTE, "fms_io(query_initialized_r3d): Unable to find "// & + trim(name)//" queried by pointer, "//"probably because of the suspect comparison of pointers by ASSOCIATED.") + query_initialized_r3d = query_initialized_name(fileObj, name) + if (mpp_pe() == mpp_root_pe() .AND. query_initialized_r3d) call mpp_error(NOTE, & + "fms_io(query_initialized_r3d): "//trim(name)// " initialization confirmed by name.") + endif + + return + +end function query_initialized_r3d + + +!######################################################################### +! This function sets that a variable has been initialized for future queries. +! +! Arguments: name - A pointer to the field whose initialization status is being set. +! (in) fileObj - The control structure returned by a previous call to +! register_restart_field +subroutine set_initialized_id(fileObj, id, is_set) + type(restart_file_type), intent(inout) :: fileObj + integer , intent(in) :: id + logical, optional, intent(in) :: is_set + + logical :: set_val + integer :: m + + set_val = .true. + if (present(is_set)) set_val = is_set + + if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(set_initialized_id): " // & + "restart_file_type data must be initialized by calling set_restart_field before using it") + + if(id < 1 .OR. id > fileObj%nvar) call mpp_error(FATAL, "fms_io(set_initialized_id): " // & + "argument id must be between 1 and nvar in the restart_file_type object") + + fileObj%var(id)%initialized = set_val + + +end subroutine set_initialized_id + +!######################################################################### +! This function sets that a variable has been initialized for future queries. +! +! Arguments: name - A pointer to the field whose initialization status is being set. +! (in) fileObj - The control structure returned by a previous call to +! register_restart_field +subroutine set_initialized_name(fileObj, name, is_set) + type(restart_file_type), intent(inout) :: fileObj + character(len=*), intent(in) :: name + logical, optional, intent(in) :: is_set + + logical :: set_val + integer :: m + + set_val = .true. + if (present(is_set)) set_val = is_set + + if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(set_initialized_name): " // & + "restart_file_type data must be initialized by calling set_restart_field before using it") + + do m=1,fileObj%nvar + if (trim(name) == fileObj%var(m)%name) then + fileObj%var(m)%initialized = set_val + exit + endif + enddo + + if (m>fileObj%nvar) then + call mpp_error(NOTE,"fms_io(set_initialized_name): Unknown restart variable "//name// & + " attempted to set initialization.") + end if + +end subroutine set_initialized_name + +!######################################################################### +! This function sets that a variable has been initialized for future queries. +! +! Arguments: name - A pointer to the field whose initialization status is being set. +! (in) fileObj - The control structure returned by a previous call to +! register_restart_field +subroutine set_initialized_r2d(fileObj, f_ptr, name, is_set) + type(restart_file_type), intent(inout) :: fileObj + real, dimension(:,:), target, intent(in) :: f_ptr + character(len=*), intent(in) :: name + logical, optional, intent(in) :: is_set + logical :: set_val + integer :: m + + set_val = .true. + if (present(is_set)) set_val = is_set + + if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(set_initialized_r2d): " // & + "restart_file_type data must be initialized by calling set_restart_field before using it") + + do m=1, fileObj%nvar + if (ASSOCIATED(fileObj%p2dr(1,m)%p,f_ptr)) then + fileObj%var(m)%initialized = set_val + return + endif + enddo + + if (m>fileObj%nvar .AND. mpp_pe() == mpp_root_pe() ) then + call mpp_error(NOTE,"fms_io(set_initialized_r2d): Unable to find "// & + trim(name)//" queried by pointer, "//"probably because of the suspect comparison of pointers by ASSOCIATED"// & + " when attempting to set initialization.") + end if + + do m=1,fileObj%nvar + if (trim(name) == fileObj%var(m)%name) then + fileObj%var(m)%initialized = set_val + return + endif + enddo + + if (m>fileObj%nvar .AND. mpp_pe() == mpp_root_pe() ) then + call mpp_error(NOTE,"fms_io(set_initialized_r2d): Unknown restart variable "//name// & + " attempted to set initialization.") + end if + +end subroutine set_initialized_r2d + +!######################################################################### +! This function sets that a variable has been initialized for future queries. +! +! Arguments: name - A pointer to the field whose initialization status is being set. +! (in) fileObj - The control structure returned by a previous call to +! register_restart_field +subroutine set_initialized_r3d(fileObj, f_ptr, name, is_set) + type(restart_file_type), intent(inout) :: fileObj + real, dimension(:,:,:), target, intent(in) :: f_ptr + character(len=*), intent(in) :: name + logical, optional, intent(in) :: is_set + logical :: set_val + integer :: m + + set_val = .true. + if (present(is_set)) set_val = is_set + + if (.not.associated(fileObj%var)) call mpp_error(FATAL, "fms_io(set_initialized_r3d): " // & + "restart_file_type data must be initialized by calling set_restart_field before using it") + + do m=1, fileObj%nvar + if (ASSOCIATED(fileObj%p3dr(1,m)%p,f_ptr)) then + fileObj%var(m)%initialized = set_val + return + endif + enddo + + if (m>fileObj%nvar .AND. mpp_pe() == mpp_root_pe() ) then + call mpp_error(NOTE,"fms_io(set_initialized_r3d): Unable to find "// & + trim(name)//" queried by pointer, "//"probably because of the suspect comparison of pointers by ASSOCIATED"//& + " when attempting to set initialization.") + end if + + do m=1,fileObj%nvar + if (trim(name) == fileObj%var(m)%name) then + fileObj%var(m)%initialized = set_val + return + endif + enddo + + if (m>fileObj%nvar .AND. mpp_pe() == mpp_root_pe() ) then + call mpp_error(NOTE,"fms_io(set_initialized_r3d): Unknown restart variable "//name// & + " attempted to set initialization.") + end if + +end subroutine set_initialized_r3d + !####################################################################### !####################################################################### @@ -4082,6 +4573,9 @@ end function query_initialized_r2d function open_namelist_file (file) result (unit) character(len=*), intent(in), optional :: file integer :: unit +! local variables necessary for nesting code and alternate input.nmls + character(len=32) :: pelist_name + character(len=128) :: filename #ifdef INTERNAL_FILE_NML if(show_open_namelist_file_warning) call mpp_error(WARNING, "fms_io_mod: open_namelist_file should not be called when INTERNAL_FILE_NML is defined") @@ -4092,7 +4586,14 @@ function open_namelist_file (file) result (unit) call mpp_open ( unit, file, form=MPP_ASCII, action=MPP_RDONLY, & access=MPP_SEQUENTIAL, threading=MPP_SINGLE ) else - call mpp_open ( unit, 'input.nml', form=MPP_ASCII, action=MPP_RDONLY, & +! the following code is necessary for using alternate namelist files (nests, stretched grids, etc) + pelist_name = mpp_get_current_pelist_name() + if ( file_exist('input_'//trim(pelist_name)//'.nml') ) then + filename='input_'//trim(pelist_name)//'.nml' + else + filename='input.nml' + endif + call mpp_open ( unit, trim(filename), form=MPP_ASCII, action=MPP_RDONLY, & access=MPP_SEQUENTIAL, threading=MPP_SINGLE ) endif end function open_namelist_file @@ -4711,7 +5212,7 @@ subroutine get_var_att_value_text(file, varname, attname, attvalue) end subroutine get_var_att_value_text !############################################################################# - ! return false if the attribute is not find in the file. + ! return false if the attribute is not found in the file. function get_global_att_value_text(file, att, attvalue) character(len=*), intent(in) :: file character(len=*), intent(in) :: att @@ -4739,7 +5240,7 @@ function get_global_att_value_text(file, att, attvalue) end function get_global_att_value_text !############################################################################# - ! return false if the attribute is not find in the file. + ! return false if the attribute is not found in the file. function get_global_att_value_real(file, att, attvalue) character(len=*), intent(in) :: file character(len=*), intent(in) :: att @@ -4818,12 +5319,12 @@ function get_file_name(orig_file, actual_file, read_dist, io_domain_exist, no_do io_domain => mpp_get_io_domain(d_ptr) if(associated(io_domain)) then tile_id = mpp_get_tile_id(io_domain) - if(mpp_npes()>10000) then + write(fname, '(a,i4.4)' ) trim(actual_file)//'.', tile_id(1) + inquire (file=trim(fname), exist=fexist) + if(.not. fexist) then write(fname, '(a,i6.6)' ) trim(actual_file)//'.', tile_id(1) - else - write(fname, '(a,i4.4)' ) trim(actual_file)//'.', tile_id(1) + inquire (file=trim(fname), exist=fexist) endif - inquire (file=trim(fname), exist=fexist) if(fexist) io_domain_exist = .true. endif io_domain=>NULL() @@ -4846,9 +5347,33 @@ function get_file_name(orig_file, actual_file, read_dist, io_domain_exist, no_do endif !Perhaps the file has an ensemble instance appendix - call get_instance_filename(actual_file, actual_file) - inquire (file=trim(actual_file)//trim(pe_name), exist=fexist) - if(.not. fexist) inquire (file=trim(actual_file)//'.nc'//trim(pe_name), exist=fexist) + call get_instance_filename(orig_file, actual_file) + if(index(orig_file, '.nc', back=.true.) == 0) then + inquire (file=trim(actual_file), exist=fexist) + if(fexist) then + get_file_name = .true. + return + endif + endif + + call get_mosaic_tile_file(actual_file, actual_file, is_no_domain, domain, tile_count) + !--- check if the file is group redistribution. + if(ASSOCIATED(d_ptr)) then + io_domain => mpp_get_io_domain(d_ptr) + if(associated(io_domain)) then + tile_id = mpp_get_tile_id(io_domain) + if(mpp_npes()>10000) then + write(fname, '(a,i6.6)' ) trim(actual_file)//'.', tile_id(1) + else + write(fname, '(a,i4.4)' ) trim(actual_file)//'.', tile_id(1) + endif + inquire (file=trim(fname), exist=fexist) + if(fexist) io_domain_exist = .true. + endif + io_domain=>NULL() + endif + + if(.not. fexist) inquire (file=trim(actual_file)//trim(pe_name), exist=fexist) if(fexist) then read_dist = .true. d_ptr => NULL() @@ -4856,7 +5381,6 @@ function get_file_name(orig_file, actual_file, read_dist, io_domain_exist, no_do return endif inquire (file=trim(actual_file), exist=fexist) - if(.not. fexist) inquire (file=trim(actual_file)//'.nc', exist=fexist) if(fexist) then d_ptr => NULL() @@ -4993,8 +5517,8 @@ subroutine get_field_id(unit, index_file, fieldname, index_field, is_no_domain, do i=1,ndim call mpp_get_atts(axes(i), name=name, len = siz_in(1)) if (lowercase(trim(name)) == lowercase(trim(fieldname))) then - if(.not. is_no_domain) call mpp_error(FATAL, & - 'fms_io(get_field_id): the field is a dimension variable, no_domain should be true.') +! if(.not. is_no_domain) call mpp_error(FATAL, & +! 'fms_io(get_field_id): the field is a dimension variable, no_domain should be true.') files_read(index_file)%var(index_field)%is_dimvar = .true. files_read(index_file)%var(index_field)%name = fieldname files_read(index_file)%var(index_field)%axis = axes(i) @@ -5250,6 +5774,17 @@ subroutine parse_mask_table(mask_table, maskmap, modelname) end subroutine parse_mask_table +function get_great_circle_algorithm() + logical :: get_great_circle_algorithm + + if(.NOT. module_is_initialized) call mpp_error(FATAL, & + "fms_io(use_great_circle_algorithm): fms_io_init is not called yet") + + get_great_circle_algorithm = great_circle_algorithm + +end function get_great_circle_algorithm + + end module fms_io_mod diff --git a/src/shared/fms/test_fms_io.F90 b/src/shared/fms/test_fms_io.F90 index b02c31ec35..2c617fc542 100644 --- a/src/shared/fms/test_fms_io.F90 +++ b/src/shared/fms/test_fms_io.F90 @@ -75,13 +75,15 @@ program fms_io_test if (file_exist('input.nml') )then call mpp_open(unit, 'input.nml',form=MPP_ASCII,action=MPP_RDONLY) read(unit,test_fms_io_nml,iostat=io_status) - - if (io_status > 0) then - call mpp_error(FATAL,'=>test_fms_io: Error reading test_fms_io_nml') - endif call mpp_close (unit) end if #endif + if (io_status > 0) then + call mpp_error(FATAL,'=>test_fms_io: Error reading test_fms_io_nml') + endif + + !-- list nt maximum to be 2 to avoid integer overflow. + if(nt > 2 .OR. nt < 1) call mpp_error(FATAL,"test_fms_io: nt should be 1 or 2") outunit = stdout() write(outunit, test_fms_io_nml ) @@ -240,8 +242,8 @@ subroutine setup_test_restart(restart_data, type, ntiles, storage, file, layout_ do i = isc, iec storage%data1_r3d(i,j,k,n) = tile*1e6 + n*1e3 + k + i*1e-3 + j*1e-6; storage%data2_r3d(i,j,k,n) = -tile*1e6 - n*1e3 - k - i*1e-3 - j*1e-6; - storage%data1_i3d(i,j,k,n) = tile*1e9 + n*1e8 + k*1e6 + i*1e3 + j; - storage%data2_i3d(i,j,k,n) = -tile*1e9 - n*1e8 - k*1e6 - i*1e3 - j; + storage%data1_i3d(i,j,k,n) = (n*ntiles+tile)*1e8 + k*1e6 + i*1e3 + j; + storage%data2_i3d(i,j,k,n) = -(n*ntiles+tile)*1e8 - k*1e6 - i*1e3 - j; end do end do end do diff --git a/src/shared/horiz_interp/horiz_interp.F90 b/src/shared/horiz_interp/horiz_interp.F90 index 921c953ca1..4869a581ae 100644 --- a/src/shared/horiz_interp/horiz_interp.F90 +++ b/src/shared/horiz_interp/horiz_interp.F90 @@ -54,7 +54,10 @@ module horiz_interp_mod !----------------------------------------------------------------------- use fms_mod, only: write_version_number, fms_error_handler -use mpp_mod, only: mpp_error, FATAL, stdout, mpp_min +use fms_mod, only: file_exist, close_file +use fms_mod, only: check_nml_error, open_namelist_file +use mpp_mod, only: mpp_error, FATAL, stdout, stdlog, mpp_min +use mpp_mod, only: input_nml_file, WARNING, mpp_pe, mpp_root_pe use constants_mod, only: pi use horiz_interp_type_mod, only: horiz_interp_type, assignment(=) use horiz_interp_type_mod, only: CONSERVE, BILINEAR, SPHERICA, BICUBIC @@ -215,9 +218,25 @@ module horiz_interp_mod end interface ! + + !--- namelist interface + ! + ! + ! Set reproduce_siena = .true. to reproduce siena results. + ! Set reproduce_siena = .false. to decrease truncation error + ! in routine poly_area in file mosaic_util.c. The truncation error of + ! second order conservative remapping might be big for high resolution + ! grid. + ! + ! + + logical :: reproduce_siena = .false. + + namelist /horiz_interp_nml/ reproduce_siena + !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: horiz_interp.F90,v 19.0 2012/01/06 21:57:50 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: horiz_interp.F90,v 20.0 2013/12/14 00:20:17 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. !----------------------------------------------------------------------- @@ -233,9 +252,40 @@ module horiz_interp_mod ! subroutine horiz_interp_init + integer :: unit, ierr, io if(module_is_initialized) return call write_version_number (version, tagname) + +#ifdef INTERNAL_FILE_NML + read (input_nml_file, horiz_interp_nml, iostat=io) + ierr = check_nml_error(io,'horiz_interp_nml') +#else + if (file_exist('input.nml')) then + unit = open_namelist_file ( ) + ierr=1 + do while (ierr /= 0) + read (unit, nml=horiz_interp_nml, iostat=io, end=10) + ierr = check_nml_error(io,'horiz_interp_nml') ! also initializes nml error codes + enddo +10 call close_file (unit) + endif +#endif + if (mpp_pe() == mpp_root_pe() ) then + unit = stdlog() + write (unit, nml=horiz_interp_nml) + endif + + if( reproduce_siena ) then + if( mpp_pe() == mpp_root_pe() ) then + call mpp_error(WARNING, "horiz_interp_mod: You have overridden the default value of reproduce_siena " // & + "and set it to .true. in horiz_interp_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. ") + endif + call set_reproduce_siena_true( ) + endif + call horiz_interp_conserve_init call horiz_interp_bilinear_init call horiz_interp_bicubic_init @@ -1287,6 +1337,7 @@ program horiz_interp_test !--- read namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, test_horiz_interp_nml, iostat=io) + ierr = check_nml_error(io, 'test_horiz_interp_nml') #else if (file_exist('input.nml')) then ierr=1 diff --git a/src/shared/horiz_interp/horiz_interp_bicubic.F90 b/src/shared/horiz_interp/horiz_interp_bicubic.F90 index 30d35960bf..46285aef1e 100644 --- a/src/shared/horiz_interp/horiz_interp_bicubic.F90 +++ b/src/shared/horiz_interp/horiz_interp_bicubic.F90 @@ -42,7 +42,7 @@ module horiz_interp_bicubic_mod end interface character(len=128) :: version="$Id: horiz_interp_bicubic.F90,v 19.0 2012/01/06 21:57:52 fms Exp $" - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. integer :: verbose_bicubic = 0 diff --git a/src/shared/horiz_interp/horiz_interp_bilinear.F90 b/src/shared/horiz_interp/horiz_interp_bilinear.F90 index eda9f85cec..77278a4b7e 100644 --- a/src/shared/horiz_interp/horiz_interp_bilinear.F90 +++ b/src/shared/horiz_interp/horiz_interp_bilinear.F90 @@ -35,10 +35,11 @@ module horiz_interp_bilinear_mod real, parameter :: epsln=1.e-10 + integer, parameter :: DUMMY = -999 !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: horiz_interp_bilinear.F90,v 14.0 2007/03/15 22:39:57 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: horiz_interp_bilinear.F90,v 20.0 2013/12/14 00:20:22 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. contains @@ -263,7 +264,7 @@ end subroutine horiz_interp_bilinear_new_1d ! subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_out, & - verbose, src_modulo ) + verbose, src_modulo, new_search, no_crash_when_not_found ) !----------------------------------------------------------------------- type(horiz_interp_type), intent(inout) :: Interp @@ -271,6 +272,8 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o real, intent(in), dimension(:,:) :: lon_out, lat_out integer, intent(in), optional :: verbose logical, intent(in), optional :: src_modulo + logical, intent(in), optional :: new_search + logical, intent(in), optional :: no_crash_when_not_found integer :: warns logical :: src_is_modulo integer :: nlon_in, nlat_in, nlon_out, nlat_out @@ -279,6 +282,8 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o real :: a1, b1, c1, d1, a2, b2, c2, d2, a, b, c real :: lon1, lat1, lon2, lat2, lon3, lat3, lon4, lat4 real :: tpi, lon_min, lon_max + real :: epsln2 + logical :: use_new_search, no_crash tpi = 2.0*pi @@ -286,6 +291,10 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o if(present(verbose)) warns = verbose src_is_modulo = .true. if (present(src_modulo)) src_is_modulo = src_modulo + use_new_search = .false. + if (present(new_search)) use_new_search = new_search + no_crash = .false. + if(present(no_crash_when_not_found)) no_crash = no_crash_when_not_found ! make sure lon and lat has the same dimension if(size(lon_out,1) /= size(lat_out,1) .or. size(lon_out,2) /= size(lat_out,2) ) & @@ -308,7 +317,13 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o Interp % j_lat (size(lon_out,1),size(lon_out,2),2)) !--- first fine the neighbor points for the destination points. - call find_neighbor(Interp, lon_in, lat_in, lon_out, lat_out, src_is_modulo) + if(use_new_search) then + epsln2 = epsln*1e5 + call find_neighbor_new(Interp, lon_in, lat_in, lon_out, lat_out, src_is_modulo, no_crash) + else + epsln2 = epsln + call find_neighbor(Interp, lon_in, lat_in, lon_out, lat_out, src_is_modulo) + endif !*************************************************************************** ! Algorithm explanation (from disscussion with Steve Garner ) * @@ -358,6 +373,7 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o endif is = Interp%i_lon(m,n,1); ie = Interp%i_lon(m,n,2) js = Interp%j_lat(m,n,1); je = Interp%j_lat(m,n,2) + if( is == DUMMY) cycle lon1 = lon_in(is,js); lat1 = lat_in(is,js); lon2 = lon_in(ie,js); lat2 = lat_in(ie,js); lon3 = lon_in(ie,je); lat3 = lat_in(ie,je); @@ -383,23 +399,23 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o if(abs(quadra) < epsln) quadra = 0.0 if(quadra < 0.0) call mpp_error(FATAL, & "horiz_interp_bilinear_mod: No solution existed for this quadratic equation") - if ( abs(a) .lt. epsln) then ! a = 0 is a linear equation + if ( abs(a) .lt. epsln2) then ! a = 0 is a linear equation if( abs(b) .lt. epsln) call mpp_error(FATAL, & "horiz_interp_bilinear_mod: no unique solution existed for this linear equation") y = -c/b else y1 = 0.5*(-b+sqrt(quadra))/a y2 = 0.5*(-b-sqrt(quadra))/a - if(abs(y1) < epsln) y1 = 0.0 - if(abs(y2) < epsln) y2 = 0.0 - if(abs(1-y1) < epsln) y1 = 1.0 - if(abs(1-y2) < epsln) y2 = 1.0 + if(abs(y1) < epsln2) y1 = 0.0 + if(abs(y2) < epsln2) y2 = 0.0 + if(abs(1.0-y1) < epsln2) y1 = 1.0 + if(abs(1.0-y2) < epsln2) y2 = 1.0 num_solution = 0 - if(y1 .le. 1 .and. y1 .ge. 0) then + if(y1 >= 0.0 .and. y1 <= 1.0) then y = y1 num_solution = num_solution +1 endif - if(y2 .le. 1 .and. y2 .ge. 0) then + if(y2 >= 0.0 .and. y2 <= 1.0) then y = y2 num_solution = num_solution + 1 endif @@ -411,16 +427,23 @@ subroutine horiz_interp_bilinear_new_2d ( Interp, lon_in, lat_in, lon_out, lat_o endif if(abs(a1+c1*y) < epsln) call mpp_error(FATAL, & "horiz_interp_bilinear_mod: the denomenator is 0") - if(abs(y) < epsln) y = 0.0 - if(abs(1-y) < epsln) y = 1.0 + if(abs(y) < epsln2) y = 0.0 + if(abs(1.0-y) < epsln2) y = 1.0 x = (lon-b1*y-d1)/(a1+c1*y) - if(abs(x) < epsln) x = 0.0 - if(abs(1-x) < epsln) x = 1.0 + if(abs(x) < epsln2) x = 0.0 + if(abs(1.0-x) < epsln2) x = 1.0 ! x and y should be between 0 and 1. + !! Added for ECDA + if(use_new_search) then + if (x < 0.0) x = 0.0 ! snz + if (y < 0.0) y = 0.0 ! snz + if (x > 1.0) x = 1.0 + if (y > 1.0) y = 1.0 + endif if( x>1 .or. x<0 .or. y>1 .or. y < 0) call mpp_error(FATAL, & - "horiz_interp_bilinear_mod: weight should be between 0 and 1") - Interp % wti(m,n,1)=1-x; Interp % wti(m,n,2)=x - Interp % wtj(m,n,1)=1-y; Interp % wtj(m,n,2)=y + "horiz_interp_bilinear_mod: weight should be between 0 and 1") + Interp % wti(m,n,1)=1.0-x; Interp % wti(m,n,2)=x + Interp % wtj(m,n,1)=1.0-y; Interp % wtj(m,n,2)=y enddo enddo @@ -636,6 +659,246 @@ subroutine find_neighbor( Interp, lon_in, lat_in, lon_out, lat_out, src_modulo ) end subroutine find_neighbor + !####################################################################### + ! + ! The function will return true if the point x,y is inside a polygon, or + ! NO if it is not. If the point is exactly on the edge of a polygon, + ! the function will return .true. + ! + ! real polyx(:) : longitude coordinates of corners + ! real polyx(:) : latitude coordinates of corners + ! real x,y : point to be tested + ! ??? How to deal with truncation error. + ! + function inside_polygon(polyx, polyy, x, y) + real, dimension(:), intent(in) :: polyx, polyy + real, intent(in) :: x, y + logical :: inside_polygon + integer :: i, j, nedges + real :: xx + + inside_polygon = .false. + nedges = size(polyx(:)) + j = nedges + do i = 1, nedges + if( (polyy(i) < y .AND. polyy(j) >= y) .OR. (polyy(j) < y .AND. polyy(i) >= y) ) then + xx = polyx(i)+(y-polyy(i))/(polyy(j)-polyy(i))*(polyx(j)-polyx(i)) + if( xx == x ) then + inside_polygon = .true. + return + else if( xx < x ) then + inside_polygon = .not. inside_polygon + endif + endif + j = i + enddo + + return + + end function inside_polygon + + !####################################################################### + ! this routine will search the source grid to fine the grid box that encloses + ! each destination grid. + subroutine find_neighbor_new( Interp, lon_in, lat_in, lon_out, lat_out, src_modulo, no_crash ) + type(horiz_interp_type), intent(inout) :: Interp + real, intent(in), dimension(:,:) :: lon_in , lat_in + real, intent(in), dimension(:,:) :: lon_out, lat_out + logical, intent(in) :: src_modulo, no_crash + integer :: nlon_in, nlat_in, nlon_out, nlat_out + integer :: max_step, n, m, l, i, j, ip1, jp1, step + integer :: is, js, jstart, jend, istart, iend, npts + integer, allocatable, dimension(:) :: ilon, jlat + real :: lon_min, lon_max, lon, lat, tpi + logical :: found + real :: polyx(4), polyy(4) + real :: min_lon, min_lat, max_lon, max_lat + + tpi = 2.0*pi + nlon_in = size(lon_in,1) ; nlat_in = size(lat_in,2) + nlon_out = size(lon_out,1); nlat_out = size(lon_out,2) + + lon_min = minval(lon_in); + lon_max = maxval(lon_in); + + max_step = min(nlon_in,nlat_in)/2 ! can be adjusted if needed + allocate(ilon(8*max_step), jlat(8*max_step) ) + + do n = 1, nlat_out + do m = 1, nlon_out + found = .false. + lon = lon_out(m,n) + lat = lat_out(m,n) + + if(src_modulo) then + if(lon .lt. lon_min) then + lon = lon + tpi + else if(lon .gt. lon_max) then + lon = lon - tpi + endif + else + if(lon .lt. lon_min .or. lon .gt. lon_max ) & + call mpp_error(FATAL,'horiz_interp_bilinear_mod: ' //& + 'when input grid is not modulo, output grid should locate inside input grid') + endif + !--- search for the surrounding four points locatioon. + if(m==1 .and. n==1) then + J_LOOP: do j = 1, nlat_in-1 + do i = 1, nlon_in + ip1 = i+1 + jp1 = j+1 + if(i==nlon_in) then + if(src_modulo)then + ip1 = 1 + else + cycle + endif + endif + + polyx(1) = lon_in(i, j); polyy(1) = lat_in(i,j) + polyx(2) = lon_in(ip1,j); polyy(2) = lat_in(ip1,j) + polyx(3) = lon_in(ip1,jp1); polyy(3) = lat_in(ip1,jp1) + polyx(4) = lon_in(i, jp1); polyy(4) = lat_in(i, jp1) + if(lon .lt. lon_min .or. lon .gt. lon_max) then + if(i .ne. nlon_in) then + cycle + else + if(lon .lt. lon_min) then + polyx(1) = polyx(1) -tpi; polyx(4) = polyx(4) - tpi + else if(lon .gt. lon_max) then + polyx(2) = polyx(2) +tpi; polyx(3) = polyx(3) + tpi + endif + endif + endif + + min_lon = minval(polyx) + max_lon = maxval(polyx) + min_lat = minval(polyy) + max_lat = maxval(polyy) +! if( lon .GE. min_lon .AND. lon .LE. max_lon .AND. & +! lat .GE. min_lat .AND. lat .LE. max_lat ) then +! print*, 'i =', i, 'j = ', j +! print '(5f15.11)', lon, polyx +! print '(5f15.11)', lat, polyy +! endif + + if(inside_polygon(polyx, polyy, lon, lat)) then + found = .true. +! print*, " found ", i, j + Interp % i_lon (m,n,1) = i; Interp % i_lon (m,n,2) = ip1 + Interp % j_lat (m,n,1) = j; Interp % j_lat (m,n,2) = jp1 + exit J_LOOP + endif + enddo + enddo J_LOOP + else + step = 0 + do while ( .not. found .and. step .lt. max_step ) + !--- take the adajcent point as the starting point + if(m == 1) then + is = Interp % i_lon (m,n-1,1) + js = Interp % j_lat (m,n-1,1) + else + is = Interp % i_lon (m-1,n,1) + js = Interp % j_lat (m-1,n,1) + endif + if(step==0) then + npts = 1 + ilon(1) = is + jlat(1) = js + else + npts = 0 + !--- bottom and top boundary + jstart = max(js-step,1) + jend = min(js+step,nlat_in) + + do l = -step, step + i = is+l + if(src_modulo)then + if( i < 1) then + i = i + nlon_in + else if (i > nlon_in) then + i = i - nlon_in + endif + if( i < 1 .or. i > nlon_in) call mpp_error(FATAL, & + 'horiz_interp_bilinear_mod: max_step is too big, decrease max_step' ) + else + if( i < 1 .or. i > nlon_in) cycle + endif + + npts = npts + 1 + ilon(npts) = i + jlat(npts) = jstart + npts = npts + 1 + ilon(npts) = i + jlat(npts) = jend + enddo + + !--- right and left boundary ----------------------------------------------- + istart = is - step + iend = is + step + if(src_modulo) then + if( istart < 1) istart = istart + nlon_in + if( iend > nlon_in) iend = iend - nlon_in + else + istart = max(istart,1) + iend = min(iend, nlon_in) + endif + do l = -step, step + j = js+l + if( j < 1 .or. j > nlat_in) cycle + npts = npts+1 + ilon(npts) = istart + jlat(npts) = j + npts = npts+1 + ilon(npts) = iend + jlat(npts) = j + end do + end if + + !--- find the surrouding points + do l = 1, npts + i = ilon(l) + j = jlat(l) + ip1 = i+1 + if(ip1>nlon_in) then + if(src_modulo) then + ip1 = 1 + else + cycle + endif + endif + jp1 = j+1 + if(jp1>nlat_in) cycle + polyx(1) = lon_in(i, j); polyy(1) = lat_in(i,j) + polyx(2) = lon_in(ip1,j); polyy(2) = lat_in(ip1,j) + polyx(3) = lon_in(ip1,jp1); polyy(3) = lat_in(ip1,jp1) + polyx(4) = lon_in(i, jp1); polyy(4) = lat_in(i, jp1) + if(inside_polygon(polyx, polyy, lon, lat)) then + found = .true. + Interp % i_lon (m,n,1) = i; Interp % i_lon (m,n,2) = ip1 + Interp % j_lat (m,n,1) = j; Interp % j_lat (m,n,2) = jp1 + exit + endif + enddo + step = step + 1 + enddo + endif + if(.not.found) then + if(no_crash) then + Interp % i_lon (m,n,1:2) = DUMMY + Interp % j_lat (m,n,1:2) = DUMMY + print*,'lon,lat=',lon,lat ! snz + else + call mpp_error(FATAL, & + 'horiz_interp_bilinear_mod: the destination point is not inside the source grid' ) + endif + endif + enddo + enddo + + end subroutine find_neighbor_new + !####################################################################### function intersect(x1, y1, x2, y2, x) real, intent(in) :: x1, y1, x2, y2, x diff --git a/src/shared/horiz_interp/horiz_interp_conserve.F90 b/src/shared/horiz_interp/horiz_interp_conserve.F90 index ea3aaab44b..492819f1bb 100644 --- a/src/shared/horiz_interp/horiz_interp_conserve.F90 +++ b/src/shared/horiz_interp/horiz_interp_conserve.F90 @@ -27,6 +27,7 @@ module horiz_interp_conserve_mod use mpp_mod, only: mpp_error, FATAL, mpp_sync_self use mpp_mod, only: COMM_TAG_1, COMM_TAG_2 use fms_mod, only: write_version_number + use fms_io_mod, only: get_great_circle_algorithm use constants_mod, only: PI use horiz_interp_type_mod, only: horiz_interp_type @@ -89,10 +90,12 @@ module horiz_interp_conserve_mod integer :: pe, root_pe !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: horiz_interp_conserve.F90,v 19.0.2.2 2012/05/14 19:31:27 Zhi.Liang Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: horiz_interp_conserve.F90,v 20.0 2013/12/14 00:20:25 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. + logical :: great_circle_algorithm = .false. + contains !####################################################################### @@ -108,6 +111,9 @@ subroutine horiz_interp_conserve_init if(module_is_initialized) return call write_version_number (version, tagname) + + great_circle_algorithm = get_great_circle_algorithm() + module_is_initialized = .true. end subroutine horiz_interp_conserve_init @@ -121,6 +127,7 @@ subroutine horiz_interp_conserve_new_1dx1d ( Interp, lon_in, lat_in, lon_out, la real, intent(in), dimension(:) :: lon_in , lat_in real, intent(in), dimension(:) :: lon_out, lat_out integer, intent(in), optional :: verbose + ! !----------------------------------------------------------------------- real, dimension(size(lat_out(:))-1,2) :: sph @@ -136,6 +143,12 @@ subroutine horiz_interp_conserve_new_1dx1d ( Interp, lon_in, lat_in, lon_out, la iverbose, m2, n2, iter logical :: s2n character(len=64) :: mesg + + if(.not. module_is_initialized) call mpp_error(FATAL, & + 'horiz_interp_conserve_new_1dx1d: horiz_interp_conserve_init is not called') + + if(great_circle_algorithm) call mpp_error(FATAL, & + 'horiz_interp_conserve_new_1dx1d: great_circle_algorithm is not implemented, contact developer') !----------------------------------------------------------------------- iverbose = 0; if (present(verbose)) iverbose = verbose @@ -310,21 +323,27 @@ end subroutine horiz_interp_conserve_new_1dx1d !####################################################################### ! - subroutine horiz_interp_conserve_new_1dx2d ( Interp, lon_in, lat_in, lon_out, lat_out, mask_in, mask_out, verbose) + subroutine horiz_interp_conserve_new_1dx2d ( Interp, lon_in, lat_in, lon_out, lat_out, & + mask_in, mask_out, verbose) type(horiz_interp_type), intent(inout) :: Interp real, intent(in), dimension(:) :: lon_in , lat_in real, intent(in), dimension(:,:) :: lon_out, lat_out real, intent(in), optional, dimension(:,:) :: mask_in real, intent(inout), optional, dimension(:,:) :: mask_out integer, intent(in), optional :: verbose + ! integer :: create_xgrid_1DX2D_order1, get_maxxgrid, maxxgrid - integer :: nlon_in, nlat_in, nlon_out, nlat_out, nxgrid, i + integer :: create_xgrid_great_circle + integer :: nlon_in, nlat_in, nlon_out, nlat_out, nxgrid, i, j real, dimension(size(lon_in(:))-1, size(lat_in(:))-1) :: mask_src integer, allocatable, dimension(:) :: i_src, j_src, i_dst, j_dst - real, allocatable, dimension(:) :: xgrid_area - real, allocatable, dimension(:,:) :: dst_area + real, allocatable, dimension(:) :: xgrid_area, clon, clat + real, allocatable, dimension(:,:) :: dst_area, lon_src, lat_src + + if(.not. module_is_initialized) call mpp_error(FATAL, & + 'horiz_interp_conserve_new_1dx2d: horiz_interp_conserve_init is not called') if( (size(lon_out,1) .NE. size(lat_out,1)) .OR. (size(lon_out,2) .NE. size(lat_out,2)) ) & call mpp_error(FATAL, 'horiz_interp_conserve_mod: size mismatch between lon_out and lat_out') @@ -341,8 +360,23 @@ subroutine horiz_interp_conserve_new_1dx2d ( Interp, lon_in, lat_in, lon_out, la maxxgrid = get_maxxgrid() allocate(i_src(maxxgrid), j_src(maxxgrid), i_dst(maxxgrid), j_dst(maxxgrid) ) allocate( xgrid_area(maxxgrid), dst_area(nlon_out, nlat_out) ) - nxgrid = create_xgrid_1DX2D_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & - mask_src, i_src, j_src, i_dst, j_dst, xgrid_area) + + if( .not. great_circle_algorithm ) then + nxgrid = create_xgrid_1DX2D_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & + mask_src, i_src, j_src, i_dst, j_dst, xgrid_area) + else + allocate(lon_src(nlon_in+1,nlat_in+1), lat_src(nlon_in+1,nlat_in+1)) + allocate(clon(maxxgrid), clat(maxxgrid)) + do j = 1, nlat_in+1 + do i = 1, nlon_in+1 + lon_src(i,j) = lon_in(i) + lat_src(i,j) = lat_in(j) + enddo + enddo + nxgrid = create_xgrid_great_circle(nlon_in, nlat_in, nlon_out, nlat_out, lon_src, lat_src, lon_out, lat_out, & + mask_src, i_src, j_src, i_dst, j_dst, xgrid_area, clon, clat) + deallocate(lon_src, lat_src, clon, clat) + endif allocate(Interp%i_src(nxgrid), Interp%j_src(nxgrid) ) allocate(Interp%i_dst(nxgrid), Interp%j_dst(nxgrid) ) allocate(Interp%area_frac_dst(nxgrid) ) @@ -379,21 +413,27 @@ end subroutine horiz_interp_conserve_new_1dx2d !####################################################################### ! - subroutine horiz_interp_conserve_new_2dx1d ( Interp, lon_in, lat_in, lon_out, lat_out, mask_in, mask_out, verbose) + subroutine horiz_interp_conserve_new_2dx1d ( Interp, lon_in, lat_in, lon_out, lat_out, & + mask_in, mask_out, verbose) type(horiz_interp_type), intent(inout) :: Interp real, intent(in), dimension(:,:) :: lon_in , lat_in real, intent(in), dimension(:) :: lon_out, lat_out real, intent(in), optional, dimension(:,:) :: mask_in real, intent(inout), optional, dimension(:,:) :: mask_out integer, intent(in), optional :: verbose + ! integer :: create_xgrid_2DX1D_order1, get_maxxgrid, maxxgrid - integer :: nlon_in, nlat_in, nlon_out, nlat_out, nxgrid, i + integer :: create_xgrid_great_circle + integer :: nlon_in, nlat_in, nlon_out, nlat_out, nxgrid, i, j real, dimension(size(lon_in,1)-1, size(lon_in,2)-1) :: mask_src integer, allocatable, dimension(:) :: i_src, j_src, i_dst, j_dst - real, allocatable, dimension(:) :: xgrid_area - real, allocatable, dimension(:,:) :: dst_area + real, allocatable, dimension(:) :: xgrid_area, clon, clat + real, allocatable, dimension(:,:) :: dst_area, lon_dst, lat_dst + + if(.not. module_is_initialized) call mpp_error(FATAL, & + 'horiz_interp_conserve_new_2dx1d: horiz_interp_conserve_init is not called') if( (size(lon_in,1) .NE. size(lat_in,1)) .OR. (size(lon_in,2) .NE. size(lat_in,2)) ) & call mpp_error(FATAL, 'horiz_interp_conserve_mod: size mismatch between lon_in and lat_in') @@ -411,8 +451,22 @@ subroutine horiz_interp_conserve_new_2dx1d ( Interp, lon_in, lat_in, lon_out, la allocate(i_src(maxxgrid), j_src(maxxgrid), i_dst(maxxgrid), j_dst(maxxgrid) ) allocate( xgrid_area(maxxgrid), dst_area(nlon_out, nlat_out) ) - nxgrid = create_xgrid_2DX1D_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & + if( .not. great_circle_algorithm ) then + nxgrid = create_xgrid_2DX1D_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & mask_src, i_src, j_src, i_dst, j_dst, xgrid_area) + else + allocate(lon_dst(nlon_out+1, nlat_out+1), lat_dst(nlon_out+1, nlat_out+1) ) + allocate(clon(maxxgrid), clat(maxxgrid)) + do j = 1, nlat_out+1 + do i = 1, nlon_out+1 + lon_dst(i,j) = lon_out(i) + lat_dst(i,j) = lat_out(j) + enddo + enddo + nxgrid = create_xgrid_great_circle(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_dst, lat_dst, & + mask_src, i_src, j_src, i_dst, j_dst, xgrid_area, clon, clat) + deallocate(lon_dst, lat_dst, clon, clat) + endif allocate(Interp%i_src(nxgrid), Interp%j_src(nxgrid) ) allocate(Interp%i_dst(nxgrid), Interp%j_dst(nxgrid) ) allocate(Interp%area_frac_dst(nxgrid) ) @@ -449,7 +503,8 @@ end subroutine horiz_interp_conserve_new_2dx1d !####################################################################### ! - subroutine horiz_interp_conserve_new_2dx2d ( Interp, lon_in, lat_in, lon_out, lat_out, mask_in, mask_out, verbose) + subroutine horiz_interp_conserve_new_2dx2d ( Interp, lon_in, lat_in, lon_out, lat_out, & + mask_in, mask_out, verbose) type(horiz_interp_type), intent(inout) :: Interp real, intent(in), dimension(:,:) :: lon_in , lat_in real, intent(in), dimension(:,:) :: lon_out, lat_out @@ -459,12 +514,16 @@ subroutine horiz_interp_conserve_new_2dx2d ( Interp, lon_in, lat_in, lon_out, la ! integer :: create_xgrid_2DX2D_order1, get_maxxgrid, maxxgrid + integer :: create_xgrid_great_circle integer :: nlon_in, nlat_in, nlon_out, nlat_out, nxgrid, i real, dimension(size(lon_in,1)-1, size(lon_in,2)-1) :: mask_src integer, allocatable, dimension(:) :: i_src, j_src, i_dst, j_dst - real, allocatable, dimension(:) :: xgrid_area + real, allocatable, dimension(:) :: xgrid_area, clon, clat real, allocatable, dimension(:,:) :: dst_area + if(.not. module_is_initialized) call mpp_error(FATAL, & + 'horiz_interp_conserve_new_2dx2d: horiz_interp_conserve_init is not called') + if( (size(lon_in,1) .NE. size(lat_in,1)) .OR. (size(lon_in,2) .NE. size(lat_in,2)) ) & call mpp_error(FATAL, 'horiz_interp_conserve_mod: size mismatch between lon_in and lat_in') if( (size(lon_out,1) .NE. size(lat_out,1)) .OR. (size(lon_out,2) .NE. size(lat_out,2)) ) & @@ -482,8 +541,17 @@ subroutine horiz_interp_conserve_new_2dx2d ( Interp, lon_in, lat_in, lon_out, la maxxgrid = get_maxxgrid() allocate(i_src(maxxgrid), j_src(maxxgrid), i_dst(maxxgrid), j_dst(maxxgrid) ) allocate( xgrid_area(maxxgrid), dst_area(nlon_out, nlat_out) ) - nxgrid = create_xgrid_2DX2D_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & - mask_src, i_src, j_src, i_dst, j_dst, xgrid_area) + + if( .not. great_circle_algorithm ) then + nxgrid = create_xgrid_2DX2D_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & + mask_src, i_src, j_src, i_dst, j_dst, xgrid_area) + else + allocate(clon(maxxgrid), clat(maxxgrid)) + nxgrid = create_xgrid_great_circle(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, & + mask_src, i_src, j_src, i_dst, j_dst, xgrid_area, clon, clat) + deallocate(clon, clat) + endif + allocate(Interp%i_src(nxgrid), Interp%j_src(nxgrid) ) allocate(Interp%i_dst(nxgrid), Interp%j_dst(nxgrid) ) allocate(Interp%area_frac_dst(nxgrid) ) diff --git a/src/shared/horiz_interp/horiz_interp_spherical.F90 b/src/shared/horiz_interp/horiz_interp_spherical.F90 index 5e7682d0dd..15971f74e0 100644 --- a/src/shared/horiz_interp/horiz_interp_spherical.F90 +++ b/src/shared/horiz_interp/horiz_interp_spherical.F90 @@ -29,7 +29,7 @@ module horiz_interp_spherical_mod public :: horiz_interp_spherical_new, horiz_interp_spherical, horiz_interp_spherical_del - public :: horiz_interp_spherical_init + public :: horiz_interp_spherical_init, horiz_interp_spherical_wght integer, parameter :: max_neighbors = 400 real, parameter :: max_dist_default = 0.1 ! radians @@ -59,8 +59,8 @@ module horiz_interp_spherical_mod namelist /horiz_interp_spherical_nml/ search_method !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: horiz_interp_spherical.F90,v 19.0 2012/01/06 21:58:27 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: horiz_interp_spherical.F90,v 20.0 2013/12/14 00:20:28 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. contains @@ -82,6 +82,7 @@ subroutine horiz_interp_spherical_init call write_version_number (version, tagname) #ifdef INTERNAL_FILE_NML read (input_nml_file, horiz_interp_spherical_nml, iostat=io) + ierr = check_nml_error(io,'horiz_interp_spherical_nml') #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) @@ -478,6 +479,90 @@ subroutine horiz_interp_spherical( Interp, data_in, data_out, verbose, mask_in, return end subroutine horiz_interp_spherical + + ! + !####################################################################### + subroutine horiz_interp_spherical_wght( Interp, wt, verbose, mask_in, mask_out, missing_value) + type (horiz_interp_type), intent(in) :: Interp + real, intent(out), dimension(:,:,:) :: wt + integer, intent(in), optional :: verbose + real, intent(in), dimension(:,:), optional :: mask_in + real, intent(out), dimension(:,:), optional :: mask_out + real, intent(in), optional :: missing_value + + !--- some local variables ---------------------------------------- + real, dimension(Interp%nlon_src, Interp%nlat_src) :: mask_src + real, dimension(Interp%nlon_dst, Interp%nlat_dst) :: mask_dst + integer :: nlon_in, nlat_in, nlon_out, nlat_out, num_found + integer :: m, n, i, j, k, miss_in, miss_out, i1, i2, j1, j2, iverbose + real :: min_in, max_in, avg_in, min_out, max_out, avg_out, sum + !----------------------------------------------------------------- + + iverbose = 0; if (present(verbose)) iverbose = verbose + + nlon_in = Interp%nlon_src; nlat_in = Interp%nlat_src + nlon_out = Interp%nlon_dst; nlat_out = Interp%nlat_dst + + mask_src = 1.0; mask_dst = 1.0 + if(present(mask_in)) mask_src = mask_in + + do n=1,nlat_out + do m=1,nlon_out + ! neighbors are sorted nearest to farthest + ! check nearest to see if it is a land point + num_found = Interp%num_found(m,n) + + if (num_found > num_nbrs_default) then + print*,'pe=',mpp_pe(),'num_found=',num_found + num_found = num_nbrs_default + end if + + if(num_found == 0 ) then + mask_dst(m,n) = 0.0 + else + i1 = Interp%i_lon(m,n,1); j1 = Interp%j_lat(m,n,1) + if (mask_src(i1,j1) .lt. 0.5) then + mask_dst(m,n) = 0.0 + endif + + if(num_found .gt. 1 ) then + i2 = Interp%i_lon(m,n,2); j2 = Interp%j_lat(m,n,2) + ! compare first 2 nearest neighbors -- if they are nearly + ! equidistant then use this mask for robustness + if(abs(Interp%src_dist(m,n,2)-Interp%src_dist(m,n,1)) .lt. epsln) then + if((mask_src(i1,j1) .lt. 0.5)) mask_dst(m,n) = 0.0 + endif + endif + + sum=0.0 + do k=1, num_found + if(mask_src(Interp%i_lon(m,n,k),Interp%j_lat(m,n,k)) .lt. 0.5 ) then + wt(m,n,k) = 0.0 + else + if (Interp%src_dist(m,n,k) <= epsln) then + wt(m,n,k) = large + sum = sum + large + else if(Interp%src_dist(m,n,k) <= Interp%max_src_dist ) then + wt(m,n,k) = 1.0/Interp%src_dist(m,n,k) + sum = sum+wt(m,n,k) + else + wt(m,n,k) = 0.0 + endif + endif + enddo + if (sum > epsln) then + do k = 1, num_found + wt(m,n,k) = wt(m,n,k)/sum + enddo + else + mask_dst(m,n) = 0.0 + endif + endif + enddo + enddo + + return + end subroutine horiz_interp_spherical_wght ! !####################################################################### diff --git a/src/shared/include/fms_platform.h b/src/shared/include/fms_platform.h index 2f07fe10bb..47df3243b8 100644 --- a/src/shared/include/fms_platform.h +++ b/src/shared/include/fms_platform.h @@ -97,7 +97,7 @@ #define NF_GET_ATT_REAL nf_get_att_double #endif -#ifdef __CRAYXT_COMPUTE_LINUX_TARGET +#if defined __CRAYXT_COMPUTE_LINUX_TARGET || defined __GFORTRAN__ !Cray XT compilers do not support real*16 computation !also known as 128-bit or quad precision #define NO_QUAD_PRECISION diff --git a/src/shared/mosaic/create_xgrid.c b/src/shared/mosaic/create_xgrid.c index 26f61a3d6f..fd9556e13e 100644 --- a/src/shared/mosaic/create_xgrid.c +++ b/src/shared/mosaic/create_xgrid.c @@ -7,11 +7,18 @@ #define AREA_RATIO_THRESH (1.e-6) #define MASK_THRESH (0.5) -#define EPSLN (1.0e-30) +#define EPSLN8 (1.e-8) +#define EPSLN30 (1.0e-30) +#define EPSLN10 (1.0e-10) +#define R2D (180/M_PI) double grid_box_radius(const double *x, const double *y, const double *z, int n); double dist_between_boxes(const double *x1, const double *y1, const double *z1, int n1, const double *x2, const double *y2, const double *z2, int n2); int inside_edge(double x0, double y0, double x1, double y1, double x, double y); +int line_intersect_2D_3D(double *a1, double *a2, double *q1, double *q2, double *q3, + double *intersect, double *u_a, double *u_q, int *inbound); + + /******************************************************************************* int get_maxxgrid return constants MAXXGRID. @@ -30,10 +37,12 @@ int get_maxxgrid_(void) void get_grid_area(const int *nlon, const int *nlat, const double *lon, const double *lat, const double *area) return the grid area. *******************************************************************************/ +#ifndef __AIX void get_grid_area_(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area) { get_grid_area(nlon, nlat, lon, lat, area); } +#endif void get_grid_area(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area) { @@ -59,6 +68,56 @@ void get_grid_area(const int *nlon, const int *nlat, const double *lon, const do }; /* get_grid_area */ +#ifndef __AIX +void get_grid_great_circle_area_(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area) +{ + get_grid_great_circle_area(nlon, nlat, lon, lat, area); + +} +#endif + +void get_grid_great_circle_area(const int *nlon, const int *nlat, const double *lon, const double *lat, double *area) +{ + int nx, ny, nxp, nyp, i, j, n_in; + int n0, n1, n2, n3; + double x_in[20], y_in[20], z_in[20]; + struct Node *grid=NULL; + double *x=NULL, *y=NULL, *z=NULL; + + + nx = *nlon; + ny = *nlat; + nxp = nx + 1; + nyp = ny + 1; + + x = (double *)malloc(nxp*nyp*sizeof(double)); + y = (double *)malloc(nxp*nyp*sizeof(double)); + z = (double *)malloc(nxp*nyp*sizeof(double)); + + latlon2xyz(nxp*nyp, lon, lat, x, y, z); + + for(j=0; j and should not parallel to " "the line between and "); } @@ -911,6 +971,739 @@ int clip_2dx2d(const double lon1_in[], const double lat1_in[], int n1_in, return(n_out); }; /* clip */ +/*#define debug_test_create_xgrid*/ + +#ifndef __AIX +int create_xgrid_great_circle_(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, + const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, + const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, + double *xgrid_area, double *xgrid_clon, double *xgrid_clat) +{ + int nxgrid; + nxgrid = create_xgrid_great_circle(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, + mask_in, i_in, j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat); + + return nxgrid; +}; +#endif + +int create_xgrid_great_circle(const int *nlon_in, const int *nlat_in, const int *nlon_out, const int *nlat_out, + const double *lon_in, const double *lat_in, const double *lon_out, const double *lat_out, + const double *mask_in, int *i_in, int *j_in, int *i_out, int *j_out, + double *xgrid_area, double *xgrid_clon, double *xgrid_clat) +{ + + int nx1, nx2, ny1, ny2, nx1p, nx2p, ny1p, ny2p, nxgrid, n1_in, n2_in; + int n0, n1, n2, n3, i1, j1, i2, j2, l, n; + double x1_in[MV], y1_in[MV], z1_in[MV]; + double x2_in[MV], y2_in[MV], z2_in[MV]; + double x_out[MV], y_out[MV], z_out[MV]; + double *x1=NULL, *y1=NULL, *z1=NULL; + double *x2=NULL, *y2=NULL, *z2=NULL; + + double xctrlon, xctrlat; + double *area1, *area2, min_area; + + nx1 = *nlon_in; + ny1 = *nlat_in; + nx2 = *nlon_out; + ny2 = *nlat_out; + nxgrid = 0; + nx1p = nx1 + 1; + nx2p = nx2 + 1; + ny1p = ny1 + 1; + ny2p = ny2 + 1; + + /* first convert lon-lat to cartesian coordinates */ + x1 = (double *)malloc(nx1p*ny1p*sizeof(double)); + y1 = (double *)malloc(nx1p*ny1p*sizeof(double)); + z1 = (double *)malloc(nx1p*ny1p*sizeof(double)); + x2 = (double *)malloc(nx2p*ny2p*sizeof(double)); + y2 = (double *)malloc(nx2p*ny2p*sizeof(double)); + z2 = (double *)malloc(nx2p*ny2p*sizeof(double)); + + latlon2xyz(nx1p*ny1p, lon_in, lat_in, x1, y1, z1); + latlon2xyz(nx2p*ny2p, lon_out, lat_out, x2, y2, z2); + + area1 = (double *)malloc(nx1*ny1*sizeof(double)); + area2 = (double *)malloc(nx2*ny2*sizeof(double)); + get_grid_great_circle_area(nlon_in, nlat_in, lon_in, lat_in, area1); + get_grid_great_circle_area(nlon_out, nlat_out, lon_out, lat_out, area2); + n1_in = 4; + n2_in = 4; + + for(j1=0; j1 MASK_THRESH ) { + /* clockwise */ + n0 = j1*nx1p+i1; n1 = (j1+1)*nx1p+i1; + n2 = (j1+1)*nx1p+i1+1; n3 = j1*nx1p+i1+1; + x1_in[0] = x1[n0]; y1_in[0] = y1[n0]; z1_in[0] = z1[n0]; + x1_in[1] = x1[n1]; y1_in[1] = y1[n1]; z1_in[1] = z1[n1]; + x1_in[2] = x1[n2]; y1_in[2] = y1[n2]; z1_in[2] = z1[n2]; + x1_in[3] = x1[n3]; y1_in[3] = y1[n3]; z1_in[3] = z1[n3]; + + for(j2=0; j2 0) { + xarea = great_circle_area ( n_out, x_out, y_out, z_out ) * mask_in[j1*nx1+i1]; + min_area = min(area1[j1*nx1+i1], area2[j2*nx2+i2]); + if( xarea/min_area > AREA_RATIO_THRESH ) { +#ifdef debug_test_create_xgrid + printf("(i2,j2)=(%d,%d), (i1,j1)=(%d,%d), xarea=%g\n", i2, j2, i1, j1, xarea); +#endif + xgrid_area[nxgrid] = xarea; + xgrid_clon[nxgrid] = 0; /*z1l: will be developed very soon */ + xgrid_clat[nxgrid] = 0; + i_in[nxgrid] = i1; + j_in[nxgrid] = j1; + i_out[nxgrid] = i2; + j_out[nxgrid] = j2; + ++nxgrid; + if(nxgrid > MAXXGRID) error_handler("nxgrid is greater than MAXXGRID, increase MAXXGRID"); + } + } + } + } + + + free(area1); + free(area2); + + free(x1); + free(y1); + free(z1); + free(x2); + free(y2); + free(z2); + + return nxgrid; + +};/* create_xgrid_great_circle */ + +/******************************************************************************* + Revise Sutherland-Hodgeman algorithm to find the vertices of the overlapping + between any two grid boxes. It return the number of vertices for the exchange grid. + Each edge of grid box is a part of great circle. All the points are cartesian + coordinates. Here we are assuming each polygon is convex. + RANGE_CHECK_CRITERIA is used to determine if the two grid boxes are possible to be + overlap. The size should be between 0 and 0.5. The larger the range_check_criteria, + the more expensive of the computatioin. When the value is close to 0, + some small exchange grid might be lost. Suggest to use value 0.05 for C48. +*******************************************************************************/ + +int clip_2dx2d_great_circle(const double x1_in[], const double y1_in[], const double z1_in[], int n1_in, + const double x2_in[], const double y2_in[], const double z2_in [], int n2_in, + double x_out[], double y_out[], double z_out[]) +{ + struct Node *subjList=NULL; + struct Node *clipList=NULL; + struct Node *grid1List=NULL; + struct Node *grid2List=NULL; + struct Node *intersectList=NULL; + struct Node *polyList=NULL; + struct Node *curList=NULL; + struct Node *firstIntersect=NULL, *curIntersect=NULL; + struct Node *temp1=NULL, *temp2=NULL, *temp=NULL; + + int i1, i2, i1p, i2p, i2p2, npts1, npts2; + int nintersect, n_out; + int maxiter1, maxiter2, iter1, iter2; + int found1, found2, curListNum; + int has_inbound, inbound; + double pt1[MV][3], pt2[MV][3]; + double *p1_0=NULL, *p1_1=NULL; + double *p2_0=NULL, *p2_1=NULL, *p2_2=NULL; + double intersect[3]; + double u1, u2; + double min_x1, max_x1, min_y1, max_y1, min_z1, max_z1; + double min_x2, max_x2, min_y2, max_y2, min_z2, max_z2; + static int first_call=1; + + + /* first check the min and max of (x1_in, y1_in, z1_in) with (x2_in, y2_in, z2_in) */ + min_x1 = minval_double(n1_in, x1_in); + max_x2 = maxval_double(n2_in, x2_in); + if(min_x1 >= max_x2+RANGE_CHECK_CRITERIA) return 0; + max_x1 = maxval_double(n1_in, x1_in); + min_x2 = minval_double(n2_in, x2_in); + if(min_x2 >= max_x1+RANGE_CHECK_CRITERIA) return 0; + + min_y1 = minval_double(n1_in, y1_in); + max_y2 = maxval_double(n2_in, y2_in); + if(min_y1 >= max_y2+RANGE_CHECK_CRITERIA) return 0; + max_y1 = maxval_double(n1_in, y1_in); + min_y2 = minval_double(n2_in, y2_in); + if(min_y2 >= max_y1+RANGE_CHECK_CRITERIA) return 0; + + min_z1 = minval_double(n1_in, z1_in); + max_z2 = maxval_double(n2_in, z2_in); + if(min_z1 >= max_z2+RANGE_CHECK_CRITERIA) return 0; + max_z1 = maxval_double(n1_in, z1_in); + min_z2 = minval_double(n2_in, z2_in); + if(min_z2 >= max_z1+RANGE_CHECK_CRITERIA) return 0; + + rewindList(); + + grid1List = getNext(); + grid2List = getNext(); + intersectList = getNext(); + polyList = getNext(); + + /* insert points into SubjList and ClipList */ + for(i1=0; i1isInside = 1; + else + temp->isInside = 0; + temp = getNextNode(temp); + } + +#ifdef debug_test_create_xgrid + printf("\nNOTE from clip_2dx2d_great_circle: begin to set inside value of grid2List\n"); +#endif + /* check if grid2List is inside grid1List */ + temp = grid2List; + + while(temp) { + if(insidePolygon(temp, grid1List)) + temp->isInside = 1; + else + temp->isInside = 0; + temp = getNextNode(temp); + } + + /* make sure the grid box is clockwise */ + + /*make sure each polygon is convex, which is equivalent that the great_circle_area is positive */ + if( gridArea(grid1List) <= 0 ) + error_handler("create_xgrid.c(clip_2dx2d_great_circle): grid box 1 is not convex"); + if( gridArea(grid2List) <= 0 ) + error_handler("create_xgrid.c(clip_2dx2d_great_circle): grid box 2 is not convex"); + +#ifdef debug_test_create_xgrid + printNode(grid1List, "grid1List"); + printNode(grid2List, "grid2List"); +#endif + + /* get the coordinates from grid1List and grid2List. + Please not npts1 might not equal n1_in, npts2 might not equal n2_in because of pole + */ + + temp = grid1List; + for(i1=0; i1Next; + } + temp = grid2List; + for(i2=0; i2Next; + } + + firstIntersect=getNext(); + curIntersect = getNext(); + +#ifdef debug_test_create_xgrid + printf("\n\n************************ Start line_intersect_2D_3D ******************************\n"); +#endif + /* first find all the intersection points */ + nintersect = 0; + for(i1=0; i1 1) { + getFirstInbound(intersectList, firstIntersect); + if(firstIntersect->initialized) { + has_inbound = 1; + } + } + + /* when has_inbound == 0, get the grid1List and grid2List */ + if( !has_inbound && nintersect > 1) { + setInbound(intersectList, grid1List); + getFirstInbound(intersectList, firstIntersect); + if(firstIntersect->initialized) has_inbound = 1; + } + + /* if has_inbound = 1, find the overlapping */ + n_out = 0; + + if(has_inbound) { + maxiter1 = nintersect; +#ifdef debug_test_create_xgrid + printf("\nNOTE from clip_2dx2d_great_circle: number of intersect is %d\n", nintersect); + printf("\n size of grid2List is %d, size of grid1List is %d\n", length(grid2List), length(grid1List)); + printNode(intersectList, "beginning intersection list"); + printNode(grid2List, "beginning clip list"); + printNode(grid1List, "beginning subj list"); + printf("\n************************ End line_intersect_2D_3D **********************************\n\n"); +#endif + temp1 = getNode(grid1List, *firstIntersect); + if( temp1 == NULL) { + double lon[10], lat[10]; + int i; + xyz2latlon(n1_in, x1_in, y1_in, z1_in, lon, lat); + for(i=0; i< n1_in; i++) printf("lon1 = %g, lat1 = %g\n", lon[i]*R2D, lat[i]*R2D); + printf("\n"); + xyz2latlon(n2_in, x2_in, y2_in, z2_in, lon, lat); + for(i=0; i< n2_in; i++) printf("lon2 = %g, lat2 = %g\n", lon[i]*R2D, lat[i]*R2D); + printf("\n"); + + error_handler("firstIntersect is not in the grid1List"); + } + addNode(polyList, *firstIntersect); + nintersect--; +#ifdef debug_test_create_xgrid + printNode(polyList, "polyList at stage 1"); +#endif + + /* Loop over the grid1List and grid2List to find again the firstIntersect */ + curList = grid1List; + curListNum = 0; + + /* Loop through curList to find the next intersection, the loop will end + when come back to firstIntersect + */ + copyNode(curIntersect, *firstIntersect); + iter1 = 0; + found1 = 0; + + while( iter1 < maxiter1 ) { +#ifdef debug_test_create_xgrid + printf("\n----------- At iteration = %d\n\n", iter1+1 ); + printNode(curIntersect, "curIntersect at the begining of iter1"); +#endif + /* find the curIntersect in curList and get the next intersection points */ + temp1 = getNode(curList, *curIntersect); + temp2 = temp1->Next; + if( temp2 == NULL ) temp2 = curList; + + maxiter2 = length(curList); + found2 = 0; + iter2 = 0; + /* Loop until find the next intersection */ + while( iter2 < maxiter2 ) { + int temp2IsIntersect; + + temp2IsIntersect = 0; + if( isIntersect( *temp2 ) ) { /* copy the point and switch to the grid2List */ + struct Node *temp3; + + /* first check if temp2 is the firstIntersect */ + if( sameNode( *temp2, *firstIntersect) ) { + found1 = 1; + break; + } + + temp3 = temp2->Next; + if( temp3 == NULL) temp3 = curList; + if( temp3 == NULL) error_handler("creat_xgrid.c: temp3 can not be NULL"); + found2 = 1; + /* if next node is inside or an intersection, + need to keep on curList + */ + temp2IsIntersect = 1; + if( isIntersect(*temp3) || (temp3->isInside == 1) ) found2 = 0; + } + if(found2) { + copyNode(curIntersect, *temp2); + break; + } + else { + addNode(polyList, *temp2); +#ifdef debug_test_create_xgrid + printNode(polyList, "polyList at stage 2"); +#endif + if(temp2IsIntersect) { + nintersect--; + } + } + temp2 = temp2->Next; + if( temp2 == NULL ) temp2 = curList; + iter2 ++; + } + if(found1) break; + + if( !found2 ) error_handler(" not found the next intersection "); + + /* if find the first intersection, the poly found */ + if( sameNode( *curIntersect, *firstIntersect) ) { + found1 = 1; + break; + } + + /* add curIntersect to polyList and remove it from intersectList and curList */ + addNode(polyList, *curIntersect); +#ifdef debug_test_create_xgrid + printNode(polyList, "polyList at stage 3"); +#endif + nintersect--; + + + /* switch curList */ + if( curListNum == 0) { + curList = grid2List; + curListNum = 1; + } + else { + curList = grid1List; + curListNum = 0; + } + iter1++; + } + if(!found1) error_handler("not return back to the first intersection"); + + /* currently we are only clipping convex polygon to convex polygon */ + if( nintersect > 0) error_handler("After clipping, nintersect should be 0"); + + /* copy the polygon to x_out, y_out, z_out */ + temp1 = polyList; + while (temp1 != NULL) { + getCoordinate(*temp1, x_out+n_out, y_out+n_out, z_out+n_out); + temp1 = temp1->Next; + n_out++; + } + + /* if(n_out < 3) error_handler(" The clipped region has < 3 vertices"); */ + if( n_out < 3) n_out = 0; +#ifdef debug_test_create_xgrid + printNode(polyList, "polyList after clipping"); +#endif + } + + /* check if grid1 is inside grid2 */ + if(n_out==0){ + /* first check number of points in grid1 is inside grid2 */ + int n, n1in2; + /* One possible is that grid1List is inside grid2List */ +#ifdef debug_test_create_xgrid + printf("\nNOTE from clip_2dx2d_great_circle: check if grid1 is inside grid2\n"); +#endif + n1in2 = 0; + temp = grid1List; + while(temp) { + if(temp->intersect != 1) { +#ifdef debug_test_create_xgrid + printf("grid1->isInside = %d\n", temp->isInside); +#endif + if( temp->isInside == 1) n1in2++; + } + temp = getNextNode(temp); + } + if(npts1==n1in2) { /* grid1 is inside grid2 */ + n_out = npts1; + n = 0; + temp = grid1List; + while( temp ) { + getCoordinate(*temp, &x_out[n], &y_out[n], &z_out[n]); + n++; + temp = getNextNode(temp); + } + } + if(n_out>0) return n_out; + } + + /* check if grid2List is inside grid1List */ + if(n_out ==0){ + int n, n2in1; +#ifdef debug_test_create_xgrid + printf("\nNOTE from clip_2dx2d_great_circle: check if grid2 is inside grid1\n"); +#endif + + temp = grid2List; + n2in1 = 0; + while(temp) { + if(temp->intersect != 1) { +#ifdef debug_test_create_xgrid + printf("grid2->isInside = %d\n", temp->isInside); +#endif + if( temp->isInside == 1) n2in1++; + } + temp = getNextNode(temp); + } + + if(npts2==n2in1) { /* grid2 is inside grid1 */ + n_out = npts2; + n = 0; + temp = grid2List; + while( temp ) { + getCoordinate(*temp, &x_out[n], &y_out[n], &z_out[n]); + n++; + temp = getNextNode(temp); + } + + } + } + + + return n_out; +} + + +/* Intersects between the line a and the seqment s + where both line and segment are great circle lines on the sphere represented by + 3D cartesian points. + [sin sout] are the ends of a line segment + returns true if the lines could be intersected, false otherwise. + inbound means the direction of (a1,a2) go inside or outside of (q1,q2,q3) +*/ + +int line_intersect_2D_3D(double *a1, double *a2, double *q1, double *q2, double *q3, + double *intersect, double *u_a, double *u_q, int *inbound){ + + /* Do this intersection by reprsenting the line a1 to a2 as a plane through the + two line points and the origin of the sphere (0,0,0). This is the + definition of a great circle arc. + */ + double plane[9]; + double plane_p[2]; + double u; + double p1[3], v1[3], v2[3]; + double c1[3], c2[3], c3[3]; + double coincident, sense, norm; + int i; + int is_inter1, is_inter2; + + *inbound = 0; + + /* first check if any vertices are the same */ + if(samePoint(a1[0], a1[1], a1[2], q1[0], q1[1], q1[2])) { + *u_a = 0; + *u_q = 0; + intersect[0] = a1[0]; + intersect[1] = a1[1]; + intersect[2] = a1[2]; +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound); +#endif + return 1; + } + else if (samePoint(a1[0], a1[1], a1[2], q2[0], q2[1], q2[2])) { + *u_a = 0; + *u_q = 1; + intersect[0] = a1[0]; + intersect[1] = a1[1]; + intersect[2] = a1[2]; +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound); +#endif + return 1; + } + else if(samePoint(a2[0], a2[1], a2[2], q1[0], q1[1], q1[2])) { +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound); +#endif + *u_a = 1; + *u_q = 0; + intersect[0] = a2[0]; + intersect[1] = a2[1]; + intersect[2] = a2[2]; + return 1; + } + else if (samePoint(a2[0], a2[1], a2[2], q2[0], q2[1], q2[2])) { +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound); +#endif + *u_a = 1; + *u_q = 1; + intersect[0] = a2[0]; + intersect[1] = a2[1]; + intersect[2] = a2[2]; + return 1; + } + + + /* Load points defining plane into variable (these are supposed to be in counterclockwise order) */ + plane[0]=q1[0]; + plane[1]=q1[1]; + plane[2]=q1[2]; + plane[3]=q2[0]; + plane[4]=q2[1]; + plane[5]=q2[2]; + plane[6]=0.0; + plane[7]=0.0; + plane[8]=0.0; + + /* Intersect the segment with the plane */ + is_inter1 = intersect_tri_with_line(plane, a1, a2, plane_p, u_a); + + if(!is_inter1) + return 0; + + if(fabs(*u_a) < EPSLN8) *u_a = 0; + if(fabs(*u_a-1) < EPSLN8) *u_a = 1; + + +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: u_a = %19.15f\n", *u_a); +#endif + + + if( (*u_a < 0) || (*u_a > 1) ) return 0; + + /* Load points defining plane into variable (these are supposed to be in counterclockwise order) */ + plane[0]=a1[0]; + plane[1]=a1[1]; + plane[2]=a1[2]; + plane[3]=a2[0]; + plane[4]=a2[1]; + plane[5]=a2[2]; + plane[6]=0.0; + plane[7]=0.0; + plane[8]=0.0; + + /* Intersect the segment with the plane */ + is_inter2 = intersect_tri_with_line(plane, q1, q2, plane_p, u_q); + + if(!is_inter2) + return 0; + + if(fabs(*u_q) < EPSLN8) *u_q = 0; + if(fabs(*u_q-1) < EPSLN8) *u_q = 1; +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: u_q = %19.15f\n", *u_q); +#endif + + + if( (*u_q < 0) || (*u_q > 1) ) return 0; + + u =*u_a; + + /* The two planes are coincidental */ + vect_cross(a1, a2, c1); + vect_cross(q1, q2, c2); + vect_cross(c1, c2, c3); + coincident = metric(c3); + + if(fabs(coincident) < EPSLN30) return 0; + + /* Calculate point of intersection */ + intersect[0]=a1[0] + u*(a2[0]-a1[0]); + intersect[1]=a1[1] + u*(a2[1]-a1[1]); + intersect[2]=a1[2] + u*(a2[2]-a1[2]); + + norm = metric( intersect ); + for(i = 0; i < 3; i ++) intersect[i] /= norm; + + /* when u_q =0 or u_q =1, the following could not decide the inbound value */ + if(*u_q != 0 && *u_q != 1){ + + p1[0] = a2[0]-a1[0]; + p1[1] = a2[1]-a1[1]; + p1[2] = a2[2]-a1[2]; + v1[0] = q2[0]-q1[0]; + v1[1] = q2[1]-q1[1]; + v1[2] = q2[2]-q1[2]; + v2[0] = q3[0]-q2[0]; + v2[1] = q3[1]-q2[1]; + v2[2] = q3[2]-q2[2]; + + vect_cross(v1, v2, c1); + vect_cross(v1, p1, c2); + + sense = dot(c1, c2); + *inbound = 1; + if(sense > 0) *inbound = 2; /* v1 going into v2 in CCW sense */ + } +#ifdef debug_test_create_xgrid + printf("\nNOTE from line_intersect_2D_3D: inbound=%d\n", *inbound); +#endif + + return 1; +} + /*------------------------------------------------------------------------------ double poly_ctrlat(const double x[], const double y[], int n) @@ -1099,6 +1892,7 @@ double dist_between_boxes(const double *x1, const double *y1, const double *z1, double dist; int i, j; + dist = 0.0; for(i=0; i* > 0, outside, otherwise inside. inner product value = 0 also treate as inside. *******************************************************************************/ - int inside_edge(double x0, double y0, double x1, double y1, double x, double y) - { +int inside_edge(double x0, double y0, double x1, double y1, double x, double y) +{ const double SMALL = 1.e-12; double product; @@ -1129,3 +1923,540 @@ double dist_between_boxes(const double *x1, const double *y1, const double *z1, }; /* inside_edge */ + +/* The following is a test program to test subroutines in create_xgrid.c */ + +#ifdef test_create_xgrid + +#include "create_xgrid.h" +#include + +#define D2R (M_PI/180) +#define R2D (180/M_PI) +#define MAXPOINT 1000 + +int main(int argc, char* argv[]) +{ + + double lon1_in[MAXPOINT], lat1_in[MAXPOINT]; + double lon2_in[MAXPOINT], lat2_in[MAXPOINT]; + double x1_in[MAXPOINT], y1_in[MAXPOINT], z1_in[MAXPOINT]; + double x2_in[MAXPOINT], y2_in[MAXPOINT], z2_in[MAXPOINT]; + double lon_out[20], lat_out[20]; + double x_out[20], y_out[20], z_out[20]; + int n1_in, n2_in, n_out, i, j; + int nlon1=0, nlat1=0, nlon2=0, nlat2=0; + int n; + int ntest = 11; + + + for(n=11; n<=ntest; n++) { + + switch (n) { + case 1: + /**************************************************************** + + test clip_2dx2d_great_cirle case 1: + box 1: (20,10), (20,12), (22,12), (22,10) + box 2: (21,11), (21,14), (24,14), (24,11) + out : (21, 12.0018), (22, 12), (22, 11.0033), (21, 11) + + ****************************************************************/ + n1_in = 4; n2_in = 4; + /* first a simple lat-lon grid box to clip another lat-lon grid box */ + lon1_in[0] = 20; lat1_in[0] = 10; + lon1_in[1] = 20; lat1_in[1] = 12; + lon1_in[2] = 22; lat1_in[2] = 12; + lon1_in[3] = 22; lat1_in[3] = 10; + lon2_in[0] = 21; lat2_in[0] = 11; + lon2_in[1] = 21; lat2_in[1] = 14; + lon2_in[2] = 24; lat2_in[2] = 14; + lon2_in[3] = 24; lat2_in[3] = 11; + break; + + case 2: + /**************************************************************** + + test clip_2dx2d_great_cirle case 2: two identical box + box 1: (20,10), (20,12), (22,12), (22,10) + box 2: (20,10), (20,12), (22,12), (22,10) + out : (20,10), (20,12), (22,12), (22,10) + + ****************************************************************/ + lon1_in[0] = 20; lat1_in[0] = 10; + lon1_in[1] = 20; lat1_in[1] = 12; + lon1_in[2] = 22; lat1_in[2] = 12; + lon1_in[3] = 22; lat1_in[3] = 10; + + for(i=0; i 10 ) { + int nxgrid; + int *i1, *j1, *i2, *j2; + double *xarea, *xclon, *xclat, *mask1; + + mask1 = (double *)malloc(nlon1*nlat1*sizeof(double)); + i1 = (int *)malloc(MAXXGRID*sizeof(int)); + j1 = (int *)malloc(MAXXGRID*sizeof(int)); + i2 = (int *)malloc(MAXXGRID*sizeof(int)); + j2 = (int *)malloc(MAXXGRID*sizeof(int)); + xarea = (double *)malloc(MAXXGRID*sizeof(double)); + xclon = (double *)malloc(MAXXGRID*sizeof(double)); + xclat = (double *)malloc(MAXXGRID*sizeof(double)); + + for(i=0; i1) then if(index(xgrid_file,trim(tile_name))==0) cycle endif + found_xgrid_files = found_xgrid_files + 1 + !---make sure the atmosphere grid is not a nested grid + is_nest = .false. + do m = 1, num_nest_tile + if(index(xgrid_file, trim(nest_tile_name(m))) .NE. 0) then + is_nest = .true. + exit + end if + end do + if(is_nest) cycle + ! finally read the exchange grid nxgrid = get_mosaic_xgrid_size(grid_dir//xgrid_file) allocate(i1(nxgrid), j1(nxgrid), i2(nxgrid), j2(nxgrid), xgrid_area(nxgrid)) @@ -301,7 +354,12 @@ subroutine get_grid_comp_area(component,tile,area,domain) end do deallocate(i1, j1, i2, j2, xgrid_area) enddo + if (found_xgrid_files == 0) & + call error_mesg('get_grid_comp_area', 'no xgrid files were found for component '& + //trim(component)//' (mosaic name is '//trim(mosaic_name)//')', FATAL) + endif + deallocate(nest_tile_name) end select ! version ! convert area to m2 area = area*4*PI*radius**2 @@ -321,7 +379,7 @@ subroutine get_grid_cell_vertices_1D(component, tile, glonb, glatb) integer :: nlon, nlat integer :: start(4), nread(4) - real, allocatable :: tmp(:,:) + real, allocatable :: tmp(:,:), x_vert_t(:,:,:), y_vert_t(:,:,:) character(len=MAX_FILE) :: filename1, filename2 call get_grid_size_for_one_tile(component, tile, nlon, nlat) @@ -353,8 +411,22 @@ subroutine get_grid_cell_vertices_1D(component, tile, glonb, glatb) call read_data(grid_file, 'xb'//lowercase(component(1:1)), glonb, no_domain=.true.) call read_data(grid_file, 'yb'//lowercase(component(1:1)), glatb, no_domain=.true.) case('OCN') - call error_mesg(module_name//'/get_grid_cell_vertices_1D',& - 'reading of OCN grid vertices from VERSION_1 grid specs is not implemented', FATAL) + allocate (x_vert_t(nlon,1,2), y_vert_t(1,nlat,2) ) + start = 1; nread = 1 + nread(1) = nlon; nread(2) = 1; start(3) = 1 + call read_data(grid_file, "x_vert_T", x_vert_t(:,:,1), start, nread, no_domain=.TRUE.) + nread(1) = nlon; nread(2) = 1; start(3) = 2 + call read_data(grid_file, "x_vert_T", x_vert_t(:,:,2), start, nread, no_domain=.TRUE.) + + nread(1) = 1; nread(2) = nlat; start(3) = 1 + call read_data(grid_file, "y_vert_T", y_vert_t(:,:,1), start, nread, no_domain=.TRUE.) + nread(1) = 1; nread(2) = nlat; start(3) = 4 + call read_data(grid_file, "y_vert_T", y_vert_t(:,:,2), start, nread, no_domain=.TRUE.) + glonb(1:nlon) = x_vert_t(1:nlon,1,1) + glonb(nlon+1) = x_vert_t(nlon,1,2) + glatb(1:nlat) = y_vert_t(1,1:nlat,1) + glatb(nlat+1) = y_vert_t(1,nlat,2) + deallocate(x_vert_t, y_vert_t) end select case(VERSION_2) ! get the name of the mosaic file for the component @@ -445,13 +517,16 @@ subroutine get_grid_cell_vertices_2D(component, tile, lonb, latb, domain) enddo deallocate(buffer) case('OCN') - !!!!!! ERROR: this is not going to work when domain is present, because the size of the - ! domain is smaller by 1 then the size of the vertices array - if (present(domain)) & - call error_mesg(module_name//'/get_grid_cell_vertices',& - 'reading of OCN grid vertices from VERSION_0 grid specs for non-global domain is not implemented', FATAL) - call read_data(grid_file, 'geolon_vert_t', lonb, no_domain=.not.present(domain), domain=domain ) - call read_data(grid_file, 'geolat_vert_t', latb, no_domain=.not.present(domain), domain=domain ) + if (present(domain)) then + start = 1; nread = 1 + start(1) = is; start(2) = js + nread(1) = ie-is+2; nread(2) = je-js+2 + call read_data(grid_file, 'geolon_vert_t', lonb, start, nread, no_domain=.true. ) + call read_data(grid_file, 'geolat_vert_t', latb, start, nread, no_domain=.true. ) + else + call read_data(grid_file, 'geolon_vert_t', lonb, no_domain=.TRUE. ) + call read_data(grid_file, 'geolat_vert_t', latb, no_domain=.TRUE. ) + endif end select case(VERSION_1) select case(component) diff --git a/src/shared/mosaic/interp.c b/src/shared/mosaic/interp.c index 33b85f7705..4c8ee80934 100644 --- a/src/shared/mosaic/interp.c +++ b/src/shared/mosaic/interp.c @@ -286,6 +286,59 @@ void conserve_interp(int nx_src, int ny_src, int nx_dst, int ny_dst, const doubl }; /* conserve_interp */ +/*------------------------------------------------------------------------------ + void conserve_interp_great_circle() + conservative interpolation through exchange grid. + Currently only first order interpolation are implemented here. + great_circle algorithm is used for clipping and interpolation. + ----------------------------------------------------------------------------*/ +void conserve_interp_great_circle(int nx_src, int ny_src, int nx_dst, int ny_dst, const double *x_src, + const double *y_src, const double *x_dst, const double *y_dst, + const double *mask_src, const double *data_src, double *data_dst ) +{ + int n, nxgrid; + int *xgrid_i1, *xgrid_j1, *xgrid_i2, *xgrid_j2; + double *xgrid_area, *dst_area, *area_frac, *xgrid_di, *xgrid_dj; + + /* get the exchange grid between source and destination grid. */ + xgrid_i1 = (int *)malloc(MAXXGRID*sizeof(int)); + xgrid_j1 = (int *)malloc(MAXXGRID*sizeof(int)); + xgrid_i2 = (int *)malloc(MAXXGRID*sizeof(int)); + xgrid_j2 = (int *)malloc(MAXXGRID*sizeof(int)); + xgrid_area = (double *)malloc(MAXXGRID*sizeof(double)); + xgrid_di = (double *)malloc(MAXXGRID*sizeof(double)); + xgrid_dj = (double *)malloc(MAXXGRID*sizeof(double)); + dst_area = (double *)malloc(nx_dst*ny_dst*sizeof(double)); + nxgrid = create_xgrid_great_circle(&nx_src, &ny_src, &nx_dst, &ny_dst, x_src, y_src, x_dst, y_dst, mask_src, + xgrid_i1, xgrid_j1, xgrid_i2, xgrid_j2, xgrid_area, xgrid_di, xgrid_dj ); + /* The source grid may not cover the destination grid + so need to sum of exchange grid area to get dst_area + get_grid_area(&nx_dst, &ny_dst, x_dst, y_dst, dst_area); + */ + for(n=0; n ! area of the exchange grid. The area is scaled to represent unit earth area. ! - subroutine get_mosaic_xgrid(xgrid_file, i1, j1, i2, j2, area, di, dj) + subroutine get_mosaic_xgrid(xgrid_file, i1, j1, i2, j2, area, di, dj, istart, iend) character(len=*), intent(in) :: xgrid_file integer, intent(inout) :: i1(:), j1(:), i2(:), j2(:) real, intent(inout) :: area(:) real, optional,intent(inout) :: di(:), dj(:) + integer, optional,intent(in) :: istart, iend character(len=len_trim(xgrid_file)+1) :: xfile integer :: n, strlen, nxgrid @@ -142,10 +145,17 @@ subroutine get_mosaic_xgrid(xgrid_file, i1, j1, i2, j2, area, di, dj) nxgrid = size(i1(:)) if(PRESENT(di)) then + if( PRESENT(istart) .OR. PRESENT(iend) ) & + call mpp_error(FATAL, "mosaic_mod: istart and iend should not present when di is present, contact developer") if(.NOT. PRESENT(dj) ) call mpp_error(FATAL, "mosaic_mod: when di is present, dj should be present") call read_mosaic_xgrid_order2(xfile, i1, j1, i2, j2, area, di, dj) else - call read_mosaic_xgrid_order1(xfile, i1, j1, i2, j2, area) + if( PRESENT(istart) .AND. PRESENT(iend) ) then + if( iend-istart+1 .NE. nxgrid) call mpp_error(FATAL, "mosaic_mod: iend-istart+1 must equal size(i1)") + call read_mosaic_xgrid_order1_region(xfile, i1, j1, i2, j2, area, istart-1, iend-1) ! convert to c-index + else + call read_mosaic_xgrid_order1(xfile, i1, j1, i2, j2, area) + endif end if ! in C, programming, the starting index is 0, so need add 1 to the index. @@ -378,6 +388,71 @@ subroutine calc_mosaic_grid_area(lon, lat, area) end subroutine calc_mosaic_grid_area ! + !############################################################################### + ! + ! + ! calculate grid cell area using great cirlce algorithm + ! + ! + ! calculate the grid cell area. The purpose of this routine is to make + ! sure the consistency between model grid area and exchange grid area. + ! + ! + ! + ! geographical longitude of grid cell vertices. + ! + ! + ! geographical latitude of grid cell vertices. + ! + ! + ! grid cell area. + ! + subroutine calc_mosaic_grid_great_circle_area(lon, lat, area) + real, dimension(:,:), intent(in) :: lon + real, dimension(:,:), intent(in) :: lat + real, dimension(:,:), intent(inout) :: area + integer :: nlon, nlat + + + nlon = size(area,1) + nlat = size(area,2) + ! make sure size of lon, lat and area are consitency + if( size(lon,1) .NE. nlon+1 .OR. size(lat,1) .NE. nlon+1 ) & + call mpp_error(FATAL, "mosaic_mod: size(lon,1) and size(lat,1) should equal to size(area,1)+1") + if( size(lon,2) .NE. nlat+1 .OR. size(lat,2) .NE. nlat+1 ) & + call mpp_error(FATAL, "mosaic_mod: size(lon,2) and size(lat,2) should equal to size(area,2)+1") + + call get_grid_great_circle_area( nlon, nlat, lon, lat, area) + + end subroutine calc_mosaic_grid_great_circle_area + ! + + !##################################################################### + ! This function check if a point (lon1,lat1) is inside a polygon (lon2(:), lat2(:)) + ! lon1, lat1, lon2, lat2 are in radians. + function is_inside_polygon(lon1, lat1, lon2, lat2 ) + real, intent(in) :: lon1, lat1 + real, intent(in) :: lon2(:), lat2(:) + logical :: is_inside_polygon + real, dimension(size(lon2(:))) :: x2, y2, z2 + integer :: npts, isinside + integer :: inside_a_polygon + + npts = size(lon2(:)) + + isinside = inside_a_polygon(lon1, lat1, npts, lon2, lat2) + if(isinside == 1) then + is_inside_polygon = .TRUE. + else + is_inside_polygon = .FALSE. + endif + + return + + end function is_inside_polygon + end module mosaic_mod diff --git a/src/shared/mosaic/mosaic_util.c b/src/shared/mosaic/mosaic_util.c index f87cd6f43b..995fad7cb0 100644 --- a/src/shared/mosaic/mosaic_util.c +++ b/src/shared/mosaic/mosaic_util.c @@ -11,12 +11,29 @@ #define HPI (0.5*M_PI) #define TPI (2.0*M_PI) #define TOLORENCE (1.e-6) -#define EPSLN (1.e-10) +#define EPSLN8 (1.e-8) +#define EPSLN10 (1.e-10) +#define EPSLN15 (1.e-15) +#define EPSLN30 (1.e-30) /*********************************************************** void error_handler(char *str) error handler: will print out error message and then abort ***********************************************************/ +int reproduce_siena = 0; +void set_reproduce_siena_true(void) +{ + reproduce_siena = 1; +} + +#ifndef __AIX +void set_reproduce_siena_true_(void) +{ + reproduce_siena = 1; +} +#endif + + void error_handler(const char *msg) { fprintf(stderr, "FATAL Error: %s\n", msg ); @@ -205,7 +222,7 @@ void xyz2latlon( int np, const double *x, const double *y, const double *z, doub yy /= dist; zz /= dist; - if ( fabs(xx)+fabs(yy) < EPSLN ) + if ( fabs(xx)+fabs(yy) < EPSLN10 ) lon[i] = 0; else lon[i] = atan2(yy, xx); @@ -260,13 +277,14 @@ double poly_area_dimensionless(const double x[], const double y[], int n) if ( fabs(lat1-lat2) < SMALL_VALUE) /* cheap area calculation along latitude */ area -= dx*sin(0.5*(lat1+lat2)); else { -#ifdef fix_truncate - dy = 0.5*(lat1-lat2); - dat = sin(dy)/dy; - area -= dx*sin(0.5*(lat1+lat2))*dat; -#else - area += dx*(cos(lat1)-cos(lat2))/(lat1-lat2); -#endif + if(reproduce_siena) { + area += dx*(cos(lat1)-cos(lat2))/(lat1-lat2); + } + else { + dy = 0.5*(lat1-lat2); + dat = sin(dy)/dy; + area -= dx*sin(0.5*(lat1+lat2))*dat; + } } } if(area < 0) @@ -296,13 +314,14 @@ double poly_area(const double x[], const double y[], int n) if ( fabs(lat1-lat2) < SMALL_VALUE) /* cheap area calculation along latitude */ area -= dx*sin(0.5*(lat1+lat2)); else { -#ifdef fix_truncate - dy = 0.5*(lat1-lat2); - dat = sin(dy)/dy; - area -= dx*sin(0.5*(lat1+lat2))*dat; -#else - area += dx*(cos(lat1)-cos(lat2))/(lat1-lat2); -#endif + if(reproduce_siena) { + area += dx*(cos(lat1)-cos(lat2))/(lat1-lat2); + } + else { + dy = 0.5*(lat1-lat2); + dat = sin(dy)/dy; + area -= dx*sin(0.5*(lat1+lat2))*dat; + } } } if(area < 0) @@ -445,6 +464,34 @@ double great_circle_distance(double *p1, double *p2) }; /* great_circle_distance */ +/* Compute the great circle area of a polygon on a sphere */ +double great_circle_area(int n, const double *x, const double *y, const double *z) { + int i; + double pnt0[3], pnt1[3], pnt2[3]; + double sum, area; + + /* sum angles around polygon */ + sum=0.0; + for ( i=0; i 0) { - angle = acos((px*qx+py*qy+pz*qz)/ddd); - } - else - angle = 0.; + ddd = (px*px+py*py+pz*pz)*(qx*qx+qy*qy+qz*qz); + if ( ddd <= 0.0 ) + angle = 0. ; + else { + ddd = (px*qx+py*qy+pz*qz) / sqrt(ddd); + if( fabs(ddd-1) < EPSLN30 ) ddd = 1; + if( fabs(ddd+1) < EPSLN30 ) ddd = -1; + if ( ddd>1. || ddd<-1. ) { + /*FIX (lmh) to correctly handle co-linear points (angle near pi or 0) */ + if (ddd < 0.) + angle = M_PI; + else + angle = 0.; + } + else + angle = acosl( ddd ); + } + return angle; }; /* spherical_angle */ @@ -537,6 +598,25 @@ void vect_cross(const double *p1, const double *p2, double *e ) }; /* vect_cross */ + +/*---------------------------------------------------------------------- + double* vect_cross(p1, p2) + return cross products of 3D vectors: = P1 X P2 + -------------------------------------------------------------------*/ + +double dot(const double *p1, const double *p2) +{ + + return( p1[0]*p2[0] + p1[1]*p2[1] + p1[2]*p2[2] ); + +} + + +double metric(const double *p) { + return (sqrt(p[0]*p[0] + p[1]*p[1]+p[2]*p[2]) ); +} + + /* ---------------------------------------------------------------- make a unit vector --------------------------------------------------------------*/ @@ -578,3 +658,694 @@ void unit_vect_latlon(int size, const double *lon, const double *lat, double *vl vlat[3*n+2] = cos_lat; } }; /* unit_vect_latlon */ + + +/* Intersect a line and a plane + Intersects between the plane ( three points ) (entries in counterclockwise order) + and the line determined by the endpoints l1 and l2 (t=0.0 at l1 and t=1.0 at l2) + returns true if the two intersect and the output variables are valid + outputs p containing the coordinates in the tri and t the coordinate in the line + of the intersection. + NOTE: the intersection doesn't have to be inside the tri or line for this to return true +*/ +int intersect_tri_with_line(const double *plane, const double *l1, const double *l2, double *p, + double *t) { + + long double M[3*3], inv_M[3*3]; + long double V[3]; + long double X[3]; + int is_invert=0; + + const double *pnt0=plane; + const double *pnt1=plane+3; + const double *pnt2=plane+6; + + /* To do intersection just solve the set of linear equations for both + Setup M + */ + M[0]=l1[0]-l2[0]; M[1]=pnt1[0]-pnt0[0]; M[2]=pnt2[0]-pnt0[0]; + M[3]=l1[1]-l2[1]; M[4]=pnt1[1]-pnt0[1]; M[5]=pnt2[1]-pnt0[1]; + M[6]=l1[2]-l2[2]; M[7]=pnt1[2]-pnt0[2]; M[8]=pnt2[2]-pnt0[2]; + + + /* Invert M */ + is_invert = invert_matrix_3x3(M,inv_M); + if (!is_invert) return 0; + + /* Set variable holding vector */ + V[0]=l1[0]-pnt0[0]; + V[1]=l1[1]-pnt0[1]; + V[2]=l1[2]-pnt0[2]; + + /* Calculate solution */ + mult(inv_M, V, X); + + /* Get answer out */ + *t=X[0]; + p[0]=X[1]; + p[1]=X[2]; + + return 1; +} + + +void mult(long double m[], long double v[], long double out_v[]) { + + out_v[0]=m[0]*v[0]+m[1]*v[1]+m[2]*v[2]; + out_v[1]=m[3]*v[0]+m[4]*v[1]+m[5]*v[2]; + out_v[2]=m[6]*v[0]+m[7]*v[1]+m[8]*v[2]; + +} + + +/* returns 1 if matrix is inverted, 0 otherwise */ +int invert_matrix_3x3(long double m[], long double m_inv[]) { + + + const long double det = m[0] * (m[4]*m[8] - m[5]*m[7]) + -m[1] * (m[3]*m[8] - m[5]*m[6]) + +m[2] * (m[3]*m[7] - m[4]*m[6]); +#ifdef test_invert_matrix_3x3 + printf("det = %Lf\n", det); +#endif + if (fabs(det) < EPSLN15 ) return 0; + + const long double deti = 1.0/det; + + m_inv[0] = (m[4]*m[8] - m[5]*m[7]) * deti; + m_inv[1] = (m[2]*m[7] - m[1]*m[8]) * deti; + m_inv[2] = (m[1]*m[5] - m[2]*m[4]) * deti; + + m_inv[3] = (m[5]*m[6] - m[3]*m[8]) * deti; + m_inv[4] = (m[0]*m[8] - m[2]*m[6]) * deti; + m_inv[5] = (m[2]*m[3] - m[0]*m[5]) * deti; + + m_inv[6] = (m[3]*m[7] - m[4]*m[6]) * deti; + m_inv[7] = (m[1]*m[6] - m[0]*m[7]) * deti; + m_inv[8] = (m[0]*m[4] - m[1]*m[3]) * deti; + + return 1; +} + +#ifndef MAXNODELIST +#define MAXNODELIST 100 +#endif + +struct Node *nodeList=NULL; +int curListPos=0; + +void rewindList(void) +{ + int n; + + curListPos = 0; + if(!nodeList) nodeList = (struct Node *)malloc(MAXNODELIST*sizeof(struct Node)); + for(n=0; n MAXNODELIST) error_handler("getNext: curListPos >= MAXNODELIST"); + + return (temp); +} + + +void initNode(struct Node *node) +{ + node->x = 0; + node->y = 0; + node->z = 0; + node->u = 0; + node->intersect = 0; + node->inbound = 0; + node->isInside = 0; + node->Next = NULL; + node->initialized=0; + +} + +void addEnd(struct Node *list, double x, double y, double z, int intersect, double u, int inbound, int inside) +{ + + struct Node *temp=NULL; + + if(list == NULL) error_handler("addEnd: list is NULL"); + + if(list->initialized) { + + /* (x,y,z) might already in the list when intersect is true and u=0 or 1 */ + temp = list; + while (temp) { + if(samePoint(temp->x, temp->y, temp->z, x, y, z)) return; + temp=temp->Next; + } + temp = list; + while(temp->Next) + temp=temp->Next; + + /* Append at the end of the list. */ + temp->Next = getNext(); + temp = temp->Next; + } + else { + temp = list; + } + + temp->x = x; + temp->y = y; + temp->z = z; + temp->u = u; + temp->intersect = intersect; + temp->inbound = inbound; + temp->initialized=1; + temp->isInside = inside; +} + +/* return 1 if the point (x,y,z) is added in the list, return 0 if it is already in the list */ + +int addIntersect(struct Node *list, double x, double y, double z, int intersect, double u1, double u2, int inbound, + int is1, int ie1, int is2, int ie2) +{ + + double u1_cur, u2_cur; + int i1_cur, i2_cur; + struct Node *temp=NULL; + + if(list == NULL) error_handler("addEnd: list is NULL"); + + /* first check to make sure this point is not in the list */ + u1_cur = u1; + i1_cur = is1; + u2_cur = u2; + i2_cur = is2; + if(u1_cur == 1) { + u1_cur = 0; + i1_cur = ie1; + } + if(u2_cur == 1) { + u2_cur = 0; + i2_cur = ie2; + } + + if(list->initialized) { + temp = list; + while(temp) { + if( temp->u == u1_cur && temp->subj_index == i1_cur) return 0; + if( temp->u_clip == u2_cur && temp->clip_index == i2_cur) return 0; + if( !temp->Next ) break; + temp=temp->Next; + } + + /* Append at the end of the list. */ + temp->Next = getNext(); + temp = temp->Next; + } + else { + temp = list; + } + + temp->x = x; + temp->y = y; + temp->z = z; + temp->intersect = intersect; + temp->inbound = inbound; + temp->initialized=1; + temp->isInside = 0; + temp->u = u1_cur; + temp->subj_index = i1_cur; + temp->u_clip = u2_cur; + temp->clip_index = i2_cur; + + return 1; +} + + +int length(struct Node *list) +{ + struct Node *cur_ptr=NULL; + int count=0; + + cur_ptr=list; + + while(cur_ptr) + { + if(cur_ptr->initialized ==0) break; + cur_ptr=cur_ptr->Next; + count++; + } + return(count); +} + +/* two points are the same if there are close enough */ +int samePoint(double x1, double y1, double z1, double x2, double y2, double z2) +{ + if( fabs(x1-x2) > EPSLN10 || fabs(y1-y2) > EPSLN10 || fabs(z1-z2) > EPSLN10 ) + return 0; + else + return 1; +} + + + +int sameNode(struct Node node1, struct Node node2) +{ + if( node1.x == node2.x && node1.y == node2.y && node1.z==node2.z ) + return 1; + else + return 0; +} + + +void addNode(struct Node *list, struct Node inNode) +{ + + addEnd(list, inNode.x, inNode.y, inNode.z, inNode.intersect, inNode.u, inNode.inbound, inNode.isInside); + +} + +struct Node *getNode(struct Node *list, struct Node inNode) +{ + struct Node *thisNode=NULL; + struct Node *temp=NULL; + + temp = list; + while( temp ) { + if( sameNode( *temp, inNode ) ) { + thisNode = temp; + temp = NULL; + break; + } + temp = temp->Next; + } + + return thisNode; +} + +struct Node *getNextNode(struct Node *list) +{ + return list->Next; +} + +void copyNode(struct Node *node_out, struct Node node_in) +{ + + node_out->x = node_in.x; + node_out->y = node_in.y; + node_out->z = node_in.z; + node_out->u = node_in.u; + node_out->intersect = node_in.intersect; + node_out->inbound = node_in.inbound; + node_out->Next = NULL; + node_out->initialized = node_in.initialized; + node_out->isInside = node_in.isInside; +} + +void printNode(struct Node *list, char *str) +{ + struct Node *temp; + + if(list == NULL) error_handler("printNode: list is NULL"); + if(str) printf(" %s \n", str); + temp = list; + while(temp) { + if(temp->initialized ==0) break; + printf(" (x, y, z, interset, inbound, isInside) = (%19.15f,%19.15f,%19.15f,%d,%d,%d)\n", + temp->x, temp->y, temp->z, temp->intersect, temp->inbound, temp->isInside); + temp = temp->Next; + } + printf("\n"); +} + +int intersectInList(struct Node *list, double x, double y, double z) +{ + struct Node *temp; + int found=0; + + temp = list; + found = 0; + while ( temp ) { + if( temp->x == x && temp->y == y && temp->z == z ) { + found = 1; + break; + } + temp=temp->Next; + } + if (!found) error_handler("intersectInList: point (x,y,z) is not found in the list"); + if( temp->intersect == 2 ) + return 1; + else + return 0; + +} + + +/* The following insert a intersection after non-intersect point (x2,y2,z2), if the point + after (x2,y2,z2) is an intersection, if u is greater than the u value of the intersection, + insert after, otherwise insert before +*/ +void insertIntersect(struct Node *list, double x, double y, double z, double u1, double u2, int inbound, + double x2, double y2, double z2) +{ + struct Node *temp1=NULL, *temp2=NULL; + struct Node *temp; + double u_cur; + int found=0; + + temp1 = list; + found = 0; + while ( temp1 ) { + if( temp1->x == x2 && temp1->y == y2 && temp1->z == z2 ) { + found = 1; + break; + } + temp1=temp1->Next; + } + if (!found) error_handler("inserAfter: point (x,y,z) is not found in the list"); + + /* when u = 0 or u = 1, set the grid point to be the intersection point to solve truncation error isuse */ + u_cur = u1; + if(u1 == 1) { + u_cur = 0; + temp1 = temp1->Next; + if(!temp1) temp1 = list; + } + if(u_cur==0) { + temp1->intersect = 2; + temp1->isInside = 1; + temp1->u = u_cur; + temp1->x = x; + temp1->y = y; + temp1->z = z; + return; + } + + /* when u2 != 0 and u2 !=1, can decide if one end of the point is outside depending on inbound value */ + if(u2 != 0 && u2 != 1) { + if(inbound == 1) { /* goes outside, then temp1->Next is an outside point */ + /* find the next non-intersect point */ + temp2 = temp1->Next; + if(!temp2) temp2 = list; + while(temp2->intersect) { + temp2=temp2->Next; + if(!temp2) temp2 = list; + } + + temp2->isInside = 0; + } + else if(inbound ==2) { /* goes inside, then temp1 is an outside point */ + temp1->isInside = 0; + } + } + + temp2 = temp1->Next; + while ( temp2 ) { + if( temp2->intersect == 1 ) { + if( temp2->u > u_cur ) { + break; + } + } + else + break; + temp1 = temp2; + temp2 = temp2->Next; + } + + /* assign value */ + temp = getNext(); + temp->x = x; + temp->y = y; + temp->z = z; + temp->u = u_cur; + temp->intersect = 1; + temp->inbound = inbound; + temp->isInside = 1; + temp->initialized = 1; + temp1->Next = temp; + temp->Next = temp2; + +} + +double gridArea(struct Node *grid) { + double x[20], y[20], z[20]; + struct Node *temp=NULL; + double area; + int n; + + temp = grid; + n = 0; + while( temp ) { + x[n] = temp->x; + y[n] = temp->y; + z[n] = temp->z; + n++; + temp = temp->Next; + } + + area = great_circle_area(n, x, y, z); + + return area; + +} + +int isIntersect(struct Node node) { + + return node.intersect; + +} + + +int getInbound( struct Node node ) +{ + return node.inbound; +} + +struct Node *getLast(struct Node *list) +{ + struct Node *temp1; + + temp1 = list; + if( temp1 ) { + while( temp1->Next ) { + temp1 = temp1->Next; + } + } + + return temp1; +} + + +int getFirstInbound( struct Node *list, struct Node *nodeOut) +{ + struct Node *temp=NULL; + + temp=list; + + while(temp) { + if( temp->inbound == 2 ) { + copyNode(nodeOut, *temp); + return 1; + } + temp=temp->Next; + } + + return 0; +} + +void getCoordinate(struct Node node, double *x, double *y, double *z) +{ + + + *x = node.x; + *y = node.y; + *z = node.z; + +} + +void getCoordinates(struct Node *node, double *p) +{ + + + p[0] = node->x; + p[1] = node->y; + p[2] = node->z; + +} + +void setCoordinate(struct Node *node, double x, double y, double z) +{ + + + node->x = x; + node->y = y; + node->z = z; + +} + +/* set inbound value for the points in interList that has inbound =0, + this will also set some inbound value of the points in list1 +*/ + +void setInbound(struct Node *interList, struct Node *list) +{ + + struct Node *temp1=NULL, *temp=NULL; + struct Node *temp1_prev=NULL, *temp1_next=NULL; + int prev_is_inside, next_is_inside; + + /* for each point in interList, search through list to decide the inbound value the interList point */ + /* For each inbound point, the prev node should be outside and the next is inside. */ + if(length(interList) == 0) return; + + temp = interList; + + while(temp) { + if( !temp->inbound) { + /* search in grid1 to find the prev and next point of temp, when prev point is outside and next point is inside + inbound = 2, else inbound = 1*/ + temp1 = list; + temp1_prev = NULL; + temp1_next = NULL; + while(temp1) { + if(sameNode(*temp1, *temp)) { + if(!temp1_prev) temp1_prev = getLast(list); + temp1_next = temp1->Next; + if(!temp1_next) temp1_next = list; + break; + } + temp1_prev = temp1; + temp1 = temp1->Next; + } + if(!temp1_next) error_handler("Error from create_xgrid.c: temp is not in list1"); + if( temp1_prev->isInside == 0 && temp1_next->isInside == 1) + temp->inbound = 2; /* go inside */ + else + temp->inbound = 1; + } + temp=temp->Next; + } +} + +int isInside(struct Node *node) { + + if(node->isInside == -1) error_handler("Error from mosaic_util.c: node->isInside is not set"); + return(node->isInside); + +} + +/* #define debug_test_create_xgrid */ + +/* check if node is inside polygon list or not */ + int insidePolygon( struct Node *node, struct Node *list) +{ + int i, ip, is_inside; + double pnt0[3], pnt1[3], pnt2[3]; + double anglesum; + struct Node *p1=NULL, *p2=NULL; + + anglesum = 0; + + pnt0[0] = node->x; + pnt0[1] = node->y; + pnt0[2] = node->z; + + p1 = list; + p2 = list->Next; + is_inside = 0; + + + while(p1) { + pnt1[0] = p1->x; + pnt1[1] = p1->y; + pnt1[2] = p1->z; + pnt2[0] = p2->x; + pnt2[1] = p2->y; + pnt2[2] = p2->z; + if(samePoint(pnt0[0], pnt0[1], pnt0[2], pnt1[0], pnt1[1], pnt1[2])) return 1; + anglesum += spherical_angle(pnt0, pnt2, pnt1); + p1 = p1->Next; + p2 = p2->Next; + if(p2==NULL)p2 = list; + } + + if( fabs(anglesum - 2*M_PI) < EPSLN8 ) + is_inside = 1; + else + is_inside = 0; + +#ifdef debug_test_create_xgrid + printf("anglesum-2PI is %19.15f, is_inside = %d\n", anglesum- 2*M_PI, is_inside); +#endif + + return is_inside; + +} + +int inside_a_polygon(double *lon1, double *lat1, int *npts, double *lon2, double *lat2) +{ + + double x2[20], y2[20], z2[20]; + double x1, y1, z1; + double min_x2, max_x2, min_y2, max_y2, min_z2, max_z2; + int isinside, i; + + struct Node *grid1=NULL, *grid2=NULL; + + /* first convert to cartesian grid */ + latlon2xyz(*npts, lon2, lat2, x2, y2, z2); + latlon2xyz(1, lon1, lat1, &x1, &y1, &z1); + + max_x2 = maxval_double(*npts, x2); + if(x1 >= max_x2+RANGE_CHECK_CRITERIA) return 0; + min_x2 = minval_double(*npts, x2); + if(min_x2 >= x1+RANGE_CHECK_CRITERIA) return 0; + + max_y2 = maxval_double(*npts, y2); + if(y1 >= max_y2+RANGE_CHECK_CRITERIA) return 0; + min_y2 = minval_double(*npts, y2); + if(min_y2 >= y1+RANGE_CHECK_CRITERIA) return 0; + + max_z2 = maxval_double(*npts, z2); + if(z1 >= max_z2+RANGE_CHECK_CRITERIA) return 0; + min_z2 = minval_double(*npts, z2); + if(min_z2 >= z1+RANGE_CHECK_CRITERIA) return 0; + + + /* add x2,y2,z2 to a Node */ + rewindList(); + grid1 = getNext(); + grid2 = getNext(); + + addEnd(grid1, x1, y1, z1, 0, 0, 0, -1); + for(i=0; i<*npts; i++) addEnd(grid2, x2[i], y2[i], z2[i], 0, 0, 0, -1); + + isinside = insidePolygon(grid1, grid2); + + return isinside; + +} + +#ifndef __AIX +int inside_a_polygon_(double *lon1, double *lat1, int *npts, double *lon2, double *lat2) +{ + + int isinside; + + isinside = inside_a_polygon(lon1, lat1, npts, lon2, lat2); + + return isinside; + +} +#endif + diff --git a/src/shared/mosaic/mosaic_util.h b/src/shared/mosaic/mosaic_util.h index 6191cf7cbd..0641640981 100644 --- a/src/shared/mosaic/mosaic_util.h +++ b/src/shared/mosaic/mosaic_util.h @@ -7,9 +7,25 @@ #ifndef MOSAIC_UTIL_H_ #define MOSAIC_UTIL_H_ +#ifndef RANGE_CHECK_CRITERIA +#define RANGE_CHECK_CRITERIA 0.05 +#endif + #define min(a,b) (ab ? a:b) #define SMALL_VALUE ( 1.e-10 ) +struct Node{ + double x, y, z, u, u_clip; + int intersect; /* indicate if this point is an intersection, 0 = no, 1= yes, 2=both intersect and vertices */ + int inbound; /* -1 uninitialized, 0 coincident, 1 outbound, 2 inbound */ + int initialized; /* = 0 means empty list */ + int isInside; /* = 1 means one point is inside the other polygon, 0 is not, -1 undecided. */ + int subj_index; /* the index of subject point that an intersection follow. */ + int clip_index; /* the index of clip point that an intersection follow */ + struct Node *Next; +}; + + void error_handler(const char *msg); int nearest_index(double value, const double *array, int ia); int lon_fix(double *x, double *y, int n_in, double tlon); @@ -32,4 +48,45 @@ void vect_cross(const double *p1, const double *p2, double *e ); double spherical_angle(const double *v1, const double *v2, const double *v3); void normalize_vect(double *e); void unit_vect_latlon(int size, const double *lon, const double *lat, double *vlon, double *vlat); +double great_circle_area(int n, const double *x, const double *y, const double *z); +double * cross(const double *p1, const double *p2); +double dot(const double *p1, const double *p2); +int intersect_tri_with_line(const double *plane, const double *l1, const double *l2, double *p, + double *t); +int invert_matrix_3x3(long double m[], long double m_inv[]); +void mult(long double m[], long double v[], long double out_v[]); +double metric(const double *p); +int insidePolygon(struct Node *node, struct Node *list ); +int inside_a_polygon( double *lon1, double *lat1, int *npts, double *lon2, double *lat2); + +void rewindList(void); +struct Node *getNext(); +void initNode(struct Node *node); +void addEnd(struct Node *list, double x, double y, double z, int intersect, double u, int inbound, int inside); +int addIntersect(struct Node *list, double x, double y, double z, int intersect, double u1, double u2, + int inbound, int is1, int ie1, int is2, int ie2); +int length(struct Node *list); +int samePoint(double x1, double y1, double z1, double x2, double y2, double z2); +int sameNode(struct Node node1, struct Node node2); +void addNode(struct Node *list, struct Node nodeIn); +struct Node *getNode(struct Node *list, struct Node inNode); +struct Node *getNextNode(struct Node *list); +void copyNode(struct Node *node_out, struct Node node_in); +void printNode(struct Node *list, char *str); +int intersectInList(struct Node *list, double x, double y, double z); +void insertAfter(struct Node *list, double x, double y, double z, int intersect, double u, int inbound, + double x2, double y2, double z2); +double gridArea(struct Node *grid); +int isIntersect(struct Node node); +int getInbound( struct Node node ); +struct Node *getLast(struct Node *list); +int getFirstInbound( struct Node *list, struct Node *nodeOut); +void getCoordinate(struct Node node, double *x, double *y, double *z); +void getCoordinates(struct Node *node, double *p); +void setCoordinate(struct Node *node, double x, double y, double z); +void setInbound(struct Node *interList, struct Node *list); +int isInside(struct Node *node); +void set_reproduce_siena_true(void); + + #endif diff --git a/src/shared/mosaic/read_mosaic.c b/src/shared/mosaic/read_mosaic.c index 5ca40f2392..27ed0b2e4a 100644 --- a/src/shared/mosaic/read_mosaic.c +++ b/src/shared/mosaic/read_mosaic.c @@ -201,12 +201,14 @@ void get_string_data_level(const char *file, const char *name, char *data, const /******************************************************************************* - void get_int_data(const char *file, const char *name, int *data) - get int data of field with "name" from "file". + void get_var_data(const char *file, const char *name, double *data) + get var data of field with "name" from "file". ******************************************************************************/ -void get_int_data(const char *file, const char *name, int *data) +void get_var_data(const char *file, const char *name, void *data) { - int ncid, varid, status; + + int ncid, varid, status; + nc_type vartype; char msg[512]; #ifdef use_netCDF @@ -219,10 +221,32 @@ void get_int_data(const char *file, const char *name, int *data) if(status != NC_NOERR) { sprintf(msg, "in getting varid of %s from file %s.", name, file); handle_netcdf_error(msg, status); - } - status = nc_get_var_int(ncid, varid, data); + } + + status = nc_inq_vartype(ncid, varid, &vartype); if(status != NC_NOERR) { - sprintf(msg, "in getting data of %s from file %s", name, file); + sprintf(msg, "get_var_data: in getting vartype of of %s in file %s ", name, file); + handle_netcdf_error(msg, status); + } + + switch (vartype) { + case NC_DOUBLE:case NC_FLOAT: +#ifdef OVERLOAD_R4 + status = nc_get_var_float(ncid, varid, data); +#else + status = nc_get_var_double(ncid, varid, data); +#endif + break; + case NC_INT: + status = nc_get_var_int(ncid, varid, data); + break; + default: + sprintf(msg, "get_var_data: field %s in file %s has an invalid type, " + "the type should be NC_DOUBLE, NC_FLOAT or NC_INT", name, file); + error_handler(msg); + } + if(status != NC_NOERR) { + sprintf(msg, "in getting data of %s from file %s.", name, file); handle_netcdf_error(msg, status); } status = nc_close(ncid); @@ -234,22 +258,23 @@ void get_int_data(const char *file, const char *name, int *data) error_handler("read_mosaic: Add flag -Duse_netCDF when compiling"); #endif -}; /* get_int_data */ +}; /* get_var_data */ /******************************************************************************* void get_var_data(const char *file, const char *name, double *data) get var data of field with "name" from "file". ******************************************************************************/ -void get_var_data(const char *file, const char *name, void *data) +void get_var_data_region(const char *file, const char *name, const size_t *start, const size_t *nread, void *data) { int ncid, varid, status; + nc_type vartype; char msg[512]; #ifdef use_netCDF status = nc_open(file, NC_NOWRITE, &ncid); if(status != NC_NOERR) { - sprintf(msg, "in opening file %s", file); + sprintf(msg, "get_var_data_region: in opening file %s", file); handle_netcdf_error(msg, status); } status = nc_inq_varid(ncid, name, &varid); @@ -258,26 +283,43 @@ void get_var_data(const char *file, const char *name, void *data) handle_netcdf_error(msg, status); } + status = nc_inq_vartype(ncid, varid, &vartype); + if(status != NC_NOERR) { + sprintf(msg, "get_var_data_region: in getting vartype of of %s in file %s ", name, file); + handle_netcdf_error(msg, status); + } + + switch (vartype) { + case NC_DOUBLE:case NC_FLOAT: #ifdef OVERLOAD_R4 - status = nc_get_var_float(ncid, varid, data); -#else - status = nc_get_var_double(ncid, varid, data); + status = nc_get_vara_float(ncid, varid, start, nread, data); +#else + status = nc_get_vara_double(ncid, varid, start, nread, data); #endif + break; + case NC_INT: + status = nc_get_vara_int(ncid, varid, start, nread, data); + break; + default: + sprintf(msg, "get_var_data_region: field %s in file %s has an invalid type, " + "the type should be NC_DOUBLE, NC_FLOAT or NC_INT", name, file); + error_handler(msg); + } if(status != NC_NOERR) { - sprintf(msg, "in getting data of %s from file %s.", name, file); + sprintf(msg, "get_var_data_region: in getting data of %s from file %s.", name, file); handle_netcdf_error(msg, status); } status = nc_close(ncid); if(status != NC_NOERR) { - sprintf(msg, "in closing file %s.", file); + sprintf(msg, "get_var_data_region: in closing file %s.", file); handle_netcdf_error(msg, status); } #else error_handler("read_mosaic: Add flag -Duse_netCDF when compiling"); #endif -}; /* get_var_data */ +}; /* get_var_data_region */ /****************************************************************************** void get_var_text_att(const char *file, const char *name, const char *attname, char *att) @@ -366,8 +408,8 @@ void read_mosaic_xgrid_order1(const char *xgrid_file, int *i1, int *j1, int *i2, tile1_cell = (int *)malloc(ncells*2*sizeof(int)); tile2_cell = (int *)malloc(ncells*2*sizeof(int)); - get_int_data(xgrid_file, "tile1_cell", tile1_cell); - get_int_data(xgrid_file, "tile2_cell", tile2_cell); + get_var_data(xgrid_file, "tile1_cell", tile1_cell); + get_var_data(xgrid_file, "tile2_cell", tile2_cell); get_var_data(xgrid_file, "xgrid_area", area); @@ -386,6 +428,68 @@ void read_mosaic_xgrid_order1(const char *xgrid_file, int *i1, int *j1, int *i2, }; /* read_mosaic_xgrid_order1 */ + +#ifndef __AIX +#ifdef OVERLOAD_R4 +void read_mosaic_xgrid_order1_region_(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, float *area, int *isc, int *iec ) +#else +void read_mosaic_xgrid_order1_region_(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area, int *isc, int *iec ) +#endif +{ + read_mosaic_xgrid_order1_region(xgrid_file, i1, j1, i2, j2, area, isc, iec); + +}; +#endif + +#ifdef OVERLOAD_R4 +void read_mosaic_xgrid_order1_region(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, float *area, int *isc, int *iec ) +#else +void read_mosaic_xgrid_order1_region(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area, int *isc, int *iec ) +#endif +{ + int ncells, n, i; + int *tile1_cell, *tile2_cell; + size_t start[4], nread[4]; +#ifdef OVERLOAD_R4 + float garea; +#else + double garea; +#endif + + ncells = *iec-*isc+1; + + tile1_cell = (int *)malloc(ncells*2*sizeof(int)); + tile2_cell = (int *)malloc(ncells*2*sizeof(int)); + for(i=0; i<4; i++) { + start[i] = 0; nread[i] = 1; + } + + start[0] = *isc; + nread[0] = ncells; + nread[1] = 2; + + get_var_data_region(xgrid_file, "tile1_cell", start, nread, tile1_cell); + get_var_data_region(xgrid_file, "tile2_cell", start, nread, tile2_cell); + + nread[1] = 1; + + get_var_data_region(xgrid_file, "xgrid_area", start, nread, area); + + garea = 4*M_PI*RADIUS*RADIUS; + + for(n=0; n - - -File shared/mpp/affinity.c - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                              -

                                              File shared/mpp/affinity.c

                                              - - -
                                              -Contact:  -
                                              -Reviewers:  -
                                              -Change History: WebCVS Log -
                                              -
                                              -
                                              - - -
                                              -

                                              OVERVIEW

                                              - -

                                              - - - -
                                              -
                                              - - -
                                              -

                                              MODULES USED

                                              - -
                                              -
                                              
                                              -
                                              - - - -
                                              -

                                              PUBLIC INTERFACE

                                              -
                                              -
                                              -
                                              -
                                              - - -
                                              -

                                              PUBLIC ROUTINES

                                              - -
                                                - - - - - - -
                                                -
                                                -top -
                                                - - diff --git a/src/shared/mpp/include/mpp_comm_mpi.inc b/src/shared/mpp/include/mpp_comm_mpi.inc index 227f165a57..e8024364b0 100644 --- a/src/shared/mpp/include/mpp_comm_mpi.inc +++ b/src/shared/mpp/include/mpp_comm_mpi.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_comm_mpi.inc,v 19.0.2.1 2012/05/08 17:45:39 Zhi.Liang Exp $ +! $Id: mpp_comm_mpi.inc,v 20.0 2013/12/14 00:24:07 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -86,6 +86,13 @@ close(unit_nml) #endif + if (io_status > 0) then + call mpp_error(FATAL,'=>mpp_init: Error reading input.nml') + endif + + if(sync_all_clocks .AND. mpp_pe()==mpp_root_pe() ) call mpp_error(NOTE, & + "mpp_mod: mpp_nml variable sync_all_clocks is set to .true., all clocks are synchronized in mpp_clock_begin.") + ! non-root pe messages written to other location than stdout() if(etc_unit_is_stderr) then diff --git a/src/shared/mpp/include/mpp_comm_nocomm.inc b/src/shared/mpp/include/mpp_comm_nocomm.inc index 704d98bee2..88be6b188b 100644 --- a/src/shared/mpp/include/mpp_comm_nocomm.inc +++ b/src/shared/mpp/include/mpp_comm_nocomm.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_comm_nocomm.inc,v 19.0 2012/01/06 22:00:41 fms Exp $ +! $Id: mpp_comm_nocomm.inc,v 20.0 2013/12/14 00:24:09 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -20,6 +20,7 @@ subroutine mpp_init( flags,localcomm ) module_is_initialized = .TRUE. + allocate(peset(0:0)) !PEsets: make defaults illegal peset(:)%count = -1 peset(:)%id = -1 @@ -62,6 +63,10 @@ subroutine mpp_init( flags,localcomm ) close(unit_nml) #endif + if (io_status > 0) then + call mpp_error(FATAL,'=>mpp_init: Error reading input.nml') + endif + ! non-root pe messages written to other location than stdout() ! 9 is reserved for etc_unit etc_unit=9 diff --git a/src/shared/mpp/include/mpp_comm_sma.inc b/src/shared/mpp/include/mpp_comm_sma.inc index 88154ffcf7..0feda1b7e0 100644 --- a/src/shared/mpp/include/mpp_comm_sma.inc +++ b/src/shared/mpp/include/mpp_comm_sma.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_comm_sma.inc,v 19.0 2012/01/06 22:00:43 fms Exp $ +! $Id: mpp_comm_sma.inc,v 20.0 2013/12/14 00:24:11 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -90,6 +90,11 @@ subroutine mpp_init( flags,localcomm ) close(unit_nml) #endif + if (io_status > 0) then + call mpp_error(FATAL,'=>mpp_init: Error reading input.nml') + endif + + ! non-root pe messages written to other location than stdout() if(etc_unit_is_stderr) then etc_unit = stderr() diff --git a/src/shared/mpp/include/mpp_define_nest_domains.inc b/src/shared/mpp/include/mpp_define_nest_domains.inc index e14baf0755..8b88199551 100644 --- a/src/shared/mpp/include/mpp_define_nest_domains.inc +++ b/src/shared/mpp/include/mpp_define_nest_domains.inc @@ -1,5 +1,5 @@ ! -*-f90-*- -! $Id: mpp_define_nest_domains.inc,v 19.0.4.1.2.1 2012/05/15 18:43:38 z1l Exp $ +! $Id: mpp_define_nest_domains.inc,v 20.0 2013/12/14 00:24:16 fms Exp $ !############################################################################# diff --git a/src/shared/mpp/include/mpp_do_get_boundary.h b/src/shared/mpp/include/mpp_do_get_boundary.h index a3e561df6f..3cd3aa3045 100644 --- a/src/shared/mpp/include/mpp_do_get_boundary.h +++ b/src/shared/mpp/include/mpp_do_get_boundary.h @@ -1,12 +1,12 @@ + ! -*-f90-*- -subroutine MPP_DO_GET_BOUNDARY_3D_( f_addrs, domain, bound, b_addrs, bsize, ke, d_type, flags) +subroutine MPP_DO_GET_BOUNDARY_3D_( f_addrs, domain, bound, b_addrs, bsize, ke, d_type) type(domain2D), intent(in) :: domain type(overlapSpec), intent(in) :: bound integer(LONG_KIND), intent(in) :: f_addrs(:,:) integer(LONG_KIND), intent(in) :: b_addrs(:,:,:) integer, intent(in) :: bsize(:), ke MPP_TYPE_, intent(in) :: d_type ! creates unique interface - integer, intent(in) :: flags MPP_TYPE_ :: field(bound%xbegin:bound%xend, bound%ybegin:bound%yend,ke) MPP_TYPE_ :: ebuffer(bsize(1), ke), sbuffer(bsize(2), ke), wbuffer(bsize(3), ke), nbuffer(bsize(4), ke) @@ -20,7 +20,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_( f_addrs, domain, bound, b_addrs, bsize, ke, logical :: recv(4), send(4) integer :: nlist, buffer_pos, pos, tMe, from_pe integer :: i, j, k, l, m, n, index, buffer_recv_size - integer :: is, ie, js, je, msgsize, l_size + integer :: is, ie, js, je, msgsize, l_size, num character(len=8) :: text integer :: outunit @@ -31,13 +31,52 @@ subroutine MPP_DO_GET_BOUNDARY_3D_( f_addrs, domain, bound, b_addrs, bsize, ke, outunit = stdout() l_size = size(f_addrs,1) - recv(1) = BTEST(flags,EAST) - recv(2) = BTEST(flags,SOUTH) - recv(3) = BTEST(flags,WEST) - recv(4) = BTEST(flags,NORTH) - send = recv + !---- determine recv(1) based on b_addrs ( east boundary ) + num = count(b_addrs(1,:,1) == 0) + if( num == 0 ) then + recv(1) = .true. + else if( num == l_size ) then + recv(1) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary: number of ebuffer with null address should be 0 or l_size") + endif + + !---- determine recv(2) based on b_addrs ( south boundary ) + num = count(b_addrs(2,:,1) == 0) + if( num == 0 ) then + recv(2) = .true. + else if( num == l_size ) then + recv(2) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary: number of sbuffer with null address should be 0 or l_size") + endif + + !---- determine recv(3) based on b_addrs ( west boundary ) + num = count(b_addrs(3,:,1) == 0) + if( num == 0 ) then + recv(3) = .true. + else if( num == l_size ) then + recv(3) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary: number of wbuffer with null address should be 0 or l_size") + endif + !---- determine recv(4) based on b_addrs ( north boundary ) + num = count(b_addrs(4,:,1) == 0) + if( num == 0 ) then + recv(4) = .true. + else if( num == l_size ) then + recv(4) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary: number of nbuffer with null address should be 0 or l_size") + endif + + send = recv nlist = size(domain%list(:)) if(debug_message_passing) then @@ -295,12 +334,13 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, pointer(ptr_nbuffery, nbuffery) integer, allocatable :: msg1(:), msg2(:) - logical :: recv(4), send(4) + logical :: recvx(4), sendx(4) + logical :: recvy(4), sendy(4) integer :: nlist, buffer_pos, pos, tMe, m integer :: is, ie, js, je, msgsize, l_size, buffer_recv_size integer :: i, j, k, l, n, index, to_pe, from_pe integer :: rank_x, rank_y, cur_rank, ind_x, ind_y - integer :: nsend_x, nsend_y, nrecv_x, nrecv_y + integer :: nsend_x, nsend_y, nrecv_x, nrecv_y, num character(len=8) :: text integer :: outunit @@ -310,11 +350,96 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, outunit = stdout() l_size = size(f_addrsx,1) - recv(1) = BTEST(flags,EAST) - recv(2) = BTEST(flags,SOUTH) - recv(3) = BTEST(flags,WEST) - recv(4) = BTEST(flags,NORTH) - send = recv + !---- determine recv(1) based on b_addrs ( east boundary ) + num = count(b_addrsx(1,:,1) == 0) + if( num == 0 ) then + recvx(1) = .true. + else if( num == l_size ) then + recvx(1) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of ebufferx with null address should be 0 or l_size") + endif + + !---- determine recv(2) based on b_addrs ( south boundary ) + num = count(b_addrsx(2,:,1) == 0) + if( num == 0 ) then + recvx(2) = .true. + else if( num == l_size ) then + recvx(2) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of sbufferx with null address should be 0 or l_size") + endif + + !---- determine recv(3) based on b_addrs ( west boundary ) + num = count(b_addrsx(3,:,1) == 0) + if( num == 0 ) then + recvx(3) = .true. + else if( num == l_size ) then + recvx(3) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of wbufferx with null address should be 0 or l_size") + endif + + !---- determine recv(4) based on b_addrs ( north boundary ) + num = count(b_addrsx(4,:,1) == 0) + if( num == 0 ) then + recvx(4) = .true. + else if( num == l_size ) then + recvx(4) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of nbufferx with null address should be 0 or l_size") + endif + + !---- determine recv(1) based on b_addrs ( east boundary ) + num = count(b_addrsy(1,:,1) == 0) + if( num == 0 ) then + recvy(1) = .true. + else if( num == l_size ) then + recvy(1) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of ebuffery with null address should be 0 or l_size") + endif + + !---- determine recv(2) based on b_addrs ( south boundary ) + num = count(b_addrsy(2,:,1) == 0) + if( num == 0 ) then + recvy(2) = .true. + else if( num == l_size ) then + recvy(2) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of sbuffery with null address should be 0 or l_size") + endif + + !---- determine recv(3) based on b_addrs ( west boundary ) + num = count(b_addrsy(3,:,1) == 0) + if( num == 0 ) then + recvy(3) = .true. + else if( num == l_size ) then + recvy(3) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of wbuffery with null address should be 0 or l_size") + endif + + !---- determine recv(4) based on b_addrs ( north boundary ) + num = count(b_addrsy(4,:,1) == 0) + if( num == 0 ) then + recvy(4) = .true. + else if( num == l_size ) then + recvy(4) = .false. + else + if( num .NE. 0 ) call mpp_error(FATAL, & + "mpp_do_get_boundary_V: number of nbuffery with null address should be 0 or l_size") + endif + + sendx = recvx + sendy = recvy nlist = size(domain%list(:)) @@ -335,7 +460,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_x) then from_pe = boundx%recv(ind_x)%pe do n = 1, boundx%recv(ind_x)%count - if(recv(boundx%recv(ind_x)%dir(n))) then + if(recvx(boundx%recv(ind_x)%dir(n))) then is = boundx%recv(ind_x)%is(n); ie = boundx%recv(ind_x)%ie(n) js = boundx%recv(ind_x)%js(n); je = boundx%recv(ind_x)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) @@ -353,7 +478,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_y) then from_pe = boundy%recv(ind_y)%pe do n = 1, boundy%recv(ind_y)%count - if(recv(boundy%recv(ind_y)%dir(n))) then + if(recvy(boundy%recv(ind_y)%dir(n))) then is = boundy%recv(ind_y)%is(n); ie = boundy%recv(ind_y)%ie(n) js = boundy%recv(ind_y)%js(n); je = boundy%recv(ind_y)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) @@ -379,7 +504,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_x) then to_pe = boundx%send(ind_x)%pe do n = 1, boundx%send(ind_x)%count - if(send(boundx%send(ind_x)%dir(n))) then + if(sendx(boundx%send(ind_x)%dir(n))) then is = boundx%send(ind_x)%is(n); ie = boundx%send(ind_x)%ie(n) js = boundx%send(ind_x)%js(n); je = boundx%send(ind_x)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) @@ -397,7 +522,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_y) then to_pe = boundy%send(ind_y)%pe do n = 1, boundy%send(ind_y)%count - if(send(boundy%send(ind_y)%dir(n))) then + if(sendy(boundy%send(ind_y)%dir(n))) then is = boundy%send(ind_y)%is(n); ie = boundy%send(ind_y)%ie(n) js = boundy%send(ind_y)%js(n); je = boundy%send(ind_y)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) @@ -439,7 +564,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_x) then from_pe = boundx%recv(ind_x)%pe do n = 1, boundx%recv(ind_x)%count - if(recv(boundx%recv(ind_x)%dir(n))) then + if(recvx(boundx%recv(ind_x)%dir(n))) then is = boundx%recv(ind_x)%is(n); ie = boundx%recv(ind_x)%ie(n) js = boundx%recv(ind_x)%js(n); je = boundx%recv(ind_x)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) @@ -457,7 +582,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_y) then from_pe = boundy%recv(ind_y)%pe do n = 1, boundy%recv(ind_y)%count - if(recv(boundy%recv(ind_y)%dir(n))) then + if(recvy(boundy%recv(ind_y)%dir(n))) then is = boundy%recv(ind_y)%is(n); ie = boundy%recv(ind_y)%ie(n) js = boundy%recv(ind_y)%js(n); je = boundy%recv(ind_y)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) @@ -494,7 +619,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_x) then to_pe = boundx%send(ind_x)%pe do n = 1, boundx%send(ind_x)%count - if(send(boundx%send(ind_x)%dir(n))) then + if(sendx(boundx%send(ind_x)%dir(n))) then is = boundx%send(ind_x)%is(n); ie = boundx%send(ind_x)%ie(n) js = boundx%send(ind_x)%js(n); je = boundx%send(ind_x)%je(n) tMe = boundx%send(ind_x)%tileMe(n) @@ -590,7 +715,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_y) then to_pe = boundy%send(ind_y)%pe do n = 1, boundy%send(ind_y)%count - if(send(boundy%send(ind_y)%dir(n))) then + if(sendy(boundy%send(ind_y)%dir(n))) then is = boundy%send(ind_y)%is(n); ie = boundy%send(ind_y)%ie(n) js = boundy%send(ind_y)%js(n); je = boundy%send(ind_y)%je(n) tMe = boundy%send(ind_y)%tileMe(n) @@ -708,7 +833,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, do while(ind_x >0 .OR. ind_y >0) if(cur_rank == rank_y) then do n = boundy%recv(ind_y)%count, 1, -1 - if(recv(boundy%recv(ind_y)%dir(n))) then + if(recvy(boundy%recv(ind_y)%dir(n))) then is = boundy%recv(ind_y)%is(n); ie = boundy%recv(ind_y)%ie(n) js = boundy%recv(ind_y)%js(n); je = boundy%recv(ind_y)%je(n) msgsize = (ie-is+1)*(je-js+1)*ke*l_size @@ -786,7 +911,7 @@ subroutine MPP_DO_GET_BOUNDARY_3D_V_(f_addrsx, f_addrsy, domain, boundx, boundy, if(cur_rank == rank_x) then do n = boundx%recv(ind_x)%count, 1, -1 - if(recv(boundx%recv(ind_x)%dir(n))) then + if(recvx(boundx%recv(ind_x)%dir(n))) then is = boundx%recv(ind_x)%is(n); ie = boundx%recv(ind_x)%ie(n) js = boundx%recv(ind_x)%js(n); je = boundx%recv(ind_x)%je(n) msgsize = (ie-is+1)*(je-js+1)*ke*l_size diff --git a/src/shared/mpp/include/mpp_do_global_field.h b/src/shared/mpp/include/mpp_do_global_field.h index d0cd32fa07..da91c60fb5 100644 --- a/src/shared/mpp/include/mpp_do_global_field.h +++ b/src/shared/mpp/include/mpp_do_global_field.h @@ -1,4 +1,4 @@ - subroutine MPP_DO_GLOBAL_FIELD_3D_( domain, local, global, tile, ishift, jshift, flags) + subroutine MPP_DO_GLOBAL_FIELD_3D_( domain, local, global, tile, ishift, jshift, flags, default_data) !get a global field from a local field !local field may be on compute OR data domain type(domain2D), intent(in) :: domain @@ -6,6 +6,7 @@ integer, intent(in) :: tile, ishift, jshift MPP_TYPE_, intent(out) :: global(domain%x(tile)%global%begin:,domain%y(tile)%global%begin:,:) integer, intent(in), optional :: flags + MPP_TYPE_, intent(in), optional :: default_data integer :: i, j, k, m, n, nd, nwords, lpos, rpos, ioff, joff, from_pe, root_pe, tile_id integer :: ke, isc, iec, jsc, jec, is, ie, js, je, nword_me @@ -95,7 +96,15 @@ m = 0 if(global_on_this_pe) then !z1l: initialize global = 0 to support mask domain - global = 0 + if(PRESENT(default_data)) then + global = default_data + else +#ifdef LOGICAL_VARIABLE + global = .false. +#else + global = 0 +#endif + endif do k = 1, ke do j = jsc, jec diff --git a/src/shared/mpp/include/mpp_do_update.h b/src/shared/mpp/include/mpp_do_update.h index 6cdd90bfab..9b74e67068 100644 --- a/src/shared/mpp/include/mpp_do_update.h +++ b/src/shared/mpp/include/mpp_do_update.h @@ -32,6 +32,9 @@ integer :: is, ie, js, je, tMe, dir integer :: start, start1, start2, index, is1, ie1, js1, je1, ni, nj, total integer :: buffer_recv_size, nlist, outunit + integer :: send_start_pos + integer :: send_msgsize(MAXLIST) + outunit = stdout() ptr = LOC(mpp_domains_stack) @@ -111,11 +114,11 @@ endif !recv - buffer_pos = 0 + buffer_pos = 0 + call mpp_clock_begin(recv_clock) do m = 1, update%nrecv overPtr => update%recv(m) if( overPtr%count == 0 )cycle - call mpp_clock_begin(recv_clock) msgsize = 0 do n = 1, overPtr%count dir = overPtr%dir(n) @@ -138,15 +141,17 @@ call mpp_recv( buffer(buffer_pos+1), glen=msgsize, from_pe=from_pe, block=.FALSE., tag=COMM_TAG_2 ) buffer_pos = buffer_pos + msgsize end if - call mpp_clock_end(recv_clock) end do ! end do m = 1, update%nrecv - buffer_recv_size = buffer_pos + call mpp_clock_end(recv_clock) - ! send + buffer_recv_size = buffer_pos + send_start_pos = buffer_pos + ! pack + call mpp_clock_begin(pack_clock) do m = 1, update%nsend + send_msgsize(m) = 0 overPtr => update%send(m) if( overPtr%count == 0 )cycle - call mpp_clock_begin(pack_clock) pos = buffer_pos msgsize = 0 do n = 1, overPtr%count @@ -235,17 +240,21 @@ end if endif end do ! do n = 1, overPtr%count + send_msgsize(m) = pos-buffer_pos + buffer_pos = pos + end do ! end do m = 1, nsend + call mpp_clock_end(pack_clock) - call mpp_clock_end(pack_clock) - call mpp_clock_begin(send_clock) - msgsize = pos - buffer_pos - if( msgsize.GT.0 )then - to_pe = overPtr%pe - call mpp_send( buffer(buffer_pos+1), plen=msgsize, to_pe=to_pe, tag=COMM_TAG_2 ) - buffer_pos = pos - end if - call mpp_clock_end(send_clock) + buffer_pos = send_start_pos + call mpp_clock_begin(send_clock) + do m = 1, update%nsend + msgsize = send_msgsize(m) + if(msgsize == 0) cycle + to_pe = update%send(m)%pe + call mpp_send( buffer(buffer_pos+1), plen=msgsize, to_pe=to_pe, tag=COMM_TAG_2 ) + buffer_pos = buffer_pos + msgsize end do ! end do ist = 0,nlist-1 + call mpp_clock_end(send_clock) !unpack recv !unpack halos in reverse order @@ -255,10 +264,10 @@ call mpp_clock_end(wait_clock) buffer_pos = buffer_recv_size + call mpp_clock_begin(unpk_clock) do m = update%nrecv, 1, -1 overPtr => update%recv(m) if( overPtr%count == 0 )cycle - call mpp_clock_begin(unpk_clock) pos = buffer_pos do n = overPtr%count, 1, -1 dir = overPtr%dir(n) @@ -308,8 +317,8 @@ endif end if end do ! do n = 1, overPtr%count - call mpp_clock_end(unpk_clock) end do + call mpp_clock_end(unpk_clock) call mpp_clock_begin(wait_clock) call mpp_sync_self( ) diff --git a/src/shared/mpp/include/mpp_do_updateV.h b/src/shared/mpp/include/mpp_do_updateV.h index faacaa0689..648843b553 100644 --- a/src/shared/mpp/include/mpp_do_updateV.h +++ b/src/shared/mpp/include/mpp_do_updateV.h @@ -28,7 +28,10 @@ integer :: tMe, dir integer :: index, is1, ie1, js1, je1, ni, nj, total, start1, start, start2 - integer, allocatable :: msg1(:), msg2(:) + integer :: send_start_pos, nsend + integer :: send_msgsize(2*MAXLIST) + integer :: send_pe(2*MAXLIST) + integer, allocatable :: msg1(:), msg2(:) logical :: send(8), recv(8), update_edge_only MPP_TYPE_ :: buffer(size(mpp_domains_stack(:))) pointer(ptr,buffer ) @@ -195,9 +198,8 @@ !--- recv buffer_pos = 0 cur_rank = get_rank_recv(domain, update_x, update_y, rank_x, rank_y, ind_x, ind_y) - + call mpp_clock_begin(recv_clock) do while (ind_x .LE. nrecv_x .OR. ind_y .LE. nrecv_y) - call mpp_clock_begin(recv_clock) msgsize = 0 select case(gridtype) case(BGRID_NE, BGRID_SW, AGRID) @@ -274,15 +276,16 @@ call mpp_recv( buffer(buffer_pos+1), glen=msgsize, from_pe=from_pe, block=.false., tag=COMM_TAG_2 ) buffer_pos = buffer_pos + msgsize end if - call mpp_clock_end(recv_clock) end do + call mpp_clock_end(recv_clock) buffer_recv_size = buffer_pos + send_start_pos = buffer_pos !--- send cur_rank = get_rank_send(domain, update_x, update_y, rank_x, rank_y, ind_x, ind_y) - + nsend = 0 + call mpp_clock_begin(pack_clock) do while (ind_x .LE. nsend_x .OR. ind_y .LE. nsend_y) - call mpp_clock_begin(pack_clock) pos = buffer_pos !--- make sure the domain stack size is big enough msgsize = 0 @@ -896,16 +899,24 @@ endif endif end select - call mpp_clock_end(pack_clock) - call mpp_clock_begin(send_clock) cur_rank = min(rank_x, rank_y) - msgsize = pos - buffer_pos + nsend = nsend + 1 + send_pe(nsend) = to_pe + send_msgsize(nsend) = pos - buffer_pos + buffer_pos = pos + end do + + buffer_pos = send_start_pos + call mpp_clock_end(pack_clock) + call mpp_clock_begin(send_clock) + do m = 1, nsend + msgsize = send_msgsize(m) if( msgsize.GT.0 )then - call mpp_send( buffer(buffer_pos+1), plen=msgsize, to_pe=to_pe, tag=COMM_TAG_2 ) - buffer_pos = pos + call mpp_send( buffer(buffer_pos+1), plen=msgsize, to_pe=send_pe(m), tag=COMM_TAG_2 ) + buffer_pos = buffer_pos + msgsize end if - call mpp_clock_end(send_clock) end do + call mpp_clock_end(send_clock) !unpack recv !unpack halos in reverse order @@ -915,8 +926,8 @@ buffer_pos = buffer_recv_size cur_rank = get_rank_unpack(domain, update_x, update_y, rank_x, rank_y, ind_x, ind_y) + call mpp_clock_begin(unpk_clock) do while (ind_x > 0 .OR. ind_y > 0) - call mpp_clock_begin(unpk_clock) pos = buffer_pos select case ( gridtype ) case(BGRID_NE, BGRID_SW, AGRID) @@ -1111,8 +1122,8 @@ endif end select cur_rank = min(rank_x, rank_y) - call mpp_clock_end(unpk_clock) end do + call mpp_clock_end(unpk_clock) ! ---northern boundary fold shift = 0 diff --git a/src/shared/mpp/include/mpp_do_updateV_nonblock.h b/src/shared/mpp/include/mpp_do_updateV_nonblock.h index b3b6e62406..2a3f2703fe 100644 --- a/src/shared/mpp/include/mpp_do_updateV_nonblock.h +++ b/src/shared/mpp/include/mpp_do_updateV_nonblock.h @@ -14,14 +14,19 @@ subroutine MPP_START_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, upda integer, intent(in) :: flags !---local variable ------------------------------------------ - integer :: i, j, k, l, is, ie, js, je, n + integer :: i, j, k, l, is, ie, js, je, n, m integer :: pos, nlist, msgsize, tile, l_size integer :: to_pe, from_pe, buffer_pos - integer :: tMe, dir, count, ke_sum + integer :: tMe, dir, ke_sum logical :: send(8), recv(8), update_edge_only character(len=128) :: text - integer :: rank_x, rank_y, ind_x, ind_y, cur_rank - integer :: nsend_x, nsend_y, nrecv_x, nrecv_y + integer :: ind_x, ind_y + integer :: nsend, nrecv, sendsize, recvsize + integer :: request + integer :: ind_send_x(update_x%nsend+update_y%nsend), ind_send_y(update_x%nsend+update_y%nsend) + integer :: ind_recv_x(update_x%nrecv+update_y%nrecv), ind_recv_y(update_x%nrecv+update_y%nrecv) + integer :: from_pe_list(update_x%nrecv+update_y%nrecv), to_pe_list(update_x%nsend+update_y%nsend) + integer :: start_pos_recv(update_x%nrecv+update_y%nrecv), start_pos_send(update_x%nsend+update_y%nsend) MPP_TYPE_ :: fieldx(update_x%xbegin:update_x%xend, update_x%ybegin:update_x%yend,ke_max) MPP_TYPE_ :: fieldy(update_y%xbegin:update_y%xend, update_y%ybegin:update_y%yend,ke_max) MPP_TYPE_ :: buffer(size(mpp_domains_stack_nonblock(:))) @@ -56,145 +61,137 @@ subroutine MPP_START_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, upda nlist = size(domain%list(:)) ptr = LOC(mpp_domains_stack_nonblock) - !recv - nsend_x = update_x%nsend - nsend_y = update_y%nsend - nrecv_x = update_x%nrecv - nrecv_y = update_y%nrecv - - !--- recv - cur_rank = get_rank_recv(domain, update_x, update_y, rank_x, rank_y, ind_x, ind_y) - + nrecv = get_vector_recv(domain, update_x, update_y, ind_recv_x, ind_recv_y, start_pos_recv, from_pe_list) + nsend = get_vector_send(domain, update_x, update_y, ind_send_x, ind_send_y, start_pos_send, to_pe_list) + if( nrecv > MAX_REQUEST ) then + write( text,'(a,i8,a,i8)' ) 'nrecv =', nrecv, ' greater than MAX_REQEUST =', MAX_REQUEST + call mpp_error(FATAL,'MPP_START_DO_UPDATE_V: '//trim(text)) + endif + if( nsend > MAX_REQUEST ) then + write( text,'(a,i8,a,i8)' ) 'nsend =', nsend, ' greater than MAX_REQEUST =', MAX_REQUEST + call mpp_error(FATAL,'MPP_START_DO_UPDATE_V: '//trim(text)) + endif + !--- make sure the domain stack size is big enough. buffer_pos = nonblock_data(id_update)%recv_pos - call mpp_clock_begin(recv_clock_nonblock) - do while (ind_x .LE. nrecv_x .OR. ind_y .LE. nrecv_y) + recvsize = 0 + do m = 1, nrecv msgsize = 0 - select case(gridtype) - case(BGRID_NE, BGRID_SW, AGRID) - if(cur_rank == rank_x) then - from_pe = update_x%recv(ind_x)%pe - do n = 1, update_x%recv(ind_x)%count - dir = update_x%recv(ind_x)%dir(n) - if(recv(dir)) then - msgsize = msgsize + update_x%recv(ind_x)%msgsize(n) - end if - end do - msgsize = msgsize*2 - ind_x = ind_x+1 - ind_y = ind_x - if(ind_x .LE. nrecv_x) then - rank_x = update_x%recv(ind_x)%pe - domain%pe - if(rank_x .LE.0) rank_x = rank_x + nlist - else - rank_x = -1 - endif - rank_y = rank_x - endif - case(CGRID_NE, CGRID_SW) - if(cur_rank == rank_x) then - from_pe = update_x%recv(ind_x)%pe - do n = 1, update_x%recv(ind_x)%count - dir = update_x%recv(ind_x)%dir(n) - if(recv(dir)) then - msgsize = msgsize + update_x%recv(ind_x)%msgsize(n) - end if - end do - ind_x = ind_x+1 - if(ind_x .LE. nrecv_x) then - rank_x = update_x%recv(ind_x)%pe - domain%pe - if(rank_x .LE.0) rank_x = rank_x + nlist - else - rank_x = -1 - endif - endif - if(cur_rank == rank_y) then - from_pe = update_y%recv(ind_y)%pe - do n = 1, update_y%recv(ind_y)%count - dir = update_y%recv(ind_y)%dir(n) - if(recv(dir)) then - msgsize = msgsize + update_y%recv(ind_y)%msgsize(n) - end if - end do - ind_y = ind_y+1 - if(ind_y .LE. nrecv_y) then - rank_y = update_y%recv(ind_y)%pe - domain%pe - if(rank_y .LE.0) rank_y = rank_y + nlist - else - rank_y = -1 - endif - endif - end select - cur_rank = max(rank_x, rank_y) - msgsize = msgsize*ke_sum - + nonblock_data(id_update)%size_recv(m) = 0 + ind_x = ind_recv_x(m) + ind_y = ind_recv_y(m) + if(ind_x >= 0) then + do n = 1, update_x%recv(ind_x)%count + dir = update_x%recv(ind_x)%dir(n) + if(recv(dir)) then + msgsize = msgsize + update_x%recv(ind_x)%msgsize(n) + end if + end do + endif + if(ind_y >= 0) then + do n = 1, update_y%recv(ind_y)%count + dir = update_y%recv(ind_y)%dir(n) + if(recv(dir)) then + msgsize = msgsize + update_y%recv(ind_y)%msgsize(n) + end if + end do + endif if( msgsize.GT.0 )then - mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, buffer_pos+msgsize ) - if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then - write( text,'(i8)' )mpp_domains_stack_hwm - call mpp_error( FATAL, 'MPP_START_DO_UPDATE_V: mpp_domains_stack overflow, '// & - 'call mpp_domains_set_stack_size('//trim(text)//') from all PEs.' ) - end if - count = nonblock_data(id_update)%request_recv_count + 1 - if( count > MAX_REQUEST ) then - write( text,'(a,i8,a,i8)' ) 'request count =', count, ' greater than MAX_REQEUST =', MAX_REQUEST - call mpp_error(FATAL,'MPP_START_DO_UPDATE_V: '//trim(text)) - endif - nonblock_data(id_update)%request_recv_count = count - - call mpp_recv( buffer(buffer_pos+1), glen=msgsize, from_pe=from_pe, block=.false., & - tag=id_update, request=nonblock_data(id_update)%request_recv(count)) - nonblock_data(id_update)%size_recv(count) = msgsize - nonblock_data(id_update)%type_recv(count) = MPI_TYPE_ + msgsize = msgsize*ke_sum + recvsize = recvsize + msgsize + nonblock_data(id_update)%size_recv(m) = msgsize + nonblock_data(id_update)%buffer_pos_recv(m) = buffer_pos buffer_pos = buffer_pos + msgsize end if - end do - call mpp_clock_end(recv_clock_nonblock) - msgsize = buffer_pos - nonblock_data(id_update)%recv_pos - if( reuse_id_update ) then - if(msgsize .NE. nonblock_data(id_update)%recv_msgsize) then - call mpp_error(FATAL,'MPP_START_UPDATE_DOMAINS_V: mismatch of recv msgsize for field '//trim(name) ) - endif - else - nonblock_data(id_update)%recv_msgsize = msgsize - nonblock_data(id_update)%send_pos = buffer_pos - nonblock_buffer_pos = nonblock_buffer_pos + msgsize - endif + end do - !--- send - cur_rank = get_rank_send(domain, update_x, update_y, rank_x, rank_y, ind_x, ind_y) - - do while (ind_x .LE. nsend_x .OR. ind_y .LE. nsend_y) - call mpp_clock_begin(pack_clock_nonblock) - pos = buffer_pos - !--- make sure the domain stack size is big enough + sendsize = 0 + do m = 1, nsend msgsize = 0 - if(cur_rank == rank_x) then + ind_x = ind_send_x(m) + ind_y = ind_send_y(m) + if(ind_x >= 0) then do n = 1, update_x%send(ind_x)%count dir = update_x%send(ind_x)%dir(n) - if( send(dir) ) msgsize = msgsize + update_x%send(ind_x)%msgsize(n) - enddo + if(send(dir)) then + msgsize = msgsize + update_x%send(ind_x)%msgsize(n) + end if + end do endif - if(cur_rank == rank_y) then + if(ind_y >= 0) then do n = 1, update_y%send(ind_y)%count dir = update_y%send(ind_y)%dir(n) - if( send(dir) ) msgsize = msgsize + update_y%send(ind_y)%msgsize(n) - enddo + if(send(dir)) then + msgsize = msgsize + update_y%send(ind_y)%msgsize(n) + end if + end do endif - if( msgsize.GT.0 )then msgsize = msgsize*ke_sum - mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, pos+msgsize ) - if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then - write( text,'(i8)' )mpp_domains_stack_hwm - call mpp_error( FATAL, 'MPP_START_DO_UPDATE_V: mpp_domains_stack overflow, ' // & - 'call mpp_domains_set_stack_size('//trim(text)//') from all PEs.') - end if + sendsize = sendsize + msgsize + nonblock_data(id_update)%buffer_pos_send(m) = buffer_pos + buffer_pos = buffer_pos + msgsize + end if + end do + + mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, & + nonblock_data(id_update)%recv_pos+recvsize+sendsize ) + if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then + write( text,'(i8)' )mpp_domains_stack_hwm + call mpp_error( FATAL, 'MPP_START_DO_UPDATE_V: mpp_domains_stack overflow, '// & + 'call mpp_domains_set_stack_size('//trim(text)//') from all PEs.' ) + end if + + if( reuse_id_update ) then + if(recvsize .NE. nonblock_data(id_update)%recv_msgsize) then + call mpp_error(FATAL,'MPP_START_DO_UPDATE: mismatch of recv msgsize for field '//trim(name) ) + endif + if(sendsize .NE. nonblock_data(id_update)%send_msgsize) then + call mpp_error(FATAL,'MPP_START_DO_UPDATE: mismatch of send msgsize for field '//trim(name) ) + endif + else + nonblock_data(id_update)%recv_msgsize = recvsize + nonblock_data(id_update)%send_msgsize = sendsize + nonblock_data(id_update)%send_pos = nonblock_data(id_update)%recv_pos + recvsize + nonblock_buffer_pos = nonblock_buffer_pos + recvsize + sendsize + endif + + !--- recv + call mpp_clock_begin(recv_clock_nonblock) + !$OMP parallel do schedule(dynamic) default(shared) private(msgsize,ind_x,ind_y,from_pe,dir,buffer_pos,request) + do m = 1, nrecv + msgsize = nonblock_data(id_update)%size_recv(m) + from_pe = from_pe_list(m) + if( msgsize .GT. 0 )then + buffer_pos = nonblock_data(id_update)%buffer_pos_recv(m) +!$OMP CRITICAL + call mpp_recv( buffer(buffer_pos+1), glen=msgsize, from_pe=from_pe, block=.false., & + tag=id_update, request=request) +!$OMP END CRITICAL + nonblock_data(id_update)%request_recv(m) = request +#ifdef use_libMPI + nonblock_data(id_update)%type_recv(m) = MPI_TYPE_ +#endif end if + end do +!$OMP end parallel do + call mpp_clock_end(recv_clock_nonblock) + + !--- send + + call mpp_clock_begin(send_pack_clock_nonblock) + +!$OMP parallel do schedule(dynamic) default(shared) private(ind_x,ind_y,to_pe,buffer_pos,pos,dir,tMe, & +!$OMP is,ie,js,je,ptr_fieldx,ptr_fieldy,msgsize,request) + do m = 1, nsend + ind_x = ind_send_x(m) + ind_y = ind_send_y(m) + to_pe = to_pe_list(m) + buffer_pos = nonblock_data(id_update)%buffer_pos_send(m) + pos = buffer_pos select case( gridtype ) case(BGRID_NE, BGRID_SW, AGRID) - if(cur_rank == rank_x) then - to_pe = update_x%send(ind_x)%pe + if(ind_x >= 0) then do n = 1, update_x%send(ind_x)%count dir = update_x%send(ind_x)%dir(n) if( send(dir) ) then @@ -418,19 +415,9 @@ subroutine MPP_START_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, upda end if ! if( is_refined(n) ) end if ! if( send(dir) ) end do ! do n = 1, update_x%send(ind_x)%count - ind_x = ind_x+1 - ind_y = ind_x - if(ind_x .LE. nsend_x) then - rank_x = update_x%send(ind_x)%pe - domain%pe - if(rank_x .LT.0) rank_x = rank_x + nlist - else - rank_x = nlist+1 - endif - rank_y = rank_x endif case(CGRID_NE, CGRID_SW) - if(cur_rank == rank_x) then - to_pe = update_x%send(ind_x)%pe + if(ind_x>=0) then do n = 1, update_x%send(ind_x)%count dir = update_x%send(ind_x)%dir(n) if( send(dir) ) then @@ -595,16 +582,8 @@ subroutine MPP_START_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, upda end if end if end do - ind_x = ind_x+1 - if(ind_x .LE. nsend_x) then - rank_x = update_x%send(ind_x)%pe - domain%pe - if(rank_x .LT.0) rank_x = rank_x + nlist - else - rank_x = nlist+1 - endif endif - if(cur_rank == rank_y) then - to_pe = update_y%send(ind_y)%pe + if(ind_y>=0) then do n = 1, update_y%send(ind_y)%count dir = update_y%send(ind_y)%dir(n) if( send(dir) ) then @@ -769,42 +748,21 @@ subroutine MPP_START_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, upda end if endif enddo - ind_y = ind_y+1 - if(ind_y .LE. nsend_y) then - rank_y = update_y%send(ind_y)%pe - domain%pe - if(rank_y .LT.0) rank_y = rank_y + nlist - else - rank_y = nlist+1 - endif endif end select - call mpp_clock_end(pack_clock_nonblock) - call mpp_clock_begin(send_clock_nonblock) - cur_rank = min(rank_x, rank_y) + msgsize = pos - buffer_pos - if( msgsize.GT.0 )then - count = nonblock_data(id_update)%request_send_count + 1 - if( count > MAX_REQUEST ) then - write( text,'(a,i8,a,i8)' ) 'send request count =', count, ' greater than MAX_REQEUST =', MAX_REQUEST - call mpp_error(FATAL,'MPP_START_DO_UPDATE_V: '//trim(text)) - endif - nonblock_data(id_update)%request_send_count = count + if( msgsize .GT.0 )then +!$OMP CRITICAL call mpp_send( buffer(buffer_pos+1), plen=msgsize, to_pe=to_pe, & - tag=id_update, request=nonblock_data(id_update)%request_send(count) ) - buffer_pos = pos + tag=id_update, request=request ) +!$OMP END CRITICAL + nonblock_data(id_update)%request_send(m) = request end if - call mpp_clock_end(send_clock_nonblock) end do +!$OMP end parallel do - msgsize = buffer_pos - nonblock_data(id_update)%send_pos - if( reuse_id_update ) then - if(msgsize .NE. nonblock_data(id_update)%send_msgsize) then - call mpp_error(FATAL,'MPP_START_DO_UPDATE_V: mismatch of send msgsize for field '//trim(name) ) - endif - else - nonblock_buffer_pos = nonblock_buffer_pos + msgsize - nonblock_data(id_update)%send_msgsize = msgsize - endif + call mpp_clock_end(send_pack_clock_nonblock) end subroutine MPP_START_DO_UPDATE_3D_V_ @@ -840,13 +798,16 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, u MPP_TYPE_ :: recv_buffer(size(mpp_domains_stack_nonblock(:))) pointer( ptr, recv_buffer ) - integer :: i, j, k, l, is, ie, js, je, n, ke_sum, l_size + integer :: i, j, k, l, is, ie, js, je, n, ke_sum, l_size, m integer :: pos, nlist, msgsize, tile, buffer_pos - integer :: rank_x, rank_y, ind_x, ind_y, cur_rank + integer :: ind_x, ind_y, nrecv, nsend integer :: index, is1, ie1, js1, je1, ni, nj, total, start1, start, start2 + integer :: ind_recv_x(update_x%nrecv+update_y%nrecv), ind_recv_y(update_x%nrecv+update_y%nrecv) + integer :: start_pos_recv(update_x%nrecv+update_y%nrecv) + integer :: from_pe_list(update_x%nrecv+update_y%nrecv) logical :: recv(8), send(8), update_edge_only integer :: shift, midpoint - integer :: tMe, dir, count + integer :: tMe, dir update_edge_only = BTEST(flags, EDGEONLY) recv(1) = BTEST(flags,EAST) @@ -874,28 +835,33 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, u nlist = size(domain%list(:)) ptr = LOC(mpp_domains_stack_nonblock) - buffer_pos = nonblock_data(id_update)%recv_pos + nonblock_data(id_update)%recv_msgsize - cur_rank = get_rank_unpack(domain, update_x, update_y, rank_x, rank_y, ind_x, ind_y) + nrecv = get_vector_recv(domain, update_x, update_y, ind_recv_x, ind_recv_y, start_pos_recv, from_pe_list) - count = nonblock_data(id_update)%request_recv_count - if(count > 0) then + if(nrecv > 0) then call mpp_clock_begin(wait_clock_nonblock) - call mpp_sync_self(check=EVENT_RECV, request=nonblock_data(id_update)%request_recv(1:count), & - msg_size=nonblock_data(id_update)%size_recv(1:count), & - msg_type=nonblock_data(id_update)%type_recv(1:count) ) + call mpp_sync_self(check=EVENT_RECV, request=nonblock_data(id_update)%request_recv(1:nrecv), & + msg_size=nonblock_data(id_update)%size_recv(1:nrecv), & + msg_type=nonblock_data(id_update)%type_recv(1:nrecv) ) call mpp_clock_end(wait_clock_nonblock) - nonblock_data(id_update)%request_recv_count = 0 +#ifdef use_libMPI nonblock_data(id_update)%request_recv(:) = MPI_REQUEST_NULL - nonblock_data(id_update)%size_recv(:) = 0 +#else + nonblock_data(id_update)%request_recv(:) = 0 +#endif nonblock_data(id_update)%type_recv(:) = 0 endif - do while (ind_x > 0 .OR. ind_y > 0) - call mpp_clock_begin(unpk_clock_nonblock) + call mpp_clock_begin(unpk_clock_nonblock) +!$OMP parallel do schedule(dynamic) default(shared) private(ind_x,ind_y,buffer_pos,pos,dir,tMe,is,ie,js,je, & +!$OMP msgsize,index,is1,ie1,js1,je1,ni,nj,total,start,ptr_bufferx,ptr_buffery,start1,start2,ptr_fieldx,ptr_fieldy) + do m = nrecv,1,-1 + ind_x = ind_recv_x(m) + ind_y = ind_recv_y(m) + buffer_pos = nonblock_data(id_update)%buffer_pos_recv(m)+nonblock_data(id_update)%size_recv(m) pos = buffer_pos select case ( gridtype ) case(BGRID_NE, BGRID_SW, AGRID) - if(cur_rank == rank_x) then + if(ind_x>=0) then do n = update_x%recv(ind_x)%count, 1, -1 dir = update_x%recv(ind_x)%dir(n) if( recv(dir) ) then @@ -952,18 +918,9 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, u end if end if ! end if( recv(dir) ) end do ! do dir=8,1,-1 - ind_x = ind_x-1 - ind_y = ind_x - if(ind_x .GT. 0) then - rank_x = update_x%recv(ind_x)%pe - domain%pe - if(rank_x .LE.0) rank_x = rank_x + nlist - else - rank_x = nlist+1 - endif - rank_y = rank_x endif case(CGRID_NE, CGRID_SW) - if(cur_rank == rank_y) then + if(ind_y>=0) then do n = update_y%recv(ind_y)%count, 1, -1 dir = update_y%recv(ind_y)%dir(n) @@ -1017,15 +974,8 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, u end if end if end do - ind_y = ind_y-1 - if(ind_y .GT. 0) then - rank_y = update_y%recv(ind_y)%pe - domain%pe - if(rank_y .LE.0) rank_y = rank_y + nlist - else - rank_y = nlist+1 - endif endif - if(cur_rank == rank_x) then + if(ind_x>=0) then do n = update_x%recv(ind_x)%count, 1, -1 dir = update_x%recv(ind_x)%dir(n) if( recv(dir) ) then @@ -1078,21 +1028,14 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, u end if end if end do - ind_x = ind_x-1 - if(ind_x .GT. 0) then - rank_x = update_x%recv(ind_x)%pe - domain%pe - if(rank_x .LE.0) rank_x = rank_x + nlist - else - rank_x = nlist+1 - endif endif end select - cur_rank = min(rank_x, rank_y) - call mpp_clock_end(unpk_clock_nonblock) end do - +!$OMP end parallel do + call mpp_clock_end(unpk_clock_nonblock) ! ---northern boundary fold shift = 0 + tMe = 1 if(domain%symmetry) shift = 1 if( BTEST(domain%fold,NORTH) .AND. (.NOT.BTEST(flags,SCALAR_BIT)) )then j = domain%y(1)%global%end+shift @@ -1476,13 +1419,22 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_V_(id_update, f_addrsx, f_addrsy, domain, u end if end if - count = nonblock_data(id_update)%request_send_count - if(count > 0) then + + if(nrecv>0) then + nonblock_data(id_update)%size_recv(:) = 0 + endif + + nsend = update_x%nsend+update_y%nsend + if(nsend > 0) then call mpp_clock_begin(wait_clock_nonblock) - call mpp_sync_self(check=EVENT_SEND, request=nonblock_data(id_update)%request_send(1:count)) + call mpp_sync_self(check=EVENT_SEND, request=nonblock_data(id_update)%request_send(1:nsend)) call mpp_clock_end(wait_clock_nonblock) nonblock_data(id_update)%request_send_count = 0 +#ifdef use_libMPI nonblock_data(id_update)%request_send(:) = MPI_REQUEST_NULL +#else + nonblock_data(id_update)%request_send(:) = 0 +#endif endif return diff --git a/src/shared/mpp/include/mpp_do_update_nonblock.h b/src/shared/mpp/include/mpp_do_update_nonblock.h index d4cbc8b5b1..c800c45416 100644 --- a/src/shared/mpp/include/mpp_do_update_nonblock.h +++ b/src/shared/mpp/include/mpp_do_update_nonblock.h @@ -12,13 +12,13 @@ subroutine MPP_START_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type, k integer, intent(in) :: flags !--- local variables - integer :: i, j, k, m, n, l, dir, count, tMe + integer :: i, j, k, m, n, l, dir, tMe integer :: buffer_pos, msgsize, from_pe, to_pe, pos - integer :: is, ie, js, je + integer :: is, ie, js, je, sendsize, recvsize logical :: send(8), recv(8), update_edge_only - integer :: l_size, ke_sum + integer :: l_size, ke_sum, my_id_update + integer :: request character(len=128) :: text - type(overlap_type), pointer :: overPtr => NULL() MPP_TYPE_ :: buffer(size(mpp_domains_stack_nonblock(:))) MPP_TYPE_ :: field(update%xbegin:update%xend, update%ybegin:update%yend,ke_max) pointer( ptr, buffer ) @@ -50,85 +50,117 @@ subroutine MPP_START_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type, k buffer_pos = nonblock_data(id_update)%recv_pos + if( update%nrecv > MAX_REQUEST ) then + write( text,'(a,i8,a,i8)' ) 'update%nrecv =', update%nrecv, ' greater than MAX_REQEUST =', MAX_REQUEST + call mpp_error(FATAL,'MPP_START_DO_UPDATE: '//trim(text)) + endif + if( update%nsend > MAX_REQUEST ) then + write( text,'(a,i8,a,i8)' ) 'update%nsend =', update%nsend, ' greater than MAX_REQEUST =', MAX_REQUEST + call mpp_error(FATAL,'MPP_START_DO_UPDATE: '//trim(text)) + endif + ! pre-postrecv + !--- make sure the domain stack size is big enough. + recvsize = 0 do m = 1, update%nrecv - overPtr => update%recv(m) - if( overPtr%count == 0 )cycle - call mpp_clock_begin(recv_clock_nonblock) + nonblock_data(id_update)%size_recv(m) = 0 + if( update%recv(m)%count == 0 )cycle msgsize = 0 - !--- make sure the domain stack size is big enough. - do n = 1, overPtr%count - dir = overPtr%dir(n) + do n = 1, update%recv(m)%count + dir = update%recv(m)%dir(n) if(recv(dir)) then - msgsize = msgsize + overPtr%msgsize(n) + msgsize = msgsize + update%recv(m)%msgsize(n) end if end do - - msgsize = msgsize*ke_sum if( msgsize.GT.0 )then - from_pe = overPtr%pe - mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, (buffer_pos+msgsize) ) - if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then - write( text,'(i8)' )mpp_domains_stack_hwm - call mpp_error( FATAL, 'MPP_START_DO_UPDATE: mpp_domains_stack overflow, '// & - 'call mpp_domains_set_stack_size('//trim(text)//') from all PEs.' ) - end if - count = nonblock_data(id_update)%request_recv_count + 1 - if( count > MAX_REQUEST ) then - write( text,'(a,i8,a,i8)' ) 'recv request count =', count, ' greater than MAX_REQEUST =', MAX_REQUEST - call mpp_error(FATAL,'MPP_START_DO_UPDATE: '//trim(text)) - endif - nonblock_data(id_update)%request_recv_count = count - call mpp_recv( buffer(buffer_pos+1), glen=msgsize, from_pe=from_pe, block=.FALSE., & - tag=id_update, request=nonblock_data(id_update)%request_recv(count)) - nonblock_data(id_update)%size_recv(count) = msgsize - nonblock_data(id_update)%type_recv(count) = MPI_TYPE_ + msgsize = msgsize*ke_sum + recvsize = recvsize + msgsize + nonblock_data(id_update)%size_recv(m) = msgsize + nonblock_data(id_update)%buffer_pos_recv(m) = buffer_pos buffer_pos = buffer_pos + msgsize end if - call mpp_clock_end(recv_clock_nonblock) - end do ! end do m = 1, update%nrecv + end do + + sendsize = 0 + do m = 1, update%nsend + if( update%send(m)%count == 0 )cycle + + ! make sure the stacksize is big enough + msgsize = 0 + do n = 1, update%send(m)%count + dir = update%send(m)%dir(n) + if( send(dir) ) msgsize = msgsize + update%send(m)%msgsize(n) + enddo + if( msgsize.GT.0 )then + msgsize = msgsize*ke_sum + sendsize = sendsize + msgsize + nonblock_data(id_update)%buffer_pos_send(m) = buffer_pos + buffer_pos = buffer_pos + msgsize + end if + end do + + mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, & + nonblock_data(id_update)%recv_pos+recvsize+sendsize ) + if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then + write( text,'(i8)' )mpp_domains_stack_hwm + call mpp_error( FATAL, 'MPP_START_DO_UPDATE: mpp_domains_stack overflow, ' // & + 'call mpp_domains_set_stack_size('//trim(text)//') from all PEs.') + end if - msgsize = buffer_pos - nonblock_data(id_update)%recv_pos if( reuse_id_update ) then - if(msgsize .NE. nonblock_data(id_update)%recv_msgsize) then + if(recvsize .NE. nonblock_data(id_update)%recv_msgsize) then call mpp_error(FATAL,'MPP_START_DO_UPDATE: mismatch of recv msgsize for field '//trim(name) ) endif + if(sendsize .NE. nonblock_data(id_update)%send_msgsize) then + call mpp_error(FATAL,'MPP_START_DO_UPDATE: mismatch of send msgsize for field '//trim(name) ) + endif else - nonblock_data(id_update)%recv_msgsize = msgsize - nonblock_data(id_update)%send_pos = buffer_pos - nonblock_buffer_pos = nonblock_buffer_pos + msgsize + nonblock_data(id_update)%recv_msgsize = recvsize + nonblock_data(id_update)%send_msgsize = sendsize + nonblock_data(id_update)%send_pos = nonblock_data(id_update)%recv_pos + recvsize + nonblock_buffer_pos = nonblock_buffer_pos + recvsize + sendsize endif + ! pre-postrecv + call mpp_clock_begin(recv_clock_nonblock) +!$OMP parallel do schedule(dynamic) default(shared) private(dir,from_pe,buffer_pos, request, msgsize) + do m = 1, update%nrecv + msgsize = nonblock_data(id_update)%size_recv(m) + if( msgsize.GT.0 )then + from_pe = update%recv(m)%pe + buffer_pos = nonblock_data(id_update)%buffer_pos_recv(m) +!$OMP CRITICAL + call mpp_recv( buffer(buffer_pos+1), glen=msgsize, from_pe=from_pe, block=.FALSE., & + tag=id_update, request=request) +!$OMP END CRITICAL + nonblock_data(id_update)%request_recv(m) = request + +#ifdef use_libMPI + nonblock_data(id_update)%type_recv(m) = MPI_TYPE_ +#endif + end if + end do ! end do m = 1, update%nrecv +!$OMP end parallel do + + call mpp_clock_end(recv_clock_nonblock) + ! send + call mpp_clock_begin(send_pack_clock_nonblock) +!$OMP parallel do schedule(dynamic) default(shared) private(buffer_pos,pos,dir,tMe,is,ie,js,je,ptr_field,to_pe, & +!$OMP msgsize,request) do m = 1, update%nsend - overPtr => update%send(m) - if( overPtr%count == 0 )cycle - call mpp_clock_begin(pack_clock_nonblock) + if( update%send(m)%count == 0 )cycle + + buffer_pos = nonblock_data(id_update)%buffer_pos_send(m) pos = buffer_pos - ! make sure the stacksize is big enough - msgsize = 0 - do n = 1, overPtr%count - dir = overPtr%dir(n) - if( send(dir) ) msgsize = msgsize + overPtr%msgsize(n) - enddo - if( msgsize.GT.0 )then - msgsize = msgsize*ke_sum - mpp_domains_stack_hwm = max( mpp_domains_stack_hwm, pos+msgsize ) - if( mpp_domains_stack_hwm.GT.mpp_domains_stack_size )then - write( text,'(i8)' )mpp_domains_stack_hwm - call mpp_error( FATAL, 'MPP_START_DO_UPDATE: mpp_domains_stack overflow, ' // & - 'call mpp_domains_set_stack_size('//trim(text)//') from all PEs.') - end if - end if - - do n = 1, overPtr%count - dir = overPtr%dir(n) + do n = 1, update%send(m)%count + dir = update%send(m)%dir(n) if( send(dir) ) then - tMe = overPtr%tileMe(n) - is = overPtr%is(n); ie = overPtr%ie(n) - js = overPtr%js(n); je = overPtr%je(n) - if( overptr%is_refined(n) ) then + tMe = update%send(m)%tileMe(n) + is = update%send(m)%is(n); ie = update%send(m)%ie(n) + js = update%send(m)%js(n); je = update%send(m)%je(n) + if( update%send(m)%is_refined(n) ) then do l=1,l_size ! loop over number of fields ptr_field = f_addrs(l, tMe) do k = 1,ke_list(l,tMe) @@ -141,7 +173,7 @@ subroutine MPP_START_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type, k end do enddo else - select case( overPtr%rotation(n) ) + select case( update%send(m)%rotation(n) ) case(ZERO) do l=1,l_size ! loop over number of fields ptr_field = f_addrs(l, tMe) @@ -195,37 +227,22 @@ subroutine MPP_START_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type, k end select end if endif - end do ! do n = 1, overPtr%count + end do ! do n = 1, update%send(m)%count + - call mpp_clock_end(pack_clock_nonblock) - call mpp_clock_begin(send_clock_nonblock) msgsize = pos - buffer_pos - if( msgsize.GT.0 )then - to_pe = overPtr%pe - count = nonblock_data(id_update)%request_send_count + 1 - if( count > MAX_REQUEST ) then - write( text,'(a,i8,a,i8)' ) 'send request count =', count, ' greater than MAX_REQEUST =', MAX_REQUEST - call mpp_error(FATAL,'MPP_START_DO_UPDATE: '//trim(text)) - endif - nonblock_data(id_update)%request_send_count = count - call mpp_send( buffer(buffer_pos+1), plen=msgsize, to_pe=to_pe, & - tag=id_update, request=nonblock_data(id_update)%request_send(count)) - buffer_pos = pos + if( msgsize .GT.0 )then + to_pe = update%send(m)%pe +!$OMP CRITICAL + call mpp_send( buffer(buffer_pos+1), plen= msgsize, to_pe=to_pe, & + tag=id_update, request=request) +!$OMP END CRITICAL + nonblock_data(id_update)%request_send(m) = request end if - call mpp_clock_end(send_clock_nonblock) end do ! end do ist = 0,nlist-1 +!$OMP end parallel do - msgsize = buffer_pos - nonblock_data(id_update)%send_pos - if( reuse_id_update ) then - if(msgsize .NE. nonblock_data(id_update)%send_msgsize) then - call mpp_error(FATAL,'MPP_START_DO_UPDATE: mismatch of send msgsize for field '//trim(name) ) - endif - else - nonblock_buffer_pos = nonblock_buffer_pos + msgsize - nonblock_data(id_update)%send_msgsize = msgsize - endif - - overPtr => NULL() + call mpp_clock_end(send_pack_clock_nonblock) return @@ -254,9 +271,8 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type integer :: start, start1, start2, index integer :: is1, ie1, js1, je1, ni, nj, total logical :: send(8), recv(8), update_edge_only - integer :: l_size, ke_sum + integer :: l_size, ke_sum, sendsize, recvsize character(len=128) :: text - type(overlap_type), pointer :: overPtr => NULL() MPP_TYPE_ :: recv_buffer(size(mpp_domains_stack_nonblock(:))) MPP_TYPE_ :: field(update%xbegin:update%xend, update%ybegin:update%yend,ke_max) MPP_TYPE_ :: buffer(b_size) @@ -289,38 +305,41 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type l_size = size(f_addrs,1) ptr = LOC(mpp_domains_stack_nonblock) - count = nonblock_data(id_update)%request_recv_count + count = update%nrecv if(count > 0) then call mpp_clock_begin(wait_clock_nonblock) call mpp_sync_self(check=EVENT_RECV, request=nonblock_data(id_update)%request_recv(1:count), & msg_size=nonblock_data(id_update)%size_recv(1:count), & msg_type=nonblock_data(id_update)%type_recv(1:count) ) call mpp_clock_end(wait_clock_nonblock) - nonblock_data(id_update)%request_recv_count = 0 +#ifdef use_libMPI nonblock_data(id_update)%request_recv(:) = MPI_REQUEST_NULL - nonblock_data(id_update)%size_recv(:) = 0 +#else + nonblock_data(id_update)%request_recv(:) = 0 +#endif nonblock_data(id_update)%type_recv(:) = 0 endif - buffer_pos = nonblock_data(id_update)%recv_pos + nonblock_data(id_update)%recv_msgsize !--unpack the data call mpp_clock_begin(unpk_clock_nonblock) +!$OMP parallel do schedule(dynamic) default(shared) private(dir,buffer_pos,pos,tMe,is,ie,js,je,msgsize, & +!$OMP ptr_field, index,is1,ie1,js1,je1,total,start,ptr_buffer,start1,start2) do m = update%nrecv, 1, -1 - overPtr => update%recv(m) - if( overPtr%count == 0 )cycle + if( update%recv(m)%count == 0 )cycle + buffer_pos = nonblock_data(id_update)%buffer_pos_recv(m) + nonblock_data(id_update)%size_recv(m) pos = buffer_pos - do n = overPtr%count, 1, -1 - dir = overPtr%dir(n) + do n = update%recv(m)%count, 1, -1 + dir = update%recv(m)%dir(n) if( recv(dir) ) then - tMe = overPtr%tileMe(n) - is = overPtr%is(n); ie = overPtr%ie(n) - js = overPtr%js(n); je = overPtr%je(n) + tMe = update%recv(m)%tileMe(n) + is = update%recv(m)%is(n); ie = update%recv(m)%ie(n) + js = update%recv(m)%js(n); je = update%recv(m)%je(n) msgsize = (ie-is+1)*(je-js+1)*ke_sum pos = buffer_pos - msgsize buffer_pos = pos - if(OverPtr%is_refined(n)) then - index = overPtr%index(n) + if(update%recv(m)%is_refined(n)) then + index = update%recv(m)%index(n) is1 = update%rSpec(tMe)%isNbr(index); ie1 = update%rSpec(tMe)%ieNbr(index) js1 = update%rSpec(tMe)%jsNbr(index); je1 = update%rSpec(tMe)%jeNbr(index) ni = ie1 - is1 + 1 @@ -358,18 +377,27 @@ subroutine MPP_COMPLETE_DO_UPDATE_3D_(id_update, f_addrs, domain, update, d_type end do endif end if - end do ! do n = 1, overPtr%count + end do ! do n = 1, update%recv(m)%count end do - +!$OMP end parallel do call mpp_clock_end(unpk_clock_nonblock) - count = nonblock_data(id_update)%request_send_count + count = update%nrecv + if(count > 0) then + nonblock_data(id_update)%size_recv(:) = 0 + endif + + count = update%nsend if(count > 0) then call mpp_clock_begin(wait_clock_nonblock) call mpp_sync_self(check=EVENT_SEND, request=nonblock_data(id_update)%request_send(1:count)) call mpp_clock_end(wait_clock_nonblock) nonblock_data(id_update)%request_send_count = 0 +#ifdef use_libMPI nonblock_data(id_update)%request_send(:) = MPI_REQUEST_NULL +#else + nonblock_data(id_update)%request_send(:) = 0 +#endif endif ! call init_nonblock_type(nonblock_data(id_update)) diff --git a/src/shared/mpp/include/mpp_domains_comm.inc b/src/shared/mpp/include/mpp_domains_comm.inc index 5b241feaa3..9b2a3842fc 100644 --- a/src/shared/mpp/include/mpp_domains_comm.inc +++ b/src/shared/mpp/include/mpp_domains_comm.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_domains_comm.inc,v 18.0.24.1 2012/03/30 20:56:03 Zhi.Liang Exp $ +! $Id: mpp_domains_comm.inc,v 20.0 2013/12/14 00:24:40 fms Exp $ function mpp_redistribute_init_comm(domain_in,l_addrs_in, domain_out,l_addrs_out, & diff --git a/src/shared/mpp/include/mpp_domains_define.inc b/src/shared/mpp/include/mpp_domains_define.inc index 40ab95fe40..3510ef8134 100644 --- a/src/shared/mpp/include/mpp_domains_define.inc +++ b/src/shared/mpp/include/mpp_domains_define.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_domains_define.inc,v 19.0.2.1.2.1.2.1.2.1 2012/05/15 19:02:00 z1l Exp $ +! $Id: mpp_domains_define.inc,v 20.0 2013/12/14 00:24:42 fms Exp $ ! @@ -1013,6 +1013,10 @@ call set_bound_overlap( domain, EAST ) call set_bound_overlap( domain, NORTH ) end if + call set_domain_comm_inf(domain%update_T) + call set_domain_comm_inf(domain%update_E) + call set_domain_comm_inf(domain%update_C) + call set_domain_comm_inf(domain%update_N) end if !--- check the send and recv size are matching. @@ -1057,8 +1061,9 @@ js = update%send(m)%js(n); je = update%send(m)%je(n) msgsize = msgsize + (ie-is+1)*(je-js+1) end do - msg3(m) = msgsize - call mpp_send( msg3(m), plen=1, to_pe=update%send(m)%pe, tag=COMM_TAG_1) + l = update%send(m)%pe-mpp_root_pe() + msg3(l) = msgsize + call mpp_send( msg3(l), plen=1, to_pe=update%send(m)%pe, tag=COMM_TAG_1) enddo call mpp_sync_self(check=EVENT_RECV) @@ -1089,6 +1094,7 @@ deallocate( pes, pesall) + return end subroutine mpp_define_domains2D @@ -1398,6 +1404,12 @@ call set_contact_point( domain, EAST ) call set_contact_point( domain, NORTH ) + call set_domain_comm_inf(domain%update_T) + call set_domain_comm_inf(domain%update_E) + call set_domain_comm_inf(domain%update_C) + call set_domain_comm_inf(domain%update_N) + + !--- goffset setting is needed for exact global sum do m = 1, size(domain%tile_id(:)) tile = domain%tile_id(m) @@ -5102,6 +5114,8 @@ if(allocated(recv)) deallocate(recv) ptrIn => NULL() + call set_domain_comm_inf(overlap_out) + end subroutine set_overlaps @@ -6499,7 +6513,7 @@ end subroutine set_check_overlap subroutine set_bound_overlap( domain, position ) type(domain2d), intent(inout) :: domain integer, intent(in) :: position - integer :: m, n, l, count, dr, tMe + integer :: m, n, l, count, dr, tMe, i integer, parameter :: MAXCOUNT = 100 integer, dimension(MAXCOUNT) :: dir, rotation, is, ie, js, je, isMe, ieMe, jsMe, jeMe, tileMe integer, dimension(size(domain%x(:)), 4) :: nrecvl @@ -6509,9 +6523,15 @@ subroutine set_bound_overlap( domain, position ) type(overlapSpec), pointer :: bound => NULL() integer :: nlist_send, nlist_recv, ishift, jshift integer :: ism, iem, jsm, jem, nsend, nrecv + integer :: isg, ieg, jsg, jeg, nlist, list + integer :: isc1, iec1, jsc1, jec1 + integer :: isc2, iec2, jsc2, jec2 + integer :: isd, ied, jsd, jed + if( position == CENTER .OR. .NOT. domain%symmetry ) return call mpp_get_domain_shift(domain, ishift, jshift, position) + call mpp_get_global_domain(domain, isg, ieg, jsg, jeg, position=position) call mpp_get_memory_domain ( domain, ism, iem, jsm, jem ) select case(position) @@ -6544,124 +6564,87 @@ subroutine set_bound_overlap( domain, position ) bound%recv(:)%count = 0 endif !--- loop over the list of domains to find the boundary overlap for send + nlist = size(domain%list(:)) nsend = 0 - do m = 1, nlist_send - overlap => update%send(m) - if( overlap%count == 0 ) cycle - count = 0 - do n = 1, overlap%count - if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 1) then ! east - count=count+1 - dir(count) = 1 - rotation(count) = overlap%rotation(n) - tileMe(count) = overlap%tileMe(n) - select case( rotation(count) ) - case( ZERO ) ! W -> E - is(count) = overlap%is(n) - 1 - ie(count) = is(count) - js(count) = overlap%js(n) - je(count) = overlap%je(n) - case( NINETY ) ! S -> E - is(count) = overlap%is(n) - ie(count) = overlap%ie(n) - js(count) = overlap%js(n) - 1 - je(count) = js(count) - end select - end if - if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 3 ) then ! south - count=count+1 - dir(count) = 2 - rotation(count) = overlap%rotation(n) - tileMe(count) = overlap%tileMe(n) - select case( rotation(count) ) - case( ZERO ) ! N->S - is(count) = overlap%is(n) - ie(count) = overlap%ie(n) - js(count) = overlap%je(n) + 1 - je(count) = js(count) - case( MINUS_NINETY ) ! E->S - is(count) = overlap%ie(n) + 1 - ie(count) = is(count) - js(count) = overlap%js(n) - je(count) = overlap%je(n) - end select - end if - if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 5 ) then ! west - count=count+1 - dir(count) = 3 - rotation(count) = overlap%rotation(n) - tileMe(count) = overlap%tileMe(n) - select case( rotation(count) ) - case( ZERO ) ! E->W - is(count) = overlap%ie(n) + 1 - ie(count) = is(count) - js(count) = overlap%js(n) - je(count) = overlap%je(n) - case( NINETY ) ! N->W - is(count) = overlap%is(n) - ie(count) = overlap%ie(n) - js(count) = overlap%je(n) + 1 - je(count) = js(count) - end select - end if - if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 7 ) then ! north - count=count+1 - dir(count) = 4 - rotation(count) = overlap%rotation(n) - tileMe(count) = overlap%tileMe(n) - select case( rotation(count) ) - case( ZERO ) ! S->N - is(count) = overlap%is(n) - ie(count) = overlap%ie(n) - js(count) = overlap%js(n) - 1 - je(count) = js(count) - case( MINUS_NINETY ) ! W->N - is(count) = overlap%is(n) - 1 - ie(count) = is(count) - js(count) = overlap%js(n) - je(count) = overlap%je(n) - end select - end if - end do ! do n =1, overlap%count - if(count>0) then - nsend = nsend + 1 - bound%send(nsend)%count = count - bound%send(nsend)%pe = overlap%pe - allocate(bound%send(nsend)%is(count), bound%send(nsend)%ie(count) ) - allocate(bound%send(nsend)%js(count), bound%send(nsend)%je(count) ) - allocate(bound%send(nsend)%dir(count), bound%send(nsend)%rotation(count) ) - allocate(bound%send(nsend)%tileMe(count)) - bound%send(nsend)%is(:) = is(1:count) - bound%send(nsend)%ie(:) = ie(1:count) - bound%send(nsend)%js(:) = js(1:count) - bound%send(nsend)%je(:) = je(1:count) - bound%send(nsend)%dir(:) = dir(1:count) - bound%send(nsend)%tileMe(:) = tileMe(1:count) - bound%send(nsend)%rotation(:) = rotation(1:count) - end if - end do ! end do list = 0, nlist + !--- will computing overlap for tripolar grid. + if( BTEST(domain%fold,NORTH) ) then + !--- currently only set up for west and south boundary. + !---south boundary + if( position == NORTH .OR. position == CORNER ) then + isc1 = domain%x(1)%compute%begin; iec1 = domain%x(1)%compute%end +ishift + jsc1 = domain%y(1)%compute%end+jshift; jec1 = jsc1 + endif + !--- west boundary + if( position == EAST .OR. position == CORNER ) then + isc2 = domain%x(1)%compute%end+ishift; iec2 = isc2 + jsc2 = domain%y(1)%compute%begin; jec2 = domain%y(1)%compute%end + jshift + endif - !--- loop over the list of domains to find the boundary overlap for recv - bound%nsend = nsend - nrecvl(:,:) = 0 - nrecv = 0 - - do m = 1, nlist_recv - overlap => update%recv(m) - if( overlap%count == 0 ) cycle - count = 0 - do n = 1, overlap%count - if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 1) then ! east - count=count+1 - dir(count) = 1 - rotation(count) = overlap%rotation(n) - isMe(count) = overlap%isMe(n) - 1 - ieMe(count) = isMe(count) - jsMe(count) = overlap%jsMe(n) - jeMe(count) = overlap%jeMe(n) - tileMe(count) = overlap%tileMe(n) - if( overlap%is_refined(n)) then + do list = 0,nlist-1 + m = mod( domain%pos+list, nlist ) + count = 0 + + !--- south boundary + if( position == NORTH .OR. position == CORNER ) then + isd = domain%list(m)%x(1)%compute%begin; ied = domain%list(m)%x(1)%compute%end + ishift + jsd = domain%list(m)%y(1)%compute%begin; jed = jsd + if( isc1 == isd .AND. iec1 == ied .AND. jsc1 == jsd) then + count = count + 1 + is(count) = isc1; ie(count) = iec1 + js(count) = jsc1; je(count) = jec1 + dir(count) = 2 + endif + endif + + !--- west boundary + if( position == EAST .OR. position == CORNER ) then + isd = domain%list(m)%x(1)%compute%begin; ied = isd + jsd = domain%list(m)%y(1)%compute%begin; jed = domain%list(m)%y(1)%compute%end + jshift + !--- cyclic in x-direction is assumed for folded-north + if(isd == isg) then + isd = ieg; ied = ieg + endif + if( isc2 == isd .AND. jsc2 == jsd .AND. jec2 == jed ) then + count = count + 1 + is(count) = isc2; ie(count) = iec2 + js(count) = jsc2; je(count) = jec2 + dir(count) = 3 + endif + endif + + if(count >0) then + nsend = nsend + 1 + if(nsend > nlist_send) call mpp_error(FATAL, "set_bound_overlap: nsend > nlist_send") + bound%send(nsend)%count = count + bound%send(nsend)%pe = domain%list(m)%pe + allocate(bound%send(nsend)%is(count), bound%send(nsend)%ie(count) ) + allocate(bound%send(nsend)%js(count), bound%send(nsend)%je(count) ) + allocate(bound%send(nsend)%dir(count), bound%send(nsend)%rotation(count) ) + allocate(bound%send(nsend)%tileMe(count)) + bound%send(nsend)%is(:) = is(1:count) + bound%send(nsend)%ie(:) = ie(1:count) + bound%send(nsend)%js(:) = js(1:count) + bound%send(nsend)%je(:) = je(1:count) + bound%send(nsend)%dir(:) = dir(1:count) + bound%send(nsend)%tileMe(:) = 1 + bound%send(nsend)%rotation(:) = ZERO + endif + enddo + else + !--- The following did not consider wide halo case. + do m = 1, nlist_send + overlap => update%send(m) + if( overlap%count == 0 ) cycle + count = 0 + do n = 1, overlap%count + !--- currently not support folded-north + if( overlap%rotation(n) == ONE_HUNDRED_EIGHTY ) cycle + if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 1) then ! east + count=count+1 + dir(count) = 1 + rotation(count) = overlap%rotation(n) + tileMe(count) = overlap%tileMe(n) select case( rotation(count) ) case( ZERO ) ! W -> E is(count) = overlap%is(n) - 1 @@ -6674,34 +6657,12 @@ subroutine set_bound_overlap( domain, position ) js(count) = overlap%js(n) - 1 je(count) = js(count) end select - else - is(count) = overlap%is(n) - 1 - ie(count) = is(count) - js(count) = overlap%js(n) - je(count) = overlap%je(n) end if - tMe = tileMe(count) - nrecvl(tMe, 1) = nrecvl(tMe,1) + 1 - islMe(tMe,1,nrecvl(tMe, 1)) = isMe(count) - ielMe(tMe,1,nrecvl(tMe, 1)) = ieMe(count) - jslMe(tMe,1,nrecvl(tMe, 1)) = jsMe(count) - jelMe(tMe,1,nrecvl(tMe, 1)) = jeMe(count) - isl (tMe,1,nrecvl(tMe, 1)) = is (count) - iel (tMe,1,nrecvl(tMe, 1)) = ie (count) - jsl (tMe,1,nrecvl(tMe, 1)) = js (count) - jel (tMe,1,nrecvl(tMe, 1)) = je (count) - end if - - if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 3) then ! south - count=count+1 - dir(count) = 2 - rotation(count) = overlap%rotation(n) - isMe(count) = overlap%isMe(n) - ieMe(count) = overlap%ieMe(n) - jsMe(count) = overlap%jeMe(n) + 1 - jeMe(count) = jsMe(count) - tileMe(count) = overlap%tileMe(n) - if( overlap%is_refined(n)) then + if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 3 ) then ! south + count=count+1 + dir(count) = 2 + rotation(count) = overlap%rotation(n) + tileMe(count) = overlap%tileMe(n) select case( rotation(count) ) case( ZERO ) ! N->S is(count) = overlap%is(n) @@ -6714,74 +6675,30 @@ subroutine set_bound_overlap( domain, position ) js(count) = overlap%js(n) je(count) = overlap%je(n) end select - else - is(count) = overlap%is(n) - ie(count) = overlap%ie(n) - js(count) = overlap%je(n) + 1 - je(count) = js(count) end if - tMe = tileMe(count) - nrecvl(tMe, 2) = nrecvl(tMe,2) + 1 - islMe(tMe,2,nrecvl(tMe, 2)) = isMe(count) - ielMe(tMe,2,nrecvl(tMe, 2)) = ieMe(count) - jslMe(tMe,2,nrecvl(tMe, 2)) = jsMe(count) - jelMe(tMe,2,nrecvl(tMe, 2)) = jeMe(count) - isl (tMe,2,nrecvl(tMe, 2)) = is (count) - iel (tMe,2,nrecvl(tMe, 2)) = ie (count) - jsl (tMe,2,nrecvl(tMe, 2)) = js (count) - jel (tMe,2,nrecvl(tMe, 2)) = je (count) - end if - - if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 5) then ! west - count=count+1 - dir(count) = 3 - rotation(count) = overlap%rotation(n) - isMe(count) = overlap%ieMe(n) + 1 - ieMe(count) = isMe(count) - jsMe(count) = overlap%jsMe(n) - jeMe(count) = overlap%jeMe(n) - tileMe(count) = overlap%tileMe(n) - if( overlap%is_refined(n)) then + if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 5 ) then ! west + count=count+1 + dir(count) = 3 + rotation(count) = overlap%rotation(n) + tileMe(count) = overlap%tileMe(n) select case( rotation(count) ) case( ZERO ) ! E->W is(count) = overlap%ie(n) + 1 ie(count) = is(count) js(count) = overlap%js(n) je(count) = overlap%je(n) - case( NINETY ) ! S -> E + case( NINETY ) ! N->W is(count) = overlap%is(n) ie(count) = overlap%ie(n) js(count) = overlap%je(n) + 1 je(count) = js(count) end select - else - is(count) = overlap%ie(n) + 1 - ie(count) = is(count) - js(count) = overlap%js(n) - je(count) = overlap%je(n) end if - tMe = tileMe(count) - nrecvl(tMe, 3) = nrecvl(tMe,3) + 1 - islMe(tMe,3,nrecvl(tMe, 3)) = isMe(count) - ielMe(tMe,3,nrecvl(tMe, 3)) = ieMe(count) - jslMe(tMe,3,nrecvl(tMe, 3)) = jsMe(count) - jelMe(tMe,3,nrecvl(tMe, 3)) = jeMe(count) - isl (tMe,3,nrecvl(tMe, 3)) = is (count) - iel (tMe,3,nrecvl(tMe, 3)) = ie (count) - jsl (tMe,3,nrecvl(tMe, 3)) = js (count) - jel (tMe,3,nrecvl(tMe, 3)) = je (count) - end if - - if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 7) then ! north - count=count+1 - dir(count) = 4 - rotation(count) = overlap%rotation(n) - isMe(count) = overlap%isMe(n) - ieMe(count) = overlap%ieMe(n) - jsMe(count) = overlap%jsMe(n) - 1 - jeMe(count) = jsMe(count) - tileMe(count) = overlap%tileMe(n) - if( overlap%is_refined(n)) then + if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 7 ) then ! north + count=count+1 + dir(count) = 4 + rotation(count) = overlap%rotation(n) + tileMe(count) = overlap%tileMe(n) select case( rotation(count) ) case( ZERO ) ! S->N is(count) = overlap%is(n) @@ -6794,48 +6711,315 @@ subroutine set_bound_overlap( domain, position ) js(count) = overlap%js(n) je(count) = overlap%je(n) end select - else - is(count) = overlap%is(n) - ie(count) = overlap%ie(n) - js(count) = overlap%js(n) - 1 - je(count) = js(count) end if - tMe = tileMe(count) - nrecvl(tMe, 4) = nrecvl(tMe,4) + 1 - islMe(tMe,4,nrecvl(tMe, 4)) = isMe(count) - ielMe(tMe,4,nrecvl(tMe, 4)) = ieMe(count) - jslMe(tMe,4,nrecvl(tMe, 4)) = jsMe(count) - jelMe(tMe,4,nrecvl(tMe, 4)) = jeMe(count) - isl (tMe,4,nrecvl(tMe, 4)) = is (count) - iel (tMe,4,nrecvl(tMe, 4)) = ie (count) - jsl (tMe,4,nrecvl(tMe, 4)) = js (count) - jel (tMe,4,nrecvl(tMe, 4)) = je (count) - end if - end do ! do n = 1, overlap%count + end do ! do n =1, overlap%count if(count>0) then - nrecv = nrecv + 1 - bound%recv(nrecv)%count = count - bound%recv(nrecv)%pe = overlap%pe - allocate(bound%recv(nrecv)%isMe(count), bound%recv(nrecv)%ieMe(count) ) - allocate(bound%recv(nrecv)%jsMe(count), bound%recv(nrecv)%jeMe(count) ) - allocate(bound%recv(nrecv)%is(count), bound%recv(nrecv)%ie(count) ) - allocate(bound%recv(nrecv)%js(count), bound%recv(nrecv)%je(count) ) - allocate(bound%recv(nrecv)%dir(count), bound%recv(nrecv)%index(count) ) - allocate(bound%recv(nrecv)%tileMe(count), bound%recv(nrecv)%rotation(count) ) - bound%recv(nrecv)%isMe(:) = isMe(1:count) - bound%recv(nrecv)%ieMe(:) = ieMe(1:count) - bound%recv(nrecv)%jsMe(:) = jsMe(1:count) - bound%recv(nrecv)%jeMe(:) = jeMe(1:count) - bound%recv(nrecv)%is(:) = is(1:count) - bound%recv(nrecv)%ie(:) = ie(1:count) - bound%recv(nrecv)%js(:) = js(1:count) - bound%recv(nrecv)%je(:) = je(1:count) - bound%recv(nrecv)%dir(:) = dir(1:count) - bound%recv(nrecv)%tileMe(:) = tileMe(1:count) - bound%recv(nrecv)%rotation(:) = rotation(1:count) + nsend = nsend + 1 + bound%send(nsend)%count = count + bound%send(nsend)%pe = overlap%pe + allocate(bound%send(nsend)%is(count), bound%send(nsend)%ie(count) ) + allocate(bound%send(nsend)%js(count), bound%send(nsend)%je(count) ) + allocate(bound%send(nsend)%dir(count), bound%send(nsend)%rotation(count) ) + allocate(bound%send(nsend)%tileMe(count)) + bound%send(nsend)%is(:) = is(1:count) + bound%send(nsend)%ie(:) = ie(1:count) + bound%send(nsend)%js(:) = js(1:count) + bound%send(nsend)%je(:) = je(1:count) + bound%send(nsend)%dir(:) = dir(1:count) + bound%send(nsend)%tileMe(:) = tileMe(1:count) + bound%send(nsend)%rotation(:) = rotation(1:count) end if end do ! end do list = 0, nlist + endif + + !--- loop over the list of domains to find the boundary overlap for recv + bound%nsend = nsend + nrecvl(:,:) = 0 + nrecv = 0 + + !--- will computing overlap for tripolar grid. + if( BTEST(domain%fold,NORTH) ) then + tMe = 1 + !--- currently only set up for west and south boundary. + !---south boundary + if( position == NORTH .OR. position == CORNER ) then + isc1 = domain%x(1)%compute%begin; iec1 = domain%x(1)%compute%end +ishift + jsc1 = domain%y(1)%compute%begin; jec1 = jsc1 + endif + !--- west boundary + if( position == EAST .OR. position == CORNER ) then + isc2 = domain%x(1)%compute%begin; iec2 = isc2 + jsc2 = domain%y(1)%compute%begin; jec2 = domain%y(1)%compute%end + jshift + endif + + do list = 0,nlist-1 + m = mod( domain%pos+nlist-list, nlist ) + count = 0 + + !--- south boundary + if( position == NORTH .OR. position == CORNER ) then + isd = domain%list(m)%x(1)%compute%begin; ied = domain%list(m)%x(1)%compute%end + ishift + jsd = domain%list(m)%y(1)%compute%end+jshift; jed = jsd + if( isc1 == isd .AND. iec1 == ied .AND. jsc1 == jsd) then + count = count + 1 + is(count) = isc1; ie(count) = iec1 + js(count) = jsc1; je(count) = jec1 + dir(count) = 2 + nrecvl(tMe, 2) = nrecvl(tMe,2) + 1 + islMe(tMe,2,nrecvl(tMe, 2)) = is(count) + ielMe(tMe,2,nrecvl(tMe, 2)) = ie(count) + jslMe(tMe,2,nrecvl(tMe, 2)) = js(count) + jelMe(tMe,2,nrecvl(tMe, 2)) = je(count) + isl (tMe,2,nrecvl(tMe, 2)) = is(count) + iel (tMe,2,nrecvl(tMe, 2)) = ie(count) + jsl (tMe,2,nrecvl(tMe, 2)) = js(count) + jel (tMe,2,nrecvl(tMe, 2)) = je(count) + + endif + endif + + !--- west boundary + if( position == EAST .OR. position == CORNER ) then + isd = domain%list(m)%x(1)%compute%end+ishift; ied = isd + jsd = domain%list(m)%y(1)%compute%begin; jed = domain%list(m)%y(1)%compute%end + jshift + !--- cyclic in x-direction is assumed for folded-north + if(ied == ieg) then + isd = isg; ied = isg + endif + if( isc2 == isd .AND. jsc2 == jsd .AND. jec2 == jed ) then + count = count + 1 + is(count) = isc2; ie(count) = iec2 + js(count) = jsc2; je(count) = jec2 + dir(count) = 3 + nrecvl(tMe, 3) = nrecvl(tMe,3) + 1 + islMe(tMe,3,nrecvl(tMe, 3)) = is(count) + ielMe(tMe,3,nrecvl(tMe, 3)) = ie(count) + jslMe(tMe,3,nrecvl(tMe, 3)) = js(count) + jelMe(tMe,3,nrecvl(tMe, 3)) = je(count) + isl (tMe,3,nrecvl(tMe, 3)) = is(count) + iel (tMe,3,nrecvl(tMe, 3)) = ie(count) + jsl (tMe,3,nrecvl(tMe, 3)) = js(count) + jel (tMe,3,nrecvl(tMe, 3)) = je(count) + endif + endif + + if(count >0) then + nrecv = nrecv + 1 + if(nrecv > nlist_recv) call mpp_error(FATAL, "set_bound_overlap: nrecv > nlist_recv") + bound%recv(nrecv)%count = count + bound%recv(nrecv)%pe = domain%list(m)%pe + allocate(bound%recv(nrecv)%isMe(count), bound%recv(nrecv)%ieMe(count) ) + allocate(bound%recv(nrecv)%jsMe(count), bound%recv(nrecv)%jeMe(count) ) + allocate(bound%recv(nrecv)%is(count), bound%recv(nrecv)%ie(count) ) + allocate(bound%recv(nrecv)%js(count), bound%recv(nrecv)%je(count) ) + allocate(bound%recv(nrecv)%dir(count), bound%recv(nrecv)%index(count) ) + allocate(bound%recv(nrecv)%tileMe(count), bound%recv(nrecv)%rotation(count) ) + bound%recv(nrecv)%is(:) = is(1:count) + bound%recv(nrecv)%ie(:) = ie(1:count) + bound%recv(nrecv)%js(:) = js(1:count) + bound%recv(nrecv)%je(:) = je(1:count) + bound%recv(nrecv)%isMe(:) = is(1:count) + bound%recv(nrecv)%ieMe(:) = ie(1:count) + bound%recv(nrecv)%jsMe(:) = js(1:count) + bound%recv(nrecv)%jeMe(:) = je(1:count) + + bound%recv(nrecv)%dir(:) = dir(1:count) + bound%recv(nrecv)%tileMe(:) = 1 + bound%recv(nrecv)%rotation(:) = ZERO + endif + enddo + else + do m = 1, nlist_recv + overlap => update%recv(m) + if( overlap%count == 0 ) cycle + count = 0 + do n = 1, overlap%count + !--- currently not support folded-north + if( overlap%rotation(n) == ONE_HUNDRED_EIGHTY ) cycle + if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 1) then ! east + count=count+1 + dir(count) = 1 + rotation(count) = overlap%rotation(n) + isMe(count) = overlap%isMe(n) - 1 + ieMe(count) = isMe(count) + jsMe(count) = overlap%jsMe(n) + jeMe(count) = overlap%jeMe(n) + tileMe(count) = overlap%tileMe(n) + if( overlap%is_refined(n)) then + select case( rotation(count) ) + case( ZERO ) ! W -> E + is(count) = overlap%is(n) - 1 + ie(count) = is(count) + js(count) = overlap%js(n) + je(count) = overlap%je(n) + case( NINETY ) ! S -> E + is(count) = overlap%is(n) + ie(count) = overlap%ie(n) + js(count) = overlap%js(n) - 1 + je(count) = js(count) + end select + else + is(count) = overlap%is(n) - 1 + ie(count) = is(count) + js(count) = overlap%js(n) + je(count) = overlap%je(n) + end if + tMe = tileMe(count) + nrecvl(tMe, 1) = nrecvl(tMe,1) + 1 + islMe(tMe,1,nrecvl(tMe, 1)) = isMe(count) + ielMe(tMe,1,nrecvl(tMe, 1)) = ieMe(count) + jslMe(tMe,1,nrecvl(tMe, 1)) = jsMe(count) + jelMe(tMe,1,nrecvl(tMe, 1)) = jeMe(count) + isl (tMe,1,nrecvl(tMe, 1)) = is (count) + iel (tMe,1,nrecvl(tMe, 1)) = ie (count) + jsl (tMe,1,nrecvl(tMe, 1)) = js (count) + jel (tMe,1,nrecvl(tMe, 1)) = je (count) + end if + + if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 3) then ! south + count=count+1 + dir(count) = 2 + rotation(count) = overlap%rotation(n) + isMe(count) = overlap%isMe(n) + ieMe(count) = overlap%ieMe(n) + jsMe(count) = overlap%jeMe(n) + 1 + jeMe(count) = jsMe(count) + tileMe(count) = overlap%tileMe(n) + if( overlap%is_refined(n)) then + select case( rotation(count) ) + case( ZERO ) ! N->S + is(count) = overlap%is(n) + ie(count) = overlap%ie(n) + js(count) = overlap%je(n) + 1 + je(count) = js(count) + case( MINUS_NINETY ) ! E->S + is(count) = overlap%ie(n) + 1 + ie(count) = is(count) + js(count) = overlap%js(n) + je(count) = overlap%je(n) + end select + else + is(count) = overlap%is(n) + ie(count) = overlap%ie(n) + js(count) = overlap%je(n) + 1 + je(count) = js(count) + end if + tMe = tileMe(count) + nrecvl(tMe, 2) = nrecvl(tMe,2) + 1 + islMe(tMe,2,nrecvl(tMe, 2)) = isMe(count) + ielMe(tMe,2,nrecvl(tMe, 2)) = ieMe(count) + jslMe(tMe,2,nrecvl(tMe, 2)) = jsMe(count) + jelMe(tMe,2,nrecvl(tMe, 2)) = jeMe(count) + isl (tMe,2,nrecvl(tMe, 2)) = is (count) + iel (tMe,2,nrecvl(tMe, 2)) = ie (count) + jsl (tMe,2,nrecvl(tMe, 2)) = js (count) + jel (tMe,2,nrecvl(tMe, 2)) = je (count) + end if + if( (position == EAST .OR. position == CORNER) .AND. overlap%dir(n) == 5) then ! west + count=count+1 + dir(count) = 3 + rotation(count) = overlap%rotation(n) + isMe(count) = overlap%ieMe(n) + 1 + ieMe(count) = isMe(count) + jsMe(count) = overlap%jsMe(n) + jeMe(count) = overlap%jeMe(n) + tileMe(count) = overlap%tileMe(n) + if( overlap%is_refined(n)) then + select case( rotation(count) ) + case( ZERO ) ! E->W + is(count) = overlap%ie(n) + 1 + ie(count) = is(count) + js(count) = overlap%js(n) + je(count) = overlap%je(n) + case( NINETY ) ! S -> E + is(count) = overlap%is(n) + ie(count) = overlap%ie(n) + js(count) = overlap%je(n) + 1 + je(count) = js(count) + end select + else + is(count) = overlap%ie(n) + 1 + ie(count) = is(count) + js(count) = overlap%js(n) + je(count) = overlap%je(n) + end if + tMe = tileMe(count) + nrecvl(tMe, 3) = nrecvl(tMe,3) + 1 + islMe(tMe,3,nrecvl(tMe, 3)) = isMe(count) + ielMe(tMe,3,nrecvl(tMe, 3)) = ieMe(count) + jslMe(tMe,3,nrecvl(tMe, 3)) = jsMe(count) + jelMe(tMe,3,nrecvl(tMe, 3)) = jeMe(count) + isl (tMe,3,nrecvl(tMe, 3)) = is (count) + iel (tMe,3,nrecvl(tMe, 3)) = ie (count) + jsl (tMe,3,nrecvl(tMe, 3)) = js (count) + jel (tMe,3,nrecvl(tMe, 3)) = je (count) + end if + + if( (position == NORTH .OR. position == CORNER) .AND. overlap%dir(n) == 7) then ! north + count=count+1 + dir(count) = 4 + rotation(count) = overlap%rotation(n) + isMe(count) = overlap%isMe(n) + ieMe(count) = overlap%ieMe(n) + jsMe(count) = overlap%jsMe(n) - 1 + jeMe(count) = jsMe(count) + tileMe(count) = overlap%tileMe(n) + if( overlap%is_refined(n)) then + select case( rotation(count) ) + case( ZERO ) ! S->N + is(count) = overlap%is(n) + ie(count) = overlap%ie(n) + js(count) = overlap%js(n) - 1 + je(count) = js(count) + case( MINUS_NINETY ) ! W->N + is(count) = overlap%is(n) - 1 + ie(count) = is(count) + js(count) = overlap%js(n) + je(count) = overlap%je(n) + end select + else + is(count) = overlap%is(n) + ie(count) = overlap%ie(n) + js(count) = overlap%js(n) - 1 + je(count) = js(count) + end if + tMe = tileMe(count) + nrecvl(tMe, 4) = nrecvl(tMe,4) + 1 + islMe(tMe,4,nrecvl(tMe, 4)) = isMe(count) + ielMe(tMe,4,nrecvl(tMe, 4)) = ieMe(count) + jslMe(tMe,4,nrecvl(tMe, 4)) = jsMe(count) + jelMe(tMe,4,nrecvl(tMe, 4)) = jeMe(count) + isl (tMe,4,nrecvl(tMe, 4)) = is (count) + iel (tMe,4,nrecvl(tMe, 4)) = ie (count) + jsl (tMe,4,nrecvl(tMe, 4)) = js (count) + jel (tMe,4,nrecvl(tMe, 4)) = je (count) + end if + end do ! do n = 1, overlap%count + if(count>0) then + nrecv = nrecv + 1 + bound%recv(nrecv)%count = count + bound%recv(nrecv)%pe = overlap%pe + allocate(bound%recv(nrecv)%isMe(count), bound%recv(nrecv)%ieMe(count) ) + allocate(bound%recv(nrecv)%jsMe(count), bound%recv(nrecv)%jeMe(count) ) + allocate(bound%recv(nrecv)%is(count), bound%recv(nrecv)%ie(count) ) + allocate(bound%recv(nrecv)%js(count), bound%recv(nrecv)%je(count) ) + allocate(bound%recv(nrecv)%dir(count), bound%recv(nrecv)%index(count) ) + allocate(bound%recv(nrecv)%tileMe(count), bound%recv(nrecv)%rotation(count) ) + bound%recv(nrecv)%isMe(:) = isMe(1:count) + bound%recv(nrecv)%ieMe(:) = ieMe(1:count) + bound%recv(nrecv)%jsMe(:) = jsMe(1:count) + bound%recv(nrecv)%jeMe(:) = jeMe(1:count) + bound%recv(nrecv)%is(:) = is(1:count) + bound%recv(nrecv)%ie(:) = ie(1:count) + bound%recv(nrecv)%js(:) = js(1:count) + bound%recv(nrecv)%je(:) = je(1:count) + bound%recv(nrecv)%dir(:) = dir(1:count) + bound%recv(nrecv)%tileMe(:) = tileMe(1:count) + bound%recv(nrecv)%rotation(:) = rotation(1:count) + end if + end do ! end do list = 0, nlist + endif bound%nrecv = nrecv !--- find the boundary index for each contact within the east boundary @@ -6863,6 +7047,7 @@ subroutine set_bound_overlap( domain, position ) end do + end subroutine set_bound_overlap @@ -8047,3 +8232,47 @@ subroutine check_overlap_pe_order(domain, overlap, name) end subroutine check_overlap_pe_order + + +!############################################################################### +subroutine set_domain_comm_inf(update) + type(overlapSpec), intent(inout) :: update + + integer :: m, totsize, n + + + ! first set the send and recv size + update%sendsize = 0 + update%recvsize = 0 + do m = 1, update%nrecv + totsize = 0 + do n = 1, update%recv(m)%count + totsize = totsize + update%recv(m)%msgsize(n) + enddo + update%recv(m)%totsize = totsize + if(m==1) then + update%recv(m)%start_pos = 0 + else + update%recv(m)%start_pos = update%recv(m-1)%start_pos + update%recv(m-1)%totsize + endif + update%recvsize = update%recvsize + totsize + enddo + + do m = 1, update%nsend + totsize = 0 + do n = 1, update%send(m)%count + totsize = totsize + update%send(m)%msgsize(n) + enddo + update%send(m)%totsize = totsize + if(m==1) then + update%send(m)%start_pos = 0 + else + update%send(m)%start_pos = update%send(m-1)%start_pos + update%send(m-1)%totsize + endif + update%sendsize = update%sendsize + totsize + enddo + + return + + +end subroutine set_domain_comm_inf diff --git a/src/shared/mpp/include/mpp_domains_misc.inc b/src/shared/mpp/include/mpp_domains_misc.inc index 9e4228d680..77267e3131 100644 --- a/src/shared/mpp/include/mpp_domains_misc.inc +++ b/src/shared/mpp/include/mpp_domains_misc.inc @@ -54,6 +54,9 @@ end if !--- namelist +#ifdef INTERNAL_FILE_NML + read (input_nml_file, mpp_domains_nml, iostat=io_status) +#else unit_begin = 103 unit_end = 512 do unit_nml = unit_begin, unit_end @@ -64,6 +67,12 @@ open(unit_nml,file='input.nml', iostat=io_status) read(unit_nml,mpp_domains_nml,iostat=io_status) close(unit_nml) +#endif + + if (io_status > 0) then + call mpp_error(FATAL,'=>mpp_domains_init: Error reading input.nml') + endif + select case(lowercase(trim(debug_update_domain))) case("none") @@ -99,8 +108,7 @@ recv_clock = mpp_clock_id( 'Halo recv' ) unpk_clock = mpp_clock_id( 'Halo unpk' ) wait_clock = mpp_clock_id( 'Halo wait' ) - pack_clock_nonblock = mpp_clock_id( 'Halo pack nonblock' ) - send_clock_nonblock = mpp_clock_id( 'Halo send nonblock' ) + send_pack_clock_nonblock = mpp_clock_id( 'Halo pack and send nonblock' ) recv_clock_nonblock = mpp_clock_id( 'Halo recv nonblock' ) unpk_clock_nonblock = mpp_clock_id( 'Halo unpk nonblock' ) wait_clock_nonblock = mpp_clock_id( 'Halo wait nonblock' ) @@ -140,6 +148,8 @@ subroutine init_nonblock_type( nonblock_obj ) nonblock_obj%request_send(:) = 0 nonblock_obj%request_recv(:) = 0 #endif + nonblock_obj%buffer_pos_send(:) = 0 + nonblock_obj%buffer_pos_recv(:) = 0 nonblock_obj%nfields = 0 nonblock_obj%field_addrs(:) = 0 nonblock_obj%field_addrs2(:) = 0 @@ -1668,18 +1678,18 @@ end subroutine init_nonblock_type #define MPP_GET_BOUNDARY_2D_ mpp_get_boundary_r8_2d #undef MPP_GET_BOUNDARY_3D_ #define MPP_GET_BOUNDARY_3D_ mpp_get_boundary_r8_3d -#undef MPP_GET_BOUNDARY_4D_ -#define MPP_GET_BOUNDARY_4D_ mpp_get_boundary_r8_4d -#undef MPP_GET_BOUNDARY_5D_ -#define MPP_GET_BOUNDARY_5D_ mpp_get_boundary_r8_5d +!#undef MPP_GET_BOUNDARY_4D_ +!#define MPP_GET_BOUNDARY_4D_ mpp_get_boundary_r8_4d +!#undef MPP_GET_BOUNDARY_5D_ +!#define MPP_GET_BOUNDARY_5D_ mpp_get_boundary_r8_5d #undef MPP_GET_BOUNDARY_2D_V_ #define MPP_GET_BOUNDARY_2D_V_ mpp_get_boundary_r8_2dv #undef MPP_GET_BOUNDARY_3D_V_ #define MPP_GET_BOUNDARY_3D_V_ mpp_get_boundary_r8_3dv -#undef MPP_GET_BOUNDARY_4D_V_ -#define MPP_GET_BOUNDARY_4D_V_ mpp_get_boundary_r8_4dv -#undef MPP_GET_BOUNDARY_5D_V_ -#define MPP_GET_BOUNDARY_5D_V_ mpp_get_boundary_r8_5dv +!#undef MPP_GET_BOUNDARY_4D_V_ +!#define MPP_GET_BOUNDARY_4D_V_ mpp_get_boundary_r8_4dv +!#undef MPP_GET_BOUNDARY_5D_V_ +!#define MPP_GET_BOUNDARY_5D_V_ mpp_get_boundary_r8_5dv #include #ifdef OVERLOAD_R4 @@ -1689,18 +1699,18 @@ end subroutine init_nonblock_type #define MPP_GET_BOUNDARY_2D_ mpp_get_boundary_r4_2d #undef MPP_GET_BOUNDARY_3D_ #define MPP_GET_BOUNDARY_3D_ mpp_get_boundary_r4_3d -#undef MPP_GET_BOUNDARY_4D_ -#define MPP_GET_BOUNDARY_4D_ mpp_get_boundary_r4_4d -#undef MPP_GET_BOUNDARY_5D_ -#define MPP_GET_BOUNDARY_5D_ mpp_get_boundary_r4_5d +!#undef MPP_GET_BOUNDARY_4D_ +!#define MPP_GET_BOUNDARY_4D_ mpp_get_boundary_r4_4d +!#undef MPP_GET_BOUNDARY_5D_ +!#define MPP_GET_BOUNDARY_5D_ mpp_get_boundary_r4_5d #undef MPP_GET_BOUNDARY_2D_V_ #define MPP_GET_BOUNDARY_2D_V_ mpp_get_boundary_r4_2dv #undef MPP_GET_BOUNDARY_3D_V_ #define MPP_GET_BOUNDARY_3D_V_ mpp_get_boundary_r4_3dv -#undef MPP_GET_BOUNDARY_4D_V_ -#define MPP_GET_BOUNDARY_4D_V_ mpp_get_boundary_r4_4dv -#undef MPP_GET_BOUNDARY_5D_V_ -#define MPP_GET_BOUNDARY_5D_V_ mpp_get_boundary_r4_5dv +!#undef MPP_GET_BOUNDARY_4D_V_ +!#define MPP_GET_BOUNDARY_4D_V_ mpp_get_boundary_r4_4dv +!#undef MPP_GET_BOUNDARY_5D_V_ +!#define MPP_GET_BOUNDARY_5D_V_ mpp_get_boundary_r4_5dv #include #endif diff --git a/src/shared/mpp/include/mpp_domains_reduce.inc b/src/shared/mpp/include/mpp_domains_reduce.inc index 9c18d886a4..f268075764 100644 --- a/src/shared/mpp/include/mpp_domains_reduce.inc +++ b/src/shared/mpp/include/mpp_domains_reduce.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_domains_reduce.inc,v 18.0 2010/03/02 23:57:19 fms Exp $ +! $Id: mpp_domains_reduce.inc,v 20.0 2013/12/14 00:24:46 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -912,9 +912,11 @@ #undef MPP_DO_GLOBAL_FIELD_3D_ #define MPP_DO_GLOBAL_FIELD_3D_ mpp_do_global_field2D_l8_3d +#define LOGICAL_VARIABLE #undef MPP_TYPE_ #define MPP_TYPE_ logical(LONG_KIND) #include +#undef LOGICAL_VARIABLE #endif #ifdef OVERLOAD_R4 @@ -941,7 +943,9 @@ #undef MPP_DO_GLOBAL_FIELD_3D_ #define MPP_DO_GLOBAL_FIELD_3D_ mpp_do_global_field2D_l4_3d +#define LOGICAL_VARIABLE #undef MPP_TYPE_ #define MPP_TYPE_ logical(INT_KIND) #include +#undef LOGICAL_VARIABLE diff --git a/src/shared/mpp/include/mpp_domains_util.inc b/src/shared/mpp/include/mpp_domains_util.inc index 2d2cca35bd..4588ea3baf 100644 --- a/src/shared/mpp/include/mpp_domains_util.inc +++ b/src/shared/mpp/include/mpp_domains_util.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_domains_util.inc,v 19.0.4.1 2012/05/11 14:54:02 Zhi.Liang Exp $ +! $Id: mpp_domains_util.inc,v 20.0 2013/12/14 00:24:48 fms Exp $ ! ! @@ -1110,6 +1110,73 @@ end subroutine mpp_get_domain_shift end function mpp_get_tile_npes + !######################################################################## + ! get the processors list used on current tile. + subroutine mpp_get_tile_pelist(domain, pelist) + type(domain2d), intent(in) :: domain + integer, intent(inout) :: pelist(:) + integer :: npes_on_tile + integer :: i, tile, pos + + npes_on_tile = mpp_get_tile_npes(domain) + if(size(pelist(:)) .NE. npes_on_tile) call mpp_error(FATAL, & + "mpp_domains_util.inc(mpp_get_tile_pelist): size(pelist) does not equal npes on current tile") + tile = domain%tile_id(1) + pos = 0 + do i = 0, size(domain%list(:))-1 + if(tile == domain%list(i)%tile_id(1)) then + pos = pos+1 + pelist(pos) = domain%list(i)%pe + endif + enddo + + return + + end subroutine mpp_get_tile_pelist + +!##################################################################### +subroutine mpp_get_tile_compute_domains( domain, xbegin, xend, ybegin, yend, position ) + type(domain2D), intent(in) :: domain + integer, intent(out), dimension(:) :: xbegin, xend, ybegin, yend + integer, intent(in ), optional :: position + + integer :: i, ishift, jshift + integer :: npes_on_tile, pos, tile + + call mpp_get_domain_shift( domain, ishift, jshift, position ) + + + if( .NOT.module_is_initialized ) & + call mpp_error( FATAL, 'mpp_get_compute_domains2D: must first call mpp_domains_init.' ) + + npes_on_tile = mpp_get_tile_npes(domain) + if(size(xbegin(:)) .NE. npes_on_tile) call mpp_error(FATAL, & + "mpp_domains_util.inc(mpp_get_compute_domains2D): size(xbegin) does not equal npes on current tile") + if(size(xend(:)) .NE. npes_on_tile) call mpp_error(FATAL, & + "mpp_domains_util.inc(mpp_get_compute_domains2D): size(xend) does not equal npes on current tile") + if(size(ybegin(:)) .NE. npes_on_tile) call mpp_error(FATAL, & + "mpp_domains_util.inc(mpp_get_compute_domains2D): size(ybegin) does not equal npes on current tile") + if(size(yend(:)) .NE. npes_on_tile) call mpp_error(FATAL, & + "mpp_domains_util.inc(mpp_get_compute_domains2D): size(yend) does not equal npes on current tile") + + tile = domain%tile_id(1) + pos = 0 + do i = 0, size(domain%list(:))-1 + if(tile == domain%list(i)%tile_id(1)) then + pos = pos+1 + xbegin(pos) = domain%list(i)%x(1)%compute%begin + xend (pos) = domain%list(i)%x(1)%compute%end + ishift + ybegin(pos) = domain%list(i)%y(1)%compute%begin + yend (pos) = domain%list(i)%y(1)%compute%end + jshift + endif + enddo + + return + +end subroutine mpp_get_tile_compute_domains + + + !############################################################################# function mpp_get_num_overlap(domain, action, p, position) type(domain2d), intent(in) :: domain @@ -1384,6 +1451,139 @@ end subroutine mpp_get_domain_shift end function get_rank_recv + function get_vector_recv(domain, update_x, update_y, ind_x, ind_y, start_pos, pelist) + type(domain2D), intent(in) :: domain + type(overlapSpec), intent(in) :: update_x, update_y + integer, intent(out) :: ind_x(:), ind_y(:) + integer, intent(out) :: start_pos(:) + integer, intent(out) :: pelist(:) + integer :: nlist, nrecv_x, nrecv_y, ntot, n + integer :: ix, iy, rank_x, rank_y, cur_pos + integer :: get_vector_recv + + nlist = size(domain%list(:)) + nrecv_x = update_x%nrecv + nrecv_y = update_y%nrecv + + ntot = nrecv_x + nrecv_y + + n = 1 + ix = 1 + iy = 1 + ind_x = -1 + ind_y = -1 + get_vector_recv = 0 + cur_pos = 0 + do while (n<=ntot) + if(ix <= nrecv_x ) then + rank_x = update_x%recv(ix)%pe-domain%pe + if(rank_x .LE. 0) rank_x = rank_x + nlist + else + rank_x = -1 + endif + if(iy <= nrecv_y ) then + rank_y = update_y%recv(iy)%pe-domain%pe + if(rank_y .LE. 0) rank_y = rank_y + nlist + else + rank_y = -1 + endif + get_vector_recv = get_vector_recv + 1 + start_pos(get_vector_recv) = cur_pos + if( rank_x == rank_y ) then + n = n+2 + ind_x (get_vector_recv) = ix + ind_y (get_vector_recv) = iy + cur_pos = cur_pos + update_x%recv(ix)%totsize + update_y%recv(iy)%totsize + pelist(get_vector_recv) = update_x%recv(ix)%pe + ix = ix + 1 + iy = iy + 1 + else if ( rank_x > rank_y ) then + n = n+1 + ind_x (get_vector_recv) = ix + ind_y (get_vector_recv) = -1 + cur_pos = cur_pos + update_x%recv(ix)%totsize + pelist(get_vector_recv) = update_x%recv(ix)%pe + ix = ix + 1 + else if ( rank_y > rank_x ) then + n = n+1 + ind_x (get_vector_recv) = -1 + ind_y (get_vector_recv) = iy + cur_pos = cur_pos + update_y%recv(iy)%totsize + pelist(get_vector_recv) = update_y%recv(iy)%pe + iy = iy+1 + endif + end do + + + end function get_vector_recv + + function get_vector_send(domain, update_x, update_y, ind_x, ind_y, start_pos, pelist) + type(domain2D), intent(in) :: domain + type(overlapSpec), intent(in) :: update_x, update_y + integer, intent(out) :: ind_x(:), ind_y(:) + integer, intent(out) :: start_pos(:) + integer, intent(out) :: pelist(:) + integer :: nlist, nsend_x, nsend_y, ntot, n + integer :: ix, iy, rank_x, rank_y, cur_pos + integer :: get_vector_send + + nlist = size(domain%list(:)) + nsend_x = update_x%nsend + nsend_y = update_y%nsend + + ntot = nsend_x + nsend_y + n = 1 + ix = 1 + iy = 1 + ind_x = -1 + ind_y = -1 + get_vector_send = 0 + cur_pos = 0 + do while (n<=ntot) + if(ix <= nsend_x ) then + rank_x = update_x%send(ix)%pe-domain%pe + if(rank_x .LT. 0) rank_x = rank_x + nlist + else + rank_x = nlist+1 + endif + if(iy <= nsend_y ) then + rank_y = update_y%send(iy)%pe-domain%pe + if(rank_y .LT. 0) rank_y = rank_y + nlist + else + rank_y = nlist+1 + endif + get_vector_send = get_vector_send + 1 + start_pos(get_vector_send) = cur_pos + + if( rank_x == rank_y ) then + n = n+2 + ind_x (get_vector_send) = ix + ind_y (get_vector_send) = iy + cur_pos = cur_pos + update_x%send(ix)%totsize + update_y%send(iy)%totsize + pelist (get_vector_send) = update_x%send(ix)%pe + ix = ix + 1 + iy = iy + 1 + else if ( rank_x < rank_y ) then + n = n+1 + ind_x (get_vector_send) = ix + ind_y (get_vector_send) = -1 + cur_pos = cur_pos + update_x%send(ix)%totsize + pelist (get_vector_send) = update_x%send(ix)%pe + ix = ix + 1 + else if ( rank_y < rank_x ) then + n = n+1 + ind_x (get_vector_send) = -1 + ind_y (get_vector_send) = iy + cur_pos = cur_pos + update_y%send(iy)%totsize + pelist (get_vector_send) = update_y%send(iy)%pe + iy = iy+1 + endif + end do + + + end function get_vector_send + + !############################################################################ function get_rank_unpack(domain, overlap_x, overlap_y, rank_x, rank_y, ind_x, ind_y) type(domain2D), intent(in) :: domain diff --git a/src/shared/mpp/include/mpp_get_boundary.h b/src/shared/mpp/include/mpp_get_boundary.h index f3da6e9a26..60be0228d9 100644 --- a/src/shared/mpp/include/mpp_get_boundary.h +++ b/src/shared/mpp/include/mpp_get_boundary.h @@ -13,49 +13,132 @@ subroutine MPP_GET_BOUNDARY_2D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe MPP_TYPE_, allocatable, dimension(:,:) :: ebuffer2D, sbuffer2D, wbuffer2D, nbuffer2D integer :: xcount, ycount - pointer( ptr, field3D ) - ptr = LOC(field) - - !--- We require wbuffer and ebuffer should coexist, sbuffer and nbuffer should coexist. - xcount =0; ycount = 0 - if(present(ebuffer)) xcount = xcount + 1 - if(present(wbuffer)) xcount = xcount + 1 - if(present(sbuffer)) ycount = ycount + 1 - if(present(nbuffer)) ycount = ycount + 1 - if(xcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D: ebuffer and wbuffer should be paired together") - if(ycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D: sbuffer and nbuffer should be paired together") - if(xcount>0) then - allocate(ebuffer2D(size(ebuffer(:)), 1), wbuffer2D(size(wbuffer(:)), 1) ) - ebuffer2D = RESHAPE( ebuffer, SHAPE(ebuffer2D) ) - wbuffer2D = RESHAPE( wbuffer, SHAPE(wbuffer2D) ) - end if - - if(ycount>0) then - allocate(sbuffer2D(size(sbuffer(:)), 1), nbuffer2D(size(nbuffer(:)), 1) ) - sbuffer2D = RESHAPE( sbuffer, SHAPE(sbuffer2D) ) - nbuffer2D = RESHAPE( nbuffer, SHAPE(nbuffer2D) ) - end if - - if(xcount>0 .AND. ycount>0 ) then - call mpp_get_boundary(field3D, domain, ebuffer=ebuffer2D, sbuffer=sbuffer2D, wbuffer=wbuffer2D, nbuffer=nbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - else if(xcount>0) then - call mpp_get_boundary(field3D, domain, ebuffer=ebuffer2D, wbuffer=wbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - else if(ycount>0) then - call mpp_get_boundary(field3D, domain, sbuffer=sbuffer2D, nbuffer=nbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - end if - - if(xcount>0) then - ebuffer = RESHAPE( ebuffer2D, SHAPE(ebuffer) ) - wbuffer = RESHAPE( wbuffer2D, SHAPE(wbuffer) ) - deallocate(ebuffer2D, wbuffer2D) - end if - if(ycount>0) then - sbuffer = RESHAPE( sbuffer2D, SHAPE(sbuffer) ) - nbuffer = RESHAPE( nbuffer2D, SHAPE(nbuffer) ) - deallocate(sbuffer2D, nbuffer2D) + + integer :: ntile + logical :: need_ebuffer, need_sbuffer, need_wbuffer, need_nbuffer + integer(LONG_KIND),dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save :: f_addrs=-9999 + integer(LONG_KIND),dimension(4,MAX_DOMAIN_FIELDS, MAX_TILES),save :: b_addrs=-9999 + integer, save :: bsize(4)=0, isize=0, jsize=0, ksize=0, pos, list=0, l_size=0, upflags + integer :: buffer_size(4) + integer :: max_ntile, tile, update_position, ishift, jshift + logical :: do_update, is_complete, set_mismatch + character(len=3) :: text + MPP_TYPE_ :: d_type + type(overlapSpec), pointer :: bound => NULL() + + ntile = size(domain%x(:)) + + if(present(flags)) then + call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_: flags is a dummy optional argument") + endif + update_position = CENTER + if(present(position)) update_position = position + + !--- check if the buffer are needed + need_ebuffer=.false.; need_sbuffer=.false.; need_wbuffer=.false.; need_nbuffer=.false. + if( domain%symmetry .AND. PRESENT(position) ) then + select case(position) + case(CORNER) + need_ebuffer=.true.; need_sbuffer=.true.; need_wbuffer=.true.; need_nbuffer=.true. + case(NORTH) + need_sbuffer=.true.; need_nbuffer=.true. + case(EAST) + need_ebuffer=.true.; need_wbuffer=.true. + end select + end if + + tile = 1 + max_ntile = domain%max_ntile_pe + is_complete = .true. + if(PRESENT(complete)) then + is_complete = complete + end if + + if(max_ntile>1) then + if(ntile>MAX_TILES) then + write( text,'(i2)' ) MAX_TILES + call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: MAX_TILES='//text//' is less than number of tiles on this pe.' ) + endif + if(.NOT. present(tile_count) ) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D: "// & + "optional argument tile_count should be present when number of tiles on this pe is more than 1") + tile = tile_count + end if + + do_update = (tile == ntile) .AND. is_complete + list = list+1 + if(list > MAX_DOMAIN_FIELDS)then + write( text,'(i2)' ) MAX_DOMAIN_FIELDS + call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: MAX_DOMAIN_FIELDS='//text//' exceeded for group update.' ) + endif + f_addrs(list, tile) = LOC(field) + if(present(ebuffer)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_2D: ebuffer should not be present when north is folded') + if(.not. need_ebuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: ebuffer should not be present') + b_addrs(1, list, tile) = LOC(ebuffer) + buffer_size(1) = size(ebuffer(:)) + else + b_addrs(1, list, tile) = 0 + buffer_size(1) = 1 + end if + if(present(sbuffer)) then + if(.not. need_sbuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: sbuffer should not be present') + b_addrs(2, list, tile) = LOC(sbuffer) + buffer_size(2) = size(sbuffer(:)) + else + b_addrs(2, list, tile) = 0 + buffer_size(2) = 1 + end if + if(present(wbuffer)) then + if(.not. need_wbuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: wbuffer should not be present') + b_addrs(3, list, tile) = LOC(wbuffer) + buffer_size(3) = size(wbuffer(:)) + else + b_addrs(3, list, tile) = 0 + buffer_size(3) = 1 + end if + if(present(nbuffer)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_2D: nbuffer should not be present when north is folded') + if(.not. need_nbuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: nbuffer should be be present') + b_addrs(4, list, tile) = LOC(nbuffer) + buffer_size(4) = size(nbuffer(:)) + else + b_addrs(4, list, tile) = 0 + buffer_size(4) = 1 + end if + + if(list == 1 .AND. tile == 1 )then + isize=size(field,1); jsize=size(field,2); ksize = 1; pos = update_position + bsize = buffer_size + else + set_mismatch = .false. + set_mismatch = set_mismatch .OR. (isize .NE. size(field,1)) + set_mismatch = set_mismatch .OR. (jsize .NE. size(field,2)) + set_mismatch = set_mismatch .OR. ANY( bsize .NE. buffer_size ) + set_mismatch = set_mismatch .OR. (update_position .NE. pos) + if(set_mismatch)then + write( text,'(i2)' ) list + call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D: Incompatible field at count '//text//' for group update.' ) + endif + endif + if(is_complete) then + l_size = list + list = 0 + end if + + if(do_update )then + !--- only non-center data in symmetry domain will be retrieved. + if(position == CENTER .OR. (.NOT. domain%symmetry) ) return + bound => search_bound_overlap(domain, update_position) + call mpp_get_domain_shift(domain, ishift, jshift, update_position) + if(size(field,1) .NE. domain%x(1)%memory%size+ishift .OR. size(field,2) .NE. domain%y(1)%memory%size+jshift ) & + call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D: field is not on memory domain") + if(ASSOCIATED(bound)) then + call mpp_do_get_boundary(f_addrs(1:l_size,1:ntile), domain, bound, b_addrs(:,1:l_size,1:ntile), & + bsize, ksize, d_type) + endif + l_size=0; f_addrs=-9999; bsize=0; b_addrs=-9999; isize=0; jsize=0; ksize=0 end if return @@ -72,7 +155,7 @@ subroutine MPP_GET_BOUNDARY_3D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe integer, intent(in), optional :: flags, position, tile_count logical, intent(in), optional :: complete - integer :: update_flags, ntile + integer :: ntile logical :: need_ebuffer, need_sbuffer, need_wbuffer, need_nbuffer integer(LONG_KIND),dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save :: f_addrs=-9999 integer(LONG_KIND),dimension(4,MAX_DOMAIN_FIELDS, MAX_TILES),save :: b_addrs=-9999 @@ -86,8 +169,9 @@ subroutine MPP_GET_BOUNDARY_3D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe ntile = size(domain%x(:)) - update_flags = XUPDATE+YUPDATE - if(present(flags)) update_flags = flags + if(present(flags)) then + call mpp_error(FATAL, "MPP_GET_BOUNDARY_3D_: flags is a dummy optional argument") + endif update_position = CENTER if(present(position)) update_position = position @@ -102,24 +186,8 @@ subroutine MPP_GET_BOUNDARY_3D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe case(EAST) need_ebuffer=.true.; need_wbuffer=.true. end select - end if - need_ebuffer = need_ebuffer .AND. BTEST(update_flags, EAST) - need_sbuffer = need_sbuffer .AND. BTEST(update_flags, SOUTH) - need_wbuffer = need_wbuffer .AND. BTEST(update_flags, WEST) - need_nbuffer = need_nbuffer .AND. BTEST(update_flags, NORTH) - if(need_ebuffer) then - if(.NOT. PRESENT(ebuffer) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D: optional argument ebuffer should be presented') - end if - if(need_sbuffer) then - if(.NOT. PRESENT(sbuffer) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D: optional argument sbuffer should be presented') - end if - if(need_wbuffer) then - if(.NOT. PRESENT(wbuffer) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D: optional argument wbuffer should be presented') - end if - if(need_nbuffer) then - if(.NOT. PRESENT(nbuffer) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D: optional argument nbuffer should be presented') - end if - + end if + tile = 1 max_ntile = domain%max_ntile_pe is_complete = .true. @@ -144,30 +212,47 @@ subroutine MPP_GET_BOUNDARY_3D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: MAX_DOMAIN_FIELDS='//text//' exceeded for group update.' ) endif f_addrs(list, tile) = LOC(field) - buffer_size = 0 if(present(ebuffer)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_3D: ebuffer should not be present when north is folded') + if(.not. need_ebuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: ebuffer should not be present') b_addrs(1, list, tile) = LOC(ebuffer) buffer_size(1) = size(ebuffer,1) + else + b_addrs(1, list, tile) = 0 + buffer_size(1) = 1 end if - if(present(sbuffer)) then + if(.not. need_sbuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: sbuffer should not be present') b_addrs(2, list, tile) = LOC(sbuffer) buffer_size(2) = size(sbuffer,1) + else + b_addrs(2, list, tile) = 0 + buffer_size(2) = 1 end if - if(present(wbuffer)) then + if(.not. need_wbuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: wbuffer should not be present') b_addrs(3, list, tile) = LOC(wbuffer) buffer_size(3) = size(wbuffer,1) + else + b_addrs(3, list, tile) = 0 + buffer_size(3) = 1 end if - if(present(nbuffer)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_3D: nbuffer should not be present when north is folded') + if(.not. need_nbuffer) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: nbuffer should not be present') b_addrs(4, list, tile) = LOC(nbuffer) buffer_size(4) = size(nbuffer,1) + else + b_addrs(4, list, tile) = 0 + buffer_size(4) = 1 end if + if(list == 1 .AND. tile == 1 )then isize=size(field,1); jsize=size(field,2); ksize = size(field,3); pos = update_position - bsize = buffer_size; upflags = update_flags + bsize = buffer_size else set_mismatch = .false. set_mismatch = set_mismatch .OR. (isize .NE. size(field,1)) @@ -175,7 +260,6 @@ subroutine MPP_GET_BOUNDARY_3D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe set_mismatch = set_mismatch .OR. (ksize .NE. size(field,3)) set_mismatch = set_mismatch .OR. ANY( bsize .NE. buffer_size ) set_mismatch = set_mismatch .OR. (update_position .NE. pos) - set_mismatch = set_mismatch .OR. (upflags .NE. update_flags) if(set_mismatch)then write( text,'(i2)' ) list call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: Incompatible field at count '//text//' for group update.' ) @@ -195,139 +279,13 @@ subroutine MPP_GET_BOUNDARY_3D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffe call mpp_error(FATAL, "MPP_GET_BOUNDARY_3D: field is not on memory domain") if(ASSOCIATED(bound)) then call mpp_do_get_boundary(f_addrs(1:l_size,1:ntile), domain, bound, b_addrs(:,1:l_size,1:ntile), & - bsize, ksize, d_type, update_flags) + bsize, ksize, d_type) endif l_size=0; f_addrs=-9999; bsize=0; b_addrs=-9999; isize=0; jsize=0; ksize=0 end if end subroutine MPP_GET_BOUNDARY_3D_ -!######################################################################################### -subroutine MPP_GET_BOUNDARY_4D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffer, flags, & - position, complete, tile_count) - type(domain2D), intent(in) :: domain - MPP_TYPE_, intent(in) :: field(:,:,:,:) - MPP_TYPE_, intent(inout), optional :: ebuffer(:,:,:), sbuffer(:,:,:), wbuffer(:,:,:), nbuffer(:,:,:) - integer, intent(in), optional :: flags, position, tile_count - logical, intent(in), optional :: complete - - MPP_TYPE_ :: field3D(size(field,1),size(field,2),size(field,3)*size(field,4)) - MPP_TYPE_, allocatable, dimension(:,:) :: ebuffer2D, sbuffer2D, wbuffer2D, nbuffer2D - integer :: xcount, ycount - pointer( ptr, field3D ) - ptr = LOC(field) - - !--- We require wbuffer and ebuffer should coexist, sbuffer and nbuffer should coexist. - xcount = 0; ycount = 0 - if(present(ebuffer)) xcount = xcount + 1 - if(present(wbuffer)) xcount = xcount + 1 - if(present(sbuffer)) ycount = ycount + 1 - if(present(nbuffer)) ycount = ycount + 1 - if(xcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_4D: ebuffer and wbuffer should be paired together") - if(ycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_4D: sbuffer and nbuffer should be paired together") - if(xcount>0) then - allocate(ebuffer2D(size(ebuffer,1), size(ebuffer,2)*size(ebuffer,3)) ) - allocate(ebuffer2D(size(wbuffer,1), size(wbuffer,2)*size(wbuffer,3)) ) - ebuffer2D = RESHAPE( ebuffer, SHAPE(ebuffer2D) ) - wbuffer2D = RESHAPE( wbuffer, SHAPE(wbuffer2D) ) - end if - - if(ycount>0) then - allocate(sbuffer2D(size(sbuffer,1), size(sbuffer,2)*size(sbuffer,3)) ) - allocate(nbuffer2D(size(nbuffer,1), size(nbuffer,2)*size(nbuffer,3)) ) - sbuffer2D = RESHAPE( sbuffer, SHAPE(sbuffer2D) ) - nbuffer2D = RESHAPE( nbuffer, SHAPE(nbuffer2D) ) - end if - - if(xcount>0 .AND. ycount>0 ) then - call mpp_get_boundary(field3D, domain, ebuffer=ebuffer2D, sbuffer=sbuffer2D, wbuffer=wbuffer2D, nbuffer=nbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - else if(xcount>0) then - call mpp_get_boundary(field3D, domain, ebuffer=ebuffer2D, wbuffer=wbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - else if(ycount>0) then - call mpp_get_boundary(field3D, domain, sbuffer=sbuffer2D, nbuffer=nbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - end if - - if(xcount>0) then - ebuffer = RESHAPE( ebuffer2D, SHAPE(ebuffer) ) - wbuffer = RESHAPE( wbuffer2D, SHAPE(wbuffer) ) - deallocate(ebuffer2D, wbuffer2D) - end if - if(ycount>0) then - sbuffer = RESHAPE( sbuffer2D, SHAPE(sbuffer) ) - nbuffer = RESHAPE( nbuffer2D, SHAPE(nbuffer) ) - deallocate(sbuffer2D, nbuffer2D) - end if - - return - -end subroutine MPP_GET_BOUNDARY_4D_ - -!############################################################################### -subroutine MPP_GET_BOUNDARY_5D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffer, flags, & - position, complete, tile_count) - type(domain2D), intent(in) :: domain - MPP_TYPE_, intent(in) :: field(:,:,:,:,:) - MPP_TYPE_, intent(inout), optional :: ebuffer(:,:,:,:), sbuffer(:,:,:,:), wbuffer(:,:,:,:), nbuffer(:,:,:,:) - integer, intent(in), optional :: flags, position, tile_count - logical, intent(in), optional :: complete - - MPP_TYPE_ :: field3D(size(field,1),size(field,2),size(field,3)*size(field,4)*size(field,5)) - MPP_TYPE_, allocatable, dimension(:,:) :: ebuffer2D, sbuffer2D, wbuffer2D, nbuffer2D - integer :: xcount, ycount - pointer( ptr, field3D ) - ptr = LOC(field) - - !--- We require wbuffer and ebuffer should coexist, sbuffer and nbuffer should coexist. - xcount = 0; ycount = 0 - if(present(ebuffer)) xcount = xcount + 1 - if(present(wbuffer)) xcount = xcount + 1 - if(present(sbuffer)) ycount = ycount + 1 - if(present(nbuffer)) ycount = ycount + 1 - if(xcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_5D: ebuffer and wbuffer should be paired together") - if(ycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_5D: sbuffer and nbuffer should be paired together") - if(xcount>0) then - allocate(ebuffer2D(size(ebuffer,1), size(ebuffer,2)*size(ebuffer,3)*size(ebuffer,4)) ) - allocate(ebuffer2D(size(wbuffer,1), size(wbuffer,2)*size(wbuffer,3)*size(wbuffer,4)) ) - ebuffer2D = RESHAPE( ebuffer, SHAPE(ebuffer2D) ) - wbuffer2D = RESHAPE( wbuffer, SHAPE(wbuffer2D) ) - end if - - if(ycount>0) then - allocate(sbuffer2D(size(sbuffer,1), size(sbuffer,2)*size(sbuffer,3)*size(sbuffer,4)) ) - allocate(nbuffer2D(size(nbuffer,1), size(nbuffer,2)*size(nbuffer,3)*size(nbuffer,4)) ) - sbuffer2D = RESHAPE( sbuffer, SHAPE(sbuffer2D) ) - nbuffer2D = RESHAPE( nbuffer, SHAPE(nbuffer2D) ) - end if - - if(xcount>0 .AND. ycount>0 ) then - call mpp_get_boundary(field3D, domain, ebuffer=ebuffer2D, sbuffer=sbuffer2D, wbuffer=wbuffer2D, nbuffer=nbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - else if(xcount>0) then - call mpp_get_boundary(field3D, domain, ebuffer=ebuffer2D, wbuffer=wbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - else if(ycount>0) then - call mpp_get_boundary(field3D, domain, sbuffer=sbuffer2D, nbuffer=nbuffer2D, & - flags=flags, position=position, complete=complete, tile_count=tile_count) - end if - - if(xcount>0) then - ebuffer = RESHAPE( ebuffer2D, SHAPE(ebuffer) ) - wbuffer = RESHAPE( wbuffer2D, SHAPE(wbuffer) ) - deallocate(ebuffer2D, wbuffer2D) - end if - if(ycount>0) then - sbuffer = RESHAPE( sbuffer2D, SHAPE(sbuffer) ) - nbuffer = RESHAPE( nbuffer2D, SHAPE(nbuffer) ) - deallocate(sbuffer2D, nbuffer2D) - end if - - return - -end subroutine MPP_GET_BOUNDARY_5D_ - !#################################################################### ! vector update @@ -341,97 +299,211 @@ subroutine MPP_GET_BOUNDARY_2D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wb integer, intent(in), optional :: flags, gridtype, tile_count logical, intent(in), optional :: complete - MPP_TYPE_ :: field3Dx(size(fieldx,1),size(fieldx,2),1) - MPP_TYPE_ :: field3Dy(size(fieldy,1),size(fieldy,2),1) - - MPP_TYPE_, allocatable, dimension(:,:) :: ebufferx2D, sbufferx2D, wbufferx2D, nbufferx2D - MPP_TYPE_, allocatable, dimension(:,:) :: ebuffery2D, sbuffery2D, wbuffery2D, nbuffery2D - integer :: xxcount, xycount, yycount, yxcount - - pointer( ptrx, field3Dx ) - pointer( ptry, field3Dy ) - ptrx = LOC(fieldx) - ptry = LOC(fieldy) - - !--- We require wbuffex and ebufferx should coexist, sbufferx and nbufferx should coexist. - !--- wbuffey and ebuffery should coexist, sbuffery and nbuffery should coexist. - xxcount = 0; xycount = 0; yxcount = 0; yycount = 0 - if(present(ebufferx)) xxcount = xxcount + 1 - if(present(wbufferx)) xxcount = xxcount + 1 - if(present(ebuffery)) xycount = xycount + 1 - if(present(wbuffery)) xycount = xycount + 1 - if(present(sbufferx)) yxcount = yxcount + 1 - if(present(nbufferx)) yxcount = yxcount + 1 - if(present(sbuffery)) yycount = yycount + 1 - if(present(nbuffery)) yycount = yycount + 1 - - if(xxcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: ebufferx and wbufferx should be paired together") - if(xycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: ebuffery and wbuffery should be paired together") - if(yxcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: sbufferx and nbufferx should be paired together") - if(yycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: sbuffery and nbuffery should be paired together") - - if(xxcount>0) then - allocate(ebufferx2D(size(ebufferx(:)), 1), wbufferx2D(size(wbufferx(:)), 1) ) - ebufferx2D = RESHAPE( ebufferx, SHAPE(ebufferx2D) ) - wbufferx2D = RESHAPE( wbufferx, SHAPE(wbufferx2D) ) - end if - - if(xycount>0) then - allocate(ebuffery2D(size(ebuffery(:)), 1), wbuffery2D(size(wbuffery(:)), 1) ) - ebuffery2D = RESHAPE( ebuffery, SHAPE(ebuffery2D) ) - wbuffery2D = RESHAPE( wbuffery, SHAPE(wbuffery2D) ) - end if - - if(yxcount>0) then - allocate(sbufferx2D(size(sbufferx(:)), 1), nbufferx2D(size(nbufferx(:)), 1) ) - sbufferx2D = RESHAPE( sbufferx, SHAPE(sbufferx2D) ) - nbufferx2D = RESHAPE( nbufferx, SHAPE(nbufferx2D) ) - end if - - if(yycount>0) then - allocate(sbuffery2D(size(sbuffery(:)), 1), nbuffery2D(size(nbuffery(:)), 1) ) - sbuffery2D = RESHAPE( sbuffery, SHAPE(sbuffery2D) ) - nbuffery2D = RESHAPE( nbuffery, SHAPE(nbuffery2D) ) - end if - - !--- We are assuming flags will be always XUPDATE+YUPDATE, so there are three possible - if( xxcount>0 .AND. xycount>0 .AND. yxcount>0 .AND. yycount>0 ) then ! BGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, ebufferx=ebufferx2D, sbufferx=sbufferx2D, & - wbufferx=wbufferx2D, nbufferx=nbufferx2D, ebuffery=ebuffery2D, sbuffery=sbuffery2D, & - wbuffery=wbuffery2D, nbuffery=nbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - else if( xxcount>0 .AND. yycount>0 ) then ! CGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, ebufferx=ebufferx2D, wbufferx=wbufferx2D, & - sbuffery=sbuffery2D, nbuffery=nbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - else if( xycount>0 .AND. yxcount>0 ) then ! DGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, sbufferx=sbufferx2D, nbufferx=nbufferx2D, & - ebuffery=ebuffery2D, wbuffery=wbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - end if - - if(xxcount>0) then - ebufferx = RESHAPE( ebufferx2D, SHAPE(ebufferx) ) - wbufferx = RESHAPE( wbufferx2D, SHAPE(wbufferx) ) - deallocate(ebufferx2D, wbufferx2D) - end if - if(xycount>0) then - ebuffery = RESHAPE( ebuffery2D, SHAPE(ebuffery) ) - wbuffery = RESHAPE( wbuffery2D, SHAPE(wbuffery) ) - deallocate(ebuffery2D, wbuffery2D) - end if - - if(yxcount>0) then - sbufferx = RESHAPE( sbufferx2D, SHAPE(sbufferx) ) - nbufferx = RESHAPE( nbufferx2D, SHAPE(nbufferx) ) - deallocate(sbufferx2D, nbufferx2D) - end if - if(yycount>0) then - sbuffery = RESHAPE( sbuffery2D, SHAPE(sbuffery) ) - nbuffery = RESHAPE( nbuffery2D, SHAPE(nbuffery) ) - deallocate(sbuffery2D, nbuffery2D) + integer :: ntile, update_flags + logical :: need_ebufferx, need_sbufferx, need_wbufferx, need_nbufferx + logical :: need_ebuffery, need_sbuffery, need_wbuffery, need_nbuffery + + integer(LONG_KIND),dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save :: f_addrsx=-9999 + integer(LONG_KIND),dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save :: f_addrsy=-9999 + integer(LONG_KIND),dimension(4,MAX_DOMAIN_FIELDS, MAX_TILES),save :: b_addrsx=-9999 + integer(LONG_KIND),dimension(4,MAX_DOMAIN_FIELDS, MAX_TILES),save :: b_addrsy=-9999 + integer, save :: bsizex(4)=0, bsizey(4)=0, isize(2)=0, jsize(2)=0, ksize=0, l_size=0, list=0 + integer, save :: offset_type, upflags + integer :: bufferx_size(4), buffery_size(4) + integer :: max_ntile, tile, grid_offset_type + logical :: do_update, is_complete, set_mismatch + character(len=3) :: text + MPP_TYPE_ :: d_type + type(overlapSpec), pointer :: boundx=>NULL() + type(overlapSpec), pointer :: boundy=>NULL() + integer :: position_x, position_y, ishift, jshift + + ntile = size(domain%x(:)) + update_flags = 0 + if( PRESENT(flags) ) then + update_flags = flags end if + !--- check if the suitable buffer are present + need_ebufferx=.FALSE.; need_sbufferx=.FALSE. + need_wbufferx=.FALSE.; need_nbufferx=.FALSE. + need_ebuffery=.FALSE.; need_sbuffery=.FALSE. + need_wbuffery=.FALSE.; need_nbuffery=.FALSE. + if( domain%symmetry .AND. PRESENT(gridtype) ) then + select case(gridtype) + case(BGRID_NE, BGRID_SW) + need_ebufferx=.true.; need_sbufferx=.true.; need_wbufferx=.true.; need_nbufferx=.true. + need_ebuffery=.true.; need_sbuffery=.true.; need_wbuffery=.true.; need_nbuffery=.true. + case(CGRID_NE, CGRID_SW) + need_ebufferx=.true.; need_wbufferx=.true.; need_sbuffery=.true.; need_nbuffery=.true. + case(DGRID_NE, DGRID_SW) + need_ebuffery=.true.; need_wbuffery=.true.; need_sbufferx=.true.; need_nbufferx=.true. + end select + end if + + tile = 1 + max_ntile = domain%max_ntile_pe + is_complete = .true. + if(PRESENT(complete)) then + is_complete = complete + end if + + if(max_ntile>1) then + if(ntile>MAX_TILES) then + write( text,'(i2)' ) MAX_TILES + call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: MAX_TILES='//text//' is less than number of tiles on this pe.' ) + endif + if(.NOT. present(tile_count) ) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: "// & + "optional argument tile_count should be present when number of tiles on this pe is more than 1") + tile = tile_count + end if + + do_update = (tile == ntile) .AND. is_complete + list = list+1 + if(list > MAX_DOMAIN_FIELDS)then + write( text,'(i2)' ) MAX_DOMAIN_FIELDS + call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: MAX_DOMAIN_FIELDS='//text//' exceeded for group update.' ) + endif + f_addrsx(list, tile) = LOC(fieldx) + f_addrsy(list, tile) = LOC(fieldy) + + if(present(ebufferx)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_2D_V: ebufferx should not be present when north is folded') + if(.not. need_ebufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: ebufferx should not be present') + b_addrsx(1, list, tile) = LOC(ebufferx) + bufferx_size(1) = size(ebufferx,1) + else + b_addrsx(1, list, tile) = 0 + bufferx_size(1) = 1 + end if + if(present(sbufferx)) then + if(.not. need_sbufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: sbufferx should not be present') + b_addrsx(2, list, tile) = LOC(sbufferx) + bufferx_size(2) = size(sbufferx,1) + else + b_addrsx(2, list, tile) = 0 + bufferx_size(2) = 1 + end if + if(present(wbufferx)) then + if(.not. need_wbufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: wbufferx should not be present') + b_addrsx(3, list, tile) = LOC(wbufferx) + bufferx_size(3) = size(wbufferx,1) + else + b_addrsx(3, list, tile) = 0 + bufferx_size(3) = 1 + end if + if(present(nbufferx)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_2D_V: nbufferx should not be present when north is folded') + if(.not. need_nbufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: nbufferx should not be present') + b_addrsx(4, list, tile) = LOC(nbufferx) + bufferx_size(4) = size(nbufferx,1) + else + b_addrsx(4, list, tile) = 0 + bufferx_size(4) = 1 + end if + + if(present(ebuffery)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_2D_V: ebuffery should not be present when north is folded') + if(.not. need_ebuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: ebuffery should not be present') + b_addrsy(1, list, tile) = LOC(ebuffery) + buffery_size(1) = size(ebuffery,1) + else + b_addrsy(1, list, tile) = 0 + buffery_size(1) = 1 + end if + if(present(sbuffery)) then + if(.not. need_sbuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: sbuffery should not be present') + b_addrsy(2, list, tile) = LOC(sbuffery) + buffery_size(2) = size(sbuffery,1) + else + b_addrsy(2, list, tile) = 0 + buffery_size(2) = 1 + end if + if(present(wbuffery)) then + if(.not. need_wbuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: wbuffery should not be present') + b_addrsy(3, list, tile) = LOC(wbuffery) + buffery_size(3) = size(wbuffery,1) + else + b_addrsy(3, list, tile) = 0 + buffery_size(3) = 1 + end if + if(present(nbuffery)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_2D_V: nbuffery should not be present when north is folded') + if(.not. need_nbuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_2D_V: nbuffery should not be present') + b_addrsy(4, list, tile) = LOC(nbuffery) + buffery_size(4) = size(nbuffery,1) + else + b_addrsy(4, list, tile) = 0 + buffery_size(4) = 1 + end if + + grid_offset_type = AGRID + if(present(gridtype)) grid_offset_type = gridtype + if(list == 1 .AND. tile == 1 )then + isize(1)=size(fieldx,1); jsize(1)=size(fieldx,2); isize(2)=size(fieldy,1); jsize(2)=size(fieldy,2) + ksize = 1; offset_type = grid_offset_type + bsizex = bufferx_size; bsizey = buffery_size; upflags = update_flags + else + set_mismatch = .false. + set_mismatch = set_mismatch .OR. (isize(1) .NE. size(fieldx,1)) + set_mismatch = set_mismatch .OR. (jsize(1) .NE. size(fieldx,2)) + set_mismatch = set_mismatch .OR. (isize(2) .NE. size(fieldy,1)) + set_mismatch = set_mismatch .OR. (jsize(2) .NE. size(fieldy,2)) + set_mismatch = set_mismatch .OR. ANY( bsizex .NE. bufferx_size ) + set_mismatch = set_mismatch .OR. ANY( bsizey .NE. buffery_size ) + set_mismatch = set_mismatch .OR. (offset_type .NE. grid_offset_type) + set_mismatch = set_mismatch .OR. (upflags .NE. update_flags) + if(set_mismatch)then + write( text,'(i2)' ) list + call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: Incompatible field at count '//text//' for group update.' ) + endif + endif + if(is_complete) then + l_size = list + list = 0 + end if + + if(do_update )then + select case(grid_offset_type) + case (AGRID) + position_x = CENTER + position_y = CENTER + case (BGRID_NE, BGRID_SW) + position_x = CORNER + position_y = CORNER + case (CGRID_NE, CGRID_SW) + position_x = EAST + position_y = NORTH + case (DGRID_NE, DGRID_SW) + position_x = NORTH + position_y = EAST + case default + call mpp_error(FATAL, "mpp_get_boundary.h: invalid value of grid_offset_type") + end select + + boundx => search_bound_overlap(domain, position_x) + boundy => search_bound_overlap(domain, position_y) + + call mpp_get_domain_shift(domain, ishift, jshift, position_x) + if(size(fieldx,1) .NE. domain%x(1)%memory%size+ishift .OR. size(fieldx,2) .NE. domain%y(1)%memory%size+jshift ) & + call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: fieldx is not on memory domain") + call mpp_get_domain_shift(domain, ishift, jshift, position_y) + if(size(fieldy,1) .NE. domain%x(1)%memory%size+ishift .OR. size(fieldy,2) .NE. domain%y(1)%memory%size+jshift ) & + call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: fieldy is not on memory domain") + if(ASSOCIATED(boundx) ) then + call mpp_do_get_boundary(f_addrsx(1:l_size,1:ntile), f_addrsy(1:l_size,1:ntile), domain, boundx, boundy, & + b_addrsx(:,1:l_size,1:ntile), b_addrsy(:,1:l_size,1:ntile), bsizex, & + bsizey, ksize, d_type, update_flags) + endif + l_size=0; f_addrsx=-9999; f_addrsy=-9999; bsizex=0; bsizey=0; + b_addrsx=-9999; b_addrsy=-9999; isize=0; jsize=0; ksize=0 + end if + + return end subroutine MPP_GET_BOUNDARY_2D_V_ @@ -469,16 +541,9 @@ subroutine MPP_GET_BOUNDARY_3D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wb integer :: position_x, position_y, ishift, jshift ntile = size(domain%x(:)) - update_flags = XUPDATE+YUPDATE !default + update_flags = 0 if( PRESENT(flags) ) then update_flags = flags - ! The following test is so that SCALAR_PAIR can be used alone with the - ! same default update pattern as without. - if (BTEST(update_flags,SCALAR_BIT)) then - if (.NOT.(BTEST(update_flags,WEST) .OR. BTEST(update_flags,EAST) & - .OR. BTEST(update_flags,NORTH) .OR. BTEST(update_flags,SOUTH))) & - update_flags = update_flags + XUPDATE+YUPDATE !default with SCALAR_PAIR - end if end if !--- check if the suitable buffer are present @@ -498,39 +563,6 @@ subroutine MPP_GET_BOUNDARY_3D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wb end select end if - need_ebufferx = need_ebufferx .AND. BTEST(update_flags, EAST) - need_sbufferx = need_sbufferx .AND. BTEST(update_flags, SOUTH) - need_wbufferx = need_wbufferx .AND. BTEST(update_flags, WEST) - need_nbufferx = need_nbufferx .AND. BTEST(update_flags, NORTH) - need_ebuffery = need_ebuffery .AND. BTEST(update_flags, EAST) - need_sbuffery = need_sbuffery .AND. BTEST(update_flags, SOUTH) - need_wbuffery = need_wbuffery .AND. BTEST(update_flags, WEST) - need_nbuffery = need_nbuffery .AND. BTEST(update_flags, NORTH) - if(need_ebufferx) then - if(.NOT. PRESENT(ebufferx) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument ebufferx should be presented') - end if - if(need_sbufferx) then - if(.NOT. PRESENT(sbufferx) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument sbufferx should be presented') - end if - if(need_wbufferx) then - if(.NOT. PRESENT(wbufferx) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument wbufferx should be presented') - end if - if(need_nbufferx) then - if(.NOT. PRESENT(nbufferx) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument nbufferx should be presented') - end if - if(need_ebuffery) then - if(.NOT. PRESENT(ebuffery) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument ebuffery should be presented') - end if - if(need_sbuffery) then - if(.NOT. PRESENT(sbuffery) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument sbuffery should be presented') - end if - if(need_wbuffery) then - if(.NOT. PRESENT(wbuffery) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument wbuffery should be presented') - end if - if(need_nbuffery) then - if(.NOT. PRESENT(nbuffery) ) call mpp_error( FATAL,'MPP_GET_BOUNDARY_3D_V: optional argument nbuffery should be presented') - end if - tile = 1 max_ntile = domain%max_ntile_pe is_complete = .true. @@ -541,9 +573,9 @@ subroutine MPP_GET_BOUNDARY_3D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wb if(max_ntile>1) then if(ntile>MAX_TILES) then write( text,'(i2)' ) MAX_TILES - call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: MAX_TILES='//text//' is less than number of tiles on this pe.' ) + call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: MAX_TILES='//text//' is less than number of tiles on this pe.' ) endif - if(.NOT. present(tile_count) ) call mpp_error(FATAL, "MPP_GET_BOUNDARY_3D: "// & + if(.NOT. present(tile_count) ) call mpp_error(FATAL, "MPP_GET_BOUNDARY_3D_V: "// & "optional argument tile_count should be present when number of tiles on this pe is more than 1") tile = tile_count end if @@ -552,50 +584,83 @@ subroutine MPP_GET_BOUNDARY_3D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wb list = list+1 if(list > MAX_DOMAIN_FIELDS)then write( text,'(i2)' ) MAX_DOMAIN_FIELDS - call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D: MAX_DOMAIN_FIELDS='//text//' exceeded for group update.' ) + call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: MAX_DOMAIN_FIELDS='//text//' exceeded for group update.' ) endif f_addrsx(list, tile) = LOC(fieldx) f_addrsy(list, tile) = LOC(fieldy) - bufferx_size = 0; buffery_size = 0 if(present(ebufferx)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_3D_V: ebufferx should not be present when north is folded') + if(.not. need_ebufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: ebufferx should not be present') b_addrsx(1, list, tile) = LOC(ebufferx) bufferx_size(1) = size(ebufferx,1) + else + b_addrsx(1, list, tile) = 0 + bufferx_size(1) = 1 end if - if(present(sbufferx)) then + if(.not. need_sbufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: sbufferx should not be present') b_addrsx(2, list, tile) = LOC(sbufferx) bufferx_size(2) = size(sbufferx,1) + else + b_addrsx(2, list, tile) = 0 + bufferx_size(2) = 1 end if - if(present(wbufferx)) then + if(.not. need_wbufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: wbufferx should not be present') b_addrsx(3, list, tile) = LOC(wbufferx) bufferx_size(3) = size(wbufferx,1) + else + b_addrsx(3, list, tile) = 0 + bufferx_size(3) = 1 end if - if(present(nbufferx)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_3D_V: nbufferx should not be present when north is folded') + if(.not. need_nbufferx) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: nbufferx should not be present') b_addrsx(4, list, tile) = LOC(nbufferx) bufferx_size(4) = size(nbufferx,1) + else + b_addrsx(4, list, tile) = 0 + bufferx_size(4) = 1 end if if(present(ebuffery)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_3D_V: ebuffery should not be present when north is folded') + if(.not. need_ebuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: ebuffery should not be present') b_addrsy(1, list, tile) = LOC(ebuffery) buffery_size(1) = size(ebuffery,1) + else + b_addrsy(1, list, tile) = 0 + buffery_size(1) = 1 end if - if(present(sbuffery)) then + if(.not. need_sbuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: sbuffery should not be present') b_addrsy(2, list, tile) = LOC(sbuffery) buffery_size(2) = size(sbuffery,1) + else + b_addrsy(2, list, tile) = 0 + buffery_size(2) = 1 end if - if(present(wbuffery)) then + if(.not. need_wbuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: wbuffery should not be present') b_addrsy(3, list, tile) = LOC(wbuffery) buffery_size(3) = size(wbuffery,1) + else + b_addrsy(3, list, tile) = 0 + buffery_size(3) = 1 end if - if(present(nbuffery)) then + if(BTEST(domain%fold,NORTH)) call mpp_error(FATAL, & + 'MPP_GET_BOUNDARY_3D_V: nbuffery should not be present when north is folded') + if(.not. need_nbuffery) call mpp_error(FATAL,'MPP_GET_BOUNDARY_3D_V: nbuffery should not be present') b_addrsy(4, list, tile) = LOC(nbuffery) buffery_size(4) = size(nbuffery,1) + else + b_addrsy(4, list, tile) = 0 + buffery_size(4) = 1 end if grid_offset_type = AGRID @@ -664,218 +729,3 @@ subroutine MPP_GET_BOUNDARY_3D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wb end subroutine MPP_GET_BOUNDARY_3D_V_ -!########################################################################## -subroutine MPP_GET_BOUNDARY_4D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wbufferx, nbufferx, & - ebuffery, sbuffery, wbuffery, nbuffery, flags, gridtype, complete, tile_count) - type(domain2D), intent(in) :: domain - MPP_TYPE_, intent(in) :: fieldx(:,:,:,:), fieldy(:,:,:,:) - MPP_TYPE_, intent(inout), optional :: ebufferx(:,:,:), sbufferx(:,:,:), wbufferx(:,:,:), nbufferx(:,:,:) - MPP_TYPE_, intent(inout), optional :: ebuffery(:,:,:), sbuffery(:,:,:), wbuffery(:,:,:), nbuffery(:,:,:) - integer, intent(in), optional :: flags, gridtype, tile_count - logical, intent(in), optional :: complete - - MPP_TYPE_ :: field3Dx(size(fieldx,1),size(fieldx,2),size(fieldx,3)*size(fieldx,4)) - MPP_TYPE_ :: field3Dy(size(fieldy,1),size(fieldy,2),size(fieldy,3)*size(fieldy,4)) - MPP_TYPE_, allocatable, dimension(:,:) :: ebufferx2D, sbufferx2D, wbufferx2D, nbufferx2D - MPP_TYPE_, allocatable, dimension(:,:) :: ebuffery2D, sbuffery2D, wbuffery2D, nbuffery2D - integer :: xxcount, xycount, yycount, yxcount - - pointer( ptrx, field3Dx ) - pointer( ptry, field3Dy ) - ptrx = LOC(fieldx) - ptry = LOC(fieldy) - - !--- We require wbuffex and ebufferx should coexist, sbufferx and nbufferx should coexist. - !--- wbuffey and ebuffery should coexist, sbuffery and nbuffery should coexist. - xxcount = 0; xycount = 0; yxcount = 0; yycount = 0 - if(present(ebufferx)) xxcount = xxcount + 1 - if(present(wbufferx)) xxcount = xxcount + 1 - if(present(ebuffery)) xycount = xycount + 1 - if(present(wbuffery)) xycount = xycount + 1 - if(present(sbufferx)) yxcount = yxcount + 1 - if(present(nbufferx)) yxcount = yxcount + 1 - if(present(sbuffery)) yycount = yycount + 1 - if(present(nbuffery)) yycount = yycount + 1 - - if(xxcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: ebufferx and wbufferx should be paired together") - if(xycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: ebuffery and wbuffery should be paired together") - if(yxcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: sbufferx and nbufferx should be paired together") - if(yycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: sbuffery and nbuffery should be paired together") - - if(xxcount>0) then - allocate(ebufferx2D(size(ebufferx,1), size(ebufferx,2)*size(ebufferx,3))) - allocate(wbufferx2D(size(wbufferx,1), size(wbufferx,2)*size(wbufferx,3))) - ebufferx2D = RESHAPE( ebufferx, SHAPE(ebufferx2D) ) - wbufferx2D = RESHAPE( wbufferx, SHAPE(wbufferx2D) ) - end if - - if(xycount>0) then - allocate(ebuffery2D(size(ebuffery,1), size(ebuffery,2)*size(ebuffery,3))) - allocate(wbuffery2D(size(wbuffery,1), size(wbuffery,2)*size(wbuffery,3))) - ebuffery2D = RESHAPE( ebuffery, SHAPE(ebuffery2D) ) - wbuffery2D = RESHAPE( wbuffery, SHAPE(wbuffery2D) ) - end if - - if(yxcount>0) then - allocate(sbufferx2D(size(sbufferx,1), size(sbufferx,2)*size(sbufferx,3))) - allocate(nbufferx2D(size(nbufferx,1), size(nbufferx,2)*size(nbufferx,3))) - sbufferx2D = RESHAPE( sbufferx, SHAPE(sbufferx2D) ) - nbufferx2D = RESHAPE( nbufferx, SHAPE(nbufferx2D) ) - end if - - if(yycount>0) then - allocate(sbuffery2D(size(sbuffery,1), size(sbuffery,2)*size(sbuffery,3))) - allocate(nbuffery2D(size(nbuffery,1), size(nbuffery,2)*size(nbuffery,3))) - sbuffery2D = RESHAPE( sbuffery, SHAPE(sbuffery2D) ) - nbuffery2D = RESHAPE( nbuffery, SHAPE(nbuffery2D) ) - end if - - !--- We are assuming flags will be always XUPDATE+YUPDATE, so there are three possible - if( xxcount>0 .AND. xycount>0 .AND. yxcount>0 .AND. yycount>0 ) then ! BGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, ebufferx=ebufferx2D, sbufferx=sbufferx2D, & - wbufferx=wbufferx2D, nbufferx=nbufferx2D, ebuffery=ebuffery2D, sbuffery=sbuffery2D, & - wbuffery=wbuffery2D, nbuffery=nbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - else if( xxcount>0 .AND. yycount>0 ) then ! CGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, ebufferx=ebufferx2D, wbufferx=wbufferx2D, & - sbuffery=sbuffery2D, nbuffery=nbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - else if( xycount>0 .AND. yxcount>0 ) then ! DGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, sbufferx=sbufferx2D, nbufferx=nbufferx2D, & - ebuffery=ebuffery2D, wbuffery=wbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - end if - - if(xxcount>0) then - ebufferx = RESHAPE( ebufferx2D, SHAPE(ebufferx) ) - wbufferx = RESHAPE( wbufferx2D, SHAPE(wbufferx) ) - deallocate(ebufferx2D, wbufferx2D) - end if - if(xycount>0) then - ebuffery = RESHAPE( ebuffery2D, SHAPE(ebuffery) ) - wbuffery = RESHAPE( wbuffery2D, SHAPE(wbuffery) ) - deallocate(ebuffery2D, wbuffery2D) - end if - - if(yxcount>0) then - sbufferx = RESHAPE( sbufferx2D, SHAPE(sbufferx) ) - nbufferx = RESHAPE( nbufferx2D, SHAPE(nbufferx) ) - deallocate(sbufferx2D, nbufferx2D) - end if - if(yycount>0) then - sbuffery = RESHAPE( sbuffery2D, SHAPE(sbuffery) ) - nbuffery = RESHAPE( nbuffery2D, SHAPE(nbuffery) ) - deallocate(sbufferx2D, nbuffery2D) - end if - - return - -end subroutine MPP_GET_BOUNDARY_4D_V_ - -!############################################################################### -subroutine MPP_GET_BOUNDARY_5D_V_(fieldx, fieldy, domain, ebufferx, sbufferx, wbufferx, nbufferx, & - ebuffery, sbuffery, wbuffery, nbuffery, flags, gridtype, complete, tile_count) - type(domain2D), intent(in) :: domain - MPP_TYPE_, intent(in) :: fieldx(:,:,:,:,:), fieldy(:,:,:,:,:) - MPP_TYPE_, intent(inout), optional :: ebufferx(:,:,:,:), sbufferx(:,:,:,:), wbufferx(:,:,:,:), nbufferx(:,:,:,:) - MPP_TYPE_, intent(inout), optional :: ebuffery(:,:,:,:), sbuffery(:,:,:,:), wbuffery(:,:,:,:), nbuffery(:,:,:,:) - integer, intent(in), optional :: flags, gridtype, tile_count - logical, intent(in), optional :: complete - - MPP_TYPE_ :: field3Dx(size(fieldx,1),size(fieldx,2),size(fieldx,3)*size(fieldx,4)*size(fieldx,5)) - MPP_TYPE_ :: field3Dy(size(fieldy,1),size(fieldy,2),size(fieldy,3)*size(fieldy,4)*size(fieldy,5)) - MPP_TYPE_, allocatable, dimension(:,:) :: ebufferx2D, sbufferx2D, wbufferx2D, nbufferx2D - MPP_TYPE_, allocatable, dimension(:,:) :: ebuffery2D, sbuffery2D, wbuffery2D, nbuffery2D - integer :: xxcount, xycount, yycount, yxcount - - pointer( ptrx, field3Dx ) - pointer( ptry, field3Dy ) - ptrx = LOC(fieldx) - ptry = LOC(fieldy) - - !--- We require wbuffex and ebufferx should coexist, sbufferx and nbufferx should coexist. - !--- wbuffey and ebuffery should coexist, sbuffery and nbuffery should coexist. - xxcount = 0; xycount = 0; yxcount = 0; yycount = 0 - if(present(ebufferx)) xxcount = xxcount + 1 - if(present(wbufferx)) xxcount = xxcount + 1 - if(present(ebuffery)) xycount = xycount + 1 - if(present(wbuffery)) xycount = xycount + 1 - if(present(sbufferx)) yxcount = yxcount + 1 - if(present(nbufferx)) yxcount = yxcount + 1 - if(present(sbuffery)) yycount = yycount + 1 - if(present(nbuffery)) yycount = yycount + 1 - - if(xxcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: ebufferx and wbufferx should be paired together") - if(xycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: ebuffery and wbuffery should be paired together") - if(yxcount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: sbufferx and nbufferx should be paired together") - if(yycount==1) call mpp_error(FATAL, "MPP_GET_BOUNDARY_2D_V: sbuffery and nbuffery should be paired together") - - if(xxcount>0) then - allocate(ebufferx2D(size(ebufferx,1), size(ebufferx,2)*size(ebufferx,3)*size(ebufferx,4))) - allocate(wbufferx2D(size(wbufferx,1), size(wbufferx,2)*size(wbufferx,3)*size(wbufferx,4))) - ebufferx2D = RESHAPE( ebufferx, SHAPE(ebufferx2D) ) - wbufferx2D = RESHAPE( wbufferx, SHAPE(wbufferx2D) ) - end if - - if(xycount>0) then - allocate(ebuffery2D(size(ebuffery,1), size(ebuffery,2)*size(ebuffery,3)*size(ebuffery,4))) - allocate(wbuffery2D(size(wbuffery,1), size(wbuffery,2)*size(wbuffery,3)*size(wbuffery,4))) - ebuffery2D = RESHAPE( ebuffery, SHAPE(ebuffery2D) ) - wbuffery2D = RESHAPE( wbuffery, SHAPE(wbuffery2D) ) - end if - - if(yxcount>0) then - allocate(sbufferx2D(size(sbufferx,1), size(sbufferx,2)*size(sbufferx,3)*size(sbufferx,4))) - allocate(nbufferx2D(size(nbufferx,1), size(nbufferx,2)*size(nbufferx,3)*size(nbufferx,4))) - sbufferx2D = RESHAPE( sbufferx, SHAPE(sbufferx2D) ) - nbufferx2D = RESHAPE( nbufferx, SHAPE(nbufferx2D) ) - end if - - if(yycount>0) then - allocate(sbuffery2D(size(sbuffery,1), size(sbuffery,2)*size(sbuffery,3)*size(sbuffery,4))) - allocate(nbuffery2D(size(nbuffery,1), size(nbuffery,2)*size(nbuffery,3)*size(nbuffery,4))) - sbuffery2D = RESHAPE( sbuffery, SHAPE(sbuffery2D) ) - nbuffery2D = RESHAPE( nbuffery, SHAPE(nbuffery2D) ) - end if - - !--- We are assuming flags will be always XUPDATE+YUPDATE, so there are three possible - if( xxcount>0 .AND. xycount>0 .AND. yxcount>0 .AND. yycount>0 ) then ! BGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, ebufferx=ebufferx2D, sbufferx=sbufferx2D, & - wbufferx=wbufferx2D, nbufferx=nbufferx2D, ebuffery=ebuffery2D, sbuffery=sbuffery2D, & - wbuffery=wbuffery2D, nbuffery=nbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - else if( xxcount>0 .AND. yycount>0 ) then ! CGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, ebufferx=ebufferx2D, wbufferx=wbufferx2D, & - sbuffery=sbuffery2D, nbuffery=nbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - else if( xycount>0 .AND. yxcount>0 ) then ! DGRID - call mpp_get_boundary(field3Dx, field3Dy, domain, sbufferx=sbufferx2D, nbufferx=nbufferx2D, & - ebuffery=ebuffery2D, wbuffery=wbuffery2D, flags=flags, gridtype=gridtype, & - complete=complete, tile_count=tile_count) - end if - - if(xxcount>0) then - ebufferx = RESHAPE( ebufferx2D, SHAPE(ebufferx) ) - wbufferx = RESHAPE( wbufferx2D, SHAPE(wbufferx) ) - deallocate(ebufferx2D, wbufferx2D) - end if - if(xycount>0) then - ebuffery = RESHAPE( ebuffery2D, SHAPE(ebuffery) ) - wbuffery = RESHAPE( wbuffery2D, SHAPE(wbuffery) ) - deallocate(ebuffery2D, wbuffery2D) - end if - - if(yxcount>0) then - sbufferx = RESHAPE( sbufferx2D, SHAPE(sbufferx) ) - nbufferx = RESHAPE( nbufferx2D, SHAPE(nbufferx) ) - deallocate(sbufferx2D, nbufferx2D) - end if - if(yycount>0) then - sbuffery = RESHAPE( sbuffery2D, SHAPE(sbuffery) ) - nbuffery = RESHAPE( nbuffery2D, SHAPE(nbuffery) ) - deallocate(sbufferx2D, nbuffery2D) - end if - - return - -end subroutine MPP_GET_BOUNDARY_5D_V_ diff --git a/src/shared/mpp/include/mpp_global_field.h b/src/shared/mpp/include/mpp_global_field.h index bb4fcaa5f3..29f61ed775 100644 --- a/src/shared/mpp/include/mpp_global_field.h +++ b/src/shared/mpp/include/mpp_global_field.h @@ -1,10 +1,11 @@ - subroutine MPP_GLOBAL_FIELD_2D_( domain, local, global, flags, position,tile_count) + subroutine MPP_GLOBAL_FIELD_2D_( domain, local, global, flags, position,tile_count, default_data) type(domain2D), intent(in) :: domain MPP_TYPE_, intent(in) :: local(:,:) MPP_TYPE_, intent(out) :: global(:,:) integer, intent(in), optional :: flags integer, intent(in), optional :: position integer, intent(in), optional :: tile_count + MPP_TYPE_, intent(in), optional :: default_data MPP_TYPE_ :: local3D (size( local,1),size( local,2),1) MPP_TYPE_ :: global3D(size(global,1),size(global,2),1) @@ -12,11 +13,11 @@ pointer( gptr, global3D ) lptr = LOC( local) gptr = LOC(global) - call mpp_global_field( domain, local3D, global3D, flags, position,tile_count ) + call mpp_global_field( domain, local3D, global3D, flags, position,tile_count, default_data ) end subroutine MPP_GLOBAL_FIELD_2D_ - subroutine MPP_GLOBAL_FIELD_3D_( domain, local, global, flags, position, tile_count) + subroutine MPP_GLOBAL_FIELD_3D_( domain, local, global, flags, position, tile_count, default_data) !get a global field from a local field !local field may be on compute OR data domain type(domain2D), intent(in) :: domain @@ -25,6 +26,7 @@ integer, intent(in), optional :: flags integer, intent(in), optional :: position integer, intent(in), optional :: tile_count + MPP_TYPE_, intent(in), optional :: default_data integer :: ishift, jshift integer :: tile @@ -32,17 +34,18 @@ tile = 1; if(PRESENT(tile_count)) tile = tile_count call mpp_get_domain_shift(domain, ishift, jshift, position) - call mpp_do_global_field( domain, local, global, tile, ishift, jshift, flags) + call mpp_do_global_field( domain, local, global, tile, ishift, jshift, flags, default_data) end subroutine MPP_GLOBAL_FIELD_3D_ - subroutine MPP_GLOBAL_FIELD_4D_( domain, local, global, flags, position,tile_count ) + subroutine MPP_GLOBAL_FIELD_4D_( domain, local, global, flags, position,tile_count, default_data ) type(domain2D), intent(in) :: domain MPP_TYPE_, intent(in) :: local(:,:,:,:) MPP_TYPE_, intent(out) :: global(:,:,:,:) integer, intent(in), optional :: flags integer, intent(in), optional :: position integer, intent(in), optional :: tile_count + MPP_TYPE_, intent(in), optional :: default_data MPP_TYPE_ :: local3D (size( local,1),size( local,2),size( local,3)*size(local,4)) MPP_TYPE_ :: global3D(size(global,1),size(global,2),size(global,3)*size(local,4)) @@ -50,16 +53,17 @@ pointer( gptr, global3D ) lptr = LOC(local) gptr = LOC(global) - call mpp_global_field( domain, local3D, global3D, flags, position,tile_count ) + call mpp_global_field( domain, local3D, global3D, flags, position,tile_count, default_data ) end subroutine MPP_GLOBAL_FIELD_4D_ - subroutine MPP_GLOBAL_FIELD_5D_( domain, local, global, flags, position,tile_count ) + subroutine MPP_GLOBAL_FIELD_5D_( domain, local, global, flags, position,tile_count, default_data ) type(domain2D), intent(in) :: domain MPP_TYPE_, intent(in) :: local(:,:,:,:,:) MPP_TYPE_, intent(out) :: global(:,:,:,:,:) integer, intent(in), optional :: flags integer, intent(in), optional :: position integer, intent(in), optional :: tile_count + MPP_TYPE_, intent(in), optional :: default_data MPP_TYPE_ :: local3D (size( local,1),size( local,2),size( local,3)*size( local,4)*size(local,5)) MPP_TYPE_ :: global3D(size(global,1),size(global,2),size(global,3)*size(global,4)*size(local,5)) @@ -67,5 +71,5 @@ pointer( gptr, global3D ) lptr = LOC(local) gptr = LOC(global) - call mpp_global_field( domain, local3D, global3D, flags, position,tile_count ) + call mpp_global_field( domain, local3D, global3D, flags, position,tile_count, default_data ) end subroutine MPP_GLOBAL_FIELD_5D_ diff --git a/src/shared/mpp/include/mpp_io_misc.inc b/src/shared/mpp/include/mpp_io_misc.inc index b99840deb9..e2e6bf7dfc 100644 --- a/src/shared/mpp/include/mpp_io_misc.inc +++ b/src/shared/mpp/include/mpp_io_misc.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_io_misc.inc,v 19.0 2012/01/06 22:03:22 fms Exp $ +! $Id: mpp_io_misc.inc,v 20.0 2013/12/14 00:26:36 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -66,6 +66,12 @@ read(unit_nml,mpp_io_nml,iostat=io_status) close(unit_nml) #endif + + if (io_status > 0) then + call mpp_error(FATAL,'=>mpp_io_init: Error reading input.nml') + endif + + outunit = stdout(); logunit=stdlog() write(outunit, mpp_io_nml) write(logunit, mpp_io_nml) diff --git a/src/shared/mpp/include/mpp_io_read.inc b/src/shared/mpp/include/mpp_io_read.inc index 8f84db7e77..770faa5eeb 100644 --- a/src/shared/mpp/include/mpp_io_read.inc +++ b/src/shared/mpp/include/mpp_io_read.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_io_read.inc,v 19.0.2.1 2012/05/07 02:19:08 z1l Exp $ +! $Id: mpp_io_read.inc,v 20.0 2013/12/14 00:26:38 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -425,11 +425,14 @@ integer, intent(in) :: unit integer :: ncid,ndim,nvar_total,natt,recdim,nv,nvar,len - integer :: error, i, j, istat + integer :: error, i, j, istat, check_exist integer :: type, nvdims, nvatts, dimid integer, allocatable, dimension(:) :: dimids character(len=128) :: name, attname, unlimname, attval logical :: isdim + integer(LONG_KIND) :: checksumf + character(len=64) :: checksum_char + integer :: num_checksumf, last, is, k integer(SHORT_KIND), allocatable :: i2vals(:) integer(INT_KIND), allocatable :: ivals(:) @@ -852,6 +855,8 @@ mpp_file(unit)%Axis(dimid)%calendar = '365_day' if (trim(mpp_file(unit)%Axis(dimid)%calendar) == '360_days') & mpp_file(unit)%Axis(dimid)%calendar = '360_day' + case('compress') + mpp_file(unit)%Axis(dimid)%compressed=mpp_file(unit)%Axis(dimid)%Att(j)%catt(1:len) case('positive') attval = mpp_file(unit)%Axis(dimid)%Att(j)%catt(1:len) if( attval.eq.'down' )then @@ -1033,6 +1038,24 @@ case('valid_range') mpp_file(unit)%Var(nv)%min=mpp_file(unit)%Var(nv)%Att(j)%fatt(1) mpp_file(unit)%Var(nv)%max=mpp_file(unit)%Var(nv)%Att(j)%fatt(2) + case('checksum') + checksum_char = mpp_file(unit)%Var(nv)%Att(j)%catt +! Scan checksum attribute for , delimiter. If found implies multiple time levels. + checksumf = 0 + num_checksumf = 1 + + last = len_trim(checksum_char) + is = index (trim(checksum_char),",") ! A value of 0 implies only 1 checksum value + do while ((is > 0) .and. (is < (last-15))) + is = is + scan(checksum_char(is:last), "," ) ! move starting pointer after "," + num_checksumf = num_checksumf + 1 + enddo + is =1 + do k = 1, num_checksumf + read (checksum_char(is:is+15),'(Z16)') checksumf + mpp_file(unit)%Var(nv)%checksum(k) = checksumf + is = is + 17 ! Move index past the , + enddo end select enddo endif diff --git a/src/shared/mpp/include/mpp_io_util.inc b/src/shared/mpp/include/mpp_io_util.inc index 3e79f49c24..7894248d4a 100644 --- a/src/shared/mpp/include/mpp_io_util.inc +++ b/src/shared/mpp/include/mpp_io_util.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_io_util.inc,v 19.0.2.1 2012/05/11 14:54:02 Zhi.Liang Exp $ +! $Id: mpp_io_util.inc,v 20.0 2013/12/14 00:26:40 fms Exp $ !##################################################################### @@ -75,22 +75,24 @@ end subroutine mpp_get_global_atts !##################################################################### - subroutine mpp_get_field_atts(field, name, units, longname, min, max, missing, ndim, siz, axes, atts, valid, scale, add) + subroutine mpp_get_field_atts(field, name, units, longname, min, max, missing, ndim, siz, axes, atts, & + valid, scale, add, checksum) - type(fieldtype), intent(in) :: field - character(len=*), intent(out) , optional :: name, units - character(len=*), intent(out), optional :: longname - real,intent(out), optional :: min,max,missing - integer, intent(out), optional :: ndim - integer, intent(out), dimension(:), optional :: siz - type(validtype), intent(out), optional :: valid - real, intent(out), optional :: scale - real, intent(out), optional :: add + type(fieldtype), intent(in) :: field + character(len=*), intent(out), optional :: name, units + character(len=*), intent(out), optional :: longname + real, intent(out), optional :: min,max,missing + integer, intent(out), optional :: ndim + integer, intent(out), dimension(:), optional :: siz + type(validtype), intent(out), optional :: valid + real, intent(out), optional :: scale + real, intent(out), optional :: add + integer(LONG_KIND), intent(out), dimension(:), optional :: checksum - type(atttype), intent(inout), optional, dimension(:) :: atts - type(axistype), intent(inout), optional, dimension(:) :: axes + type(atttype), intent(inout), dimension(:), optional :: atts + type(axistype), intent(inout), dimension(:), optional :: axes - integer :: n,m + integer :: n,m, check_exist if (PRESENT(name)) name = field%name if (PRESENT(units)) units = field%units @@ -134,8 +136,13 @@ call mpp_get_valid(field,valid) endif - if(PRESENT(scale)) scale = field%scale - if(present(add)) add = field%add + if(PRESENT(scale)) scale = field%scale + if(present(add)) add = field%add + if(present(checksum)) then + checksum = 0 + check_exist = mpp_find_att(field%Att(:),"checksum") + if ( check_exist >= 0 ) checksum = field%checksum + endif return end subroutine mpp_get_field_atts @@ -354,6 +361,27 @@ return end function mpp_get_axis_index + !##################################################################### + function mpp_get_axis_by_name(unit,axisname) + + integer :: unit + character(len=*) :: axisname + type(axistype) :: mpp_get_axis_by_name + + integer :: n + + mpp_get_axis_by_name = default_axis + + do n=1,size(mpp_file(unit)%Axis(:)) + if (lowercase(mpp_file(unit)%Axis(n)%name) == lowercase(axisname)) then + mpp_get_axis_by_name = mpp_file(unit)%Axis(n) + exit + endif + enddo + + return + end function mpp_get_axis_by_name + !##################################################################### function mpp_get_field_size(field) @@ -371,6 +399,18 @@ end function mpp_get_field_size + !##################################################################### + function mpp_get_axis_length(axis) + + type(axistype) :: axis + integer :: mpp_get_axis_length + + mpp_get_axis_length = axis%len + + return + end function mpp_get_axis_length + + !##################################################################### subroutine mpp_get_axis_data( axis, data ) @@ -523,7 +563,7 @@ scale_T = 0 iscale = mpp_find_att(f%att,'scale_factor') if(iscale>0) scale_T = f%att(iscale)%type - iscale = mpp_find_att(f%att,'add_offest') + iscale = mpp_find_att(f%att,'add_offset') if(iscale>0) scale_T = max(scale_T,f%att(iscale)%type) @@ -781,3 +821,14 @@ return end function mpp_io_clock_on + + + function mpp_attribute_exist(field,name) + integer :: mpp_attribute_exist + type(fieldtype), intent(in) :: field ! The field that you are searching for the attribute. + character(len=*), intent(in) :: name ! name of the attributes + + mpp_attribute_exist = mpp_find_att(field%Att(:),name) + + end function mpp_attribute_exist + diff --git a/src/shared/mpp/include/mpp_io_write.inc b/src/shared/mpp/include/mpp_io_write.inc index edc22b91d7..5fcf08e81d 100644 --- a/src/shared/mpp/include/mpp_io_write.inc +++ b/src/shared/mpp/include/mpp_io_write.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_io_write.inc,v 19.0 2012/01/06 22:03:58 fms Exp $ +! $Id: mpp_io_write.inc,v 20.0 2013/12/14 00:26:42 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -222,18 +222,42 @@ return end subroutine mpp_write_meta_scalar_i - subroutine mpp_write_meta_axis( unit, axis, name, units, longname, cartesian, sense, domain, data) + + subroutine mpp_write_axis_data (unit, axes ) + integer, intent(in) :: unit + type(axistype), dimension(:), intent(in) :: axes + + integer :: naxis + + naxis = size (axes) + allocate (mpp_file(unit)%axis(naxis)) + mpp_file(unit)%axis(1:naxis) = axes(1:naxis) +#ifdef use_netCDF + if( mpp_file(unit)%action.EQ.MPP_WRONLY )then + if(header_buffer_val>0) then + error = NF__ENDDEF(mpp_file(unit)%ncid,header_buffer_val,4,0,4) + else + error = NF_ENDDEF(mpp_file(unit)%ncid) + endif + endif +#endif + end subroutine mpp_write_axis_data + + subroutine mpp_write_meta_axis( unit, axis, name, units, longname, cartesian, sense, domain, data, min, compressed) !load the values in an axistype (still need to call mpp_write) !write metadata attributes for axis !it is declared intent(inout) so you can nullify pointers in the incoming object if needed !the f90 standard doesn't guarantee that intent(out) on a type guarantees that its pointer components will be unassociated - integer, intent(in) :: unit - type(axistype), intent(inout) :: axis - character(len=*), intent(in) :: name, units, longname + integer, intent(in) :: unit + type(axistype), intent(inout) :: axis + character(len=*), intent(in) :: name, units, longname character(len=*), intent(in), optional :: cartesian - integer, intent(in), optional :: sense - type(domain1D), intent(in), optional :: domain - real, intent(in), optional :: data(:) + integer, intent(in), optional :: sense + type(domain1D), intent(in), optional :: domain + real, intent(in), optional :: data(:) + real, intent(in), optional :: min + character(len=*), intent(in), optional :: compressed + integer :: is, ie, isg, ieg integer :: istat logical :: domain_exist @@ -290,7 +314,8 @@ axis%name = name axis%units = units axis%longname = longname - if( PRESENT(sense) )axis%sense = sense + if( PRESENT(sense) ) axis%sense = sense + if( PRESENT(compressed)) axis%compressed = trim(compressed) if( PRESENT(data) )then if( mpp_file(unit)%fileset.EQ.MPP_MULTI .AND. domain_exist ) then axis%len = ie - is + 1 @@ -352,29 +377,46 @@ end if end if !write axis attributes - call mpp_write_meta( unit, axis%id, 'long_name', cval=axis%longname) - call mpp_write_meta( unit, axis%id, 'units', cval=axis%units) - if( PRESENT(cartesian) )call mpp_write_meta( unit, axis%id, 'cartesian_axis', cval=axis%cartesian) + call mpp_write_meta( unit, axis%id, 'long_name', cval=axis%longname) ; axis%natt = axis%natt + 1 + call mpp_write_meta( unit, axis%id, 'units', cval=axis%units) ; axis%natt = axis%natt + 1 + if( PRESENT(cartesian) ) then + call mpp_write_meta( unit, axis%id, 'cartesian_axis', cval=axis%cartesian) + axis%natt = axis%natt + 1 + endif if( PRESENT(sense) )then if( sense.EQ.-1 )then call mpp_write_meta( unit, axis%id, 'positive', cval='down') + axis%natt = axis%natt + 1 else if( sense.EQ.1 )then call mpp_write_meta( unit, axis%id, 'positive', cval='up') + axis%natt = axis%natt + 1 end if !silently ignore values of sense other than +/-1. end if + if( PRESENT(compressed) ) then + call mpp_write_meta( unit, axis%id, 'compress', cval=axis%compressed) + axis%natt = axis%natt + 1 + endif + if( PRESENT(min) ) then + call mpp_write_meta( unit, axis%id, 'valid_min', rval=min) + axis%natt = axis%natt + 1 + endif if( mpp_file(unit)%threading.EQ.MPP_MULTI .AND. mpp_file(unit)%fileset.EQ.MPP_MULTI .AND. domain_exist )then call mpp_write_meta( unit, axis%id, 'domain_decomposition', ival=(/isg,ieg,is,ie/)) + axis%natt = axis%natt + 1 end if if( verbose )print '(a,2i3,x,a,2i3)', 'MPP_WRITE_META: Wrote axis metadata, pe, unit, axis%name, axis%id, axis%did=', & pe, unit, trim(axis%name), axis%id, axis%did + + mpp_file(unit)%ndim = max(1,mpp_file(unit)%ndim + 1) + ! call mpp_clock_end(mpp_write_clock) return end subroutine mpp_write_meta_axis subroutine mpp_write_meta_field( unit, field, axes, name, units, longname,& - min, max, missing, fill, scale, add, pack, time_method,standard_name) + min, max, missing, fill, scale, add, pack, time_method,standard_name, checksum) !define field: must have already called mpp_write_meta(axis) for each axis integer, intent(in) :: unit type(fieldtype), intent(inout) :: field @@ -384,10 +426,12 @@ integer, intent(in), optional :: pack character(len=*), intent(in), optional :: time_method character(len=*), intent(in), optional :: standard_name + integer(LONG_KIND), dimension(:), intent(in), optional :: checksum !this array is required because of f77 binding on netCDF interface integer, allocatable :: axis_id(:) real :: a, b integer :: i, istat, ishift, jshift + character(len=64) :: checksum_char ! call mpp_clock_begin(mpp_write_clock) @@ -421,8 +465,14 @@ return endif if( .NOT.mpp_file(unit)%opened ) call mpp_error( FATAL, 'MPP_WRITE_META: invalid unit number.' ) - if( mpp_file(unit)%initialized ) & - call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) + if( mpp_file(unit)%initialized ) then +! File has already been written to and needs to be returned to define mode. +#ifdef use_netCDF + error = NF_REDEF(mpp_file(unit)%ncid) +#endif + mpp_file(unit)%initialized = .false. + endif +! call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) !pre-existing pointers need to be nullified if( ASSOCIATED(field%axes) ) then @@ -448,13 +498,15 @@ end if end do !attributes - if( PRESENT(min) )field%min = min - if( PRESENT(max) )field%max = max - if( PRESENT(scale) )field%scale = scale - if( PRESENT(add) )field%add = add + if( PRESENT(min) ) field%min = min + if( PRESENT(max) ) field%max = max + if( PRESENT(scale) ) field%scale = scale + if( PRESENT(add) ) field%add = add if( PRESENT(standard_name)) field%standard_name = standard_name - if( PRESENT(missing) ) field%missing = missing - if( PRESENT(fill) ) field%fill = fill + if( PRESENT(missing) ) field%missing = missing + if( PRESENT(fill) ) field%fill = fill + field%checksum = 0 + if( PRESENT(checksum) ) field%checksum(1:size(checksum)) = checksum(:) ! Issue warning if fill and missing are different if ( (present(fill).and.present(missing)) .and. (field%missing .ne. field%fill) ) then @@ -471,6 +523,8 @@ end do !write field def select case (field%pack) + case(0) + error = NF_DEF_VAR( mpp_file(unit)%ncid, field%name, NF_INT, size(field%axes(:)), axis_id, field%id ) case(1) error = NF_DEF_VAR( mpp_file(unit)%ncid, field%name, NF_DOUBLE, size(field%axes(:)), axis_id, field%id ) case(2) @@ -556,6 +610,14 @@ if( PRESENT(add) )call mpp_write_meta( unit, field%id, 'add_offset', rval=field%add ) end if + if( present(checksum) )then + write (checksum_char,'(Z16)') field%checksum(1) + do i = 2,size(checksum) + write (checksum_char,'(a,Z16)') trim(checksum_char)//",",checksum(i) + enddo + call mpp_write_meta( unit, field%id, 'checksum', cval=checksum_char ) + end if + if ( PRESENT(time_method) ) then call mpp_write_meta(unit,field%id, 'cell_methods',cval='time: '//trim(time_method)) endif @@ -810,6 +872,14 @@ field%size(1) = axis%len field%id = axis%id + field%name = axis%name + field%longname = axis%longname + field%units = axis%units + + allocate( field%axes(1)%data(size(axis%data) )) + field%axes(1)%data = axis%data + + call write_record( unit, field, axis%len, axis%data ) call mpp_clock_end(mpp_write_clock) return @@ -950,7 +1020,8 @@ ptr1 = LOC(mpp_io_stack(1)) !subdomain contains (/is,ie,js,je/) if( PRESENT(domain) )then - subdomain(:) = (/ is, ie, js, je /) ! ??? is, ie, js, je are never initialized. + call mpp_get_compute_domain(domain, is, ie, js, je) + subdomain(:) = (/ is, ie, js, je /) else subdomain(:) = -1 ! -1 means use global value from axis metadata end if @@ -1011,13 +1082,19 @@ !for a non-netCDF file, it is encoded into a string "GLOBAL " integer, intent(in) :: unit type(atttype), intent(in) :: gatt - integer :: len + integer :: len, error if( .NOT.module_is_initialized )call mpp_error( FATAL, 'MPP_WRITE_META: must first call mpp_io_init.' ) if( .NOT. mpp_file(unit)%write_on_this_pe )return if( .NOT.mpp_file(unit)%opened )call mpp_error( FATAL, 'MPP_WRITE_META: invalid unit number.' ) - if( mpp_file(unit)%initialized ) & - call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) + if( mpp_file(unit)%initialized ) then +! File has already been written to and needs to be returned to define mode. +#ifdef use_netCDF + error = NF_REDEF(mpp_file(unit)%ncid) +#endif + mpp_file(unit)%initialized = .false. + endif +! call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) #ifdef use_netCDF if( mpp_file(unit)%format.EQ.MPP_NETCDF )then if( gatt%type.EQ.NF_CHAR )then @@ -1049,7 +1126,7 @@ type(axistype), intent(inout) :: axis type(domain1D), intent(in), optional :: domain character(len=512) :: text - integer :: i, len, is, ie, isg, ieg + integer :: i, len, is, ie, isg, ieg, error ! call mpp_clock_begin(mpp_write_clock) if( .NOT.module_is_initialized )call mpp_error( FATAL, 'MPP_WRITE_META: must first call mpp_io_init.' ) @@ -1058,8 +1135,14 @@ return endif if( .NOT.mpp_file(unit)%opened )call mpp_error( FATAL, 'MPP_WRITE_META: invalid unit number.' ) - if( mpp_file(unit)%initialized ) & - call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) + if( mpp_file(unit)%initialized ) then +! File has already been written to and needs to be returned to define mode. +#ifdef use_netCDF + error = NF_REDEF(mpp_file(unit)%ncid) +#endif + mpp_file(unit)%initialized = .false. + endif +! call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) ! redefine domain if present if( PRESENT(domain) )then @@ -1104,6 +1187,7 @@ write( text, '(a,i4,a)' )'AXIS ', axis%id, ' size' if( ASSOCIATED(axis%data) )then !space axis if( mpp_file(unit)%fileset.EQ.MPP_MULTI .AND. axis%domain.NE.NULL_DOMAIN1D )then + call mpp_get_compute_domain(axis%domain, is, ie) call write_attribute( unit, trim(text), ival=(/ie-is+1/) ) ! ??? is, ie is not initialized else call write_attribute( unit, trim(text), ival=(/size(axis%data(:))/) ) @@ -1149,7 +1233,7 @@ !this array is required because of f77 binding on netCDF interface integer, allocatable :: axis_id(:) real :: a, b - integer :: i + integer :: i, error ! call mpp_clock_begin(mpp_write_clock) if( .NOT.module_is_initialized )call mpp_error( FATAL, 'MPP_WRITE_META: must first call mpp_io_init.' ) @@ -1158,8 +1242,14 @@ return endif if( .NOT.mpp_file(unit)%opened )call mpp_error( FATAL, 'MPP_WRITE_META: invalid unit number.' ) - if( mpp_file(unit)%initialized ) & - call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) + if( mpp_file(unit)%initialized ) then +! File has already been written to and needs to be returned to define mode. +#ifdef use_netCDF + error = NF_REDEF(mpp_file(unit)%ncid) +#endif + mpp_file(unit)%initialized = .false. + endif +! call mpp_error( FATAL, 'MPP_WRITE_META: cannot write metadata to file after an mpp_write.' ) if( field%pack.NE.1 .AND. field%pack.NE.2 )then if( field%pack.NE.4 .AND. field%pack.NE.8 ) & diff --git a/src/shared/mpp/include/mpp_update_domains2D_nonblock.h b/src/shared/mpp/include/mpp_update_domains2D_nonblock.h index 8777ded85b..19c2d0736b 100644 --- a/src/shared/mpp/include/mpp_update_domains2D_nonblock.h +++ b/src/shared/mpp/include/mpp_update_domains2D_nonblock.h @@ -720,7 +720,6 @@ function MPP_START_UPDATE_DOMAINS_3D_V_( fieldx, fieldy, domain, flags, gridtype updatex => search_update_overlap(domain, update_whalo, update_ehalo, update_shalo, update_nhalo, position_x) updatey => search_update_overlap(domain, update_whalo, update_ehalo, update_shalo, update_nhalo, position_y) - ke_max = maxval(ke_list(1:l_size,1:ntile)) ke_max = maxval(ke_list(1:l_size,1:ntile)) if(exchange_uv) then call mpp_start_do_update(current_id, f_addrsx(1:l_size,1:ntile), f_addrsy(1:l_size,1:ntile), domain, & @@ -728,7 +727,7 @@ function MPP_START_UPDATE_DOMAINS_3D_V_( fieldx, fieldy, domain, flags, gridtype update_flags, reuse_id_update, field_name) else call mpp_start_do_update(current_id, f_addrsx(1:l_size,1:ntile), f_addrsy(1:l_size,1:ntile), domain, & - updatex, updatey, d_type, ke_max, ke_list(1:l_size,1:ntile), gridtype, & + updatex, updatey, d_type, ke_max, ke_list(1:l_size,1:ntile), grid_offset_type, & update_flags, reuse_id_update, field_name) endif endif diff --git a/src/shared/mpp/include/mpp_update_nest_domains.h b/src/shared/mpp/include/mpp_update_nest_domains.h index 88ed6a5b2e..7f8a032436 100644 --- a/src/shared/mpp/include/mpp_update_nest_domains.h +++ b/src/shared/mpp/include/mpp_update_nest_domains.h @@ -65,9 +65,9 @@ subroutine MPP_UPDATE_NEST_FINE_3D_(field, nest_domain, wbuffer, sbuffer, ebuffe integer :: add_halo, update_flags, update_position integer :: wbuffersz, ebuffersz, sbuffersz, nbuffersz integer :: isize, jsize, ksize, l_size - integer, save :: isize_save, jsize_save, ksize_save - integer :: wbuffersz_save, ebuffersz_save, sbuffersz_save, nbuffersz_save - integer, save :: add_halo_save, update_flags_save, update_position_save + integer, save :: isize_save=0, jsize_save=0, ksize_save=0 + integer :: wbuffersz_save=0, ebuffersz_save=0, sbuffersz_save=0, nbuffersz_save=0 + integer, save :: add_halo_save=0, update_flags_save=0, update_position_save=0 integer, save :: list=0 add_halo = 0 @@ -227,10 +227,10 @@ subroutine MPP_UPDATE_NEST_COARSE_3D_(field, nest_domain, buffer, complete, posi logical :: is_complete, set_mismatch integer :: tile integer :: update_position - integer :: buffersz, buffersz_save + integer :: buffersz, buffersz_save=0 integer :: isize, jsize, ksize, l_size - integer, save :: isize_save, jsize_save, ksize_save - integer, save :: update_position_save + integer, save :: isize_save=0, jsize_save=0, ksize_save=0 + integer, save :: update_position_save=0 integer, save :: list=0 update_position = CENTER diff --git a/src/shared/mpp/include/mpp_util.inc b/src/shared/mpp/include/mpp_util.inc index a64764f98c..290ecf1ac3 100644 --- a/src/shared/mpp/include/mpp_util.inc +++ b/src/shared/mpp/include/mpp_util.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_util.inc,v 19.0.2.1 2012/04/13 16:25:53 sdu Exp $ +! $Id: mpp_util.inc,v 20.0 2013/12/14 00:27:35 fms Exp $ #ifdef use_libSMA @@ -555,6 +555,14 @@ end function rarray_to_char return end subroutine mpp_set_current_pelist + !##################################################################### + function mpp_get_current_pelist_name() + ! Simply return the current pelist name + character(len=len(peset(current_peset_num)%name)) :: mpp_get_current_pelist_name + + mpp_get_current_pelist_name = peset(current_peset_num)%name + end function mpp_get_current_pelist_name + !##################################################################### !this is created for use by mpp_define_domains within a pelist !will be published but not publicized @@ -801,7 +809,7 @@ end function rarray_to_char call mpp_error( FATAL, 'MPP_CLOCK_BEGIN: cannot change pelist context of a clock.' ) if( clocks(id)%is_on) call mpp_error(FATAL, 'MPP_CLOCK_BEGIN: mpp_clock_begin is called again '// & 'before calling mpp_clock_end for the clock '//trim(clocks(id)%name) ) - if( clocks(id)%sync_on_begin )then + if( clocks(id)%sync_on_begin .OR. sync_all_clocks )then !do an untimed sync at the beginning of the clock !this puts all PEs in the current pelist on par, so that measurements begin together !ending time will be different, thus measuring load imbalance for this clock. @@ -853,6 +861,21 @@ end function rarray_to_char return end subroutine mpp_clock_end + !##################################################################### + subroutine mpp_record_time_start() + + mpp_record_timing_data = .TRUE. + + end subroutine mpp_record_time_start + + !##################################################################### + subroutine mpp_record_time_end() + + mpp_record_timing_data = .FALSE. + + end subroutine mpp_record_time_end + + !##################################################################### subroutine increment_current_clock( event_id, bytes ) integer, intent(in) :: event_id @@ -1012,7 +1035,7 @@ end function rarray_to_char 1000 format(a) 1001 format(a,f8.2,a,f8.2,a,i6) 1002 format(a) -1003 format(a,i6,' ',' ',f6.1,a,' ',f7.3,'MB/sec') +1003 format(a,i6,' ',' ',f9.1,a,' ',f9.2,'MB/sec') 1004 format(a,i8,a,f9.2,a) 1005 format(a,f9.2,a) return @@ -1258,29 +1281,111 @@ end function rarray_to_char ! read(input_nml_file, nml=, iostat=status) ! ! - subroutine read_input_nml + subroutine read_input_nml() ! version and tagging information - character(len=128) :: version = '$Id: mpp_util.inc,v 19.0.2.1 2012/04/13 16:25:53 sdu Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: mpp_util.inc,v 20.0 2013/12/14 00:27:35 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' -!private variables +! private variables integer :: log_unit integer :: num_lines, i + logical :: file_exist + character(len=32) :: pelist_name + character(len=128) :: filename - call read_ascii_file('input.nml', INPUT_STR_LENGTH, input_nml_file, num_lines=num_lines) +! check the status of input_nml_file + if ( allocated(input_nml_file) ) then + deallocate(input_nml_file) + endif + +! the following code is necessary for using alternate namelist files (nests, stretched grids, etc) + pelist_name = mpp_get_current_pelist_name() + filename='input_'//trim(pelist_name)//'.nml' + inquire(FILE=filename, EXIST=file_exist) + if (.not. file_exist ) then + filename='input.nml' + endif + num_lines = get_ascii_file_num_lines(filename, INPUT_STR_LENGTH) + allocate(input_nml_file(num_lines)) + call read_ascii_file(filename, INPUT_STR_LENGTH, input_nml_file) ! write info logfile if (pe == root_pe) then log_unit = stdlog() write(log_unit,'(a)') '========================================================================' write(log_unit,'(a)') 'READ_INPUT_NML: '//trim(version)//':'//trim(tagname) + write(log_unit,'(a)') 'READ_INPUT_NML: '//trim(filename)//' ' do i = 1, num_lines write(log_unit,*) trim(input_nml_file(i)) enddo end if end subroutine read_input_nml + + !####################################################################### + !z1l: This is extracted from read_ascii_file + function get_ascii_file_num_lines(FILENAME, LENGTH, PELIST) + character(len=*), intent(in) :: FILENAME + integer, intent(in) :: LENGTH + integer, intent(in), optional, dimension(:) :: PELIST + + integer :: num_lines, get_ascii_file_num_lines + character(len=LENGTH) :: str_tmp + character(len=5) :: text + integer :: status, f_unit, from_pe + logical :: file_exist + + if( read_ascii_file_on) then + call mpp_error(FATAL, & + "mpp_util.inc: get_ascii_file_num_lines is called again before calling read_ascii_file") + endif + read_ascii_file_on = .true. + + from_pe = root_pe + get_ascii_file_num_lines = -1 + num_lines = -1 + if ( pe == root_pe ) then + inquire(FILE=FILENAME, EXIST=file_exist) + + if ( file_exist ) then + f_unit = get_unit() + open(UNIT=f_unit, FILE=FILENAME, ACTION='READ', STATUS='OLD', IOSTAT=status) + + if ( status .ne. 0 ) then + write (UNIT=text, FMT='(I5)') status + call mpp_error(FATAL, 'get_ascii_file_num_lines: Error opening file:' //trim(FILENAME)// & + '. (IOSTAT = '//trim(text)//')') + else + num_lines = 1 + do + read (UNIT=f_unit, FMT='(A)', IOSTAT=status) str_tmp + if ( status .lt. 0 ) exit + if ( status .gt. 0 ) then + write (UNIT=text, FMT='(I5)') num_lines + call mpp_error(FATAL, 'get_ascii_file_num_lines: Error reading line '//trim(text)// & + ' in file '//trim(FILENAME)//'.') + end if + if ( len_trim(str_tmp) == LENGTH ) then + write(UNIT=text, FMT='(I5)') length + call mpp_error(FATAL, 'get_ascii_file_num_lines: Length of output string ('//trim(text)//' is too small.& + & Increase the LENGTH value.') + end if + num_lines = num_lines + 1 + end do + close(UNIT=f_unit) + end if + else + call mpp_error(FATAL, 'get_ascii_file_num_lines: File '//trim(FILENAME)//' does not exist.') + end if + end if + + ! Broadcast number of lines + call mpp_broadcast(num_lines, from_pe, PELIST=PELIST) + get_ascii_file_num_lines = num_lines + + end function get_ascii_file_num_lines + !----------------------------------------------------------------------- ! ! AUTHOR: Rusty Benson , @@ -1303,33 +1408,30 @@ end function rarray_to_char ! read (UNIT=array_name(i), FMT=*) var1, var2, ... ! end do ! - subroutine read_ascii_file(FILENAME, LENGTH, Content, num_lines, PELIST) - character(len=*), intent(in) ::FILENAME - integer, intent(in) :: LENGTH - character(len=LENGTH), intent(inout), dimension(:), allocatable :: Content - integer, intent(out), optional, target :: num_lines - integer, intent(in), optional, dimension(:) :: PELIST + subroutine read_ascii_file(FILENAME, LENGTH, Content, PELIST) + character(len=*), intent(in) :: FILENAME + integer, intent(in) :: LENGTH + character(len=*), intent(inout), dimension(:) :: Content + integer, intent(in), optional, dimension(:) :: PELIST ! version and tagging information - character(len=*), parameter :: VERSION = '$Id: mpp_util.inc,v 19.0.2.1 2012/04/13 16:25:53 sdu Exp $' - character(len=*), parameter :: TAGNAME = '$Name: siena_201207 $' + character(len=*), parameter :: VERSION = '$Id: mpp_util.inc,v 20.0 2013/12/14 00:27:35 fms Exp $' + character(len=*), parameter :: TAGNAME = '$Name: tikal $' - character(len=LENGTH) :: str_tmp character(len=5) :: text logical :: file_exist integer :: status, i, f_unit, log_unit integer :: from_pe - integer, pointer :: pnum_lines - integer, target :: mynum_lines + integer :: pnum_lines, num_lines - from_pe = root_pe + if( .NOT. read_ascii_file_on) then + call mpp_error(FATAL, & + "mpp_util.inc: get_ascii_file_num_lines needs to be called before calling read_ascii_file") + endif + read_ascii_file_on = .false. - ! Use pnum_lines to point to num_lines if present, else use a local variable - if ( present(num_lines) ) then - pnum_lines => num_lines - else - pnum_lines => mynum_lines - end if + from_pe = root_pe + num_lines = size(Content(:)) if ( pe == root_pe ) then ! write info logfile @@ -1347,87 +1449,54 @@ end function rarray_to_char if ( status .ne. 0 ) then write (UNIT=text, FMT='(I5)') status call mpp_error(FATAL, 'READ_ASCII_FILE: Error opening file: '//trim(FILENAME)//'. (IOSTAT = '//trim(text)//')') - pnum_lines = -1 else - pnum_lines = 1 - do - read (UNIT=f_unit, FMT='(A)', IOSTAT=status) str_tmp - if ( status .lt. 0 ) exit - if ( status .gt. 0 ) then - write (UNIT=text, FMT='(I5)') pnum_lines - call mpp_error(FATAL, 'READ_ASCII_FILE: Error reading line '//trim(text)//' in file '//trim(FILENAME)//'.') - pnum_lines = -1 - exit - end if - if ( len_trim(str_tmp) == LENGTH ) then - write(UNIT=text, FMT='(I5)') length - call mpp_error(FATAL, 'READ_ASCII_FILE: Length of output string ('//trim(text)//' is too small.& - & Increase the LENGTH value.') - pnum_lines = -1 - exit - end if - pnum_lines = pnum_lines + 1 - end do - if ( pnum_lines .gt. 0 ) then - allocate(Content(pnum_lines), STAT=status) + if ( num_lines .gt. 0 ) then + Content(:) = ' ' + + rewind(UNIT=f_unit, IOSTAT=status) if ( status .ne. 0 ) then - write (UNIT=text, FMT='(I5)') pe - call mpp_error(FATAL, 'READ_ASCII_FILE: PE '//trim(text)//'. Unable to allocate space for array& - & of character strings.') - pnum_lines = -1 + write (UNIT=text, FMT='(I5)') status + call mpp_error(FATAL, 'READ_ASCII_FILE: Unable to re-read file '//trim(FILENAME)//'. (IOSTAT = '& + //trim(text)//'.') else - Content(:) = ' ' - - rewind(UNIT=f_unit, IOSTAT=status) - if ( status .ne. 0 ) then - write (UNIT=text, FMT='(I5)') status - call mpp_error(FATAL, 'READ_ASCII_FILE: Unable to re-read file '//trim(FILENAME)//'. (IOSTAT = '& - &//trim(text)//')') - deallocate(Content) ! No content. - pnum_lines = -1 - else - ! A second 'sanity' check on the file - pnum_lines = 1 - - do - read (UNIT=f_unit, FMT='(A)', IOSTAT=status) Content(pnum_lines) - if ( status .lt. 0 ) exit - if ( status .gt. 0 ) then - write (UNIT=text, FMT='(I5)') pnum_lines - call mpp_error(FATAL, 'READ_ASCII_FILE: Error reading line '//trim(text)//' in file '//trim(FILENAME)//'.') - pnum_lines = -1 - exit - end if - pnum_lines = pnum_lines + 1 - end do + ! A second 'sanity' check on the file + pnum_lines = 1 + + do + read (UNIT=f_unit, FMT='(A)', IOSTAT=status) Content(pnum_lines) + + if ( status .lt. 0 ) exit + if ( status .gt. 0 ) then + write (UNIT=text, FMT='(I5)') pnum_lines + call mpp_error(FATAL, 'READ_ASCII_FILE: Error reading line '//trim(text)//' in file '//trim(FILENAME)//'.') + end if + if(pnum_lines > num_lines) then + call mpp_error(FATAL, 'READ_ASCII_FILE: number of lines in file '//trim(FILENAME)// & + ' is greater than size(Content(:)). ') + end if + if ( len_trim(Content(pnum_lines)) == LENGTH ) then + write(UNIT=text, FMT='(I5)') length + call mpp_error(FATAL, 'READ_ASCII_FILE: Length of output string ('//trim(text)//' is too small.& + & Increase the LENGTH value.') + end if + pnum_lines = pnum_lines + 1 + end do + if(num_lines .NE. pnum_lines) then + call mpp_error(FATAL, 'READ_ASCII_FILE: number of lines in file '//trim(FILENAME)// & + ' does not equal to size(Content(:)) ' ) end if end if end if - close(UNIT=f_unit) end if else call mpp_error(FATAL, 'READ_ASCII_FILE: File '//trim(FILENAME)//' does not exist.') - pnum_lines = -1 end if end if - ! Broadcast number of lines - call mpp_broadcast(pnum_lines, from_pe, PELIST=PELIST) - - if ( (pe .ne. root_pe).and.(pnum_lines > 0) ) then - allocate (Content(pnum_lines), STAT=status) - if ( status .ne. 0 ) then - write (UNIT=text, FMT='(I5)') pe - call mpp_error(FATAL, 'READ_ASCII_FILE: PE '//trim(text)//'. Unable to allocate space for array& - & of character strings.') - else - Content(:) = ' ' - end if - endif - ! Broadcast character array call mpp_broadcast(Content, LENGTH, from_pe, PELIST=PELIST) + end subroutine read_ascii_file diff --git a/src/shared/mpp/include/mpp_util_mpi.inc b/src/shared/mpp/include/mpp_util_mpi.inc index 301129765c..758e413052 100644 --- a/src/shared/mpp/include/mpp_util_mpi.inc +++ b/src/shared/mpp/include/mpp_util_mpi.inc @@ -1,5 +1,5 @@ ! -*-f90-*- -! $Id: mpp_util_mpi.inc,v 19.0.2.1.2.1 2012/05/24 20:01:32 Zhi.Liang Exp $ +! $Id: mpp_util_mpi.inc,v 20.0 2013/12/14 00:27:37 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -12,7 +12,7 @@ subroutine mpp_error_basic( errortype, errormsg ) !uses ABORT and FLUSH calls, may need to use cpp to rename integer, intent(in) :: errortype character(len=*), intent(in), optional :: errormsg - character(len=256) :: text + character(len=512) :: text logical :: opened integer :: istat, out_unit, errunit @@ -140,7 +140,7 @@ subroutine mpp_sync( pelist, do_self ) integer :: n dself=.true.; if(PRESENT(do_self))dself=do_self - if(dself)call mpp_sync_self(pelist) +! if(dself)call mpp_sync_self(pelist) n = get_peset(pelist); if( peset(n)%count.EQ.1 )return @@ -199,6 +199,7 @@ subroutine mpp_sync_self( pelist, check, request, msg_size, msg_type) endif do m = 1, size(request(:)) + if( request(m) == MPI_REQUEST_NULL ) cycle call MPI_WAIT(request(m), stat, error ) call MPI_GET_COUNT(stat, msg_type(m), rsize, error) if(msg_size(m) .NE. rsize) then diff --git a/src/shared/mpp/include/mpp_util_nocomm.inc b/src/shared/mpp/include/mpp_util_nocomm.inc index 53d567a393..d8a81ee407 100644 --- a/src/shared/mpp/include/mpp_util_nocomm.inc +++ b/src/shared/mpp/include/mpp_util_nocomm.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_util_nocomm.inc,v 19.0 2012/01/06 22:04:49 fms Exp $ +! $Id: mpp_util_nocomm.inc,v 20.0 2013/12/14 00:27:39 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -13,7 +13,7 @@ subroutine mpp_error_basic( errortype, errormsg ) !uses ABORT and FLUSH calls, may need to use cpp to rename integer, intent(in) :: errortype character(len=*), intent(in), optional :: errormsg - character(len=256) :: text + character(len=512) :: text logical :: opened integer :: istat, errunit, outunit @@ -87,10 +87,13 @@ end subroutine mpp_sync !this is to check if current PE's outstanding puts are complete !but we can't use shmem_fence because we are actually waiting for !a remote PE to complete its get -subroutine mpp_sync_self( pelist, check, request ) +subroutine mpp_sync_self( pelist, check, request, msg_size, msg_type ) integer, intent(in), optional :: pelist(:) integer, intent(in), optional :: check integer, intent(inout), optional :: request(:) + integer, intent(in ), optional :: msg_size(:) + integer, intent(in ), optional :: msg_type(:) + return end subroutine mpp_sync_self diff --git a/src/shared/mpp/include/mpp_util_sma.inc b/src/shared/mpp/include/mpp_util_sma.inc index c8aebcd291..addfd6b3db 100644 --- a/src/shared/mpp/include/mpp_util_sma.inc +++ b/src/shared/mpp/include/mpp_util_sma.inc @@ -1,6 +1,6 @@ ! -*-f90-*- -! $Id: mpp_util_sma.inc,v 19.0 2012/01/06 22:05:21 fms Exp $ +! $Id: mpp_util_sma.inc,v 20.0 2013/12/14 00:27:41 fms Exp $ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! @@ -13,7 +13,7 @@ subroutine mpp_error_basic( errortype, errormsg ) !uses ABORT and FLUSH calls, may need to use cpp to rename integer, intent(in) :: errortype character(len=*), intent(in), optional :: errormsg - character(len=256) :: text + character(len=512) :: text logical :: opened integer :: istat, errunit, outunit diff --git a/src/shared/mpp/include/mpp_write_2Ddecomp.h b/src/shared/mpp/include/mpp_write_2Ddecomp.h index 4b138c5ddd..08bf7777c6 100644 --- a/src/shared/mpp/include/mpp_write_2Ddecomp.h +++ b/src/shared/mpp/include/mpp_write_2Ddecomp.h @@ -73,11 +73,13 @@ else allocate( gdata(1,1,1)) endif - if(PRESENT(default_data)) gdata = default_data if(global_field_on_root_pe) then - call mpp_global_field( domain, data, gdata, position = position, flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY) + call mpp_global_field( domain, data, gdata, position = position, & + flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY, & + default_data=default_data) else - call mpp_global_field( domain, data, gdata, position = position) + call mpp_global_field( domain, data, gdata, position = position, & + default_data=default_data) endif !all non-0 PEs have passed their data to PE 0 and may now exit if(mpp_file(unit)%write_on_this_pe ) then @@ -99,11 +101,13 @@ else allocate( gdata(1,1,1)) endif - if(PRESENT(default_data)) gdata = default_data if(global_field_on_root_pe) then - call mpp_global_field( io_domain, data, gdata, position = position, flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY) + call mpp_global_field( io_domain, data, gdata, position = position, & + flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY, & + default_data=default_data) else - call mpp_global_field( io_domain, data, gdata, position = position) + call mpp_global_field( io_domain, data, gdata, position = position, & + default_data=default_data) endif io_domain => NULL() if(mpp_file(unit)%write_on_this_pe ) then @@ -126,7 +130,7 @@ return end subroutine MPP_WRITE_2DDECOMP_3D_ - subroutine MPP_WRITE_2DDECOMP_4D_( unit, field, domain, data, tstamp, tile_count) + subroutine MPP_WRITE_2DDECOMP_4D_( unit, field, domain, data, tstamp, tile_count, default_data) !mpp_write writes which has the domain decomposition integer, intent(in) :: unit type(fieldtype), intent(in) :: field @@ -134,6 +138,7 @@ MPP_TYPE_, intent(inout) :: data(:,:,:,:) real, intent(in), optional :: tstamp integer, intent(in), optional :: tile_count + MPP_TYPE_, intent(in), optional :: default_data !cdata is used to store compute domain as contiguous data !gdata is used to globalize data for multi-PE single-threaded I/O @@ -184,9 +189,12 @@ allocate( gdata(1,1,1,1)) endif if(global_field_on_root_pe) then - call mpp_global_field( domain, data, gdata, position = position, flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY) + call mpp_global_field( domain, data, gdata, position = position, & + flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY, & + default_data=default_data) else - call mpp_global_field( domain, data, gdata, position = position) + call mpp_global_field( domain, data, gdata, position = position, & + default_data=default_data) endif !all non-0 PEs have passed their data to PE 0 and may now exit if(mpp_file(unit)%write_on_this_pe ) then @@ -196,7 +204,7 @@ end if else if(mpp_file(unit)%io_domain_exist ) then if( halos_are_global )then - call mpp_update_domains( data, domain, position = position ) + if(npes .GT. 1) call mpp_update_domains( data, domain, position = position ) if(mpp_file(unit)%write_on_this_pe ) then call write_record( unit, field, size(data(:,:,:,:)), data, tstamp) endif @@ -209,9 +217,12 @@ allocate( gdata(1,1,1,1)) endif if(global_field_on_root_pe) then - call mpp_global_field( io_domain, data, gdata, position = position, flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY) + call mpp_global_field( io_domain, data, gdata, position = position, & + flags=XUPDATE+YUPDATE+GLOBAL_ROOT_ONLY, & + default_data=default_data) else - call mpp_global_field( io_domain, data, gdata, position = position) + call mpp_global_field( io_domain, data, gdata, position = position, & + default_data=default_data) endif io_domain => NULL() if(mpp_file(unit)%write_on_this_pe ) then diff --git a/src/shared/mpp/mpp.F90 b/src/shared/mpp/mpp.F90 index 7c9ff7e959..486667d0bf 100644 --- a/src/shared/mpp/mpp.F90 +++ b/src/shared/mpp/mpp.F90 @@ -206,9 +206,11 @@ module mpp_mod public :: stdin, stdout, stderr, stdlog, lowercase, uppercase, mpp_error, mpp_error_state public :: mpp_set_warn_level, mpp_sync, mpp_sync_self, mpp_set_stack_size, mpp_pe public :: mpp_node, mpp_npes, mpp_root_pe, mpp_set_root_pe, mpp_declare_pelist - public :: mpp_get_current_pelist, mpp_set_current_pelist, mpp_clock_begin, mpp_clock_end + public :: mpp_get_current_pelist, mpp_set_current_pelist, mpp_get_current_pelist_name public :: mpp_clock_id, mpp_clock_set_grain, mpp_record_timing_data, get_unit - public :: read_ascii_file + public :: read_ascii_file, read_input_nml, mpp_clock_begin, mpp_clock_end + public :: get_ascii_file_num_lines + public :: mpp_record_time_start, mpp_record_time_end !--- public interface from mpp_comm.h ------------------------------ public :: mpp_chksum, mpp_max, mpp_min, mpp_sum, mpp_transmit, mpp_send, mpp_recv @@ -1173,25 +1175,27 @@ module mpp_mod integer :: get_len_nocomm = 0 ! needed for mpp_transmit_nocomm.h !*********************************************************************** -! variables needed for include/read_input_nml.inc +! variables needed for subroutine read_input_nml (include/mpp_util.inc) ! ! parameter defining length of character variables integer, parameter :: INPUT_STR_LENGTH = 256 ! public variable needed for reading input.nml from an internal file character(len=INPUT_STR_LENGTH), dimension(:), allocatable, public :: input_nml_file + logical :: read_ascii_file_on = .FALSE. !*********************************************************************** character(len=128), public :: version= & '$Id mpp.F90 $' character(len=128), public :: tagname= & - '$Name: siena_201207 $' + '$Name: tikal $' integer, parameter :: MAX_REQUEST_MIN = 10000 integer :: request_multiply = 20 logical :: etc_unit_is_stderr = .false. integer :: max_request = 0 - namelist /mpp_nml/ etc_unit_is_stderr, request_multiply + logical :: sync_all_clocks = .false. + namelist /mpp_nml/ etc_unit_is_stderr, request_multiply, mpp_record_timing_data, sync_all_clocks contains #include diff --git a/src/shared/mpp/mpp.html b/src/shared/mpp/mpp.html deleted file mode 100644 index d388254395..0000000000 --- a/src/shared/mpp/mpp.html +++ /dev/null @@ -1,791 +0,0 @@ - - - -Module mpp_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                -

                                                Module mpp_mod

                                                - - -
                                                -Contact:  - V. Balaji - -
                                                -Reviewers:  -
                                                -Change History: WebCVS Log -
                                                -
                                                -
                                                - - -
                                                -

                                                OVERVIEW

                                                - -

                                                - -mpp_mod, is a set of simple calls to provide a uniform interface - to different message-passing libraries. It currently can be - implemented either in the SGI/Cray native SHMEM library or in the MPI - standard. Other libraries (e.g MPI-2, Co-Array Fortran) can be - incorporated as the need arises. -

                                                - - - -
                                                - The data transfer between a processor and its own memory is based - on load and store operations upon - memory. Shared-memory systems (including distributed shared memory - systems) have a single address space and any processor can acquire any - data within the memory by load and - store. The situation is different for distributed - parallel systems. Specialized MPP systems such as the T3E can simulate - shared-memory by direct data acquisition from remote memory. But if - the parallel code is distributed across a cluster, or across the Net, - messages must be sent and received using the protocols for - long-distance communication, such as TCP/IP. This requires a - ``handshaking'' between nodes of the distributed system. One can think - of the two different methods as involving puts or - gets (e.g the SHMEM library), or in the case of - negotiated communication (e.g MPI), sends and - recvs. - - The difference between SHMEM and MPI is that SHMEM uses one-sided - communication, which can have very low-latency high-bandwidth - implementations on tightly coupled systems. MPI is a standard - developed for distributed computing across loosely-coupled systems, - and therefore incurs a software penalty for negotiating the - communication. It is however an open industry standard whereas SHMEM - is a proprietary interface. Besides, the puts or - gets on which it is based cannot currently be implemented in - a cluster environment (there are recent announcements from Compaq that - occasion hope). - - The message-passing requirements of climate and weather codes can be - reduced to a fairly simple minimal set, which is easily implemented in - any message-passing API. mpp_mod provides this API. - - Features of mpp_mod include: - - 1) Simple, minimal API, with free access to underlying API for - more complicated stuff.
                                                - 2) Design toward typical use in climate/weather CFD codes.
                                                - 3) Performance to be not significantly lower than any native API. - - This module is used to develop higher-level calls for domain decomposition and parallel I/O. - - Parallel computing is initially daunting, but it soon becomes - second nature, much the way many of us can now write vector code - without much effort. The key insight required while reading and - writing parallel code is in arriving at a mental grasp of several - independent parallel execution streams through the same code (the SPMD - model). Each variable you examine may have different values for each - stream, the processor ID being an obvious example. Subroutines and - function calls are particularly subtle, since it is not always obvious - from looking at a call what synchronization between execution streams - it implies. An example of erroneous code would be a global barrier - call (see mpp_sync below) placed - within a code block that not all PEs will execute, e.g: - -
                                                   if( pe.EQ.0 )call mpp_sync()
                                                - - Here only PE 0 reaches the barrier, where it will wait - indefinitely. While this is a particularly egregious example to - illustrate the coding flaw, more subtle versions of the same are - among the most common errors in parallel code. - - It is therefore important to be conscious of the context of a - subroutine or function call, and the implied synchronization. There - are certain calls here (e.g mpp_declare_pelist, mpp_init, - mpp_malloc, mpp_set_stack_size) which must be called by all - PEs. There are others which must be called by a subset of PEs (here - called a pelist) which must be called by all the PEs in the - pelist (e.g mpp_max, mpp_sum, mpp_sync). Still - others imply no synchronization at all. I will make every effort to - highlight the context of each call in the MPP modules, so that the - implicit synchronization is spelt out. - - For performance it is necessary to keep synchronization as limited - as the algorithm being implemented will allow. For instance, a single - message between two PEs should only imply synchronization across the - PEs in question. A global synchronization (or barrier) - is likely to be slow, and is best avoided. But codes first - parallelized on a Cray T3E tend to have many global syncs, as very - fast barriers were implemented there in hardware. - - Another reason to use pelists is to run a single program in MPMD - mode, where different PE subsets work on different portions of the - code. A typical example is to assign an ocean model and atmosphere - model to different PE subsets, and couple them concurrently instead of - running them serially. The MPP module provides the notion of a - current pelist, which is set when a group of PEs branch off - into a subset. Subsequent calls that omit the pelist optional - argument (seen below in many of the individual calls) assume that the - implied synchronization is across the current pelist. The calls - mpp_root_pe and mpp_npes also return the values - appropriate to the current pelist. The mpp_set_current_pelist - call is provided to set the current pelist. -
                                                -
                                                - - -
                                                -

                                                OTHER MODULES USED

                                                - -
                                                -
                                                  shmem_interface
                                                mpi
                                                mpp_parameter_mod
                                                mpp_data_mod
                                                -
                                                - - - -
                                                -

                                                PUBLIC INTERFACE

                                                -
                                                - F90 is a strictly-typed language, and the syntax pass of the - compiler requires matching of type, kind and rank (TKR). Most calls - listed here use a generic type, shown here as MPP_TYPE_. This - is resolved in the pre-processor stage to any of a variety of - types. In general the MPP operations work on 4-byte and 8-byte - variants of integer, real, complex, logical variables, of - rank 0 to 5, leading to 48 specific module procedures under the same - generic interface. Any of the variables below shown as - MPP_TYPE_ is treated in this way. -
                                                -
                                                -mpp_error:
                                                -
                                                - Error handler. -
                                                -
                                                -mpp_init:
                                                -
                                                - Initialize mpp_mod. -
                                                -
                                                -mpp_exit:
                                                -
                                                - Exit mpp_mod. -
                                                -
                                                -mpp_malloc:
                                                -
                                                - Symmetric memory allocation. -
                                                -
                                                -mpp_set_stack_size:
                                                -
                                                - Allocate module internal workspace. -
                                                -
                                                -mpp_max:
                                                -
                                                - Reduction operations. -
                                                -
                                                -mpp_sum:
                                                -
                                                - Reduction operation. -
                                                -
                                                -mpp_gather:
                                                -
                                                - gather information onto root pe. -
                                                -
                                                -mpp_transmit:
                                                -
                                                - Basic message-passing call. -
                                                -
                                                -mpp_broadcast:
                                                -
                                                - Parallel broadcasts. -
                                                -
                                                -mpp_chksum:
                                                -
                                                - Parallel checksums. -
                                                -
                                                -
                                                -
                                                - - -
                                                -

                                                PUBLIC ROUTINES

                                                - -
                                                  -
                                                1. - -

                                                  mpp_error

                                                  -
                                                  -call mpp_error ( errortype, routine, errormsg )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - It is strongly recommended that all error exits pass through - mpp_error to assure the program fails cleanly. An individual - PE encountering a STOP statement, for instance, can cause the - program to hang. The use of the STOP statement is strongly - discouraged. - - Calling mpp_error with no arguments produces an immediate error - exit, i.e: -
                                                      call mpp_error
                                                  -    call mpp_error(FATAL)
                                                  - are equivalent. - - The argument order -
                                                      call mpp_error( routine, errormsg, errortype )
                                                  - is also provided to support legacy code. In this version of the - call, none of the arguments may be omitted. - - The behaviour of mpp_error for a WARNING can be - controlled with an additional call mpp_set_warn_level. -
                                                      call mpp_set_warn_level(ERROR)
                                                  - causes mpp_error to treat WARNING - exactly like FATAL. -
                                                      call mpp_set_warn_level(WARNING)
                                                  - resets to the default behaviour described above. - - mpp_error also has an internal error state which - maintains knowledge of whether a warning has been issued. This can be - used at startup in a subroutine that checks if the model has been - properly configured. You can generate a series of warnings using - mpp_error, and then check at the end if any warnings has been - issued using the function mpp_error_state(). If the value of - this is WARNING, at least one warning has been issued, and - the user can take appropriate action: - -
                                                      if( ... )call mpp_error( WARNING, '...' )
                                                  -    if( ... )call mpp_error( WARNING, '...' )
                                                  -    if( ... )call mpp_error( WARNING, '...' )
                                                  -    ...
                                                  -    if( mpp_error_state().EQ.WARNING )call mpp_error( FATAL, '...' )
                                                  - -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - -
                                                  errortype    - One of NOTE, WARNING or FATAL - (these definitions are acquired by use association). - NOTE writes errormsg to STDOUT. - WARNING writes errormsg to STDERR. - FATAL writes errormsg to STDERR, - and induces a clean error exit with a call stack traceback. -
                                                  -
                                                  -
                                                  -
                                                  -
                                                2. -
                                                3. - -

                                                  mpp_init

                                                  -
                                                  -call mpp_init ( flags )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - Called to initialize the mpp_mod package. It is recommended - that this call be the first executed line in your program. It sets the - number of PEs assigned to this run (acquired from the command line, or - through the environment variable NPES), and associates an ID - number to each PE. These can be accessed by calling mpp_npes and mpp_pe. -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - -
                                                  flags    - flags can be set to MPP_VERBOSE to - have mpp_mod keep you informed of what it's up to. -
                                                     [integer]
                                                  -
                                                  -
                                                  -
                                                  -
                                                4. -
                                                5. - -

                                                  mpp_exit

                                                  -
                                                  -call mpp_exit ()
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - Called at the end of the run, or to re-initialize mpp_mod, - should you require that for some odd reason. - - This call implies synchronization across all PEs. -
                                                  -
                                                  -
                                                  -
                                                  -
                                                6. -
                                                7. - -

                                                  mpp_malloc

                                                  -
                                                  -call mpp_malloc ( ptr, newlen, len )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - This routine is used on SGI systems when mpp_mod is - invoked in the SHMEM library. It ensures that dynamically allocated - memory can be used with shmem_get and - shmem_put. This is called symmetric - allocation and is described in the - intro_shmem man page. ptr is a Cray - pointer (see the section on portability). The operation can be expensive - (since it requires a global barrier). We therefore attempt to re-use - existing allocation whenever possible. Therefore len - and ptr must have the SAVE attribute - in the calling routine, and retain the information about the last call - to mpp_malloc. Additional memory is symmetrically - allocated if and only if newlen exceeds - len. - - This is never required on Cray PVP or MPP systems. While the T3E - manpages do talk about symmetric allocation, mpp_mod - is coded to remove this restriction. - - It is never required if mpp_mod is invoked in MPI. - - This call implies synchronization across all PEs. -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - - - - - - - -
                                                  ptr    - a cray pointer, points to a dummy argument in this routine. -
                                                  newlen    - the required allocation length for the pointer ptr -
                                                     [integer]
                                                  len    - the current allocation (0 if unallocated). -
                                                     [integer]
                                                  -
                                                  -
                                                  -
                                                  -
                                                8. -
                                                9. - -

                                                  mpp_set_stack_size

                                                  -
                                                  -call mpp_set_stack_size (n)
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - -mpp_mod maintains a private internal array called - mpp_stack for private workspace. This call sets the length, - in words, of this array. - - The mpp_init call sets this - workspace length to a default of 32768, and this call may be used if a - longer workspace is needed. - - This call implies synchronization across all PEs. - - This workspace is symmetrically allocated, as required for - efficient communication on SGI and Cray MPP systems. Since symmetric - allocation must be performed by all PEs in a job, this call - must also be called by all PEs, using the same value of - n. Calling mpp_set_stack_size from a subset of PEs, - or with unequal argument n, may cause the program to hang. - - If any MPP call using mpp_stack overflows the declared - stack array, the program will abort with a message specifying the - stack length that is required. Many users wonder why, if the required - stack length can be computed, it cannot also be specified at that - point. This cannot be automated because there is no way for the - program to know if all PEs are present at that call, and with equal - values of n. The program must be rerun by the user with the - correct argument to mpp_set_stack_size, called at an - appropriate point in the code where all PEs are known to be present. -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - -
                                                  n    -
                                                     [integer]
                                                  -
                                                  -
                                                  -
                                                  -
                                                10. -
                                                11. - -

                                                  mpp_max

                                                  -
                                                  -call mpp_max ( a, pelist )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - Find the max of scalar a the PEs in pelist - result is also automatically broadcast to all PEs -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - - - - -
                                                  a    - real or integer, of 4-byte of 8-byte kind. -
                                                  pelist    - If pelist is omitted, the context is assumed to be the - current pelist. This call implies synchronization across the PEs in - pelist, or the current pelist if pelist is absent. -
                                                  -
                                                  -
                                                  -
                                                  -
                                                12. -
                                                13. - -

                                                  mpp_sum

                                                  -
                                                  -call mpp_sum ( a, length, pelist )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - -MPP_TYPE_ corresponds to any 4-byte and 8-byte variant of - integer, real, complex variables, of rank 0 or 1. A - contiguous block from a multi-dimensional array may be passed by its - starting address and its length, as in f77. - - Library reduction operators are not required or guaranteed to be - bit-reproducible. In any case, changing the processor count changes - the data layout, and thus very likely the order of operations. For - bit-reproducible sums of distributed arrays, consider using the - mpp_global_sum routine provided by the mpp_domains module. - - The bit_reproducible flag provided in earlier versions of - this routine has been removed. - - - If pelist is omitted, the context is assumed to be the - current pelist. This call implies synchronization across the PEs in - pelist, or the current pelist if pelist is absent. -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - - - - -
                                                  length   
                                                  pelist   
                                                  -
                                                  -
                                                  -
                                                  -INPUT/OUTPUT -
                                                  -
                                                  - - - - -
                                                  a   
                                                  -
                                                  -
                                                  -
                                                  -
                                                14. -
                                                15. - -

                                                  mpp_gather

                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  -
                                                  -
                                                  -
                                                  -
                                                16. -
                                                17. - -

                                                  mpp_transmit

                                                  -
                                                  -call mpp_transmit ( put_data, put_len, put_pe, get_data, get_len, get_pe )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - -MPP_TYPE_ corresponds to any 4-byte and 8-byte variant of - integer, real, complex, logical variables, of rank 0 or 1. A - contiguous block from a multi-dimensional array may be passed by its - starting address and its length, as in f77. - - mpp_transmit is currently implemented as asynchronous - outward transmission and synchronous inward transmission. This follows - the behaviour of shmem_put and shmem_get. In MPI, it - is implemented as mpi_isend and mpi_recv. For most - applications, transmissions occur in pairs, and are here accomplished - in a single call. - - The special PE designations NULL_PE, - ANY_PE and ALL_PES are provided by use - association. - - NULL_PE: is used to disable one of the pair of - transmissions.
                                                  - -ANY_PE: is used for unspecific remote - destination. (Please note that put_pe=ANY_PE has no meaning - in the MPI context, though it is available in the SHMEM invocation. If - portability is a concern, it is best avoided).
                                                  - -ALL_PES: is used for broadcast operations. - - It is recommended that mpp_broadcast be used for - broadcasts. - - The following example illustrates the use of - NULL_PE and ALL_PES: - -
                                                      real, dimension(n) :: a
                                                  -    if( pe.EQ.0 )then
                                                  -        do p = 1,npes-1
                                                  -           call mpp_transmit( a, n, p, a, n, NULL_PE )
                                                  -        end do
                                                  -    else
                                                  -        call mpp_transmit( a, n, NULL_PE, a, n, 0 )
                                                  -    end if
                                                  -    
                                                  -    call mpp_transmit( a, n, ALL_PES, a, n, 0 )
                                                  - - The do loop and the broadcast operation above are equivalent. - - Two overloaded calls mpp_send and - mpp_recv have also been - provided. mpp_send calls mpp_transmit - with get_pe=NULL_PE. mpp_recv calls - mpp_transmit with put_pe=NULL_PE. Thus - the do loop above could be written more succinctly: - -
                                                      if( pe.EQ.0 )then
                                                  -        do p = 1,npes-1
                                                  -           call mpp_send( a, n, p )
                                                  -        end do
                                                  -    else
                                                  -        call mpp_recv( a, n, 0 )
                                                  -    end if
                                                  - -
                                                  -
                                                  -
                                                  -
                                                  -
                                                18. -
                                                19. - -

                                                  mpp_broadcast

                                                  -
                                                  -call mpp_broadcast ( data, length, from_pe, pelist )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - The mpp_broadcast call has been added because the original - syntax (using ALL_PES in mpp_transmit) did not - support a broadcast across a pelist. - - MPP_TYPE_ corresponds to any 4-byte and 8-byte variant of - integer, real, complex, logical variables, of rank 0 or 1. A - contiguous block from a multi-dimensional array may be passed by its - starting address and its length, as in f77. - - Global broadcasts through the ALL_PES argument to mpp_transmit are still provided for - backward-compatibility. - - If pelist is omitted, the context is assumed to be the - current pelist. from_pe must belong to the current - pelist. This call implies synchronization across the PEs in - pelist, or the current pelist if pelist is absent. -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - - - - - - - -
                                                  length   
                                                  from_pe   
                                                  pelist   
                                                  -
                                                  -
                                                  -
                                                  -INPUT/OUTPUT -
                                                  -
                                                  - - - - -
                                                  data(*)   
                                                  -
                                                  -
                                                  -
                                                  -
                                                20. -
                                                21. - -

                                                  mpp_chksum

                                                  -
                                                   
                                                  -mpp_chksum ( var, pelist )
                                                  -
                                                  -
                                                  -DESCRIPTION -
                                                  -
                                                  - -mpp_chksum is a parallel checksum routine that returns an - identical answer for the same array irrespective of how it has been - partitioned across processors. LONG_KINDis the KIND - parameter corresponding to long integers (see discussion on - OS-dependent preprocessor directives) defined in - the header file fms_platform.h. MPP_TYPE_ corresponds to any - 4-byte and 8-byte variant of integer, real, complex, logical - variables, of rank 0 to 5. - - Integer checksums on FP data use the F90 TRANSFER() - intrinsic. - - by this function, and is no longer being actively maintained. This - provides identical results on a single-processor job, and to perform - serial checksums on a single processor of a parallel job, you only - need to use the optional pelist argument. -
                                                       use mpp_mod
                                                  -     integer :: pe, chksum
                                                  -     real :: a(:)
                                                  -     pe = mpp_pe()
                                                  -     chksum = mpp_chksum( a, (/pe/) )
                                                  - - The additional functionality of mpp_chksum over - serial checksums is to compute the checksum across the PEs in - pelist. The answer is guaranteed to be the same for - the same distributed array irrespective of how it has been - partitioned. - - If pelist is omitted, the context is assumed to be the - current pelist. This call implies synchronization across the PEs in - pelist, or the current pelist if pelist is absent. -
                                                  -
                                                  -
                                                  -
                                                  -INPUT -
                                                  -
                                                  - - - - - - - -
                                                  pelist   
                                                  var   
                                                  -
                                                  -
                                                  -
                                                  -
                                                22. -
                                                - - - - - - -
                                                -
                                                -top -
                                                - - diff --git a/src/shared/mpp/mpp_data.F90 b/src/shared/mpp/mpp_data.F90 index 91c5e52d0c..cb3655c07c 100644 --- a/src/shared/mpp/mpp_data.F90 +++ b/src/shared/mpp/mpp_data.F90 @@ -13,7 +13,7 @@ module mpp_data_mod character(len=128), public :: version= & '$Id mpp_data.F90 $' character(len=128), public :: tagname= & - '$Name: siena_201207 $' + '$Name: tikal $' #if defined(use_libSMA) || defined(use_MPI_SMA) #include diff --git a/src/shared/mpp/mpp_data.html b/src/shared/mpp/mpp_data.html deleted file mode 100644 index af65d7936a..0000000000 --- a/src/shared/mpp/mpp_data.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module mpp_data_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                -

                                                Module mpp_data_mod

                                                - - -
                                                -Contact:  -
                                                -Reviewers:  -
                                                -Change History: WebCVS Log -
                                                -
                                                -
                                                - - -
                                                -

                                                OVERVIEW

                                                - -

                                                - - - -
                                                -
                                                - - -
                                                -

                                                OTHER MODULES USED

                                                - -
                                                -
                                                              mpi
                                                mpp_parameter_mod
                                                -
                                                - - - -
                                                -

                                                PUBLIC INTERFACE

                                                -
                                                -
                                                -
                                                -
                                                - - -
                                                -

                                                PUBLIC ROUTINES

                                                - -
                                                  - - - - - - -
                                                  -
                                                  -top -
                                                  - - diff --git a/src/shared/mpp/mpp_domains.F90 b/src/shared/mpp/mpp_domains.F90 index 6346dee385..b3f063d3b6 100644 --- a/src/shared/mpp/mpp_domains.F90 +++ b/src/shared/mpp/mpp_domains.F90 @@ -174,7 +174,7 @@ module mpp_domains_mod public :: mpp_get_tile_id, mpp_get_domain_extents, mpp_get_current_ntile, mpp_get_ntile_count public :: mpp_get_refine_overlap_number, mpp_get_mosaic_refine_overlap public :: mpp_get_tile_list - public :: mpp_get_tile_npes, mpp_get_domain_root_pe + public :: mpp_get_tile_npes, mpp_get_domain_root_pe, mpp_get_tile_pelist, mpp_get_tile_compute_domains public :: mpp_get_num_overlap, mpp_get_overlap public :: mpp_get_io_domain, mpp_get_domain_pe, mpp_get_domain_tile_root_pe public :: mpp_get_domain_name, mpp_get_io_domain_layout @@ -241,6 +241,8 @@ module mpp_domains_mod private integer :: count = 0 ! number of ovrelapping integer :: pe + integer :: start_pos ! start position in the buffer + integer :: totsize ! all message size integer , pointer :: msgsize(:) => NULL() ! overlapping msgsize to be sent or received integer, pointer :: tileMe(:) => NULL() ! my tile id for this overlap integer, pointer :: tileNbr(:) => NULL() ! neighbor tile id for this overlap @@ -264,10 +266,11 @@ module mpp_domains_mod integer :: whalo, ehalo, shalo, nhalo ! halo size integer :: xbegin, xend, ybegin, yend integer :: nsend, nrecv + integer :: sendsize, recvsize type(overlap_type), pointer :: send(:) => NULL() type(overlap_type), pointer :: recv(:) => NULL() type(refineSpec), pointer :: rSpec(:)=> NULL() - type(overlapSpec), pointer :: next => NULL() + type(overlapSpec), pointer :: next end type overlapSpec type tile_type @@ -361,7 +364,7 @@ module mpp_domains_mod integer :: extra_halo type(overlap_type), pointer :: send(:) => NULL() type(overlap_type), pointer :: recv(:) => NULL() - type(nestSpec), pointer :: next => NULL() + type(nestSpec), pointer :: next end type nestSpec @@ -457,6 +460,8 @@ module mpp_domains_mod integer, dimension(MAX_REQUEST) :: request_recv integer, dimension(MAX_REQUEST) :: size_recv integer, dimension(MAX_REQUEST) :: type_recv + integer, dimension(MAX_REQUEST) :: buffer_pos_send + integer, dimension(MAX_REQUEST) :: buffer_pos_recv integer(LONG_KIND) :: field_addrs(MAX_DOMAIN_FIELDS) integer(LONG_KIND) :: field_addrs2(MAX_DOMAIN_FIELDS) integer :: nfields @@ -533,8 +538,8 @@ module mpp_domains_mod logical :: domain_clocks_on=.FALSE. integer :: send_clock=0, recv_clock=0, unpk_clock=0 integer :: wait_clock=0, pack_clock=0 - integer :: send_clock_nonblock=0, recv_clock_nonblock=0, unpk_clock_nonblock=0 - integer :: wait_clock_nonblock=0, pack_clock_nonblock=0 + integer :: send_pack_clock_nonblock=0, recv_clock_nonblock=0, unpk_clock_nonblock=0 + integer :: wait_clock_nonblock=0 integer :: nest_send_clock=0, nest_recv_clock=0, nest_unpk_clock=0 integer :: nest_wait_clock=0, nest_pack_clock=0 @@ -1711,21 +1716,21 @@ module mpp_domains_mod interface mpp_get_boundary module procedure mpp_get_boundary_r8_2d module procedure mpp_get_boundary_r8_3d - module procedure mpp_get_boundary_r8_4d - module procedure mpp_get_boundary_r8_5d +! module procedure mpp_get_boundary_r8_4d +! module procedure mpp_get_boundary_r8_5d module procedure mpp_get_boundary_r8_2dv module procedure mpp_get_boundary_r8_3dv - module procedure mpp_get_boundary_r8_4dv - module procedure mpp_get_boundary_r8_5dv +! module procedure mpp_get_boundary_r8_4dv +! module procedure mpp_get_boundary_r8_5dv #ifdef OVERLOAD_R4 module procedure mpp_get_boundary_r4_2d module procedure mpp_get_boundary_r4_3d - module procedure mpp_get_boundary_r4_4d - module procedure mpp_get_boundary_r4_5d +! module procedure mpp_get_boundary_r4_4d +! module procedure mpp_get_boundary_r4_5d module procedure mpp_get_boundary_r4_2dv module procedure mpp_get_boundary_r4_3dv - module procedure mpp_get_boundary_r4_4dv - module procedure mpp_get_boundary_r4_5dv +! module procedure mpp_get_boundary_r4_4dv +! module procedure mpp_get_boundary_r4_5dv #endif end interface @@ -2458,9 +2463,9 @@ module mpp_domains_mod !--- version information variables character(len=128), public :: version= & - '$Id: mpp_domains.F90,v 19.0.2.1.2.3.2.1 2012/05/15 19:13:31 z1l Exp $' + '$Id: mpp_domains.F90,v 20.0 2013/12/14 00:22:42 fms Exp $' character(len=128), public :: tagname= & - '$Name: siena_201207 $' + '$Name: tikal $' contains diff --git a/src/shared/mpp/mpp_domains.html b/src/shared/mpp/mpp_domains.html deleted file mode 100644 index c99bd7db4e..0000000000 --- a/src/shared/mpp/mpp_domains.html +++ /dev/null @@ -1,2033 +0,0 @@ - - - -Module mpp_domains_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                                  -

                                                  Module mpp_domains_mod

                                                  - - -
                                                  -Contact:  - V. Balaji - ,  - - Zhi Liang - -
                                                  -Reviewers:  -
                                                  -Change History: WebCVS Log -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  OVERVIEW

                                                  - -

                                                  - -mpp_domains_mod is a set of simple calls for domain - decomposition and domain updates on rectilinear grids. It requires the - module mpp_mod, upon which it is built. -

                                                  - - - -
                                                  - Scalable implementations of finite-difference codes are generally - based on decomposing the model domain into subdomains that are - distributed among processors. These domains will then be obliged to - exchange data at their boundaries if data dependencies are merely - nearest-neighbour, or may need to acquire information from the global - domain if there are extended data dependencies, as in the spectral - transform. The domain decomposition is a key operation in the - development of parallel codes. - - mpp_domains_mod provides a domain decomposition and domain - update API for rectilinear grids, built on top of the mpp_mod API for message passing. Features - of mpp_domains_mod include: - - Simple, minimal API, with free access to underlying API for more complicated stuff. - - Design toward typical use in climate/weather CFD codes. - -

                                                  Domains

                                                  - - I have assumed that domain decomposition will mainly be in 2 - horizontal dimensions, which will in general be the two - fastest-varying indices. There is a separate implementation of 1D - decomposition on the fastest-varying index, and 1D decomposition on - the second index, treated as a special case of 2D decomposition, is - also possible. We define domain as the grid associated with a task. - We define the compute domain as the set of gridpoints that are - computed by a task, and the data domain as the set of points - that are required by the task for the calculation. There can in - general be more than 1 task per PE, though often - the number of domains is the same as the processor count. We define - the global domain as the global computational domain of the - entire model (i.e, the same as the computational domain if run on a - single processor). 2D domains are defined using a derived type domain2D, - constructed as follows (see comments in code for more details): - -
                                                       type, public :: domain_axis_spec
                                                  -        private
                                                  -        integer :: begin, end, size, max_size
                                                  -        logical :: is_global
                                                  -     end type domain_axis_spec
                                                  -     type, public :: domain1D
                                                  -        private
                                                  -        type(domain_axis_spec) :: compute, data, global, active
                                                  -        logical :: mustputb, mustgetb, mustputf, mustgetf, folded
                                                  -        type(domain1D), pointer, dimension(:) :: list
                                                  -        integer :: pe              !PE to which this domain is assigned
                                                  -        integer :: pos
                                                  -     end type domain1D
                                                  -domaintypes of higher rank can be constructed from type domain1D
                                                  -typically we only need 1 and 2D, but could need higher (e.g 3D LES)
                                                  -some elements are repeated below if they are needed once per domain
                                                  -     type, public :: domain2D
                                                  -        private
                                                  -        type(domain1D) :: x
                                                  -        type(domain1D) :: y
                                                  -        type(domain2D), pointer, dimension(:) :: list
                                                  -        integer :: pe              !PE to which this domain is assigned
                                                  -        integer :: pos
                                                  -     end type domain2D
                                                  -     type(domain1D), public :: NULL_DOMAIN1D
                                                  -     type(domain2D), public :: NULL_DOMAIN2D
                                                  - The domain2D type contains all the necessary information to - define the global, compute and data domains of each task, as well as the PE - associated with the task. The PEs from which remote data may be - acquired to update the data domain are also contained in a linked list - of neighbours. -
                                                  -
                                                  - - -
                                                  -

                                                  OTHER MODULES USED

                                                  - -
                                                  -
                                                                mpi
                                                  mpp_parameter_mod
                                                  mpp_data_mod
                                                  mpp_mod
                                                  mpp_memutils_mod
                                                  mpp_pset_mod
                                                  -
                                                  - - - -
                                                  -

                                                  PUBLIC INTERFACE

                                                  -
                                                  -
                                                  -
                                                  -mpp_define_layout:
                                                  -
                                                  - Retrieve layout associated with a domain decomposition. -
                                                  -
                                                  -mpp_define_domains:
                                                  -
                                                  - Set up a domain decomposition. -
                                                  -
                                                  -mpp_modify_domain:
                                                  -
                                                  - modifies the extents (compute, data and global) of domain -
                                                  -
                                                  -mpp_update_domains:
                                                  -
                                                  - Halo updates. -
                                                  -
                                                  -mpp_start_update_domains/mpp_complete_update_domains:
                                                  -
                                                  - Interface to start halo updates. -
                                                  -
                                                  -mpp_define_nest_domains:
                                                  -
                                                  - Set up a domain to pass data between coarse and fine grid of nested model. -
                                                  -
                                                  -mpp_get_C2F_index:
                                                  -
                                                  - Get the index of the data passed from coarse grid to fine grid. -
                                                  -
                                                  -mpp_get_F2C_index:
                                                  -
                                                  - Get the index of the data passed from fine grid to coarse grid. -
                                                  -
                                                  -mpp_update_nest_fine:
                                                  -
                                                  - Pass the data from coarse grid to fill the buffer to be ready to be interpolated - onto fine grid. -
                                                  -
                                                  -mpp_update_nest_coarse:
                                                  -
                                                  - Pass the data from fine grid to fill the buffer to be ready to be interpolated - onto coarse grid. -
                                                  -
                                                  -mpp_get_boundary:
                                                  -
                                                  - Get the boundary data for symmetric domain when the data is at C, E, or N-cell center -
                                                  -
                                                  -mpp_redistribute:
                                                  -
                                                  - Reorganization of distributed global arrays. -
                                                  -
                                                  -mpp_check_field:
                                                  -
                                                  - Parallel checking between two ensembles which run - on different set pes at the same time. -
                                                  -
                                                  -mpp_global_field:
                                                  -
                                                  - Fill in a global array from domain-decomposed arrays. -
                                                  -
                                                  -mpp_global_max:
                                                  -
                                                  - Global max/min of domain-decomposed arrays. -
                                                  -
                                                  -mpp_global_sum:
                                                  -
                                                  - Global sum of domain-decomposed arrays. -
                                                  -
                                                  -mpp_get_neighbor_pe:
                                                  -
                                                  - Retrieve PE number of a neighboring domain. -
                                                  -
                                                  -operator:
                                                  -
                                                  - Equality/inequality operators for domaintypes. -
                                                  -
                                                  -mpp_get_compute_domain:
                                                  -
                                                  - These routines retrieve the axis specifications associated with the compute domains. -
                                                  -
                                                  -mpp_get_compute_domains:
                                                  -
                                                  - Retrieve the entire array of compute domain extents associated with a decomposition. -
                                                  -
                                                  -mpp_get_data_domain:
                                                  -
                                                  - These routines retrieve the axis specifications associated with the data domains. -
                                                  -
                                                  -mpp_get_global_domain:
                                                  -
                                                  - These routines retrieve the axis specifications associated with the global domains. -
                                                  -
                                                  -mpp_get_memory_domain:
                                                  -
                                                  - These routines retrieve the axis specifications associated with the memory domains. -
                                                  -
                                                  -mpp_set_compute_domain:
                                                  -
                                                  - These routines set the axis specifications associated with the compute domains. -
                                                  -
                                                  -mpp_set_data_domain:
                                                  -
                                                  - These routines set the axis specifications associated with the data domains. -
                                                  -
                                                  -mpp_set_global_domain:
                                                  -
                                                  - These routines set the axis specifications associated with the global domains. -
                                                  -
                                                  -mpp_get_pelist:
                                                  -
                                                  - Retrieve list of PEs associated with a domain decomposition. -
                                                  -
                                                  -mpp_get_layout:
                                                  -
                                                  - Retrieve layout associated with a domain decomposition. -
                                                  -
                                                  -mpp_nullify_domain_list:
                                                  -
                                                  - nullify domain list. -
                                                  -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  PUBLIC ROUTINES

                                                  - -
                                                    -
                                                  1. - -

                                                    mpp_define_layout

                                                    -
                                                    -call mpp_define_layout ( global_indices, ndivs, layout )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Given a global 2D domain and the number of divisions in the - decomposition (ndivs: usually the PE count unless some - domains are masked) this calls returns a 2D domain layout. - - By default, mpp_define_layout will attempt to divide the - 2D index space into domains that maintain the aspect ratio of the - global domain. If this cannot be done, the algorithm favours domains - that are longer in x than y, a preference that could - improve vector performance. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - -
                                                    global_indices   
                                                    ndivs   
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - -
                                                    layout   
                                                    -
                                                    -
                                                    -
                                                    -
                                                  2. -
                                                  3. - -

                                                    mpp_define_domains

                                                    -
                                                    -call mpp_define_domains ( global_indices, ndivs, domain, & pelist, flags, halo, extent, maskmap )
                                                    -
                                                    -call mpp_define_domains ( global_indices, layout, domain, pelist, & xflags, yflags, xhalo, yhalo, & xextent, yextent, maskmap, name )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - There are two forms for the mpp_define_domains call. The 2D - version is generally to be used but is built by repeated calls to the - 1D version, also provided. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                    global_indices    - Defines the global domain. -
                                                    ndivs    - Is the number of domain divisions required. -
                                                    pelist    - List of PEs to which the domains are to be assigned. -
                                                    flags    - An optional flag to pass additional information - about the desired domain topology. Useful flags in a 1D decomposition - include GLOBAL_DATA_DOMAIN and - CYCLIC_GLOBAL_DOMAIN. Flags are integers: multiple flags may - be added together. The flag values are public parameters available by - use association. -
                                                    halo    - Width of the halo. -
                                                    extent    - Normally mpp_define_domains attempts - an even division of the global domain across ndivs - domains. The extent array can be used by the user to pass a - custom domain division. The extent array has ndivs - elements and holds the compute domain widths, which should add up to - cover the global domain exactly. -
                                                    maskmap    - Some divisions may be masked - (maskmap=.FALSE.) to exclude them from the computation (e.g - for ocean model domains that are all land). The maskmap array - is dimensioned ndivs and contains .TRUE. values for - any domain that must be included in the computation (default - all). The pelist array length should match the number of - domains included in the computation. -
                                                    layout   
                                                    xflags, yflags   
                                                    xhalo, yhalo   
                                                    xextent, yextent   
                                                    name   
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    domain    - Holds the resulting domain decomposition. -
                                                    -
                                                    -
                                                    -
                                                    -NOTE -
                                                    -
                                                    - For example: - -
                                                        call mpp_define_domains( (/1,100/), 10, domain, &
                                                    -         flags=GLOBAL_DATA_DOMAIN+CYCLIC_GLOBAL_DOMAIN, halo=2 )
                                                    - - defines 10 compute domains spanning the range [1,100] of the global - domain. The compute domains are non-overlapping blocks of 10. All the data - domains are global, and with a halo of 2 span the range [-1:102]. And - since the global domain has been declared to be cyclic, - domain(9)%next => domain(0) and domain(0)%prev => - domain(9). A field is allocated on the data domain, and computations proceed on - the compute domain. A call to mpp_update_domains would fill in - the values in the halo region: -
                                                        call mpp_get_data_domain( domain, isd, ied ) !returns -1 and 102
                                                    -    call mpp_get_compute_domain( domain, is, ie ) !returns (1,10) on PE 0 ...
                                                    -    allocate( a(isd:ied) )
                                                    -    do i = is,ie
                                                    -       a(i) = <perform computations>
                                                    -    end do
                                                    -    call mpp_update_domains( a, domain )
                                                    - The call to mpp_update_domains fills in the regions outside - the compute domain. Since the global domain is cyclic, the values at - i=(-1,0) are the same as at i=(99,100); and - i=(101,102) are the same as i=(1,2). - - The 2D version is just an extension of this syntax to two - dimensions. - - The 2D version of the above should generally be used in - codes, including 1D-decomposed ones, if there is a possibility of - future evolution toward 2D decomposition. The arguments are similar to - the 1D case, except that now we have optional arguments - flags, halo, extent and maskmap - along two axes. - - flags can now take an additional possible value to fold - one or more edges. This is done by using flags - FOLD_WEST_EDGE, FOLD_EAST_EDGE, - FOLD_SOUTH_EDGE or FOLD_NORTH_EDGE. When a fold - exists (e.g cylindrical domain), vector fields reverse sign upon - crossing the fold. This parity reversal is performed only in the - vector version of mpp_update_domains. In - addition, shift operations may need to be applied to vector fields on - staggered grids, also described in the vector interface to - mpp_update_domains. - - name is the name associated with the decomposition, - e.g 'Ocean model'. If this argument is present, - mpp_define_domains will print the domain decomposition - generated to stdlog. - - Examples: - -
                                                        call mpp_define_domains( (/1,100,1,100/), (/2,2/), domain, xhalo=1 )
                                                    - - will create the following domain layout: -
                                                                       |---------|-----------|-----------|-------------|
                                                    -                   |domain(1)|domain(2)  |domain(3)  |domain(4)    |
                                                    -    |--------------|---------|-----------|-----------|-------------|
                                                    -    |Compute domain|1,50,1,50|51,100,1,50|1,50,51,100|51,100,51,100|
                                                    -    |--------------|---------|-----------|-----------|-------------|
                                                    -    |Data domain   |0,51,1,50|50,101,1,50|0,51,51,100|50,101,51,100|
                                                    -    |--------------|---------|-----------|-----------|-------------|
                                                    - - Again, we allocate arrays on the data domain, perform computations - on the compute domain, and call mpp_update_domains to update - the halo region. - - If we wished to perfom a 1D decomposition along Y - on the same global domain, we could use: -
                                                        call mpp_define_domains( (/1,100,1,100/), layout=(/4,1/), domain, xhalo=1 )
                                                    - This will create the following domain layout: -
                                                                       |----------|-----------|-----------|------------|
                                                    -                   |domain(1) |domain(2)  |domain(3)  |domain(4)   |
                                                    -    |--------------|----------|-----------|-----------|------------|
                                                    -    |Compute domain|1,100,1,25|1,100,26,50|1,100,51,75|1,100,76,100|
                                                    -    |--------------|----------|-----------|-----------|------------|
                                                    -    |Data domain   |0,101,1,25|0,101,26,50|0,101,51,75|1,101,76,100|
                                                    -    |--------------|----------|-----------|-----------|------------|
                                                    - -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  4. -
                                                  5. - -

                                                    mpp_modify_domain

                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                    domain_in    - The source domain. -
                                                    halo    - Halo size of the returned 1D doamin. Default value is 0. -
                                                    cbegin,cend    - Axis specifications associated with the compute domain of the returned 1D domain. -
                                                    gbegin,gend    - Axis specifications associated with the global domain of the returned 1D domain. -
                                                    isc,iec    - Zonal axis specifications associated with the compute domain of the returned 2D domain. -
                                                    jsc,jec    - Meridinal axis specifications associated with the compute domain of the returned 2D domain. -
                                                    isg,ieg    - Zonal axis specifications associated with the global domain of the returned 2D domain. -
                                                    jsg,jeg    - Meridinal axis specifications associated with the global domain of the returned 2D domain. -
                                                    xhalo,yhalo    - Halo size of the returned 2D doamin. Default value is 0. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    domain_out    - The returned domain. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  6. -
                                                  7. - -

                                                    mpp_update_domains

                                                    -
                                                    -call mpp_update_domains ( field, domain, flags )
                                                    -
                                                    -call mpp_update_domains ( fieldx, fieldy, domain, flags, gridtype )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_update_domains is used to perform a halo update of a - domain-decomposed array on each PE. MPP_TYPE_ can be of type - complex, integer, logical or real; - of 4-byte or 8-byte kind; of rank up to 5. The vector version (with - two input data fields) is only present for real types. - - For 2D domain updates, if there are halos present along both - x and y, we can choose to update one only, by - specifying flags=XUPDATE or flags=YUPDATE. In - addition, one-sided updates can be performed by setting flags - to any combination of WUPDATE, EUPDATE, - SUPDATE and NUPDATE, to update the west, east, north - and south halos respectively. Any combination of halos may be used by - adding the requisite flags, e.g: flags=XUPDATE+SUPDATE or - flags=EUPDATE+WUPDATE+SUPDATE will update the east, west and - south halos. - - If a call to mpp_update_domains involves at least one E-W - halo and one N-S halo, the corners involved will also be updated, i.e, - in the example above, the SE and SW corners will be updated. - - If flags is not supplied, that is - equivalent to flags=XUPDATE+YUPDATE. - - The vector version is passed the x and y - components of a vector field in tandem, and both are updated upon - return. They are passed together to treat parity issues on various - grids. For example, on a cubic sphere projection, the x and - y components may be interchanged when passing from an - equatorial cube face to a polar face. For grids with folds, vector - components change sign on crossing the fold. Paired scalar quantities - can also be passed with the vector version if flags=SCALAR_PAIR, in which - case components are appropriately interchanged, but signs are not. - - Special treatment at boundaries such as folds is also required for - staggered grids. The following types of staggered grids are - recognized: - - 1) AGRID: values are at grid centers.
                                                    - 2) BGRID_NE: vector fields are at the NE vertex of a grid - cell, i.e: the array elements u(i,j) and v(i,j) are - actually at (i+½,j+½) with respect to the grid centers.
                                                    - 3) BGRID_SW: vector fields are at the SW vertex of a grid - cell, i.e: the array elements u(i,j) and v(i,j) are - actually at (i-½,j-½) with respect to the grid centers.
                                                    - 4) CGRID_NE: vector fields are at the N and E faces of a - grid cell, i.e: the array elements u(i,j) and v(i,j) - are actually at (i+½,j) and (i,j+½) with respect to the - grid centers.
                                                    - 5) CGRID_SW: vector fields are at the S and W faces of a - grid cell, i.e: the array elements u(i,j) and v(i,j) - are actually at (i-½,j) and (i,j-½) with respect to the - grid centers. - - The gridtypes listed above are all available by use association as - integer parameters. The scalar version of mpp_update_domains - assumes that the values of a scalar field are always at AGRID - locations, and no special boundary treatment is required. If vector - fields are at staggered locations, the optional argument - gridtype must be appropriately set for correct treatment at - boundaries. - - It is safe to apply vector field updates to the appropriate arrays - irrespective of the domain topology: if the topology requires no - special treatment of vector fields, specifying gridtype will - do no harm. - - mpp_update_domains internally buffers the date being sent - and received into single messages for efficiency. A turnable internal - buffer area in memory is provided for this purpose by - mpp_domains_mod. The size of this buffer area can be set by - the user by calling - mpp_domains_set_stack_size. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  8. -
                                                  9. - -

                                                    mpp_start_update_domains/mpp_complete_update_domains

                                                    -
                                                    -call mpp_start_update_domains/mpp_complete_update_domains 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_start_update_domains is used to start a halo update of a - domain-decomposed array on each PE. MPP_TYPE_ can be of type - complex, integer, logical or real; - of 4-byte or 8-byte kind; of rank up to 5. The vector version (with - two input data fields) is only present for real types. - - mpp_start_update_domains must be paired together with - mpp_complete_update_domains. In mpp_start_update_domains, - a buffer will be pre-post to receive (non-blocking) the - data and data on computational domain will be packed and sent (non-blocking send) - to other processor. In mpp_complete_update_domains, buffer will - be unpacked to fill the halo and mpp_sync_self will be called to - to ensure communication safe at the last call of mpp_complete_update_domains. - - Each mpp_update_domains can be replaced by the combination of mpp_start_update_domains - and mpp_complete_update_domains. The arguments in mpp_start_update_domains - and mpp_complete_update_domains should be the exact the same as in - mpp_update_domains to be replaced except no optional argument "complete". - The following are examples on how to replace mpp_update_domains with - mpp_start_update_domains/mpp_complete_update_domains - - Example 1: Replace one scalar mpp_update_domains. - - Replace - - call mpp_update_domains(data, domain, flags=update_flags) - - with - - id_update = mpp_start_update_domains(data, domain, flags=update_flags)
                                                    - ...( doing some computation )
                                                    - call mpp_complete_update_domains(id_update, data, domain, flags=update_flags)
                                                    - -
                                                    - Example 2: Replace group scalar mpp_update_domains, - - Replace - - call mpp_update_domains(data_1, domain, flags=update_flags, complete=.false.)
                                                    - .... ( other n-2 call mpp_update_domains with complete = .false. )
                                                    - call mpp_update_domains(data_n, domain, flags=update_flags, complete=.true. )
                                                    - -
                                                    - With - - id_up_1 = mpp_start_update_domains(data_1, domain, flags=update_flags)
                                                    - .... ( other n-2 call mpp_start_update_domains )
                                                    - id_up_n = mpp_start_update_domains(data_n, domain, flags=update_flags)
                                                    - - ..... ( doing some computation ) - - call mpp_complete_update_domains(id_up_1, data_1, domain, flags=update_flags)
                                                    - .... ( other n-2 call mpp_complete_update_domains )
                                                    - call mpp_complete_update_domains(id_up_n, data_n, domain, flags=update_flags)
                                                    - -
                                                    - Example 3: Replace group CGRID_NE vector, mpp_update_domains - - Replace - - call mpp_update_domains(u_1, v_1, domain, flags=update_flgs, gridtype=CGRID_NE, complete=.false.)
                                                    - .... ( other n-2 call mpp_update_domains with complete = .false. )
                                                    - call mpp_update_domains(u_1, v_1, domain, flags=update_flags, gridtype=CGRID_NE, complete=.true. )
                                                    - -
                                                    - with - - id_up_1 = mpp_start_update_domains(u_1, v_1, domain, flags=update_flags, gridtype=CGRID_NE)
                                                    - .... ( other n-2 call mpp_start_update_domains )
                                                    - id_up_n = mpp_start_update_domains(u_n, v_n, domain, flags=update_flags, gridtype=CGRID_NE)
                                                    - -
                                                    - ..... ( doing some computation ) - - call mpp_complete_update_domains(id_up_1, u_1, v_1, domain, flags=update_flags, gridtype=CGRID_NE)
                                                    - .... ( other n-2 call mpp_complete_update_domains )
                                                    - call mpp_complete_update_domains(id_up_n, u_n, v_n, domain, flags=update_flags, gridtype=CGRID_NE)
                                                    - -
                                                    - For 2D domain updates, if there are halos present along both - x and y, we can choose to update one only, by - specifying flags=XUPDATE or flags=YUPDATE. In - addition, one-sided updates can be performed by setting flags - to any combination of WUPDATE, EUPDATE, - SUPDATE and NUPDATE, to update the west, east, north - and south halos respectively. Any combination of halos may be used by - adding the requisite flags, e.g: flags=XUPDATE+SUPDATE or - flags=EUPDATE+WUPDATE+SUPDATE will update the east, west and - south halos. - - If a call to mpp_start_update_domains/mpp_complete_update_domains involves at least one E-W - halo and one N-S halo, the corners involved will also be updated, i.e, - in the example above, the SE and SW corners will be updated. - - If flags is not supplied, that is - equivalent to flags=XUPDATE+YUPDATE. - - The vector version is passed the x and y - components of a vector field in tandem, and both are updated upon - return. They are passed together to treat parity issues on various - grids. For example, on a cubic sphere projection, the x and - y components may be interchanged when passing from an - equatorial cube face to a polar face. For grids with folds, vector - components change sign on crossing the fold. Paired scalar quantities - can also be passed with the vector version if flags=SCALAR_PAIR, in which - case components are appropriately interchanged, but signs are not. - - Special treatment at boundaries such as folds is also required for - staggered grids. The following types of staggered grids are - recognized: - - 1) AGRID: values are at grid centers.
                                                    - 2) BGRID_NE: vector fields are at the NE vertex of a grid - cell, i.e: the array elements u(i,j) and v(i,j) are - actually at (i+½,j+½) with respect to the grid centers.
                                                    - 3) BGRID_SW: vector fields are at the SW vertex of a grid - cell, i.e: the array elements u(i,j) and v(i,j) are - actually at (i-½,j-½) with respect to the grid centers.
                                                    - 4) CGRID_NE: vector fields are at the N and E faces of a - grid cell, i.e: the array elements u(i,j) and v(i,j) - are actually at (i+½,j) and (i,j+½) with respect to the - grid centers.
                                                    - 5) CGRID_SW: vector fields are at the S and W faces of a - grid cell, i.e: the array elements u(i,j) and v(i,j) - are actually at (i-½,j) and (i,j-½) with respect to the - grid centers. - - The gridtypes listed above are all available by use association as - integer parameters. If vector fields are at staggered locations, the - optional argument gridtype must be appropriately set for - correct treatment at boundaries. - - It is safe to apply vector field updates to the appropriate arrays - irrespective of the domain topology: if the topology requires no - special treatment of vector fields, specifying gridtype will - do no harm. - - mpp_start_update_domains/mpp_complete_update_domains internally - buffers the data being sent and received into single messages for efficiency. - A turnable internal buffer area in memory is provided for this purpose by - mpp_domains_mod. The size of this buffer area can be set by - the user by calling - mpp_domains_set_stack_size. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  10. -
                                                  11. - -

                                                    mpp_define_nest_domains

                                                    -
                                                    -call mpp_define_nest_domains (nest_domain, domain_fine, domain_coarse, tile_fine, tile_coarse, istart_fine, iend_fine, jstart_fine, jend_fine, istart_coarse, iend_coarse, jstart_coarse, jend_coarse, pelist, extra_halo, name)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Set up a domain to pass data between coarse and fine grid of nested model. - Currently it only support one fine nest region over the corase grid region. - It supports both serial and concurrent nesting. The serial nesting is that - both coarse and fine grid are on the exact same processor list. Concurrent - nesting is that coarse and fine grid are on individual processor list and - no overlapping. Coarse and fine grid domain need to be defined before - calling mpp_define_nest_domains. For concurrent nesting, mpp_broadcast - need to be called to broadcast both fine and coarse grid domain onto - all the processors. -
                                                    - -
                                                    - mpp_update_nest_coarse is used to pass data from fine grid to coarse grid computing domain. - mpp_update_nest_fine is used to pass data from coarse grid to fine grid halo. - You may call mpp_get_C2F_index before calling mpp_update_nest_fine to get the index for - passing data from coarse to fine. You may call mpp_get_F2C_index before calling - mpp_update_nest_coarse to get the index for passing data from coarse to fine. -
                                                    - -
                                                    - NOTE: The following tests are done in test_mpp_domains: the coarse grid is cubic sphere - grid and the fine grid is a regular-latlon grid (symmetric domain) nested inside - face 3 of the cubic sphere grid. Tests are done for data at T, E, C, N-cell center. - - Below is an example to pass data between fine and coarse grid (More details on how to - use the nesting domain update are available in routing test_update_nest_domain of - shared/mpp/test_mpp_domains.F90. - -
                                                        if( concurrent ) then
                                                    -       call mpp_broadcast_domain(domain_fine)
                                                    -       call mpp_broadcast_domain(domain_coarse)
                                                    -    endif
                                                    -    
                                                    -     call mpp_define_nest_domains(nest_domain, domain_fine, domain_coarse, tile_fine, tile_coarse, &
                                                    -                                  istart_fine, iend_fine, jstart_fine, jend_fine,                  &
                                                    -                                  istart_coarse, iend_coarse, jstart_coarse, jend_coarse,         &
                                                    -                                  pelist, extra_halo, name="nest_domain")
                                                    -     call mpp_get_C2F_index(nest_domain, isw_f, iew_f, jsw_f, jew_f, isw_c, iew_c, jsw_c, jew_c, WEST)
                                                    -     call mpp_get_C2F_index(nest_domain, ise_f, iee_f, jse_f, jee_f, ise_c, iee_c, jse_c, jee_c, EAST)
                                                    -     call mpp_get_C2F_index(nest_domain, iss_f, ies_f, jss_f, jes_f, iss_c, ies_c, jss_c, jes_c, SOUTH)
                                                    -     call mpp_get_C2F_index(nest_domain, isn_f, ien_f, jsn_f, jen_f, isn_c, ien_c, jsn_c, jen_c, NORTH)
                                                    -
                                                    -     allocate(wbuffer(isw_c:iew_c, jsw_c:jew_c,nz))
                                                    -     allocate(ebuffer(ise_c:iee_c, jse_c:jee_c,nz))
                                                    -     allocate(sbuffer(iss_c:ies_c, jss_c:jes_c,nz))
                                                    -     allocate(nbuffer(isn_c:ien_c, jsn_c:jen_c,nz))
                                                    -     call mpp_update_nest_fine(x, nest_domain, wbuffer, sbuffer, ebuffer, nbuffer)
                                                    -
                                                    -     call mpp_get_F2C_index(nest_domain, is_c, ie_c, js_c, je_c, is_f, ie_f, js_f, je_f)
                                                    -     allocate(buffer (is_f:ie_f, js_f:je_f,nz))
                                                    -     call mpp_update_nest_coarse(x, nest_domain, buffer)
                                                    - -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                    domain_fine    - domain for fine grid. -
                                                    domain_coarse    - domain for coarse grid. -
                                                    tile_fine    - tile number of the fine grid. Currently this value should be 1. -
                                                    tile_coarse    - tile numuber of the coarse grid. -
                                                    istart_fine, iend_fine, jstart_fine, jend_fine    - index in the fine grid of the nested region -
                                                    istart_coarse, iend_coarse, jstart_coarse, jend_coarse    - index in the coarse grid of the nested region -
                                                    pelist    - List of PEs to which the domains are to be assigned. -
                                                    extra_halo    - optional argument. extra halo for passing data from coarse grid to fine grid. - Default is 0 and currently only support extra_halo = 0. -
                                                    name    - opitonal argument. Name of the nest domain. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    nest_domain    - Holds the information to pass data between fine and coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  12. -
                                                  13. - -

                                                    mpp_get_C2F_index

                                                    -
                                                    -call mpp_get_C2F_index (nest_domain, is_fine, ie_fine, js_fine, je_fine, is_coarse, ie_coarse, js_coarse, je_coarse, dir, position)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Get the index of the data passed from coarse grid to fine grid. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - -
                                                    nest_domain    - Holds the information to pass data between fine and coarse grid. -
                                                    dir    - direction of the halo update. Its value should be WEST, EAST, SOUTH or NORTH. -
                                                    position    - Cell position. It value should be CENTER, EAST, NORTH or SOUTH. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - - - - -
                                                    istart_fine, iend_fine, jstart_fine, jend_fine    - index in the fine grid of the nested region -
                                                    istart_coarse, iend_coarse, jstart_coarse, jend_coarse    - index in the coarse grid of the nested region -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  14. -
                                                  15. - -

                                                    mpp_get_F2C_index

                                                    -
                                                    -call mpp_get_F2C_index (nest_domain, is_coarse, ie_coarse, js_coarse, je_coarse, is_fine, ie_fine, js_fine, je_fine, position)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Get the index of the data passed from fine grid to coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - -
                                                    nest_domain    - Holds the information to pass data between fine and coarse grid. -
                                                    position    - Cell position. It value should be CENTER, EAST, NORTH or SOUTH. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - - - - -
                                                    istart_fine, iend_fine, jstart_fine, jend_fine    - index in the fine grid of the nested region -
                                                    istart_coarse, iend_coarse, jstart_coarse, jend_coarse    - index in the coarse grid of the nested region -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  16. -
                                                  17. - -

                                                    mpp_update_nest_fine

                                                    -
                                                    -call mpp_update_nest_fine (field, nest_domain, wbuffer, ebuffer, sbuffer, nbuffer, flags, complete, position, extra_halo, name, tile_count)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Pass the data from coarse grid to fill the buffer to be ready to be interpolated - onto fine grid. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - - - - - - - -
                                                    field    - field on the model grid. -
                                                    flags    - optional arguments. Specify the direction of fine grid halo buffer to be filled. - Default value is XUPDATE+YUPDATE. -
                                                    complete    - optional argument. When true, do the buffer filling. Default value is true. -
                                                    position    - Cell position. It value should be CENTER, EAST, NORTH or SOUTH. Default is CENTER. -
                                                    extra_halo    - optional argument. extra halo for passing data from coarse grid to fine grid. - Default is 0 and currently only support extra_halo = 0. -
                                                    name    - opitonal argument. Name of the nest domain. -
                                                    tile_count    - optional argument. Used to support multiple-tile-per-pe. default is 1 and currently - only support tile_count = 1. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    nest_domain    - Holds the information to pass data between fine and coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - - - - - - - - - - -
                                                    wbuffer    - west side buffer to be filled with data on coarse grid. -
                                                    ebuffer    - east side buffer to be filled with data on coarse grid. -
                                                    sbuffer    - south side buffer to be filled with data on coarse grid. -
                                                    nbuffer    - north side buffer to be filled with data on coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  18. -
                                                  19. - -

                                                    mpp_update_nest_coarse

                                                    -
                                                    -call mpp_update_nest_coarse (field, nest_domain, buffer, complete, position, name, tile_count)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Pass the data from fine grid to fill the buffer to be ready to be interpolated - onto coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - -
                                                    field    - field on the model grid. -
                                                    complete    - optional argument. When true, do the buffer filling. Default value is true. -
                                                    position    - Cell position. It value should be CENTER, EAST, NORTH or SOUTH. Default is CENTER. -
                                                    name    - opitonal argument. Name of the nest domain. -
                                                    tile_count    - optional argument. Used to support multiple-tile-per-pe. default is 1 and currently - only support tile_count = 1. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    nest_domain    - Holds the information to pass data between fine and coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - -
                                                    buffer    - buffer to be filled with data on coarse grid. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  20. -
                                                  21. - -

                                                    mpp_get_boundary

                                                    -
                                                    -call mpp_get_boundary 
                                                    -
                                                    -
                                                    -call mpp_get_boundary 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_get_boundary is used to get the boundary data for symmetric domain - when the data is at C, E, or N-cell center. For cubic grid, the data should - always at C-cell center. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  22. -
                                                  23. - -

                                                    mpp_redistribute

                                                    -
                                                    -call mpp_redistribute ( domain_in, field_in, domain_out, field_out )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_redistribute is used to reorganize a distributed - array. MPP_TYPE_ can be of type integer, - complex, or real; of 4-byte or 8-byte kind; of rank - up to 5. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - -
                                                    field_in    - field_in is dimensioned on the data domain of domain_in. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - -
                                                    field_out    - field_out on the data domain of domain_out. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  24. -
                                                  25. - -

                                                    mpp_check_field

                                                    -
                                                    -call mpp_check_field (field_in, pelist1, pelist2, domain, mesg, & w_halo, s_halo, e_halo, n_halo, force_abort )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - There are two forms for the mpp_check_field call. The 2D - version is generally to be used and 3D version is built by repeated calls to the - 2D version. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - - - - -
                                                    field_in    - Field to be checked -
                                                    pelist1, pelist2    - Pelist of the two ensembles to be compared -
                                                    domain    - Domain of current pe -
                                                    mesg    - Message to be printed out -
                                                    w_halo, s_halo, e_halo, n_halo    - Halo size to be checked. Default value is 0. -
                                                    force_abort    - When true, abort program when any difference found. Default value is false. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  26. -
                                                  27. - -

                                                    mpp_global_field

                                                    -
                                                    -call mpp_global_field ( domain, local, global, flags )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_global_field is used to get an entire - domain-decomposed array on each PE. MPP_TYPE_ can be of type - complex, integer, logical or real; - of 4-byte or 8-byte kind; of rank up to 5. - - All PEs in a domain decomposition must call - mpp_global_field, and each will have a complete global field - at the end. Please note that a global array of rank 3 or higher could - occupy a lot of memory. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - -
                                                    domain   
                                                    local    - local is dimensioned on either the compute domain or the - data domain of domain. -
                                                    flags    - flags can be given the value XONLY or - YONLY, to specify a globalization on one axis only. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - -
                                                    global    - global is dimensioned on the corresponding global domain. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  28. -
                                                  29. - -

                                                    mpp_global_max

                                                    -
                                                     
                                                    -mpp_global_max ( domain, field, locus )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_global_max is used to get the maximum value of a - domain-decomposed array on each PE. MPP_TYPE_ can be of type - integer or real; of 4-byte or 8-byte kind; of rank - up to 5. The dimension of locus must equal the rank of - field. - - All PEs in a domain decomposition must call - mpp_global_max, and each will have the result upon exit. - - The function mpp_global_min, with an identical syntax. is - also available. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - -
                                                    domain   
                                                    field    - field is dimensioned on either the compute domain or the - data domain of domain. -
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - -
                                                    locus    - locus, if present, can be used to retrieve the location of - the maximum (as in the MAXLOC intrinsic of f90). -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  30. -
                                                  31. - -

                                                    mpp_global_sum

                                                    -
                                                    -call mpp_global_sum ( domain, field, flags )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_global_sum is used to get the sum of a - domain-decomposed array on each PE. MPP_TYPE_ can be of type - integer, complex, or real; of 4-byte or - 8-byte kind; of rank up to 5. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - -
                                                    domain   
                                                    field    - field is dimensioned on either the compute domain or the - data domain of domain. -
                                                    flags    - flags, if present, must have the value - BITWISE_EXACT_SUM. This produces a sum that is guaranteed to - produce the identical result irrespective of how the domain is - decomposed. This method does the sum first along the ranks beyond 2, - and then calls mpp_global_field to produce a - global 2D array which is then summed. The default method, which is - considerably faster, does a local sum followed by mpp_sum across the domain - decomposition. -
                                                    -
                                                    -
                                                    -
                                                    -NOTE -
                                                    -
                                                    - All PEs in a domain decomposition must call - mpp_global_sum, and each will have the result upon exit. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  32. -
                                                  33. - -

                                                    mpp_get_neighbor_pe

                                                    -
                                                    -call mpp_get_neighbor_pe ( domain1d, direction=+1 , pe) call mpp_get_neighbor_pe( domain2d, direction=NORTH, pe)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Given a 1-D or 2-D domain decomposition, this call allows users to retrieve - the PE number of an adjacent PE-domain while taking into account that the - domain may have holes (masked) and/or have cyclic boundary conditions and/or a - folded edge. Which PE-domain will be retrived will depend on "direction": - +1 (right) or -1 (left) for a 1-D domain decomposition and either NORTH, SOUTH, - EAST, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, or NORTH_WEST for a 2-D - decomposition. If no neighboring domain exists (masked domain), then the - returned "pe" value will be set to NULL_PE. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  34. -
                                                  35. - -

                                                    operator

                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The module provides public operators to check for - equality/inequality of domaintypes, e.g: - -
                                                        type(domain1D) :: a, b
                                                    -    type(domain2D) :: c, d
                                                    -    ...
                                                    -    if( a.NE.b )then
                                                    -        ...
                                                    -    end if
                                                    -    if( c==d )then
                                                    -        ...
                                                    -    end if
                                                    - - Domains are considered equal if and only if the start and end - indices of each of their component global, data and compute domains - are equal. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  36. -
                                                  37. - -

                                                    mpp_get_compute_domain

                                                    -
                                                    -call mpp_get_compute_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - retrieve the axis specifications associated with the compute domains - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  38. -
                                                  39. - -

                                                    mpp_get_compute_domains

                                                    -
                                                    -call mpp_get_compute_domains ( domain, xbegin, xend, xsize, & ybegin, yend, ysize )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Retrieve the entire array of compute domain extents associated with a decomposition. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - -
                                                    domain   
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - - - - - - - -
                                                    xbegin,ybegin   
                                                    xend,yend   
                                                    xsize,ysize   
                                                    -
                                                    -
                                                    -
                                                    -
                                                  40. -
                                                  41. - -

                                                    mpp_get_data_domain

                                                    -
                                                    -call mpp_get_data_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - retrieve the axis specifications associated with the data domains. - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  42. -
                                                  43. - -

                                                    mpp_get_global_domain

                                                    -
                                                    -call mpp_get_global_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - retrieve the axis specifications associated with the global domains. - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  44. -
                                                  45. - -

                                                    mpp_get_memory_domain

                                                    -
                                                    -call mpp_get_memory_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - retrieve the axis specifications associated with the memory domains. - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  46. -
                                                  47. - -

                                                    mpp_set_compute_domain

                                                    -
                                                    -call mpp_set_compute_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - set the axis specifications associated with the compute domains - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  48. -
                                                  49. - -

                                                    mpp_set_data_domain

                                                    -
                                                    -call mpp_set_data_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - set the axis specifications associated with the data domains. - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  50. -
                                                  51. - -

                                                    mpp_set_global_domain

                                                    -
                                                    -call mpp_set_global_domain 
                                                    -
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The domain is a derived type with private elements. These routines - set the axis specifications associated with the global domains. - The 2D version of these is a simple extension of 1D. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  52. -
                                                  53. - -

                                                    mpp_get_pelist

                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The 1D version of this call returns an array of the PEs assigned to this 1D domain - decomposition. In addition the optional argument pos may be - used to retrieve the 0-based position of the domain local to the - calling PE, i.e domain%list(pos)%pe is the local PE, - as returned by mpp_pe(). - The 2D version of this call is identical to 1D version. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - -
                                                    domain   
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - - - - -
                                                    pelist   
                                                    pos   
                                                    -
                                                    -
                                                    -
                                                    -
                                                  54. -
                                                  55. - -

                                                    mpp_get_layout

                                                    -
                                                    -call mpp_get_layout ( domain, layout )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - The 1D version of this call returns the number of divisions that was assigned to this - decomposition axis. The 2D version of this call returns an array of - dimension 2 holding the results on two axes. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - -
                                                    domain   
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - -
                                                    layout   
                                                    -
                                                    -
                                                    -
                                                    -
                                                  56. -
                                                  57. - -

                                                    mpp_nullify_domain_list

                                                    -
                                                    -call mpp_nullify_domain_list ( domain)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Nullify domain list. This interface is needed in mpp_domains_test. - 1-D case can be added in if needed. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    domain   
                                                    -
                                                    -
                                                    -
                                                    -
                                                  58. -
                                                  - - - - -
                                                  -

                                                  NAMELIST

                                                  - -
                                                  -&mpp_domains_nml -
                                                  -
                                                  -
                                                  -
                                                  -
                                                  -debug_update_domain -
                                                  -
                                                  - when debug_update_domain = none, no debug will be done. When debug_update_domain is set to fatal, - the run will be exited with fatal error message. When debug_update_domain is set to - warning, the run will output warning message. when debug update_domain is set to - note, the run will output some note message. Will check the consistency on the boundary between - processor/tile when updating doamin for symmetric domain and check the consistency on the north - folded edge. -
                                                  -[character(len=32), default: none] -
                                                  -
                                                  -
                                                  -
                                                  -
                                                  - - - - -
                                                  -

                                                  COMPILER SPECIFICS

                                                  - -
                                                  -
                                                  -
                                                  -
                                                  -
                                                  - Any module or program unit using mpp_domains_mod - must contain the line -
                                                       use mpp_domains_mod
                                                  - -mpp_domains_mod uses mpp_mod, and therefore is subject to the compiling and linking requirements of that module. - -
                                                  -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  PRECOMPILER OPTIONS

                                                  - -
                                                  -
                                                  -
                                                  -
                                                  -
                                                  - -mpp_domains_mod uses standard f90, and has no special - requirements. There are some OS-dependent - pre-processor directives that you might need to modify on - non-SGI/Cray systems and compilers. The portability of mpp_mod - obviously is a constraint, since this module is built on top of - it. Contact me, Balaji, SGI/GFDL, with questions. -
                                                  -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  LOADER OPTIONS

                                                  - -
                                                  -

                                                  - The source consists of the main source file - and also requires the following include files: - - GFDL users can check it out of the main CVS repository as part of - the CVS module. The current public tag is . - External users can download the latest package . Public access - to the GFDL CVS repository will soon be made available. -

                                                  -
                                                          
                                                  -
                                                  -
                                                  -
                                                  - -
                                                  -
                                                  -top -
                                                  - - diff --git a/src/shared/mpp/mpp_io.F90 b/src/shared/mpp/mpp_io.F90 index fcf4d8ade8..4c02397b87 100644 --- a/src/shared/mpp/mpp_io.F90 +++ b/src/shared/mpp/mpp_io.F90 @@ -349,19 +349,19 @@ module mpp_io_mod !--- public interface from mpp_io_util.h ---------------------- public :: mpp_get_iospec, mpp_get_id, mpp_get_ncid, mpp_get_unit_range, mpp_is_valid public :: mpp_set_unit_range, mpp_get_info, mpp_get_atts, mpp_get_fields - public :: mpp_get_times, mpp_get_axes, mpp_get_recdimid, mpp_get_axis_data + public :: mpp_get_times, mpp_get_axes, mpp_get_recdimid, mpp_get_axis_data, mpp_get_axis_by_name public :: mpp_io_set_stack_size, mpp_get_field_index, mpp_get_axis_index public :: mpp_get_field_name, mpp_get_att_value, mpp_get_att_length public :: mpp_get_att_type, mpp_get_att_name, mpp_get_att_real, mpp_get_att_char - public :: mpp_get_att_real_scalar - public :: mpp_get_file_name, mpp_file_is_opened + public :: mpp_get_att_real_scalar, mpp_get_axis_length + public :: mpp_get_file_name, mpp_file_is_opened, mpp_attribute_exist public :: mpp_io_clock_on, mpp_get_time_axis, mpp_get_default_calendar !--- public interface from mpp_io_misc.h ---------------------- public :: mpp_io_init, mpp_io_exit, netcdf_err, mpp_flush !--- public interface from mpp_io_write.h --------------------- - public :: mpp_write, mpp_write_meta, mpp_copy_meta, mpp_modify_meta + public :: mpp_write, mpp_write_meta, mpp_copy_meta, mpp_modify_meta, mpp_write_axis_data !--- public interface from mpp_io_read.h --------------------- public :: mpp_read, mpp_read_meta, mpp_get_tavg_info @@ -387,6 +387,7 @@ module mpp_io_mod character(len=128) :: units character(len=256) :: longname character(len=8) :: cartesian + character(len=256) :: compressed character(len=24) :: calendar integer :: sense, len !+/-1, depth or height? type(domain1D) :: domain !if pointer is associated, it is a distributed data axis @@ -411,6 +412,7 @@ module mpp_io_mod character(len=128) :: standard_name ! CF standard name real :: min, max, missing, fill, scale, add integer :: pack + integer(LONG_KIND), dimension(3) :: checksum type(axistype), pointer :: axes(:) =>NULL() !axes associated with field size, time_axis_index redundantly !hold info already contained in axes. it's clunky and inelegant, !but required so that axes can be shared among multiple files @@ -818,9 +820,9 @@ module mpp_io_mod integer :: pack_size ! = 1 when compiling with -r8 and = 2 when compiling with -r4. character(len=128) :: version= & - '$Id: mpp_io.F90,v 19.0.2.1 2012/05/09 18:28:56 Zhi.Liang Exp $' + '$Id: mpp_io.F90,v 20.0 2013/12/14 00:23:45 fms Exp $' character(len=128) :: tagname= & - '$Name: siena_201207 $' + '$Name: tikal $' contains diff --git a/src/shared/mpp/mpp_io.html b/src/shared/mpp/mpp_io.html deleted file mode 100644 index 17603ed973..0000000000 --- a/src/shared/mpp/mpp_io.html +++ /dev/null @@ -1,740 +0,0 @@ - - - -Module mpp_io_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                  -

                                                  Module mpp_io_mod

                                                  - - -
                                                  -Contact:  - V. Balaji - -
                                                  -Reviewers:  -
                                                  -Change History: WebCVS Log -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  OVERVIEW

                                                  - -

                                                  - -mpp_io_mod, is a set of simple calls for parallel I/O on - distributed systems. It is geared toward the writing of data in netCDF - format. It requires the modules mpp_domains_mod and mpp_mod, upon which it is built. -

                                                  - - - -
                                                  - In massively parallel environments, an often difficult problem is - the reading and writing of data to files on disk. MPI-IO and MPI-2 IO - are moving toward providing this capability, but are currently not - widely implemented. Further, it is a rather abstruse - API. mpp_io_mod is an attempt at a simple API encompassing a - certain variety of the I/O tasks that will be required. It does not - attempt to be an all-encompassing standard such as MPI, however, it - can be implemented in MPI if so desired. It is equally simple to add - parallel I/O capability to mpp_io_mod based on vendor-specific - APIs while providing a layer of insulation for user codes. - - The mpp_io_mod parallel I/O API built on top of the mpp_domains_mod and mpp_mod API for domain decomposition and - message passing. Features of mpp_io_mod include: - - 1) Simple, minimal API, with free access to underlying API for more - complicated stuff.
                                                  - 2) Self-describing files: comprehensive header information - (metadata) in the file itself.
                                                  - 3) Strong focus on performance of parallel write: the climate models - for which it is designed typically read a minimal amount of data - (typically at the beginning of the run); but on the other hand, tend - to write copious amounts of data during the run. An interface for - reading is also supplied, but its performance has not yet been optimized.
                                                  - 4) Integrated netCDF capability: netCDF is a - data format widely used in the climate/weather modeling - community. netCDF is considered the principal medium of data storage - for mpp_io_mod. But I provide a raw unformatted - fortran I/O capability in case netCDF is not an option, either due to - unavailability, inappropriateness, or poor performance.
                                                  - 5) May require off-line post-processing: a tool for this purpose, - mppnccombine, is available. GFDL users may use - ~hnv/pub/mppnccombine. Outside users may obtain the - source here. It - can be compiled on any C compiler and linked with the netCDF - library. The program is free and is covered by the GPL license. - - The internal representation of the data being written out is - assumed be the default real type, which can be 4 or 8-byte. Time data - is always written as 8-bytes to avoid overflow on climatic time scales - in units of seconds. - - -

                                                  I/O modes in mpp_io_mod -

                                                  - - The I/O activity critical to performance in the models for which - mpp_io_mod is designed is typically the writing of large - datasets on a model grid volume produced at intervals during - a run. Consider a 3D grid volume, where model arrays are stored as - (i,j,k). The domain decomposition is typically along - i or j: thus to store data to disk as a global - volume, the distributed chunks of data have to be seen as - non-contiguous. If we attempt to have all PEs write this data into a - single file, performance can be seriously compromised because of the - data reordering that will be required. Possible options are to have - one PE acquire all the data and write it out, or to have all the PEs - write independent files, which are recombined offline. These three - modes of operation are described in the mpp_io_mod terminology - in terms of two parameters, threading and fileset, - as follows: - - Single-threaded I/O: a single PE acquires all the data - and writes it out.
                                                  - -Multi-threaded, single-fileset I/O: many PEs write to a - single file.
                                                  - -Multi-threaded, multi-fileset I/O: many PEs write to - independent files. This is also called distributed I/O. - - The middle option is the most difficult to achieve performance. The - choice of one of these modes is made when a file is opened for I/O, in - mpp_open. - - -

                                                  Metadata in mpp_io_mod -

                                                  - - A requirement of the design of mpp_io_mod is that the file must - be entirely self-describing: comprehensive header information - describing its contents is present in the header of every file. The - header information follows the model of netCDF. Variables in the file - are divided into axes and fields. An axis describes a - co-ordinate variable, e.g x,y,z,t. A field consists of data in - the space described by the axes. An axis is described in - mpp_io_mod using the defined type axistype: - -
                                                     type, public :: axistype
                                                  -      sequence
                                                  -      character(len=128) :: name
                                                  -      character(len=128) :: units
                                                  -      character(len=256) :: longname
                                                  -      character(len=8) :: cartesian
                                                  -      integer :: len
                                                  -      integer :: sense           !+/-1, depth or height?
                                                  -      type(domain1D), pointer :: domain
                                                  -      real, dimension(:), pointer :: data
                                                  -      integer :: id, did
                                                  -      integer :: type  ! external NetCDF type format for axis data
                                                  -      integer :: natt
                                                  -      type(atttype), pointer :: Att(:) ! axis attributes
                                                  -   end type axistype
                                                  - - A field is described using the type fieldtype: - -
                                                     type, public :: fieldtype
                                                  -      sequence
                                                  -      character(len=128) :: name
                                                  -      character(len=128) :: units
                                                  -      character(len=256) :: longname
                                                  -      real :: min, max, missing, fill, scale, add
                                                  -      integer :: pack
                                                  -      type(axistype), dimension(:), pointer :: axes
                                                  -      integer, dimension(:), pointer :: size
                                                  -      integer :: time_axis_index
                                                  -      integer :: id
                                                  -      integer :: type ! external NetCDF format for field data
                                                  -      integer :: natt, ndim
                                                  -      type(atttype), pointer :: Att(:) ! field metadata
                                                  -   end type fieldtype
                                                  - - An attribute (global, field or axis) is described using the atttype: - -
                                                     type, public :: atttype
                                                  -      sequence
                                                  -      integer :: type, len
                                                  -      character(len=128) :: name
                                                  -      character(len=256)  :: catt
                                                  -      real(FLOAT_KIND), pointer :: fatt(:)
                                                  -   end type atttype
                                                  - - -This default set of field attributes corresponds - closely to various conventions established for netCDF files. The - pack attribute of a field defines whether or not a - field is to be packed on output. Allowed values of - pack are 1,2,4 and 8. The value of - pack is the number of variables written into 8 - bytes. In typical use, we write 4-byte reals to netCDF output; thus - the default value of pack is 2. For - pack = 4 or 8, packing uses a simple-minded linear - scaling scheme using the scale and add - attributes. There is thus likely to be a significant loss of dynamic - range with packing. When a field is declared to be packed, the - missing and fill attributes, if - supplied, are packed also. - - Please note that the pack values are the same even if the default - real is 4 bytes, i.e PACK=1 still follows the definition - above and writes out 8 bytes. - - A set of attributes for each variable is also available. The - variable definitions and attribute information is written/read by calling - mpp_write_meta or mpp_read_meta. A typical calling - sequence for writing data might be: - -
                                                     ...
                                                  -     type(domain2D), dimension(:), allocatable, target :: domain
                                                  -     type(fieldtype) :: field
                                                  -     type(axistype) :: x, y, z, t
                                                  -   ...
                                                  -     call mpp_define_domains( (/1,nx,1,ny/), domain )
                                                  -     allocate( a(domain(pe)%x%data%start_index:domain(pe)%x%data%end_index, &
                                                  -                 domain(pe)%y%data%start_index:domain(pe)%y%data%end_index,nz) )
                                                  -   ...
                                                  -     call mpp_write_meta( unit, x, 'X', 'km', 'X distance', &
                                                  -          domain=domain(pe)%x, data=(/(float(i),i=1,nx)/) )
                                                  -     call mpp_write_meta( unit, y, 'Y', 'km', 'Y distance', &
                                                  -          domain=domain(pe)%y, data=(/(float(i),i=1,ny)/) )
                                                  -     call mpp_write_meta( unit, z, 'Z', 'km', 'Z distance', &
                                                  -          data=(/(float(i),i=1,nz)/) )
                                                  -     call mpp_write_meta( unit, t, 'Time', 'second', 'Time' )
                                                  -   
                                                  -     call mpp_write_meta( unit, field, (/x,y,z,t/), 'a', '(m/s)', AAA', &
                                                  -          missing=-1e36 )
                                                  -   ...
                                                  -     call mpp_write( unit, x )
                                                  -     call mpp_write( unit, y )
                                                  -     call mpp_write( unit, z )
                                                  -   ...
                                                  - - In this example, x and y have been - declared as distributed axes, since a domain decomposition has been - associated. z and t are undistributed - axes. t is known to be a record axis (netCDF - terminology) since we do not allocate the data element - of the axistype. Only one record axis may be - associated with a file. The call to mpp_write_meta initializes - the axes, and associates a unique variable ID with each axis. The call - to mpp_write_meta with argument field - declared field to be a 4D variable that is a function - of (x,y,z,t), and a unique variable ID is associated - with it. A 3D field will be written at each call to - mpp_write(field). - - The data to any variable, including axes, is written by - mpp_write. - - Any additional attributes of variables can be added through - subsequent mpp_write_meta calls, using the variable ID as a - handle. Global attributes, associated with the dataset as a - whole, can also be written thus. See the mpp_write_meta call syntax below - for further details. - - You cannot interleave calls to mpp_write and - mpp_write_meta: the first call to - mpp_write implies that metadata specification is - complete. - - A typical calling sequence for reading data might be: - -
                                                     ...
                                                  -     integer :: unit, natt, nvar, ntime
                                                  -     type(domain2D), dimension(:), allocatable, target :: domain
                                                  -     type(fieldtype), allocatable, dimension(:) :: fields
                                                  -     type(atttype), allocatable, dimension(:) :: global_atts
                                                  -     real, allocatable, dimension(:) :: times
                                                  -   ...
                                                  -     call mpp_define_domains( (/1,nx,1,ny/), domain )
                                                  -   
                                                  -     call mpp_read_meta(unit)
                                                  -     call mpp_get_info(unit,natt,nvar,ntime)
                                                  -     allocate(global_atts(natt))
                                                  -     call mpp_get_atts(unit,global_atts)
                                                  -     allocate(fields(nvar))
                                                  -     call mpp_get_vars(unit, fields)
                                                  -     allocate(times(ntime))
                                                  -     call mpp_get_times(unit, times)
                                                  -   
                                                  -     allocate( a(domain(pe)%x%data%start_index:domain(pe)%x%data%end_index, &
                                                  -                 domain(pe)%y%data%start_index:domain(pe)%y%data%end_index,nz) )
                                                  -   ...
                                                  -     do i=1, nvar
                                                  -       if (fields(i)%name == 'a')  call mpp_read(unit,fields(i),domain(pe), a,
                                                  -                                                 tindex)
                                                  -     enddo
                                                  -   ...
                                                  - - In this example, the data are distributed as in the previous - example. The call to mpp_read_meta initializes - all of the metadata associated with the file, including global - attributes, variable attributes and non-record dimension data. The - call to mpp_get_info returns the number of global - attributes (natt), variables (nvar) and - time levels (ntime) associated with the file - identified by a unique ID (unit). - mpp_get_atts returns all global attributes for - the file in the derived type atttype(natt). - mpp_get_vars returns variable types - (fieldtype(nvar)). Since the record dimension data are not allocated for calls to mpp_write, a separate call to mpp_get_times is required to access record dimension data. Subsequent calls to - mpp_read return the field data arrays corresponding to - the fieldtype. The domain type is an optional - argument. If domain is omitted, the incoming field - array should be dimensioned for the global domain, otherwise, the - field data is assigned to the computational domain of a local array. - - Multi-fileset reads are not supported with mpp_read. -
                                                  -
                                                  - - -
                                                  -

                                                  OTHER MODULES USED

                                                  - -
                                                  -
                                                  mpp_parameter_mod
                                                  mpp_mod
                                                  mpp_domains_mod
                                                  -
                                                  - - - -
                                                  -

                                                  PUBLIC INTERFACE

                                                  -
                                                  -
                                                  -
                                                  -mpp_get_atts:
                                                  -
                                                  - Get file global metdata. -
                                                  -
                                                  -mpp_read:
                                                  -
                                                  - Read from an open file. -
                                                  -
                                                  -mpp_write_meta:
                                                  -
                                                  - Write metadata. -
                                                  -
                                                  -mpp_write:
                                                  -
                                                  - Write to an open file. -
                                                  -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  PUBLIC ROUTINES

                                                  - -
                                                    -
                                                  1. - -

                                                    mpp_get_atts

                                                    -
                                                    -call mpp_get_atts ( unit, global_atts)
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - Get file global metdata. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - -
                                                    unit   
                                                    global_atts   
                                                    -
                                                    -
                                                    -
                                                    -
                                                  2. -
                                                  3. - -

                                                    mpp_read

                                                    -
                                                    -call mpp_read ( unit, field, data, time_index )
                                                    -
                                                    -call mpp_read ( unit, field, domain, data, time_index )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_read is used to read data to the file on an I/O unit - using the file parameters supplied by mpp_open. There are two - forms of mpp_read, one to read - distributed field data, and one to read non-distributed field - data. Distributed data refer to arrays whose two - fastest-varying indices are domain-decomposed. Distributed data must - be 2D or 3D (in space). Non-distributed data can be 0-3D. - - The data argument for distributed data is expected by - mpp_read to contain data specified on the data domain, - and will read the data belonging to the compute domain, - fetching data as required by the parallel I/O mode specified in the mpp_open call. This - is consistent with our definition of domains, where all arrays are - expected to be dimensioned on the data domain, and all operations - performed on the compute domain. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - -
                                                    unit   
                                                    field   
                                                    domain   
                                                    time_index    - time_index is an optional argument. It is to be omitted if the - field was defined not to be a function of time. Results are - unpredictable if the argument is supplied for a time- independent - field, or omitted for a time-dependent field. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT/OUTPUT -
                                                    -
                                                    - - - - -
                                                    data   
                                                    -
                                                    -
                                                    -
                                                    -NOTE -
                                                    -
                                                    - The type of read performed by mpp_read depends on - the file characteristics on the I/O unit specified at the mpp_open call. Specifically, the - format of the input data (e.g netCDF or IEEE) and the - threading flags, etc., can be changed there, and - require no changes to the mpp_read - calls. (fileset = MPP_MULTI is not supported by - mpp_read; IEEE is currently not supported). - - Packed variables are unpacked using the scale and - add attributes. - - mpp_read_meta must be called prior to calling mpp_read. - -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  4. -
                                                  5. - -

                                                    mpp_write_meta

                                                    -
                                                    -call mpp_write_meta ( unit, axis, name, units, longname, cartesian, sense, domain, data )
                                                    -
                                                    -call mpp_write_meta ( unit, field, axes, name, units, longname, min, max, missing, fill, scale, add, pack )
                                                    -
                                                    -call mpp_write_meta ( unit, id, name, rval=rval, pack=pack )
                                                    -
                                                    -call mpp_write_meta ( unit, id, name, ival=ival )
                                                    -
                                                    -call mpp_write_meta ( unit, id, name, cval=cval )
                                                    -
                                                    -call mpp_write_meta ( unit, name, rval=rval, pack=pack )
                                                    -
                                                    -call mpp_write_meta ( unit, name, ival=ival )
                                                    -
                                                    -call mpp_write_meta ( unit, name, cval=cval )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - This routine is used to write the metadata - describing the contents of a file being written. Each file can contain - any number of fields, which are functions of 0-3 space axes and 0-1 - time axes. (Only one time axis can be defined per file). The basic - metadata defined above for axistype - and fieldtype are written in the first two forms of the call - shown below. These calls will associate a unique variable ID with each - variable (axis or field). These can be used to attach any other real, - integer or character attribute to a variable. The last form is used to - define a global real, integer or character attribute that - applies to the dataset as a whole. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                    unit   
                                                    name   
                                                    units   
                                                    longname   
                                                    cartesian   
                                                    sense   
                                                    domain   
                                                    data   
                                                    min, max   
                                                    missing   
                                                    fill   
                                                    scale   
                                                    add   
                                                    pack   
                                                    id   
                                                    cval   
                                                    ival   
                                                    rval   
                                                    -
                                                    -
                                                    -
                                                    -OUTPUT -
                                                    -
                                                    - - - - - - - -
                                                    axis   
                                                    field   
                                                    -
                                                    -
                                                    -
                                                    -NOTE -
                                                    -
                                                    - The first form defines a time or space axis. Metadata corresponding to the type - above are written to the file on <unit>. A unique ID for subsequen - references to this axis is returned in axis%id. If the <domain> - element is present, this is recognized as a distributed data axis - and domain decomposition information is also written if required (the - domain decomposition info is required for multi-fileset multi-threaded - I/O). If the <data> element is allocated, it is considered to be a - space axis, otherwise it is a time axis with an unlimited dimension. Only - one time axis is allowed per file. -
                                                    -
                                                    - The second form defines a field. Metadata corresponding to the type - above are written to the file on <unit>. A unique ID for subsequen - references to this field is returned in field%id. At least one axis - must be associated, 0D variables are not considered. mpp_write_meta - must previously have been called on all axes associated with this - field. -
                                                    -
                                                    - The third form (3 - 5) defines metadata associated with a previously defined - axis or field, identified to mpp_write_meta by its unique ID <id>. - The attribute is named <name> and can take on a real, integer - or character value. <rval> and <ival> can be scalar or 1D arrays. - This need not be called for attributes already contained in - the type. -
                                                    -
                                                    - The last form (6 - 8) defines global metadata associated with the file as a - whole. The attribute is named <name> and can take on a real, integer - or character value. <rval> and <ival> can be scalar or 1D arrays. -
                                                    -
                                                    - Note that mpp_write_meta is expecting axis data on the - global domain even if it is a domain-decomposed axis. - - You cannot interleave calls to mpp_write and - mpp_write_meta: the first call to - mpp_write implies that metadata specification is complete. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  6. -
                                                  7. - -

                                                    mpp_write

                                                    -
                                                     
                                                    -mpp_write ( unit, axis )
                                                    -
                                                     
                                                    -mpp_write ( unit, field, data, tstamp )
                                                    -
                                                     
                                                    -mpp_write ( unit, field, domain, data, tstamp )
                                                    -
                                                    -
                                                    -DESCRIPTION -
                                                    -
                                                    - -mpp_write is used to write data to the file on an I/O unit - using the file parameters supplied by mpp_open. Axis and field definitions must - have previously been written to the file using mpp_write_meta. There are three - forms of mpp_write, one to write axis data, one to write - distributed field data, and one to write non-distributed field - data. Distributed data refer to arrays whose two - fastest-varying indices are domain-decomposed. Distributed data must - be 2D or 3D (in space). Non-distributed data can be 0-3D. - - The data argument for distributed data is expected by - mpp_write to contain data specified on the data domain, - and will write the data belonging to the compute domain, - fetching or sending data as required by the parallel I/O mode specified in the mpp_open call. This - is consistent with our definition of domains, where all arrays are - expected to be dimensioned on the data domain, and all operations - performed on the compute domain. - - The type of the data argument must be a default - real, which can be 4 or 8 byte. -
                                                    -
                                                    -
                                                    -
                                                    -INPUT -
                                                    -
                                                    - - - - -
                                                    tstamp    - tstamp is an optional argument. It is to - be omitted if the field was defined not to be a function of time. - Results are unpredictable if the argument is supplied for a time- - independent field, or omitted for a time-dependent field. Repeated - writes of a time-independent field are also not recommended. One - time level of one field is written per call. tstamp must be an 8-byte - real, even if the default real type is 4-byte. -
                                                    -
                                                    -
                                                    -
                                                    -NOTE -
                                                    -
                                                    - The type of write performed by mpp_write depends on the file - characteristics on the I/O unit specified at the mpp_open call. Specifically, the format of - the output data (e.g netCDF or IEEE), the threading and - fileset flags, etc., can be changed there, and require no - changes to the mpp_write calls. - - Packing is currently not implemented for non-netCDF files, and the - pack attribute is ignored. On netCDF files, - NF_DOUBLEs (8-byte IEEE floating point numbers) are - written for pack=1 and NF_FLOATs for - pack=2. (pack=2 gives the customary - and default behaviour). We write NF_SHORTs (2-byte - integers) for pack=4, or NF_BYTEs - (1-byte integers) for pack=8. Integer scaling is done - using the scale and add attributes at - pack=4 or 8, satisfying the relation - -
                                                        data = packed_data*scale + add
                                                    - - -NOTE: mpp_write does not check to see if the scaled - data in fact fits into the dynamic range implied by the specified - packing. It is incumbent on the user to supply correct scaling - attributes. - - You cannot interleave calls to mpp_write and - mpp_write_meta: the first call to - mpp_write implies that metadata specification is - complete. -
                                                    -
                                                    -
                                                    -
                                                    -
                                                  8. -
                                                  - - - - - - -
                                                  -
                                                  -top -
                                                  - - diff --git a/src/shared/mpp/mpp_memutils.html b/src/shared/mpp/mpp_memutils.html deleted file mode 100644 index da121ca4ce..0000000000 --- a/src/shared/mpp/mpp_memutils.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module mpp_memutils_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                  -

                                                  Module mpp_memutils_mod

                                                  - - -
                                                  -Contact:  -
                                                  -Reviewers:  -
                                                  -Change History: WebCVS Log -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  OVERVIEW

                                                  - -

                                                  - - - -
                                                  -
                                                  - - -
                                                  -

                                                  OTHER MODULES USED

                                                  - -
                                                  -
                                                  mpp_mod
                                                  -
                                                  - - - -
                                                  -

                                                  PUBLIC INTERFACE

                                                  -
                                                  -
                                                  -
                                                  -
                                                  - - -
                                                  -

                                                  PUBLIC ROUTINES

                                                  - -
                                                    - - - - - - -
                                                    -
                                                    -top -
                                                    - - diff --git a/src/shared/mpp/mpp_parameter.F90 b/src/shared/mpp/mpp_parameter.F90 index 1aa7941237..b70369a11a 100644 --- a/src/shared/mpp/mpp_parameter.F90 +++ b/src/shared/mpp/mpp_parameter.F90 @@ -7,7 +7,7 @@ module mpp_parameter_mod character(len=128), public :: version= & '$Id mpp_parameter.F90 $' character(len=128), public :: tagname= & - '$Name: siena_201207 $' + '$Name: tikal $' !--- public paramters which is used by mpp_mod and its components. !--- All othere modules should import these parameters from mpp_mod. diff --git a/src/shared/mpp/mpp_parameter.html b/src/shared/mpp/mpp_parameter.html deleted file mode 100644 index a2f0f456a3..0000000000 --- a/src/shared/mpp/mpp_parameter.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module mpp_parameter_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                    -

                                                    Module mpp_parameter_mod

                                                    - - -
                                                    -Contact:  -
                                                    -Reviewers:  -
                                                    -Change History: WebCVS Log -
                                                    -
                                                    -
                                                    - - -
                                                    -

                                                    OVERVIEW

                                                    - -

                                                    - - - -
                                                    -
                                                    - - -
                                                    -

                                                    OTHER MODULES USED

                                                    - -
                                                    -
                                                    
                                                    -
                                                    - - - -
                                                    -

                                                    PUBLIC INTERFACE

                                                    -
                                                    -
                                                    -
                                                    -
                                                    - - -
                                                    -

                                                    PUBLIC ROUTINES

                                                    - -
                                                      - - - - - - -
                                                      -
                                                      -top -
                                                      - - diff --git a/src/shared/mpp/mpp_pset.F90 b/src/shared/mpp/mpp_pset.F90 index 2cf0c115e5..02914d55f0 100644 --- a/src/shared/mpp/mpp_pset.F90 +++ b/src/shared/mpp/mpp_pset.F90 @@ -50,7 +50,9 @@ module mpp_pset_mod !public type type :: mpp_pset_type private +#ifdef IBM_FIX sequence +#endif integer :: npset !number of PSETs integer :: next_in_pset, prev_in_pset !next and prev PE in PSET (cyclic) integer :: root_in_pset !PE designated to be the root within PSET diff --git a/src/shared/mpp/mpp_pset.html b/src/shared/mpp/mpp_pset.html deleted file mode 100644 index 903c2f716c..0000000000 --- a/src/shared/mpp/mpp_pset.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module mpp_pset_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                      -

                                                      Module mpp_pset_mod

                                                      - - -
                                                      -Contact:  -
                                                      -Reviewers:  -
                                                      -Change History: WebCVS Log -
                                                      -
                                                      -
                                                      - - -
                                                      -

                                                      OVERVIEW

                                                      - -

                                                      - - - -
                                                      -
                                                      - - -
                                                      -

                                                      OTHER MODULES USED

                                                      - -
                                                      -
                                                      mpp_mod
                                                      -
                                                      - - - -
                                                      -

                                                      PUBLIC INTERFACE

                                                      -
                                                      -
                                                      -
                                                      -
                                                      - - -
                                                      -

                                                      PUBLIC ROUTINES

                                                      - -
                                                        - - - - - - -
                                                        -
                                                        -top -
                                                        - - diff --git a/src/shared/mpp/mpp_utilities.F90 b/src/shared/mpp/mpp_utilities.F90 index bc66458432..e78d348754 100644 --- a/src/shared/mpp/mpp_utilities.F90 +++ b/src/shared/mpp/mpp_utilities.F90 @@ -2,7 +2,7 @@ module mpp_utilities_mod !----------------------------------------------------------------------- character(len=128) :: version = '$Id: mpp_utilities.F90,v 17.0 2009/07/21 03:21:23 fms Exp $' - character(len=128) :: tag = '$Name: siena_201207 $' + character(len=128) :: tag = '$Name: tikal $' !----------------------------------------------------------------------- public :: mpp_array_global_min_max diff --git a/src/shared/mpp/mpp_utilities.html b/src/shared/mpp/mpp_utilities.html deleted file mode 100644 index 1ffe3ac9b4..0000000000 --- a/src/shared/mpp/mpp_utilities.html +++ /dev/null @@ -1,112 +0,0 @@ - - - -Module mpp_utilities_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                        -

                                                        Module mpp_utilities_mod

                                                        - - -
                                                        -Contact:  -
                                                        -Reviewers:  -
                                                        -Change History: WebCVS Log -
                                                        -
                                                        -
                                                        - - -
                                                        -

                                                        OVERVIEW

                                                        - -

                                                        - - - -
                                                        -
                                                        - - -
                                                        -

                                                        OTHER MODULES USED

                                                        - -
                                                        -
                                                        mpp_mod
                                                        -
                                                        - - - -
                                                        -

                                                        PUBLIC INTERFACE

                                                        - -
                                                        - - -
                                                        -

                                                        PUBLIC ROUTINES

                                                        - -
                                                          -
                                                        1. - -

                                                          mpp_array_global_min_max

                                                          -
                                                          -
                                                          -DESCRIPTION -
                                                          -
                                                          - Compute and return the global min and max of an array - and the corresponding lat-lon-depth locations . - - NOTES: - This algorithm works only for an input array that has a unique global - max and min location. This is assured by introducing a factor that distinguishes - the values of extrema at each processor. - - Vectorized using maxloc() and minloc() intrinsic functions by - Russell.Fiedler@csiro.au (May 2005). - - Modified by Zhi.Liang (July 2005) - - Modified by Niki.Zadeh (Feb. 2009) - -
                                                          -
                                                          -
                                                          -
                                                          -
                                                        2. -
                                                        - - - - - - -
                                                        -
                                                        -top -
                                                        - - diff --git a/src/shared/mpp/nsclock.html b/src/shared/mpp/nsclock.html deleted file mode 100644 index 8bc1549943..0000000000 --- a/src/shared/mpp/nsclock.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -File shared/mpp/nsclock.c - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                        -

                                                        File shared/mpp/nsclock.c

                                                        - - -
                                                        -Contact:  -
                                                        -Reviewers:  -
                                                        -Change History: WebCVS Log -
                                                        -
                                                        -
                                                        - - -
                                                        -

                                                        OVERVIEW

                                                        - -

                                                        - - - -
                                                        -
                                                        - - -
                                                        -

                                                        MODULES USED

                                                        - -
                                                        -
                                                        
                                                        -
                                                        - - - -
                                                        -

                                                        PUBLIC INTERFACE

                                                        -
                                                        -
                                                        -
                                                        -
                                                        - - -
                                                        -

                                                        PUBLIC ROUTINES

                                                        - -
                                                          - - - - - - -
                                                          -
                                                          -top -
                                                          - - diff --git a/src/shared/mpp/test_mpp.html b/src/shared/mpp/test_mpp.html deleted file mode 100644 index 7b64a72d0f..0000000000 --- a/src/shared/mpp/test_mpp.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module null_mpp_test - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                          -

                                                          Module null_mpp_test

                                                          - - -
                                                          -Contact:  -
                                                          -Reviewers:  -
                                                          -Change History: WebCVS Log -
                                                          -
                                                          -
                                                          - - -
                                                          -

                                                          OVERVIEW

                                                          - -

                                                          - - - -
                                                          -
                                                          - - -
                                                          -

                                                          OTHER MODULES USED

                                                          - -
                                                          -
                                                          
                                                          -
                                                          - - - -
                                                          -

                                                          PUBLIC INTERFACE

                                                          -
                                                          -
                                                          -
                                                          -
                                                          - - -
                                                          -

                                                          PUBLIC ROUTINES

                                                          - -
                                                            - - - - - - -
                                                            -
                                                            -top -
                                                            - - diff --git a/src/shared/mpp/test_mpp_domains.F90 b/src/shared/mpp/test_mpp_domains.F90 index 7302f1e7ca..4a4adde0bf 100644 --- a/src/shared/mpp/test_mpp_domains.F90 +++ b/src/shared/mpp/test_mpp_domains.F90 @@ -50,6 +50,7 @@ program test logical :: test_cubic_grid_redistribute = .false. logical :: check_parallel = .FALSE. ! when check_parallel set to false, logical :: test_get_nbr = .FALSE. + logical :: test_boundary = .false. integer :: ensemble_size integer :: layout_cubic(2) = (/0,0/) integer :: layout_ensemble(2) = (/0,0/) @@ -66,6 +67,7 @@ program test integer :: npes_fine = 0 integer :: extra_halo = 0 logical :: mix_2D_3D = .false. + integer :: nthreads = 1 namelist / test_mpp_domains_nml / nx, ny, nz, stackmax, debug, mpes, check_parallel, & whalo, ehalo, shalo, nhalo, x_cyclic_offset, y_cyclic_offset, & @@ -75,11 +77,12 @@ program test jstart_fine, jend_fine, istart_coarse, iend_coarse, jstart_coarse, & jend_coarse, extra_halo, npes_fine, npes_coarse, mix_2D_3D, test_get_nbr, & test_edge_update, test_cubic_grid_redistribute, ensemble_size, & - layout_cubic, layout_ensemble + layout_cubic, layout_ensemble, nthreads, test_boundary integer :: i, j, k integer :: layout(2) integer :: id - integer :: outunit, errunit + integer :: outunit, errunit, io_status + integer :: get_cpu_affinity, base_cpu, omp_get_num_threads, omp_get_thread_num call mpp_memuse_begin() call mpp_init() @@ -87,7 +90,7 @@ program test outunit = stdout() errunit = stderr() #ifdef INTERNAL_FILE_NML - read (input_nml_file, test_mpp_domains_nml) + read (input_nml_file, test_mpp_domains_nml, status=io_status) #else do inquire( unit=unit, opened=opened ) @@ -95,12 +98,16 @@ program test unit = unit + 1 if( unit.EQ.100 )call mpp_error( FATAL, 'Unable to locate unit number.' ) end do - open( unit=unit, status='OLD', file='input.nml', err=10 ) - read( unit,test_mpp_domains_nml ) + open( unit=unit, file='input.nml', iostat=io_status ) + read( unit,test_mpp_domains_nml, iostat=io_status ) close(unit) -10 continue #endif + if (io_status > 0) then + call mpp_error(FATAL,'=>test_mpp_domains: Error reading input.nml') + endif + + select case(trim(warn_level)) case("fatal") call mpp_set_warn_level(FATAL) @@ -119,6 +126,12 @@ program test call mpp_domains_init(MPP_DOMAIN_TIME) end if call mpp_domains_set_stack_size(stackmax) + +!$ call omp_set_num_threads(nthreads) +!$ base_cpu = get_cpu_affinity() +!$OMP PARALLEL +!$ call set_cpu_affinity( base_cpu + omp_get_thread_num() ) +!$OMP END PARALLEL if( pe.EQ.mpp_root_pe() )print '(a,9i6)', 'npes, mpes, nx, ny, nz, whalo, ehalo, shalo, nhalo =', & npes, mpes, nx, ny, nz, whalo, ehalo, shalo, nhalo @@ -159,15 +172,18 @@ program test call cubic_grid_redistribute() endif + if(test_boundary) then + call test_get_boundary('Four-Tile') + call test_get_boundary('Cubic-Grid') + call test_get_boundary('Folded-north') + endif + if( test_interface ) then call test_modify_domain() !!$ call test_cyclic_offset('x_cyclic_offset') !!$ call test_cyclic_offset('y_cyclic_offset') !!$ call test_cyclic_offset('torus_x_offset') !!$ call test_cyclic_offset('torus_y_offset') - - call test_get_boundary('Four-Tile') - call test_get_boundary('Cubic-Grid') call test_uniform_mosaic('Single-Tile') call test_uniform_mosaic('Folded-north mosaic') ! one-tile tripolar grid call test_uniform_mosaic('Folded-north symmetry mosaic') ! one-tile tripolar grid @@ -245,7 +261,7 @@ program test contains subroutine test_openmp() -#ifdef _OPENMP +#ifdef _OPENMP_TEST integer :: omp_get_num_thread, omp_get_max_threads, omp_get_thread_num real, allocatable :: a(:,:,:) type(domain2D) :: domain @@ -536,8 +552,6 @@ subroutine test_redistribute( type ) dch =>NULL() call mpp_set_current_pelist() - - call mpp_sync() deallocate(gcheck, global) if(ALLOCATED(pelist)) deallocate(pelist) @@ -1790,10 +1804,11 @@ subroutine update_domains_performance( type ) if(ntile_per_pe == 1) then + allocate( x1(ism:iem,jsm:jem,nz, num_fields) ) + allocate( a1(ism:iem,jsm:jem,nz, num_fields) ) + if(mix_2D_3D) allocate( a1_2D(ism:iem,jsm:jem,num_fields) ) + do n = 1, num_iter - allocate( x1(ism:iem,jsm:jem,nz, num_fields) ) - allocate( a1(ism:iem,jsm:jem,nz, num_fields) ) - if(mix_2D_3D) allocate( a1_2D(ism:iem,jsm:jem,num_fields) ) do l = 1, num_fields x1(:,:,:,l) = x_save(:,:,:,1) a1(:,:,:,l) = x_save(:,:,:,1) @@ -1838,9 +1853,9 @@ subroutine update_domains_performance( type ) call compare_checksums( x1(:,:,:,l), a1(:,:,:,l), type//' X'//text) enddo if(mix_2D_3D)call compare_checksums( x1(:,:,1,:), a1_2D(:,:,:), type//' X 2D') - deallocate(x1, a1) - if(mix_2D_3D) deallocate(a1_2D) enddo + deallocate(x1, a1) + if(mix_2D_3D) deallocate(a1_2D) endif call mpp_clock_begin(id_single) @@ -1899,16 +1914,17 @@ subroutine update_domains_performance( type ) id1 = mpp_clock_id( trim(type)//' BGRID group', flags=MPP_CLOCK_SYNC) id2 = mpp_clock_id( trim(type)//' BGRID group non-blocking', flags=MPP_CLOCK_SYNC) - do n = 1, num_iter - if(ntile_per_pe == 1) then - allocate( x1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) - allocate( y1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) - allocate( a1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) - allocate( b1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) - if(mix_2D_3D) then - allocate( a1_2D(ism:iem+shift,jsm:jem+shift,num_fields) ) - allocate( b1_2D(ism:iem+shift,jsm:jem+shift,num_fields) ) - endif + if(ntile_per_pe == 1) then + allocate( x1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) + allocate( y1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) + allocate( a1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) + allocate( b1(ism:iem+shift,jsm:jem+shift,nz,num_fields) ) + if(mix_2D_3D) then + allocate( a1_2D(ism:iem+shift,jsm:jem+shift,num_fields) ) + allocate( b1_2D(ism:iem+shift,jsm:jem+shift,num_fields) ) + endif + + do n = 1, num_iter do l = 1, num_fields x1(:,:,:,l) = x_save(:,:,:,1) a1(:,:,:,l) = x_save(:,:,:,1) @@ -1971,10 +1987,10 @@ subroutine update_domains_performance( type ) call compare_checksums( x1(:,:,1,:), a1_2D(:,:,:), type//' BGRID X 2D') call compare_checksums( y1(:,:,1,:), b1_2D(:,:,:), type//' BGRID Y 2D') endif - deallocate(x1, y1, a1, b1) - if(mix_2D_3D) deallocate(a1_2D, b1_2D) - endif - enddo + enddo + deallocate(x1, y1, a1, b1) + if(mix_2D_3D) deallocate(a1_2D, b1_2D) + endif call mpp_clock_begin(id_single) call mpp_complete_update_domains(id_update_single, a, b, domain, gridtype=BGRID_NE) @@ -1988,7 +2004,6 @@ subroutine update_domains_performance( type ) deallocate(x, y, a, b, x_save, y_save) - !------------------------------------------------------------------ ! vector update : CGRID_NE, one extra point in each direction for cubic-grid !------------------------------------------------------------------ @@ -2038,16 +2053,17 @@ subroutine update_domains_performance( type ) id1 = mpp_clock_id( trim(type)//' CGRID group', flags=MPP_CLOCK_SYNC ) id2 = mpp_clock_id( trim(type)//' CGRID group non-blocking', flags=MPP_CLOCK_SYNC ) - do n = 1, num_iter - if(ntile_per_pe == 1) then - allocate( x1(ism:iem+shift,jsm:jem ,nz,num_fields) ) - allocate( y1(ism:iem ,jsm:jem+shift,nz,num_fields) ) - allocate( a1(ism:iem+shift,jsm:jem ,nz,num_fields) ) - allocate( b1(ism:iem ,jsm:jem+shift,nz,num_fields) ) - if(mix_2D_3D) then - allocate( a1_2D(ism:iem+shift,jsm:jem ,num_fields) ) - allocate( b1_2D(ism:iem ,jsm:jem+shift,num_fields) ) - endif + if(ntile_per_pe == 1) then + allocate( x1(ism:iem+shift,jsm:jem ,nz,num_fields) ) + allocate( y1(ism:iem ,jsm:jem+shift,nz,num_fields) ) + allocate( a1(ism:iem+shift,jsm:jem ,nz,num_fields) ) + allocate( b1(ism:iem ,jsm:jem+shift,nz,num_fields) ) + if(mix_2D_3D) then + allocate( a1_2D(ism:iem+shift,jsm:jem ,num_fields) ) + allocate( b1_2D(ism:iem ,jsm:jem+shift,num_fields) ) + endif + + do n = 1, num_iter do l = 1, num_fields x1(:,:,:,l) = x_save(:,:,:,1) a1(:,:,:,l) = x_save(:,:,:,1) @@ -2090,7 +2106,7 @@ subroutine update_domains_performance( type ) call mpp_clock_begin(id2) do l = 1, num_fields if(mix_2D_3D)call mpp_complete_update_domains(id_update, a1_2D(:,:,l), b1_2D(:,:,l), domain, & - gridtype=CGRID_NE, complete=l==.false.) + gridtype=CGRID_NE, complete=.false.) call mpp_complete_update_domains(id_update, a1(:,:,:,l), b1(:,:,:,l), domain, & gridtype=CGRID_NE, complete=l==num_fields) enddo @@ -2106,11 +2122,10 @@ subroutine update_domains_performance( type ) call compare_checksums( x1(:,:,1,:), a1_2D(:,:,:), type//' BGRID X 2D') call compare_checksums( y1(:,:,1,:), b1_2D(:,:,:), type//' BGRID Y 2D') endif - - deallocate(x1, y1, a1, b1) - if(mix_2D_3D) deallocate(a1_2D, b1_2D) - endif - enddo + enddo + deallocate(x1, y1, a1, b1) + if(mix_2D_3D) deallocate(a1_2D, b1_2D) + endif call mpp_clock_begin(id_single) call mpp_complete_update_domains(id_update_single, a, b, domain, gridtype=CGRID_NE) @@ -2304,6 +2319,38 @@ subroutine fill_four_tile_bound(data_all, is, ie, js, je, ioff, joff, tile, & end subroutine fill_four_tile_bound + + !################################################################################ + subroutine fill_folded_north_bound(data_all, is, ie, js, je, ioff, joff, tile, & + sbound, wbound) + real, dimension(:,:,:), intent(in) :: data_all + integer, intent(in) :: is, ie, js, je + integer, intent(in) :: tile, ioff, joff + real, dimension(:,:), optional, intent(inout) :: sbound, wbound + integer :: tw, te, ts, tn + + if(tile .NE. 1) call mpp_error(FATAL, "fill_folded_north_bound: tile must be 1") + + if(present(wbound)) then + if( is == 1 ) then + wbound(:,:) = data_all(nx+ioff, js:je+joff, :) + else + wbound(:,:) = data_all(is, js:je+joff, :) + end if + end if + + if(present(sbound)) then + if( js == 1 ) then + sbound(:,:) = 0 + else + sbound(:,:) = data_all(is:ie+ioff, js, :) + end if + end if + + return + + end subroutine fill_folded_north_bound + !################################################################################ subroutine fill_cubic_grid_bound(data1_all, data2_all, is, ie, js, je, ioff, joff, tile, sign1, sign2, & ebound, sbound, wbound, nbound ) @@ -3916,6 +3963,11 @@ subroutine test_get_boundary(type) real, allocatable, dimension(:,:,:,:) :: global_all, global1_all, global2_all real, allocatable, dimension(:,:,:,:) :: global, global1, global2 real, allocatable, dimension(:,:,:,:) :: x, x1, x2, y, y1, y2 + logical :: folded_north = .false. + integer :: nx_save, ny_save + + nx_save = nx + ny_save = ny !--- check the type select case(type) @@ -3925,11 +3977,11 @@ subroutine test_get_boundary(type) case ( 'Cubic-Grid' ) ntiles = 6 num_contact = 12 - if( nx .NE. ny) then - call mpp_error(NOTE,'TEST_MPP_DOMAINS: for Cubic_grid mosaic, nx should equal ny, '//& - 'No test is done for Cubic-Grid mosaic. ' ) - return - end if + nx = nx_cubic + ny = nx + case ( 'Folded-north' ) + folded_north = .true. + ntiles = 1 case default call mpp_error(FATAL, 'TEST_MPP_DOMAINS: no such test: '//type) end select @@ -3979,6 +4031,12 @@ subroutine test_get_boundary(type) layout2D, pe_start, pe_end, .true. ) case("Cubic-Grid") call define_cubic_mosaic(type, domain, ni, nj, global_indices, layout2D, pe_start, pe_end ) + case("Folded-north") + call mpp_define_domains((/1,nx,1,ny/), layout, domain, & + xflags=CYCLIC_GLOBAL_DOMAIN, yflags=FOLD_NORTH_EDGE, & + whalo=whalo, ehalo=ehalo, shalo=shalo, nhalo=nhalo, & + symmetry=.true., name='tripolar' ) + end select !--- Test the get_boundary of the data at C-cell center. @@ -4017,17 +4075,34 @@ subroutine test_get_boundary(type) allocate(sbuffer2(iec-isc+2, nz, ntile_per_pe), nbuffer2(iec-isc+2, nz, ntile_per_pe)) allocate(ebound(jec-jsc+2, nz, ntile_per_pe), wbound(jec-jsc+2, nz, ntile_per_pe)) allocate(sbound(iec-isc+2, nz, ntile_per_pe), nbound(iec-isc+2, nz, ntile_per_pe)) + ebound = 0; ebuffer = 0; ebuffer1 = 0; ebuffer2 = 0 + sbound = 0; sbuffer = 0; sbuffer1 = 0; sbuffer2 = 0 + wbound = 0; wbuffer = 0; wbuffer1 = 0; wbuffer2 = 0 + nbound = 0; nbuffer = 0; nbuffer1 = 0; nbuffer2 = 0 + do n = 1, ntile_per_pe - call mpp_get_boundary(x(:,:,:,n), domain, ebuffer=ebuffer(:,:,n), sbuffer=sbuffer(:,:,n), wbuffer=wbuffer(:,:,n), & - nbuffer=nbuffer(:,:,n), position=CORNER, tile_count=n ) + if(folded_north) then + call mpp_get_boundary(x(:,:,:,n), domain, sbuffer=sbuffer(:,:,n), wbuffer=wbuffer(:,:,n), & + position=CORNER, tile_count=n ) + else + call mpp_get_boundary(x(:,:,:,n), domain, ebuffer=ebuffer(:,:,n), sbuffer=sbuffer(:,:,n), wbuffer=wbuffer(:,:,n), & + nbuffer=nbuffer(:,:,n), position=CORNER, tile_count=n ) + endif end do !--- multiple variable do n = 1, ntile_per_pe - call mpp_get_boundary(x1(:,:,:,n), domain, ebuffer=ebuffer1(:,:,n), sbuffer=sbuffer1(:,:,n), wbuffer=wbuffer1(:,:,n), & - nbuffer=nbuffer1(:,:,n), position=CORNER, tile_count=n, complete = .false. ) - call mpp_get_boundary(x2(:,:,:,n), domain, ebuffer=ebuffer2(:,:,n), sbuffer=sbuffer2(:,:,n), wbuffer=wbuffer2(:,:,n), & - nbuffer=nbuffer2(:,:,n), position=CORNER, tile_count=n, complete = .true. ) + if(folded_north) then + call mpp_get_boundary(x1(:,:,:,n), domain, sbuffer=sbuffer1(:,:,n), wbuffer=wbuffer1(:,:,n), & + position=CORNER, tile_count=n, complete = .false. ) + call mpp_get_boundary(x2(:,:,:,n), domain, sbuffer=sbuffer2(:,:,n), wbuffer=wbuffer2(:,:,n), & + position=CORNER, tile_count=n, complete = .true. ) + else + call mpp_get_boundary(x1(:,:,:,n), domain, ebuffer=ebuffer1(:,:,n), sbuffer=sbuffer1(:,:,n), wbuffer=wbuffer1(:,:,n), & + nbuffer=nbuffer1(:,:,n), position=CORNER, tile_count=n, complete = .false. ) + call mpp_get_boundary(x2(:,:,:,n), domain, ebuffer=ebuffer2(:,:,n), sbuffer=sbuffer2(:,:,n), wbuffer=wbuffer2(:,:,n), & + nbuffer=nbuffer2(:,:,n), position=CORNER, tile_count=n, complete = .true. ) + endif end do !--- compare the buffer. @@ -4042,20 +4117,27 @@ subroutine test_get_boundary(type) call fill_cubic_grid_bound(global_all, global_all, isc, iec, jsc, jec, 1, 1, & tile(n), 1, 1, ebound(:,:,n), sbound(:,:,n), wbound(:,:,n), nbound(:,:,n) ) end do + case("Folded-north") + do n = 1, ntile_per_pe + call fill_folded_north_bound(global_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), sbound(:,:,n), wbound(:,:,n) ) + end do end select - call compare_checksums( ebound, ebuffer(:,:,:), "east bound of "//trim(type) ) + if(.not. folded_north) then + call compare_checksums( ebound, ebuffer(:,:,:), "east bound of "//trim(type) ) + call compare_checksums( nbound, nbuffer(:,:,:), "north bound of "//trim(type) ) + call compare_checksums( ebound, ebuffer1(:,:,:), "east bound of "//trim(type)//" X1" ) + call compare_checksums( nbound, nbuffer1(:,:,:), "north bound of "//trim(type)//" X1" ) + call compare_checksums( ebound*10, ebuffer2(:,:,:), "east bound of "//trim(type)//" X2" ) + call compare_checksums( nbound*10, nbuffer2(:,:,:), "north bound of "//trim(type)//" X2" ) + endif call compare_checksums( sbound, sbuffer(:,:,:), "south bound of "//trim(type) ) call compare_checksums( wbound, wbuffer(:,:,:), "west bound of "//trim(type) ) - call compare_checksums( nbound, nbuffer(:,:,:), "north bound of "//trim(type) ) - call compare_checksums( ebound, ebuffer1(:,:,:), "east bound of "//trim(type)//" X1" ) call compare_checksums( sbound, sbuffer1(:,:,:), "south bound of "//trim(type)//" X1" ) call compare_checksums( wbound, wbuffer1(:,:,:), "west bound of "//trim(type)//" X1" ) - call compare_checksums( nbound, nbuffer1(:,:,:), "north bound of "//trim(type)//" X1" ) - call compare_checksums( ebound*10, ebuffer2(:,:,:), "east bound of "//trim(type)//" X2" ) call compare_checksums( sbound*10, sbuffer2(:,:,:), "south bound of "//trim(type)//" X2" ) call compare_checksums( wbound*10, wbuffer2(:,:,:), "west bound of "//trim(type)//" X2" ) - call compare_checksums( nbound*10, nbuffer2(:,:,:), "north bound of "//trim(type)//" X2" ) !--- release memory deallocate(global, global_all, x, x1, x2) @@ -4117,23 +4199,46 @@ subroutine test_get_boundary(type) allocate(sbuffery2(iec-isc+2, nz, ntile_per_pe), nbuffery2(iec-isc+2, nz, ntile_per_pe)) allocate(eboundy(jec-jsc+2, nz, ntile_per_pe), wboundy(jec-jsc+2, nz, ntile_per_pe)) allocate(sboundy(iec-isc+2, nz, ntile_per_pe), nboundy(iec-isc+2, nz, ntile_per_pe)) + eboundx = 0; ebufferx = 0; ebufferx1 = 0; ebufferx2 = 0 + sboundx = 0; sbufferx = 0; sbufferx1 = 0; sbufferx2 = 0 + wboundx = 0; wbufferx = 0; wbufferx1 = 0; wbufferx2 = 0 + nboundx = 0; nbufferx = 0; nbufferx1 = 0; nbufferx2 = 0 + eboundy = 0; ebuffery = 0; ebuffery1 = 0; ebuffery2 = 0 + sboundy = 0; sbuffery = 0; sbuffery1 = 0; sbuffery2 = 0 + wboundy = 0; wbuffery = 0; wbuffery1 = 0; wbuffery2 = 0 + nboundy = 0; nbuffery = 0; nbuffery1 = 0; nbuffery2 = 0 + do n = 1, ntile_per_pe - call mpp_get_boundary(x(:,:,:,n), y(:,:,:,n), domain, ebufferx=ebufferx(:,:,n), sbufferx=sbufferx(:,:,n), & - wbufferx=wbufferx(:,:,n), nbufferx=nbufferx(:,:,n), ebuffery=ebuffery(:,:,n), & - sbuffery=sbuffery(:,:,n), wbuffery=wbuffery(:,:,n), nbuffery=nbuffery(:,:,n), & - gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR ) + if(folded_north) then + call mpp_get_boundary(x(:,:,:,n), y(:,:,:,n), domain, sbufferx=sbufferx(:,:,n), wbufferx=wbufferx(:,:,n), & + sbuffery=sbuffery(:,:,n), wbuffery=wbuffery(:,:,n), gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR ) + else + call mpp_get_boundary(x(:,:,:,n), y(:,:,:,n), domain, ebufferx=ebufferx(:,:,n), sbufferx=sbufferx(:,:,n), & + wbufferx=wbufferx(:,:,n), nbufferx=nbufferx(:,:,n), ebuffery=ebuffery(:,:,n), & + sbuffery=sbuffery(:,:,n), wbuffery=wbuffery(:,:,n), nbuffery=nbuffery(:,:,n), & + gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR ) + endif end do do n = 1, ntile_per_pe - call mpp_get_boundary(x1(:,:,:,n), y1(:,:,:,n), domain, ebufferx=ebufferx1(:,:,n), sbufferx=sbufferx1(:,:,n), & - wbufferx=wbufferx1(:,:,n), nbufferx=nbufferx1(:,:,n), ebuffery=ebuffery1(:,:,n), & - sbuffery=sbuffery1(:,:,n), wbuffery=wbuffery1(:,:,n), nbuffery=nbuffery1(:,:,n), & - gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR, complete = .false. ) - call mpp_get_boundary(x2(:,:,:,n), y2(:,:,:,n), domain, ebufferx=ebufferx2(:,:,n), sbufferx=sbufferx2(:,:,n), & - wbufferx=wbufferx2(:,:,n), nbufferx=nbufferx2(:,:,n), ebuffery=ebuffery2(:,:,n), & - sbuffery=sbuffery2(:,:,n), wbuffery=wbuffery2(:,:,n), nbuffery=nbuffery2(:,:,n), & - gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR, complete = .true. ) + if(folded_north) then + call mpp_get_boundary(x1(:,:,:,n), y1(:,:,:,n), domain, sbufferx=sbufferx1(:,:,n), wbufferx=wbufferx1(:,:,n), & + sbuffery=sbuffery1(:,:,n), wbuffery=wbuffery1(:,:,n), & + gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR, complete = .false. ) + call mpp_get_boundary(x2(:,:,:,n), y2(:,:,:,n), domain, sbufferx=sbufferx2(:,:,n), wbufferx=wbufferx2(:,:,n), & + sbuffery=sbuffery2(:,:,n), wbuffery=wbuffery2(:,:,n), & + gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR, complete = .true. ) + else + call mpp_get_boundary(x1(:,:,:,n), y1(:,:,:,n), domain, ebufferx=ebufferx1(:,:,n), sbufferx=sbufferx1(:,:,n), & + wbufferx=wbufferx1(:,:,n), nbufferx=nbufferx1(:,:,n), ebuffery=ebuffery1(:,:,n), & + sbuffery=sbuffery1(:,:,n), wbuffery=wbuffery1(:,:,n), nbuffery=nbuffery1(:,:,n), & + gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR, complete = .false. ) + call mpp_get_boundary(x2(:,:,:,n), y2(:,:,:,n), domain, ebufferx=ebufferx2(:,:,n), sbufferx=sbufferx2(:,:,n), & + wbufferx=wbufferx2(:,:,n), nbufferx=nbufferx2(:,:,n), ebuffery=ebuffery2(:,:,n), & + sbuffery=sbuffery2(:,:,n), wbuffery=wbuffery2(:,:,n), nbuffery=nbuffery2(:,:,n), & + gridtype=BGRID_NE, tile_count=n, flags = SCALAR_PAIR, complete = .true. ) + endif end do !--- compare the buffer. @@ -4152,24 +4257,34 @@ subroutine test_get_boundary(type) call fill_cubic_grid_bound(global2_all, global1_all, isc, iec, jsc, jec, 1, 1, & tile(n), 1, 1, eboundy(:,:,n), sboundy(:,:,n), wboundy(:,:,n), nboundy(:,:,n) ) end do + case("Folded-north") + do n = 1, ntile_per_pe + call fill_folded_north_bound(global1_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), sboundx(:,:,n), wboundx(:,:,n) ) + call fill_folded_north_bound(global2_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), sboundy(:,:,n), wboundy(:,:,n) ) + end do end select - call compare_checksums( eboundx, ebufferx(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" X" ) + if(.not. folded_north) then + call compare_checksums( eboundx, ebufferx(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" X" ) + call compare_checksums( nboundx, nbufferx(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" X" ) + call compare_checksums( eboundy, ebuffery(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" Y" ) + call compare_checksums( nboundy, nbuffery(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" Y" ) + call compare_checksums( eboundx, ebufferx1(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" X1" ) + call compare_checksums( nboundx, nbufferx1(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" X1" ) + call compare_checksums( eboundy, ebuffery1(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" Y1" ) + call compare_checksums( nboundy, nbuffery1(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" Y1" ) + endif + call compare_checksums( sboundx, sbufferx(:,:,:), "south bound of SCALAR_PAIR BGRID "//trim(type)//" X" ) call compare_checksums( wboundx, wbufferx(:,:,:), "west bound of SCALAR_PAIR BGRID " //trim(type)//" X" ) - call compare_checksums( nboundx, nbufferx(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" X" ) - call compare_checksums( eboundy, ebuffery(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" Y" ) call compare_checksums( sboundy, sbuffery(:,:,:), "south bound of SCALAR_PAIR BGRID "//trim(type)//" Y" ) call compare_checksums( wboundy, wbuffery(:,:,:), "west bound of SCALAR_PAIR BGRID " //trim(type)//" Y" ) - call compare_checksums( nboundy, nbuffery(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" Y" ) - call compare_checksums( eboundx, ebufferx1(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" X1" ) call compare_checksums( sboundx, sbufferx1(:,:,:), "south bound of SCALAR_PAIR BGRID "//trim(type)//" X1" ) call compare_checksums( wboundx, wbufferx1(:,:,:), "west bound of SCALAR_PAIR BGRID " //trim(type)//" X1" ) - call compare_checksums( nboundx, nbufferx1(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" X1" ) - call compare_checksums( eboundy, ebuffery1(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" Y1" ) call compare_checksums( sboundy, sbuffery1(:,:,:), "south bound of SCALAR_PAIR BGRID "//trim(type)//" Y1" ) call compare_checksums( wboundy, wbuffery1(:,:,:), "west bound of SCALAR_PAIR BGRID " //trim(type)//" Y1" ) - call compare_checksums( nboundy, nbuffery1(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" Y1" ) select case(type) case("Four-Tile") @@ -4186,16 +4301,93 @@ subroutine test_get_boundary(type) call fill_cubic_grid_bound(global2_all*10, global1_all*10, isc, iec, jsc, jec, 1, 1, & tile(n), 1, 1, eboundy(:,:,n), sboundy(:,:,n), wboundy(:,:,n), nboundy(:,:,n) ) end do + case("Folded-north") + do n = 1, ntile_per_pe + call fill_folded_north_bound(global1_all(:,:,:,1)*10, isc, iec, jsc, jec, 1, 1, & + tile(n), sboundx(:,:,n), wboundx(:,:,n) ) + call fill_folded_north_bound(global2_all(:,:,:,1)*10, isc, iec, jsc, jec, 1, 1, & + tile(n), sboundy(:,:,n), wboundy(:,:,n) ) + end do end select - call compare_checksums( eboundx, ebufferx2(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" X2" ) + if(.not. folded_north) then + call compare_checksums( eboundx, ebufferx2(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" X2" ) + call compare_checksums( nboundx, nbufferx2(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" X2" ) + call compare_checksums( eboundy, ebuffery2(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" Y2" ) + call compare_checksums( nboundy, nbuffery2(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" Y2" ) + endif call compare_checksums( sboundx, sbufferx2(:,:,:), "south bound of SCALAR_PAIR BGRID "//trim(type)//" X2" ) call compare_checksums( wboundx, wbufferx2(:,:,:), "west bound of SCALAR_PAIR BGRID " //trim(type)//" X2" ) - call compare_checksums( nboundx, nbufferx2(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" X2" ) - call compare_checksums( eboundy, ebuffery2(:,:,:), "east bound of SCALAR_PAIR BGRID " //trim(type)//" Y2" ) call compare_checksums( sboundy, sbuffery2(:,:,:), "south bound of SCALAR_PAIR BGRID "//trim(type)//" Y2" ) call compare_checksums( wboundy, wbuffery2(:,:,:), "west bound of SCALAR_PAIR BGRID " //trim(type)//" Y2" ) - call compare_checksums( nboundy, nbuffery2(:,:,:), "north bound of SCALAR_PAIR BGRID "//trim(type)//" Y2" ) + + !------------------------------------------------------------------------------------------- + ! + ! Test 2-D Vector BGRID + ! + !------------------------------------------------------------------------------------------- + x = 0.; y = 0 + eboundx = 0; ebufferx = 0; ebufferx1 = 0; ebufferx2 = 0 + sboundx = 0; sbufferx = 0; sbufferx1 = 0; sbufferx2 = 0 + wboundx = 0; wbufferx = 0; wbufferx1 = 0; wbufferx2 = 0 + nboundx = 0; nbufferx = 0; nbufferx1 = 0; nbufferx2 = 0 + eboundy = 0; ebuffery = 0; ebuffery1 = 0; ebuffery2 = 0 + sboundy = 0; sbuffery = 0; sbuffery1 = 0; sbuffery2 = 0 + wboundy = 0; wbuffery = 0; wbuffery1 = 0; wbuffery2 = 0 + nboundy = 0; nbuffery = 0; nbuffery1 = 0; nbuffery2 = 0 + + x(isc:iec+1,jsc:jec+1,1,:) = global1(isc:iec+1,jsc:jec+1,1,:) + y(isc:iec+1,jsc:jec+1,1,:) = global2(isc:iec+1,jsc:jec+1,1,:) + + do n = 1, ntile_per_pe + if(folded_north) then + call mpp_get_boundary(x(:,:,1,n), y(:,:,1,n), domain, sbufferx=sbufferx(:,1,n), wbufferx=wbufferx(:,1,n), & + sbuffery=sbuffery(:,1,n), wbuffery=wbuffery(:,1,n), gridtype=BGRID_NE, tile_count=n) + else + call mpp_get_boundary(x(:,:,1,n), y(:,:,1,n), domain, ebufferx=ebufferx(:,1,n), sbufferx=sbufferx(:,1,n), & + wbufferx=wbufferx(:,1,n), nbufferx=nbufferx(:,1,n), ebuffery=ebuffery(:,1,n), & + sbuffery=sbuffery(:,1,n), wbuffery=wbuffery(:,1,n), nbuffery=nbuffery(:,1,n), & + gridtype=BGRID_NE, tile_count=n) + endif + end do + + !--- compare the buffer. + select case(type) + case("Four-Tile") + do n = 1, ntile_per_pe + call fill_four_tile_bound(global1_all, isc, iec, jsc, jec, 1, 1, & + tile(n), eboundx(:,:,n), sboundx(:,:,n), wboundx(:,:,n), nboundx(:,:,n) ) + call fill_four_tile_bound(global2_all, isc, iec, jsc, jec, 1, 1, & + tile(n), eboundy(:,:,n), sboundy(:,:,n), wboundy(:,:,n), nboundy(:,:,n) ) + end do + case("Cubic-Grid") + do n = 1, ntile_per_pe + call fill_cubic_grid_bound(global1_all, global2_all, isc, iec, jsc, jec, 1, 1, & + tile(n), 1, -1, eboundx(:,:,n), sboundx(:,:,n), wboundx(:,:,n), nboundx(:,:,n) ) + call fill_cubic_grid_bound(global2_all, global1_all, isc, iec, jsc, jec, 1, 1, & + tile(n), -1, 1, eboundy(:,:,n), sboundy(:,:,n), wboundy(:,:,n), nboundy(:,:,n) ) + end do + case("Folded-north") + do n = 1, ntile_per_pe + call fill_folded_north_bound(global1_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), sboundx(:,:,n), wboundx(:,:,n) ) + call fill_folded_north_bound(global2_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), sboundy(:,:,n), wboundy(:,:,n) ) + end do + end select + + if(.not. folded_north) then + call compare_checksums( eboundx(:,1:1,:), ebufferx(:,1:1,:), "east bound of 2-D BGRID " //trim(type)//" X" ) + call compare_checksums( nboundx(:,1:1,:), nbufferx(:,1:1,:), "north bound of 2-D BGRID "//trim(type)//" X" ) + call compare_checksums( eboundy(:,1:1,:), ebuffery(:,1:1,:), "east bound of 2-D BGRID " //trim(type)//" Y" ) + call compare_checksums( nboundy(:,1:1,:), nbuffery(:,1:1,:), "north bound of 2-D BGRID "//trim(type)//" Y" ) + endif + + call compare_checksums( sboundx(:,1:1,:), sbufferx(:,1:1,:), "south bound of 2-D BGRID "//trim(type)//" X" ) + call compare_checksums( wboundx(:,1:1,:), wbufferx(:,1:1,:), "west bound of 2-D BGRID " //trim(type)//" X" ) + call compare_checksums( sboundy(:,1:1,:), sbuffery(:,1:1,:), "south bound of 2-D BGRID "//trim(type)//" Y" ) + call compare_checksums( wboundy(:,1:1,:), wbuffery(:,1:1,:), "west bound of 2-D BGRID " //trim(type)//" Y" ) + !--- release memory deallocate(global1, global1_all, global2, global2_all) @@ -4264,19 +4456,38 @@ subroutine test_get_boundary(type) allocate(sbuffery2(iec-isc+1, nz, ntile_per_pe), nbuffery2(iec-isc+1, nz, ntile_per_pe)) allocate(eboundx(jec-jsc+1, nz, ntile_per_pe), wboundx(jec-jsc+1, nz, ntile_per_pe)) allocate(sboundy(iec-isc+1, nz, ntile_per_pe), nboundy(iec-isc+1, nz, ntile_per_pe)) + eboundx = 0; ebufferx = 0; ebufferx1 = 0; ebufferx2 = 0 + wboundx = 0; wbufferx = 0; wbufferx1 = 0; wbufferx2 = 0 + sboundy = 0; sbuffery = 0; sbuffery1 = 0; sbuffery2 = 0 + nboundy = 0; nbuffery = 0; nbuffery1 = 0; nbuffery2 = 0 + do n = 1, ntile_per_pe - call mpp_get_boundary(x(:,:,:,n), y(:,:,:,n), domain, ebufferx=ebufferx(:,:,n), wbufferx=wbufferx(:,:,n), & - sbuffery=sbuffery(:,:,n), nbuffery=nbuffery(:,:,n), gridtype=CGRID_NE, tile_count=n ) + if(folded_north) then + call mpp_get_boundary(x(:,:,:,n), y(:,:,:,n), domain, wbufferx=wbufferx(:,:,n), & + sbuffery=sbuffery(:,:,n), gridtype=CGRID_NE, tile_count=n ) + else + call mpp_get_boundary(x(:,:,:,n), y(:,:,:,n), domain, ebufferx=ebufferx(:,:,n), wbufferx=wbufferx(:,:,n), & + sbuffery=sbuffery(:,:,n), nbuffery=nbuffery(:,:,n), gridtype=CGRID_NE, tile_count=n ) + endif end do do n = 1, ntile_per_pe - call mpp_get_boundary(x1(:,:,:,n), y1(:,:,:,n), domain, ebufferx=ebufferx1(:,:,n), wbufferx=wbufferx1(:,:,n), & - sbuffery=sbuffery1(:,:,n), nbuffery=nbuffery1(:,:,n), gridtype=CGRID_NE, tile_count=n, & - complete = .false. ) - call mpp_get_boundary(x2(:,:,:,n), y2(:,:,:,n), domain, ebufferx=ebufferx2(:,:,n), wbufferx=wbufferx2(:,:,n), & - sbuffery=sbuffery2(:,:,n), nbuffery=nbuffery2(:,:,n), gridtype=CGRID_NE, tile_count=n, & - complete = .true. ) + if( folded_north ) then + call mpp_get_boundary(x1(:,:,:,n), y1(:,:,:,n), domain, wbufferx=wbufferx1(:,:,n), & + sbuffery=sbuffery1(:,:,n), gridtype=CGRID_NE, tile_count=n, & + complete = .false. ) + call mpp_get_boundary(x2(:,:,:,n), y2(:,:,:,n), domain, wbufferx=wbufferx2(:,:,n), & + sbuffery=sbuffery2(:,:,n), gridtype=CGRID_NE, tile_count=n, & + complete = .true. ) + else + call mpp_get_boundary(x1(:,:,:,n), y1(:,:,:,n), domain, ebufferx=ebufferx1(:,:,n), wbufferx=wbufferx1(:,:,n), & + sbuffery=sbuffery1(:,:,n), nbuffery=nbuffery1(:,:,n), gridtype=CGRID_NE, tile_count=n, & + complete = .false. ) + call mpp_get_boundary(x2(:,:,:,n), y2(:,:,:,n), domain, ebufferx=ebufferx2(:,:,n), wbufferx=wbufferx2(:,:,n), & + sbuffery=sbuffery2(:,:,n), nbuffery=nbuffery2(:,:,n), gridtype=CGRID_NE, tile_count=n, & + complete = .true. ) + endif end do !--- compare the buffer. @@ -4295,16 +4506,25 @@ subroutine test_get_boundary(type) call fill_cubic_grid_bound(global2_all, global1_all, isc, iec, jsc, jec, 0, 1, & tile(n), -1, 1, sbound=sboundy(:,:,n), nbound=nboundy(:,:,n) ) end do + case("Folded-north") + do n = 1, ntile_per_pe + call fill_folded_north_bound(global1_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), wbound=wboundx(:,:,n) ) + call fill_folded_north_bound(global2_all(:,:,:,1), isc, iec, jsc, jec, 1, 1, & + tile(n), sbound=sboundy(:,:,n) ) + end do end select - call compare_checksums( eboundx, ebufferx(:,:,:), "east bound of CGRID " //trim(type)//" X" ) + if(.not. folded_north) then + call compare_checksums( eboundx, ebufferx(:,:,:), "east bound of CGRID " //trim(type)//" X" ) + call compare_checksums( nboundy, nbuffery(:,:,:), "north bound of CGRID "//trim(type)//" Y" ) + call compare_checksums( eboundx, ebufferx1(:,:,:), "east bound of CGRID " //trim(type)//" X1" ) + call compare_checksums( nboundy, nbuffery1(:,:,:), "north bound of CGRID "//trim(type)//" Y1" ) + endif call compare_checksums( wboundx, wbufferx(:,:,:), "west bound of CGRID " //trim(type)//" X" ) call compare_checksums( sboundy, sbuffery(:,:,:), "south bound of CGRID "//trim(type)//" Y" ) - call compare_checksums( nboundy, nbuffery(:,:,:), "north bound of CGRID "//trim(type)//" Y" ) - call compare_checksums( eboundx, ebufferx1(:,:,:), "east bound of CGRID " //trim(type)//" X1" ) call compare_checksums( wboundx, wbufferx1(:,:,:), "west bound of CGRID " //trim(type)//" X1" ) call compare_checksums( sboundy, sbuffery1(:,:,:), "south bound of CGRID "//trim(type)//" Y1" ) - call compare_checksums( nboundy, nbuffery1(:,:,:), "north bound of CGRID "//trim(type)//" Y1" ) select case(type) case("Four-Tile") @@ -4321,12 +4541,21 @@ subroutine test_get_boundary(type) call fill_cubic_grid_bound(global2_all*10, global1_all*10, isc, iec, jsc, jec, 0, 1, & tile(n), -1, 1, sbound=sboundy(:,:,n), nbound=nboundy(:,:,n) ) end do + case("Folded-north") + do n = 1, ntile_per_pe + call fill_folded_north_bound(global1_all(:,:,:,1)*10, isc, iec, jsc, jec, 1, 1, & + tile(n), wbound=wboundx(:,:,n) ) + call fill_folded_north_bound(global2_all(:,:,:,1)*10, isc, iec, jsc, jec, 1, 1, & + tile(n), sbound=sboundy(:,:,n) ) + end do end select - call compare_checksums( eboundx, ebufferx2(:,:,:), "east bound of CGRID " //trim(type)//" X2" ) + if(.not. folded_north) then + call compare_checksums( eboundx, ebufferx2(:,:,:), "east bound of CGRID " //trim(type)//" X2" ) + call compare_checksums( nboundy, nbuffery2(:,:,:), "north bound of CGRID "//trim(type)//" Y2" ) + endif call compare_checksums( wboundx, wbufferx2(:,:,:), "west bound of CGRID " //trim(type)//" X2" ) call compare_checksums( sboundy, sbuffery2(:,:,:), "south bound of CGRID "//trim(type)//" Y2" ) - call compare_checksums( nboundy, nbuffery2(:,:,:), "north bound of CGRID "//trim(type)//" Y2" ) !--- release memory deallocate(global1, global1_all, global2, global2_all) @@ -4339,6 +4568,9 @@ subroutine test_get_boundary(type) deallocate(ebuffery2, sbuffery2, wbuffery2, nbuffery2) deallocate(eboundx, sboundy, wboundx, nboundy ) + nx = nx_save + ny = ny_save + end subroutine test_get_boundary !###################################################################################### @@ -4992,14 +5224,15 @@ end subroutine set_corner_zero !################################################################################## subroutine test_update_edge( type ) character(len=*), intent(in) :: type - real, allocatable, dimension(:,:,:) :: x, x2 - real, allocatable, dimension(:,:,:) :: y, y2 + real, allocatable, dimension(:,:,:) :: x, x2, a + real, allocatable, dimension(:,:,:) :: y, y2, b type(domain2D) :: domain real, allocatable :: global1(:,:,:), global2(:,:,:), global(:,:,:) logical, allocatable :: maskmap(:,:) integer :: shift, i, xhalo, yhalo logical :: is_symmetry, folded_south, folded_west, folded_east integer :: is, ie, js, je, isd, ied, jsd, jed + integer :: id_update allocate(global(1-whalo:nx+ehalo,1-shalo:ny+nhalo,nz) ) @@ -5043,6 +5276,7 @@ subroutine test_update_edge( type ) call mpp_get_compute_domain( domain, is, ie, js, je ) call mpp_get_data_domain ( domain, isd, ied, jsd, jed ) allocate( x (isd:ied,jsd:jed,nz) ) + allocate( a (isd:ied,jsd:jed,nz) ) allocate( x2 (isd:ied,jsd:jed,nz) ) x2 (isd:ied,jsd:jed,:) = global(isd:ied,jsd:jed,:) call set_corner_zero(x2, isd, ied, jsd, jed, is, ie, js, je) @@ -5058,9 +5292,15 @@ subroutine test_update_edge( type ) call compare_checksums( x, x2, type ) deallocate(x2) + a = 0 + a(is:ie,js:je,:) = global(is:ie,js:je,:) + id_update = mpp_start_update_domains( a, domain, flags=EDGEUPDATE) + call mpp_complete_update_domains(id_update, a, domain, flags=EDGEUPDATE) + call compare_checksums( x, a, type//" nonblock") + !--- test vector update for FOLDED and MASKED case. if( type == 'Cyclic' ) then - deallocate(global, x) + deallocate(global, x, a) return end if @@ -5080,8 +5320,9 @@ subroutine test_update_edge( type ) end do end do end do - deallocate(x) + deallocate(x,a) allocate( x (isd:ied+1,jsd:jed+1,nz) ) + allocate( a (isd:ied+1,jsd:jed+1,nz) ) endif select case (type) @@ -5095,16 +5336,23 @@ subroutine test_update_edge( type ) end select x = 0. + a = 0. x(is:ie+shift,js:je+shift,:) = global(is:ie+shift,js:je+shift,:) + a(is:ie+shift,js:je+shift,:) = global(is:ie+shift,js:je+shift,:) !set up y array allocate( y (isd:ied+shift,jsd:jed+shift,nz) ) + allocate( b (isd:ied+shift,jsd:jed+shift,nz) ) + b = x y = x - id = mpp_clock_id( type//' vector BGRID_NE', flags=MPP_CLOCK_SYNC+MPP_CLOCK_DETAILED ) call mpp_clock_begin(id) call mpp_update_domains( x, y, domain, flags=EDGEUPDATE, gridtype=BGRID_NE) call mpp_clock_end (id) + !--nonblocking update + id_update = mpp_start_update_domains(a,b, domain, flags=EDGEUPDATE, gridtype=BGRID_NE) + call mpp_complete_update_domains(id_update, a,b, domain, flags=EDGEUPDATE, gridtype=BGRID_NE) + !redundant points must be equal and opposite @@ -5123,8 +5371,10 @@ subroutine test_update_edge( type ) call compare_checksums( x, x2, type//' BGRID_NE X' ) call compare_checksums( y, x2, type//' BGRID_NE Y' ) + call compare_checksums( a, x2, type//' BGRID_NE X nonblock' ) + call compare_checksums( b, x2, type//' BGRID_NE Y nonblock' ) - deallocate(global, x, y, x2) + deallocate(global, x, y, x2, a, b) !------------------------------------------------------------------ ! vector update : CGRID_NE @@ -5134,7 +5384,8 @@ subroutine test_update_edge( type ) allocate(global2(1-whalo:nx+ehalo, 1-shalo:ny+nhalo+shift, nz)) allocate(x (isd:ied+shift,jsd:jed,nz), y (isd:ied,jsd:jed+shift,nz) ) allocate(x2 (isd:ied+shift,jsd:jed,nz), y2 (isd:ied,jsd:jed+shift,nz) ) - + allocate(a (isd:ied+shift,jsd:jed,nz), b (isd:ied,jsd:jed+shift,nz) ) + global1 = 0.0 global2 = 0.0 do k = 1,nz @@ -5174,12 +5425,19 @@ subroutine test_update_edge( type ) x = 0.; y = 0. x(is:ie+shift,js:je, :) = global1(is:ie+shift,js:je, :) y(is:ie ,js:je+shift,:) = global2(is:ie, js:je+shift,:) + a = 0.; b = 0. + a(is:ie+shift,js:je, :) = global1(is:ie+shift,js:je, :) + b(is:ie ,js:je+shift,:) = global2(is:ie, js:je+shift,:) id = mpp_clock_id( type//' vector CGRID_NE', flags=MPP_CLOCK_SYNC+MPP_CLOCK_DETAILED ) call mpp_clock_begin(id) call mpp_update_domains( x, y, domain, flags=EDGEUPDATE, gridtype=CGRID_NE) call mpp_clock_end (id) + !--nonblocking + id_update = mpp_start_update_domains( a, b, domain, flags=EDGEUPDATE, gridtype=CGRID_NE) + call mpp_complete_update_domains(id_update, a, b, domain, flags=EDGEUPDATE, gridtype=CGRID_NE) + !redundant points must be equal and opposite global2(nx/2+1:nx, ny+shift,:) = -global2(nx/2:1:-1, ny+shift,:) global2(1-whalo:0, ny+shift,:) = -global2(nx-whalo+1:nx, ny+shift,:) @@ -5192,8 +5450,10 @@ subroutine test_update_edge( type ) call compare_checksums( x, x2, type//' CGRID_NE X' ) call compare_checksums( y, y2, type//' CGRID_NE Y' ) + call compare_checksums( a, x2, type//' CGRID_NE X nonblock' ) + call compare_checksums( b, y2, type//' CGRID_NE Y nonblock' ) - deallocate(global1, global2, x, y, x2, y2) + deallocate(global1, global2, x, y, x2, y2, a, b) end subroutine test_update_edge diff --git a/src/shared/mpp/test_mpp_domains.html b/src/shared/mpp/test_mpp_domains.html deleted file mode 100644 index ec2b0b3223..0000000000 --- a/src/shared/mpp/test_mpp_domains.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module null_mpp_domains_test - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                            -

                                                            Module null_mpp_domains_test

                                                            - - -
                                                            -Contact:  -
                                                            -Reviewers:  -
                                                            -Change History: WebCVS Log -
                                                            -
                                                            -
                                                            - - -
                                                            -

                                                            OVERVIEW

                                                            - -

                                                            - - - -
                                                            -
                                                            - - -
                                                            -

                                                            OTHER MODULES USED

                                                            - -
                                                            -
                                                            
                                                            -
                                                            - - - -
                                                            -

                                                            PUBLIC INTERFACE

                                                            -
                                                            -
                                                            -
                                                            -
                                                            - - -
                                                            -

                                                            PUBLIC ROUTINES

                                                            - -
                                                              - - - - - - -
                                                              -
                                                              -top -
                                                              - - diff --git a/src/shared/mpp/test_mpp_io.F90 b/src/shared/mpp/test_mpp_io.F90 index 17b60539cf..6579ea0e15 100644 --- a/src/shared/mpp/test_mpp_io.F90 +++ b/src/shared/mpp/test_mpp_io.F90 @@ -38,7 +38,7 @@ program test namelist / test_mpp_io_nml / nx, ny, nz, nt, halo, stackmax, stackmaxd, debug, file, iospec, & ntiles_x, ntiles_y, layout, io_layout - integer :: pe, npes + integer :: pe, npes, io_status type(domain2D) :: domain integer :: tks_per_sec @@ -53,23 +53,31 @@ program test type(fieldtype) :: f type(domain1D) :: xdom, ydom integer(LONG_KIND) :: rchk, chk - real(DOUBLE_KIND) :: doubledata + real(DOUBLE_KIND) :: doubledata = 0.0 real :: realarray(4) call mpp_init() pe = mpp_pe() npes = mpp_npes() +#ifdef INTERNAL_FILE_NML + read (input_nml_file, test_mpp_io_nml, status=io_status) +#else do inquire( unit=unit, opened=opened ) if( .NOT.opened )exit unit = unit + 1 if( unit.EQ.100 )call mpp_error( FATAL, 'Unable to locate unit number.' ) end do - open( unit=unit, status='OLD', file='input.nml', err=10 ) - read( unit,test_mpp_io_nml ) + open( unit=unit, file='input.nml', iostat=io_status) + read( unit,test_mpp_io_nml, iostat=io_status ) close(unit) -10 continue +#endif + + if (io_status > 0) then + call mpp_error(FATAL,'=>test_mpp_io: Error reading input.nml') + endif + call SYSTEM_CLOCK( count_rate=tks_per_sec ) if( debug )then diff --git a/src/shared/mpp/test_mpp_io.html b/src/shared/mpp/test_mpp_io.html deleted file mode 100644 index f6f0c43ffe..0000000000 --- a/src/shared/mpp/test_mpp_io.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module null_mpp_io_test - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                              -

                                                              Module null_mpp_io_test

                                                              - - -
                                                              -Contact:  -
                                                              -Reviewers:  -
                                                              -Change History: WebCVS Log -
                                                              -
                                                              -
                                                              - - -
                                                              -

                                                              OVERVIEW

                                                              - -

                                                              - - - -
                                                              -
                                                              - - -
                                                              -

                                                              OTHER MODULES USED

                                                              - -
                                                              -
                                                              
                                                              -
                                                              - - - -
                                                              -

                                                              PUBLIC INTERFACE

                                                              -
                                                              -
                                                              -
                                                              -
                                                              - - -
                                                              -

                                                              PUBLIC ROUTINES

                                                              - -
                                                                - - - - - - -
                                                                -
                                                                -top -
                                                                - - diff --git a/src/shared/mpp/test_mpp_pset.html b/src/shared/mpp/test_mpp_pset.html deleted file mode 100644 index cb99e5b513..0000000000 --- a/src/shared/mpp/test_mpp_pset.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Module null_mpp_pset_test - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                                -

                                                                Module null_mpp_pset_test

                                                                - - -
                                                                -Contact:  -
                                                                -Reviewers:  -
                                                                -Change History: WebCVS Log -
                                                                -
                                                                -
                                                                - - -
                                                                -

                                                                OVERVIEW

                                                                - -

                                                                - - - -
                                                                -
                                                                - - -
                                                                -

                                                                OTHER MODULES USED

                                                                - -
                                                                -
                                                                
                                                                -
                                                                - - - -
                                                                -

                                                                PUBLIC INTERFACE

                                                                -
                                                                -
                                                                -
                                                                -
                                                                - - -
                                                                -

                                                                PUBLIC ROUTINES

                                                                - -
                                                                  - - - - - - -
                                                                  -
                                                                  -top -
                                                                  - - diff --git a/src/shared/mpp/threadloc.html b/src/shared/mpp/threadloc.html deleted file mode 100644 index 4e50fc4c13..0000000000 --- a/src/shared/mpp/threadloc.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -File shared/mpp/threadloc.c - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES -
                                                                  -

                                                                  File shared/mpp/threadloc.c

                                                                  - - -
                                                                  -Contact:  -
                                                                  -Reviewers:  -
                                                                  -Change History: WebCVS Log -
                                                                  -
                                                                  -
                                                                  - - -
                                                                  -

                                                                  OVERVIEW

                                                                  - -

                                                                  - - - -
                                                                  -
                                                                  - - -
                                                                  -

                                                                  MODULES USED

                                                                  - -
                                                                  -
                                                                  
                                                                  -
                                                                  - - - -
                                                                  -

                                                                  PUBLIC INTERFACE

                                                                  -
                                                                  -
                                                                  -
                                                                  -
                                                                  - - -
                                                                  -

                                                                  PUBLIC ROUTINES

                                                                  - -
                                                                    - - - - - - -
                                                                    -
                                                                    -top -
                                                                    - - diff --git a/src/shared/oda_tools/oda_core.F90 b/src/shared/oda_tools/oda_core.F90 index 59b2ff9107..93f67dffa5 100644 --- a/src/shared/oda_tools/oda_core.F90 +++ b/src/shared/oda_tools/oda_core.F90 @@ -913,6 +913,7 @@ subroutine oda_core_init(Domain, Grid, localize) #ifdef INTERNAL_FILE_NML read (input_nml_file, oda_core_nml, iostat=io_status) + ierr = check_nml_error(io_status,'oda_core_nml') #else ioun = open_namelist_file() read(ioun,nml=oda_core_nml,iostat = io_status) @@ -1431,10 +1432,15 @@ subroutine init_observations(localize) character(len=256) :: record type(obs_entry_type) :: tbl_entry +#ifdef INTERNAL_FILE_NML + read (input_nml_file, ocean_obs_nml, iostat=io_status) + ierr = check_nml_error(io_status,'ocean_obs_nml') +#else ioun = open_namelist_file() read(ioun,nml=ocean_obs_nml,iostat = io_status) ierr = check_nml_error(io_status,'ocean_obs_nml') call close_file(ioun) +#endif time_window(:) = set_time(0,data_window) diff --git a/src/shared/oda_tools/oda_core_ecda.F90 b/src/shared/oda_tools/oda_core_ecda.F90 new file mode 100644 index 0000000000..fb6d643b93 --- /dev/null +++ b/src/shared/oda_tools/oda_core_ecda.F90 @@ -0,0 +1,3601 @@ +! -*- f90 -*- +module oda_core_ecda_mod + ! FMS Shared modules + use fms_mod, only : file_exist, read_data + use fms_mod, only : open_namelist_file, check_nml_error, close_file + use fms_mod, only : error_mesg, FATAL, NOTE +#ifdef INTERNAL_FILE_NML + USE mpp_mod, ONLY: input_nml_file +#endif + use mpp_mod, only : mpp_sum, stdout, stdlog, mpp_sync_self + use mpp_mod, only : mpp_pe, mpp_root_pe + use mpp_io_mod, only : mpp_open, mpp_close, MPP_ASCII, MPP_RDONLY, MPP_MULTI, MPP_SINGLE, MPP_NETCDF + use mpp_io_mod, only : mpp_get_atts, mpp_get_info, mpp_get_fields, mpp_read, axistype, fieldtype, mpp_get_axes + use mpp_io_mod, only : mpp_get_axis_data, mpp_get_field_name + use mpp_domains_mod, only : mpp_get_compute_domain, mpp_get_data_domain + use mpp_domains_mod, only : domain2d, mpp_get_global_domain, mpp_update_domains + use mpp_domains_mod, only : mpp_global_field + use mpp_memutils_mod, only : mpp_print_memuse_stats + use time_manager_mod, only : time_type, set_time, set_date, get_date, get_time + use time_manager_mod, only : operator( <= ), operator( - ), operator( > ), operator ( < ) + use get_cal_time_mod, only : get_cal_time + use axis_utils_mod, only : frac_index + use horiz_interp_type_mod, only: horiz_interp_type + use horiz_interp_bilinear_mod, only : horiz_interp_bilinear_new + use constants_mod, only : DEG_TO_RAD + + ! ODA_tools modules + use oda_types_mod, only : ocean_profile_type, ocn_obs_flag_type, grid_type, obs_clim_type + use oda_types_mod, only : DROP_PROFILER, MOORING, SATELLITE, DRIFTER, SHIP, TEMP_ID, SALT_ID, MISSING_VALUE + use oda_types_mod, only : UNKNOWN, TAO + use xbt_adjust, only : xbt_drop_rate_adjust + + implicit none + + private + + public :: copy_obs, oda_core_init, open_profile_dataset, & + get_obs, get_obs_woa05t, get_obs_woa05s, get_obs_sst, get_obs_suv, & + get_obs_eta, open_profile_dataset_sst, ocn_obs, ssh_td, max_profiles + + ! Parameters + integer, parameter :: PROFILE_FILE = 1 + integer, parameter :: SFC_FILE = 2 + + ! oda_core_nml variables + real :: max_misfit = 5.0 !< used to inflate observation errors where the difference from the first guess is large + real :: ass_start_lat = -87.0 !< set obs domain + real :: ass_end_lat = 87.0 !< set obs domain + integer :: max_profiles = 50000 + namelist /oda_core_nml/ max_misfit, ass_start_lat, ass_end_lat, max_profiles + + ! Shared ocean_obs_nml namelist variables + real :: eta_obs_start_lat = -80.0 !< set obs domain + real :: eta_obs_end_lat = 85.0 !< set obs domain + real :: sst_obs_start_lat = -82.0 !< set obs domain + real :: sst_obs_end_lat = 89.0 !< set obs domain + + integer :: max_prflvs = 200 ! for vd test + + type(ocean_profile_type), target, dimension(:), allocatable :: profiles + + integer :: num_profiles, no_sst, no_prf, no_temp, no_salt, no_suv, no_eta ! total number of observations + integer :: no_woa05 + + integer :: isc, iec, jsc, jec, isd, ied, jsd, jed ! indices for local domain on model grid + integer :: isg, ieg, jsg, jeg + integer :: isd_filt, ied_filt, jsd_filt, jed_filt + integer :: isd_flt0, ied_flt0, jsd_flt0, jed_flt0 + integer :: nk + + real, dimension(:,:), allocatable, save :: mask_tao + + ! sst obs grid information + real, allocatable :: woa05_lon(:), woa05_lat(:), woa05_z(:) + real, allocatable :: sst_lon(:), sst_lat(:), obs_sst(:,:) + real, allocatable, save :: obs_woa05t(:,:,:), obs_woa05s(:,:,:) + integer :: nlon, nlat, nlev + integer :: nlon_woa, nlat_woa, nlev_woa + + ! time window for DROP, MOORING and SATELLITE data respectively + + type(time_type) , dimension(0:100), public :: time_window + + type(grid_type), pointer :: Grd + + type(horiz_interp_type) :: Interp + + real, allocatable, dimension(:, :) :: x_grid, y_grid, x_grid_uv, y_grid_uv + real :: lon_out(1, 1), lat_out(1, 1) + + type(ocn_obs_flag_type) :: ocn_obs + + integer :: ssh_td + + type obs_entry_type + character(len=128) :: filename + character(len=16) :: file_type + end type obs_entry_type + + +contains + + subroutine init_observations(time_s, time_e, filt_domain, localize) + type(time_type), intent(in) :: time_s, time_e + type(domain2d), intent(in) :: filt_domain + logical, intent(in), optional :: localize + + integer, parameter :: SUV_ID = 4, ETA_ID = 5, WOAT_ID = 11, WOAS_ID = 12 + + ! ocean_obs_nml variables + integer :: mooring_window = 5 + integer :: satellite_window = 10 + integer :: drop_window = 30 + integer :: drifter_window = 30 + integer :: ship_window = 30 + integer :: unknown_window = 30 + + logical :: prfs_obs, salt_obs, sst_obs, eta_obs, suv_obs + logical :: temp_obs_argo, salt_obs_argo, temp_obs_gtspp + logical :: temp_obs_woa05, salt_obs_woa05 + integer :: eta_obs_td = 10 + integer :: max_files = 30 + integer :: max_files_argo = 10 + integer :: max_files_gtspp = 10 + namelist /ocean_obs_nml/ mooring_window, satellite_window, drop_window,& + & drifter_window, ship_window, unknown_window,& + & prfs_obs, salt_obs, sst_obs, eta_obs, suv_obs,& + & temp_obs_argo, salt_obs_argo, temp_obs_gtspp,& + & temp_obs_woa05, salt_obs_woa05, eta_obs_td,& + & sst_obs_start_lat, sst_obs_end_lat, eta_obs_start_lat, eta_obs_end_lat,& + & max_files, max_files_argo, max_files_gtspp + + integer :: i, j, n, obs_variable + integer :: ioun, io_status, ierr + integer :: stdout_unit, stdlog_unit + integer :: nfiles, nrecs, unit + integer :: nfiles_argo, nrecs_argo, unit_argo + integer :: nfiles_gtspp, nrecs_gtspp, unit_gtspp + integer, dimension(:), allocatable :: filetype + integer, dimension(:), allocatable :: filetype_argo + integer, dimension(:), allocatable :: filetype_gtspp + + character(len=128) :: input_files_woa05t, input_files_woa05s + character(len=256) :: record + character(len=128), dimension(:), allocatable :: input_files + character(len=128), dimension(:), allocatable :: input_files_argo + character(len=128), dimension(:), allocatable :: input_files_gtspp + + type(obs_entry_type) :: tbl_entry + + stdout_unit = stdout() + stdlog_unit = stdlog() + +#ifdef INTERNAL_FILE_NML + read (input_nml_file, ocean_obs_nml, iostat=io_status) +#else + ioun = open_namelist_file() + read(UNIT=ioun, NML=ocean_obs_nml, IOSTAT=io_status) + ierr = check_nml_error(io_status,'ocean_obs_nml') + call close_file(ioun) +#endif + write (UNIT=stdlog_unit, NML=ocean_obs_nml) + + ! Allocate filetype* and input_files* variables + allocate(filetype(max_files), input_files(max_files)) + allocate(filetype_argo(max_files_argo), input_files_argo(max_files_argo)) + allocate(filetype_gtspp(max_files_gtspp), input_files_gtspp(max_files_gtspp)) + + filetype = -1 + filetype_argo = -1 + filetype_gtspp = -1 + input_files = '' + input_files_argo = '' + input_files_gtspp = '' + + if ( prfs_obs .or. salt_obs .or. temp_obs_argo .or. temp_obs_gtspp .or. salt_obs_argo ) then + ocn_obs%use_prf_as_obs = .true. + end if + ocn_obs%use_sst_as_obs = sst_obs + ocn_obs%use_ssh_as_obs = eta_obs + ocn_obs%use_suv_as_obs = suv_obs + ocn_obs%use_woa05_t = temp_obs_woa05 + ocn_obs%use_woa05_s = salt_obs_woa05 + ssh_td = eta_obs_td + + ! time window for DROP, MOORING and SATELLITE data respectively + ! will be available from namelist + time_window(:) = set_time(0,unknown_window) + time_window(DROP_PROFILER:DROP_PROFILER+9) = set_time(0,drop_window) + time_window(MOORING:MOORING+9) = set_time(0,mooring_window) + time_window(SATELLITE:SATELLITE+9) = set_time(0,satellite_window) + time_window(DRIFTER:DRIFTER+9) = set_time(0,drifter_window) + time_window(SHIP:SHIP+9) = set_time(0,ship_window) + + nfiles = 0 + nrecs=0 + call mpp_open(unit, 'ocean_obs_table', action=MPP_RDONLY) + read_obs: do while ( nfiles <= max_files ) + read (UNIT=unit, FMT='(A)', IOSTAT=io_status) record + if ( io_status < 0 ) then + exit read_obs + else if ( io_status > 0 ) then + cycle read_obs + else + nrecs = nrecs + 1 + if ( record(1:1) == '#' ) cycle read_obs + read ( UNIT=record, FMT=*, IOSTAT=io_status ) tbl_entry + if ( io_status < 0 ) then + exit read_obs + else if ( io_status > 0 ) then + cycle read_obs + else + nfiles = nfiles + 1 + input_files(nfiles) = tbl_entry%filename + select case ( trim(tbl_entry%file_type) ) + case ('profiles') + filetype(nfiles) = PROFILE_FILE + case ('sfc') + filetype(nfiles) = SFC_FILE + case default + call error_mesg('oda_core_mod::init_observations', 'error in obs_table entry format', FATAL) + end select + end if + end if + end do read_obs + if ( nfiles > max_files ) then + call error_mesg('oda_core_mod::init_observations', 'number of obs files exceeds max_files parameter', FATAL) + end if + CALL mpp_close(unit) + + nfiles_argo = 0 + nrecs_argo = 0 + call mpp_open(unit_argo, 'ocean_obs_argo_table', action=MPP_RDONLY) + read_obs_argo: do while ( nfiles_argo <= max_files_argo ) + read (UNIT=unit_argo, FMT='(A)', IOSTAT=io_status) record + if ( io_status < 0 ) then + exit read_obs_argo + else if ( io_status > 0 ) then + cycle read_obs_argo + else + nrecs_argo = nrecs_argo + 1 + if ( record(1:1) == '#' ) cycle read_obs_argo + read (UNIT=record, FMT=*, IOSTAT=io_status) tbl_entry + if ( io_status < 0 ) then + exit read_obs_argo + else if ( io_status > 0 ) then + cycle read_obs_argo + else + nfiles_argo = nfiles_argo + 1 + input_files_argo(nfiles_argo) = tbl_entry%filename + select case ( trim(tbl_entry%file_type) ) + case ('profiles') + filetype_argo(nfiles_argo) = PROFILE_FILE + case ('sfc') + filetype_argo(nfiles_argo) = SFC_FILE + case default + call error_mesg('oda_core_mod::init_observations', 'error in obs_table entry format for argo', FATAL) + end select + end if + end if + end do read_obs_argo + if ( nfiles_argo > max_files_argo ) then + call error_mesg('oda_core_mod::init_observations', 'number of obs files exceeds max_files_argo parameter', FATAL) + end if + call mpp_close(unit_argo) + + nfiles_gtspp = 0 + nrecs_gtspp = 0 + call mpp_open(unit_gtspp, 'ocean_obs_gtspp_table', action=MPP_RDONLY) + read_obs_gtspp: do while ( nfiles_gtspp <= max_files_gtspp ) + read (UNIT=unit_gtspp, FMT='(A)', IOSTAT=io_status) record + if ( io_status < 0 ) then + exit read_obs_gtspp + else if ( io_status > 0 ) then + cycle read_obs_gtspp + else + nrecs_gtspp = nrecs_gtspp + 1 + if ( record(1:1) == '#' ) cycle read_obs_gtspp + read (UNIT=record, FMT=*, IOSTAT=io_status) tbl_entry + if ( io_status < 0 ) then + exit read_obs_gtspp + else if ( io_status > 0 ) then + cycle read_obs_gtspp + else + nfiles_gtspp = nfiles_gtspp + 1 + input_files_gtspp(nfiles_gtspp) = tbl_entry%filename + select case ( trim(tbl_entry%file_type) ) + case ('profiles') + filetype_gtspp(nfiles_gtspp) = PROFILE_FILE + case ('sfc') + filetype_gtspp(nfiles_gtspp) = SFC_FILE + case default + call error_mesg('oda_core_mod::init_observations', 'error in obs_table entry format for gtspp', FATAL) + end select + end if + end if + end do read_obs_gtspp + if ( nfiles_gtspp > max_files_gtspp ) then + call error_mesg('oda_core_mod::init_observations', 'number of obs files exceeds max_files_gtspp parameter', FATAL) + end if + CALL mpp_close(unit_gtspp) + + num_profiles = 0 + no_prf = 0 + no_sst = 0 + no_temp = 0 + no_salt = 0 + no_suv = 0 + no_eta = 0 + no_woa05 = 0 + + ! get local indices for Model grid + allocate(x_grid(isg:ieg,jsg:jeg), x_grid_uv(isg:ieg,jsg:jeg)) + allocate(y_grid(isg:ieg,jsg:jeg), y_grid_uv(isg:ieg,jsg:jeg)) + + call mpp_global_field(filt_domain, Grd%x(:,:), x_grid(:,:)) + call mpp_global_field(filt_domain, Grd%y(:,:), y_grid(:,:)) + + ! Allocate profiles + allocate(profiles(max_profiles)) + + do j=jsg, jeg + do i=isg, ieg + if ( x_grid(i,j) .lt. 80.0 ) x_grid(i,j) = x_grid(i,j) + 360.0 + end do + end do + + ! uv grid may not be precise, need to be carefully checked + x_grid_uv(:,:) = x_grid(:,:) + 0.5 + do j=jsg, jeg-1 + do i=isg, ieg + y_grid_uv(i,j) = y_grid(i,j) + 0.5*(y_grid(i,j+1)-y_grid(i,j)) + end do + end do + do i=isg, ieg + y_grid_uv(i,jeg) = 90.0 + end do + + if ( prfs_obs ) then + obs_variable = TEMP_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("TEMP_ID = ",I5)') TEMP_ID + end if + do n=1, nfiles + select case ( filetype(n) ) + case (PROFILE_FILE) + call open_profile_dataset(trim(input_files(n)), time_s, time_e, obs_variable, localize) + case default + call error_mesg('oda_core_mod::init_observations', 'filetype not currently supported for prfs_obs', FATAL) + end select + end do + end if + + if ( salt_obs ) then + obs_variable = SALT_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("SALT_ID = ",I5)') SALT_ID + end if + do n=1, nfiles + select case ( filetype(n) ) + case (PROFILE_FILE) + call open_profile_dataset(trim(input_files(n)), time_s, time_e, obs_variable, localize) + case default + call error_mesg('oda_core_mod::init_observations', 'filetype not currently supported for salt_obs', FATAL) + end select + end do + end if + + if ( temp_obs_gtspp ) then + obs_variable = TEMP_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("TEMP_ID = ",I5)') TEMP_ID + end if + do n=1, nfiles_gtspp + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("f_typ_gtspp = ",I8)') filetype_gtspp(n) + write (UNIT=stdout_unit, FMT='("i_f_gtspp = ",A)') input_files_gtspp(n) + end if + select case ( filetype_gtspp(n) ) + case (PROFILE_FILE) + call open_profile_dataset_gtspp() + case default + call error_mesg('oda_core_mod::init_observations', 'filetype_gtspp not currently supported', FATAL) + end select + end do + end if + + if ( temp_obs_argo ) then + obs_variable = TEMP_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("TEMP_ID = ",I5)') TEMP_ID + end if + do n=1, nfiles_argo + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("f_typ_argo = ",I8)') filetype_argo(n) + write (UNIT=stdout_unit, FMT='("i_f_argo = ",A)') input_files_argo(n) + end if + select case ( filetype_argo(n) ) + case (PROFILE_FILE) + call open_profile_dataset_argo(trim(input_files_argo(n)), time_s, time_e, obs_variable, localize) + case default + call error_mesg('oda_core_mod::init_observations', 'filetype_argo not currently supported', FATAL) + end select + end do + end if + + if ( salt_obs_argo ) then + obs_variable = SALT_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("SALT_ID = ",I5)') SALT_ID + end if + do n=1, nfiles_argo + select case ( filetype_argo(n) ) + case (PROFILE_FILE) + call open_profile_dataset_argo(trim(input_files_argo(n)), time_s, time_e, obs_variable, localize) + case default + call error_mesg('oda_core_mod::init_observations', 'filetype_argo not currently supported', FATAL) + end select + end do + end if + + if ( temp_obs_woa05 ) then + obs_variable = WOAT_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("WOAT_ID = ",I5)') WOAT_ID + end if + input_files_woa05t = "INPUT/woa05_temp.nc" + call open_profile_dataset_woa05t(trim(input_files_woa05t), obs_variable, localize) + end if + + if ( salt_obs_woa05 ) then + obs_variable = WOAS_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("WOAS_ID = ",I5)') WOAS_ID + end if + input_files_woa05s = "INPUT/woa05_salt.nc" + call open_profile_dataset_woa05s(trim(input_files_woa05s), obs_variable, localize) + end if + + if ( sst_obs ) then + obs_variable = TEMP_ID + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("TEMP_ID for sst = ",I5)') TEMP_ID + end if + nfiles = 1 + nrecs = 0 + input_files(nfiles) = "INPUT/sst_daily.nc" + filetype(nfiles) = PROFILE_FILE +!!$ call open_profile_dataset_sst(trim(input_files(nfiles)), obs_variable, localize) + end if + + if ( eta_obs ) then + obs_variable = ETA_ID + nfiles = 1 + nrecs = 0 + input_files(nfiles) = "INPUT/ocean.19760101-20001231.eta_t.nc" + filetype(nfiles) = PROFILE_FILE + call open_profile_dataset_eta(trim(input_files(nfiles)), obs_variable, localize) + end if + + if ( suv_obs ) then + obs_variable = SUV_ID + nfiles = 1 + nrecs = 0 + input_files(nfiles) = "INPUT/sfc_current.197601-200012.nc" + filetype(nfiles) = PROFILE_FILE + call open_profile_dataset_suv(trim(input_files(nfiles)), obs_variable, localize) + end if + + ! Deallocate before exiting routine + deallocate(filetype, input_files) + deallocate(filetype_argo, input_files_argo) + deallocate(filetype_gtspp, input_files_gtspp) + end subroutine init_observations + + subroutine open_profile_dataset(filename, time_start, time_end, obs_variable, localize) + character(len=*), intent(in) :: filename + type(time_type), intent(in) :: time_start, time_end + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 1000 + integer, parameter :: MAX_LNKS = 500 + + real :: lon, lat, time, profile_error, rlink, flag_t, flag_s, fix_depth + real :: ri0, rj0 + real, dimension(MAX_LEVELS) :: depth, data, t_flag, s_flag + real, dimension(MAX_LNKS, MAX_LEVELS) :: data_bfr, depth_bfr, t_flag_bfr, s_flag_bfr + + integer :: unit, ndim, nvar, natt, nstation + integer :: stdout_unit + integer :: inst_type, var_id + integer :: num_levs, k, kk, i, i0, j0, k0, nlevs, a, nn, ii, nlinks + integer :: nprof_in_filt_domain + integer :: bad_point, bad_point_g, out_bound_point + + logical :: data_is_local, localize_data, cont + logical :: data_in_period + logical :: prof_in_filt_domain + logical, dimension(MAX_LEVELS) :: flag + logical, dimension(MAX_LNKS, MAX_LEVELS) :: flag_bfr + + character(len=32) :: fldname, axisname, anal_fldname, time_units + character(len=138) :: emsg_local + + type(time_type) :: profile_time + type(axistype), pointer :: depth_axis, station_axis + type(axistype), allocatable, dimension(:), target :: axes + type(fieldtype), allocatable, dimension(:), target :: fields + type(fieldtype), pointer :: field_lon, field_lat, field_flag, field_time, field_depth, field_data + type(fieldtype), pointer :: field_error, field_link, field_t_flag, field_s_flag, field_fix_depth ! snz drop rate + + ! NOTE: fields are restricted to be in separate files + + if ( PRESENT(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + nprof_in_filt_domain = 0 + stdout_unit = stdout() + + anal_fldname = 'none' + var_id=-1 + if ( obs_variable == TEMP_ID ) then + anal_fldname = 'temp' + var_id = TEMP_ID + else if ( obs_variable == SALT_ID ) then + anal_fldname = 'salt' + var_id = SALT_ID + end if + +! call mpp_print_memuse_stats('open_profile_dataset Start') + + call mpp_open(unit, filename, form=MPP_NETCDF, fileset=MPP_SINGLE, threading=MPP_MULTI, action=MPP_RDONLY) + call mpp_get_info(unit, ndim, nvar, natt, nstation) + + if ( mpp_pe() .eq. mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("Opened profile dataset: ",A)') trim(filename) + end if + + ! get axis information + allocate(axes(ndim)) + call mpp_get_axes(unit, axes) + do i=1, ndim + call mpp_get_atts(axes(i), name=axisname) + select case ( trim(axisname) ) + case ('depth_index') + depth_axis => axes(i) + case ('station_index') + station_axis => axes(i) + end select + end do + + ! get field information + allocate(fields(nvar)) + call mpp_get_fields(unit, fields) + do i=1, nvar + call mpp_get_atts(fields(i), name=fldname) + if( var_id .eq. TEMP_ID ) then + select case (trim(fldname)) + case ('longitude') + field_lon => fields(i) + case ('latitude') + field_lat => fields(i) + case ('profile_flag') + field_flag => fields(i) + case ('time') + field_time => fields(i) + case ('temp') + field_data => fields(i) + case ('depth') + field_depth => fields(i) + case ('link') + field_link => fields(i) + case ('temp_error') + field_error => fields(i) + case ('temp_flag') + field_t_flag => fields(i) + case ('fix_depth') ! snz drop rate + field_fix_depth => fields(i) + end select + else if( var_id .eq. SALT_ID ) then + select case (trim(fldname)) + case ('longitude') + field_lon => fields(i) + case ('latitude') + field_lat => fields(i) + case ('profile_flag_s') + field_flag => fields(i) + case ('time') + field_time => fields(i) + case ('salt') + field_data => fields(i) + case ('depth') + field_depth => fields(i) + case ('link') + field_link => fields(i) + case ('salt_error') + field_error => fields(i) + case ('salt_flag') + field_s_flag => fields(i) + case ('fix_depth') ! snz drop rate + field_fix_depth => fields(i) + end select + end if + end do + + call mpp_get_atts(depth_axis, len=nlevs) + + if ( nlevs > MAX_LEVELS ) then + call error_mesg('oda_core_mod::open_profile_dataset', 'increase parameter MAX_LEVELS', FATAL) + else if (nlevs < 1) then + call error_mesg('oda_core_mod::open_profile_dataset', 'Value of nlevs is less than 1.', FATAL) + end if + + if ( .NOT.ASSOCIATED(field_data) ) then + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'profile dataset not used because data not needed for Analysis', NOTE) + return + end if + + write(UNIT=stdout_unit, FMT='("There are ",I8," records in this dataset.")') nstation + write(UNIT=stdout_unit, FMT='("Searching for profiles . . .")') + + call mpp_get_atts(field_time, units=time_units) + + bad_point = 0 + out_bound_point = 0 + + i = 1 + cont = .true. + + do while ( cont ) + prof_in_filt_domain = .false. + depth = missing_value ! snz add + data = missing_value ! snz add + + call mpp_read(unit, field_lon, lon, tindex=i) + call mpp_read(unit, field_lat, lat, tindex=i) + call mpp_read(unit, field_time, time, tindex=i) + call mpp_read(unit, field_depth, depth(1:nlevs), tindex=i) + call mpp_read(unit, field_data, data(1:nlevs), tindex=i) + call mpp_read(unit, field_error, profile_error, tindex=i) + call mpp_read(unit, field_fix_depth, fix_depth, tindex=i) ! snz drop rate + if ( var_id == TEMP_ID ) then + call mpp_read(unit, field_t_flag, t_flag(1:nlevs), tindex=i) + call mpp_read(unit, field_flag, flag_t, tindex=i) + else if ( var_id == SALT_ID ) then + call mpp_read(unit, field_s_flag, s_flag(1:nlevs), tindex=i) + call mpp_read(unit, field_flag, flag_s, tindex=i) + end if + call mpp_read(unit, field_link, rlink, tindex=i) + + inst_type = 20 ! snz change one line +!!$ inst_type = DRIFTER + ARGO + + data_is_local = .false. + data_in_period = .false. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat > ass_start_lat .and. lat < ass_end_lat ) data_is_local = .true. + + profile_time = get_cal_time(time, time_units, 'julian') + if ( profile_time > time_start .and. profile_time < time_end ) data_in_period = .true. + if ( (data_in_period .and. data_is_local) .and. (.NOT.localize_data) ) then ! localize + + if (isd_filt >= 1 .and. ied_filt <= ieg) then + if (lon >= x_grid(isd_filt,jsd_flt0) .and.& + & lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and.& + & lat <= y_grid(ied_filt-1,jed_flt0-1)) then + prof_in_filt_domain = .true. + end if + end if + if (isd_filt < 1) then + isd_flt0 = isd_filt + ieg + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_filt-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if ( lon >= x_grid(isd_flt0,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_flt0,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + if (ied_filt > ieg) then + ied_flt0 = ied_filt - ieg + if ( lon >= x_grid(isd_filt,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if (ied_flt0-1 > 1) then + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_flt0-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_flt0-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + end if + + if ( var_id == TEMP_ID .and. flag_t == 0.0 ) then + num_profiles = num_profiles + 1 + no_temp = no_temp + 1 + no_prf = no_prf + 1 + end if + if ( var_id == SALT_ID .and. flag_s == 0.0 ) then + num_profiles = num_profiles + 1 + no_salt = no_salt + 1 + no_prf = no_prf + 1 + end if + + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'maximum number of profiles exceeded, increase max_profiles in oda_core_nml', FATAL) + end if + + num_levs = 0 + do k=1, MAX_LEVELS + flag(k) = .true. + + if ( depth(k) > 2000.0 ) depth(k) = missing_value ! snz add for rdat-hybn + + if ( var_id == TEMP_ID ) then + if ( data(k) .eq. missing_value .or.& + & depth(k) .eq. missing_value .or. t_flag(k) .ne. 0.0 ) then + flag(k) = .false. + else + num_levs = num_levs + 1 + end if + else if ( var_id == SALT_ID ) then + if ( data(k) .eq. missing_value .or.& + & depth(k) .eq. missing_value .or. s_flag(k) .ne. 0.0 ) then + flag(k) = .false. + else + num_levs = num_levs+1 + end if + end if + end do + + ! large profile are stored externally in separate records + ! read linked records and combine profile + ii = i + 1 + nlinks = 0 + do while ( rlink > 0.0 ) + nlinks = nlinks + 1 + + if ( nlinks > MAX_LNKS ) then + write (emsg_local, '("nlinks (",I6,") > MAX_LNKS (",I6,")")')& + & nlinks, MAX_LNKS + call error_mesg('oda_core_mod::open_profile_dataset',& + & trim(emsg_local)//' in file "'//trim(filename)//& + & '". Increase parameter MAX_LNKS', FATAL) + end if + + depth_bfr(nlinks,:) = missing_value + data_bfr(nlinks,:) = missing_value + call mpp_read(unit, field_depth, depth_bfr(nlinks,1:nlevs), tindex=ii) + call mpp_read(unit, field_data, data_bfr(nlinks,1:nlevs), tindex=ii) + if ( var_id == TEMP_ID ) then + call mpp_read(unit, field_t_flag, t_flag_bfr(nlinks,1:nlevs), tindex=ii) + else if ( var_id == SALT_ID ) then + call mpp_read(unit, field_s_flag, s_flag_bfr(nlinks,1:nlevs), tindex=ii) + end if + call mpp_read(unit, field_link, rlink, tindex=ii) + ii = ii + 1 + end do + i = ii ! set record counter to start of next profile + + if ( nlinks > 0 ) then + do nn=1, nlinks + do k=1, MAX_LEVELS + flag_bfr(nn,k) = .true. + + if ( depth_bfr(nn,k) > 2000.0 ) depth_bfr(nn,k) = missing_value ! snz add for rdat-hybn + + if ( var_id == TEMP_ID ) then + if ( data_bfr(nn,k) .eq. missing_value .or.& + & depth_bfr(nn,k) .eq. missing_value .or.& + & t_flag_bfr(nn,k) .ne. 0.0 ) then + flag_bfr(nn,k) = .false. + else + num_levs = num_levs+1 + end if + else if (var_id == SALT_ID) then + if ( data_bfr(nn,k) .eq. missing_value .or.& + & depth_bfr(nn,k) .eq. missing_value .or.& + & s_flag_bfr(nn,k) .ne. 0.0 ) then + flag_bfr(nn,k) = .false. + else + num_levs = num_levs+1 + end if + end if + end do + end do + end if + + ! mh2 asks to change from [if (num_levs == 0) cycle] + if ( num_levs == 0 ) then + if ( i .gt. nstation ) cont = .false. + cycle + end if + + if ( num_profiles > 0 .and. prof_in_filt_domain ) then ! snz - 05 Nov 2012 + + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) + profiles(num_profiles)%variable = var_id + if ( inst_type < 1 ) inst_type = UNKNOWN + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon +! allocate(profiles(num_profiles)%ms(num_levs)) +! allocate(profiles(num_profiles)%ms_inv(num_levs)) +! profiles(num_profiles)%ms(:) = 0.5 + kk = 1 + do k=1, MAX_LEVELS + if ( flag(k) ) then + if ( kk > profiles(num_profiles)%levels ) then + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'Loop value "kk" is greater than profile levels', FATAL) + end if + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) +! profiles(num_profiles)%ms_inv(kk) = 1./profiles(num_profiles)%ms(kk) + kk = kk + 1 + end if + end do + + do nn=1, nlinks + do k=1, MAX_LEVELS + if ( flag_bfr(nn,k) ) then + if ( kk > profiles(num_profiles)%levels ) then + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'Loop value "kk" is greater than profile levels (bfr loop)', FATAL) + end if + profiles(num_profiles)%depth(kk) = depth_bfr(nn,k) + profiles(num_profiles)%data(kk) = data_bfr(nn,k) +! profiles(num_profiles)%ms_inv(kk) = 1./profiles(num_profiles)%ms(kk) + kk = kk + 1 + end if + end do + end do + + profiles(num_profiles)%time = profile_time + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + if ( lat < 65.0 ) then ! regular grids + ri0 = frac_index(lon, x_grid(:,1)) + rj0 = frac_index(lat, y_grid(90,:)) + i0 = floor(ri0) + j0 = floor(rj0) + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I8,", j0 = ",I8)') mpp_pe(), i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'For regular grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( isd_filt >= 1 .and. ied_filt <= ieg ) then + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in prfs01. '//trim(emsg_local), FATAL) + end if + end if + if ( isd_filt < 1 .and. i0 > ied_filt-1 .and. i0 < isd_filt + ieg ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in prfs02. '//trim(emsg_local), FATAL) + end if + if ( ied_filt > ieg .and. i0 > ied_filt-ieg-1 .and. ied_filt < isd_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in prfs03. '//trim(emsg_local), FATAL) + end if + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + else ! tripolar grids + lon_out(1,1) = (lon-360.0)*DEG_TO_RAD + lat_out(1,1) = lat*DEG_TO_RAD + call horiz_interp_bilinear_new (Interp, (x_grid-360.0)*DEG_TO_RAD, y_grid*DEG_TO_RAD,& + & lon_out, lat_out, new_search=.true., no_crash_when_not_found=.true.) + + if ( Interp%i_lon(1,1,1) == -999. ) bad_point = bad_point + 1 + if ( Interp%wti(1,1,2) < 1.0 ) then + i0 = Interp%i_lon(1,1,1) + else + i0 = Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + j0 = Interp%j_lat(1,1,1) + else + j0 = Interp%j_lat(1,1,2) + end if + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I6,", j0 = ",I6)') mpp_pe(), i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'For tripolar grids, either i0 > ieg or j0 > jeg', FATAL) + end if + if( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then +!!$ print*,'prfs.pe,i0,j0= ',mpp_pe(), i0, j0,& +!!$ & 'isd_filt,ied_filt,jsd_filt,jed_filt= ',isd_filt,ied_filt,jsd_filt,jed_filt +!!$ print*,'pe,lon,lat=',mpp_pe(),lon,lat,'x_grid(i0+-1)',x_grid(i0-1:i0+1,j0),& +!!$ & 'y_grid(i0,j0+-1)=',y_grid(i0,j0-1:j0+1) +!!$ print*,'lono11,lato11=',x_grid(i0,j0),y_grid(i0,j0),'lono21,lato21=',x_grid(i0+1,j0),y_grid(i0+1,j0) +!!$ print*,'lono12,lato12=',x_grid(i0,j0+1),y_grid(i0,j0+1),'lono22,lato22=',x_grid(i0+1,j0+1),y_grid(i0+1,j0+1) +!!$ print*,'lonm11,latm11=',x_grid(isd_filt,jsd_filt),y_grid(isd_filt,jsd_filt),& +!!$ & 'lonm21,latm21=',x_grid(ied_filt,jsd_filt),y_grid(ied_filt,jsd_filt) +!!$ print*,'lonm12,latm12=',x_grid(isd_filt,jed_filt),y_grid(isd_filt,jed_filt),& +!!$ & 'lonm22,latm22=',x_grid(ied_filt,jed_filt),y_grid(ied_filt,jed_filt) +!!$ print*,'wti(1:2)=',Interp%wti(1,1,:),'wtj(1:2)=',Interp%wtj(1,1,:) + + out_bound_point = out_bound_point + 1 + end if + if ( Interp%wti(1,1,2) < 1.0 ) then + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,1) + Interp%wti(1,1,2) + else + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,2) + end if + if (Interp%wtj(1,1,2) < 1.0) then + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,1) + Interp%wtj(1,1,2) + else + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,2) + end if + end if ! grids + + Profiles(num_profiles)%accepted = .true. + + if ( var_id == TEMP_ID .and. flag_t /= 0.0 ) Profiles(num_profiles)%accepted = .false. + if ( var_id == SALT_ID .and. flag_s /= 0.0 ) Profiles(num_profiles)%accepted = .false. + + if (i0 < 1 .or. j0 < 1) then + Profiles(num_profiles)%accepted = .false. + end if + if( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + Profiles(num_profiles)%accepted = .false. + end if + + if ( Profiles(num_profiles)%accepted ) then ! here + if ( i0 /= ieg .and. j0 /= jeg ) then + if (Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if (Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or. Grd%mask(i0+1,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else + if ( Grd%mask(i0,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + end if ! here + + if ( Profiles(num_profiles)%accepted .and.& + & Profiles(num_profiles)%inst_type == MOORING+TAO ) then + if ( allocated(mask_tao) ) then + if ( mask_tao(i0,j0) < 1.0 ) then + Profiles(num_profiles)%accepted = .false. + write (UNIT=stdout_unit,& + & FMT='("Rejecting tao mooring at (lat,lon) = (",F10.5,",",F10.5,") based on user-specified mask.")')& + & Profiles(num_profiles)%lat,& + & Profiles(num_profiles)%lon + end if + end if + end if + + if ( Profiles(num_profiles)%accepted ) then ! accepted + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + if (Profiles(num_profiles)%depth(k) < Grd%z(1)) then + Profiles(num_profiles)%k_index(k) = 1.0 + else + Profiles(num_profiles)%k_index(k) = frac_index(Profiles(num_profiles)%depth(k), (/0.,Grd%z(:)/))! - 1 snz modify to v3.2 JAN3012 + end if + if ( Profiles(num_profiles)%k_index(k) < 1.0 ) then + if ( Profiles(num_profiles)%depth(k) < 0.0 ) then + Profiles(num_profiles)%k_index(k) = 0.0 + else if ( Profiles(num_profiles)%depth(k) > Grd%z(size(Grd%z,1)) ) then + Profiles(num_profiles)%k_index(k) = real(nk) + end if + else + Profiles(num_profiles)%k_index(k) = Profiles(num_profiles)%k_index(k) - 1.0 + end if + if ( Profiles(num_profiles)%k_index(k) > real(nk) ) then + call error_mesg('oda_core_mod::open_profile_dataset', 'Profile k_index is greater than nk', FATAL) + else if ( Profiles(num_profiles)%k_index(k) < 0.0 ) then + call error_mesg('oda_core_mod::open_profile_dataset', 'Profile k_index is less than 0', FATAL) + end if + k0 = floor(Profiles(num_profiles)%k_index(k)) + + IF ( k0 >= 1 ) THEN ! snz add + if ( Profiles(num_profiles)%flag(k) ) then ! flag + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(1,j0+1,k0) == 0.0) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( i0 /= ieg .and. j0 /= jeg) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(1,j0+1,k0+1) == 0.0) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( abs(Profiles(num_profiles)%data(k)) > 1.e4 & + & .or. abs(Profiles(num_profiles)%depth(k)) > 1.e4 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if ! flag + end if ! snz add + end do + end if ! accepted + endif ! 05 Nov 2012 + else ! localize + i = i+1 + end if ! localize + + if ( var_id == TEMP_ID .and. num_profiles > 0 ) call xbt_drop_rate_adjust(Profiles(num_profiles)) + + if ( i .gt. nstation ) cont = .false. + end do + + a = nprof_in_filt_domain + bad_point_g = bad_point + call mpp_sum(a) + call mpp_sum(bad_point_g) + call mpp_sum(out_bound_point) + + if ( no_prf /= num_profiles ) then + write(UNIT=stdout_unit, FMT='("PE: ",I6," no_prf = ",I8,", num_profiles = ",I8)') mpp_pe(), no_prf, num_profiles + end if + if ( var_id == TEMP_ID ) then + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," temp prfs within global domain")') no_temp + write(UNIT=stdout_unit, FMT='("The total of bad_point temp ",I8," within global domain")') bad_point_g + write(UNIT=stdout_unit, FMT='("The total out_bound_point temp ",I8)') out_bound_point + else if ( var_id == SALT_ID ) then + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," salt prfs within global domain")') no_salt + write(UNIT=stdout_unit, FMT='("The total of bad_point salt",I8," within global domain")') bad_point_g + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," prfs within global domain")') no_prf + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," prfs within current PEs computer domain")') a + write(UNIT=stdout_unit, FMT='("The total out_bound_point salt ",I8)') out_bound_point + end if + + call mpp_sync_self() + call mpp_close(unit) + deallocate(axes) + deallocate(fields) + +! call mpp_print_memuse_stats('open_profile_dataset End') + + end subroutine open_profile_dataset + + subroutine open_profile_dataset_gtspp() + return + end subroutine open_profile_dataset_gtspp + + subroutine open_profile_dataset_argo(filename, time_start, time_end, obs_variable, localize) + character(len=*), intent(in) :: filename + type(time_type), intent(in) :: time_start, time_end + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 1000 + integer, parameter :: MAX_LNKS = 500 + + real :: lon, lat, time, rlink, prf_type + real :: ri0, rj0 + real, dimension(MAX_LEVELS) :: depth, data + real, dimension(MAX_LNKS, MAX_LEVELS) :: data_bfr, depth_bfr + + integer :: unit, ndim, nvar, natt, nstation + integer :: stdout_unit + integer :: inst_type, var_id + integer :: num_levs, k, kk, i, i0, j0, k0, nlevs, a, nn, ii, nlinks + integer :: nprof_in_filt_domain, out_bound_point + + character(len=32) :: fldname, axisname, anal_fldname, time_units + character(len=128) :: emsg_local + + logical :: data_is_local, localize_data, cont + logical :: data_in_period + logical :: prof_in_filt_domain + logical, dimension(MAX_LEVELS) :: flag + logical, dimension(MAX_LNKS, MAX_LEVELS) :: flag_bfr + + type(time_type) :: profile_time + type(axistype), pointer :: depth_axis, station_axis + type(axistype), allocatable, dimension(:), target :: axes + type(fieldtype), allocatable, dimension(:), target :: fields + type(fieldtype), pointer :: field_lon, field_lat, field_flag, field_time + type(fieldtype), pointer :: field_depth, field_data, field_link, field_var_type + + ! NOTE: fields are restricted to be in separate files + + stdout_unit = stdout() + + if ( PRESENT(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + nprof_in_filt_domain = 0 + + anal_fldname = 'none' + var_id=-1 + if ( obs_variable == TEMP_ID ) then + anal_fldname = 'temp' + var_id = TEMP_ID + else if ( obs_variable == SALT_ID ) then + anal_fldname = 'salt' + var_id = SALT_ID + end if + +! call mpp_print_memuse_stats('open_profile_dataset_argo Start') + + call mpp_open(unit, filename, form=MPP_NETCDF, fileset=MPP_SINGLE, threading=MPP_MULTI, action=MPP_RDONLY) + call mpp_get_info(unit, ndim, nvar, natt, nstation) + + write (UNIT=stdout_unit, FMT='("Opened profile dataset: ",A)') trim(filename) + + ! get axis information + + allocate(axes(ndim)) + call mpp_get_axes(unit, axes) + do i=1, ndim + call mpp_get_atts(axes(i), name=axisname) + select case (trim(axisname)) + case ('depth_index') + depth_axis => axes(i) + case ('station_index') + station_axis => axes(i) + end select + end do + + ! get field information + allocate(fields(nvar)) + call mpp_get_fields(unit, fields) + do i=1, nvar + call mpp_get_atts(fields(i), name=fldname) + if( var_id .eq. TEMP_ID ) then + select case (trim(fldname)) + case ('longitude') + field_lon => fields(i) + case ('latitude') + field_lat => fields(i) + case ('dens_flag') + field_flag => fields(i) + case ('time') + field_time => fields(i) + case ('temp') + field_data => fields(i) + case ('depth') + field_depth => fields(i) + case ('link') + field_link => fields(i) + case ('var_type') + field_var_type => fields(i) + end select + else if( var_id .eq. SALT_ID ) then + select case (trim(fldname)) + case ('longitude') + field_lon => fields(i) + case ('latitude') + field_lat => fields(i) + case ('dens_flag') + field_flag => fields(i) + case ('time') + field_time => fields(i) + case ('salt') + field_data => fields(i) + case ('depth') + field_depth => fields(i) + case ('link') + field_link => fields(i) + case ('var_type') + field_var_type => fields(i) + end select + end if + end do + + call mpp_get_atts(depth_axis, len=nlevs) + + if ( nlevs > MAX_LEVELS ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo', 'increase parameter MAX_LEVELS', FATAL) + else if (nlevs < 1) then + call error_mesg('oda_core_mod::open_profile_dataset_argo', 'nlevs less than 1.', FATAL) + end if + + if ( .NOT.ASSOCIATED(field_data) ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & 'profile dataset not used because data not needed for Analysis', NOTE) + return + end if + + write (UNIT=stdout_unit, FMT='("There are ",I8," records in this dataset")') nstation + write (UNIT=stdout_unit, FMT='("Searching for profiles . . .")') + + call mpp_get_atts(field_time, units=time_units) + + out_bound_point = 0 + + i=1 + cont=.true. + + do while (cont) + prof_in_filt_domain = .false. + depth = missing_value ! snz add + data = missing_value ! snz add + + call mpp_read(unit, field_lon, lon, tindex=i) + call mpp_read(unit, field_lat, lat, tindex=i) + call mpp_read(unit, field_time, time, tindex=i) + call mpp_read(unit, field_depth, depth(1:nlevs), tindex=i) + call mpp_read(unit, field_data, data(1:nlevs), tindex=i) + call mpp_read(unit, field_var_type, prf_type, tindex=i) + call mpp_read(unit, field_link, rlink, tindex=i) + +!!$ inst_type = DRIFTER + ARGO + inst_type = 20 ! snz change one line + data_is_local = .false. + data_in_period = .false. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat > ass_start_lat .and. lat < ass_end_lat ) data_is_local = .true. + + profile_time = get_cal_time(time, time_units, 'NOLEAP') + if ( profile_time > time_start .and. profile_time < time_end ) data_in_period = .true. + if ( (data_in_period .and. data_is_local) .and. (.NOT.localize_data) ) then + + if (isd_filt >= 1 .and. ied_filt <= ieg) then + if (lon >= x_grid(isd_filt,jsd_flt0) .and.& + & lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and.& + & lat <= y_grid(ied_filt-1,jed_flt0-1)) then + prof_in_filt_domain = .true. + end if + end if + if (isd_filt < 1) then + isd_flt0 = isd_filt + ieg + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_filt-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if ( lon >= x_grid(isd_flt0,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_flt0,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + if (ied_filt > ieg) then + ied_flt0 = ied_filt - ieg + if ( lon >= x_grid(isd_filt,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if (ied_flt0-1 > 1) then + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_flt0-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_flt0-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + end if + + if ( var_id == TEMP_ID ) then + num_profiles = num_profiles + 1 + no_temp = no_temp + 1 + no_prf = no_prf + 1 + else if ( var_id == SALT_ID .and. prf_type == 2.0 ) then + num_profiles =num_profiles + 1 + no_salt = no_salt + 1 + no_prf = no_prf + 1 + end if + + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & 'maximum number of profiles exceeded, increase max_profiles in oda_core_nml', FATAL) + end if + + num_levs = 0 + do k=1, MAX_LEVELS + flag(k) = .true. + if ( depth(k) > 2000.0 ) depth(k) = missing_value ! snz add for rdat-hybn + if ( var_id == TEMP_ID ) then + if ( data(k) .eq. missing_value .or. depth(k) .eq. missing_value ) then + flag(k) = .false. + else + num_levs = num_levs+1 + end if + else if ( var_id == SALT_ID ) then + if ( data(k) .eq. missing_value .or. depth(k) .eq. missing_value ) then + flag(k) = .false. + else + num_levs = num_levs+1 + end if + end if + end do + + ! large profile are stored externally in separate records + ! read linked records and combine profile + ii=i+1 + nlinks = 0 + do while ( rlink > 0.0 ) + nlinks = nlinks + 1 + + if ( nlinks > MAX_LNKS ) then + write (emsg_local, '("nlinks (",I6,") > MAX_LNKS (",I6,")")')& + & nlinks, MAX_LNKS + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & trim(emsg_local)//' in file "'//trim(filename)//& + & '". Increase parameter MAX_LNKS', FATAL) + end if + + depth_bfr(nlinks,:) = missing_value + data_bfr(nlinks,:) = missing_value + call mpp_read(unit,field_depth,depth_bfr(nlinks,1:nlevs),tindex=ii) + call mpp_read(unit,field_data,data_bfr(nlinks,1:nlevs),tindex=ii) + call mpp_read(unit,field_link,rlink,tindex=ii) + ii=ii+1 + end do + i=ii ! set record counter to start of next profile + + if ( nlinks > 0 ) then + do nn=1, nlinks + do k=1, MAX_LEVELS + flag_bfr(nn,k) = .true. + + if ( depth_bfr(nn,k) > 2000.0 ) depth_bfr(nn,k) = missing_value ! snz add for rdat-hybn + + if ( var_id == TEMP_ID ) then + if ( data_bfr(nn,k) .eq. missing_value .or. depth_bfr(nn,k) .eq. missing_value ) then + flag_bfr(nn,k) = .false. + else + num_levs = num_levs+1 + end if + else if ( var_id == SALT_ID ) then + if ( data_bfr(nn,k) .eq. missing_value .or. depth_bfr(nn,k) .eq. missing_value ) then + flag_bfr(nn,k) = .false. + else + num_levs = num_levs+1 + end if + end if + end do + end do + end if + + ! mh2 asks to change from [if (num_levs == 0) cycle] + if ( num_levs == 0 ) then + if ( i .gt. nstation ) cont = .false. + cycle + end if + + if (nprof_in_filt_domain > 0 .and. prof_in_filt_domain) then ! snz 05 Nov 2012 + + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) + profiles(num_profiles)%variable = var_id + if ( inst_type < 1 ) inst_type = UNKNOWN + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon +! allocate(profiles(num_profiles)%ms(num_levs)) +! allocate(profiles(num_profiles)%ms_inv(num_levs)) +! profiles(num_profiles)%ms(:) = 0.5 + + kk= 1 + do k=1, MAX_LEVELS + if ( flag(k) ) then + if ( kk > profiles(num_profiles)%levels ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & 'Loop variable "kk" is greater than profile levels', FATAL) + end if + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) +! profiles(num_profiles)%ms_inv(kk) = 1./profiles(num_profiles)%ms(kk) + kk = kk + 1 + end if + end do + + do nn=1, nlinks + do k=1, MAX_LEVELS + if ( flag_bfr(nn,k) ) then + if ( kk > profiles(num_profiles)%levels ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & 'Loop variable "kk" is greater than profile levels (bfr loop)', FATAL) + end if + profiles(num_profiles)%depth(kk) = depth_bfr(nn,k) + profiles(num_profiles)%data(kk) = data_bfr(nn,k) +! profiles(num_profiles)%ms_inv(kk) = 1./profiles(num_profiles)%ms(kk) + kk = kk + 1 + end if + end do + end do + + profiles(num_profiles)%time = profile_time + +! snz uses the following to test excluding the coast area salt profiles +! if (profiles(num_profiles)%variable == SALT_ID .and. & +! profiles(num_profiles)%depth(num_levs) < 900.0) profiles(num_profiles)%accepted = .false. + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + ! note that this only works for lat/lon grids + if ( lat < 65.0 ) then ! regular grids + ri0 = frac_index(lon, x_grid(:,1)) + rj0 = frac_index(lat, y_grid(90,:)) + i0 = floor(ri0) + j0 = floor(rj0) + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I6,", j0 = ",I6)') mpp_pe(), i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & 'For regular grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( isd_filt >= 1 .and. ied_filt <= ieg ) then + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in argo01. '//trim(emsg_local), FATAL) + end if + end if + if ( isd_filt < 1 .and. i0 > ied_filt-1 .and. i0 < isd_filt + ieg ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in argo02. '//trim(emsg_local), FATAL) + end if + if ( ied_filt > ieg .and. i0 > ied_filt-ieg-1 .and. ied_filt < isd_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in argo03. '//trim(emsg_local), FATAL) + end if + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + else ! tripolar grids + lon_out(1,1) = lon*DEG_TO_RAD + lat_out(1,1) = lat*DEG_TO_RAD + call horiz_interp_bilinear_new (Interp, x_grid*DEG_TO_RAD, y_grid*DEG_TO_RAD, lon_out, lat_out) + if(Interp%wti(1,1,2) < 1.0) then + i0 = Interp%i_lon(1,1,1) + else + i0 = Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + j0 = Interp%j_lat(1,1,1) + else + j0 = Interp%j_lat(1,1,2) + end if + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I6,", j0 = ",I6)') mpp_pe(), i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_argo',& + & 'For tirpolar grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then +!!$ print*,'argo.pe,i0,j0= ',mpp_pe(), i0, j0,& +!!$ & 'isd_filt,ied_filt,jsd_filt,jed_filt= ',isd_filt,ied_filt,jsd_filt,jed_filt +!!$ print*,'pe,lon,lat=',mpp_pe(),lon,lat,'x_grid(i0+-1)',x_grid(i0-1:i0+1,j0),& +!!$ & 'y_grid(i0,j0+-1)=',y_grid(i0,j0-1:j0+1) +!!$ print*,'lono11,lato11=',x_grid(i0,j0),y_grid(i0,j0),'lono21,lato21=',x_grid(i0+1,j0),y_grid(i0+1,j0) +!!$ print*,'lono12,lato12=',x_grid(i0,j0+1),y_grid(i0,j0+1),'lono22,lato22=',x_grid(i0+1,j0+1),y_grid(i0+1,j0+1) +!!$ print*,'lonm11,latm11=',x_grid(isd_filt,jsd_filt),y_grid(isd_filt,jsd_filt),& +!!$ & 'lonm21,latm21=',x_grid(ied_filt,jsd_filt),y_grid(ied_filt,jsd_filt) +!!$ print*,'lonm12,latm12=',x_grid(isd_filt,jed_filt),y_grid(isd_filt,jed_filt),& +!!$ & 'lonm22,latm22=',x_grid(ied_filt,jed_filt),y_grid(ied_filt,jed_filt) +!!$ print*,'wti(1:2)=',Interp%wti(1,1,:),'wtj(1:2)=',Interp%wtj(1,1,:) + + out_bound_point = out_bound_point + 1 + end if + if ( Interp%wti(1,1,2) < 1.0 ) then + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,1) + Interp%wti(1,1,2) + else + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,1) + Interp%wtj(1,1,2) + else + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,2) + end if + end if ! grids + + Profiles(num_profiles)%accepted = .true. + if ( i0 < 1 .or. j0 < 1 ) then + Profiles(num_profiles)%accepted = .false. + end if + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + Profiles(num_profiles)%accepted = .false. + end if + + if ( Profiles(num_profiles)%accepted ) then ! here + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if (Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(1,j0+1,1) == 0.0) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if (Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0) then + Profiles(num_profiles)%accepted = .false. + end if + else + if ( Grd%mask(i0,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + end if ! here + + if ( Profiles(num_profiles)%accepted .and. Profiles(num_profiles)%inst_type == MOORING+TAO) then + if ( allocated(mask_tao) ) then + if ( mask_tao(i0,j0) < 1.0 ) then + Profiles(num_profiles)%accepted = .false. + write (UNIT=stdout_unit,& + & FMT='("Rejecting tao mooring at (lat,lon) = (",F10.5,",",F10.5,") based on user-specified mask.")')& + & Profiles(num_profiles)%lat,& + & Profiles(num_profiles)%lon + end if + end if + end if + + if ( Profiles(num_profiles)%accepted ) then + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + if (Profiles(num_profiles)%depth(k) < Grd%z(1)) then + Profiles(num_profiles)%k_index(k) = 1.0 + else + Profiles(num_profiles)%k_index(k) = frac_index(Profiles(num_profiles)%depth(k), (/0.,Grd%z(:)/))! - 1 snz modify to v3.2 JAN3012 + end if + if ( Profiles(num_profiles)%k_index(k) < 1 ) then + if ( Profiles(num_profiles)%depth(k) < 0 ) then + Profiles(num_profiles)%k_index(k) = 0 + else if ( Profiles(num_profiles)%depth(k) > Grd%z(size(Grd%z,1)) ) then + Profiles(num_profiles)%k_index(k) = nk + end if + else + Profiles(num_profiles)%k_index(k) = Profiles(num_profiles)%k_index(k) - 1 + end if + if ( Profiles(num_profiles)%k_index(k) > nk ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo', 'Profile k_index is greater than nk', FATAL) + else if ( Profiles(num_profiles)%k_index(k) < 0 ) then + call error_mesg('oda_core_mod::open_profile_dataset_argo', 'Profile k_index is less than 0', FATAL) + end if + k0 = floor(Profiles(num_profiles)%k_index(k)) + + if ( k0 >= 1 ) then ! snz add + if ( Profiles(num_profiles)%flag(k) ) then ! flag + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(1,j0+1,k0+1) == 0.0) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( abs(Profiles(num_profiles)%data(k)) > 1.e4 & + & .or. abs(Profiles(num_profiles)%depth(k)) > 1.e4 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if ! flag + end if ! snz add + end do + end if ! accepted + + end if ! 05 Nov 2012 + + else ! localize + i = i+1 + end if ! localize + + if ( i .gt. nstation ) cont = .false. + end do + + a = nprof_in_filt_domain + call mpp_sum(a) + call mpp_sum(out_bound_point) + + if ( no_prf /= num_profiles ) then + write(UNIT=stdout_unit, FMT='("PE: ",I6," no_prf = ",I8,", num_profiles = ",I8)') mpp_pe(), no_prf, num_profiles + end if + if ( var_id == TEMP_ID ) then + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," argo temp prfs within global domain")') no_temp + write(UNIT=stdout_unit, FMT='("A total out of bound points",I8," argo temp within global domain")') out_bound_point + else if ( var_id == SALT_ID ) then + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," argo salt prfs within global domain")') no_salt + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," argo prfs within global domain")') no_prf + write(UNIT=stdout_unit, FMT='("A grand total of ",I8," argo prfs within current PEs computer domain")') a + write(UNIT=stdout_unit, FMT='("A total out of bound points",I8," argo salt within global domain")') out_bound_point + end if + + call mpp_sync_self() + call mpp_close(unit) + deallocate(axes) + deallocate(fields) + +! call mpp_print_memuse_stats('open_profile_dataset_argo End') + + end subroutine open_profile_dataset_argo + + ! get profiles and sfc + ! obs relevant to current analysis interval + subroutine get_obs(model_time, Prof, nprof) + type(time_type), intent(in) :: model_time + type(ocean_profile_type), dimension(:), intent(inout) :: Prof + integer, intent(inout) :: nprof + + integer :: i, k, kk, k_interval + integer :: yr, mon, day, hr, min, sec + integer :: stdout_unit + + type(time_type) :: tdiff + + nprof = 0 + stdout_unit = stdout() + + write (UNIT=stdout_unit, FMT='("Gathering profiles for current analysis time")') + call get_date(model_time, yr, mon, day, hr, min, sec) + write (UNIT=stdout_unit, FMT='("Current YYYY/MM/DD = ",I4,"/",I2,"/",I2)') yr, mon, day + + do i=1, no_prf + if ( Profiles(i)%time <= model_time ) then + tdiff = model_time - Profiles(i)%time + else + tdiff = Profiles(i)%time - model_time + end if + + ! no tdiff criteria for monthly mean data like + ! but tdiff criteria has to be set for daily data + if ( tdiff <= time_window(Profiles(i)%inst_type) .and. Profiles(i)%accepted ) then + ! for single profile test + + nprof = nprof + 1 + if ( nprof > size(Prof,1) ) then + call error_mesg('oda_core_mod::get_obs',& + & 'Passed in array "Prof" is smaller than number of profiles, increase size of Prof before call.',& + & FATAL) + end if + call copy_obs(Profiles(i:i), Prof(nprof:nprof)) + + Prof(nprof)%tdiff = tdiff + + ! snz add the following few lines for increasing deep water data + if ( Prof(nprof)%levels > max_prflvs ) then + k_interval = (Prof(nprof)%levels-max_prflvs+50)/50 + 1 + kk = max_prflvs - 50 + do k=max_prflvs-50+1, Prof(nprof)%levels, k_interval + kk = kk + 1 + Prof(nprof)%depth(kk) = Prof(nprof)%depth(k) + Prof(nprof)%k_index(kk) = Prof(nprof)%k_index(k) + Prof(nprof)%data(kk) = Prof(nprof)%data(k) + Prof(nprof)%flag(kk) = Prof(nprof)%flag(k) + end do + Prof(nprof)%levels = kk + end if + ! snz end the adding lines + end if + end do + + write (UNIT=stdout_unit,& + & FMT='("A total of ",I8," profiles are being used for the current analysis step.")') nprof + + return + end subroutine get_obs + + subroutine oda_core_init(Domain, Grid, time_s, time_e, filt_domain, localize) + type(domain2d), intent(inout) :: Domain + type(grid_type), target, intent(in) :: Grid + logical, intent(in), optional :: localize + type(time_type), intent(in) :: time_s, time_e + type(domain2d), intent(in) :: filt_domain + + integer :: ioun, ierr, io_status + integer :: stdlog_unit + + stdlog_unit = stdlog() + + ! Read in the namelist file +#ifdef INTERNAL_FILE_NML + read (input_nml_file, oda_core_nml, iostat=io_status) +#else + ioun = open_namelist_file() + read(ioun, NML=oda_core_nml, IOSTAT=io_status) + ierr = check_nml_error(io_status, 'oda_core_nml') + call close_file(ioun) +#endif + + write(stdlog_unit, NML=oda_core_nml) + + Grd => Grid + + call mpp_get_compute_domain(Domain, isc, iec, jsc, jec) + call mpp_get_data_domain(Domain, isd, ied, jsd, jed) + call mpp_get_global_domain(Domain, isg, ieg, jsg, jeg) + call mpp_get_data_domain(filt_domain, isd_filt, ied_filt, jsd_filt, jed_filt) + + jsd_flt0 = jsd_filt + jed_flt0 = jed_filt + if (jsd_filt < 1) jsd_flt0 = 1 + if (jed_filt > jeg) jed_flt0 = jeg + + nk = size(Grid%z) + + call init_observations(time_s, time_e, filt_domain, localize) + end subroutine oda_core_init + + subroutine copy_obs(obs_in, obs_out) + type(ocean_profile_type), dimension(:), intent(in) :: obs_in + type(ocean_profile_type), dimension(:), intent(inout) :: obs_out + + integer :: n + + if ( size(obs_in) .ne. size(obs_out) ) then + call error_mesg('oda_core_mod::copy_obs', 'Size of in and out obs variables are not equal.', FATAL) + end if + + do n=1, size(obs_in) + Obs_out(n)%variable = Obs_in(n)%variable + Obs_out(n)%inst_type = Obs_in(n)%inst_type + Obs_out(n)%levels = Obs_in(n)%levels + Obs_out(n)%lon = Obs_in(n)%lon + Obs_out(n)%lat = Obs_in(n)%lat + Obs_out(n)%accepted = Obs_in(n)%accepted + if ( associated(Obs_out(n)%depth) ) then + deallocate(Obs_out(n)%depth) + nullify(Obs_out(n)%depth) + end if + allocate(Obs_out(n)%depth(Obs_in(n)%levels)) + Obs_out(n)%depth(:) = Obs_in(n)%depth(:) + if ( associated(Obs_out(n)%data) ) then + deallocate(Obs_out(n)%data) + nullify(Obs_out(n)%data) + end if + allocate(Obs_out(n)%data(Obs_in(n)%levels)) + Obs_out(n)%data(:) = Obs_in(n)%data(:) + if ( associated(Obs_out(n)%flag) ) then + deallocate(Obs_out(n)%flag) + nullify(Obs_out(n)%flag) + end if + allocate(Obs_out(n)%flag(Obs_in(n)%levels)) + Obs_out(n)%flag(:) = Obs_in(n)%flag(:) + Obs_out(n)%time = Obs_in(n)%time + Obs_out(n)%yyyy = Obs_in(n)%yyyy + Obs_out(n)%mmdd = Obs_in(n)%mmdd + Obs_out(n)%i_index = Obs_in(n)%i_index + Obs_out(n)%j_index = Obs_in(n)%j_index + if ( associated(Obs_out(n)%k_index) ) then + deallocate(Obs_out(n)%k_index) + nullify(Obs_out(n)%k_index) + end if + allocate(Obs_out(n)%k_index(Obs_in(n)%levels)) + Obs_out(n)%k_index = Obs_in(n)%k_index + +! if ( associated(Obs_out(n)%ms) ) then +! deallocate(Obs_out(n)%ms) +! nullify(Obs_out(n)%ms) +! end if +! allocate(Obs_out(n)%ms(Obs_in(n)%levels)) +! Obs_out(n)%ms = Obs_in(n)%ms +! if ( associated(Obs_out(n)%ms_inv) ) then +! deallocate(Obs_out(n)%ms_inv) +! nullify(Obs_out(n)%ms_inv) +! end if +! allocate(Obs_out(n)%ms_inv(Obs_in(n)%levels)) +! Obs_out(n)%ms_inv = 1./Obs_in(n)%ms + + Obs_out(n)%tdiff = Obs_in(n)%tdiff + if ( associated(Obs_out(n)%Forward_model%wgt) ) then + deallocate(Obs_out(n)%Forward_model%wgt) + nullify(Obs_out(n)%Forward_model%wgt) + end if + end do + end subroutine copy_obs + + subroutine open_profile_dataset_sst(filename, obs_variable, localize) + character(len=*), intent(in) :: filename + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 1 + + real :: lon, lat, rms_err + real :: ri0, rj0 + real, dimension(MAX_LEVELS) :: depth, data + + integer :: unit, ndim, nvar, natt, ntime + integer :: var_id, inst_type + integer :: num_levs, k, kk, i, j, i0, j0 + integer :: stdout_unit + + logical :: data_is_local, localize_data + logical, dimension(MAX_LEVELS) :: flag + + character(len=32) :: axisname, anal_fldname + character(len=128) :: emsg_local + + type(axistype), dimension(:), allocatable, target :: axes + type(axistype), pointer :: lon_axis, lat_axis + + if ( PRESENT(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + stdout_unit = stdout() + + anal_fldname = 'temp' + var_id = obs_variable + + call mpp_open(unit, trim(filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + call mpp_get_info(unit, ndim, nvar, natt, ntime) + allocate(axes(ndim)) + call mpp_get_axes(unit, axes) + + do i=1, ndim + call mpp_get_atts(axes(i),name=axisname) + select case (trim(axisname)) +!!$ case ('GRIDLON_T') ! cm2 grids +!!$ case ('gridlon_t') ! cm2 grids + case ('XT_OCEAN') ! cm2.5 grids +!!$ case ('lon') ! after 2008 + lon_axis => axes(i) +!!$ case ('GRIDLAT_T') ! cm2 grids +!!$ case ('gridlat_t') ! cm2 grids + case ('YT_OCEAN') ! cm2 grids +!!$ case ('lat') ! for after 2008 + lat_axis => axes(i) + end select + end do + + call mpp_get_atts(lon_axis,len=nlon) + call mpp_get_atts(lat_axis,len=nlat) + if ( nlon /= 1440 .or. nlat /= 1070 ) then ! after 2008 + write (UNIT=emsg_local, FMT='("sst obs dim is not same as in file. nlon = ",I5,", nlat = ",I5)') nlon, nlat + call error_mesg('oda_core_mod::open_profile_dataset_sst', trim(emsg_local), FATAL) + end if + + ! idealized + do j=1, nlat + do i=1, nlon + lon = x_grid(i,j) + lat = y_grid(i,j) + rms_err = 0.5 + inst_type = 20 + data_is_local = .true. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat < sst_obs_start_lat .or. lat > sst_obs_end_lat ) data_is_local = .false. ! at the final test + + if ( Grd%mask(i,j,1) == 0 ) data_is_local = .false. + + if ( abs(lat) < 40.0 ) then + if ( i/4*4 /= i .or. j/4*4 /= j ) data_is_local = .false. + else if ( abs(lat) < 60.0 ) then + if ( i/8*8 /= i .or. j/6*6 /= j ) data_is_local = .false. + else + if ( i/16*16 /= i .or. j/8*8 /= j ) data_is_local = .false. + end if + + if ( data_is_local .and. (.NOT.localize_data) ) then + if ( lat < 60.0 ) then ! regular grids + ri0 = frac_index(lon, x_grid(:,nlat/2)) + rj0 = frac_index(lat, y_grid(nlon/4,:)) + i0 = floor(ri0) + j0 = floor(rj0) + else ! tripolar grids + lon_out(1,1) = lon*DEG_TO_RAD + lat_out(1,1) = lat*DEG_TO_RAD + call horiz_interp_bilinear_new (Interp, x_grid*DEG_TO_RAD, y_grid*DEG_TO_RAD, lon_out, lat_out) + if ( Interp%wti(1,1,2) < 1.0 ) then + i0 = Interp%i_lon(1,1,1) + else + i0 = Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + j0 = Interp%j_lat(1,1,1) + else + j0 = Interp%j_lat(1,1,2) + end if + + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I8,", j0 = ",I8)') i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_sst',& + & 'For tripolar grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + end if + + if ( i0 /= ieg .and. j0 /= jeg ) then ! exclude SSTs at ieg and jeg + if ( Grd%mask(i0,j0,1) /= 0.0 .and. Grd%mask(i0+1,j0,1) /= 0.0 .and.& + & Grd%mask(i0,j0+1,1) /= 0.0 .and. Grd%mask(i0+1,j0+1,1) /= 0.0 ) then + no_sst = no_sst+1 + num_profiles=num_profiles+1 + + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset_sst',& + & 'Maximum number of profiles exceeded, increase max_profiles in oda_core_nml', FATAL) + end if + + num_levs = 0 + flag = .false. + do k=1, 1 + flag(k) = .true. + data(k) = 0.0 + depth(k) = 0.0 + num_levs = num_levs + 1 + end do + if ( num_levs == 0 ) cycle + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) + allocate(profiles(num_profiles)%ms(num_levs)) + allocate(profiles(num_profiles)%ms_inv(num_levs)) + profiles(num_profiles)%variable = var_id + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon + + kk = 1 + do k=1, 1 + if ( flag(k) ) then + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) + profiles(num_profiles)%ms(kk) = 1.0 + profiles(num_profiles)%ms_inv(kk) = 1.0 + kk=kk+1 + end if + end do + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + if ( lat < 60.0 ) then ! for regular grids + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + else ! for tripolar grids + lon_out(1,1) = lon*DEG_TO_RAD + lat_out(1,1) = lat*DEG_TO_RAD + call horiz_interp_bilinear_new (Interp, x_grid*DEG_TO_RAD, y_grid*DEG_TO_RAD, lon_out, lat_out) + if ( Interp%wti(1,1,2) < 1.0 ) then + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,1) + Interp%wti(1,1,2) + else + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,1) + Interp%wtj(1,1,2) + else + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,2) + end if + end if + + Profiles(num_profiles)%accepted = .true. + if ( i0 < 1 .or. j0 < 1 ) then + Profiles(num_profiles)%accepted = .false. + end if + if ( Profiles(num_profiles)%accepted ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + if ( Profiles(num_profiles)%accepted ) then + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + Profiles(num_profiles)%k_index(k) = frac_index(depth(k), (/0.,Grd%z(:)/)) - 1 + !::sdu:: Do we need the same out-of-range check here? + end do + end if + end if ! exclude SSTs at ieg and jeg + end if + end if + end do + end do + + call mpp_close(unit) + deallocate(axes) + write (UNIT=stdout_unit, FMT='("A grand total of ",I8," sst points within global domain")') no_sst + write (UNIT=stdout_unit, FMT='("A final total @sst of ",I8," prfs within global domain")') num_profiles + end subroutine open_profile_dataset_sst + + subroutine open_profile_dataset_woa05t(filename, obs_variable, localize) + character(len=*), intent(in) :: filename + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 24 + + real :: lon, lat, rms_err + real :: ri0, rj0 + real, dimension(MAX_LEVELS) :: depth, data + + integer :: unit, ndim, nvar, natt, ntime + integer :: var_id, inst_type + integer :: num_levs, k, kk, i, j, i0, j0, k0 + integer :: stdout_unit, istat + integer :: out_bound_point + + logical :: data_is_local, localize_data + logical :: prof_in_filt_domain + logical, dimension(MAX_LEVELS) :: flag + + character(len=32) :: axisname, anal_fldname + character(len=128) :: emsg_local + + type(axistype), dimension(:), allocatable, target :: axes + type(axistype), pointer :: lon_axis, lat_axis, z_axis, t_axis + + if ( PRESENT(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + stdout_unit = stdout() + anal_fldname = 'temp' + var_id = obs_variable + +! call mpp_print_memuse_stats('open_profile_dataset_woa05t Start') + + call mpp_open(unit, trim(filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + + write (UNIT=stdout_unit, FMT='("Opened profile woa05t dataset: ",A)') trim(filename) + + call mpp_get_info(unit, ndim, nvar, natt, ntime) + allocate(axes(ndim)) + call mpp_get_axes(unit,axes) + do i=1, ndim + call mpp_get_atts(axes(i), name=axisname) + select case (trim(axisname)) + case ('lon') + lon_axis => axes(i) + case ('lat') + lat_axis => axes(i) + case ('depth') + z_axis => axes(i) + end select + end do + + call mpp_get_atts(lon_axis, len=nlon_woa) + call mpp_get_atts(lat_axis, len=nlat_woa) + call mpp_get_atts(z_axis, len=nlev_woa) + + if ( nlon_woa /= 360 .or. nlat_woa /= 180 ) then + write (UNIT=emsg_local, FMT='("woa05 obs dim is not same as in file. nlon_woa = ",I8,", nlat_woa = ",I8)') nlon_woa, nlat_woa + call error_mesg('oda_core_mod::open_profile_dataset_woa05t', trim(emsg_local), FATAL) + end if + + allocate(woa05_lon(nlon_woa), woa05_lat(nlat_woa), woa05_z(nlev_woa)) + + call mpp_get_axis_data(lon_axis, woa05_lon) + call mpp_get_axis_data(lat_axis, woa05_lat) + call mpp_get_axis_data(z_axis, woa05_z) + + out_bound_point = 0 + ! idealized + do j=1, nlat_woa + do i=1, nlon_woa + lon = woa05_lon(i) + lat = woa05_lat(j) + rms_err = 5 + inst_type = 20 + data_is_local = .true. + prof_in_filt_domain = .false. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat < -80.0 .or. lat > 80.0 ) data_is_local = .false. + if ( abs(lat) < 20.0 .and. (mod(i,2) /= 0 .or. mod(j,2) /= 0) ) data_is_local = .false. + if ( abs(lat) >= 20.0 .and. (mod(i,4) /= 0 .or. mod(j,4) /= 0) ) data_is_local = .false. + if ( abs(lat) >= 60.0 .and. (mod(i,6) /= 0 .or. mod(j,6) /= 0) ) data_is_local = .false. + + if (isd_filt >= 1 .and. ied_filt <= ieg) then + if (lon >= x_grid(isd_filt,jsd_flt0) .and.& + & lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and.& + & lat <= y_grid(ied_filt-1,jed_flt0-1)) then + prof_in_filt_domain = .true. + end if + end if + if (isd_filt < 1) then + isd_flt0 = isd_filt + ieg + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_filt-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if ( lon >= x_grid(isd_flt0,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_flt0,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + if (ied_filt > ieg) then + ied_flt0 = ied_filt - ieg + if ( lon >= x_grid(isd_filt,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if (ied_flt0-1 > 1) then + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_flt0-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_flt0-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + end if + + if ( data_is_local .and. (.NOT.localize_data) ) then ! global index + + no_woa05 = no_woa05 + 1 + num_profiles = num_profiles + 1 + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset_woa05t',& + & 'Maximum number of profiles exceeded, increase max_profiles in oda_core_nml', FATAL) + end if + + num_levs = 0 + flag = .false. + do k=1, nlev + flag(k) = .true. + data(k) = 0.0 + depth(k) = woa05_z(k) + num_levs = num_levs+1 + end do + if ( num_levs == 0 ) cycle + + if ( prof_in_filt_domain ) then ! localize + + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) +! allocate(profiles(num_profiles)%ms(num_levs)) +! allocate(profiles(num_profiles)%ms_inv(num_levs)) + profiles(num_profiles)%variable = var_id + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon + + kk = 1 + do k=1, nlev + if ( flag(k) ) then + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) +! profiles(num_profiles)%ms(kk) = 1.0 +! profiles(num_profiles)%ms_inv(kk) = 1.0 + kk = kk + 1 + end if + end do + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + if ( lat < 65.0 ) then ! regular grids + ri0 = frac_index(lon, x_grid(:,1)) + rj0 = frac_index(lat, y_grid(90,:)) + i0 = floor(ri0) + j0 = floor(rj0) + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I8,", j0 = ",I8)') i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_woa05t',& + & 'For regular grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( isd_filt >= 1 .and. ied_filt <= ieg ) then + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in woat01. '//trim(emsg_local), FATAL) + end if + end if + if ( isd_filt < 1 .and. i0 > ied_filt-1 .and. i0 < isd_filt + ieg ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in woat02. '//trim(emsg_local), FATAL) + end if + if ( ied_filt > ieg .and. i0 > ied_filt-ieg-1 .and. ied_filt < isd_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in woat03. '//trim(emsg_local), FATAL) + end if + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + else ! tripolar grids + lon_out(1,1) = lon*DEG_TO_RAD + lat_out(1,1) = lat*DEG_TO_RAD + call horiz_interp_bilinear_new (Interp, x_grid*DEG_TO_RAD, y_grid*DEG_TO_RAD, lon_out, lat_out) + if ( Interp%wti(1,1,2) < 1.0 ) then + i0 = Interp%i_lon(1,1,1) + else + i0 = Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + j0 = Interp%j_lat(1,1,1) + else + j0 = Interp%j_lat(1,1,2) + end if + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I8,", j0 = ",I8)') i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_woa05t',& + & 'For tripolar grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + write (UNIT=stdout_unit, FMT='("woat.pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(),i0, j0,isd_filt,ied_filt,jsd_filt,jed_filt + out_bound_point = out_bound_point + 1 + end if + if ( Interp%wti(1,1,2) < 1.0 ) then + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,1) + Interp%wti(1,1,2) + else + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,1) + Interp%wtj(1,1,2) + else + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,2) + end if + end if ! grids + + Profiles(num_profiles)%accepted = .true. + if ( i0 < 1 .or. j0 < 1 ) then + Profiles(num_profiles)%accepted = .false. + end if + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + Profiles(num_profiles)%accepted = .false. + end if + + if ( Profiles(num_profiles)%accepted ) then ! here + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else + if ( Grd%mask(i0,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + end if ! here + + if ( Profiles(num_profiles)%accepted ) then ! accepted + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + if (depth(k) < Grd%z(1)) then + Profiles(num_profiles)%k_index(k) = 0.0 + else + Profiles(num_profiles)%k_index(k) = frac_index(depth(k), (/0.,Grd%z(:)/)) - 1.0 ! snz modify to v3.2 JAN3012 + end if + if ( Profiles(num_profiles)%k_index(k) > nk ) then + call error_mesg('oda_core_mod::open_profile_dataset_woa05t',& + & 'Profile k_index is greater than nk', FATAL) + end if + k0 = floor(Profiles(num_profiles)%k_index(k)) + + if ( k0 >= 1 ) then ! snz add + if ( Profiles(num_profiles)%flag(k) ) then ! flag + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(1,j0+1,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( abs(Profiles(num_profiles)%data(k)) > 1.e4 & + & .or. abs(Profiles(num_profiles)%depth(k)) > 1.e4 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if ! flag + end if ! snz add + end do + end if ! accepted + end if ! localize + end if ! global index + end do + end do + + call mpp_close(unit) + deallocate(axes) + write (UNIT=stdout_unit, FMT='("A grand total of ",I8," woa05t points within global domain")') no_woa05 + write (UNIT=stdout_unit, FMT='("A final total @woa05t of ",I8," prfs within global domain")') num_profiles + +! call mpp_print_memuse_stats('open_profile_dataset_woa05t End') + + end subroutine open_profile_dataset_woa05t + + subroutine open_profile_dataset_woa05s(filename, obs_variable, localize) + character(len=*), intent(in) :: filename + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 24 + + real :: lon, lat, rms_err + real :: ri0, rj0 + real, dimension(MAX_LEVELS) :: depth, data + + integer :: unit, ndim, nvar, natt, ntime + integer :: var_id, inst_type + integer :: num_levs, k, kk, i, j, i0, j0, k0 + integer :: stdout_unit + integer :: out_bound_point + + logical :: data_is_local, localize_data + logical :: prof_in_filt_domain + logical, dimension(MAX_LEVELS) :: flag + + character(len=32) :: axisname, anal_fldname + character(len=128) :: emsg_local + + type(axistype), dimension(:), allocatable, target :: axes + type(axistype), pointer :: lon_axis, lat_axis, z_axis + + if ( present(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + stdout_unit = stdout() + + anal_fldname = 'salt' + var_id = obs_variable + +! call mpp_print_memuse_stats('open_profile_dataset_woa05s Start') + + call mpp_open(unit, trim(filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + + write (UNIT=stdout_unit, FMT='("Opened profile woa05s dataset: ",A)') trim(filename) + + call mpp_get_info(unit, ndim, nvar, natt, ntime) + allocate(axes(ndim)) + call mpp_get_axes(unit, axes) + do i=1, ndim + call mpp_get_atts(axes(i), name=axisname) + select case ( trim(axisname) ) + case ('lon') + lon_axis => axes(i) + case ('lat') + lat_axis => axes(i) + case ('depth') + z_axis => axes(i) + end select + end do + call mpp_get_atts(lon_axis, len=nlon_woa) + call mpp_get_atts(lat_axis, len=nlat_woa) + call mpp_get_atts(z_axis, len=nlev_woa) + if ( nlon_woa /= 360 .or. nlat_woa /= 180 ) then + write (UNIT=emsg_local, FMT='("woa05 obs dim is not same as in file nlon_woa = ",I8,", nlat_woa = ",I8)') nlon_woa, nlat_woa + call error_mesg('oda_core_mod::open_profile_dataset_woa05s', trim(emsg_local), FATAL) + end if + + out_bound_point = 0 + ! idealized + do j=1, nlat_woa + do i=1, nlon_woa + lon = woa05_lon(i) + lat = woa05_lat(j) + rms_err = 5 + inst_type = 20 + data_is_local = .true. + prof_in_filt_domain = .false. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat < -80.0 .or. lat > 80.0 ) data_is_local = .false. + if ( abs(lat) < 20.0 .and. (mod(i,2) /= 0 .or. mod(j,2) /= 0) ) data_is_local = .false. + if ( abs(lat) >= 20.0 .and. (mod(i,4) /= 0 .or. mod(j,4) /= 0) ) data_is_local = .false. + if ( abs(lat) >= 60.0 .and. (mod(i,6) /= 0 .or. mod(j,6) /= 0) ) data_is_local = .false. + + if (isd_filt >= 1 .and. ied_filt <= ieg) then + if (lon >= x_grid(isd_filt,jsd_flt0) .and.& + & lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and.& + & lat <= y_grid(ied_filt-1,jed_flt0-1)) then + prof_in_filt_domain = .true. + end if + end if + if (isd_filt < 1) then + isd_flt0 = isd_filt + ieg + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_filt-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_filt-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if ( lon >= x_grid(isd_flt0,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_flt0,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + if (ied_filt > ieg) then + ied_flt0 = ied_filt - ieg + if ( lon >= x_grid(isd_filt,jsd_flt0) .and. lon <= x_grid(ieg-1,jsd_flt0) .and.& + & lat >= y_grid(isd_filt,jsd_flt0) .and. lat <= y_grid(ieg-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + if (ied_flt0-1 > 1) then + if ( lon >= x_grid(1,jsd_flt0) .and. lon <= x_grid(ied_flt0-1,jsd_flt0) .and.& + & lat >= y_grid(1,jsd_flt0) .and. lat <= y_grid(ied_flt0-1,jed_flt0-1) ) then + prof_in_filt_domain = .true. + end if + end if + end if + + if ( data_is_local .and. (.NOT.localize_data) ) then ! global index + + no_woa05 = no_woa05 + 1 + num_profiles=num_profiles + 1 + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset_woa05s',& + & 'Maximum number of profiles exceeded, increase max_profiles in oda_core_nml.', FATAL) + end if + + num_levs = 0 + flag = .false. + do k=1, nlev_woa + flag(k) = .true. + data(k) = 0.0 + depth(k) = woa05_z(k) + num_levs = num_levs + 1 + end do + if ( num_levs == 0 ) cycle + + if ( prof_in_filt_domain ) then ! localize + + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) +! allocate(profiles(num_profiles)%ms(num_levs)) +! allocate(profiles(num_profiles)%ms_inv(num_levs)) + profiles(num_profiles)%variable = var_id + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon + + kk = 1 + do k=1, nlev_woa + if ( flag(k) ) then + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) +! profiles(num_profiles)%ms(kk) = 1.0 +! profiles(num_profiles)%ms_inv(kk) = 1.0 + kk = kk + 1 + end if + end do + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + if ( lat < 65.0 ) then ! regular grids + ri0 = frac_index(lon, x_grid(:,1)) + rj0 = frac_index(lat, y_grid(90,:)) + i0 = floor(ri0) + j0 = floor(rj0) + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I8,", j0 = ",I8)') i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_woa05s',& + & 'For regular grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( isd_filt >= 1 .and. ied_filt <= ieg ) then + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in woas01. '//trim(emsg_local), FATAL) + end if + end if + if ( isd_filt < 1 .and. i0 > ied_filt-1 .and. i0 < isd_filt + ieg ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in woas02. '//trim(emsg_local), FATAL) + end if + if ( ied_filt > ieg .and. i0 > ied_filt-ieg-1 .and. ied_filt < isd_filt ) then + write (UNIT=emsg_local, FMT='("pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(), i0, j0, isd_filt,ied_filt,jsd_filt,jed_filt + call error_mesg('oda_core_mod::open_profile_dataset',& + & 'i0,j0 out of bounds in woas03. '//trim(emsg_local), FATAL) + end if + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + else ! tripolar grids + lon_out(1,1) = lon*DEG_TO_RAD + lat_out(1,1) = lat*DEG_TO_RAD + call horiz_interp_bilinear_new (Interp, x_grid*DEG_TO_RAD, y_grid*DEG_TO_RAD, lon_out, lat_out) + if ( Interp%wti(1,1,2) < 1.0 ) then + i0 = Interp%i_lon(1,1,1) + else + i0 = Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + j0 = Interp%j_lat(1,1,1) + else + j0 = Interp%j_lat(1,1,2) + end if + if ( i0 > ieg .or. j0 > jeg ) then + write (UNIT=emsg_local, FMT='("i0 = ",I8,", j0 = ",I8)') i0, j0 + call error_mesg('oda_core_mod::open_profile_dataset_woa05s',& + & 'For tripolar grids, either i0 > ieg or j0 > jeg. '//trim(emsg_local), FATAL) + end if + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + write (UNIT=stdout_unit, FMT='("woas.pe,i0,j0= ",3I8,"isd_filt,ied_filt,jsd_filt,jed_filt= ",4I8)')& + & mpp_pe(),i0, j0,isd_filt,ied_filt,jsd_filt,jed_filt + out_bound_point = out_bound_point + 1 + end if + if ( Interp%wti(1,1,2) < 1.0 ) then + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,1) + Interp%wti(1,1,2) + else + Profiles(num_profiles)%i_index =Interp%i_lon(1,1,2) + end if + if ( Interp%wtj(1,1,2) < 1.0 ) then + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,1) + Interp%wtj(1,1,2) + else + Profiles(num_profiles)%j_index =Interp%j_lat(1,1,2) + end if + end if ! grids + + Profiles(num_profiles)%accepted = .true. + if ( i0 < 1 .or. j0 < 1 ) then + Profiles(num_profiles)%accepted = .false. + end if + if ( i0 < isd_filt .or. i0 > ied_filt .or. j0 < jsd_filt .or. j0 > jed_filt ) then + Profiles(num_profiles)%accepted = .false. + end if + + if ( Profiles(num_profiles)%accepted ) then ! here + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + else + if ( Grd%mask(i0,j0,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + end if ! here + + if ( Profiles(num_profiles)%accepted ) then ! accepted + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + if (depth(k) < Grd%z(1)) then + Profiles(num_profiles)%k_index(k) = 0.0 + else + Profiles(num_profiles)%k_index(k) = frac_index(depth(k), (/0.,Grd%z(:)/)) - 1.0 ! snz modify to v3.2 JAN3012 + end if + if ( Profiles(num_profiles)%k_index(k) > nk ) then + call error_mesg('oda_core_mod::open_profile_dataset_woa05s',& + & 'Profile k_index is greater than nk', FATAL) + end if + k0 = floor(Profiles(num_profiles)%k_index(k)) + + if ( k0 >= 1 ) then ! snz add + if ( Profiles(num_profiles)%flag(k) ) then ! flag + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(1,j0,k0) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0) == 0.0 .or.& + & Grd%mask(1,j0+1,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( i0 /= ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + elseif ( i0 == ieg .and. j0 /= jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(1,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0,j0+1,k0+1) == 0.0 .or.& + & Grd%mask(1,j0+1,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else if ( i0 /= ieg .and. j0 == jeg ) then + if ( Grd%mask(i0,j0,k0+1) == 0.0 .or.& + & Grd%mask(i0+1,j0,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + else + if ( Grd%mask(i0,j0,k0+1) == 0.0 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if + + if ( abs(Profiles(num_profiles)%data(k)) > 1.e4 & + & .or. abs(Profiles(num_profiles)%depth(k)) > 1.e4 ) then + Profiles(num_profiles)%flag(k) = .false. + end if + end if ! flag + end if ! snz add + end do + end if ! accepted + end if ! localize + end if ! global index + end do + end do + + call mpp_close(unit) + deallocate(axes) + write (UNIT=stdout_unit, FMT='("A grand total of ",I8," woa05s points within global domain")') no_woa05 + write (UNIT=stdout_unit, FMT='("A final total @woa05s of ",I8," prfs within global domain")') num_profiles + +! call mpp_print_memuse_stats('open_profile_dataset_woa05s Ens') + + end subroutine open_profile_dataset_woa05s + + subroutine get_obs_sst(model_time, Prof, nprof, no_prf0, sst_climo, Filter_domain) + type(time_type), intent(in) :: model_time + type(ocean_profile_type), dimension(:), intent(inout) :: Prof + integer, intent(inout) :: nprof + integer, intent(in) :: no_prf0 + type(obs_clim_type), intent(inout) :: sst_climo + type(domain2d), intent(in) :: Filter_domain + + integer :: i0, j0, i, days, seconds, days1, seconds1 + integer :: unit, ndim, nvar, natt, ntime, time_idx + integer :: iy0, in0, id0, ih0, im0, is0, i_m + integer :: stdout_unit, istat + integer, dimension(12) :: n_days + integer, save :: year_on_first_read = 0 !< Year on first read of file during + !! module run + character(len=128) :: sst_filename, emsg_local + + type(fieldtype), dimension(:), allocatable :: fields + type(time_type) :: tdiff, sst_time0, time1 + + n_days = (/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) + + nprof = 0 + + stdout_unit = stdout() + + call get_time(model_time, seconds, days) + call get_date(model_time, iy0, in0, id0, ih0, im0, is0) + if ( year_on_first_read == 0 ) then + year_on_first_read = iy0 + end if + time1=set_date(year_on_first_read, 1, 1, 0, 0, 0) + call get_time(time1, seconds1, days1) + time_idx = days-days1+1 + + ! daily data + + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("time_idx = ",I8)') time_idx + end if + + sst_filename = "INPUT/sst_daily.nc" + + call mpp_open(unit, trim(sst_filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + call mpp_get_info(unit, ndim, nvar, natt, ntime) + + allocate(fields(nvar), STAT=istat) + if ( istat .ne. 0 ) then + call error_mesg('oda_core_mod::get_obs_sst', 'Unable to allocate fields', FATAL) + end if + + call mpp_get_fields(unit, fields) + do i=1, nvar + select case ( mpp_get_field_name(fields(i)) ) + case ('SST1') ! for AVHRR daily SST + call mpp_read(unit, fields(i), Filter_domain, sst_climo%sst_obs, tindex=time_idx) + end select + end do + + ! get profiles and sst + ! obs relevant to current analysis interval + sst_time0 = set_date(iy0, in0, id0, ih0, im0, is0) + + if ( no_sst > 1 ) then + + do i=no_prf+no_woa05+1, no_prf+no_woa05+no_sst + Profiles(i)%time = sst_time0 + + tdiff = model_time - Profiles(i)%time + + i0 = floor(Profiles(i)%i_index) + if ( i0 < 1 .or. i0 > 1440 ) then + write (UNIT=emsg_local, FMT='("Profiles(",I8,")%lon = ",I4,", i0 = ",I8)') i, Profiles(i)%lon, i0 + call error_mesg('oda_core_mod::get_obs_sst',& + & 'Profile longitude index outside range [1,1440]. '//trim(emsg_local), FATAL) + end if + + j0 = floor(Profiles(i)%j_index) + if ( j0 < 1 .or. j0 > 1070 ) then + write (UNIT=emsg_local, FMT='("Profiles(",I8,")%lat = ",I4,", j0 = ",I8)') i, Profiles(i)%lon, j0 + call error_mesg('oda_core_mod::get_obs_sst',& + & 'Profile latitude index outside range [1,1070]. '//trim(emsg_local), FATAL) + end if + + if ( Profiles(i)%accepted ) then + nprof = nprof + 1 + if ( nprof > size(Prof,1) ) then + call error_mesg('oda_core_mod::get_obs_sst',& + & 'Passed in array "Prof" is smaller than number of profiles, increase size of Prof before call.',& + & FATAL) + end if + + call copy_obs(Profiles(i:i), Prof(no_prf0+nprof:no_prf0+nprof)) + + Prof(nprof+no_prf0)%tdiff = tdiff + end if + end do + + end if ! for no_sst > 1 + + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("no of sst records: ",I8)') nprof + end if + + deallocate(fields) + call mpp_close(unit) + end subroutine get_obs_sst + + subroutine get_obs_woa05t(model_time, Prof, nprof, no_prf0) + type(time_type), intent(in) :: model_time + type(ocean_profile_type), dimension(:), intent(inout) :: Prof + integer, intent(inout) :: nprof + integer, intent(in) :: no_prf0 + + real :: ri0, rj0, lon_woa05 + + integer :: i0, j0 + integer :: i, k, unit, time_idx + integer :: iy0, in0, id0, ih0, im0, is0 + integer :: ndim, nvar, natt, ntime + integer :: stdout_unit, istat + + character(len=32) :: axisname + character(len=128) :: woa05t_filename + + type(fieldtype), dimension(:), allocatable :: fields + type(time_type) :: tdiff, woa05_time0 + + nprof = 0 + stdout_unit = stdout() + + call get_date(model_time, iy0, in0, id0, ih0, im0, is0) + + time_idx = in0 + + ! daily data + woa05t_filename = "INPUT/woa05_temp.nc" + + call mpp_open(unit, trim(woa05t_filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + call mpp_get_info(unit, ndim, nvar, natt, ntime) + + allocate(fields(nvar), STAT=istat) + if ( istat .ne. 0 ) then + call error_mesg('oda_core_mod::get_obs_woa05t', 'Unable to allocate fields', FATAL) + end if + + call mpp_get_fields(unit, fields) + + allocate(obs_woa05t(nlon_woa,nlat_woa,nlev_woa)) + + do i=1, nvar + select case ( mpp_get_field_name(fields(i)) ) + case ('t0112an1') + call mpp_read(unit, fields(i), obs_woa05t, tindex=time_idx) + end select + end do + + woa05_time0 = set_date(iy0, in0, id0, ih0, im0, is0) + + do i=no_prf+1, no_prf+no_woa05/2 + Profiles(i)%time = woa05_time0 + + tdiff = model_time - Profiles(i)%time + + lon_woa05 = Profiles(i)%lon + if ( lon_woa05 < 0.0 ) lon_woa05 = lon_woa05 + 360.0 + if ( lon_woa05 > 360.0 ) lon_woa05 = lon_woa05 - 360.0 + ri0 = frac_index(lon_woa05, woa05_lon) + i0 = floor(ri0) + if ( i0 < 1 ) i0 = 1 + if ( i0 > nlon_woa ) i0 = nlon_woa + + rj0 = frac_index(Profiles(i)%lat, woa05_lat) + j0 = floor(rj0) + if(j0 < 1 ) j0 = 1 + if(j0 > nlat_woa) j0 = nlat_woa + + if ( Profiles(i)%accepted ) then + nprof = nprof + 1 + if ( nprof > size(Prof,1) ) then + call error_mesg('oda_core_mod::get_obs_woa05t',& + & 'Passed in array "Prof" is smaller than number of profiles, increase size of Prof before call.',& + & FATAL) + end if + Profiles(i)%data(1:nlev_woa) = obs_woa05t(i0,j0,1:nlev_woa) + do k=1, nlev_woa + if ( abs(Profiles(i)%data(k)) > 1.e3 .or.& + & abs(Profiles(i)%depth(k)) > 1.e5 ) then + Profiles(i)%flag(k) = .false. + end if + end do + call copy_obs(Profiles(i:i), Prof(no_prf0+nprof:no_prf0+nprof)) + Prof(no_prf0+nprof)%tdiff = tdiff + end if + end do + + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("no of woa05t records: ",I8)') nprof + end if + + deallocate(fields, obs_woa05t) + call mpp_close(unit) + end subroutine get_obs_woa05t + + subroutine get_obs_woa05s(model_time, Prof, nprof, no_prf0) + type(time_type), intent(in) :: model_time + type(ocean_profile_type), dimension(:), intent(inout) :: Prof + integer, intent(inout) :: nprof + integer, intent(in) :: no_prf0 + + real :: ri0, rj0, lon_woa05 + + integer :: i0, j0 + integer :: i, k, unit, time_idx + integer :: iy0, in0, id0, ih0, im0, is0 + integer :: ndim, nvar, natt, ntime + integer :: stdout_unit, istat + + character(len=128) :: woa05s_filename + + type(fieldtype), dimension(:), allocatable :: fields + type(time_type) :: tdiff, woa05_time0 + + nprof = 0 + stdout_unit = stdout() + + call get_date(model_time, iy0,in0,id0,ih0,im0,is0) + + time_idx = in0 + + ! climatological data + woa05s_filename = "INPUT/woa05_salt.nc" + + call mpp_open(unit, trim(woa05s_filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + call mpp_get_info(unit, ndim, nvar, natt, ntime) + + allocate(fields(nvar), STAT=istat) + if ( istat .ne. 0 ) then + call error_mesg('oda_core_mod::get_obs_woa05s', 'Unable to allocate fields', FATAL) + end if + + call mpp_get_fields(unit, fields) + + allocate(obs_woa05s(nlon_woa,nlat_woa,nlev_woa)) + + do i=1, nvar + select case ( mpp_get_field_name(fields(i)) ) + case ('s0112an1') + call mpp_read(unit, fields(i), obs_woa05s, tindex=time_idx) + end select + end do + + woa05_time0 = set_date(iy0, in0, id0, ih0, im0, is0) + + do i=no_prf+no_woa05/2+1, no_prf+no_woa05 + Profiles(i)%time = woa05_time0 + + tdiff = model_time - Profiles(i)%time + + lon_woa05 = Profiles(i)%lon + if ( lon_woa05 < 0.0 ) lon_woa05 = lon_woa05 + 360.0 + if ( lon_woa05 > 360.0 ) lon_woa05 = lon_woa05 - 360.0 + ri0 = frac_index(lon_woa05, woa05_lon) + i0 = floor(ri0) + if ( i0 < 1 ) i0 = 1 + if ( i0 > nlon_woa ) i0 = nlon_woa + + rj0 = frac_index(Profiles(i)%lat, woa05_lat) + j0 = floor(rj0) + if ( j0 < 1 ) j0 = 1 + if ( j0 > nlat_woa ) j0 = nlat_woa + + if ( Profiles(i)%accepted ) then + nprof = nprof + 1 + if ( nprof > size(Prof,1) ) then + call error_mesg('oda_core_mod::get_obs_woa05s',& + & 'Passed in array "Prof" is smaller than number of profiles, increase size of Prof before call',& + & FATAL) + end if + Profiles(i)%data(1:nlev_woa) = obs_woa05s(i0,j0,1:nlev_woa) + do k=1, nlev_woa + if ( abs(Profiles(i)%data(k)) > 1.e3 .or.& + & abs(Profiles(i)%depth(k)) > 1.e5 ) then + Profiles(i)%flag(k) = .false. + end if + end do + call copy_obs(Profiles(i:i),Prof(no_prf0+nprof:no_prf0+nprof)) + Prof(no_prf0+nprof)%tdiff = tdiff + end if + end do + + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("no of woa05t records: ",I8)') nprof + end if + + deallocate(fields, obs_woa05s) + call mpp_close(unit) + end subroutine get_obs_woa05s + + subroutine open_profile_dataset_eta(filename, obs_variable, localize) + character(len=*), intent(in) :: filename + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 1000 + + real :: lon, lat, rms_err + real :: ri0, rj0 + real, dimension(MAX_LEVELS) :: depth, data + + integer :: inst_type, var_id + integer :: num_levs, k, kk, i, j, i0, j0 + integer :: stdout_unit + + logical :: data_is_local, localize_data + logical, dimension(MAX_LEVELS) :: flag + + character(len=32) :: anal_fldname + + if ( PRESENT(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + stdout_unit = stdout() + + anal_fldname = 'eta' + var_id = obs_variable + + !snz idealized + do j=1, size(x_grid, dim=1) + do i=1, size(x_grid, dim=2) + lon = x_grid(i,j) + lat = y_grid(i,j) + rms_err = 0.5 + + inst_type = 20 + data_is_local = .true. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat < eta_obs_start_lat .or. lat > eta_obs_end_lat ) data_is_local = .false. + if ( abs(lat) < 20.0 .and.& + & (mod(floor(lon),2) /= 0 .or. mod(floor(lat),2) /= 0) ) data_is_local = .false. + if ( (abs(lat) >= 20.0 .and. abs(lat) < 40.0) .and.& + & (mod(floor(lon),4) /= 0 .or. mod(floor(lat),4) /= 0) ) data_is_local = .false. + if ( (abs(lat) >= 40.0) .and.& + & (mod(floor(lon),6) /= 0 .or. mod(floor(lat),6) /= 0) ) data_is_local = .false. + + if ( data_is_local .and. (.NOT.localize_data) ) then + ri0 = frac_index(lon, x_grid(:,1)) + rj0 = frac_index(lat, y_grid(90,:)) + i0 = floor(ri0) + j0 = floor(rj0) + if ( Grd%mask(i0,j0,1) /= 0.0 .and. Grd%mask(i0+1,j0,1) /= 0.0 .and.& + & Grd%mask(i0,j0+1,1) /= 0.0 .and. Grd%mask(i0+1,j0+1,1) /= 0.0 ) then + no_eta = no_eta+1 + num_profiles=num_profiles+1 + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset_eta',& + & 'Maximum number of profiles exceeded, increase max_profiles in oda_core_nml.', FATAL) + end if + + + num_levs = 0 + flag = .false. + do k=1, 1 + flag(k) = .true. + data(k) = 0.0 + depth(k) = 0.0 + num_levs = num_levs+1 + end do + if ( num_levs == 0 ) cycle + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) + allocate(profiles(num_profiles)%ms(num_levs)) + allocate(profiles(num_profiles)%ms_inv(num_levs)) + profiles(num_profiles)%variable = var_id + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon + kk = 1 + do k=1, 1 + if ( flag(k) ) then + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) + profiles(num_profiles)%ms(kk) = 1.0 + profiles(num_profiles)%ms_inv(kk) = 1.0 + kk = kk + 1 + end if + end do + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + Profiles(num_profiles)%accepted = .true. + if ( i0 < 1 .or. j0 < 1 ) then + Profiles(num_profiles)%accepted = .false. + end if + if ( Profiles(num_profiles)%accepted ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + if ( Profiles(num_profiles)%accepted ) then + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + if (depth(k) < Grd%z(1)) then + Profiles(num_profiles)%k_index(k) = 0.0 + else + Profiles(num_profiles)%k_index(k) = frac_index(depth(k), (/0.,Grd%z(:)/)) - 1 + end if + if ( Profiles(num_profiles)%k_index(k) < 1.0 ) Profiles(num_profiles)%flag(k) = .false. + end do + end if + end if + end if + end do + end do + + write (UNIT=stdout_unit, FMT='("A grand total of ",I8," eta points within global domain")') no_eta + write (UNIT=stdout_unit, FMT='("A final total @eta of ",I8," prfs within global domain")') num_profiles + end subroutine open_profile_dataset_eta + + subroutine open_profile_dataset_suv(filename, obs_variable, localize) + character(len=*), intent(in) :: filename + integer, intent(in) :: obs_variable + logical, intent(in), optional :: localize + + integer, parameter :: MAX_LEVELS = 1000 + + real :: ri0, rj0 + real :: lon, lat, rms_err + real, dimension(MAX_LEVELS) :: depth, data + + integer :: inst_type, var_id + integer :: num_levs, k, kk, i, j, i0, j0 + integer :: stdout_unit + + logical :: data_is_local, localize_data + logical, dimension(MAX_LEVELS) :: flag + + character(len=32) :: anal_fldname + + if ( PRESENT(localize) ) then + localize_data = localize + else + localize_data = .true. + end if + + stdout_unit = stdout() + + anal_fldname = 'suv' + var_id = obs_variable + + !snz idealized + do j=1, size(x_grid_uv,dim=1) + do i=1, size(x_grid_uv,dim=2) + lon = x_grid_uv(i,j) + lat = y_grid_uv(i,j) + rms_err = 0.5 + + inst_type = 20 + data_is_local = .true. + + if ( lon .lt. 0.0 ) lon = lon + 360.0 + if ( lon .gt. 360.0 ) lon = lon - 360.0 + if ( lon .lt. 80.0 ) lon = lon + 360.0 + + if ( lat < -40.0 .or. lat > 40.0 ) data_is_local = .false. + if ( abs(lat) < 20.0 .and.& + & (mod(floor(lon),2) /= 0 .or. mod(floor(lat),2) /= 0) ) data_is_local = .false. + if ( (abs(lat) >= 20.0 .and. abs(lat) < 40.0) .and.& + & (mod(floor(lon),4) /= 0 .or. mod(floor(lat),4) /= 0) ) data_is_local = .false. + if ( (abs(lat) >= 40.0) .and.& + & (mod(floor(lon),6) /= 0 .or. mod(floor(lat),6) /= 0) ) data_is_local = .false. + + if ( data_is_local .and. (.NOT.localize_data) ) then + ri0 = frac_index(lon, x_grid_uv(:,1)) + rj0 = frac_index(lat, y_grid_uv(90,:)) + i0 = floor(ri0) + j0 = floor(rj0) + if ( Grd%mask(i0,j0,1) /= 0.0 .and. Grd%mask(i0+1,j0,1) /= 0.0 .and.& + & Grd%mask(i0,j0+1,1) /= 0.0 .and. Grd%mask(i0+1,j0+1,1) /= 0.0 ) then + no_suv = no_suv+1 + num_profiles = num_profiles + 1 + if ( num_profiles > max_profiles ) then + call error_mesg('oda_core_mod::open_profile_dataset_suv',& + & 'Maximum number of profiles exceeded, increase max_profiles in oda_core_nml.', FATAL) + end if + + + num_levs = 0 + flag = .false. + do k=1, 2 + flag(k) = .true. + data(k) = 0.0 + depth(k) = 0.0 + num_levs = num_levs + 1 + end do + if ( num_levs == 0 ) cycle + allocate(profiles(num_profiles)%depth(num_levs)) + allocate(profiles(num_profiles)%data(num_levs)) + allocate(profiles(num_profiles)%flag(num_levs)) + allocate(profiles(num_profiles)%ms(num_levs)) + allocate(profiles(num_profiles)%ms_inv(num_levs)) + profiles(num_profiles)%variable = var_id + profiles(num_profiles)%inst_type = inst_type + profiles(num_profiles)%levels = num_levs + profiles(num_profiles)%lat = lat + profiles(num_profiles)%lon = lon + kk = 1 + do k=1, 2 + if ( flag(k) ) then + profiles(num_profiles)%depth(kk) = depth(k) + profiles(num_profiles)%data(kk) = data(k) + profiles(num_profiles)%ms(kk) = 1.0 + profiles(num_profiles)%ms_inv(kk) = 1.0 + kk = kk + 1 + end if + end do + + ! calculate interpolation coefficients (make sure to account for grid offsets here!) + Profiles(num_profiles)%i_index = ri0 + Profiles(num_profiles)%j_index = rj0 + Profiles(num_profiles)%accepted = .true. + if ( i0 < 1 .or. j0 < 1 ) then + Profiles(num_profiles)%accepted = .false. + end if + if ( Profiles(num_profiles)%accepted ) then + if ( Grd%mask(i0,j0,1) == 0.0 .or.& + & Grd%mask(i0+1,j0,1) == 0.0 .or.& + & Grd%mask(i0,j0+1,1) == 0.0 .or.& + & Grd%mask(i0+1,j0+1,1) == 0.0 ) then + Profiles(num_profiles)%accepted = .false. + end if + end if + if ( Profiles(num_profiles)%accepted ) then + Profiles(num_profiles)%flag(:) = .true. + allocate(Profiles(num_profiles)%k_index(Profiles(num_profiles)%levels)) + do k=1, Profiles(num_profiles)%levels + if (depth(k) < Grd%z(1)) then + Profiles(num_profiles)%k_index(k) = 0.0 + else + Profiles(num_profiles)%k_index(k) = frac_index(depth(k), (/0.,Grd%z(:)/)) - 1.0 ! snz modify to v3.2 JAN3012 + end if + if ( Profiles(num_profiles)%k_index(k) < 1.0 ) Profiles(num_profiles)%flag(k) = .false. + end do + end if + end if + end if + end do + end do + + write (UNIT=stdout_unit, FMT='("A grand total of ",I8," suv points within global domain")') no_suv + write (UNIT=stdout_unit, FMT='("A final total @suv of ",I8," prfs within global domain")') num_profiles + end subroutine open_profile_dataset_suv + + subroutine get_obs_suv(model_time, Prof, nprof, no_prf0) + type(time_type), intent(in) :: model_time + type(ocean_profile_type), dimension(:), intent(inout) :: Prof + integer, intent(inout) :: nprof + integer, intent(in) :: no_prf0 + + ! get sst data and put into profiles + ! only current day + + real :: sfc_lon, sfc_lat, ri0, rj0 + real, dimension(1440,1070,1) :: sfc_u, sfc_v + + integer :: i, k, i_m, i0, j0 + integer :: unit, time_idx, ndim, nvar, natt, ntime + integer :: iy0, in0, id0, ih0, im0, is0 + integer :: stdout_unit, istat + integer, dimension(12) :: n_days + + character(len=80) :: sfc_filename + character(len=256) :: emsg_local + + type(fieldtype), dimension(:), allocatable :: fields + type(time_type) :: tdiff, sfc_time0 + + n_days = (/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) + nprof = 0 + stdout_unit = stdout() + + call get_date(model_time, iy0, in0, id0, ih0, im0, is0) + + !monthly +!!$ time_idx = (iy0-1984)*12+in0 + ! daily + if ( in0 == 1 ) then + time_idx = (iy0-1984)*365 + id0 + else + time_idx = 0 + do i_m=1, in0-1 + time_idx = time_idx + (iy0-1984)*365 + n_days(i_m) + end do + time_idx = time_idx + id0 + end if + + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("time_idx = ",I8)') time_idx + end if + + sfc_time0 = set_date(iy0, in0, id0, ih0, im0, is0) + + sfc_filename = "INPUT/sfc_current.198401-198412.nc" + + call mpp_open(unit, trim(sfc_filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + call mpp_get_info(unit, ndim, nvar, natt, ntime) + + allocate(fields(nvar), STAT=istat) + if ( istat .ne. 0 ) then + call error_mesg('oda_core_mod::get_obs_sst', 'Unable to allocate fields', FATAL) + end if + + call mpp_get_fields(unit, fields) + do i=1, nvar + select case ( mpp_get_field_name(fields(i)) ) + case ('U_SFC') + call mpp_read(unit, fields(i), sfc_u, tindex=time_idx) + case ('V_SFC') + call mpp_read(unit, fields(i), sfc_v, tindex=time_idx) + end select + end do + + do i=no_prf+no_sst+no_eta+1, no_prf+no_sst+no_eta+no_suv + Profiles(i)%time = sfc_time0 + + tdiff = model_time - Profiles(i)%time + + sfc_lon = Profiles(i)%lon + ri0 = frac_index(sfc_lon, x_grid_uv(:,1)) + i0 = floor(ri0) + if ( i0 < 1 .or. i0 > 1440 ) then + write (UNIT=emsg_local, FMT='("Profiles(",I8,")%lon = ",I4,", i0 = ",I8)') i, Profiles(i)%lon, i0 + call error_mesg('oda_core_mod::get_obs_suv',& + & 'Profile longitude index outside range [1,1440]. '//trim(emsg_local), FATAL) + end if + + sfc_lat = Profiles(i)%lat + rj0 = frac_index(sfc_lat, y_grid_uv(90,:)) + j0 = floor(rj0) + if ( j0 < 1 .or. j0 > 1070 ) then + write (UNIT=emsg_local, FMT='("Profiles(",I8,")%lat = ",I4,", j0 = ",I8)') i, Profiles(i)%lon, j0 + call error_mesg('oda_core_mod::get_obs_suv',& + & 'Profile latitude index outside range [1,1070]. '//trim(emsg_local), FATAL) + end if + + if ( Profiles(i)%accepted ) then + nprof = nprof + 1 + if ( nprof > size(Prof,1) ) then + call error_mesg('oda_core_mod::get_obs_suv',& + & 'Passed in array "Prof" is smaller than number of profiles, increase size of Prof before call',& + & FATAL) + end if + Profiles(i)%data(1) = sfc_u(i0,j0,1) + Profiles(i)%data(2) = sfc_v(i0,j0,1) + + call copy_obs(Profiles(i:i),Prof(nprof+no_prf0:nprof+no_prf0)) + + Prof(nprof+no_prf0)%tdiff = tdiff + end if + end do + + deallocate(fields) + call mpp_close(unit) + end subroutine get_obs_suv + + subroutine get_obs_eta(model_time, Prof, nprof, no_prf0) + type(time_type), intent(in) :: model_time + type(ocean_profile_type), dimension(:), intent(inout) :: Prof + integer, intent(inout) :: nprof + integer, intent(in) :: no_prf0 + + ! get sst data and put into profiles + ! only current day + + real :: eta_lon, eta_lat, ri0, rj0 + real, dimension(1440,1070) :: eta_t + + integer :: i, i0, j0, i_m + integer :: iy0, in0, id0, ih0, im0, is0 + integer :: unit, time_idx, ndim, nvar, natt, ntime + integer :: stdout_unit, istat + integer, dimension(12) :: n_days + + character(len=80) :: eta_filename + character(len=256) :: emsg_local + + type(fieldtype), dimension(:), allocatable :: fields + type(time_type) :: tdiff, sfc_time0 + + n_days = (/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) + nprof = 0 + stdout_unit = stdout() + + call get_date(model_time, iy0, in0, id0, ih0, im0, is0) + + !monthly +!!$ time_idx = (iy0-1984)*12+in0 + ! daily + if ( in0 == 1 ) then + time_idx = (iy0-1976)*365 + id0 - 1 + else + time_idx = 0 + do i_m=1, in0-1 + time_idx = time_idx + n_days(i_m) + end do + time_idx = (iy0-1976)*365 + time_idx + id0 - 1 + end if + + if ( mpp_pe() == mpp_root_pe() ) then + write (UNIT=stdout_unit, FMT='("time_idx = ",I8)') time_idx + end if + + sfc_time0 = set_date(iy0, in0, id0, ih0, im0, is0) + + eta_filename='INPUT/ocean.19760101-20001231.eta_t.nc' + + call mpp_open(unit, trim(eta_filename), MPP_RDONLY, MPP_NETCDF, threading=MPP_MULTI, fileset=MPP_SINGLE) + call mpp_get_info(unit, ndim, nvar, natt, ntime) + + allocate(fields(nvar), STAT=istat) + if ( istat .ne. 0 ) then + call error_mesg('oda_core_mod::get_obs_sst', 'Unable to allocate fields', FATAL) + end if + + call mpp_get_fields(unit, fields) + do i=1, nvar + select case ( mpp_get_field_name(fields(i)) ) + case ('eta_t') + call mpp_read(unit, fields(i), eta_t, tindex=time_idx) + end select + end do + + do i=no_prf+no_sst+1, no_prf+no_sst+no_eta + Profiles(i)%time = sfc_time0 + + tdiff = model_time - Profiles(i)%time + + eta_lon = Profiles(i)%lon + ri0 = frac_index(eta_lon, x_grid(:,1)) + i0 = floor(ri0) + if ( i0 < 1 .or. i0 > 1440 ) then + write (UNIT=emsg_local, FMT='("Profiles(",I8,")%lon = ",I4,", i0 = ",I8)') i, Profiles(i)%lon, i0 + call error_mesg('oda_core_mod::get_obs_eta',& + & 'Profile longitude index outside range [1,1440]. '//trim(emsg_local), FATAL) + end if + + eta_lat = Profiles(i)%lat + rj0 = frac_index(eta_lat, y_grid(90,:)) + j0 = floor(rj0) + if ( j0 < 1 .or. j0 > 1070 ) then + write (UNIT=emsg_local, FMT='("Profiles(",I8,")%lat = ",I4,", j0 = ",I8)') i, Profiles(i)%lon, j0 + call error_mesg('oda_core_mod::get_obs_suv',& + & 'Profile latitude index outside range [1,1070]. '//trim(emsg_local), FATAL) + end if + + if ( Profiles(i)%accepted ) then + if ( eta_t(i0,j0) > -9.9 ) then !!! excluding missing values + nprof = nprof + 1 + if ( nprof > size(Prof,1) ) then + call error_mesg('oda_core_mod::get_obs_eta',& + & 'Passed in array "Prof" is smaller than number of profiles, increase size of Prof before call.',& + & FATAL) + end if + Profiles(i)%data(1) = eta_t(i0,j0) + + call copy_obs(Profiles(i:i),Prof(nprof+no_prf0:nprof+no_prf0)) + + Prof(nprof+no_prf0)%tdiff = tdiff + end if + end if + end do + + deallocate(fields) + call mpp_close(unit) + end subroutine get_obs_eta +end module oda_core_ecda_mod diff --git a/src/shared/oda_tools/oda_types.F90 b/src/shared/oda_tools/oda_types.F90 index 17f9611606..f2dea090e6 100644 --- a/src/shared/oda_tools/oda_types.F90 +++ b/src/shared/oda_tools/oda_types.F90 @@ -1,6 +1,12 @@ module oda_types_mod +#ifndef MAX_LEVS_FILE_ #define MAX_LEVS_FILE_ 50 - +#endif + +#ifndef MAX_LINKS_ +#define MAX_LINKS_ 100 +#endif + !============================================================ ! This module contains type declarations and default values ! for oda modules. @@ -16,22 +22,45 @@ module oda_types_mod private -! Controls record length for optimal storage - integer, parameter, public :: max_levels_file=MAX_LEVS_FILE_ -! Maximum number of neighbors for QC or analysis - integer, parameter, public :: max_neighbors=100 ! for profiles -! Maximum number of records per profile for storage - integer, parameter, public :: max_links=100 ! for profiles - -! List of variables for ODA + integer, parameter, public :: MAX_LEVELS_FILE = MAX_LEVS_FILE_ !< Controls record length for optimal storage + integer, parameter, public :: MAX_NEIGHBORS = 100 !< Maximum number of neighbors for QC or analysis for profiles + integer, parameter, public :: MAX_LINKS = MAX_LINKS_ !< Maximum number of records per profile for storage for profiles + + ! Additional Pramaeters needed for snz's ECDA + integer, parameter, public :: DROP_PROFILER = 10 + integer, parameter, public :: MOORING = 20 + integer, parameter, public :: SATELLITE = 30 + integer, parameter, public :: DRIFTER = 40 + integer, parameter, public :: SHIP = 50 + integer, parameter, public :: UNKNOWN = 0 + integer, parameter, public :: TAO = 1 !< moorings + integer, parameter, public :: PIRATA = 2 !< moorings + integer, parameter, public :: XBT = 1 !< station measurements + integer, parameter, public :: CTD = 2 !< station measurements + integer, parameter, public :: MBT = 3 !< station measurements + integer, parameter, public :: ARGO = 1 + + ! Codes for modeling error disttributions + integer, parameter, public :: COSSQ_LAT = 10 + + integer, save, public :: TEMP_ID = 1 + integer, save, public :: SALT_ID = 2 + + ! List of variables for ODA +#ifndef ENABLE_ECDA + real, parameter, public :: MISSING_VALUE = -1.e20 +#else + !::sdu:: ECDA oda files need this value to different + real, parameter, public :: MISSING_VALUE = -1.e10 +#endif - real, parameter, public :: missing_value=-1.e20 - type, public :: forward_model_type - real, dimension(:,:,:,:), pointer :: wgt=>NULL() ! interpolation weights + real, dimension(:,:,:,:), pointer :: wgt ! interpolation weights end type forward_model_type type, public :: ocean_profile_type + integer :: variable !< variable ids are defined by the ocean_types module (e.g. TEMP_ID, SALT_ID) + integer :: inst_type !< instrument types are defined by platform class (e.g. MOORING, DROP, etc.) and instrument type (XBT, CDT, etc.) integer :: nvar real :: project ! e.g. FGGE, COARE, ACCE, ... real :: probe ! MBT, XBT, drifting buoy @@ -47,21 +76,32 @@ module oda_types_mod logical :: accepted integer :: nlinks type(ocean_profile_type), pointer, dimension(:) :: next ! Large profiles are stored as linked list. - integer, dimension(max_neighbors) :: nbr_index - real, dimension(max_neighbors) :: nbr_dist ! distance in radians + integer, dimension(MAX_NEIGHBORS) :: nbr_index + real, dimension(MAX_NEIGHBORS) :: nbr_dist ! distance in radians real, dimension(:), pointer :: depth, data_t, data_s - integer, dimension(:), pointer :: flag_t ! level-by-level flags for temp + real, dimension(:), pointer :: data + integer, dimension(:), pointer :: flag_t integer, dimension(:), pointer :: flag_s ! level-by-level flags for salinity +#if !(defined(ENABLE_ECDA)||defined(__GFORTRAN__)) + ! this #if needed due to GNU not doing a logical cast properly + ! Will be removed in a later patch to only allow logical flag. + integer, dimension(:), pointer :: flag +#else + !::sdu:: For now ECDA use flag as a logical, will likely change in future releases. + logical, dimension(:), pointer :: flag +#endif real :: temp_err, salt_err ! measurement error - real, dimension(:), pointer :: ms_t ! ms temperature by level - real, dimension(:), pointer :: ms_s ! ms salinity by level + real, dimension(:), pointer :: ms_t ! ms temperature by level + real, dimension(:), pointer :: ms_s ! ms salinity by level + real, dimension(:), pointer :: ms_inv + real, dimension(:), pointer :: ms type(time_type) :: time integer :: yyyy integer :: mmdd type(time_type), pointer :: Model_time ! each profile can be associated with a first-guess field with an associated time and grid - type(grid_type), pointer :: Model_grid + type(grid_type), pointer :: Model_grid real :: i_index, j_index ! model longitude and latitude indices respectively - real, dimension(:), pointer :: k_index ! model depth indices + real, dimension(:), pointer :: k_index ! model depth indices type(forward_model_type) :: Forward_model ! linear operation from model to observation type(time_type) :: tdiff ! positive difference between model time and observation time end type ocean_profile_type @@ -72,35 +112,57 @@ module oda_types_mod integer :: qc_flag, nobs logical :: is_gridded integer :: nlon, nlat - real, pointer, dimension(:) :: lat, lon - logical :: accepted - real, pointer, dimension(:) :: data - real, dimension(:), pointer :: ms =>NULL() - real, dimension(:), pointer :: i_index=>NULL() , j_index=>NULL() ! model indices - real, pointer, dimension(:,:) :: data2=>NULL() - real, dimension(:,:), pointer :: ms2 =>NULL() - real, dimension(:,:), pointer :: i_index2=>NULL() , j_index2=>NULL() ! model indices + real, pointer, dimension(:) :: lat=>NULL(), lon=>NULL() + logical :: accepted + real, pointer, dimension(:) :: data => NULL() + real, dimension(:), pointer :: ms_inv => NULL() + real, dimension(:), pointer :: ms => NULL() + real, dimension(:), pointer :: i_index=>NULL(), j_index=>NULL() ! model indices + real, pointer, dimension(:,:) :: data2 => NULL() + real, dimension(:,:), pointer :: ms2 => NULL() + real, dimension(:,:), pointer :: i_index2=>NULL(), j_index2=>NULL() ! model indices real :: k_index type(forward_model_type) :: Forward_model type(time_type) :: time integer :: yyyy integer :: mmdd character(len=8) :: wmo_id - type(time_type), pointer :: Model_time=>NULL() - type(grid_type), pointer :: Model_grid=>NULL() + type(time_type), pointer :: Model_time => NULL() + type(grid_type), pointer :: Model_grid => NULL() ! positive difference between current model time ! and observation time type(time_type) :: tdiff end type ocean_surface_type + type, public :: da_flux_type + real, pointer, dimension(:,:) :: u_flux => NULL() + real, pointer, dimension(:,:) :: v_flux => NULL() + real, pointer, dimension(:,:) :: t_flux => NULL() + real, pointer, dimension(:,:) :: q_flux => NULL() + real, pointer, dimension(:,:) :: salt_flux => NULL() + real, pointer, dimension(:,:) :: lw_flux => NULL() + real, pointer, dimension(:,:) :: sw_flux_vis_dir => NULL() + real, pointer, dimension(:,:) :: sw_flux_vis_dif => NULL() + real, pointer, dimension(:,:) :: sw_flux_nir_dir => NULL() + real, pointer, dimension(:,:) :: sw_flux_nir_dif => NULL() + end type da_flux_type + + type, public :: ocn_obs_flag_type + logical :: use_prf_as_obs + logical :: use_ssh_as_obs + logical :: use_sst_as_obs + logical :: use_suv_as_obs + logical :: use_woa05_t + logical :: use_woa05_s + end type ocn_obs_flag_type type, public :: grid_type - real, pointer, dimension(:,:) :: x=>NULL() , y=>NULL() - real, pointer, dimension(:,:) :: x_bound=>NULL() , y_bound=>NULL() - real, pointer, dimension(:,:) :: dx=>NULL() , dy=>NULL() - real, pointer, dimension(:) :: z=>NULL() , z_bound=>NULL() - real, pointer, dimension(:) :: dz=>NULL() - real, pointer, dimension(:,:,:) :: mask=>NULL() + real, pointer, dimension(:,:) :: x=>NULL(), y=>NULL() + real, pointer, dimension(:,:) :: x_bound=>NULL(), y_bound=>NULL() + real, pointer, dimension(:,:) :: dx=>NULL(), dy=>NULL() + real, pointer, dimension(:) :: z=>NULL(), z_bound=>NULL() + real, pointer, dimension(:) :: dz => NULL() + real, pointer, dimension(:,:,:) :: mask type(domain2d), pointer :: Dom ! FMS domain type logical :: cyclic integer :: ni, nj, nk @@ -108,23 +170,23 @@ module oda_types_mod type, public :: field_type type(grid_type) :: grid - real, pointer, dimension(:,:,:) :: data=>NULL() + real, pointer, dimension(:,:,:) :: data => NULL() end type field_type type, public :: field_dist_type_3d integer :: error_model character(len=32) :: name - type(grid_type), pointer :: grid=>NULL() - real, pointer, dimension(:,:,:) :: ex=>NULL() , vr=>NULL() - real, pointer, dimension(:,:,:) :: obs_d=>NULL() ! obs minus expected value + type(grid_type), pointer :: grid => NULL() + real, pointer, dimension(:,:,:) :: ex=>NULL(), vr=>NULL() + real, pointer, dimension(:,:,:) :: obs_d => NULL() ! obs minus expected value end type field_dist_type_3d type, public :: field_dist_type_2d integer :: error_model character(len=32) :: name - type(grid_type), pointer :: grid=>NULL() - real, pointer, dimension(:,:) :: ex=>NULL() , vr=>NULL() + type(grid_type), pointer :: grid => NULL() + real, pointer, dimension(:,:) :: ex=>NULL(), vr=>NULL() end type field_dist_type_2d type, public :: ocean_dist_type @@ -132,6 +194,10 @@ module oda_types_mod type(field_dist_type_2d) :: eta end type ocean_dist_type + type, public :: obs_clim_type + real, pointer, dimension(:,:) :: sst_obs + end type obs_clim_type + public init_obs interface init_obs @@ -140,16 +206,7 @@ module oda_types_mod contains - subroutine oda_types_init() - - use fms_mod, only : open_namelist_file, check_nml_error, close_file - - - end subroutine oda_types_init - - subroutine init_obs_profile(profile) - type(ocean_profile_type), intent(inout) :: profile profile%nvar = 0 @@ -166,27 +223,27 @@ subroutine init_obs_profile(profile) profile%lat = -1.e10 profile%lon = -1.e10 profile%accepted = .true. - if (ASSOCIATED(profile%next)) deallocate(profile%next) + if (associated(profile%next)) deallocate(profile%next) profile%nlinks = 0 profile%nbr_index(:) = -1 profile%nbr_dist(:) = -1.0 - if (ASSOCIATED(profile%depth)) deallocate(profile%depth) - if (ASSOCIATED(profile%data_t)) deallocate(profile%data_t) - if (ASSOCIATED(profile%data_s)) deallocate(profile%data_s) - if (ASSOCIATED(profile%flag_t)) deallocate(profile%flag_t) - if (ASSOCIATED(profile%flag_s)) deallocate(profile%flag_s) - if (ASSOCIATED(profile%ms_t)) deallocate(profile%ms_t) - if (ASSOCIATED(profile%ms_s)) deallocate(profile%ms_s) + if (associated(profile%depth)) deallocate(profile%depth) + if (associated(profile%data_t)) deallocate(profile%data_t) + if (associated(profile%data_s)) deallocate(profile%data_s) + if (associated(profile%flag_t)) deallocate(profile%flag_t) + if (associated(profile%flag_s)) deallocate(profile%flag_s) + if (associated(profile%ms_t)) deallocate(profile%ms_t) + if (associated(profile%ms_s)) deallocate(profile%ms_s) profile%temp_err = -1.0 profile%salt_err = -1.0 profile%time = set_time(0,0) profile%yyyy = 0 profile%mmdd = 0 - if (ASSOCIATED(profile%model_time)) deallocate(profile%model_time) - if (ASSOCIATED(profile%model_grid)) deallocate(profile%model_grid) + if (associated(profile%model_time)) deallocate(profile%model_time) + if (associated(profile%model_grid)) deallocate(profile%model_grid) profile%i_index = -1 profile%j_index = -1 - if (ASSOCIATED(profile%k_index)) deallocate(profile%k_index) + if (associated(profile%k_index)) deallocate(profile%k_index) profile%tdiff = set_time(0,0) return diff --git a/src/shared/sat_vapor_pres/sat_vapor_pres.F90 b/src/shared/sat_vapor_pres/sat_vapor_pres.F90 index af7f0c8b34..dc25c2714f 100644 --- a/src/shared/sat_vapor_pres/sat_vapor_pres.F90 +++ b/src/shared/sat_vapor_pres/sat_vapor_pres.F90 @@ -491,8 +491,8 @@ module sat_vapor_pres_mod !----------------------------------------------------------------------- ! cvs version and tag name - character(len=128) :: version = '$Id: sat_vapor_pres.F90,v 19.0 2012/01/06 22:06:02 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: sat_vapor_pres.F90,v 20.0 2013/12/14 00:27:58 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. @@ -2207,6 +2207,7 @@ subroutine sat_vapor_pres_init(err_msg) !---- read namelist input ---- #ifdef INTERNAL_FILE_NML read (input_nml_file, sat_vapor_pres_nml, iostat=io) + ierr = check_nml_error(io,'sat_vapor_pres_nml') #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) @@ -2224,7 +2225,7 @@ subroutine sat_vapor_pres_init(err_msg) if (mpp_pe() == mpp_root_pe()) write (unit, nml=sat_vapor_pres_nml) if(do_simple) then - tcmin = -350 + tcmin = -173 tcmax = 350 endif nsize = (tcmax-tcmin)*esres+1 diff --git a/src/shared/sat_vapor_pres/sat_vapor_pres_k.F90 b/src/shared/sat_vapor_pres/sat_vapor_pres_k.F90 index 9c0ad3d9ea..7c6dab864a 100644 --- a/src/shared/sat_vapor_pres/sat_vapor_pres_k.F90 +++ b/src/shared/sat_vapor_pres/sat_vapor_pres_k.F90 @@ -29,7 +29,7 @@ module sat_vapor_pres_k_mod private character(len=128), parameter :: version = '$Id: sat_vapor_pres_k.F90,v 18.0 2010/03/02 23:58:26 fms Exp $' - character(len=128), parameter :: tagname = '$Name: siena_201207 $' + character(len=128), parameter :: tagname = '$Name: tikal $' public :: sat_vapor_pres_init_k public :: lookup_es_k diff --git a/src/shared/time_interp/time_interp.F90 b/src/shared/time_interp/time_interp.F90 index 83c5fd2152..97a1746f3c 100644 --- a/src/shared/time_interp/time_interp.F90 +++ b/src/shared/time_interp/time_interp.F90 @@ -35,7 +35,8 @@ module time_interp_mod use fms_mod, only: write_version_number, & error_mesg, FATAL, stdout, stdlog, & - open_namelist_file, close_file, check_nml_error + open_namelist_file, close_file, check_nml_error, & + fms_error_handler use mpp_mod, only: input_nml_file implicit none @@ -194,8 +195,8 @@ module time_interp_mod integer :: yrmod, momod, dymod logical :: mod_leapyear - character(len=128) :: version='$Id: time_interp.F90,v 19.0 2012/01/06 22:06:06 fms Exp $' - character(len=128) :: tagname='$Name: siena_201207 $' + character(len=128) :: version='$Id: time_interp.F90,v 20.0 2013/12/14 00:28:05 fms Exp $' + character(len=128) :: tagname='$Name: tikal $' logical :: module_is_initialized=.FALSE. logical :: perthlike_behavior=.FALSE. @@ -212,6 +213,7 @@ subroutine time_interp_init() #ifdef INTERNAL_FILE_NML read (input_nml_file, time_interp_nml, iostat=io) + ierr = check_nml_error (io, 'time_interp_nml') #else namelist_unit = open_namelist_file() ierr=1 @@ -470,12 +472,8 @@ subroutine time_interp_modulo(Time, Time_beg, Time_end, Timelist, weight, index1 n = size(Timelist) if (Time_beg>=Time_end) then - if(present(err_msg)) then - err_msg = "end of the specified time loop interval must be later than its beginning" - return - else - call error_handler("end of the specified time loop interval must be later than its beginning") - endif + if(fms_error_handler('time_interp_modulo', & + 'end of the specified time loop interval must be later than its beginning',err_msg)) return endif calendar_has_leap_years = (get_calendar_type() == JULIAN .or. get_calendar_type() == GREGORIAN) @@ -546,12 +544,8 @@ subroutine time_interp_modulo(Time, Time_beg, Time_end, Timelist, weight, index1 call print_date(Timelist(n), 'Timelist(n)' ) endif write(stdoutunit,*)'where n = size(Timelist) =',n - if(present(err_msg)) then - err_msg = 'the entire time list is outside the specified time loop interval' - return - else - call error_handler('the entire time list is outside the specified time loop interval') - endif + if(fms_error_handler('time_interp_modulo', & + 'the entire time list is outside the specified time loop interval',err_msg)) return endif call bisect(Timelist,Time_beg,index1=i1,index2=i2) @@ -591,12 +585,8 @@ subroutine time_interp_modulo(Time, Time_beg, Time_end, Timelist, weight, index1 endif write(stdoutunit,*)'where n = size(Timelist) =',n write(stdoutunit,*)'is =',is,'ie =',ie - if(present(err_msg)) then - err_msg = 'error in calculation of time list bounds within the specified time loop interval' - return - else - call error_handler('error in calculation of time list bounds within the specified time loop interval') - endif + if(fms_error_handler('time_interp_modulo', & + 'error in calculation of time list bounds within the specified time loop interval',err_msg)) return endif ! handle special cases: @@ -697,18 +687,13 @@ subroutine time_interp_list ( Time, Timelist, weight, index1, index2, modtime, e case (MONTH) ! month length must be equal if (days_in_month(Time_mod) /= days_in_month(Time)) then - if(present(err_msg)) then - err_msg = 'modulo months must have same length' - return - else - call error_handler ('modulo months must have same length') - endif + if(fms_error_handler ('time_interp_list','modulo months must have same length',err_msg)) return endif Period = set_time(0,days_in_month(Time_mod)) case (DAY) Period = set_time(0,1) case default - call error_handler ('invalid value for argument modtime') + if(fms_error_handler ('time_interp_list','invalid value for argument modtime',err_msg)) return end select ! If modulo time is in effect and Timelist spans a time interval exactly equal to @@ -729,12 +714,7 @@ subroutine time_interp_list ( Time, Timelist, weight, index1, index2, modtime, e ! Check that Timelist does not span a time interval greater than the modulo period if (mtime /= NONE) then if (Td > Period) then - if(present(err_msg)) then - err_msg = 'period of list exceeds modulo period' - return - else - call error_handler ('period of list exceeds modulo period') - endif + if(fms_error_handler ('time_interp_list','period of list exceeds modulo period',err_msg)) return endif endif @@ -746,12 +726,7 @@ subroutine time_interp_list ( Time, Timelist, weight, index1, index2, modtime, e ! time falls before starting list value else if ( T < Ts ) then if (mtime == NONE) then - if(present(err_msg)) then - err_msg = 'time before range of list' - return - else - call error_handler ('time before range of list') - endif + if(fms_error_handler ('time_interp_list','time before range of list',err_msg)) return endif Td = Te-Ts weight = 1. - ((Ts-T) // (Period-Td)) @@ -777,12 +752,7 @@ subroutine time_interp_list ( Time, Timelist, weight, index1, index2, modtime, e ! time falls after ending list value else if ( T > Te ) then if (mtime == NONE) then - if(present(err_msg)) then - err_msg = 'time after range of list' - return - else - call error_handler ('time after range of list') - endif + if(fms_error_handler ('time_interp_list','time after range of list',err_msg)) return endif Td = Te-Ts weight = (T-Te) // (Period-Td) diff --git a/src/shared/time_interp/time_interp_external.F90 b/src/shared/time_interp/time_interp_external.F90 index b7323f6cd7..6156af3c3e 100644 --- a/src/shared/time_interp/time_interp_external.F90 +++ b/src/shared/time_interp/time_interp_external.F90 @@ -50,8 +50,8 @@ module time_interp_external_mod private character(len=128), private :: version= & - 'CVS $Id: time_interp_external.F90,v 17.0.8.1.2.2.2.1.4.2.2.5 2012/04/20 18:08:09 Zhi.Liang Exp $' - character(len=128), private :: tagname='Tag $Name: siena_201207 $' + 'CVS $Id: time_interp_external.F90,v 20.0 2013/12/14 00:28:08 fms Exp $' + character(len=128), private :: tagname='Tag $Name: tikal $' integer, parameter, public :: NO_REGION=0, INSIDE_REGION=1, OUTSIDE_REGION=2 integer, parameter, private :: modulo_year= 0001 diff --git a/src/shared/time_manager/get_cal_time.F90 b/src/shared/time_manager/get_cal_time.F90 index 4831afc30b..fc0743a7ee 100644 --- a/src/shared/time_manager/get_cal_time.F90 +++ b/src/shared/time_manager/get_cal_time.F90 @@ -39,8 +39,8 @@ module get_cal_time_mod namelist / get_cal_time_nml / allow_calendar_conversion ! -character(len=128) :: version='$Id: get_cal_time.F90,v 19.0 2012/01/06 22:06:10 fms Exp $' -character(len=128) :: tagname='$Name: siena_201207 $' +character(len=128) :: version='$Id: get_cal_time.F90,v 20.0 2013/12/14 00:28:11 fms Exp $' +character(len=128) :: tagname='$Name: tikal $' contains !------------------------------------------------------------------------ @@ -166,7 +166,8 @@ function get_cal_time(time_increment, units, calendar, permit_calendar_conversio if(.not.module_is_initialized) then #ifdef INTERNAL_FILE_NML - read (input_nml_file, get_cal_time_nml, iostat=io) + read (input_nml_file, get_cal_time_nml, iostat=io) + ierr = check_nml_error (io, 'get_cal_time_nml') #else namelist_unit = open_namelist_file() ierr=1 diff --git a/src/shared/time_manager/get_cal_time.html b/src/shared/time_manager/get_cal_time.html deleted file mode 100644 index 41f7dfea71..0000000000 --- a/src/shared/time_manager/get_cal_time.html +++ /dev/null @@ -1,237 +0,0 @@ - - - -Module get_cal_time_mod - - - - -PUBLIC INTERFACE - - ~ PUBLIC ROUTINES - ~ NAMELIST -
                                                                    -

                                                                    Module get_cal_time_mod

                                                                    - - -
                                                                    -Contact:  - fms - -
                                                                    -Reviewers:  -
                                                                    -Change History: WebCVS Log -
                                                                    -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    OVERVIEW

                                                                    - -

                                                                    - Given a time increment as a real number, and base time and calendar - as a character strings, returns time as a time_type variable. -

                                                                    - - - -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    OTHER MODULES USED

                                                                    - -
                                                                    -
                                                                             fms_mod
                                                                    time_manager_mod
                                                                    mpp_mod
                                                                    -
                                                                    - - - -
                                                                    -

                                                                    PUBLIC INTERFACE

                                                                    -
                                                                    -
                                                                    -
                                                                    -get_cal_time:
                                                                    -
                                                                    -
                                                                    -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    PUBLIC ROUTINES

                                                                    - -
                                                                      -
                                                                    1. - -

                                                                      get_cal_time

                                                                      -
                                                                       
                                                                      -get_cal_time (time_increment, units, calendar, permit_calendar_conversion)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - -
                                                                      time_increment    A time interval.
                                                                         [real]
                                                                      units    - - Examples of acceptable values of units: - - 'days since 1980-01-01 00:00:00', - 'hours since 1980-1-1 0:0:0', - 'minutes since 0001-4-12' - - The first word in the string must be - 'years', 'months', 'days', 'hours', 'minutes' or 'seconds'. - The second word must be 'since' - - year number must occupy 4 spaces. - Number of months, days, hours, minutes, seconds may occupy 1 or 2 spaces - year, month and day must be separated by a '-' - hour, minute, second must be separated by a ':' - hour, minute, second are optional. If not present then zero is assumed. - - Because months are not equal increments of time, and, for julian calendar, - neither are years, the 'years since' and 'month since' cases deserve - further explaination. - - When 'years since' is used: - The year number is increased by floor(time_increment) to obtain a time T1. - The year number is increased by floor(time_increment)+1 to obtain a time T2. - The time returned is T1 + (time_increment-floor(time_increment))*(T2-T1). - - When 'months since' is used: - The month number is increased by floor(time_increment). If it falls outside - to range 1 to 12 then it is adjusted along with the year number to convert - to a valid date. The number of days in the month of this date is used to - compute the time interval of the fraction. - That is: - The month number is increased by floor(time_increment) to obtain a time T1. - delt = the number of days in the month in which T1 falls. - The time returned is T1 + ((time_increment-floor(time_increment))*delt. - Two of the consequences of this scheme should be kept in mind. - -- The time since should not be from the 29'th to 31'st of a month, - since an invalid date is likely to result, triggering an error stop. - -- When time since is from the begining of a month, the fraction of a month - will never advance into the month after that which results from only - the whole number. - - When NO_CALENDAR is in effect, units attribute must specify a starting - day and second, with day number appearing first - - Example: 'days since 100 0' Indicates 100 days 0 seconds -
                                                                         [character]
                                                                      calendar    - Acceptable values of calendar are: - 'noleap' - '365_day' - '360_day' - 'julian' - 'thirty_day_months' - 'no_calendar' -
                                                                         [character]
                                                                      permit_calendar_conversion    - It is sometimes desirable to allow the value of the intent(in) argument - "calendar" to be different than the calendar in use by time_manager_mod. - If this is not desirable, then the optional variable "permit_calendar_conversion" - should be set to .false. so as to allow an error check. - When calendar conversion is done, the time returned is the time in the - time_manager's calendar, but corresponds to the date computed using the input calendar. - For example, suppose the time_manager is using the julian calendar and - the values of the input arguments of get_cal_time are: - time_increment = 59.0 - units = 'days since 1980-1-1 00:00:00' - calendar = 'noleap' - Because it will use the noleap calendar to calculate the date, get_cal_time will return - value of time for midnight March 1 1980, but it will be time in the julian calendar - rather than the noleap calendar. It will never return a value of time corresponding - to anytime during the day Feb 29. - - Another example: - Suppose the time_manager is using either the noleap or julian calendars, - and the values of the input arguments are: - time_increment = 30.0 - units = 'days since 1980-1-1' - calendar = 'thirty_day_months' - In this case get_cal_time will return the value of time for Feb 1 1980 00:00:00, - but in the time_manager's calendar. - Calendar conversion may result in a fatal error when the input calendar type is - a calendar that has more days per year than that of the time_manager's calendar. - For example, if the input calendar type is julian and the time_manager's calendar - is thirty_day_months, then get_cal_time will try to convert Jan 31 to a time in - the thirty_day_months calendar, resulting in a fatal error. - Note: this option was originally coded to allow noleap calendar as input when - the julian calendar was in effect by the time_manager. -
                                                                         [logical, optional] [Default: allow_calendar_conversion]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    2. -
                                                                    - - - - -
                                                                    -

                                                                    NAMELIST

                                                                    - -
                                                                    -&get_cal_time_nml -
                                                                    -
                                                                    -
                                                                    -
                                                                    -
                                                                    -allow_calendar_conversion -
                                                                    -
                                                                    - This sets the default value of the optional argument named "permit_calendar_conversion" of get_cal_time. - This namelist is deprecated as of the memphis release. - If calendar conversion is not desired, then it is recommended that permit_calendar_conversion - be present in the call to get_cal_time and that it be set to .false. -
                                                                    -[logical, default: .true.] -
                                                                    -
                                                                    -
                                                                    -
                                                                    -
                                                                    - - - - -
                                                                    -
                                                                    -top -
                                                                    - - diff --git a/src/shared/time_manager/time_manager.F90 b/src/shared/time_manager/time_manager.F90 index 02f3318988..e5ba9acd99 100644 --- a/src/shared/time_manager/time_manager.F90 +++ b/src/shared/time_manager/time_manager.F90 @@ -70,6 +70,8 @@ module time_manager_mod ! contains three PRIVATE variables: days, seconds and ticks. !
                                                                    +#include + use constants_mod, only: rseconds_per_day=>seconds_per_day use fms_mod, only: error_mesg, FATAL, WARNING, write_version_number, stdout @@ -177,8 +179,8 @@ module time_manager_mod !====================================================================== -character(len=128) :: version='$Id: time_manager.F90,v 19.0 2012/01/06 22:06:12 fms Exp $' -character(len=128) :: tagname='$Name: siena_201207 $' +character(len=128) :: version='$Id: time_manager.F90,v 20.0 2013/12/14 00:28:14 fms Exp $' +character(len=128) :: tagname='$Name: tikal $' logical :: module_is_initialized = .false. !====================================================================== @@ -1229,7 +1231,7 @@ end subroutine time_assignment function time_type_to_real(time) -double precision :: time_type_to_real +real(DOUBLE_KIND) :: time_type_to_real type(time_type), intent(in) :: time if(.not.module_is_initialized) call time_manager_init @@ -3414,7 +3416,8 @@ program test call constants_init #ifdef INTERNAL_FILE_NML - read (input_nml_file, test_nml, iostat=io) + read (input_nml_file, test_nml, iostat=io) + ierr = check_nml_error (io, 'test_nml') #else nmlunit = open_namelist_file() ierr=1 diff --git a/src/shared/time_manager/time_manager.html b/src/shared/time_manager/time_manager.html deleted file mode 100644 index b12149d114..0000000000 --- a/src/shared/time_manager/time_manager.html +++ /dev/null @@ -1,2445 +0,0 @@ - - - -Module time_manager_mod - - - - -PUBLIC INTERFACE - ~ PUBLIC DATA - - ~ PUBLIC ROUTINES -
                                                                    -

                                                                    Module time_manager_mod

                                                                    - - -
                                                                    -Contact:  - fms - -
                                                                    -Reviewers:  -
                                                                    -Change History: WebCVS Log -
                                                                    -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    OVERVIEW

                                                                    - -

                                                                    - A software package that provides a set of simple interfaces for - modelers to perform computations related to time and dates. -

                                                                    - - - -
                                                                    - The changes between the lima revision and this revision are more - extensive that all those between antwerp and lima. - A brief description of these changes follows. - - 1) Added option to set the smallest time increment to something less than one second. - This is controlled by calling the pubic subroutine set_ticks_per_second. - - 2) Gregorian calendar fixed. - - 3) Optional error flag added to calling arguments of public routines. - This allows the using routine to terminate the program. It is likely that more - diagnostic information is available from the user than from time_manager alone. - If the error flag is present then it is the responsibility of the using - routine to test it and add additional information to the error message. - - 4) Removed the restriction that time increments be positive in routines that increment or decrement - time and date. The option to prohibit negative increments can be turned on via optional argument. - - 5) subroutine set_date_c modified to handle strings that include only hours or only hours and minutes. - This complies with CF convensions. - - 6) Made calendar specific routines private. - They are not used, and should not be used, by any using code. - - 7) Error messages made more informative. - - The module defines a type that can be used to represent discrete - times (accurate to one second) and to map these times into dates - using a variety of calendars. A time is mapped to a date by - representing the time with respect to an arbitrary base date (refer - to NOTES section for the base date setting). - - The time_manager provides a single defined type, time_type, which is - used to store time and date quantities. A time_type is a positive - definite quantity that represents an interval of time. It can be - most easily thought of as representing the number of seconds in some - time interval. A time interval can be mapped to a date under a given - calendar definition by using it to represent the time that has passed - since some base date. A number of interfaces are provided to operate - on time_type variables and their associated calendars. Time intervals - can be as large as n days where n is the largest number represented by - the default integer type on a compiler. This is typically considerably - greater than 10 million years (assuming 32 bit integer representation) - which is likely to be adequate for most applications. The description - of the interfaces is separated into two sections. The first deals with - operations on time intervals while the second deals with operations - that convert time intervals to dates for a given calendar. - The smallest increment of time is referred to as a tick. - A tick cannot be larger than 1 second, which also is the default. - The number of ticks per second is set via pubic subroutine set_ticks_per_second. - For example, ticks_per_second = 1000 will set the tick to one millisecond. -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    OTHER MODULES USED

                                                                    - -
                                                                    -
                                                                    constants_mod
                                                                    fms_mod
                                                                    -
                                                                    - - - -
                                                                    -

                                                                    PUBLIC INTERFACE

                                                                    -
                                                                    -
                                                                    -
                                                                    -set_time:
                                                                    -
                                                                    - Given some number of seconds and days, returns the - corresponding time_type. -
                                                                    -
                                                                    -get_time:
                                                                    -
                                                                    - Given a time interval, returns the corresponding seconds and days. -
                                                                    -
                                                                    -increment_time:
                                                                    -
                                                                    - Given a time and an increment of days and seconds, returns - a time that adds this increment to an input time. -
                                                                    -
                                                                    -decrement_time:
                                                                    -
                                                                    - Given a time and a decrement of days and seconds, returns - a time that subtracts this decrement from an input time. -
                                                                    -
                                                                    -time_gt operator(>):
                                                                    -
                                                                    - Returns true if time1 > time2. -
                                                                    -
                                                                    -time_ge; operator(>=):
                                                                    -
                                                                    - Returns true if time1 >= time2. -
                                                                    -
                                                                    -time_lt; operator(<):
                                                                    -
                                                                    - Returns true if time1 < time2. -
                                                                    -
                                                                    -time_le; operator(<=):
                                                                    -
                                                                    - Returns true if time1 <= time2. -
                                                                    -
                                                                    -time_eq; operator(==):
                                                                    -
                                                                    - Returns true if time1 == time2. -
                                                                    -
                                                                    -time_ne; operator(/=):
                                                                    -
                                                                    - Returns true if time1 /= time2. -
                                                                    -
                                                                    -time_plus; operator(+):
                                                                    -
                                                                    - Returns sum of two time_types. -
                                                                    -
                                                                    -time_minus; operator(-):
                                                                    -
                                                                    - Returns difference of two time_types. -
                                                                    -
                                                                    -time_scalar_mult; operator(*):
                                                                    -
                                                                    - Returns time multiplied by integer factor n. -
                                                                    -
                                                                    -scalar_time_mult; operator(*):
                                                                    -
                                                                    - Returns time multiplied by integer factor n. -
                                                                    -
                                                                    -time_divide; operator(/):
                                                                    -
                                                                    - Returns the largest integer, n, for which time1 >= time2 * n. -
                                                                    -
                                                                    -time_real_divide; operator(//):
                                                                    -
                                                                    - Returns the double precision quotient of two times. -
                                                                    -
                                                                    -time_assignment; assignment(=):
                                                                    -
                                                                    - Assigns all components of the time_type variable on - RHS to same components of time_type variable on LHS. -
                                                                    -
                                                                    -time_type_to_real:
                                                                    -
                                                                    - Converts time to seconds and returns it as a real number -
                                                                    -
                                                                    -real_to_time_type:
                                                                    -
                                                                    - Converts a real number of seconds to a time_type variable -
                                                                    -
                                                                    -time_scalar_divide; operator(/):
                                                                    -
                                                                    - Returns the largest time, t, for which n * t <= time. -
                                                                    -
                                                                    -interval_alarm:
                                                                    -
                                                                    - Given a time, and a time interval, this function returns true - if this is the closest time step to the alarm time. -
                                                                    -
                                                                    -repeat_alarm:
                                                                    -
                                                                    - Repeat_alarm supports an alarm that goes off with - alarm_frequency and lasts for alarm_length. -
                                                                    -
                                                                    -set_calendar_type:
                                                                    -
                                                                    - Sets the default calendar type for mapping time intervals to dates. -
                                                                    -
                                                                    -get_calendar_type:
                                                                    -
                                                                    - Returns the value of the default calendar type for mapping - from time to date. -
                                                                    -
                                                                    -set_ticks_per_second:
                                                                    -
                                                                    - Sets the number of ticks per second. -
                                                                    -
                                                                    -get_ticks_per_second:
                                                                    -
                                                                    - Returns the number of ticks per second. -
                                                                    -
                                                                    -get_date:
                                                                    -
                                                                    - Given a time_interval, returns the corresponding date under - the selected calendar. -
                                                                    -
                                                                    -set_date:
                                                                    -
                                                                    - Given an input date in year, month, days, etc., creates a - time_type that represents this time interval from the - internally defined base date. -
                                                                    -
                                                                    -increment_date:
                                                                    -
                                                                    - Increments the date represented by a time interval and the - default calendar type by a number of seconds, etc. -
                                                                    -
                                                                    -decrement_date:
                                                                    -
                                                                    - Decrements the date represented by a time interval and the - default calendar type by a number of seconds, etc. -
                                                                    -
                                                                    -days_in_month:
                                                                    -
                                                                    - Given a time interval, gives the number of days in the - month corresponding to the default calendar. -
                                                                    -
                                                                    -leap_year:
                                                                    -
                                                                    - Returns true if the year corresponding to the input time is - a leap year. Always returns false for THIRTY_DAY_MONTHS and NOLEAP. -
                                                                    -
                                                                    -length_of_year:
                                                                    -
                                                                    - Returns the mean length of the year in the default calendar setting. -
                                                                    -
                                                                    -days_in_year:
                                                                    -
                                                                    - Returns the number of days in the calendar year corresponding to - the date represented by time for the default calendar. -
                                                                    -
                                                                    -month_name:
                                                                    -
                                                                    - Returns a character string containing the name of the - month corresponding to month number n. -
                                                                    -
                                                                    -time_manager_init:
                                                                    -
                                                                    - Writes the version information to the log file -
                                                                    -
                                                                    -print_time:
                                                                    -
                                                                    - Prints the given time_type argument as a time (using days, seconds and ticks) -
                                                                    -
                                                                    -print_date:
                                                                    -
                                                                    - prints the time to standard output (or optional unit) as a date. -
                                                                    -
                                                                    -valid_calendar_types:
                                                                    -
                                                                    - Returns a character string that describes the - calendar type corresponding to the input integer. -
                                                                    -
                                                                    -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    PUBLIC DATA

                                                                    - -
                                                                    - - - - - - - -
                                                                    Name Type Value Units Description
                                                                    time_type derived type --- --- - Derived-type data variable used to store time and date quantities. It - contains three PRIVATE variables: days, seconds and ticks. -
                                                                    -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    PUBLIC ROUTINES

                                                                    - -
                                                                      -
                                                                    1. - -

                                                                      set_time

                                                                      -
                                                                      1. set_time (seconds, days, ticks, err_msg)
                                                                      -
                                                                      2. set_time (time_string, err_msg, allow_rounding)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given some number of seconds and days, returns the - corresponding time_type. set_time has two forms; - one accepts integer input, the other a character string. - For the first form, there are no restrictions on the range of the inputs, - except that the result must be positive time. - e.g. days=-1, seconds=86401 is acceptable. - For the second form, days and seconds must both be positive. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - -
                                                                      seconds    - A number of seconds. -
                                                                         [integer, dimension(scalar)]
                                                                      days    - A number of days. -
                                                                         [integer, dimension(scalar)]
                                                                      ticks    - A number of ticks. -
                                                                         [integer, optional, dimension(scalar)]
                                                                      time_string    - Contains days and seconds separated by a single blank. - days must be integer, seconds may be integer or real. - Examples: '100 43200' '100 43200.50' -
                                                                         [character]
                                                                      allow_rounding    - When .true., any fractions of a second will be rounded off to the nearest tick. - When .false., it is a fatal error if the second fraction cannot be exactly - represented by a number of ticks. -
                                                                         [logical, optional] [Default: .true.]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      set_time    - A time interval corresponding to this number of days and seconds. -
                                                                         [, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    2. -
                                                                    3. - -

                                                                      get_time

                                                                      -
                                                                       
                                                                      -get_time (time, seconds, days, ticks, err_msg)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a time interval, returns the corresponding seconds and days. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      time    - A time interval. -
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - -
                                                                      seconds    - A number of seconds. -
                                                                         [integer, dimension(scalar)]
                                                                      days    - A number of days. -
                                                                         [integer, dimension(scalar)]
                                                                      ticks    - A number of ticks. -
                                                                         [integer, optional, dimension(scalar)]
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    4. -
                                                                    5. - -

                                                                      increment_time

                                                                      -
                                                                       
                                                                      -increment_time (time, seconds, days, ticks, err_msg, allow_neg_inc)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a time and an increment of days and seconds, returns - a time that adds this increment to an input time. - Increments a time by seconds and days. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - -
                                                                      time    - A time interval. -
                                                                         [time_type, dimension(scalar)]
                                                                      seconds    - Increment of seconds. -
                                                                         [integer, dimension(scalar)]
                                                                      days    - Increment of days. -
                                                                         [integer, optional, dimension(scalar)]
                                                                      ticks    - Increment of ticks. -
                                                                         [integer, optional, dimension(scalar)]
                                                                      allow_neg_inc    - When .false., it is a fatal error if any of the input time increments are negative. - This mimics the behavior of lima and earlier revisions. -
                                                                         [logical, optional, dimension(scalar)] [Default: .true.]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      increment_time    - A time that adds this increment to the input time. - A negative result is a fatal error. -
                                                                         [time_type, dimension(scalar)]
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    6. -
                                                                    7. - -

                                                                      decrement_time

                                                                      -
                                                                       
                                                                      -decrement_time (time, seconds, days, ticks, err_msg, allow_neg_inc)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Decrements a time by seconds and days. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - -
                                                                      time    - A time interval. -
                                                                         [time_type, dimension(scalar)]
                                                                      seconds    - Decrement of seconds. -
                                                                         [integer, dimension(scalar)]
                                                                      days    - Decrement of days. -
                                                                         [integer, optional, dimension(scalar)]
                                                                      ticks    - Decrement of ticks. -
                                                                         [integer, optional, dimension(scalar)]
                                                                      allow_neg_inc    - When .false., it is a fatal error if any of the input time increments are negative. - This mimics the behavior of lima and earlier revisions. -
                                                                         [logical, optional, dimension(scalar)] [Default: .true.]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      decrement_time    - A time that subtracts this decrement from an input time. - A negative result is a fatal error. -
                                                                         [time_type]
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    8. -
                                                                    9. - -

                                                                      time_gt operator(>)

                                                                      -
                                                                       
                                                                      -time_gt  operator(>) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if time1 > time2. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns true if time1 > time2 -
                                                                         [logical, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    10. -
                                                                    11. - -

                                                                      time_ge; operator(>=)

                                                                      -
                                                                       
                                                                      -time_ge; operator(>=) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if time1 >= time2. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns true if time1 >= time2 -
                                                                         [logical, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    12. -
                                                                    13. - -

                                                                      time_lt; operator(<)

                                                                      -
                                                                       
                                                                      -time_lt; operator(<) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if time1 < time2. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns true if time1 < time2 -
                                                                         [logical, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    14. -
                                                                    15. - -

                                                                      time_le; operator(<=)

                                                                      -
                                                                       
                                                                      -time_le; operator(<=) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if time1 <= time2. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns true if time1 <= time2 -
                                                                         [logical, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    16. -
                                                                    17. - -

                                                                      time_eq; operator(==)

                                                                      -
                                                                       
                                                                      -time_eq; operator(==) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if time1 == time2. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns true if time1 == time2 -
                                                                         [logical, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    18. -
                                                                    19. - -

                                                                      time_ne; operator(/=)

                                                                      -
                                                                       
                                                                      -time_ne; operator(/=) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if time1 /= time2. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns true if time1 /= time2 -
                                                                         [logical, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    20. -
                                                                    21. - -

                                                                      time_plus; operator(+)

                                                                      -
                                                                       
                                                                      -time_plus; operator(+) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns sum of two time_types. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns sum of two time_types. -
                                                                         [time_type, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    22. -
                                                                    23. - -

                                                                      time_minus; operator(-)

                                                                      -
                                                                       
                                                                      -time_minus; operator(-) 
                                                                      -
                                                                      -
                                                                       
                                                                      -time_minus; operator(-) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns difference of two time_types. WARNING: a time type is positive - so by definition time1 - time2 is the same as time2 - time1. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns difference of two time_types. -
                                                                         [time_type, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    24. -
                                                                    25. - -

                                                                      time_scalar_mult; operator(*)

                                                                      -
                                                                       
                                                                      -time_scalar_mult; operator(*) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns time multiplied by integer factor n. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time    - A time interval. -
                                                                         [time_type, dimension]
                                                                      n    - A time interval. -
                                                                         [integer, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns time multiplied by integer factor n. -
                                                                         [time_type, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    26. -
                                                                    27. - -

                                                                      scalar_time_mult; operator(*)

                                                                      -
                                                                       
                                                                      -scalar_time_mult; operator(*) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns time multiplied by integer factor n. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time   A time interval.
                                                                         [time_type, dimension]
                                                                      n    An integer.
                                                                         [integer, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns time multiplied by integer factor n. -
                                                                         [time_type, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    28. -
                                                                    29. - -

                                                                      time_divide; operator(/)

                                                                      -
                                                                       
                                                                      -time_divide; operator(/) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns the largest integer, n, for which time1 >= time2 * n. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns the largest integer, n, for which time1 >= time2 * n. -
                                                                         [integer, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    30. -
                                                                    31. - -

                                                                      time_real_divide; operator(//)

                                                                      -
                                                                       
                                                                      -time_real_divide; operator(//) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns the double precision quotient of two times. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time1    - A time interval. -
                                                                         [time_type, dimension]
                                                                      time2    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns the double precision quotient of two times -
                                                                         [integer, dimensiondouble precision] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    32. -
                                                                    33. - -

                                                                      time_assignment; assignment(=)

                                                                      -
                                                                       
                                                                      -time_assignment; assignment(=) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Assigns all components of the time_type variable on - RHS to same components of time_type variable on LHS. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      time2    - A time type variable. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      time1    - A time type variable. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    34. -
                                                                    35. - -

                                                                      time_type_to_real

                                                                      -
                                                                       
                                                                      -time_type_to_real (time)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Converts time to seconds and returns it as a real number -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      time    - A time interval. -
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    36. -
                                                                    37. - -

                                                                      real_to_time_type

                                                                      -
                                                                       
                                                                      -real_to_time_type (x, err_msg)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Converts a real number of seconds to a time_type variable -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      x    - A real number of seconds -
                                                                         [real, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      real_to_time_type    - -
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    38. -
                                                                    39. - -

                                                                      time_scalar_divide; operator(/)

                                                                      -
                                                                       
                                                                      -time_scalar_divide; operator(/) 
                                                                      -
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns the largest time, t, for which n * t <= time. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      time    - A time interval. -
                                                                         [time_type, dimension]
                                                                      n    - An integer factor. -
                                                                         [integer, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - Returns the largest time, t, for which n * t <= time. -
                                                                         [integer, dimensiondouble precision] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    40. -
                                                                    41. - -

                                                                      interval_alarm

                                                                      -
                                                                       
                                                                      -interval_alarm (time, time_interval, alarm, alarm_interval)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - This is a specialized operation that is frequently performed in models. - Given a time, and a time interval, this function is true if this is the - closest time step to the alarm time. The actual computation is: - - if((alarm_time - time) <= (time_interval / 2)) - - If the function is true, the alarm time is incremented by the - alarm_interval; WARNING, this is a featured side effect. Otherwise, the - function is false and there are no other effects. CAUTION: if the - alarm_interval is smaller than the time_interval, the alarm may fail to - return true ever again. Watch - for problems if the new alarm time is less than time + time_interval -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - -
                                                                      time    Current time.
                                                                         [time_type]
                                                                      time_interval    A time interval.
                                                                         [time_type]
                                                                      alarm_interval    A time interval.
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT/OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      alarm    - An alarm time, which is incremented by the alarm_interval - if the function is true. -
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      interval_alarm    - Returns either True or false. -
                                                                         [logical]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    42. -
                                                                    43. - -

                                                                      repeat_alarm

                                                                      -
                                                                       
                                                                      -repeat_alarm (time, alarm_frequency, alarm_length)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Repeat_alarm supports an alarm that goes off with alarm_frequency and - lasts for alarm_length. If the nearest occurence of an alarm time - is less than half an alarm_length from the input time, repeat_alarm - is true. For instance, if the alarm_frequency is 1 day, and the - alarm_length is 2 hours, then repeat_alarm is true from time 2300 on - day n to time 0100 on day n + 1 for all n. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - -
                                                                      time    Current time.
                                                                         [time_type]
                                                                      alarm_frequency    - A time interval for alarm_frequency. -
                                                                         [time_type]
                                                                      alarm_length    - A time interval for alarm_length. -
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      repeat_alarm    - Returns either True or false. -
                                                                         [logical]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    44. -
                                                                    45. - -

                                                                      set_calendar_type

                                                                      -
                                                                       
                                                                      -set_calendar_type (type, err_msg)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - A constant number for setting the calendar type. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      type    - A constant number for setting the calendar type. -
                                                                         [integer, dimension(scalar)] [Default: NO_CALENDAR]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    46. -
                                                                    47. - -

                                                                      get_calendar_type

                                                                      -
                                                                       
                                                                      -get_calendar_type ()
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - There are no arguments in this function. It returns the value of - the default calendar type for mapping from time to date. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    48. -
                                                                    49. - -

                                                                      set_ticks_per_second

                                                                      -
                                                                      -call set_ticks_per_second (ticks_per_second)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Sets the number of ticks per second. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      type    -
                                                                         [integer, dimension(scalar)] [Default: 1]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    50. -
                                                                    51. - -

                                                                      get_ticks_per_second

                                                                      -
                                                                      ticks_per_second = get_ticks_per_second ()
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns the number of ticks per second. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    52. -
                                                                    53. - -

                                                                      get_date

                                                                      -
                                                                       
                                                                      -get_date (time, year, month, day, hour, minute, second, tick, err_msg)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a time_interval, returns the corresponding date under - the selected calendar. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      time    A time interval.
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                                      year    -
                                                                         [integer]
                                                                      month    -
                                                                         [integer]
                                                                      day    -
                                                                         [integer]
                                                                      hour    -
                                                                         [integer]
                                                                      minute    -
                                                                         [integer]
                                                                      second    -
                                                                         [integer]
                                                                      tick    -
                                                                         [integer, optional]
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    54. -
                                                                    55. - -

                                                                      set_date

                                                                      -
                                                                      1. set_date (year, month, day, hours, minute, second, tick, err_msg)
                                                                      -
                                                                      2. set_date _c(time_string, zero_year_warning, err_msg, allow_rounding) time_string is a character string containing a date formatted according to CF conventions. e.g. '1980-12-31 23:59:59.9'
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a date, computes the corresponding time given the selected - date time mapping algorithm. Note that it is possible to specify - any number of illegal dates; these should be checked for and generate - errors as appropriate. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                                      time    A time interval.
                                                                         [time_type]
                                                                      year    -
                                                                         [integer]
                                                                      month    -
                                                                         [integer]
                                                                      day    -
                                                                         [integer]
                                                                      hour    -
                                                                         [integer]
                                                                      minute    -
                                                                         [integer]
                                                                      second    -
                                                                         [integer]
                                                                      tick    -
                                                                         [integer]
                                                                      zero_year_warning    - If the year number is zero, it will be silently changed to one, - unless zero_year_warning=.true., in which case a WARNING message - will also be issued. -
                                                                         [logical]
                                                                      allow_rounding    - When .true., any fractions of a second will be rounded off to the nearest tick. - When .false., it is a fatal error if the second fraction cannot be exactly - represented by a number of ticks. -
                                                                         [logical, optional] [Default: .true.]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      set_date    A time interval.
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    56. -
                                                                    57. - -

                                                                      increment_date

                                                                      -
                                                                       
                                                                      -increment_date (time, years, months, days, hours, minutes, seconds, ticks, err_msg)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a time and some date increment, computes a new time. Depending - on the mapping algorithm from date to time, it may be possible to specify - undefined increments (i.e. if one increments by 68 days and 3 months in - a Julian calendar, it matters which order these operations are done and - we don't want to deal with stuff like that, make it an error). -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                                      time    A time interval.
                                                                         [time_type]
                                                                      years   An increment of years.
                                                                         [integer]
                                                                      months   An increment of months.
                                                                         [integer]
                                                                      days   An increment of days.
                                                                         [integer]
                                                                      hours   An increment of hours.
                                                                         [integer]
                                                                      minutes   An increment of minutes.
                                                                         [integer]
                                                                      seconds   An increment of seconds.
                                                                         [integer]
                                                                      ticks   An increment of ticks.
                                                                         [integer]
                                                                      allow_neg_inc    - When .false., it is a fatal error if any of the input time increments are negative. - This mimics the behavior of lima and earlier revisions. -
                                                                         [logical, optional, dimension(scalar)] [Default: .true.]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      increment_date    A new time based on the input - time interval and the calendar type. -
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -NOTE -
                                                                      -
                                                                      - For all but the thirty_day_months calendar, increments to months - and years must be made separately from other units because of the - non-associative nature of addition. - If the result is a negative time (i.e. date before the base date) - it is considered a fatal error. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    58. -
                                                                    59. - -

                                                                      decrement_date

                                                                      -
                                                                       
                                                                      -decrement_date (time, years, months, days, hours, minutes, seconds, ticks, err_msg))
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a time and some date decrement, computes a new time. Depending - on the mapping algorithm from date to time, it may be possible to specify - undefined decrements (i.e. if one decrements by 68 days and 3 months in - a Julian calendar, it matters which order these operations are done and - we don't want to deal with stuff like that, make it an error). -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                                      time    A time interval.
                                                                         [time_type]
                                                                      years   An decrement of years.
                                                                         [integer]
                                                                      months   An decrement of months.
                                                                         [integer]
                                                                      days   An decrement of days.
                                                                         [integer]
                                                                      hours   An decrement of hours.
                                                                         [integer]
                                                                      minutes   An decrement of minutes.
                                                                         [integer]
                                                                      seconds   An decrement of seconds.
                                                                         [integer]
                                                                      ticks   An decrement of ticks.
                                                                         [integer]
                                                                      allow_neg_inc    - When .false., it is a fatal error if any of the input time increments are negative. - This mimics the behavior of lima and earlier revisions. -
                                                                         [logical, optional, dimension(scalar)] [Default: .true.]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      decrement_date    A new time based on the input - time interval and the calendar type. -
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -NOTE -
                                                                      -
                                                                      - For all but the thirty_day_months calendar, decrements to months - and years must be made separately from other units because of the - non-associative nature of addition. - If the result is a negative time (i.e. date before the base date) - it is considered a fatal error. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    60. -
                                                                    61. - -

                                                                      days_in_month

                                                                      -
                                                                       
                                                                      -days_in_month (time)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Given a time, computes the corresponding date given the selected - date time mapping algorithm. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      time   A time interval.
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      days_in_month    - The number of days in the month given the selected time - mapping algorithm. -
                                                                         [integer, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    62. -
                                                                    63. - -

                                                                      leap_year

                                                                      -
                                                                       
                                                                      -leap_year (time)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns true if the year corresponding to the input time is - a leap year. Always returns false for THIRTY_DAY_MONTHS and NOLEAP. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      time   A time interval.
                                                                         [time_type, dimension]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      leap_year    - true if the year corresponding to the input time is a leap year. -
                                                                         [calendar_type, dimension] [Default: ]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    64. -
                                                                    65. - -

                                                                      length_of_year

                                                                      -
                                                                       
                                                                      -length_of_year ()
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - There are no arguments in this function. It returns the mean - length of the year in the default calendar setting. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    66. -
                                                                    67. - -

                                                                      days_in_year

                                                                      -
                                                                       
                                                                      -days_in_year (Time)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns the number of days in the calendar year corresponding to - the date represented by time for the default calendar. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      Time   A time interval.
                                                                         [time_type]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                          - The number of days in this year for the default calendar type. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    68. -
                                                                    69. - -

                                                                      month_name

                                                                      -
                                                                       
                                                                      -month_name (n)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns a character string containing the name of the - month corresponding to month number n. Definition is the - same for all calendar types. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      n   Month number.
                                                                         [integer]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - -
                                                                      month_name    - The character string associated with a month. - All calendars have 12 months and return full - month names, not abreviations. -
                                                                         [character(len=9)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    70. -
                                                                    71. - -

                                                                      time_manager_init

                                                                      -
                                                                       
                                                                      -time_manager_init ()
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Initialization routine. - Writes the version information to the log file -
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    72. -
                                                                    73. - -

                                                                      print_time

                                                                      -
                                                                       
                                                                      -print_time (time,str,unit)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Prints the given time_type argument as a time (using days, seconds and ticks) - NOTE: there is no check for PE number. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - -
                                                                      time    Time that will be printed.
                                                                         [time_type]
                                                                      str    - Character string that precedes the printed time or date. -
                                                                         [character (len=*)] [Default: TIME: or DATE:]
                                                                      unit    - Unit number for printed output. The default unit is stdout. -
                                                                         [integer]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    74. -
                                                                    75. - -

                                                                      print_date

                                                                      -
                                                                       
                                                                      -print_date (time,str,unit)
                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Prints the given time_type argument as a date (using year, month, day, - hour, minutes, seconds and ticks). NOTE: there is no check for PE number. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - - - - - - - -
                                                                      time    Time that will be printed.
                                                                         [time_type]
                                                                      str    - Character string that precedes the printed time or date. -
                                                                         [character (len=*)] [Default: TIME: or DATE:]
                                                                      unit    - Unit number for printed output. The default unit is stdout. -
                                                                         [integer]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    76. -
                                                                    77. - -

                                                                      valid_calendar_types

                                                                      -
                                                                      -
                                                                      -DESCRIPTION -
                                                                      -
                                                                      - Returns a character string that describes the - calendar type corresponding to the input integer. -
                                                                      -
                                                                      -
                                                                      -
                                                                      -INPUT -
                                                                      -
                                                                      - - - - -
                                                                      ncal    - An integer corresponding to a valid calendar type. -
                                                                         [integer]
                                                                      -
                                                                      -
                                                                      -
                                                                      -OUTPUT -
                                                                      -
                                                                      - - - - - - - -
                                                                      err_msg    - When present, and when non-blank, a fatal error condition as been detected. - The string itself is an error message. - It is recommended that, when err_msg is present in the call - to this routine, the next line of code should be something - similar to this: - if(err_msg /= '') call error_mesg('my_routine','additional info: '//trim(err_msg),FATAL) -
                                                                         [character, optional, dimension(scalar)]
                                                                      valid_calendar_types    - A character string describing the calendar type. -
                                                                         [character(len=24)]
                                                                      -
                                                                      -
                                                                      -
                                                                      -
                                                                    78. -
                                                                    - - - - - - -
                                                                    -

                                                                    TEST PROGRAM

                                                                    - -
                                                                    -
                                                                    -
                                                                    time_main2
                                                                    -
                                                                    - -
                                                                            use time_manager_mod
                                                                    -        implicit none
                                                                    -        type(time_type) :: dt, init_date, astro_base_date, time, final_date
                                                                    -        type(time_type) :: next_rad_time, mid_date
                                                                    -        type(time_type) :: repeat_alarm_freq, repeat_alarm_length
                                                                    -        integer :: num_steps, i, days, months, years, seconds, minutes, hours
                                                                    -        integer :: months2, length
                                                                    -        real :: astro_days
                                                                    -   
                                                                    -Set calendar type
                                                                    -    call set_calendar_type(THIRTY_DAY_MONTHS)
                                                                    -        call set_calendar_type(JULIAN)
                                                                    -    call set_calendar_type(NOLEAP)
                                                                    -   
                                                                    - Set timestep
                                                                    -        dt = set_time(1100, 0)
                                                                    -   
                                                                    - Set initial date
                                                                    -        init_date = set_date(1992, 1, 1)
                                                                    -   
                                                                    - Set date for astronomy delta calculation
                                                                    -        astro_base_date = set_date(1970, 1, 1, 12, 0, 0)
                                                                    -   
                                                                    - Copy initial time to model current time
                                                                    -        time = init_date
                                                                    -   
                                                                    - Determine how many steps to do to run one year
                                                                    -        final_date = increment_date(init_date, years = 1)
                                                                    -        num_steps = (final_date - init_date) / dt
                                                                    -        write(*, *) 'Number of steps is' , num_steps
                                                                    -   
                                                                    - Want to compute radiation at initial step, then every two hours
                                                                    -        next_rad_time = time + set_time(7200, 0)
                                                                    -   
                                                                    - Test repeat alarm
                                                                    -        repeat_alarm_freq = set_time(0, 1)
                                                                    -        repeat_alarm_length = set_time(7200, 0)
                                                                    -   
                                                                    - Loop through a year
                                                                    -        do i = 1, num_steps
                                                                    -   
                                                                    - Increment time
                                                                    -        time = time + dt
                                                                    -   
                                                                    - Test repeat alarm
                                                                    -        if(repeat_alarm(time, repeat_alarm_freq, repeat_alarm_length)) &
                                                                    -        write(*, *) 'REPEAT ALARM IS TRUE'
                                                                    -   
                                                                    - Should radiation be computed? Three possible tests.
                                                                    - First test assumes exact interval; just ask if times are equal
                                                                    -     if(time == next_rad_time) then
                                                                    - Second test computes rad on last time step that is <= radiation time
                                                                    -     if((next_rad_time - time) < dt .and. time < next_rad) then
                                                                    - Third test computes rad on time step closest to radiation time
                                                                    -         if(interval_alarm(time, dt, next_rad_time, set_time(7200, 0))) then
                                                                    -           call get_date(time, years, months, days, hours, minutes, seconds)
                                                                    -           write(*, *) days, month_name(months), years, hours, minutes, seconds
                                                                    -   
                                                                    - Need to compute real number of days between current time and astro_base
                                                                    -           call get_time(time - astro_base_date, seconds, days)
                                                                    -           astro_days = days + seconds / 86400.
                                                                    -       write(*, *) 'astro offset ', astro_days
                                                                    -        end if
                                                                    -   
                                                                    - Can compute daily, monthly, yearly, hourly, etc. diagnostics as for rad
                                                                    -   
                                                                    - Example: do diagnostics on last time step of this month
                                                                    -        call get_date(time + dt, years, months2, days, hours, minutes, seconds)
                                                                    -        call get_date(time, years, months, days, hours, minutes, seconds)
                                                                    -        if(months /= months2) then
                                                                    -           write(*, *) 'last timestep of month'
                                                                    -           write(*, *) days, months, years, hours, minutes, seconds
                                                                    -        endif
                                                                    -   
                                                                    - Example: mid-month diagnostics; inefficient to make things clear
                                                                    -        length = days_in_month(time)
                                                                    -        call get_date(time, years, months, days, hours, minutes, seconds)
                                                                    -        mid_date = set_date(years, months, 1) + set_time(0, length) / 2
                                                                    -   
                                                                    -        if(time < mid_date .and. (mid_date - time) < dt) then
                                                                    -           write(*, *) 'mid-month time'
                                                                    -           write(*, *) days, months, years, hours, minutes, seconds
                                                                    -        endif
                                                                    -   
                                                                    -        end do
                                                                    - end program time_main2 -
                                                                    -
                                                                    -
                                                                    -
                                                                    - - -
                                                                    -

                                                                    NOTES

                                                                    - -
                                                                    - The <a name="base date">base date</a> is implicitly defined so users don't - need to be concerned with it. For the curious, the base date is defined as - 0 seconds, 0 minutes, 0 hours, day 1, month 1, year 1 -
                                                                    -
                                                                    - Please note that a time is a positive definite quantity. -
                                                                    -
                                                                    - See the Test Program for a simple program - that shows some of the capabilities of the time manager. -
                                                                    -
                                                                    - -
                                                                    -
                                                                    -top -
                                                                    - - diff --git a/src/shared/topography/gaussian_topog.F90 b/src/shared/topography/gaussian_topog.F90 index 0c9ad97095..4cccd17797 100644 --- a/src/shared/topography/gaussian_topog.F90 +++ b/src/shared/topography/gaussian_topog.F90 @@ -72,8 +72,8 @@ module gaussian_topog_mod !----------------------------------------------------------------------- -character(len=128) :: version = '$Id: gaussian_topog.F90,v 19.0 2012/01/06 22:06:14 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: gaussian_topog.F90,v 20.0 2013/12/14 00:28:17 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: do_nml = .true. logical :: module_is_initialized = .FALSE. @@ -249,6 +249,7 @@ subroutine read_namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, gaussian_topog_nml, iostat=io) + ierr = check_nml_error(io,'gaussian_topog_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/topography/topography.F90 b/src/shared/topography/topography.F90 index 8c84a0ddbf..f7b3cc5618 100644 --- a/src/shared/topography/topography.F90 +++ b/src/shared/topography/topography.F90 @@ -1,3 +1,4 @@ + module topography_mod ! @@ -113,8 +114,8 @@ module topography_mod !----------------------------------------------------------------------- - character(len=128) :: version = '$Id: topography.F90,v 19.0 2012/01/06 22:06:16 fms Exp $' - character(len=128) :: tagname = '$Name: siena_201207 $' + character(len=128) :: version = '$Id: topography.F90,v 20.0 2013/12/14 00:28:20 fms Exp $' + character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .FALSE. @@ -898,6 +899,7 @@ subroutine read_namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, topography_nml, iostat=io) + ierr = check_nml_error(io,'topography_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/tracer_manager/tracer_manager.F90 b/src/shared/tracer_manager/tracer_manager.F90 index d653c65dcf..e24f51ae0b 100644 --- a/src/shared/tracer_manager/tracer_manager.F90 +++ b/src/shared/tracer_manager/tracer_manager.F90 @@ -95,6 +95,8 @@ module tracer_manager_mod set_tracer_profile, & register_tracers, & get_number_tracers, & + adjust_mass, & + adjust_positive_def, & NO_TRACER, & MAX_TRACER_FIELDS @@ -105,7 +107,7 @@ module tracer_manager_mod !----------------------------------------------------------------------- integer :: num_tracer_fields = 0 -integer, parameter :: MAX_TRACER_FIELDS = 120 +integer, parameter :: MAX_TRACER_FIELDS = 150 integer, parameter :: MAX_TRACER_METHOD = 20 integer, parameter :: NO_TRACER = 1-HUGE(1) integer, parameter :: NOTRACER = -HUGE(1) @@ -119,6 +121,10 @@ module tracer_manager_mod integer :: num_methods, model, instances logical :: is_prognostic, instances_set logical :: needs_init +! Does tracer need mass or positive definite adjustment? +! (true by default for both) + logical :: needs_mass_adjust + logical :: needs_positive_adjust end type tracer_type type, private :: tracer_name_type @@ -135,8 +141,8 @@ module tracer_manager_mod type(tracer_type), save :: tracers(MAX_TRACER_FIELDS) type(inst_type) , save :: instantiations(MAX_TRACER_FIELDS) -character(len=128) :: version = '$Id: tracer_manager.F90,v 16.0 2008/07/30 22:48:11 fms Exp $' -character(len=128) :: tagname = '$Name: siena_201207 $' +character(len=128) :: version = '$Id: tracer_manager.F90,v 20.0 2013/12/14 00:28:23 fms Exp $' +character(len=128) :: tagname = '$Name: tikal $' logical :: module_is_initialized = .false. logical :: verbose_local @@ -243,16 +249,28 @@ subroutine get_tracer_meta_data(model, num_tracers,num_prog,num_diag) if (mod == model .and. type == 'tracer') then num_tracer_fields = num_tracer_fields + 1 total_tracers(model) = total_tracers(model) + 1 - TRACER_ARRAY(model,total_tracers(model)) = num_tracer_fields ! ! The maximum number of tracer fields has been exceeded. ! if(num_tracer_fields > MAX_TRACER_FIELDS) call mpp_error(FATAL,'tracer_manager_init: MAX_TRACER_FIELDS exceeded') + TRACER_ARRAY(model,total_tracers(model)) = num_tracer_fields tracers(num_tracer_fields)%model = model tracers(num_tracer_fields)%tracer_name = name tracers(num_tracer_fields)%tracer_units = 'none' tracers(num_tracer_fields)%tracer_longname = tracers(num_tracer_fields)%tracer_name tracers(num_tracer_fields)%instances_set = .FALSE. +! By default, tracers need mass and positive definite adjustments. +! We hardwire exceptions for compatibility with existing field_tables +! This should ideally be cleaned up. + tracers(num_tracer_fields)%needs_mass_adjust = .true. + tracers(num_tracer_fields)%needs_positive_adjust = .true. + if (name == 'cld_amt') then + tracers(num_tracer_fields)%needs_mass_adjust = .false. + endif + if (name == 'cld_amt' .or. name == 'liq_wat' .or. name == 'ice_wat') then + tracers(num_tracer_fields)%needs_positive_adjust = .false. + endif + num_tracer_methods = 0 methods = default_method ! initialize methods array call get_field_methods(n,methods) @@ -267,6 +285,14 @@ subroutine get_tracer_meta_data(model, num_tracers,num_prog,num_diag) siz_inst = parse(methods(j)%method_name,"",instances) tracers(num_tracer_fields)%instances = instances tracers(num_tracer_fields)%instances_set = .TRUE. + case ('adjust_mass') + if (methods(j)%method_name == "false") then + tracers(num_tracer_fields)%needs_mass_adjust = .false. + endif + case ('adjust_positive_def') + if (methods(j)%method_name == "false") then + tracers(num_tracer_fields)%needs_positive_adjust = .false. + endif case default num_tracer_methods = num_tracer_methods+1 ! tracers(num_tracer_fields)%methods(num_tracer_methods) = methods(j) @@ -1043,6 +1069,57 @@ function check_if_prognostic(model, n, err_msg) end function check_if_prognostic ! + +! Does tracer need mass or positive definite adjustments? +!####################################################################### +! Function to check whether tracer should have its mass adjusted +function adjust_mass(model, n, err_msg) + +integer, intent(in) :: model, n +logical :: adjust_mass +character(len=*), intent(out), optional :: err_msg +character(len=128) :: err_msg_local +character(len=11) :: chn + +if(.not.module_is_initialized) call tracer_manager_init + +if (n < 1 .or. n > total_tracers(model)) then + write(chn, '(i11)') n + err_msg_local = ' Invalid tracer index. Model name = '//trim(MODEL_NAMES(model))//', Index='//trim(chn) + adjust_mass = .true. + if(error_handler('adjust_mass', err_msg_local, err_msg)) return +endif + +!Convert local model index to tracer_manager index + +adjust_mass = tracers(TRACER_ARRAY(model,n))%needs_mass_adjust + +end function adjust_mass + +! Function to check whether tracer should be adjusted to remain positive definite +function adjust_positive_def(model, n, err_msg) + +integer, intent(in) :: model, n +logical :: adjust_positive_def +character(len=*), intent(out), optional :: err_msg +character(len=128) :: err_msg_local +character(len=11) :: chn + +if(.not.module_is_initialized) call tracer_manager_init + +if (n < 1 .or. n > total_tracers(model)) then + write(chn, '(i11)') n + err_msg_local = ' Invalid tracer index. Model name = '//trim(MODEL_NAMES(model))//', Index='//trim(chn) + adjust_positive_def = .true. + if(error_handler('adjust_positive_def', err_msg_local, err_msg)) return +endif + +!Convert local model index to tracer_manager index + +adjust_positive_def = tracers(TRACER_ARRAY(model,n))%needs_positive_adjust + +end function adjust_positive_def + ! !####################################################################### ! diff --git a/src/tools/check_mask/check_mask.c b/src/tools/check_mask/check_mask.c index d5aac7a5c0..d2c7651cba 100644 --- a/src/tools/check_mask/check_mask.c +++ b/src/tools/check_mask/check_mask.c @@ -15,6 +15,7 @@ char *usage[] = { " [--halo #] [--sea_level #] [--show_valid_only] [--have_obc] ", " [--direction d(1)..,d(nobc)] [--is is(1)...,is(nobc)] ", " [--ie ie(1)...,ie(nobc)], [--js js(1)...,js(nobc)], [--je je(1)...,je(nobc)]", + " [--layout layout(1),layout(2)] ", " ", " check_mask is used to configure the processors which contains all land points to be ", " masked out. This program is supposed to run on single processor. This tool will print ", @@ -48,6 +49,10 @@ char *usage[] = { " ", " --max_pe # Specify the largest processor count to be checked ", " ", + " --layout #,# specify the layout to be checked. When layout is specified, ", + " --min_pe and --max_pe will be ignored. ", + " ", + " ", " --halo # Specify the halo size in the ocean model. When there is no ", " ocean points on a processor (including halo data), the ", " processor will be masked out. Default value is 1. ", @@ -126,7 +131,7 @@ int get_text_entry(char *line, char *value[]); void get_grid_size( const char *grid_file, int grid_version, int *nx, int *ny ); void get_ocean_mask(const char *grid_file, int grid_version, double *mask, double sea_level, int nx, int ny ); void check_mask(int nx, int ny, const double *wet_in, int cyclic_x, int cyclic_y, - int is_tripolar, int halo, int min_pe, int max_pe, int show_valid_only, int nobc, + int is_tripolar, int halo, int min_pe, int max_pe, int layout[], int show_valid_only, int nobc, char *direction[], int *is, int *ie, int *js, int *je ); #define MAX_OBC 4 @@ -147,7 +152,9 @@ int main (int argc, char *argv[]) int ie[] = {-999, -999, -999, -999}; int js[] = {-999, -999, -999, -999}; int je[] = {-999, -999, -999, -999}; + int layout[] = {0,0}; + int num_layout_entry; int grid_version = 0; int cyclic_x=0; int cyclic_y=0; @@ -173,6 +180,7 @@ int main (int argc, char *argv[]) {"ie", required_argument, NULL, 'l'}, {"js", required_argument, NULL, 'm'}, {"je", required_argument, NULL, 'n'}, + {"layout", required_argument, NULL, 'o'}, {NULL, 0, NULL, 0} }; @@ -235,6 +243,11 @@ int main (int argc, char *argv[]) case 'n': strcpy(entry, optarg); nobc5 = get_int_entry(entry, je); + break; + case 'o': + strcpy(entry, optarg); + num_layout_entry = get_int_entry(entry, layout); + if(num_layout_entry != 2) mpp_error("check_mask: layout should be specified by --layout #,#"); break; case '?': errflg++; @@ -268,6 +281,14 @@ int main (int argc, char *argv[]) /* print out the input arguments */ { int n; + + if(layout[0]*layout[1] > 0) { + min_pe = layout[0]*layout[1]; + max_pe = min_pe; + printf("\n ===>NOTE from check_mask: when layout is specified, min_pe and max_pe is set to layout(1)*layout(2)=%d\n", + layout[0]*layout[1]); + } + printf("\n ===>NOTE from check_mask: Below is the list of command line arguments.\n\n"); printf("grid_file = %s\n", grid_file); if( topog_file ) @@ -276,6 +297,7 @@ int main (int argc, char *argv[]) printf("topog_file is not specified"); printf("min_pe = %d\n", min_pe); printf("max_pe = %d\n", max_pe); + printf("layout = %d, %d\n", layout[0], layout[1]); printf("halo = %d\n", halo); printf("sea_level = %g\n", sea_level); if( show_valid_only ) @@ -286,7 +308,7 @@ int main (int argc, char *argv[]) printf("nobc = %d\n", nobc); for(n=0; nNOTE from check_mask: End of command line arguments.\n"); } @@ -322,7 +344,7 @@ int main (int argc, char *argv[]) get_ocean_mask( topog_file, grid_version, mask, sea_level, nx, ny ); /* check mask */ - check_mask(nx, ny, mask, cyclic_x, cyclic_y, is_tripolar, halo, min_pe, max_pe, show_valid_only, nobc, direction, is, ie, js, je ); + check_mask(nx, ny, mask, cyclic_x, cyclic_y, is_tripolar, halo, min_pe, max_pe, layout, show_valid_only, nobc, direction, is, ie, js, je ); free(mask); printf("\n***** Congratulation! You have successfully run check_mask\n"); @@ -348,7 +370,7 @@ int get_text_entry(char *line, char *value[]) void check_mask(int nx, int ny, const double *wet_in, int cyclic_x, int cyclic_y, - int is_tripolar, int halo, int min_pe, int max_pe, int show_valid_only, int nobc, + int is_tripolar, int halo, int min_pe, int max_pe, int layout_in[], int show_valid_only, int nobc, char *direction[], int *is, int *ie, int *js, int *je ) { int nxd, nyd; @@ -435,8 +457,15 @@ void check_mask(int nx, int ny, const double *wet_in, int cyclic_x, int cyclic_y jbegin = (int *)malloc(max_pe*sizeof(int)); jend = (int *)malloc(max_pe*sizeof(int)); if(nobc>0) obc_error=(int *)malloc(max_pe*sizeof(int)); + for(np=min_pe; np<=max_pe; np++) { - mpp_define_layout(nx, ny, np, layout); + if( layout_in[0]*layout_in[1] == np) { + layout[0] = layout_in[0]; + layout[1] = layout_in[1]; + } + else { + mpp_define_layout(nx, ny, np, layout); + } if( layout[0] > nx || layout[1] > ny ) continue; mpp_compute_extent(nx,layout[0],ibegin,iend); mpp_compute_extent(ny,layout[1],jbegin,jend); @@ -535,6 +564,7 @@ void check_mask(int nx, int ny, const double *wet_in, int cyclic_x, int cyclic_y if(nerror>0) continue; } printf("\n_______________________________________________________________________\n"); + printf("\nNOTE from check_mask: The following is for using model source code with version older than siena_201207,\n"); printf("Possible setting to mask out all-land points region, for use in coupler_nml"); printf("Total number of domains = %d\n", np); printf("Number of tasks (excluded all-land region) to be used is %d\n", np - nmask); @@ -582,6 +612,11 @@ void check_mask(int nx, int ny, const double *wet_in, int cyclic_x, int cyclic_y for(n=0; n y_min && yy < y_max) { - if(j > jend ) jend = j; - if(j < jstart) jstart = j; + if(opcode & GREAT_CIRCLE) { + nxgrid = create_xgrid_great_circle(&nx_in, &ny_in, &nx_out, &ny_out, grid_in[m].lonc, + grid_in[m].latc, grid_out[n].lonc, grid_out[n].latc, + mask, i_in, j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat); } - } - jstart = max(0, jstart-1); - jend = min(ny_in-1, jend+1); - ny_now = jend-jstart+1; + else { + y_min = minval_double((nx_out+1)*(ny_out+1), grid_out[n].latc); + y_max = maxval_double((nx_out+1)*(ny_out+1), grid_out[n].latc); + jstart = ny_in; jend = -1; + for(j=0; j<=ny_in; j++) for(i=0; i<=nx_in; i++) { + yy = grid_in[m].latc[j*(nx_in+1)+i]; + if( yy > y_min ) { + if(j < jstart ) jstart = j; + } + if( yy < y_max ) { + if(j > jend ) jend = j; + } + + } + jstart = max(0, jstart-1); + jend = min(ny_in-1, jend+1); + ny_now = jend-jstart+1; - if(opcode & CONSERVE_ORDER1) { - nxgrid = create_xgrid_2dx2d_order1(&nx_in, &ny_now, &nx_out, &ny_out, grid_in[m].lonc+jstart*(nx_in+1), - grid_in[m].latc+jstart*(nx_in+1), grid_out[n].lonc, grid_out[n].latc, - mask, i_in, j_in, i_out, j_out, xgrid_area); - for(i=0; i 0) { - g_i_in = (int *)malloc(g_nxgrid*sizeof(int )); - g_j_in = (int *)malloc(g_nxgrid*sizeof(int )); - g_area = (double *)malloc(g_nxgrid*sizeof(double)); - g_clon = (double *)malloc(g_nxgrid*sizeof(double)); - g_clat = (double *)malloc(g_nxgrid*sizeof(double)); - mpp_gather_field_int (nxgrid, i_in, g_i_in); - mpp_gather_field_int (nxgrid, j_in, g_j_in); - mpp_gather_field_double(nxgrid, xgrid_area, g_area); - mpp_gather_field_double(nxgrid, xgrid_clon, g_clon); - mpp_gather_field_double(nxgrid, xgrid_clat, g_clat); - for(i=0; i 0) { + g_i_in = (int *)malloc(g_nxgrid*sizeof(int )); + g_j_in = (int *)malloc(g_nxgrid*sizeof(int )); + g_area = (double *)malloc(g_nxgrid*sizeof(double)); + g_clon = (double *)malloc(g_nxgrid*sizeof(double)); + g_clat = (double *)malloc(g_nxgrid*sizeof(double)); + mpp_gather_field_int (nxgrid, i_in, g_i_in); + mpp_gather_field_int (nxgrid, j_in, g_j_in); + mpp_gather_field_double(nxgrid, xgrid_area, g_area); + mpp_gather_field_double(nxgrid, xgrid_clon, g_clon); + mpp_gather_field_double(nxgrid, xgrid_clat, g_clat); + for(i=0; i 0) { @@ -413,6 +421,58 @@ void setup_conserve_interp(int ntiles_in, const Grid_config *grid_in, int ntiles } if(mpp_pe() == mpp_root_pe())printf("NOTE: done calculating index and weight for conservative interpolation\n"); } + + /* check the input area match exchange grid area */ + if(opcode & CHECK_CONSERVE) { + int nx1, ny1, max_i, max_j, i, j; + double max_ratio, ratio_change; + double *area1, *area2; + + /* sum over exchange grid to get the area of grid_in */ + nx1 = grid_out[0].nxc; + ny1 = grid_out[0].nyc; + + area1 = (double *)malloc(nx1*ny1*sizeof(double)); + area2 = (double *)malloc(nx1*ny1*sizeof(double)); + + for(n=0; n max_ratio) { + max_ratio = ratio_change; + max_i = i; + max_j = j; + } + if( ratio_change > 1.e-4 ) { + printf("(i,j)=(%d,%d), change = %g, area1=%g, area2=%g\n", i, j, ratio_change, area1[ii],area2[ii]); + } + } + ii = max_j*nx1+max_i; + printf("The maximum ratio change at (%d,%d) = %g, area1=%g, area2=%g\n", max_i, max_j, max_ratio, area1[ii],area2[ii]); + + } + + free(area1); + free(area2); + + } + /* get target grid area if needed */ if( opcode & TARGET ) { for(n=0; n& /dev/null -gmake -j 6 -cp fregrid ../../../bin -rm *.o -gmake -j 6 -f Makefile_mpi -cp fregrid_parallel ../../../bin diff --git a/src/tools/fregrid/do_make.static b/src/tools/fregrid/do_make.static deleted file mode 100755 index 686dc4ffa6..0000000000 --- a/src/tools/fregrid/do_make.static +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/tcsh -f -source /opt/modules/default/init/tcsh -module purge -module load ifort.9.1.041 -module load icc.9.1.045 -module load mpt-1.18 -module load idb.9.1.045 -module load scsl-1.5.1.0 -module load netcdf-4.0 -module list -setenv NC_BLKSZ 64K - -rm *.o fregrid fregrid_parallel >& /dev/null -gmake -j 6 -f Makefile.static -cp fregrid ../../../bin.static -rm *.o -gmake -j 6 -f Makefile_mpi.static -cp fregrid_parallel ../../../bin.static diff --git a/src/tools/fregrid/env.gaea b/src/tools/fregrid/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/fregrid/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/fregrid/env.gfdl-ws b/src/tools/fregrid/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/fregrid/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/fregrid/env.pan b/src/tools/fregrid/env.pan new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/fregrid/env.pan @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/fregrid/env.zeus b/src/tools/fregrid/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/fregrid/fre-nctools.mk b/src/tools/fregrid/fre-nctools.mk index 2fa3f37e02..94b0f76c7c 100644 --- a/src/tools/fregrid/fre-nctools.mk +++ b/src/tools/fregrid/fre-nctools.mk @@ -1,5 +1,5 @@ # -# $Id: fre-nctools.mk,v 18.0 2010/07/28 17:44:11 fms Exp $ +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:32:02 fms Exp $ # ------------------------------------------------------------------------------ # FMS/FRE Project: Makefile to Build Regridding Executables # ------------------------------------------------------------------------------ @@ -10,39 +10,74 @@ # Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2010 # Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev # +# MPICC and CC are defined in env.$(SITE) +include ./env.$(SITE) -CC := icc -CFLAGS := -O3 -CFLAGS_O2:= -O2 -INCLUDES := -I${NETCDF_HOME}/include -LIBS := -L${NETCDF_HOME}/lib/shared -L${HDF5_HOME}/lib/shared -lnetcdf -lhdf5_hl -lhdf5 -lmpi -lz +#MPICC := mpicc +#CC := icc +CFLAGS := -O3 -g -traceback +CFLAGS_O2:= -O2 -g -traceback +INCLUDES := -I${NETCDF_HOME}/include -I./ -I../shared -I../../shared/mosaic +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) TARGETS := fregrid fregrid_parallel SOURCES := fregrid.c bilinear_interp.c conserve_interp.c fregrid_util.c -SOURCES += create_xgrid.c gradient_c2l.c interp.c mosaic_util.c +SOURCES += create_xgrid.c gradient_c2l.c interp.c read_mosaic.c SOURCES += mpp_domain.c mpp_io.c tool_util.c OBJECTS := $(SOURCES:c=o) +HEADERS = fre-nctools.mk ../shared/mpp.h ../shared/mpp_domain.h ../shared/mpp_io.h ../shared/tool_util.h \ + ../../shared/mosaic/constant.h ../../shared/mosaic/create_xgrid.h \ + ../../shared/mosaic/gradient_c2l.h ../../shared/mosaic/interp.h \ + ../../shared/mosaic/mosaic_util.h ../../shared/mosaic/read_mosaic.h + all: $(TARGETS) -fregrid: $(OBJECTS) read_mosaic.o mpp.o - $(CC) -o $@ $^ $(LIBS) +fregrid: $(OBJECTS) mosaic_util.o mpp.o + $(CC) -o $@ $^ $(CLIBS) + +fregrid_parallel: $(OBJECTS) mosaic_util_parallel.o mpp_parallel.o + $(MPICC) -o $@ $^ $(CLIBS) + +mosaic_util.o: ../../shared/mosaic/mosaic_util.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< -fregrid_parallel: $(OBJECTS) read_mosaic_parallel.o mpp_parallel.o - $(CC) -o $@ $^ $(LIBS) +mosaic_util_parallel.o: ../../shared/mosaic/mosaic_util.c $(HEADERS) + $(MPICC) -Duse_libMPI $(CFLAGS) $(INCLUDES) -o $@ -c $< -read_mosaic.o: read_mosaic.c +read_mosaic.o: ../../shared/mosaic/read_mosaic.c $(HEADERS) $(CC) -Duse_netCDF $(CFLAGS) $(INCLUDES) -c $< -read_mosaic_parallel.o: read_mosaic.c - $(CC) -Duse_netCDF -Duse_libMPI $(CFLAGS) $(INCLUDES) -o $@ -c $< +gradient_c2l.o: ../../shared/mosaic/gradient_c2l.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +interp.o: ../../shared/mosaic/interp.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +mpp_io.o: ../shared/mpp_io.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +mpp_domain.o: ../shared/mpp_domain.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< -mpp_parallel.o: mpp.c - $(CC) -Duse_libMPI $(CFLAGS) $(INCLUDES) -o $@ -c $< +mpp.o: ../shared/mpp.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +mpp_parallel.o: ../shared/mpp.c $(HEADERS) + $(MPICC) -Duse_libMPI $(CFLAGS) $(INCLUDES) -o $@ -c $< + +tool_util.o: ../shared/tool_util.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +conserve_interp.o: conserve_interp.c $(HEADERS) + $(CC) $(CFLAGS_O2) $(INCLUDES) -c $< + +bilinear_interp.o: bilinear_interp.c $(HEADERS) + $(CC) $(CFLAGS_O2) $(INCLUDES) -c $< -create_xgrid.o: create_xgrid.c +create_xgrid.o: ../../shared/mosaic/create_xgrid.c $(HEADERS) $(CC) $(CFLAGS_O2) $(INCLUDES) -c $< %.o: %.c diff --git a/src/tools/fregrid/fregrid.c b/src/tools/fregrid/fregrid.c index 87b6fda526..564815791a 100644 --- a/src/tools/fregrid/fregrid.c +++ b/src/tools/fregrid/fregrid.c @@ -227,7 +227,7 @@ char *usage[] = { NULL}; #define EPSLN10 (1.e-10) const double D2R = M_PI/180.; -char tagname[] = "$Name: siena_201205_z1l $"; +char tagname[] = "$Name: tikal $"; int main(int argc, char* argv[]) { @@ -268,7 +268,8 @@ int main(int argc, char* argv[]) char *dst_vgrid = NULL; double stop_crit=0.005; unsigned int finer_step = 0; - + int great_circle_algorithm_in, great_circle_algorithm_out; + char wt_file_obj[512]; char *weight_file=NULL; char *weight_field = NULL; @@ -482,7 +483,22 @@ int main(int argc, char* argv[]) else { if(nlon !=0 || nlat != 0) mpp_error("fregrid: when output_mosaic is specified, nlon and nlat should not be specified"); } - + + if(!strcmp(interp_method, "conserve_order1") ) { + if(mpp_pe() == mpp_root_pe())printf("****fregrid: first order conservative scheme will be used for regridding.\n"); + opcode |= CONSERVE_ORDER1; + } + else if(!strcmp(interp_method, "conserve_order2") ) { + if(mpp_pe() == mpp_root_pe())printf("****fregrid: second order conservative scheme will be used for regridding.\n"); + opcode |= CONSERVE_ORDER2; + } + else if(!strcmp(interp_method, "bilinear") ) { + if(mpp_pe() == mpp_root_pe())printf("****fregrid: bilinear remapping scheme will be used for regridding.\n"); + opcode |= BILINEAR; + } + else + mpp_error("fregrid: interp_method must be 'conserve_order1', 'conserve_order2' or 'bilinear'"); + if( nfiles == 0) { if(nvector > 0 || nscalar > 0 || nvector2 > 0) mpp_error("fregrid: when --input_file is not specified, --scalar_field, --u_field and --v_field should also not be specified"); @@ -563,21 +579,6 @@ int main(int argc, char* argv[]) else ntiles_out = 1; - if(!strcmp(interp_method, "conserve_order1") ) { - if(mpp_pe() == mpp_root_pe())printf("****fregrid: first order conservative scheme will be used for regridding.\n"); - opcode |= CONSERVE_ORDER1; - } - else if(!strcmp(interp_method, "conserve_order2") ) { - if(mpp_pe() == mpp_root_pe())printf("****fregrid: second order conservative scheme will be used for regridding.\n"); - opcode |= CONSERVE_ORDER2; - } - else if(!strcmp(interp_method, "bilinear") ) { - if(mpp_pe() == mpp_root_pe())printf("****fregrid: bilinear remapping scheme will be used for regridding.\n"); - opcode |= BILINEAR; - } - else - mpp_error("fregrid: interp_method must be 'conserve_order1', 'conserve_order2' or 'bilinear'"); - if(test_case) { if(nfiles != 1) mpp_error("fregrid: when test_case is specified, nfiles should be 1"); sprintf(output_file[0], "%s.%s.output", test_case, interp_method); @@ -602,14 +603,27 @@ int main(int argc, char* argv[]) grid_out = (Grid_config *)malloc(ntiles_out*sizeof(Grid_config)); bound_T = (Bound_config *)malloc(ntiles_in *sizeof(Bound_config)); interp = (Interp_config *)malloc(ntiles_out*sizeof(Interp_config)); - get_input_grid( ntiles_in, grid_in, bound_T, mosaic_in, opcode ); + get_input_grid( ntiles_in, grid_in, bound_T, mosaic_in, opcode, &great_circle_algorithm_in ); set_weight_inf( ntiles_in, grid_in, weight_file, weight_field); if(mosaic_out) - get_output_grid_from_mosaic( ntiles_out, grid_out, mosaic_out, opcode ); - else + get_output_grid_from_mosaic( ntiles_out, grid_out, mosaic_out, opcode, &great_circle_algorithm_out ); + else { + great_circle_algorithm_out = 0; get_output_grid_by_size(ntiles_out, grid_out, lonbegin, lonend, latbegin, latend, nlon, nlat, finer_step, y_at_center, opcode); + } + /* find out if great_circle algorithm is used in the input grid or output grid */ + + if( great_circle_algorithm_in == 0 && great_circle_algorithm_out == 0 ) + opcode |= LEGACY_CLIP; + else { + opcode |= GREAT_CIRCLE; + /* currently only first-order conservative is implemented */ + if( !(opcode & CONSERVE_ORDER1) ) + mpp_error("fregrid: when clip_method is 'conserve_great_circle', interp_methos need to be 'conserve_order1', contact developer"); + } + /* currently extrapolate are limited to ntiles = 1. extrapolate are limited to lat-lon input grid */ if( extrapolate ) { int i, j, ind0, ind1, ind2; diff --git a/src/tools/fregrid/fregrid_util.c b/src/tools/fregrid/fregrid_util.c index f775debd72..7ba7a32b6b 100644 --- a/src/tools/fregrid/fregrid_util.c +++ b/src/tools/fregrid/fregrid_util.c @@ -130,7 +130,7 @@ void set_weight_inf(int ntiles, Grid_config *grid, const char *weight_file, cons void get_mosaic_grid() *******************************************************************************/ -void get_input_grid(int ntiles, Grid_config *grid, Bound_config *bound_T, const char *mosaic_file, unsigned int opcode) +void get_input_grid(int ntiles, Grid_config *grid, Bound_config *bound_T, const char *mosaic_file, unsigned int opcode, int *great_circle_algorithm) { int n, m1, m2, i, j, l, ind1, ind2, nlon, nlat; int ts, tw, tn, te, halo, nbound; @@ -152,6 +152,7 @@ void get_input_grid(int ntiles, Grid_config *grid, Bound_config *bound_T, const nx = (int *)malloc(ntiles * sizeof(int) ); ny = (int *)malloc(ntiles * sizeof(int) ); + *great_circle_algorithm = 0; m_fid = mpp_open(mosaic_file, MPP_READ); get_file_path(mosaic_file, dir); for(n=0; nnz; nk2 = vgrid_out->nz; - for(kstart=0; kstartz[k] >= vgrid_in->z[0]) break; + + + for(kstart=0; kstartz[kstart] >= vgrid_in->z[0]) break; } - for(kend=nk2-1; k>=0; k--) { - if(vgrid_out->z[k] <= vgrid_in->z[nk1-1]) break; + for(kend=nk2-1; kend>=0; kend--) { + if(vgrid_out->z[kend] <= vgrid_in->z[nk1-1]) break; } - if(kstart >0) { + + if(kstart >0 && mpp_pe()==mpp_root_pe()) { printf("NOTE from fregrid_util: the value from level 0 to level %d will be set to the value at the shallowest source levle.\n", kstart-1); } - if(kend kstart = kstart; @@ -1546,7 +1556,9 @@ void get_input_data(int ntiles, Field_config *field, Grid_config *grid, Bound_co int *data_i4; Data_holder *dHold; int interp_method; - + double missing_value; + + missing_value = field->var[varid].missing; interp_method = field->var[varid].interp_method; if(interp_method == CONSERVE_ORDER1) halo = 0; @@ -1613,10 +1625,12 @@ void get_input_data(int ntiles, Field_config *field, Grid_config *grid, Bound_co } if(field[n].var[varid].scale != 0) { - for(i=0; ivar[varid].missing; pos = 0; if(field->var[varid].has_taxis) start[pos++] = level_t; if(field->var[varid].has_naxis) start[pos++] = level_n; @@ -1849,10 +1865,12 @@ void write_field_data(int ntiles, Field_config *field, Grid_config *grid, int va data_size = nx*ny*nz; if(field[n].var[varid].offset != 0) { - for(i=0; i 0 ) { - if( (prev_z < 0 && z > 0) || (prev_z >0 && z < 0 ) ) {/* change sign */ - if(changed_sign) - return i-1; /* previous point is concave points */ - else if(i==n-1) - return i; /* last point is concave points */ - else - changed_sign=1; - } - } - prev_z = z; - } - if(changed_sign) - return 0; /* first point is concaved points */ - else - return -1; /* convex */ -} - void get_global_area(int nx, int ny, const double *x, const double *y, double *area) { double *x_local, *y_local, *area_local; @@ -304,7 +281,7 @@ int get_nest_contact(const int *nx, const int *ny, int ncontacts, const int *til if(nnest>1)mpp_error("make_coupler_mosaic(get_nest_contact): only support one nest region, contact developer"); if(nx2_contact*ny2_contact > nx1_contact*ny1_contact) { if(nx2_contact%nx1_contact || ny2_contact%ny1_contact ) - mpp_error("make_coupler_mosaic(get_nest_contact):it is not a integer refinement"); + if(mpp_pe()==mpp_root_pe()) mpp_error("make_coupler_mosaic(get_nest_contact):it is not a integer refinement"); is_nest [0] = istart2[n]; ie_nest [0] = iend2 [n]; js_nest [0] = jstart2[n]; @@ -336,8 +313,6 @@ int get_nest_contact(const int *nx, const int *ny, int ncontacts, const int *til } - - int main (int argc, char *argv[]) { int c, i, same_mosaic; @@ -352,6 +327,7 @@ int main (int argc, char *argv[]) char **otile_name=NULL, **atile_name=NULL, **ltile_name=NULL, **wtile_name=NULL; int x_refine = 2, y_refine = 2; int interp_order = 2; + double area_ratio_thresh = 1.0e-6; unsigned int check = 0; unsigned int verbose = 0; int errflg = (argc == 1); @@ -372,9 +348,19 @@ int main (int argc, char *argv[]) int *nxw = NULL, *nyw = NULL; double **xocn = NULL, **yocn = NULL, **xatm = NULL, **yatm = NULL, **xlnd = NULL, **ylnd = NULL; double **xwav = NULL, **ywav = NULL; + double **cart_xatm=NULL, **cart_yatm=NULL, **cart_zatm=NULL; + double **cart_xocn=NULL, **cart_yocn=NULL, **cart_zocn=NULL; + double **cart_xlnd=NULL, **cart_ylnd=NULL, **cart_zlnd=NULL; + double **cart_xwav=NULL, **cart_ywav=NULL, **cart_zwav=NULL; double **area_ocn = NULL, **area_lnd = NULL, **area_atm = NULL, **area_wav = NULL; + double **atm_xarea=NULL; double **omask = NULL; double sea_level = 0.; + int clip_method = LEGACY_CLIP; + int atm_great_circle_algorithm=0; + int lnd_great_circle_algorithm=0; + int ocn_great_circle_algorithm=0; + int lnd_same_as_atm = 0; int ocn_same_as_atm = 0; int wav_same_as_ocn = 0; @@ -385,18 +371,21 @@ int main (int argc, char *argv[]) int ocn_south_ext = 0; int tile_nest, is_nest, ie_nest, js_nest, je_nest; int tile_parent, is_parent, ie_parent, js_parent, je_parent; + int print_memory=0; static struct option long_options[] = { - {"atmos_mosaic", required_argument, NULL, 'a'}, - {"land_mosaic", required_argument, NULL, 'l'}, - {"ocean_mosaic", required_argument, NULL, 'o'}, - {"wave_mosaic", required_argument, NULL, 'w'}, - {"ocean_topog", required_argument, NULL, 't'}, - {"sea_level", required_argument, NULL, 's'}, - {"interp_order", required_argument, NULL, 'i'}, - {"mosaic_name", required_argument, NULL, 'm'}, - {"check", no_argument, NULL, 'n'}, - {"verbose", no_argument, NULL, 'v'}, + {"atmos_mosaic", required_argument, NULL, 'a'}, + {"land_mosaic", required_argument, NULL, 'l'}, + {"ocean_mosaic", required_argument, NULL, 'o'}, + {"wave_mosaic", required_argument, NULL, 'w'}, + {"ocean_topog", required_argument, NULL, 't'}, + {"sea_level", required_argument, NULL, 's'}, + {"interp_order", required_argument, NULL, 'i'}, + {"mosaic_name", required_argument, NULL, 'm'}, + {"area_ratio_thresh", required_argument, NULL, 'r'}, + {"check", no_argument, NULL, 'n'}, + {"verbose", no_argument, NULL, 'v'}, + {"print_memory", no_argument, NULL, 'p'}, {NULL, 0, NULL, 0} }; @@ -433,12 +422,17 @@ int main (int argc, char *argv[]) case 'm': strcpy(mosaic_name,optarg); break; + case 'r': + area_ratio_thresh = atof(optarg); case 'n': check = 1; break; case 'v': verbose = 1; break; + case 'p': + print_memory = 1; + break; case '?': errflg++; } @@ -475,6 +469,8 @@ int main (int argc, char *argv[]) if( !strcmp(amosaic_file, "mosaic.nc") || !strcmp(lmosaic_file, "mosaic.nc") || !strcmp(omosaic_file, "mosaic.nc") ) mpp_error("make_coupler_mosaic: the file name of amosaic, lmosaic or omosaic can not be mosaic.nc"); + if(print_memory) print_mem_usage("before read atmosphere grid"); + /* * Read atmosphere grid */ @@ -500,6 +496,7 @@ int main (int argc, char *argv[]) xatm = (double **) malloc( ntile_atm*sizeof(double *)); yatm = (double **) malloc( ntile_atm*sizeof(double *)); area_atm = (double **) malloc( ntile_atm*sizeof(double *)); + if(check) atm_xarea = (double **) malloc( ntile_atm*sizeof(double *)); atile_name = (char **)malloc(ntile_atm*sizeof(char *)); /* grid should be located in the same directory of mosaic file */ get_file_path(amosaic, dir); @@ -516,6 +513,17 @@ int main (int argc, char *argv[]) g_fid = mpp_open(file, MPP_READ); nxa[n] = mpp_get_dimlen(g_fid, "nx"); nya[n] = mpp_get_dimlen(g_fid, "ny"); + /* check if use great_circle_algorithm */ + { + int great_circle_algorithm=0; + great_circle_algorithm = get_great_circle_algorithm(g_fid); + if(n>0) { + if( atm_great_circle_algorithm != great_circle_algorithm) + mpp_error("make_topog: atribute 'great_circle_algorithm' of field 'tile' have different value for different tile"); + } + atm_great_circle_algorithm = great_circle_algorithm; + } + mpp_close(g_fid); if(nxa[n]%x_refine != 0 ) mpp_error("make_coupler_mosaic: atmos supergrid x-size can not be divided by x_refine"); if(nya[n]%y_refine != 0 ) mpp_error("make_coupler_mosaic: atmos supergrid y-size can not be divided by y_refine"); @@ -523,52 +531,53 @@ int main (int argc, char *argv[]) nya[n] /= y_refine; xatm[n] = (double *)malloc((nxa[n]+1)*(nya[n]+1)*sizeof(double)); yatm[n] = (double *)malloc((nxa[n]+1)*(nya[n]+1)*sizeof(double)); - get_global_grid(file, nxa[n], nya[n], x_refine, y_refine, xatm[n], yatm[n]); - - } - - /* The following is a temprary fix to solve the issue that there is no pole in stretched grid - adjust the points close to pole to pole.*/ -/* { */ -/* double min_y, max_y; */ -/* int i, j; */ -/* min_y = 90; */ -/* max_y = -90; */ -/* for(n=0; n max_y) max_y = yatm[n][i]; */ -/* } */ -/* } */ - -/* for(n=0; n= max_y) { */ -/* printf("set atmosphere latitude at n=%d, i= %d, j=%d from %f to 90\n", n, i, j, yatm[n][j*(nxa[n]+1)+i]); */ -/* yatm[n][j*(nxa[n]+1)+i] = 90; */ -/* } */ -/* } */ -/* } */ -/* } */ - for(n=0; n0) { + if( lnd_great_circle_algorithm != great_circle_algorithm) + mpp_error("make_topog: atribute 'great_circle_algorithm' of field 'tile' have different value for different tile"); + } + lnd_great_circle_algorithm = great_circle_algorithm; + } + mpp_close(g_fid); if(nxl[n]%x_refine != 0 ) mpp_error("make_coupler_mosaic: land supergrid x-size can not be divided by x_refine"); if(nyl[n]%y_refine != 0 ) mpp_error("make_coupler_mosaic: land supergrid y-size can not be divided by y_refine"); @@ -648,46 +668,33 @@ int main (int argc, char *argv[]) nyl[n] /= y_refine; xlnd[n] = (double *)malloc((nxl[n]+1)*(nyl[n]+1)*sizeof(double)); ylnd[n] = (double *)malloc((nxl[n]+1)*(nyl[n]+1)*sizeof(double)); + area_lnd[n] = (double *)malloc((nxl[n] )*(nyl[n] )*sizeof(double)); get_global_grid(file, nxl[n], nyl[n], x_refine, y_refine, xlnd[n], ylnd[n]); + /*scale grid from degree to radian, because create_xgrid assume the grid is in radians */ + for(i=0; i<(nxl[n]+1)*(nyl[n]+1); i++) { + xlnd[n][i] *= D2R; + ylnd[n][i] *= D2R; + } + } - /* The following is a temprary fix to solve the issue that there is no pole in stretched grid - adjust the points close to pole to pole.*/ - { - double min_y, max_y; - int i, j; - min_y = 90; - max_y = -90; - for(n=0; n max_y) max_y = ylnd[n][i]; - } - } - + /* compute lnd_area */ + if(clip_method == GREAT_CIRCLE_CLIP) { + cart_xlnd = (double **) malloc( ntile_lnd*sizeof(double *)); + cart_ylnd = (double **) malloc( ntile_lnd*sizeof(double *)); + cart_zlnd = (double **) malloc( ntile_lnd*sizeof(double *)); for(n=0; n= max_y) { - printf("set land latitude at n=%d, i= %d, j=%d from %f to 90\n", n, i, j, ylnd[n][j*(nxl[n]+1)+i]); - ylnd[n][j*(nxl[n]+1)+i] = 90; - } - } + cart_xlnd[n] = (double *)malloc((nxl[n]+1)*(nyl[n]+1)*sizeof(double)); + cart_ylnd[n] = (double *)malloc((nxl[n]+1)*(nyl[n]+1)*sizeof(double)); + cart_zlnd[n] = (double *)malloc((nxl[n]+1)*(nyl[n]+1)*sizeof(double)); + latlon2xyz((nxl[n]+1)*(nyl[n]+1), xlnd[n], ylnd[n], cart_xlnd[n], cart_ylnd[n], cart_zlnd[n]); + get_grid_great_circle_area(&(nxl[n]), &(nyl[n]), xlnd[n], ylnd[n], area_lnd[n]); } } - - for(n=0; n0) { + if( ocn_great_circle_algorithm != great_circle_algorithm) + mpp_error("make_topog: atribute 'great_circle_algorithm' of field 'tile' have different value for different tile"); + } + ocn_great_circle_algorithm = great_circle_algorithm; + } + mpp_close(g_fid); if(nxo[n]%x_refine != 0 ) mpp_error("make_coupler_mosaic: ocean supergrid x-size can not be divided by x_refine"); @@ -768,16 +796,30 @@ int main (int argc, char *argv[]) */ if(ntile_ocn == 1) { int na; - for(i=1; i<=nxo[n]; i++) - if(tmpy[i] != tmpy[i-1]) mpp_error("make_coupler_mosaic: latitude is not uniform along j=0"); - /* calculate the minimum of latitude of atmosphere grid */ - min_atm_lat = 9999; /* dummy large value */ - for(na=0; na min_lat) min_atm_lat = min_lat; + int is_uniform; + + /* check if the latitude is uniform or not at j=1 */ + is_uniform = 1; + for(i=1; i<=nxo[n]; i++) { + if(tmpy[i] != tmpy[i-1]) { + is_uniform = 0; + if(mpp_pe()==mpp_root_pe()) printf("\nNOTE from make_coupler_mosaic: ocean grid latitude is not uniform along j = 1\n"); + } } - if(tmpy[0]*D2R > min_atm_lat + TINY_VALUE) { /* extend one point in south direction*/ - ocn_south_ext = 1; + + /* if latitude is uniform along j = 1, may add row in southmost */ + if( is_uniform ) { + /* calculate the minimum of latitude of atmosphere grid */ + min_atm_lat = 9999; /* dummy large value */ + for(na=0; na min_lat) min_atm_lat = min_lat; + } + min_atm_lat = -90.*D2R; + if(tmpy[0]*D2R > min_atm_lat + TINY_VALUE) { /* extend one point in south direction*/ + ocn_south_ext = 1; + if(mpp_pe()==mpp_root_pe())printf("make_coupler_mosaic: one row is add to the south end to cover the globe\n"); + } } } nyo_old = nyo[n]; @@ -796,11 +838,27 @@ int main (int argc, char *argv[]) yocn[n][i] = min_atm_lat; } } - - get_global_area(nxo[n], nyo[n], xocn[n], yocn[n], area_ocn[n]); free(tmpx); free(tmpy); } + + if(clip_method == GREAT_CIRCLE_CLIP) { + cart_xocn = (double **) malloc( ntile_lnd*sizeof(double *)); + cart_yocn = (double **) malloc( ntile_lnd*sizeof(double *)); + cart_zocn = (double **) malloc( ntile_ocn*sizeof(double *)); + for(n=0; n ya_max) ya_max = ya[0]; - if(ya[1] > ya_max) ya_max = ya[1]; - if(ya[2] > ya_max) ya_max = ya[2]; - if(ya[3] > ya_max) ya_max = ya[3]; - if(ya[0] < ya_min) ya_min = ya[0]; - if(ya[1] < ya_min) ya_min = ya[1]; - if(ya[2] < ya_min) ya_min = ya[2]; - if(ya[3] < ya_min) ya_min = ya[3]; - } + ya[0] = yatm[na][n0]; + ya[1] = yatm[na][n1]; + ya[2] = yatm[na][n2]; + ya[3] = yatm[na][n3]; + if(ya[0] > ya_max) ya_max = ya[0]; + if(ya[1] > ya_max) ya_max = ya[1]; + if(ya[2] > ya_max) ya_max = ya[2]; + if(ya[3] > ya_max) ya_max = ya[3]; + if(ya[0] < ya_min) ya_min = ya[0]; + if(ya[1] < ya_min) ya_min = ya[1]; + if(ya[2] < ya_min) ya_min = ya[2]; + if(ya[3] < ya_min) ya_min = ya[3]; + } - for(nl=0; nl ya_min && yy < ya_max ) { - if(jl > je_lnd[nl] ) je_lnd[nl] = jl; - if(jl < js_lnd[nl] ) js_lnd[nl] = jl; - } - } - js_lnd[nl] = max(0, js_lnd[nl]-1); - je_lnd[nl] = min(nyl[nl]-1, je_lnd[nl]+1); - if(nl==na || !lnd_same_as_atm ) { - is_lnd[nl] = 0; - ie_lnd[nl] = nxl[nl]-1; - } - else { - is_lnd[nl] = nxl[nl]-1; - ie_lnd[nl] = 0; - } + for(nl=0; nl ya_min ) { + if(jl < js_lnd[nl] ) js_lnd[nl] = jl; + } + if( yy < ya_max ) { + if(jl > je_lnd[nl] ) je_lnd[nl] = jl; + } + } + js_lnd[nl] = max(0, js_lnd[nl]-1); + je_lnd[nl] = min(nyl[nl]-1, je_lnd[nl]+1); + if(nl==na || !lnd_same_as_atm ) { + is_lnd[nl] = 0; + ie_lnd[nl] = nxl[nl]-1; + } + else { + is_lnd[nl] = nxl[nl]-1; + ie_lnd[nl] = 0; + } - } - - for(no=0; no ya_min && yy < ya_max ) { - if(jo > je_ocn[no] ) je_ocn[no] = jo; - if(jo < js_ocn[no] ) js_ocn[no] = jo; - } - } - js_ocn[no] = max(0, js_ocn[no]-1); - je_ocn[no] = min(nyo[no]-1, je_ocn[no]+1); - - if(no==na || !ocn_same_as_atm ) { - is_ocn[no] = 0; - ie_ocn[no] = nxo[no]-1; - } - else { - is_ocn[no] = nxo[no]-1; - ie_ocn[no] = 0; - } + } + + for(no=0; no ya_min ) { + if(jo < js_ocn[no] ) js_ocn[no] = jo; + } + if( yy < ya_max ) { + if(jo > je_ocn[no] ) je_ocn[no] = jo; + } + } + js_ocn[no] = max(0, js_ocn[no]-1); + je_ocn[no] = min(nyo[no]-1, je_ocn[no]+1); + + if(no==na || !ocn_same_as_atm ) { + is_ocn[no] = 0; + ie_ocn[no] = nxo[no]-1; + } + else { + is_ocn[no] = nxo[no]-1; + ie_ocn[no] = 0; + } - } + } + } if(mpp_pe()==mpp_root_pe() && verbose)printf("na = %d, la = %d, is=%d, ie = %d\n", na, la, is, ie); for(la=is;la<=ie;la++) { - int ind_concave; - if(mpp_pe()==mpp_root_pe() && verbose)printf("na = %d, la = %d, is=%d, ie = %d\n", na, la, is, ie); ia = la%nxa[na]; ja = la/nxa[na]; - n0 = ja *(nxa[na]+1) + ia; - n1 = ja *(nxa[na]+1) + ia+1; - n2 = (ja+1)*(nxa[na]+1) + ia+1; - n3 = (ja+1)*(nxa[na]+1) + ia; - xa[0] = xatm[na][n0]; ya[0] = yatm[na][n0]; - xa[1] = xatm[na][n1]; ya[1] = yatm[na][n1]; - xa[2] = xatm[na][n2]; ya[2] = yatm[na][n2]; - xa[3] = xatm[na][n3]; ya[3] = yatm[na][n3]; - ya_min = minval_double(4, ya); - ya_max = maxval_double(4, ya); - - na_in = fix_lon(xa, ya, 4, M_PI); - - /* check if the range of longitude is */ - /* currently do not check concave, convex is assumed */ - /* ind_concave = concave(na_in, xa, ya); */ - ind_concave = -1; - if( ind_concave >= 0) { - printf("concave point, ia=%d, ja=%d, ind=%d\n", ia, ja, ind_concave); - } - xa_min = minval_double(na_in, xa); - xa_max = maxval_double(na_in, xa); - xa_avg = avgval_double(na_in, xa); + + if(print_grid) { + n0 = ja *(nxa[na]+1) + ia; + n1 = ja *(nxa[na]+1) + ia+1; + n2 = (ja+1)*(nxa[na]+1) + ia+1; + n3 = (ja+1)*(nxa[na]+1) + ia; + xa[0] = xatm[na][n0]; ya[0] = yatm[na][n0]; + xa[1] = xatm[na][n1]; ya[1] = yatm[na][n1]; + xa[2] = xatm[na][n2]; ya[2] = yatm[na][n2]; + xa[3] = xatm[na][n3]; ya[3] = yatm[na][n3]; + printf("atm grid is \n"); + printf("%15.11f, %15.11f \n", xa[0]*R2D, ya[0]*R2D); + printf("%15.11f, %15.11f \n", xa[1]*R2D, ya[1]*R2D); + printf("%15.11f, %15.11f \n", xa[2]*R2D, ya[2]*R2D); + printf("%15.11f, %15.11f \n", xa[3]*R2D, ya[3]*R2D); + printf("%15.11f, %15.11f \n", xa[0]*R2D, ya[0]*R2D); + } + + if(clip_method == GREAT_CIRCLE_CLIP) { /*clockwise*/ + n0 = ja *(nxa[na]+1) + ia; + n1 = (ja+1)*(nxa[na]+1) + ia; + n2 = (ja+1)*(nxa[na]+1) + ia+1; + n3 = ja *(nxa[na]+1) + ia+1; + xa[0] = cart_xatm[na][n0]; ya[0] = cart_yatm[na][n0]; za[0] = cart_zatm[na][n0]; + xa[1] = cart_xatm[na][n1]; ya[1] = cart_yatm[na][n1]; za[1] = cart_zatm[na][n1]; + xa[2] = cart_xatm[na][n2]; ya[2] = cart_yatm[na][n2]; za[2] = cart_zatm[na][n2]; + xa[3] = cart_xatm[na][n3]; ya[3] = cart_yatm[na][n3]; za[3] = cart_zatm[na][n3]; + } + else { + n0 = ja *(nxa[na]+1) + ia; + n1 = ja *(nxa[na]+1) + ia+1; + n2 = (ja+1)*(nxa[na]+1) + ia+1; + n3 = (ja+1)*(nxa[na]+1) + ia; + xa[0] = xatm[na][n0]; ya[0] = yatm[na][n0]; + xa[1] = xatm[na][n1]; ya[1] = yatm[na][n1]; + xa[2] = xatm[na][n2]; ya[2] = yatm[na][n2]; + xa[3] = xatm[na][n3]; ya[3] = yatm[na][n3]; + ya_min = minval_double(4, ya); + ya_max = maxval_double(4, ya); + + na_in = fix_lon(xa, ya, 4, M_PI); + + xa_min = minval_double(na_in, xa); + xa_max = maxval_double(na_in, xa); + xa_avg = avgval_double(na_in, xa); + } count = 0; - for(nl=0; nl= ya_max || yl_max <= ya_min ) continue; - nl_in = fix_lon(xl, yl, 4, xa_avg); - xl_min = minval_double(nl_in, xl); - xl_max = maxval_double(nl_in, xl); - /* xl should in the same range as xa after lon_fix, so no need to - consider cyclic condition - */ + for(nl=0; nl= ya_max || yl_max <= ya_min ) continue; + nl_in = fix_lon(xl, yl, 4, xa_avg); + xl_min = minval_double(nl_in, xl); + xl_max = maxval_double(nl_in, xl); + /* xl should in the same range as xa after lon_fix, so no need to + consider cyclic condition + */ - if(xa_min >= xl_max || xa_max <= xl_min ) continue; - // if(use_great_circle) - // n_out=clip_great_circle(xa, ya, na_in, xl, yl, nl_in, x_out, y_out ); - // else - n_out = clip_2dx2d( xa, ya, na_in, xl, yl, nl_in, x_out, y_out ); + if(xa_min >= xl_max || xa_max <= xl_min ) continue; + n_out = clip_2dx2d( xa, ya, na_in, xl, yl, nl_in, x_out, y_out ); + } + if ( n_out > 0 ) { - xarea = poly_area(x_out, y_out, n_out); + if(clip_method == GREAT_CIRCLE_CLIP) + xarea=great_circle_area ( n_out, x_out, y_out, z_out); + else + xarea = poly_area(x_out, y_out, n_out); min_area = min(area_lnd[nl][jl*nxl[nl]+il], area_atm[na][la]); - if( xarea/min_area > AREA_RATIO_THRESH ) { - /* remember the exchange grid vertices */ - for(n=0; n area_ratio_thresh ) { + + if(print_grid) { + double xtmp[20],ytmp[20]; + printf("n_axl is %d\n", n_out); + /* convert to lon-lat */ + xyz2latlon(n_out, x_out, y_out, z_out, xtmp, ytmp); + for(n=0; nMX) mpp_error("make_coupler_mosaic: count is greater than MX, increase MX"); } } } } - /* calculate atmos/ocean x-cells */ for(no=0; no= xo_max || xa_max <= xo_min || yo_min >= ya_max || yo_max <= ya_min ) continue; - if(ind_concave >= 0) { - double x1[4], y1[4]; - for(i=0; i<2; i++) { - if(i==0) { - x1[0] = xa[0]; x1[1] = xa[1]; x1[2] = xa[3]; - y1[0] = ya[0]; y1[1] = ya[1]; y1[2] = ya[3]; - } - else { - x1[0] = xa[1]; x1[1] = xa[2]; x1[2] = xa[3]; - y1[0] = ya[1]; y1[1] = ya[2]; y1[2] = ya[3]; - } - if ( (n_out = clip_2dx2d( x1, y1, 3, xo, yo, no_in, x_out, y_out )) > 0) { - xarea = poly_area(x_out, y_out, n_out )*ocn_frac; - min_area = min(area_ocn[no][jo*nxo[no]+io], area_atm[na][la]); - if(xarea/min_area > AREA_RATIO_THRESH) { - - atmxocn_area[na][no][naxo[na][no]] = xarea; - atmxocn_io[na][no][naxo[na][no]] = io; - atmxocn_jo[na][no][naxo[na][no]] = jo; - atmxocn_ia[na][no][naxo[na][no]] = ia; - atmxocn_ja[na][no][naxo[na][no]] = ja; - if(interp_order == 2) { - atmxocn_clon[na][no][naxo[na][no]] = poly_ctrlon ( x_out, y_out, n_out, xa_avg)*ocn_frac; - atmxocn_clat[na][no][naxo[na][no]] = poly_ctrlat ( x_out, y_out, n_out )*ocn_frac; - } - } - } - } - ++(naxo[na][no]); - if(naxo[na][no] > MAXXGRID) mpp_error("naxo is greater than MAXXGRID, increase MAXXGRID"); - } - else if ( (n_out = clip_2dx2d( xa, ya, na_in, xo, yo, no_in, x_out, y_out )) > 0) { - xarea = poly_area(x_out, y_out, n_out )*ocn_frac; + + if( clip_method == GREAT_CIRCLE_CLIP ) { + n_out = clip_2dx2d_great_circle(xa, ya, za, 4, xo, yo, zo, 4, + x_out, y_out, z_out); + } + else { + if(xa_min >= xo_max || xa_max <= xo_min || yo_min >= ya_max || yo_max <= ya_min ) continue; + n_out = clip_2dx2d( xa, ya, na_in, xo, yo, no_in, x_out, y_out ); + } + if ( n_out > 0) { + + + if( clip_method == GREAT_CIRCLE_CLIP ) + xarea=great_circle_area ( n_out, x_out, y_out, z_out)*ocn_frac; + else + xarea = poly_area(x_out, y_out, n_out )*ocn_frac; + min_area = min(area_ocn[no][jo*nxo[no]+io], area_atm[na][la]); - if(xarea/min_area > AREA_RATIO_THRESH) { - + if(xarea/min_area > area_ratio_thresh) { + atmxocn_area[na][no][naxo[na][no]] = xarea; atmxocn_io[na][no][naxo[na][no]] = io; atmxocn_jo[na][no][naxo[na][no]] = jo; @@ -1314,11 +1564,30 @@ int main (int argc, char *argv[]) if(lnd_frac > MIN_AREA_FRAC) { /* over land */ /* find the overlap of atmxlnd and ocean cell */ for(l=0; l= xo_max || axl_xmax[l] <= xo_min || axl_ymin[l] >= ya_max || axl_ymax[l] <= ya_min ) continue; - if((n_out = clip_2dx2d( atmxlnd_x[l], atmxlnd_y[l], num_v[l], xo, yo, no_in, x_out, y_out )) > 0) { - xarea = poly_area(x_out, y_out, n_out )*lnd_frac; + if( clip_method == GREAT_CIRCLE_CLIP ) + n_out = clip_2dx2d_great_circle(atmxlnd_x[l], atmxlnd_y[l], atmxlnd_z[l], num_v[l], xo, yo, zo, 4, + x_out, y_out, z_out); + else { + if(axl_xmin[l] >= xo_max || axl_xmax[l] <= xo_min || axl_ymin[l] >= ya_max || axl_ymax[l] <= ya_min ) continue; + n_out = clip_2dx2d( atmxlnd_x[l], atmxlnd_y[l], num_v[l], xo, yo, no_in, x_out, y_out ); + } + if( n_out > 0) { + if( clip_method == GREAT_CIRCLE_CLIP ) + xarea=great_circle_area ( n_out, x_out, y_out, z_out)*lnd_frac; + else + xarea = poly_area(x_out, y_out, n_out )*lnd_frac; min_area = min(area_lnd[axl_t[l]][axl_j[l]*nxl[axl_t[l]]+axl_i[l]], area_atm[na][la]); - if(xarea/min_area > AREA_RATIO_THRESH) { + if(xarea/min_area > area_ratio_thresh) { + + if(print_grid) { + double xtmp[20],ytmp[20]; + printf("num exchange grid between ocean and axl is %d\n", n_out); + /* convert to lon-lat */ + xyz2latlon(n_out, x_out, y_out, z_out, xtmp, ytmp); + + for(n=0; n AREA_RATIO_THRESH) { + if(axl_area[l]/min_area > area_ratio_thresh) { atmxlnd_area[na][nl][naxl[na][nl]] = axl_area[l]; atmxlnd_ia [na][nl][naxl[na][nl]] = ia; atmxlnd_ja [na][nl][naxl[na][nl]] = ja; @@ -1360,9 +1629,13 @@ int main (int argc, char *argv[]) free(ie_ocn); free(js_ocn); free(je_ocn); + if(print_memory) { + sprintf(mesg, "end of loop na=%d", na); + print_mem_usage(mesg); + } } /* end of na loop */ - + if(print_memory)print_mem_usage("after calcuting exchange grid"); time_end = time(NULL); if(verbose) printf("one pe %d, The loop used %f seconds.\n", mpp_pe(), difftime(time_end, time_start)); /* calculate the centroid of model grid, as well as land_mask and ocean_mask */ @@ -1386,31 +1659,33 @@ int main (int argc, char *argv[]) if(interp_order == 1) { for(na=0; na 0) { - double *g_area; - int *g_il, *g_jl; - int ii; - g_il = (int *)malloc(nxgrid*sizeof(int )); - g_jl = (int *)malloc(nxgrid*sizeof(int )); - g_area = (double *)malloc(nxgrid*sizeof(double)); - mpp_gather_field_int (naxl[na][nl], atmxlnd_il[na][nl], g_il); - mpp_gather_field_int (naxl[na][nl], atmxlnd_jl[na][nl], g_jl); - mpp_gather_field_double(naxl[na][nl], atmxlnd_area[na][nl], g_area); - for(i=0; i 0) { + double *g_area; + int *g_il, *g_jl; + int ii; + g_il = (int *)malloc(nxgrid*sizeof(int )); + g_jl = (int *)malloc(nxgrid*sizeof(int )); + g_area = (double *)malloc(nxgrid*sizeof(double)); + mpp_gather_field_int (naxl[na][nl], atmxlnd_il[na][nl], g_il); + mpp_gather_field_int (naxl[na][nl], atmxlnd_jl[na][nl], g_jl); + mpp_gather_field_double(naxl[na][nl], atmxlnd_area[na][nl], g_area); + for(i=0; i 0) { - double *g_area, *g_clon, *g_clat; - int *g_ia, *g_ja, *g_il, *g_jl; - int ii; - g_ia = (int *)malloc(nxgrid*sizeof(int )); - g_ja = (int *)malloc(nxgrid*sizeof(int )); - g_il = (int *)malloc(nxgrid*sizeof(int )); - g_jl = (int *)malloc(nxgrid*sizeof(int )); - g_area = (double *)malloc(nxgrid*sizeof(double)); - g_clon = (double *)malloc(nxgrid*sizeof(double)); - g_clat = (double *)malloc(nxgrid*sizeof(double)); - mpp_gather_field_int (naxl[na][nl], atmxlnd_ia[na][nl], g_ia); - mpp_gather_field_int (naxl[na][nl], atmxlnd_ja[na][nl], g_ja); - mpp_gather_field_int (naxl[na][nl], atmxlnd_il[na][nl], g_il); - mpp_gather_field_int (naxl[na][nl], atmxlnd_jl[na][nl], g_jl); - mpp_gather_field_double(naxl[na][nl], atmxlnd_area[na][nl], g_area); - mpp_gather_field_double(naxl[na][nl], atmxlnd_clon[na][nl], g_clon); - mpp_gather_field_double(naxl[na][nl], atmxlnd_clat[na][nl], g_clat); - for(i=0; i 0) { + double *g_area, *g_clon, *g_clat; + int *g_ia, *g_ja, *g_il, *g_jl; + int ii; + g_ia = (int *)malloc(nxgrid*sizeof(int )); + g_ja = (int *)malloc(nxgrid*sizeof(int )); + g_il = (int *)malloc(nxgrid*sizeof(int )); + g_jl = (int *)malloc(nxgrid*sizeof(int )); + g_area = (double *)malloc(nxgrid*sizeof(double)); + g_clon = (double *)malloc(nxgrid*sizeof(double)); + g_clat = (double *)malloc(nxgrid*sizeof(double)); + mpp_gather_field_int (naxl[na][nl], atmxlnd_ia[na][nl], g_ia); + mpp_gather_field_int (naxl[na][nl], atmxlnd_ja[na][nl], g_ja); + mpp_gather_field_int (naxl[na][nl], atmxlnd_il[na][nl], g_il); + mpp_gather_field_int (naxl[na][nl], atmxlnd_jl[na][nl], g_jl); + mpp_gather_field_double(naxl[na][nl], atmxlnd_area[na][nl], g_area); + mpp_gather_field_double(naxl[na][nl], atmxlnd_clon[na][nl], g_clon); + mpp_gather_field_double(naxl[na][nl], atmxlnd_clat[na][nl], g_clat); + for(i=0; i TOLORENCE ) { + nbad++; printf("at ocean point (%d,%d), omask = %f, ocn_frac = %f, diff = %f\n", io, jo, omask[no][i], ocn_frac, omask[no][i] - ocn_frac); - mpp_error("make_coupler_mosaic: omask is not equal ocn_frac"); } mask[jo*nxo[no]+io] = ocn_frac; } @@ -1667,6 +1944,7 @@ int main (int argc, char *argv[]) fid = mpp_open(ocn_mask_file, MPP_WRITE); mpp_def_global_att(fid, "grid_version", grid_version); mpp_def_global_att(fid, "code_version", tagname); + if( clip_method == GREAT_CIRCLE_CLIP) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); @@ -1679,6 +1957,10 @@ int main (int argc, char *argv[]) mpp_close(fid); free(mask); } + if(nbad>0) { + printf("make_coupler_mosaic: number of points with omask != ofrac is %d\n", nbad); + mpp_error("make_coupler_mosaic: omask is not equal ocn_frac"); + } } /* calculate land_frac and write out land_frac */ @@ -1701,6 +1983,7 @@ int main (int argc, char *argv[]) fid = mpp_open(lnd_mask_file, MPP_WRITE); mpp_def_global_att(fid, "grid_version", grid_version); mpp_def_global_att(fid, "code_version", tagname); + if( clip_method == GREAT_CIRCLE_CLIP) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); dims[1] = mpp_def_dim(fid, "nx", nxl[nl]); dims[0] = mpp_def_dim(fid, "ny", nyl[nl]); @@ -1747,6 +2030,7 @@ int main (int argc, char *argv[]) fid = mpp_open(axl_file[nfile_axl], MPP_WRITE); mpp_def_global_att(fid, "grid_version", grid_version); mpp_def_global_att(fid, "code_version", tagname); + if( clip_method == GREAT_CIRCLE_CLIP) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); dim_string = mpp_def_dim(fid, "string", STRING); dim_ncells = mpp_def_dim(fid, "ncells", nxgrid); @@ -1790,6 +2074,21 @@ int main (int argc, char *argv[]) mpp_gather_field_double(naxl[na][nl], atmxlnd_area[na][nl], gdata_dbl); if(check) { + int *gdata_ia=NULL, *gdata_ja=NULL; + int ia, ja; + + gdata_ia = (int *)malloc(nxgrid*sizeof(int)); + gdata_ja = (int *)malloc(nxgrid*sizeof(int)); + mpp_gather_field_int(naxl[na][nl], atmxlnd_ia[na][nl], gdata_ia); + mpp_gather_field_int(naxl[na][nl], atmxlnd_ja[na][nl], gdata_ja); + for(n=0; n yl_max) yl_max = yl[0]; - if(yl[1] > yl_max) yl_max = yl[1]; - if(yl[2] > yl_max) yl_max = yl[2]; - if(yl[3] > yl_max) yl_max = yl[3]; - if(yl[0] < yl_min) yl_min = yl[0]; - if(yl[1] < yl_min) yl_min = yl[1]; - if(yl[2] < yl_min) yl_min = yl[2]; - if(yl[3] < yl_min) yl_min = yl[3]; - } - for(no=0; no yl_min && yy < yl_max ) { - if(jo > je_ocn[no] ) je_ocn[no] = jo; - if(jo < js_ocn[no] ) js_ocn[no] = jo; - } + yl[0] = ylnd[nl][n0]; + yl[1] = ylnd[nl][n1]; + yl[2] = ylnd[nl][n2]; + yl[3] = ylnd[nl][n3]; + if(yl[0] > yl_max) yl_max = yl[0]; + if(yl[1] > yl_max) yl_max = yl[1]; + if(yl[2] > yl_max) yl_max = yl[2]; + if(yl[3] > yl_max) yl_max = yl[3]; + if(yl[0] < yl_min) yl_min = yl[0]; + if(yl[1] < yl_min) yl_min = yl[1]; + if(yl[2] < yl_min) yl_min = yl[2]; + if(yl[3] < yl_min) yl_min = yl[3]; } - js_ocn[no] = max(0, js_ocn[no]-1); - je_ocn[no] = min(nyo[no]-1, je_ocn[no]+1); - is_ocn[no] = 0; - ie_ocn[no] = nxo[no] - 1; + for(no=0; no yl_min && yy < yl_max ) { + if(jo > je_ocn[no] ) je_ocn[no] = jo; + if(jo < js_ocn[no] ) js_ocn[no] = jo; + } + } + js_ocn[no] = max(0, js_ocn[no]-1); + je_ocn[no] = min(nyo[no]-1, je_ocn[no]+1); + is_ocn[no] = 0; + ie_ocn[no] = nxo[no] - 1; + } } for(ll=is;ll<=ie;ll++) { il = ll%nxl[nl]; jl = ll/nxl[nl]; - n0 = jl *(nxl[nl]+1) + il; - n1 = jl *(nxl[nl]+1) + il+1; - n2 = (jl+1)*(nxl[nl]+1) + il+1; - n3 = (jl+1)*(nxl[nl]+1) + il; - xl[0] = xlnd[nl][n0]; yl[0] = ylnd[nl][n0]; - xl[1] = xlnd[nl][n1]; yl[1] = ylnd[nl][n1]; - xl[2] = xlnd[nl][n2]; yl[2] = ylnd[nl][n2]; - xl[3] = xlnd[nl][n3]; yl[3] = ylnd[nl][n3]; - yl_min = minval_double(4, yl); - yl_max = maxval_double(4, yl); - nl_in = fix_lon(xl, yl, 4, M_PI); - xl_min = minval_double(nl_in, xl); - xl_max = maxval_double(nl_in, xl); - xl_avg = avgval_double(nl_in, xl); + if(clip_method == GREAT_CIRCLE_CLIP) { /* clockwise */ + n0 = jl *(nxl[nl]+1) + il; + n1 = (jl+1)*(nxl[nl]+1) + il; + n2 = (jl+1)*(nxl[nl]+1) + il+1; + n3 = jl *(nxl[nl]+1) + il+1; + xl[0] = cart_xlnd[nl][n0]; yl[0] = cart_ylnd[nl][n0]; zl[0] = cart_zlnd[nl][n0]; + xl[1] = cart_xlnd[nl][n1]; yl[1] = cart_ylnd[nl][n1]; zl[1] = cart_zlnd[nl][n1]; + xl[2] = cart_xlnd[nl][n2]; yl[2] = cart_ylnd[nl][n2]; zl[2] = cart_zlnd[nl][n2]; + xl[3] = cart_xlnd[nl][n3]; yl[3] = cart_ylnd[nl][n3]; zl[3] = cart_zlnd[nl][n3]; + } + else { + n0 = jl *(nxl[nl]+1) + il; + n1 = jl *(nxl[nl]+1) + il+1; + n2 = (jl+1)*(nxl[nl]+1) + il+1; + n3 = (jl+1)*(nxl[nl]+1) + il; + xl[0] = xlnd[nl][n0]; yl[0] = ylnd[nl][n0]; + xl[1] = xlnd[nl][n1]; yl[1] = ylnd[nl][n1]; + xl[2] = xlnd[nl][n2]; yl[2] = ylnd[nl][n2]; + xl[3] = xlnd[nl][n3]; yl[3] = ylnd[nl][n3]; + yl_min = minval_double(4, yl); + yl_max = maxval_double(4, yl); + nl_in = fix_lon(xl, yl, 4, M_PI); + xl_min = minval_double(nl_in, xl); + xl_max = maxval_double(nl_in, xl); + xl_avg = avgval_double(nl_in, xl); + } for(no=0; no MIN_AREA_FRAC) { double ocn_frac; - n0 = jo *(nxo[no]+1) + io; - n1 = jo *(nxo[no]+1) + io+1; - n2 = (jo+1)*(nxo[no]+1) + io+1; - n3 = (jo+1)*(nxo[no]+1) + io; - xo[0] = xocn[no][n0]; yo[0] = yocn[no][n0]; - xo[1] = xocn[no][n1]; yo[1] = yocn[no][n1]; - xo[2] = xocn[no][n2]; yo[2] = yocn[no][n2]; - xo[3] = xocn[no][n3]; yo[3] = yocn[no][n3]; - yo_min = minval_double(4, yo); - yo_max = maxval_double(4, yo); - if(yo_min >= yl_max || yo_max <= yl_min ) continue; - no_in = fix_lon(xo, yo, 4, xl_avg); - xo_min = minval_double(no_in, xo); - xo_max = maxval_double(no_in, xo); - /* xo should in the same range as xa after lon_fix, so no need to - consider cyclic condition - */ - if(xl_min >= xo_max || xl_max <= xo_min ) continue; + if(clip_method == GREAT_CIRCLE_CLIP) { /* clockwise */ + n0 = jo *(nxo[no]+1) + io; + n1 = (jo+1)*(nxo[no]+1) + io; + n2 = (jo+1)*(nxo[no]+1) + io+1; + n3 = jo *(nxo[no]+1) + io+1; + xo[0] = cart_xocn[no][n0]; yo[0] = cart_yocn[no][n0]; zo[0] = cart_zocn[no][n0]; + xo[1] = cart_xocn[no][n1]; yo[1] = cart_yocn[no][n1]; zo[1] = cart_zocn[no][n1]; + xo[2] = cart_xocn[no][n2]; yo[2] = cart_yocn[no][n2]; zo[2] = cart_zocn[no][n2]; + xo[3] = cart_xocn[no][n3]; yo[3] = cart_yocn[no][n3]; zo[3] = cart_zocn[no][n3]; + } + else { + n0 = jo *(nxo[no]+1) + io; + n1 = jo *(nxo[no]+1) + io+1; + n2 = (jo+1)*(nxo[no]+1) + io+1; + n3 = (jo+1)*(nxo[no]+1) + io; + xo[0] = xocn[no][n0]; yo[0] = yocn[no][n0]; + xo[1] = xocn[no][n1]; yo[1] = yocn[no][n1]; + xo[2] = xocn[no][n2]; yo[2] = yocn[no][n2]; + xo[3] = xocn[no][n3]; yo[3] = yocn[no][n3]; + yo_min = minval_double(4, yo); + yo_max = maxval_double(4, yo); + if(yo_min >= yl_max || yo_max <= yl_min ) continue; + no_in = fix_lon(xo, yo, 4, xl_avg); + xo_min = minval_double(no_in, xo); + xo_max = maxval_double(no_in, xo); + /* xo should in the same range as xa after lon_fix, so no need to + consider cyclic condition + */ + if(xl_min >= xo_max || xl_max <= xo_min ) continue; + } ocn_frac = omask[no][jo*nxo[no]+io]; - if ( (n_out = clip_2dx2d( xl, yl, nl_in, xo, yo, no_in, x_out, y_out )) > 0 ){ - xarea = poly_area(x_out, y_out, n_out )*ocn_frac; + if(clip_method == GREAT_CIRCLE_CLIP) { + n_out = clip_2dx2d_great_circle(xl, yl, zl, 4, xo, yo, zo, 4, + x_out, y_out, z_out); + } + else + n_out = clip_2dx2d( xl, yl, nl_in, xo, yo, no_in, x_out, y_out ); + + if ( n_out > 0 ){ + if(clip_method == GREAT_CIRCLE_CLIP) + xarea=great_circle_area ( n_out, x_out, y_out, z_out)*ocn_frac; + else + xarea = poly_area(x_out, y_out, n_out )*ocn_frac; min_area = min(area_ocn[no][jo*nxo[no]+io], area_lnd[nl][ll] ); - if(xarea/min_area > AREA_RATIO_THRESH ) { + if(xarea/min_area > area_ratio_thresh ) { lndxocn_area[nl][no][nlxo[nl][no]] = xarea; lndxocn_io[nl][no][nlxo[nl][no]] = io; lndxocn_jo[nl][no][nlxo[nl][no]] = jo; @@ -2359,6 +2719,7 @@ int main (int argc, char *argv[]) fid = mpp_open(lxo_file[nfile_lxo], MPP_WRITE); mpp_def_global_att(fid, "grid_version", grid_version); mpp_def_global_att(fid, "code_version", tagname); + if( clip_method == GREAT_CIRCLE_CLIP) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); dim_string = mpp_def_dim(fid, "string", STRING); dim_ncells = mpp_def_dim(fid, "ncells", nxgrid); @@ -2402,6 +2763,7 @@ int main (int argc, char *argv[]) gdata_dbl = (double *)malloc(nxgrid*sizeof(double)); mpp_gather_field_double(nlxo[nl][no], lndxocn_area[nl][no], gdata_dbl); + mpp_put_var_value(fid, id_xgrid_area, gdata_dbl); mpp_gather_field_int(nlxo[nl][no], lndxocn_il[nl][no], gdata_int); mpp_put_var_value_block(fid, id_tile1_cell, start, nwrite, gdata_int); @@ -2565,8 +2927,8 @@ int main (int argc, char *argv[]) double xo_min, yo_min, xw_min, yw_min, xw_avg; double xo_max, yo_max, xw_max, yw_max; double xarea; - double xw[MV], yw[MV], xo[MV], yo[MV]; - double x_out[MV], y_out[MV]; + double xw[MV], yw[MV], zw[MV], xo[MV], yo[MV], zo[MV]; + double x_out[MV], y_out[MV], z_out[MV]; size_t count; domain2D Dom; double yy; @@ -2587,102 +2949,139 @@ int main (int argc, char *argv[]) je_ocn = (int *)malloc(ntile_ocn*sizeof(int)); yw_min = 9999; yw_max = -9999; - - for(lw=is;lw<=ie;lw++) { + + if(clip_method == GREAT_CIRCLE_CLIP) { + for(no=0; no yw_max) yw_max = yw[0]; - if(yw[1] > yw_max) yw_max = yw[1]; - if(yw[2] > yw_max) yw_max = yw[2]; - if(yw[3] > yw_max) yw_max = yw[3]; - if(yw[0] < yw_min) yw_min = yw[0]; - if(yw[1] < yw_min) yw_min = yw[1]; - if(yw[2] < yw_min) yw_min = yw[2]; - if(yw[3] < yw_min) yw_min = yw[3]; - } - /* printf("yw_min=%f, yw_max=%f\n", yw_min, yw_max); */ + yw[0] = ywav[nw][n0]; + yw[1] = ywav[nw][n1]; + yw[2] = ywav[nw][n2]; + yw[3] = ywav[nw][n3]; + if(yw[0] > yw_max) yw_max = yw[0]; + if(yw[1] > yw_max) yw_max = yw[1]; + if(yw[2] > yw_max) yw_max = yw[2]; + if(yw[3] > yw_max) yw_max = yw[3]; + if(yw[0] < yw_min) yw_min = yw[0]; + if(yw[1] < yw_min) yw_min = yw[1]; + if(yw[2] < yw_min) yw_min = yw[2]; + if(yw[3] < yw_min) yw_min = yw[3]; + } + /* printf("yw_min=%f, yw_max=%f\n", yw_min, yw_max); */ - for(no=0; no yw_min && yy < yw_max ) { - if(jo > je_ocn[no] ) je_ocn[no] = jo; - if(jo < js_ocn[no] ) js_ocn[no] = jo; + for(no=0; no yw_min && yy < yw_max ) { + if(jo > je_ocn[no] ) je_ocn[no] = jo; + if(jo < js_ocn[no] ) js_ocn[no] = jo; + } } - } - js_ocn[no] = max(0, js_ocn[no]-1); - je_ocn[no] = min(nyo[no]-1, je_ocn[no]+1); + js_ocn[no] = max(0, js_ocn[no]-1); + je_ocn[no] = min(nyo[no]-1, je_ocn[no]+1); - if(no==nw || !wav_same_as_ocn ) { - is_ocn[no] = 0; - ie_ocn[no] = nxo[no]-1; - } - else { - is_ocn[no] = nxo[no]-1; - ie_ocn[no] = 0; + if(no==nw || !wav_same_as_ocn ) { + is_ocn[no] = 0; + ie_ocn[no] = nxo[no]-1; + } + else { + is_ocn[no] = nxo[no]-1; + ie_ocn[no] = 0; + } } - } - for(lw=is;lw<=ie;lw++) { if(mpp_pe()==mpp_root_pe() && verbose)printf("nw = %d, lw = %d, is=%d, ie = %d\n", nw, lw, is, ie); iw = lw%nxw[nw]; jw = lw/nxw[nw]; - n0 = jw *(nxw[nw]+1) + iw; - n1 = jw *(nxw[nw]+1) + iw+1; - n2 = (jw+1)*(nxw[nw]+1) + iw+1; - n3 = (jw+1)*(nxw[nw]+1) + iw; - xw[0] = xwav[nw][n0]; yw[0] = ywav[nw][n0]; - xw[1] = xwav[nw][n1]; yw[1] = ywav[nw][n1]; - xw[2] = xwav[nw][n2]; yw[2] = ywav[nw][n2]; - xw[3] = xwav[nw][n3]; yw[3] = ywav[nw][n3]; - yw_min = minval_double(4, yw); - yw_max = maxval_double(4, yw); - nw_in = fix_lon(xw, yw, 4, M_PI); - xw_min = minval_double(nw_in, xw); - xw_max = maxval_double(nw_in, xw); - xw_avg = avgval_double(nw_in, xw); - count = 0; + if(clip_method == GREAT_CIRCLE_CLIP) { /* clockwise */ + n0 = jw *(nxw[nw]+1) + iw; + n1 = (jw+1)*(nxw[nw]+1) + iw; + n2 = (jw+1)*(nxw[nw]+1) + iw+1; + n3 = jw *(nxw[nw]+1) + iw+1; + xw[0] = cart_xwav[nw][n0]; yw[0] = cart_ywav[nw][n0]; zw[0] = cart_zwav[nw][n0]; + xw[1] = cart_xwav[nw][n1]; yw[1] = cart_ywav[nw][n1]; zw[1] = cart_zwav[nw][n1]; + xw[2] = cart_xwav[nw][n2]; yw[2] = cart_ywav[nw][n2]; zw[2] = cart_zwav[nw][n2]; + xw[3] = cart_xwav[nw][n3]; yw[3] = cart_ywav[nw][n3]; zw[3] = cart_zwav[nw][n3]; + } + else { + n0 = jw *(nxw[nw]+1) + iw; + n1 = jw *(nxw[nw]+1) + iw+1; + n2 = (jw+1)*(nxw[nw]+1) + iw+1; + n3 = (jw+1)*(nxw[nw]+1) + iw; + xw[0] = xwav[nw][n0]; yw[0] = ywav[nw][n0]; + xw[1] = xwav[nw][n1]; yw[1] = ywav[nw][n1]; + xw[2] = xwav[nw][n2]; yw[2] = ywav[nw][n2]; + xw[3] = xwav[nw][n3]; yw[3] = ywav[nw][n3]; + yw_min = minval_double(4, yw); + yw_max = maxval_double(4, yw); + nw_in = fix_lon(xw, yw, 4, M_PI); + xw_min = minval_double(nw_in, xw); + xw_max = maxval_double(nw_in, xw); + xw_avg = avgval_double(nw_in, xw); + } /* calculate wave/ocean x-cells */ for(no=0; no MIN_AREA_FRAC) { /* over sea/ice */ /* xo should in the same range as xa after lon_fix, so no need to consider cyclic condition */ - if(xw_min >= xo_max || xw_max <= xo_min || yw_min >= yo_max || yw_max <= yo_min ) continue; - - if ( (n_out = clip_2dx2d( xw, yw, nw_in, xo, yo, no_in, x_out, y_out )) > 0) { + if(clip_method == GREAT_CIRCLE_CLIP) { + n_out = clip_2dx2d_great_circle(xw, yw, zw, 4, xo, yo, zo, 4, + x_out, y_out, z_out); + } + else { + if(xw_min >= xo_max || xw_max <= xo_min || yw_min >= yo_max || yw_max <= yo_min ) continue; + n_out = clip_2dx2d( xw, yw, nw_in, xo, yo, no_in, x_out, y_out); + } + if ( n_out > 0) { xarea = poly_area(x_out, y_out, n_out )*ocn_frac; min_area = min(area_ocn[no][jo*nxo[no]+io], area_wav[nw][lw]); - if(xarea/min_area > AREA_RATIO_THRESH) { + if(xarea/min_area > area_ratio_thresh) { wavxocn_area[nw][no][nwxo[nw][no]] = xarea; wavxocn_io[nw][no][nwxo[nw][no]] = io; @@ -2889,6 +3288,7 @@ int main (int argc, char *argv[]) fid = mpp_open(wav_mask_file, MPP_WRITE); mpp_def_global_att(fid, "grid_version", grid_version); mpp_def_global_att(fid, "code_version", tagname); + if( clip_method == GREAT_CIRCLE_CLIP) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); @@ -2939,6 +3339,7 @@ int main (int argc, char *argv[]) fid = mpp_open(wxo_file[nfile_wxo], MPP_WRITE); mpp_def_global_att(fid, "grid_version", grid_version); mpp_def_global_att(fid, "code_version", tagname); + if( clip_method == GREAT_CIRCLE_CLIP) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); dim_string = mpp_def_dim(fid, "string", STRING); dim_ncells = mpp_def_dim(fid, "ncells", nxgrid); @@ -3079,23 +3480,47 @@ int main (int argc, char *argv[]) double axl_area_frac_nest; double tiling_area; double tiling_area_nest; - double *atm_area; double atm_area_sum, atm_area_sum_nest; if(check) { + double max_ratio, cur_ratio; + int max_ia, max_ja, max_ta; + + /* make sure each atmosphere grid area equal sum of the axo area and axl area (atm_xarea) */ + max_ta = -1; + max_ia = -1; + max_ja = -1; + max_ratio = -1; + + for(n=0; n 1.e-5) { + printf("at tile =%d, i=%d, j=%d, ratio=%g, area1=%g, area2=%g\n", + n, i%nxa[n], i/nxa[n], cur_ratio, area_atm[n][i], atm_xarea[n][i] ); + } + if(cur_ratio > max_ratio) { + max_ratio = cur_ratio; + max_ta = n; + max_ja = i/nxa[n]; + max_ia = i%nxa[n]; + } + } + } + + printf("The maximum area is at tile=%d, i=%d, j=%d, ratio=%g, area1=%g, area2=%g\n", + max_ta, max_ia, max_ja, max_ratio, area_atm[max_ta][max_ja*nxa[max_ta]+max_ia], + atm_xarea[max_ta][max_ja*nxa[max_ta]+max_ia]); /* for cubic grid, when number of model points is odd, some grid cell area will be negative, need to think about how to solve this issue in the future */ /* atm_area_sum = 4*M_PI*RADIUS*RADIUS; */ atm_area_sum = 0; atm_area_sum_nest = 0; for(n=0; n0) { dims[0] = dim_wxo; dims[1] = dim_string; id_wxo_file = mpp_def_var(fid, "wXo_file", MPP_CHAR, 2, dims, 1, "standard_name", "wavXocn_exchange_grid_file"); @@ -3240,6 +3669,7 @@ int main (int argc, char *argv[]) } if(mpp_pe()== mpp_root_pe() && verbose)printf("\n***** Congratulation! You have successfully run make_coupler_mosaic\n"); + mpp_end(); return 0; diff --git a/src/tools/make_hgrid/COPYING b/src/tools/make_hgrid/COPYING new file mode 100644 index 0000000000..93a221957b --- /dev/null +++ b/src/tools/make_hgrid/COPYING @@ -0,0 +1,159 @@ +TERMS AND CONDITIONS +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. +1. Source Code. + +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. +2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. +7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. +8. Termination. + +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. +11. Patents. + +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. diff --git a/src/tools/make_hgrid/Makefile b/src/tools/make_hgrid/Makefile deleted file mode 100644 index f30b8278c4..0000000000 --- a/src/tools/make_hgrid/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-3.6.2 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -LDFLAGS = -L${NETCDFPATH}/lib -lm -lnetcdf -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o interp.o create_xgrid.o mpp.o mpp_domain.o mpp_io.o tool_util.o create_lonlat_grid.o \ - create_conformal_cubic_grid.o create_gnomonic_cubic_grid.o create_grid_from_file.o make_hgrid.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/mosaic_util.h $(SHAREDIR)/create_xgrid.h \ - $(SHAREDIR)/interp.h $(TOOLSHAREDIR)/tool_util.h \ - $(COREDIR)/create_hgrid.h - -make_hgrid: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -make_hgrid.o: $(COREDIR)/make_hgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/make_hgrid.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - -create_gnomonic_cubic_grid.o: $(COREDIR)/create_gnomonic_cubic_grid.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_gnomonic_cubic_grid.c - -create_conformal_cubic_grid.o: $(COREDIR)/create_conformal_cubic_grid.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_conformal_cubic_grid.c - -create_lonlat_grid.o: $(COREDIR)/create_lonlat_grid.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_lonlat_grid.c - -create_grid_from_file.o: $(COREDIR)/create_grid_from_file.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_grid_from_file.c diff --git a/src/tools/make_hgrid/Makefile_mpi b/src/tools/make_hgrid/Makefile_mpi deleted file mode 100644 index b757210ae0..0000000000 --- a/src/tools/make_hgrid/Makefile_mpi +++ /dev/null @@ -1,57 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-3.6.2 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -LDFLAGS = -L${NETCDFPATH}/lib -lm -lnetcdf -lmpi -DEFFLAG = -Duse_libMPI -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o interp.o create_xgrid.o mpp.o mpp_domain.o mpp_io.o tool_util.o create_lonlat_grid.o \ - create_conformal_cubic_grid.o create_gnomonic_cubic_grid.o create_grid_from_file.o make_hgrid.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/mosaic_util.h $(SHAREDIR)/create_xgrid.h \ - $(SHAREDIR)/interp.h $(TOOLSHAREDIR)/tool_util.h \ - $(COREDIR)/create_hgrid.h - -make_hgrid_parallel: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -make_hgrid.o: $(COREDIR)/make_hgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/make_hgrid.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(DEFFLAG) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - -create_gnomonic_cubic_grid.o: $(COREDIR)/create_gnomonic_cubic_grid.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_gnomonic_cubic_grid.c - -create_conformal_cubic_grid.o: $(COREDIR)/create_conformal_cubic_grid.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_conformal_cubic_grid.c - -create_lonlat_grid.o: $(COREDIR)/create_lonlat_grid.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_lonlat_grid.c - -create_grid_from_file.o: $(COREDIR)/create_grid_from_file.c - $(CC) $(CFLAGS) -c $(COREDIR)/create_grid_from_file.c diff --git a/src/tools/make_hgrid/create_gnomonic_cubic_grid.c b/src/tools/make_hgrid/create_gnomonic_cubic_grid.c index ea7a2ea37c..e7291cc26a 100644 --- a/src/tools/make_hgrid/create_gnomonic_cubic_grid.c +++ b/src/tools/make_hgrid/create_gnomonic_cubic_grid.c @@ -37,11 +37,10 @@ void cell_north(int ni, int nj, const double *lonc, const double *latc, double * void calc_cell_area(int nx, int ny, const double *x, const double *y, double *area); void direct_transform(double stretch_factor, int i1, int i2, int j1, int j2, double lon_p, double lat_p, int n, double *lon, double *lat); -void setup_aligned_nest(int parent_tile, int parent_ni, int parent_nj, - const double *parent_xc, const double *parent_yc, int halo, - int refine_ratio, int istart, int iend, int jstart, int jend, - double *x, double *y, double *dx, double *dy, - double *area, double *angle_dx, double *angle_dy); +void setup_aligned_nest(int parent_ni, int parent_nj, const double *parent_xc, const double *parent_yc, + int halo, int refine_ratio, int istart, int iend, int jstart, int jend, + double *xc, double *yc); + void spherical_linear_interpolation(double beta, const double *p1, const double *p2, double *pb); /******************************************************************************* @@ -58,12 +57,17 @@ void create_gnomonic_cubic_grid( char* grid_type, int *nlon, int *nlat, double * int iend_nest, int jstart_nest, int jend_nest, int halo) { const int ntiles = 6; - int nx, ny, nxp, ni, nip; - int i, j, n; + int ntiles2, global_nest=0; + int nx, ny, nxp, nyp, ni, nj, nip, njp; + int ni_nest, nj_nest, nx_nest, ny_nest; + int istart, iend, jstart, jend; + int ni2, nj2, ni2p, nj2p, n1, n2; + int *nxl=NULL, *nyl=NULL, *nil=NULL, *njl=NULL; + int i, j, n, npts; double p1[2], p2[2]; - double *lon, *lat; - double *xc, *yc, *xt, *yt; - double *xe, *ye, *xn, *yn; + double *lon=NULL, *lat=NULL; + double *xc=NULL, *yc=NULL, *xtmp=NULL, *ytmp=NULL; + double *xc2=NULL, *yc2=NULL; int stretched_grid=0; /* make sure the first 6 tiles have the same grid size and @@ -79,12 +83,63 @@ void create_gnomonic_cubic_grid( char* grid_type, int *nlon, int *nlat, double * for(n=1; n ntiles) { + nxl[ntiles] = nx_nest; + nyl[ntiles] = ny_nest; + nil[ntiles] = ni_nest; + njl[ntiles] = nj_nest; + } + + /* for global nest grid, set ni to the coarse grid size */ + if(global_nest) { + ni /= refine_ratio; + nj /= refine_ratio; + } + nip=ni+1; + njp=nj+1; if ( do_schmidt && fabs(stretch_factor-1.) > EPSLN5 ) stretched_grid = 1; @@ -102,14 +157,12 @@ void create_gnomonic_cubic_grid( char* grid_type, int *nlon, int *nlat, double * symm_ed(ni, lon, lat); - xc = (double *)malloc(ntiles*nip*nip*sizeof(double)); - yc = (double *)malloc(ntiles*nip*nip*sizeof(double)); - xt = (double *)malloc(ntiles*ni *ni *sizeof(double)); - yt = (double *)malloc(ntiles*ni *ni *sizeof(double)); - xe = (double *)malloc(ntiles*nip*ni *sizeof(double)); - ye = (double *)malloc(ntiles*nip*ni *sizeof(double)); - xn = (double *)malloc(ntiles*ni *nip*sizeof(double)); - yn = (double *)malloc(ntiles*ni *nip*sizeof(double)); + + npts = ntiles*nip*nip; + if(ntiles2>ntiles) npts += (ni_nest+1)*(nj_nest+1); + + xc = (double *)malloc(npts*sizeof(double)); + yc = (double *)malloc(npts*sizeof(double)); for(j=0; jni2) ni2 = nil[n]; + if(njl[n]>nj2) nj2 = njl[n]; + } + ni2p = ni2+1; + nj2p = nj2+1; + xtmp = (double *)malloc(ni2p*nj2p*sizeof(double)); + ytmp = (double *)malloc(ni2p*nj2p*sizeof(double)); + for(n=0; nntiles) calc_cell_area(nx_nest, ny_nest, x+ntiles*nxp*nyp, y+ntiles*nxp*nyp, area+ntiles*nx*ny); + /*calculate rotation angle, just some workaround, will modify this in the future. */ calc_rotation_angle2(nxp, x, y, angle_dx, angle_dy ); - if( nest_grid ) setup_aligned_nest(parent_tile, ni, ni, xc+nip*nip*(parent_tile-1), - yc+nip*nip*(parent_tile-1), halo, refine_ratio, - istart_nest, iend_nest, jstart_nest, jend_nest, - x+ntiles*nxp*nxp, y+ntiles*nxp*nxp, - dx+ntiles*nx*nxp, dy+ntiles*nxp*nx, - area+ntiles*nx*nx, angle_dx+ntiles*nxp*nxp, - angle_dy+ntiles*nxp*nxp); - + /* since angle is used in the model, set angle to 0 for nested region */ + if(ntiles2>ntiles) { + for(i=0; i<=(nx_nest+1)*(ny_nest+1); i++) { + angle_dx[ntiles*nxp*nxp+i]=0; + angle_dy[ntiles*nxp*nxp+i]=0; + } + } + /* convert grid location from radians to degree */ - for(i=0; i0) npts += (nx_nest+1)*(ny_nest+1); + + for(i=0; i parent_nj || - iend + ceil( halo/(double)refine_ratio ) > parent_ni ) + if( (jstart - halo) < 1 || (istart - halo) < 1 || + (jend + halo) > parent_nj || (iend + halo) > parent_ni ) mpp_error("create_gnomonic_cubic_grid(setup_aligned_nest): nested grid lies outside its parent"); ni = (iend-istart+1)*refine_ratio; nj = (jend-jstart+1)*refine_ratio; npi = ni+1; npj = nj+1; - nx = 2*ni; - ny = 2*nj; - npx = nx+1; - npy = ny+1; - - xc = (double *)malloc(npi*npj*sizeof(double)); - yc = (double *)malloc(npi*npj*sizeof(double)); - xt = (double *)malloc(ni *nj *sizeof(double)); - yt = (double *)malloc(ni *nj *sizeof(double)); - xe = (double *)malloc(npi*nj *sizeof(double)); - ye = (double *)malloc(npi*nj *sizeof(double)); - xn = (double *)malloc(ni *npj*sizeof(double)); - yn = (double *)malloc(ni *npj*sizeof(double)); - parent_npi = parent_ni+1; for(j=0; j 0) lon[i] -= 360; + xt[i] = lon[i]; + yt[i] = lat[i]; + lon[i] *= D2R; + lat[i] *= D2R; + } + + + n = log(cos(phi1)/cos(phi2))/log(tan(0.25*M_PI+0.5*phi2)/tan(0.25*M_PI+0.5*phi1)); + F = cos(phi1)*pow(tan(0.25*M_PI+0.5*phi1),n); + rho0 = F*pow(1/tan(0.25*M_PI+0.5*central_lat),n); + for(i=0; i 1.e-6 ) { + printf(" i = %d, j = %d, x1 = %g, x2 = %g \n", i, j, x1[j*nlon+i], x1[i]); + mpp_error(" x is not uniform \n"); + } + } + } + + printf(" x is uniform \n \n \n"); + + for(j=0; i 1.e-6 ) { + printf(" i = %d, j = %d, x1 = %g, x2 = %g \n", i, j, y1[j*nlon+i], y1[j*nlon]); + mpp_error(" y is not uniform \n"); + } + } + } + + printf(" y is uniform \n \n \n"); + + /* get the x and y value at corner */ + + x2 = (double *)malloc((nlon+1)*(nlat+1)*sizeof(double)); + y2 = (double *)malloc((nlon+1)*(nlat+1)*sizeof(double)); + + for(i=1; i ntiles_global) { nxl[ntiles_global] = (iend_nest-istart_nest+1)*refine_ratio; nyl[ntiles_global] = (jend_nest-jstart_nest+1)*refine_ratio; } @@ -801,46 +824,40 @@ int main(int argc, char* argv[]) jsc = 0; jec = ny-1; - switch (my_grid_type) { - case REGULAR_LONLAT_GRID: + if(my_grid_type==REGULAR_LONLAT_GRID) create_regular_lonlat_grid(&nxbnds, &nybnds, xbnds, ybnds, nlon, nlat, dx_bnds, dy_bnds, - use_legacy, &isc, &iec, &jsc, &jec, x, y, dx, dy, area, angle_dx, center); - break; - case TRIPOLAR_GRID: + use_legacy, &isc, &iec, &jsc, &jec, x, y, dx, dy, area, + angle_dx, center, use_great_circle_algorithm); + else if(my_grid_type==TRIPOLAR_GRID) create_tripolar_grid(&nxbnds, &nybnds, xbnds, ybnds, nlon, nlat, dx_bnds, dy_bnds, - use_legacy, &lat_join, &isc, &iec, &jsc, &jec, x, y, dx, dy, area, angle_dx, center, verbose); - break; - case FROM_FILE: + use_legacy, &lat_join, &isc, &iec, &jsc, &jec, x, y, dx, dy, + area, angle_dx, center, verbose, use_great_circle_algorithm); + else if(my_grid_type==FROM_FILE) { for(n=0; n=ntiles_global) mpp_def_global_att(fid, "nest_grid", "TRUE"); mpp_def_global_att(fid, "history", history); mpp_end_def(fid); diff --git a/src/tools/make_quick_mosaic/Makefile b/src/tools/make_quick_mosaic/Makefile deleted file mode 100644 index e8ce721990..0000000000 --- a/src/tools/make_quick_mosaic/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-3.6.2 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -LDFLAGS = -L${NETCDFPATH}/lib -lm -lnetcdf -DEFFLAG = -Duse_netCDF -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o mpp.o mpp_domain.o mpp_io.o tool_util.o make_quick_mosaic.o \ - interp.o create_xgrid.o read_mosaic.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(TOOLSHAREDIR)/tool_util.h \ - $(SHAREDIR)/interp.h $(SHAREDIR)/create_xgrid.h $(SHAREDIR)/read_mosaic.h - -make_quick_mosaic: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -make_quick_mosaic.o: $(COREDIR)/make_quick_mosaic.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/make_quick_mosaic.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -read_mosaic.o: $(SHAREDIR)/read_mosaic.c $(HEADERS) - $(CC) $(DEFFLAG) $(CFLAGS) -c $(SHAREDIR)/read_mosaic.c diff --git a/src/tools/make_quick_mosaic/env.gaea b/src/tools/make_quick_mosaic/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/make_quick_mosaic/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/make_quick_mosaic/env.gfdl-ws b/src/tools/make_quick_mosaic/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/make_quick_mosaic/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/make_quick_mosaic/env.pan b/src/tools/make_quick_mosaic/env.pan new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/make_quick_mosaic/env.pan @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/make_quick_mosaic/env.zeus b/src/tools/make_quick_mosaic/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/make_quick_mosaic/fre-nctools.mk b/src/tools/make_quick_mosaic/fre-nctools.mk new file mode 100644 index 0000000000..f9cd0e4376 --- /dev/null +++ b/src/tools/make_quick_mosaic/fre-nctools.mk @@ -0,0 +1,73 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:33:35 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include env.$(SITE) + +CC := icc +CFLAGS := -O3 -traceback +CFLAGS_O2:= -O2 -traceback +INCLUDES := -I${NETCDF_HOME}/include -I./ -I../shared -I../../shared/mosaic +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) + +TARGETS := make_quick_mosaic + +SOURCES := make_quick_mosaic.c +SOURCES += mpp.c mpp_domain.c mpp_io.c tool_util.c +SOURCES += create_xgrid.c interp.c mosaic_util.c read_mosaic.c + +OBJECTS := $(SOURCES:c=o) + +HEADERS = fre-nctools.mk ../shared/mpp.h ../shared/mpp_domain.h ../shared/mpp_io.h ../shared/tool_util.h \ + ../../shared/mosaic/constant.h ../../shared/mosaic/create_xgrid.h \ + ../../shared/mosaic/interp.h ../../shared/mosaic/mosaic_util.h \ + ../../shared/mosaic/read_mosaic.h + +all: $(TARGETS) + +make_quick_mosaic: $(OBJECTS) + $(CC) -o $@ $^ $(CLIBS) + +make_quick_mosaic.o: make_quick_mosaic.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +mosaic_util.o: ../../shared/mosaic/mosaic_util.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +read_mosaic.o: ../../shared/mosaic/read_mosaic.c $(HEADERS) + $(CC) -Duse_netCDF $(CFLAGS) $(INCLUDES) -c $< + +interp.o: ../../shared/mosaic/interp.c $(HEADERS) + $(CC) -Duse_netCDF $(CFLAGS) $(INCLUDES) -c $< + +mpp_io.o: ../shared/mpp_io.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +mpp_domain.o: ../shared/mpp_domain.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +mpp.o: ../shared/mpp.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +tool_util.o: ../shared/tool_util.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +create_xgrid.o: ../../shared/mosaic/create_xgrid.c $(HEADERS) + $(CC) $(CFLAGS_O2) $(INCLUDES) -c $< + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + -rm -f *.o $(TARGETS) diff --git a/src/tools/make_quick_mosaic/make_quick_mosaic.c b/src/tools/make_quick_mosaic/make_quick_mosaic.c index f017cdb1cd..d33a804cf7 100644 --- a/src/tools/make_quick_mosaic/make_quick_mosaic.c +++ b/src/tools/make_quick_mosaic/make_quick_mosaic.c @@ -48,7 +48,7 @@ char *usage[] = { char grid_version[] = "0.2"; -char tagname[] = "$Name: siena_201207 $"; +char tagname[] = "$Name: tikal $"; void get_file_name(char *file, char *filename) { @@ -78,15 +78,23 @@ int main (int argc, char *argv[]) int *nx, *ny; double **lonb, **latb, **land_area, **ocean_area, **cell_area; char **axl_file = NULL, **axo_file=NULL, **lxo_file=NULL; + char **tilename = NULL; char **ocn_topog_file = NULL; char *input_mosaic = NULL; char *ocean_topog = NULL; double sea_level = 0.; char mosaic_name[STRING] = "mosaic", mosaic_file[STRING]; char griddir[STRING], solo_mosaic[STRING], filepath[STRING]; + char solo_mosaic_full_path[STRING] = "./"; + char solo_mosaic_dir[STRING] = "./"; + char ocn_topog_dir[STRING] = "./"; + char amosaic_name[STRING] = "atmos_mosaic"; + char omosaic_name[STRING] = "ocean_mosaic"; + char lmosaic_name[STRING] = "land_mosaic"; char history[512]; int use_ocean_topog = 0; - + int fid_solo_mosaic, tid_gridtile; + static struct option long_options[] = { {"input_mosaic", required_argument, NULL, 'i'}, {"mosaic_name", required_argument, NULL, 'm'}, @@ -172,11 +180,12 @@ int main (int argc, char *argv[]) mpp_error("make_quick_mosaic: The input mosaic file location should not be current directory"); } - sprintf(filepath, "%s/%s", griddir, solo_mosaic); } sprintf(filepath, "%s/%s", griddir, solo_mosaic); + strcpy(solo_mosaic_full_path, filepath); ntiles = read_mosaic_ntiles(filepath); + if(use_ocean_topog ) nfile_aXl = ntiles; /* copy the solo_mosaic file and grid file */ { @@ -187,6 +196,7 @@ int main (int argc, char *argv[]) system(cmd); fid2 = mpp_open(filepath, MPP_READ); + vid2 = mpp_get_varid(fid2, "gridfiles"); for(i=0; i<4; i++) { start[i] = 0; nread[i] = 1; @@ -423,18 +433,37 @@ int main (int argc, char *argv[]) axl_file = (char **)malloc(ntiles*sizeof(char *)); axo_file = (char **)malloc(ntiles*sizeof(char *)); lxo_file = (char **)malloc(ntiles*sizeof(char *)); + tilename = (char **)malloc(ntiles*sizeof(char *)); + fid_solo_mosaic = mpp_open(solo_mosaic_full_path, MPP_READ); + tid_gridtile = mpp_get_varid(fid_solo_mosaic, "gridtiles"); + for(n=0; n1) folded = 0; + if(folded) { istart1[ncontact] = 1; iend1[ncontact] = nx1/2; @@ -250,7 +260,7 @@ int get_overlap_contact( int tile1, int tile2, int nx1, int ny1, int nx2, int ny p2x[0] = 0; p2y[0]=0; count = get_overlap_index(x2[l2], y2[l2], nx1, ny1, x1, y1, p1x, p1y); /* southeast corner */ - p2x[1] = nx2-1; p2y[2] = 0; + p2x[1] = nx2-1; p2y[1] = 0; if( count > 0 ) { l2 = nx2-1; count = get_overlap_index(x2[l2], y2[l2], nx1, ny1, x1, y1, p1x+1, p1y+1); diff --git a/src/tools/make_solo_mosaic/make_solo_mosaic.c b/src/tools/make_solo_mosaic/make_solo_mosaic.c index 408d010580..49934e4c6a 100644 --- a/src/tools/make_solo_mosaic/make_solo_mosaic.c +++ b/src/tools/make_solo_mosaic/make_solo_mosaic.c @@ -60,7 +60,7 @@ const int MAXTILE = 100; const int MAXCONTACT = 100; const int SHORTSTRING = 32; char grid_version[] = "0.2"; -char tagname[] = "$Name: siena_201205_z1l $"; +char tagname[] = "$Name: tikal $"; main (int argc, char *argv[]) { @@ -224,6 +224,8 @@ main (int argc, char *argv[]) } } + printf("NOTE from make_solo_mosaic: there are %d contacts (align-contact)\n", ncontact); + for(n=0; n0) { + if( use_great_circle_algorithm != use_great_circle_algorithm_prev) + mpp_error("make_topog: atribute 'great_circle_algorithm' of field 'tile' have different value for different tile"); + } + use_great_circle_algorithm_prev = use_great_circle_algorithm; + mpp_close(g_fid); } mpp_close(m_fid); + mpp_def_global_att(fid, "grid_version", grid_version); + mpp_def_global_att(fid, "code_version", tagname); + if(use_great_circle_algorithm) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); + mpp_def_global_att(fid, "history", history); + mpp_end_def(fid); + if(mpp_pe()==mpp_root_pe() && use_great_circle_algorithm) + printf("\n NOTE from make_topog: use great circle algorithm\n"); + /* get the boundary condition for realistics topogrpahy, currently only support tripolar_grid, cyclic_x and cyclic_y*/ if(my_topog_type == REALISTIC) get_boundary_type(mosaic_file, VERSION_2, &cyclic_x, &cyclic_y, &tripolar_grid); @@ -762,13 +779,13 @@ int main(int argc, char* argv[]) case IDEALIZED: create_idealized_topog( nx[n], ny[n], x, y, bottom_depth, min_depth, depth); break; - case REALISTIC: + case REALISTIC: create_realistic_topog(nxc, nyc, x, y, vgrid_file, topog_file, topog_field, scale_factor, tripolar_grid, cyclic_x, cyclic_y, fill_first_row, filter_topog, num_filter_pass, smooth_topo_allow_deepening, round_shallow, fill_shallow, deepen_shallow, full_cell, flat_bottom, adjust_topo, fill_isolated_cells, dont_change_landmask, kmt_min, min_thickness, open_very_this_cell, - fraction_full_cell, depth, num_levels, domain, verbose ); + fraction_full_cell, depth, num_levels, domain, verbose, use_great_circle_algorithm ); break; case BOX_CHANNEL: create_box_channel_topog(nx[n], ny[n], bottom_depth, diff --git a/src/tools/make_topog/topog.c b/src/tools/make_topog/topog.c index a6a48849aa..0bb211bae8 100644 --- a/src/tools/make_topog/topog.c +++ b/src/tools/make_topog/topog.c @@ -339,7 +339,7 @@ void create_realistic_topog(int nx_dst, int ny_dst, const double *x_dst, const d int deepen_shallow, int full_cell, int flat_bottom, int adjust_topo, int fill_isolated_cells, int dont_change_landmask, int kmt_min, double min_thickness, int open_very_this_cell, double fraction_full_cell, double *depth, - int *num_levels, domain2D domain, int debug ) + int *num_levels, domain2D domain, int debug, int use_great_circle_algorithm ) { char xname[128], yname[128]; int nx_src, ny_src, nxp_src, nyp_src, i, j, count, n; @@ -479,9 +479,12 @@ void create_realistic_topog(int nx_dst, int ny_dst, const double *x_dst, const d } } - - conserve_interp(nx_src, ny_now, nx_dst, ny_dst, x_src, y_src, - x_out, y_out, mask_src, depth_src, depth ); + if(use_great_circle_algorithm) + conserve_interp_great_circle(nx_src, ny_now, nx_dst, ny_dst, x_src, y_src, + x_out, y_out, mask_src, depth_src, depth ); + else + conserve_interp(nx_src, ny_now, nx_dst, ny_dst, x_src, y_src, + x_out, y_out, mask_src, depth_src, depth ); if (filter_topog) filter_topo(nx_dst, ny_dst, num_filter_pass, smooth_topo_allow_deepening, depth, domain); if(debug) show_deepest(nk, zw, depth, domain); diff --git a/src/tools/make_topog/topog.h b/src/tools/make_topog/topog.h index 9e2dd5f860..51428add99 100644 --- a/src/tools/make_topog/topog.h +++ b/src/tools/make_topog/topog.h @@ -15,7 +15,7 @@ void create_realistic_topog(int nx_dst, int ny_dst, const double *x_dst, const d int deepen_shallow, int full_cell, int flat_bottom, int adjust_topo, int fill_isolated_cells, int dont_change_landmask, int kmt_min, double min_thickness, int open_very_this_cell, double fraction_full_cell, double *depth, - int *num_levels, domain2D domain, int debug ); + int *num_levels, domain2D domain, int debug, int great_circle_algorithm ); void create_box_channel_topog(int nx, int ny, double basin_depth, double jwest_south, double jwest_north, double jeast_south, diff --git a/src/tools/make_vgrid/Makefile b/src/tools/make_vgrid/Makefile deleted file mode 100644 index f95f616b8c..0000000000 --- a/src/tools/make_vgrid/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-3.6.2 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -LDFLAGS = -L${NETCDFPATH}/lib -lm -lnetcdf -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o interp.o create_xgrid.o mpp.o mpp_domain.o mpp_io.o tool_util.o create_vgrid.o make_vgrid.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/mosaic_util.h $(SHAREDIR)/create_xgrid.h \ - $(SHAREDIR)/interp.h $(COREDIR)/create_vgrid.h $(TOOLSHAREDIR)/tool_util.h - -make_vgrid: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -make_vgrid.o: $(COREDIR)/make_vgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/make_vgrid.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - -create_vgrid.o: $(COREDIR)/create_vgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/create_vgrid.c diff --git a/src/tools/make_vgrid/env.gaea b/src/tools/make_vgrid/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/make_vgrid/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/make_vgrid/env.gfdl-ws b/src/tools/make_vgrid/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/make_vgrid/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/make_vgrid/env.pan b/src/tools/make_vgrid/env.pan new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/make_vgrid/env.pan @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/make_vgrid/env.zeus b/src/tools/make_vgrid/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/make_vgrid/fre-nctools.mk b/src/tools/make_vgrid/fre-nctools.mk index a0837e562c..f4ac04e3b0 100644 --- a/src/tools/make_vgrid/fre-nctools.mk +++ b/src/tools/make_vgrid/fre-nctools.mk @@ -1,5 +1,5 @@ # -# $Id: fre-nctools.mk,v 19.0 2012/01/06 22:09:48 fms Exp $ +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:34:26 fms Exp $ # ------------------------------------------------------------------------------ # FMS/FRE Project: Makefile to Build Regridding Executables # ------------------------------------------------------------------------------ @@ -10,13 +10,15 @@ # Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2010 # Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev # +include env.$(SITE) -MPICC := mpicc -CC := icc +# MPICC and CC are defined in env.$(SITE) +#MPICC := mpicc +#CC := icc CFLAGS := -O3 -g -traceback CFLAGS_O2:= -O2 -g -traceback INCLUDES := -I${NETCDF_HOME}/include -I./ -I../shared -I../../shared/mosaic -LIBS := -L${NETCDF_HOME}/lib/shared -L${HDF5_HOME}/lib/shared -lnetcdf -lhdf5_hl -lhdf5 -lz -limf +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) TARGETS := make_vgrid @@ -38,7 +40,7 @@ all: $(TARGETS) make_vgrid: $(OBJECTS) mosaic_util.o mpp.o - $(CC) -o $@ $^ $(LIBS) + $(CC) -o $@ $^ $(CLIBS) mosaic_util.o: ../../shared/mosaic/mosaic_util.c $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -c $< diff --git a/src/tools/make_vgrid/make_vgrid.c b/src/tools/make_vgrid/make_vgrid.c index 1fab97ec24..c28258037e 100644 --- a/src/tools/make_vgrid/make_vgrid.c +++ b/src/tools/make_vgrid/make_vgrid.c @@ -109,7 +109,7 @@ char *usage[] = { NULL }; char grid_version[] = "0.2"; -char tagname[] = "$Name: siena_201205_z1l $"; +char tagname[] = "$Name: tikal $"; int main(int argc, char* argv[]) { diff --git a/src/tools/mppncscatter/Makefile b/src/tools/mppncscatter/Makefile deleted file mode 100755 index a7d7a7afb0..0000000000 --- a/src/tools/mppncscatter/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -NC=/usr/local/netcdf-3.6.1 -CFLAGS=-g -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -INC=-I$(NC)/include -LIB=-L$(NC)/lib -lnetcdf -lm - -all: - $(CC) xmalloc.c -c $(CFLAGS) $(INC) - $(CC) strlist.c xmalloc.c -c $(CFLAGS) $(INC) - $(CC) mppncscatter.c strlist.o xmalloc.o -o mppncscatter $(CFLAGS) $(INC) $(LIB) -static - -test: - cd test - ../mppncscatter -x 4 -y 4 test3.nc - ../mppncscatter -x 4 -y 4 fv_core.res.tile1.nc - ../mppncscatter -x 2 -y 2 -X nx,nxp -Y ny,nyp C48_grid.tile1.nc - -clean: - rm -f *.o - cd test; rm -f *.nc.???? - diff --git a/src/tools/mppncscatter/common.h b/src/tools/mppncscatter/common.h index 6cd99771e2..b62ebe4393 100755 --- a/src/tools/mppncscatter/common.h +++ b/src/tools/mppncscatter/common.h @@ -20,14 +20,16 @@ #ifndef COMMON_H #define COMMON_H 1 -#include #include +#include #include #include #include #include #include #include +#include +#include #ifndef errno extern int errno; @@ -45,4 +47,6 @@ extern int errno; #define DEBUG 0 +#define MPPNCSCATTER_VERSION "0.3.2" + #endif /* !COMMON_H */ diff --git a/src/tools/mppncscatter/env.gaea b/src/tools/mppncscatter/env.gaea new file mode 100644 index 0000000000..5ca521ef74 --- /dev/null +++ b/src/tools/mppncscatter/env.gaea @@ -0,0 +1,3 @@ +# ORNL builds explicit fortran interface library +LIBNETCDFF := -lnetcdff +STATIC := -static diff --git a/src/tools/mppncscatter/env.gfdl-ws b/src/tools/mppncscatter/env.gfdl-ws new file mode 100644 index 0000000000..723744dad1 --- /dev/null +++ b/src/tools/mppncscatter/env.gfdl-ws @@ -0,0 +1 @@ +LIBNETCDFF := -lnetcdff diff --git a/src/tools/mppncscatter/env.pan b/src/tools/mppncscatter/env.pan new file mode 100644 index 0000000000..52cb634624 --- /dev/null +++ b/src/tools/mppncscatter/env.pan @@ -0,0 +1,4 @@ +LIBNETCDFF := -lnetcdff + +LIBS2 := +CLIBS2 := diff --git a/src/tools/mppncscatter/env.zeus b/src/tools/mppncscatter/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/mppncscatter/fre-nctools.mk b/src/tools/mppncscatter/fre-nctools.mk new file mode 100644 index 0000000000..b9cfe6b987 --- /dev/null +++ b/src/tools/mppncscatter/fre-nctools.mk @@ -0,0 +1,41 @@ +# +# $Id: fre-nctools.mk,v 19.4 2013/12/04 17:14:04 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include ./env.$(SITE) + +CC := icc +CFLAGS := -O3 -g -traceback +CFLAGS_O2:= -O2 -g -traceback +INCLUDES := -I${NETCDF_HOME}/include +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) + +TARGETS := mppncscatter + +SOURCES := mppncscatter.c opt.c scatterdim.c strlist.c xmalloc.c + +OBJECTS := $(SOURCES:c=o) + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +mppncscatter: $(OBJECTS) main.c + $(CC) -o $@ $^ $(CLIBS) $(INCLUDES) + +mppncscatter.o: mppncscatter.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + -rm -f *.o $(TARGETS) + diff --git a/src/tools/mppncscatter/main.c b/src/tools/mppncscatter/main.c new file mode 100755 index 0000000000..b210d133ba --- /dev/null +++ b/src/tools/mppncscatter/main.c @@ -0,0 +1,27 @@ +#include "opt.h" +#include "mppncscatter.h" + +/*-------------------------------------------------------------------*/ +int main(int argc, char** argv) +{ + int status; + mnsopts opts; + + status = 0; + + initmnsopts(&opts); + + /* parse command-line args. */ + status = getmnsopts(argc, argv, &opts); + + status = (status ? status : mppncscatter(&opts)); + + freemnsopts(&opts); + + if (opts.verbose) { + fprintf(stdout, "Info: Done.\n"); + fflush(stdout); + } + + return status; +} \ No newline at end of file diff --git a/src/tools/mppncscatter/mppncscatter.c b/src/tools/mppncscatter/mppncscatter.c index 848b230488..43edae0080 100755 --- a/src/tools/mppncscatter/mppncscatter.c +++ b/src/tools/mppncscatter/mppncscatter.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2007,2009-2010,2012 Remik Ziemlinski + Copyright (C) 2007,2009-2010,2012,2013 Remik Ziemlinski This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,66 +19,11 @@ 20070821 rsz Created. 20070824 rsz Works with file test3.nc (0,1,2,3,4)D variables. 20121130 rsz Fixes attributed start tile index to 1-based to be compatible with mppnccombine (thanks to Zhi Lang). + 20130303 rsz Uneven partition should use symmetric layout (instead of remainder). Added --io-layout-x/y -j/-i -n -p -w options. */ -#include -#include -#include -#include -#include -#include -#include "strlist.h" -#include "getopt.h" - -#define USAGE "\ -mppncscatter -- Decomposes single NetCDF file into many files (converse to mppnccombine). The output files are created in the current working directory and prefixed with the input file name, i.e. in.nc.0000 ...\n\ -\n\ -Usage: mppncscatter [OPTION...] in.nc\n\ -\n\ - -h, --help Give this usage message.\n\ - --usage \n\ - -s, --start N Start file name suffix numbers from N (default is 0).\n\ - -v, --version Print program version.\n\ - -V, --verbose Progressively output messages to stdout.\n\ - -x, --npx N Try to split domain evenly into N columns.\n\ - -X, --xdims d1,... List of X dimension names to scatter (for those not detectable through metadata).\n\ - -y, --npy N Try to split domain evenly into N rows.\n\ - -Y, --ydims d1,... List of Y dimension names to scatter (for those not detectable through metadata).\n\ -\n\ -Report bugs to Remik . Ziemlinski @ noaa gov.\n\ -" - -typedef struct MNSOPTS { - char* filein; /* Input filename (allocated). */ - int help; /* give usage insructions */ - int nx; /* Number of columns to split file into. (Required) */ - int ny; /* Number of rows to split file into. (Required) */ - int start; /* Start filename number suffix from this. */ - int version; /* give program version */ - int verbose; /* Verbose echos to stdout. */ - char** xdims; /* List of xdim names to scatter. */ - int xdims_len;/* Number of names in above list. */ - char** ydims; /* List of xdim names to scatter. */ - int ydims_len;/* Number of names in above list. */ -} mnsopts; - -#define NOSCATTER 0 -#define SCATTERX 1 -#define SCATTERY 2 - -int getmnsopts(int argc, char** argv, mnsopts* popts); -void printusage(); -void printversion(); -void initmnsopts(mnsopts* popts); -void freemnsopts(mnsopts* popts); -int mppncscatter(mnsopts* popts); - -#define handle_error(status) { \ - if (status != NC_NOERR) { \ - fprintf(stderr, "%s\n", nc_strerror(status)); \ - exit(-1); \ - } \ -} +#include "mppncscatter.h" +/*-------------------------------------------------------------------*/ void printsizetarray(size_t *a, int n) { int i=0; for(;i < n; ++i) @@ -86,165 +31,29 @@ void printsizetarray(size_t *a, int n) { fprintf(stdout, "\n"); } -static struct option const long_options[] = -{ - {"help", no_argument, 0, 'h'}, - {"usage", no_argument, 0, 'h'}, - {"start" , required_argument, 0, 's'}, - {"version", no_argument, 0, 'v'}, - {"verbose", no_argument, 0, 'V'}, - {"npx" , required_argument, 0, 'x'}, - {"xdims", required_argument, 0, 'X'}, - {"npy" , required_argument, 0, 'y'}, - {"ydims", required_argument, 0, 'Y'}, - {0, 0, 0, 0} -}; - -void initmnsopts(mnsopts* popts) -{ - if (popts == NULL) - return; - - popts->filein = NULL; - popts->help = 0; - popts->nx = 0; - popts->ny = 0; - popts->start = 0; - popts->verbose = 0; - popts->version = 0; - popts->xdims = NULL; - popts->xdims_len = 0; - popts->ydims = NULL; - popts->ydims_len = 0; -} -void freemnsopts(mnsopts* popts) -{ - if (popts == NULL) return; - - if (popts->filein != NULL) { - free(popts->filein); - popts->filein = NULL; - } - - if (popts->xdims != NULL) { - freestringlist(&popts->xdims, NC_MAX_DIMS); - popts->xdims = NULL; - } - - if (popts->ydims != NULL) { - freestringlist(&popts->ydims, NC_MAX_DIMS); - popts->ydims = NULL; - } +/*-------------------------------------------------------------------*/ +/* Return number of final x, y divisions depending if io_layout. */ +void get_num_divs(mnsopts* opts, int* nx, int* ny) { + if (opts == NULL) { + *nx = 0; + *ny = 0; + } else if (opts->nxio && opts->nyio) { + *nx = opts->nxio; + *ny = opts->nyio; + } else { + *nx = opts->nx; + *ny = opts->ny; + } } -void printusage() -{ - fprintf(stderr, USAGE); - fprintf(stderr, "Built with NetCDF %s\n", nc_inq_libvers()); -} -void printversion() -{ - fprintf(stderr, "mppncscatter 0.2.0\n"); - fprintf(stderr, "Built with NetCDF %s\n", nc_inq_libvers()); - fprintf(stderr, "Copyright (C) 2007,2009-2010 Remik Ziemlinski\n\ -\n\ -This program comes with NO WARRANTY, to the extent permitted by law.\n\ -You may redistribute copies of this program\n\ -under the terms of the GNU General Public License.\n"); -} -int getmnsopts(int argc, char** argv, mnsopts* popts) -{ - int c; - char *token, *cp; - const char delimiters[] = ","; - - if (popts == NULL) return -1; +/*-------------------------------------------------------------------*/ +int get_num_files(mnsopts* opts) { + int nx, ny; + if (opts == NULL) return 0; - if (newstringlist(&popts->xdims, &c, NC_MAX_DIMS)) { - printf("ERROR: Failed to allocate memory for X dimension list.\n"); - exit(1); - } - - if (newstringlist(&popts->ydims, &c, NC_MAX_DIMS)) { - printf("ERROR: Failed to allocate memory for Y dimension list.\n"); - exit(1); - } - - while ( (c = getopt_long(argc, argv, "hs:vVx:y:X:Y:", long_options, 0)) - != -1 - ) - switch (c) - { - case 's': - popts->start = atoi(optarg); - break; - - case 'x': - popts->nx = atoi(optarg); - break; - - case 'y': - popts->ny = atoi(optarg); - break; - - case 'v': - popts->version = 1; - break; - - case 'V': - popts->verbose = 1; - break; - - case ':': - fprintf(stderr, "Error, -%c without argument.\n\n", optopt); - popts->help = 1; - break; - case '?': - fprintf(stderr, "Error, Unknown argument %c.\n\n", optopt); - popts->help = 1; - break; - case 'h': - popts->help = 1; - break; - - case 'X': - getstringlist(optarg, &popts->xdims, &popts->xdims_len); - break; - - case 'Y': - getstringlist(optarg, &popts->ydims, &popts->ydims_len); - break; - } - - if (popts->help) { - printusage(); - return -1; - } - if (popts->version) { - printversion(); - return -1; - } - if (optind == argc) { - fprintf(stderr, "Error, missing operand after `%s'.\n\n", argv[argc - 1]); - printusage(); - return -1; - } - - /* get filename argument */ - argc -= optind; - argv += optind; - if ((argc < 1) || (argv[0] == NULL)) { - fprintf(stderr, "Error, input file required.\n\n"); - printusage(); - popts->filein = NULL; - return -1; - } else { - /* store filename */ - popts->filein = (char*)malloc(sizeof(char)*(strlen(argv[0]) + 1)); - strcpy(popts->filein, argv[0]); - } - - return 0; + get_num_divs(opts, &nx, &ny); + return nx*ny; } +/*-------------------------------------------------------------------*/ /* Memory copies subdomain to preallocated output pointer (either t,s,i,f,d datatype pointers). Record variables should not pass in record info in the start,count,ndim, so be sure to pass the pointers offset by 1 entry and ndim-1. @@ -432,84 +241,79 @@ void hyperslabcopy(nc_type type, size_t *dimlen, int *dimids, size_t *start, siz break; } } -//---------------------------------------------------------------------------- -// Returns dimension size for an even partitioning. -// In: -// i: Partition index (0 <= i < n). -// len: Entire length of original dimension. -// n: Number of partitions for the dimension. -size_t dimlen_even(int i, size_t len, int n) { - size_t newlen = (size_t)(len/n); - - if ( i == (n-1) ) - // Last column is remainder. - newlen = len - i*newlen; - - return newlen; - - /* NOT PRODUCTION READY. - // Is staggered? Assume yes for dim that has odd integer size. - if (len % 2) { - // Define size that will allow boundary duplication on contact edges. - if (i != (n-1)) { // If this isn't the last partition... - // Duplicate ending edge of parts except for last partition. - newlen += 1; - } else { - // Inner partition that shares edges with left and right neighbors. - newlen = len - i*newlen; - } - } else { - if ( i == (n-1) ) - // Last column is remainder. - newlen = len - i*newlen; - } - - return newlen; - */ +/*-------------------------------------------------------------------*/ +void free_scatter_dims(ScatterDim* dims[], int ndims) { + int i; + for(i=0; i < ndims; ++i) { + ScatterDim_free(dims[i]); + } } -//---------------------------------------------------------------------------- -/* scatterdims must be preallocated. Sets each array element to - NOSCATTER, SCATTERX, or SCATTERY. These tags denote if the dimension - should be scattered. +/*-------------------------------------------------------------------*/ +/* +Sets each array element to NOSCATTER, SCATTERX, or SCATTERY. +These tags denote if the dimension should be scattered. +'scatterdims' must be preallocated to size of 'ndims'. */ -void getscatterdims(int nc, int ndims, int nvars, int *scatterdims, mnsopts *opt) +void get_scatter_dims(int nc, int ndims, int nvars, ScatterDim* scatterdims[], mnsopts *opt) { int dimid, varid, status; char name[NC_MAX_NAME]; char att[256]; nc_type type; + size_t dimlen; int foundunits = 0; + scatter_t scatter_type; + int ndiv; + int recid; + + status = nc_inq_unlimdim(nc, &recid); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to query input file for record id.\n", __FILE__, __LINE__); + exit(-1); + } /* Condition for scatter dimension: Coordvar is x/y based on metadata, and shares dim name. */ for(dimid=0; dimid < ndims; ++dimid) { - scatterdims[dimid] = NOSCATTER; - + scatter_type = NOSCATTER; + dimlen = 0; + ndiv = 0; + status = nc_inq_dimname(nc, dimid, name); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query number dim name from input file.\n"); - exit(-1); + fprintf(stderr, "Error. Failed to query number dim name from input file for dimid %d.\n", dimid); + goto DIMDONE; } - - // First check user's x/y dim lists from command-line. + + if (dimid == recid) { + dimlen = NC_UNLIMITED; + goto DIMDONE; + } else { + status = nc_inq_dimlen(nc, dimid, &dimlen); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to query dim length from input file for \"%s\".\n", name); + goto DIMDONE; + } + } + + /* First check user's x/y dim lists from command-line. */ if (instringlist(opt->xdims, name, opt->xdims_len)) { - scatterdims[dimid] = SCATTERX; + scatter_type = SCATTERX; goto DIMDONE; } else if (instringlist(opt->ydims, name, opt->ydims_len)) { - scatterdims[dimid] = SCATTERY; + scatter_type = SCATTERY; goto DIMDONE; } - // Try to auto-detect if not in list from command-line. - // Check to see if coordvar is X or Y. + /* Try to auto-detect if not in list from command-line. */ + /* Check to see if coordvar is X or Y. */ status = nc_inq_varid(nc, name, &varid); if (status != NC_NOERR) { /* No variable that shares dimension name. */ - scatterdims[dimid] = NOSCATTER; goto DIMDONE; } - // If not found in user's explicit list of x/y dims, infer via metadata. + /* If not found in user's explicit list of x/y dims, infer via metadata. */ status = nc_inq_atttype(nc, varid, "units", &type); if (status == NC_NOERR) { if (type != NC_CHAR) { @@ -528,7 +332,7 @@ void getscatterdims(int nc, int ndims, int nvars, int *scatterdims, mnsopts *opt (!strncasecmp(att, "degree_e",8)) || (!strncasecmp(att, "degreee",7)) || (!strncasecmp(att, "degreese",8)) ) { - scatterdims[dimid] = SCATTERX; + scatter_type = SCATTERX; foundunits = 1; } else if ( (!strncasecmp(att, "degrees_north",13)) || @@ -537,10 +341,10 @@ void getscatterdims(int nc, int ndims, int nvars, int *scatterdims, mnsopts *opt (!strncasecmp(att, "degree_n",8)) || (!strncasecmp(att, "degreesn",8)) || (!strncasecmp(att, "degreen",7)) ) { - scatterdims[dimid] = SCATTERY; + scatter_type = SCATTERY; foundunits = 1; } else { - scatterdims[dimid] = NOSCATTER; + scatter_type = NOSCATTER; foundunits = 0; } } @@ -560,83 +364,190 @@ void getscatterdims(int nc, int ndims, int nvars, int *scatterdims, mnsopts *opt } if ( !strncasecmp(att, "x",1) ) - scatterdims[dimid] = SCATTERX; + scatter_type = SCATTERX; else if ( !strncasecmp(att, "y",1) ) - scatterdims[dimid] = SCATTERY; + scatter_type = SCATTERY; else - scatterdims[dimid] = NOSCATTER; + scatter_type = NOSCATTER; } - DIMDONE: - if (opt->verbose) - fprintf(stdout, "Dimension \"%s\" will be scattered? %s\n", name, - scatterdims[dimid] != NOSCATTER ? "Yes" : "No"); + DIMDONE: + switch(scatter_type) { + case SCATTERX: + ndiv = opt->nx; + break; + case SCATTERY: + ndiv = opt->ny; + break; + default: + ndiv = 0; + break; + } + + scatterdims[dimid] = ScatterDim_new(dimid, dimlen, name, scatter_type, ndiv); } } +/*-------------------------------------------------------------------*/ +/* +Computes the start/end indices per dim if scattered. +*/ +void get_scatter_extents(ScatterDim* scatterdims[], int ndims) { + int i, j; + ScatterDim * pdim; + + for(i=0; i < ndims; ++i) { + pdim = scatterdims[i]; + if (pdim == NULL) continue; + if (pdim->scatter_type == NOSCATTER) continue; + + mpp_compute_extent(0, pdim->len-1, pdim->scatter_ndiv, pdim->scatter_start, pdim->scatter_end); + + /* Compute lengths for scattering. */ + for(j=0; j < pdim->scatter_ndiv; ++j) { + pdim->scatter_len[j] = pdim->scatter_end[j] - pdim->scatter_start[j] + 1; + } + } +} +/*-------------------------------------------------------------------*/ +/* +Computes the start/end/len per dim if scattered using optional +io_layout mode, which must equally divide tiling. +*/ +void get_scatter_extents_iolayout(ScatterDim* scatterdims[], int ndims, int nxio, int nyio) { + int d, i, k; + ScatterDim * pdim; + size_t *startio = 0; + size_t *endio = 0; + size_t *lenio = 0; + int ndivio; + int step; + + for(d=0; d < ndims; ++d) { + pdim = scatterdims[d]; + if (pdim == NULL) continue; + if (pdim->scatter_type == NOSCATTER) continue; + + if (pdim->scatter_type == SCATTERX) { + ndivio = nxio; + } else { + ndivio = nyio; + } + + step = pdim->scatter_ndiv / ndivio; + + if (startio) XFREE(startio); + startio = XMALLOC(size_t, ndivio); + + if (endio) XFREE(endio); + endio = XMALLOC(size_t, ndivio); + + if (lenio) XFREE(lenio); + lenio = XMALLOC(size_t, ndivio); + + i = k = 0; + while (i < pdim->scatter_ndiv) { + startio[k] = pdim->scatter_start[i]; + endio[k] = pdim->scatter_end[i + step - 1]; + lenio[k] = endio[k] - startio[k] + 1; + k += 1; + i += step; + } + + pdim->scatter_ndiv = ndivio; + + if (pdim->scatter_start) XFREE(pdim->scatter_start); + pdim->scatter_start = startio; /* Own new array. */ + startio = 0; + + if (pdim->scatter_end) XFREE(pdim->scatter_end); + pdim->scatter_end = endio; /* Own new array. */ + endio = 0; + + if (pdim->scatter_len) XFREE(pdim->scatter_len); + pdim->scatter_len = lenio; /* Own new array. */ + lenio = 0; + } +} +/*-------------------------------------------------------------------*/ +void print_scatter_dims(ScatterDim* scatterdims[], int ndims) { + int d, i; + ScatterDim * pdim; + + for(d=0; d < ndims; ++d) { + pdim = scatterdims[d]; + if (pdim == NULL) continue; + + fprintf(stdout, "Info: Dimension %d \"%s\":\n", pdim->id, pdim->name); + fprintf(stdout, "Info: Will be scattered? %s\n", + (pdim->scatter_type == NOSCATTER ? "No" : "Yes") ); + + if (pdim->scatter_type == NOSCATTER) continue; + + fprintf(stdout, "Info: Scatter indices (start, end, length):"); + fflush(stdout); + + for(i=0; i < pdim->scatter_ndiv; ++i) { + fprintf(stdout, " (%zu,%zu,%zu)", pdim->scatter_start[i], pdim->scatter_end[i], pdim->scatter_len[i]); + fflush(stdout); + } + fprintf(stdout, "\n"); + } +} +/*-------------------------------------------------------------------*/ /* Define dimensions with optional scattering in new output files. */ -void defdim_even(int nc, int *ncids, int ndims, int *scatterdims, mnsopts *opt) +void def_dim(int nc, int *ncids, int ndims, ScatterDim *scatterdims[], mnsopts *opts) { int dimid, xi, yi, i, status, dummy, recid; size_t len, newlen; char name[NC_MAX_NAME]; - - status = nc_inq_unlimdim(nc, &recid); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query input file for record id.\n"); - exit(-1); - } + int nx, ny; + ScatterDim* scatdim = 0; + + get_num_divs(opts, &nx, &ny); for(dimid=0; dimid < ndims; ++dimid) { - status = nc_inq_dim(nc, dimid, name, &len); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get dim name and length from input file.\n"); - exit(-1); - } - - if (dimid == recid) - len = NC_UNLIMITED; - - for(yi=0; yi < opt->ny; ++yi) { - for(xi=0; xi < opt->nx; ++xi) { - // Index into complete enumerated list of partitions. Used in new filename. - i = yi*opt->nx + xi; + scatdim = scatterdims[dimid]; + if (scatdim == NULL) continue; + + for(yi=0; yi < ny; ++yi) { + for(xi=0; xi < nx; ++xi) { + /* Index into complete enumerated list of partitions. Used in new filename. */ + i = yi*nx + xi; - switch(scatterdims[dimid]) { + switch(scatdim->scatter_type) { case NOSCATTER: - if (opt->verbose) - fprintf(stderr, "INFO : %d : DEFDIM ncid = %d, dim = %s, len = %d\n", __LINE__, ncids[i], name, (int)len); - - status = nc_def_dim(ncids[i], name, len, &dummy); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to define dimension %s in output file %04d.\n", name, i); - exit(-1); + if (opts->verbose) { + fprintf(stdout, "Info: Defining dim \"%s\".\n", scatdim->name); + fflush(stdout); } + + if (!opts->dryrun) { + status = nc_def_dim(ncids[i], scatdim->name, scatdim->len, &dummy); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to define dimension \"%s\" in output file index %d. Aborting.\n", __FILE__, __LINE__, scatdim->name, i); + exit(-1); + } + } break; case SCATTERX: - newlen = dimlen_even(xi, len, opt->nx); - status = nc_def_dim(ncids[i], name, newlen, &dummy); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to define scattered x dim \"%s\" with length %d in output file %04d.\n", name, (int)newlen, i); - exit(-1); - } - - if (opt->verbose) - fprintf(stderr, "INFO : %d : DEFDIM ncid = %d, dim = %s, len = %d\n", __LINE__, ncids[i], name, (int)newlen); - + if (!opts->dryrun) { + status = nc_def_dim(ncids[i], scatdim->name, scatdim->scatter_len[xi], &dummy); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to define scattered x dim \"%s\" with length %d in output file index %d. Aborting.\n", __FILE__, __LINE__, scatdim->name, (int)scatdim->scatter_len[xi], i); + exit(-1); + } + } break; case SCATTERY: - newlen = dimlen_even(yi, len, opt->ny); - status = nc_def_dim(ncids[i], name, newlen, &dummy); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to define scattered y dim with length %d in output file %04d.\n", (int)newlen, i); - exit(-1); - } - - if (opt->verbose) - fprintf(stderr, "INFO : %d : DEFDIM ncid = %d, dim = %s, len = %d\n", __LINE__, ncids[i], name, (int)newlen); - + if (!opts->dryrun) { + status = nc_def_dim(ncids[i], scatdim->name, scatdim->scatter_len[yi], &dummy); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to define scattered y dim \"%s\" with length %d in output file index %d. Aborting.\n", __FILE__, __LINE__, scatdim->name, (int)scatdim->scatter_len[yi], i); + exit(-1); + } + } break; default: break; @@ -645,129 +556,131 @@ void defdim_even(int nc, int *ncids, int ndims, int *scatterdims, mnsopts *opt) } } } -void defvar_even(int nc, int *ncids, int nvars, int ndims, int *scatterdims, mnsopts *opt) +/*-------------------------------------------------------------------*/ +void def_var(int nc, int *ncids, int nvars, int ndims, ScatterDim *scatterdims[], mnsopts *opts) { - int varid, xi, yi, i, j, status, varidnew, natt, ndimvar; + int varid, xi, yi, ifile, j, status, varidnew, natt, ndimvar; size_t len, newlen; char varname[NC_MAX_NAME], attname[NC_MAX_NAME], dimname[NC_MAX_NAME]; nc_type type; int dimids[NC_MAX_DIMS]; - // Scatter attribute. - int attdata[4]; - - if (opt->verbose) - fprintf(stdout, "DEBUG : %d\n", __LINE__); - - /* The first element in the scatter attribute is always 1. */ - attdata[0] = 1; + /* Scatter attribute. */ + int scatatt[4]; + char verbose = opts->verbose; + char dryrun = opts->dryrun; + int nx, ny; + ScatterDim* scatdim = 0; + + get_num_divs(opts, &nx, &ny); + + /* + From mppnccombine: + "domain_decomposition = #0, #1, #2, #3 attribute + #0 starting position of original dimension + #1 ending position of original dimension + #2 starting position of decomposed dimension + #3 ending position of decomposed dimension + rsz: + All values are 1-based. + #0 is always 1. + #1 is the original length. + #2 is 1 based new start. + #3 is 1 based new length. + */ + scatatt[0] = 1; for(varid=0; varid < nvars; ++varid) { status = nc_inq_var(nc, varid, varname, &type, &ndimvar, dimids, &natt); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query var from input file.\n"); + fprintf(stderr, "Error: %s/%d: Failed to query var from input file. Aborting.\n", __FILE__, __LINE__); exit(-1); } - for(yi=0; yi < opt->ny; ++yi) { - for(xi=0; xi < opt->nx; ++xi) { - i = yi*opt->nx + xi; - - status = nc_def_var(ncids[i], varname, type, ndimvar, dimids, &varidnew); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to define var %s in output file %d.\n", varname, i); - exit(-1); + for(yi=0; yi < ny; ++yi) { + for(xi=0; xi < nx; ++xi) { + ifile = yi*nx + xi; + + if (!dryrun) { + status = nc_def_var(ncids[ifile], varname, type, ndimvar, dimids, &varidnew); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to define var \"%s\" in output file index %d. Aborting.\n", __FILE__, __LINE__, varname, ifile+opts->start); + exit(-1); + } + } + + if (verbose) { + fprintf(stdout, "Info: Defining variable \"%s\" for file %d.\n", varname, ifile+opts->start); + fflush(stdout); } - if (opt->verbose) - fprintf(stdout, "DEBUG : %d : Defining variable %s\n", __LINE__, varname); - /* Copy atts. */ - for(j=0; j < natt; ++j) { - status = nc_inq_attname(nc, varid, j, attname); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get name for att id %d.\n", j); - exit(-1); - } - - status = nc_copy_att(nc, varid, attname, ncids[i], varidnew); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to copy att %s to output file %d.\n", varname, i); - exit(-1); - } - } + if (!dryrun) { + for(j=0; j < natt; ++j) { + status = nc_inq_attname(nc, varid, j, attname); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to define var \"%s\" in output file index %d. Aborting.\n", __FILE__, __LINE__, varname, ifile+opts->start); + exit(-1); + } + + status = nc_copy_att(nc, varid, attname, ncids[ifile], varidnew); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to copy var \"%s\" att \"%s\" to output file index %d. Aborting.\n", __FILE__, __LINE__, varname, attname, ifile+opts->start); + exit(-1); + } + } + } - // Need to add new attribute "domain_decomposition" for - // dimension variables that are 1D. + /* Need to add new attribute "domain_decomposition" for + dimension variables that are 1D. */ if (ndimvar == 1) { - if (opt->verbose) - fprintf(stdout, "DEBUG : %d :\tscatterdims[dimids[0]] = %d\n", __LINE__, scatterdims[dimids[0]]); - - status = nc_inq_dimname(nc, dimids[0], dimname); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get dim name from input file for dim id %d.\n", dimids[0]); - exit(-1); - } - - status = nc_inq_dimlen(nc, dimids[0], &len); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get dim length from input file.\n"); - exit(-1); - } - - // Vars only dimension is scattered and var name is also the dim name. - if ( (scatterdims[dimids[0]] == SCATTERX) && - (strcmp(varname, dimname)==0) ) { - attdata[1] = (int)len; - - if (xi == 0) { - attdata[2] = 1; - } else { - newlen = dimlen_even(xi-1, len, opt->nx); - attdata[2] = (int)(xi * newlen) + 1; // 1-based syntax. + scatdim = scatterdims[dimids[0]]; + if (scatdim == NULL) continue; + + /* Vars only dimension is scattered and var name is also the dim name. */ + if ( (scatdim->scatter_type == SCATTERX) && + (strcmp(varname, scatdim->name)==0) ) { + scatatt[1] = (int)scatdim->len; + scatatt[2] = scatdim->scatter_start[xi] + 1; /* 1-based. */ + scatatt[3] = scatdim->scatter_len[xi]; + + if (verbose) { + fprintf(stdout, "Info: Adding attribute: %s:domain_decomposition = %d %d %d %d\n", varname, scatatt[0], scatatt[1], scatatt[2], scatatt[3]); + fflush(stdout); } - - newlen = dimlen_even(xi, len, opt->nx); - attdata[3] = (int)newlen; - if (opt->verbose) { - fprintf(stdout, "Adding attribute:\t%s:domain_decomposition = %d %d %d %d\n", varname, attdata[0], attdata[1], attdata[2], attdata[3]); - } - - status = nc_put_att_int(ncids[i], varid, "domain_decomposition", NC_INT, 4, attdata); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to set domain_decomposition attribute data for output file %d.\n", i); - exit(-1); - } - } else if ( (scatterdims[dimids[0]] == SCATTERY) && - (strcmp(varname, dimname)==0) ) { - attdata[1] = (int)len; - - if (yi == 0) { - attdata[2] = 1; - } else { - newlen = dimlen_even(yi-1, len, opt->ny); - attdata[2] = (int)(yi * newlen) + 1; // 1-based syntax. - } - - newlen = dimlen_even(yi, len, opt->ny); - attdata[3] = (int)newlen; + if (!dryrun) { + status = nc_put_att_int(ncids[ifile], varid, "domain_decomposition", NC_INT, 4, scatatt); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to set \"domain_decomposition\" attribute data for output file index %d. Aborting.\n", __FILE__, __LINE__, ifile+opts->start); + exit(-1); + } + } + } else if ( (scatdim->scatter_type == SCATTERY) && + (strcmp(varname, scatdim->name)==0) ) { + scatatt[1] = (int)scatdim->len; + scatatt[2] = scatdim->scatter_start[yi] + 1; + scatatt[3] = scatdim->scatter_len[yi]; - if (opt->verbose) { - fprintf(stdout, "Adding attribute:\t%s:domain_decomposition = %d %d %d %d\n", varname, attdata[0], attdata[1], attdata[2], attdata[3]); + if (verbose) { + fprintf(stdout, "Info: Adding attribute: %s:domain_decomposition = %d %d %d %d\n", varname, scatatt[0], scatatt[1], scatatt[2], scatatt[3]); + fflush(stdout); } - status = nc_put_att_int(ncids[i], varid, "domain_decomposition", NC_INT, 4, attdata); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to set domain_decomposition attribute data for variable %s output file %d.\n", varname, i); - exit(-1); - } + if (!dryrun) { + status = nc_put_att_int(ncids[ifile], varid, "domain_decomposition", NC_INT, 4, scatatt); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to set \"domain_decomposition\" attribute data for output file index %d. Aborting.\n", __FILE__, __LINE__, ifile+opts->start); + exit(-1); + } + } } } } } } } -void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mnsopts *opt) +/*-------------------------------------------------------------------*/ +void put_var(int nc, int *ncids, int ndims, int nvars, ScatterDim *scatterdims[], mnsopts *opt) { int varid, xi, yi, i, j, status, varidnew, natt, ndimvar, recid, reci, dimi; size_t dimlen[NC_MAX_DIMS], size; @@ -775,8 +688,10 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns size_t outstart[4] = {0,0,0,0}; size_t count[4], newlen; size_t nrec = 0; + size_t maxsize[5] = {0,0,0,0,0}; /* Array of maxsizes for each datatype. */ - enum maxsizeindex {CHAR=0,SHORT,INT,FLOAT,DOUBLE} ; + enum maxsizeindex {CHAR=0,SHORT,INT,FLOAT,DOUBLE}; + char varname[NC_MAX_NAME], attname[NC_MAX_NAME], dimname[NC_MAX_NAME]; nc_type type; int dimids[NC_MAX_DIMS]; @@ -785,17 +700,23 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns int *ip, *oip; float *fp, *ofp; double *dp, *odp; + ScatterDim *scatdim = 0; + int nx, ny; + if (opt->dryrun) return; + + get_num_divs(opt, &nx, &ny); + status = nc_inq_unlimdim(nc, &recid); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query input file for record id.\n"); + fprintf(stderr, "Error. Failed to query input file for record id. Aborting.\n"); exit(-1); } if (recid != -1) { status = nc_inq_dimlen(nc, recid, &nrec); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to number of records from input file.\n"); + fprintf(stderr, "Error. Failed to number of records from input file. Aborting.\n"); exit(-1); } } @@ -803,7 +724,7 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns for(i=0; i < ndims; ++i) { status = nc_inq_dimlen(nc, i, &dimlen[i]); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query dim length for dim id %d in input file.\n", i); + fprintf(stderr, "Error. Failed to query dim length for dim id %d in input file. Aborting.\n", i); exit(-1); } } @@ -812,7 +733,7 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns for(varid=0; varid < nvars; ++varid) { status = nc_inq_var(nc, varid, varname, &type, &ndimvar, dimids, &natt); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query var id %d in input file.\n", varid); + fprintf(stderr, "Error. Failed to query var id %d in input file. Aborting.\n", varid); exit(-1); } @@ -867,7 +788,7 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns for(varid=0; varid < nvars; ++varid) { status = nc_inq_var(nc, varid, varname, &type, &ndimvar, dimids, &natt); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query var id %d in input file.\n", varid); + fprintf(stderr, "Error. Failed to query var id %d in input file. Aborting.\n", varid); exit(-1); } @@ -878,177 +799,166 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns continue; if (opt->verbose) { - fprintf(stdout, "Reading data for static variable %s.\n", varname); + fprintf(stdout, "Info: Reading data for static variable \"%s\".\n", varname); + fflush(stdout); } - switch(type) { - case NC_BYTE: case NC_CHAR: - status = nc_get_var_text(nc, varid, tp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get var %s char data from input file.\n", varname); - exit(-1); - } - break; - case NC_SHORT: - status = nc_get_var_short(nc, varid, sp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get var %s short data from input file.\n", varname); - exit(-1); - } - break; - case NC_INT: - status = nc_get_var_int(nc, varid, ip); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get var %s int data from input file.\n", varname); - exit(-1); - } - break; - case NC_FLOAT: - status = nc_get_var_float(nc, varid, fp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get var %s float data from input file.\n", varname); - exit(-1); - } - break; - case NC_DOUBLE: - status = nc_get_var_double(nc, varid, dp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get var %s double data from input file.\n", varname); - exit(-1); - } - break; - default: - fprintf(stderr, "Error. Unknown data type for var %s.\n", varname); - break; - } - - for(yi=0; yi < opt->ny; ++yi) { - for(xi=0; xi < opt->nx; ++xi) { - i = yi*opt->nx + xi; + switch(type) { + case NC_BYTE: case NC_CHAR: + status = nc_get_var_text(nc, varid, tp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to get var %s char data from input file.\n", varname); + exit(-1); + } + break; + case NC_SHORT: + status = nc_get_var_short(nc, varid, sp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to get var %s short data from input file.\n", varname); + exit(-1); + } + break; + case NC_INT: + status = nc_get_var_int(nc, varid, ip); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to get var %s int data from input file.\n", varname); + exit(-1); + } + break; + case NC_FLOAT: + status = nc_get_var_float(nc, varid, fp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to get var %s float data from input file.\n", varname); + exit(-1); + } + break; + case NC_DOUBLE: + status = nc_get_var_double(nc, varid, dp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to get var %s double data from input file.\n", varname); + exit(-1); + } + break; + default: + fprintf(stderr, "Error. Unknown data type for var %s.\n", varname); + break; + } + + for(yi=0; yi < ny; ++yi) { + for(xi=0; xi < nx; ++xi) { + i = yi*nx + xi; if (ndimvar > 0) { for(dimi=0; dimi < ndimvar; ++dimi) { - switch(scatterdims[dimids[dimi]]) { + scatdim = scatterdims[dimids[dimi]]; + if (scatdim == NULL) continue; + + switch(scatdim->scatter_type) { case NOSCATTER: instart[dimi] = 0; - count[dimi] = dimlen[dimids[dimi]]; + count[dimi] = scatdim->len; break; case SCATTERX: - if (xi == 0) { - newlen = dimlen_even(xi, dimlen[dimids[dimi]], opt->nx); - instart[dimi] = 0; - } else { - newlen = dimlen_even(xi-1, dimlen[dimids[dimi]], opt->nx); - instart[dimi] = newlen*xi; - - } - count[dimi] = newlen; - break; - + instart[dimi] = scatdim->scatter_start[xi]; + count[dimi] = scatdim->scatter_len[xi]; + break; case SCATTERY: - if (yi == 0) { - newlen = dimlen_even(yi, dimlen[dimids[dimi]], opt->ny); - instart[dimi] = 0; - } else { - newlen = dimlen_even(yi-1, dimlen[dimids[dimi]], opt->ny); - instart[dimi] = newlen*yi; - - } - count[dimi] = newlen; + instart[dimi] = scatdim->scatter_start[yi]; + count[dimi] = scatdim->scatter_len[yi]; break; } } if (opt->verbose) { - fprintf(stdout, "\tvar = %s\n", varname); - fprintf(stdout, "\tstart = "); + fprintf(stdout, "Info: Performing hyperslab copy into file %d.\n", i+opt->start); + fprintf(stdout, "Info: var = \"%s\"\n", varname); + fprintf(stdout, "Info: start = "); printsizetarray(instart, ndimvar); - fprintf(stdout, "\tcount = "); + fprintf(stdout, "Info: count = "); printsizetarray(count, ndimvar); - fprintf(stdout, "\toutstart = "); - printsizetarray(outstart, ndimvar); - fprintf(stdout, "Performing hyperslab copy into tile %d.\n", i); + fprintf(stdout, "Info: outstart = "); + printsizetarray(outstart, ndimvar); + fflush(stdout); } - hyperslabcopy(type, dimlen, dimids, instart, count, ndimvar, tp, sp, ip, fp, dp, otp, osp, oip, ofp, odp); + hyperslabcopy(type, dimlen, dimids, instart, count, ndimvar, tp, sp, ip, fp, dp, otp, osp, oip, ofp, odp); - switch(type) { - case NC_BYTE: case NC_CHAR: - status = nc_put_vara_text(ncids[i], varid, outstart, count, otp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put var \"%s\" char data into output file %d.\n", varname, i); - handle_error(status); - } - break; - case NC_SHORT: - status = nc_put_vara_short(ncids[i], varid, outstart, count, osp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put var \"%s\" short data into output file %d.\n", varname, i); - handle_error(status); - } - break; - case NC_INT: - status = nc_put_vara_int(ncids[i], varid, outstart, count, oip); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put var \"%s\" int data into output file %d.\n", varname, i); - handle_error(status); - } - break; - case NC_FLOAT: - status = nc_put_vara_float(ncids[i], varid, outstart, count, ofp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put var \"%s\" float data into output file %d.\n", varname, i); - handle_error(status); - } - break; - case NC_DOUBLE: - status = nc_put_vara_double(ncids[i], varid, outstart, count, odp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put var \"%s\" double data into output file %d.\n", varname, i); - handle_error(status); - } - break; - } - } else { - /* Scalar variable. */ - switch(type) { - case NC_BYTE: case NC_CHAR: - status = nc_put_var_text(ncids[i], varid, tp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put scalar var %s text data into output file %d.\n", varname, i); - exit(-1); - } - break; - case NC_SHORT: - status = nc_put_var_short(ncids[i], varid, sp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put scalar var %s short data into output file %d.\n", varname, i); - exit(-1); - } - break; - case NC_INT: - status = nc_put_var_int(ncids[i], varid, ip); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put scalar var %s int data into output file %d.\n", varname, i); - exit(-1); - } - break; - case NC_FLOAT: - status = nc_put_var_float(ncids[i], varid, fp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put scalar var %s float data into output file %d.\n", varname, i); - exit(-1); - } - break; - case NC_DOUBLE: - status = nc_put_var_double(ncids[i], varid, dp); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to put scalar var %s double data into output file %d.\n", varname, i); - exit(-1); - } - break; - } - } + switch(type) { + case NC_BYTE: case NC_CHAR: + status = nc_put_vara_text(ncids[i], varid, outstart, count, otp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put var \"%s\" char data into output file %d.\n", varname, i); + handle_error(status); + } + break; + case NC_SHORT: + status = nc_put_vara_short(ncids[i], varid, outstart, count, osp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put var \"%s\" short data into output file %d.\n", varname, i); + handle_error(status); + } + break; + case NC_INT: + status = nc_put_vara_int(ncids[i], varid, outstart, count, oip); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put var \"%s\" int data into output file %d.\n", varname, i); + handle_error(status); + } + break; + case NC_FLOAT: + status = nc_put_vara_float(ncids[i], varid, outstart, count, ofp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put var \"%s\" float data into output file %d.\n", varname, i); + handle_error(status); + } + break; + case NC_DOUBLE: + status = nc_put_vara_double(ncids[i], varid, outstart, count, odp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put var \"%s\" double data into output file %d.\n", varname, i); + handle_error(status); + } + break; + } + } else { /* Scalar variable. */ + switch(type) { + case NC_BYTE: case NC_CHAR: + status = nc_put_var_text(ncids[i], varid, tp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put scalar var \"%s\" text data into output file %d.\n", varname, i); + exit(-1); + } + break; + case NC_SHORT: + status = nc_put_var_short(ncids[i], varid, sp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put scalar var \"%s\" short data into output file %d.\n", varname, i); + exit(-1); + } + break; + case NC_INT: + status = nc_put_var_int(ncids[i], varid, ip); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put scalar var \"%s\" int data into output file %d.\n", varname, i); + exit(-1); + } + break; + case NC_FLOAT: + status = nc_put_var_float(ncids[i], varid, fp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put scalar var \"%s\" float data into output file %d.\n", varname, i); + exit(-1); + } + break; + case NC_DOUBLE: + status = nc_put_var_double(ncids[i], varid, dp); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to put scalar var \"%s\" double data into output file %d.\n", varname, i); + exit(-1); + } + break; + } + } } } } @@ -1079,8 +989,10 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns } } - if (opt->verbose) - fprintf(stdout, "Reading variable %s, record %d.\n", varname, reci); + if (opt->verbose) { + fprintf(stdout, "Info: Reading variable \"%s\", record %d.\n", varname, reci); + fflush(stdout); + } /*printsizetarray(instart, ndimvar); printsizetarray(count, ndimvar);*/ @@ -1126,50 +1038,49 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns break; } - for(yi=0; yi < opt->ny; ++yi) { - for(xi=0; xi < opt->nx; ++xi) { - i = yi*opt->nx + xi; + for(yi=0; yi < ny; ++yi) { + for(xi=0; xi < nx; ++xi) { + i = yi*nx + xi; for(dimi=1; dimi < ndimvar; ++dimi) { - switch(scatterdims[dimids[dimi]]) { + scatdim = scatterdims[dimids[dimi]]; + if (scatdim == NULL) continue; + + switch(scatdim->scatter_type) { case NOSCATTER: instart[dimi] = 0; - count[dimi] = dimlen[dimids[dimi]]; + count[dimi] = scatdim->len; break; case SCATTERX: - if (xi == 0) { - newlen = dimlen_even(xi, dimlen[dimids[dimi]], opt->nx); - instart[dimi] = 0; - } else { - newlen = dimlen_even(xi-1, dimlen[dimids[dimi]], opt->nx); - instart[dimi] = newlen*xi; - - } - count[dimi] = newlen; - break; - + instart[dimi] = scatdim->scatter_start[xi]; + count[dimi] = scatdim->scatter_len[xi]; + break; case SCATTERY: - if (yi == 0) { - newlen = dimlen_even(yi, dimlen[dimids[dimi]], opt->ny); - instart[dimi] = 0; - } else { - newlen = dimlen_even(yi-1, dimlen[dimids[dimi]], opt->ny); - instart[dimi] = newlen*yi; - - } - count[dimi] = newlen; + instart[dimi] = scatdim->scatter_start[yi]; + count[dimi] = scatdim->scatter_len[yi]; break; - } } - if (opt->verbose) - fprintf(stdout, "Dicing variable %s, record %d\n", varname, reci); + if (opt->verbose) { + fprintf(stdout, "Info: Performing hyperslab copy into file %d.\n", i+opt->start); + fprintf(stdout, "Info: var = \"%s\"\n", varname); + fprintf(stdout, "Info: start = "); + printsizetarray(instart, ndimvar); + fprintf(stdout, "Info: count = "); + printsizetarray(count, ndimvar); + fprintf(stdout, "Info: outstart = "); + printsizetarray(outstart, ndimvar); + fflush(stdout); + } hyperslabcopy(type, dimlen, dimids, instart, count, ndimvar == 1?0:ndimvar, tp, sp, ip, fp, dp, otp, osp, oip, ofp, odp); - if (opt->verbose) - fprintf(stdout, "Writing variable %s, record %d\n", varname, reci); + if (opt->verbose) { + fprintf(stdout, "Info: Writing variable \"%s\", record %d\n", varname, reci); + fflush(stdout); + } + switch(type) { case NC_BYTE: case NC_CHAR: status = nc_put_vara_text(ncids[i], varid, outstart, count, otp); @@ -1223,10 +1134,98 @@ void putvar_even(int nc, int *ncids, int ndims, int nvars, int *scatterdims, mns free( dp); free(odp); } -int mppncscatter(mnsopts* popts) +/*-------------------------------------------------------------------*/ +void scatter_dims(int nc, int ndims, int nvars, ScatterDim* scatterdims[], mnsopts* opt) { + /* Populate scatter types and num divisions. */ + get_scatter_dims(nc, ndims, nvars, scatterdims, opt); + + /* Compute scatter indices. */ + get_scatter_extents(scatterdims, ndims); + + /* Convert to io_layout. */ + if (opt->nxio && opt->nyio) { + if (opt->nx % opt->nxio) { + fprintf(stderr, "Error: x divisions are not wholly divisble by io-layout x divisions (%d/%d=%g). Aborting.\n", opt->nx, opt->nxio, ((float)opt->nx)/opt->nxio); + exit(1); + } + + if (opt->ny % opt->nyio) { + fprintf(stderr, "Error: y divisions are not wholly divisble by io-layout y divisions (%d/%d=%g). Aborting.\n", opt->ny, opt->nyio, ((float)opt->ny)/opt->nyio); + exit(1); + } + + get_scatter_extents_iolayout(scatterdims, ndims, opt->nxio, opt->nyio); + } + + if (opt->verbose) { + print_scatter_dims(scatterdims, ndims); + } +} +/*-------------------------------------------------------------------*/ +/* +In: + isg: Start index for all tiles. + ieg: End index for all tiles. + ndivs: Number of tiles. + +Out: + start: Start indices of symmetric tiling. + Must be pre-allocated array of size ndivs. + end: End indices of symmetric tiling. + Must be pre-allocated array of size ndivs. +*/ +void mpp_compute_extent(size_t isg, size_t ieg, size_t ndivs, size_t* start, size_t* end) { + size_t n = ieg - isg + 1; + size_t iss = isg; + size_t ndiv, imax, ndmax, ie, ndmirror; + char symmetrize; + + for(ndiv=0; ndiv < ndivs; ++ndiv) { + symmetrize = ( EVEN(ndivs) && EVEN(n) ) || + ( ODD(ndivs) && ODD(n) ) || + ( ODD(ndivs) && EVEN(n) && (ndivs < (n/2)) ); + + if (ndiv == 0) { + imax = ieg; + ndmax = ndivs; + } + + if ( ndiv < ((ndivs-1)/2+1) ) { + ie = iss + ceil( ((float)(imax-iss+1.0))/(ndmax-ndiv) ) - 1; + ndmirror = (ndivs-1) - ndiv; + if ( (ndmirror > ndiv) && symmetrize) { + start[ndmirror] = MAX( isg+ieg-ie, ie+1 ); + end[ndmirror] = MAX( isg+ieg-iss, ie+1 ); + imax = start[ndmirror] - 1; + ndmax = ndmax - 1; + } + } else { + if (symmetrize) { + iss = start[ndiv]; + ie = end[ndiv]; + } else { + ie = iss + ceil( ((float)(imax-iss+1.0))/(ndmax-ndiv) ) - 1; + } + } + + start[ndiv] = iss; + end[ndiv] = ie; + + if (ie < iss) { + fprintf(stderr, "Error: %s/%d: domain extents must be positive definite. \"ie\"=%zu, \"iss\"=%zu\n", __FILE__, __LINE__, ie, iss); + } + if ( (ndiv == (ndivs-1)) && (end[ndiv] != ieg) ) { + fprintf(stderr, "Error: %s/%d: domain extents do not span space completely.\n", __FILE__, __LINE__); + } + + iss = ie + 1; + } +} +/*-------------------------------------------------------------------*/ +int mppncscatter(mnsopts* opts) { int status = 0; - int nfiles = popts->nx * popts->ny; + int nfiles = 0; /* number of output files. */ int nc; /* input file id. */ int *ncids = NULL; /* store ncid for output files. */ int i,j,k; @@ -1237,15 +1236,15 @@ int mppncscatter(mnsopts* popts) int natts, ngatts, ndims, nvars, unlimdimid; nc_type type; size_t len; - int scatterdims[NC_MAX_DIMS]; - int *scatterlenx = NULL; - int *scatterleny = NULL; /* Stores subdomain dim sizes for each output file. */ + ScatterDim * scatterdims[NC_MAX_DIMS]; char name[NC_MAX_NAME]; - - ncids = (int*)malloc(sizeof(int)*nfiles); - + char outnameformat[256]; /* Format string for creating out filenames. */ + char dryrun = opts->dryrun; + char verbose = opts->verbose; + + /*-------------------------------------------------*/ /* Strip path in file name for output file names. */ - prefix = popts->filein; + prefix = opts->filein; pchar = strstr(prefix, "/"); if (pchar != NULL) { do { @@ -1253,110 +1252,157 @@ int mppncscatter(mnsopts* popts) } while(pchar = strstr(prefix, "/")); } - status = nc_open(popts->filein, NC_NOWRITE, &nc); + /*-------------------------------------------------*/ + /* Get basic input file info. */ + status = nc_open(opts->filein, NC_NOWRITE, &nc); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to open input file.\n"); + fprintf(stderr, "Error: %s/%d: Failed to open input file \"%s\". Aborting.\n", __FILE__, __LINE__, opts->filein); return -1; } status = nc_inq(nc, &ndims, &nvars, &ngatts, &unlimdimid); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query general info for input file.\n"); + fprintf(stderr, "Error: %s/%d: Failed to query general info for input file. Aborting.\n", __FILE__, __LINE__); return -1; } status = nc_inq_format(nc, &format); if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to query input file format.\n"); + fprintf(stderr, "Error: %s/%d: Failed to query input file format. Aborting.\n", __FILE__, __LINE__); return -1; } + switch(format) { + case NC_FORMAT_64BIT: + format = NC_64BIT_OFFSET; + break; + case NC_FORMAT_NETCDF4: + format = NC_NETCDF4; + break; + case NC_FORMAT_NETCDF4_CLASSIC: + format = NC_CLASSIC_MODEL | NC_NETCDF4; + break; + case NC_FORMAT_CLASSIC: + default: + format = 0; + break; + } + + /*-------------------------------------------------*/ + if (opts->prefix) + i = strlen(opts->prefix); + else + i = 0; + + sprintf(outnameformat, "%s%s%%s.%%0%dd", ((i>0) ? opts->prefix : ""), ((i>0) ? "/" : ""), opts->width); + + /*-------------------------------------------------*/ + scatter_dims(nc, ndims, nvars, scatterdims, opts); + + nfiles = get_num_files(opts); + ncids = XMALLOC(int, nfiles); + for(i=0; i < nfiles; ++i) { - if (sprintf(output, "%s.%04d", prefix, i+popts->start) < 1) { - fprintf(stderr, "Error. Failed to create output file name.\n"); - return -1; - } - status = nc_create(output, NC_CLOBBER | format, &ncids[i]); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to create output file %s.\n", output); - return -1; - } - status = nc_set_fill(ncids[i], NC_NOFILL, &dummy); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to disable prefill for output file %s.\n", output); - return -1; - } - - status = nc_put_att_int(ncids[i], NC_GLOBAL, "NumFilesInSet", NC_INT, 1, &nfiles); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to add global attribute \"NumFilesInSet\" to output file %s.\n", output); + if (sprintf(output, outnameformat, prefix, i+opts->start) < 1) { + fprintf(stderr, "Error: %s/%d: Failed to create output file name. Aborting.\n", __FILE__, __LINE__); return -1; } + + if (verbose) { + fprintf(stdout, "Info: Creating file \"%s\".\n", output); + fflush(stdout); + } + + if (!dryrun) { + status = nc_create(output, NC_CLOBBER | format, &ncids[i]); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to create output file \"%s\". Aborting.\n", __FILE__, __LINE__, output); + return -1; + } + + status = nc_set_fill(ncids[i], NC_NOFILL, &dummy); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to disable prefill for output file \"%s\". Aborting.\n", __FILE__, __LINE__, output); + return -1; + } + + status = nc_put_att_int(ncids[i], NC_GLOBAL, "NumFilesInSet", NC_INT, 1, &nfiles); + if (status != NC_NOERR) { + fprintf(stderr, "Error: %s/%d: Failed to add global attribute \"NumFilesInSet\" to output file \"%s\". Aborting.\n", __FILE__, __LINE__, output); + return -1; + } + } } + /*-------------------------------------------------------*/ /* Copy all global attributes. */ - for(j=0; j < ngatts; ++j) { - for(i=0; i < nfiles; ++i) { - status = nc_inq_attname(nc, NC_GLOBAL, j, name); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to get global attribute name from input file.\n"); - return -1; - } - - status = nc_copy_att(nc, NC_GLOBAL, name, ncids[i], NC_GLOBAL); - if (status != NC_NOERR) { - fprintf(stderr, "Error. Failed to copy global attribute to output file %04d.\n", i); - return -1; - } - } + if (!dryrun) { + for(j=0; j < ngatts; ++j) { + for(i=0; i < nfiles; ++i) { + status = nc_inq_attname(nc, NC_GLOBAL, j, name); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to get global attribute name from input file.\n"); + return -1; + } + + status = nc_copy_att(nc, NC_GLOBAL, name, ncids[i], NC_GLOBAL); + if (status != NC_NOERR) { + fprintf(stderr, "Error. Failed to copy global attribute to output file %04d.\n", i); + return -1; + } + } + } + } + + if (verbose) { + fprintf(stdout, "Info: Defining output dimensions.\n"); + fflush(stdout); } + + def_dim(nc, ncids, ndims, scatterdims, opts); - getscatterdims(nc, ndims, nvars, scatterdims, popts); - - if (popts->verbose) - fprintf(stdout, "Defining output dimensions.\n"); - - defdim_even(nc, ncids, ndims, scatterdims, popts); - - if (popts->verbose) - fprintf(stdout, "Defining output variables.\n"); - - defvar_even(nc, ncids, nvars, ndims, scatterdims, popts); - - if (popts->verbose) - fprintf(stdout, "Ending define mode.\n"); - - for(i=0; i < nfiles; ++i) - nc_enddef(ncids[i]); + if (verbose) { + fprintf(stdout, "Info: Defining output variables.\n"); + fflush(stdout); + } + + def_var(nc, ncids, nvars, ndims, scatterdims, opts); - putvar_even(nc, ncids, ndims, nvars, scatterdims, popts); + if (verbose) { + fprintf(stdout, "Info: Ending define mode.\n"); + fflush(stdout); + } + + if (!dryrun) { + for(i=0; i < nfiles; ++i) + nc_enddef(ncids[i]); + } + + put_var(nc, ncids, ndims, nvars, scatterdims, opts); + if (verbose) { + fprintf(stdout, "Info: Closing files.\n"); + fflush(stdout); + } + nc_close(nc); - for(i=0; i < nfiles; ++i) - nc_close(ncids[i]); + + if (!dryrun) { + for(i=0; i < nfiles; ++i) + nc_close(ncids[i]); + } + + if (verbose) { + fprintf(stdout, "Info: Freeing memory.\n"); + fflush(stdout); + } if (ncids != NULL) free(ncids); + free_scatter_dims(scatterdims, ndims); + return 0; } -int -main(int argc, char** argv) -{ - int status; - mnsopts opts; - - status = 0; - initmnsopts(&opts); - - /* parse command-line args. */ - status = getmnsopts(argc, argv, &opts); - - status = status ? status : mppncscatter(&opts); - - freemnsopts(&opts); - - return status; -} diff --git a/src/tools/mppncscatter/mppncscatter.h b/src/tools/mppncscatter/mppncscatter.h new file mode 100755 index 0000000000..d4b2f4c8fd --- /dev/null +++ b/src/tools/mppncscatter/mppncscatter.h @@ -0,0 +1,49 @@ +#ifndef MPPNCSCATTER_H +#define MPPNCSCATTER_H + +#include "strlist.h" +#include "opt.h" +#include "scatterdim.h" +#include "util.h" + +/*-------------------------------------------------------------------*/ +#define handle_error(status) { \ + if (status != NC_NOERR) { \ + fprintf(stderr, "%s\n", nc_strerror(status)); \ + exit(-1); \ + } \ +} + +void def_dim(int nc, int *ncids, int ndims, ScatterDim *scatterdims[], mnsopts *opts); + +void def_var(int nc, int *ncids, int nvars, int ndims, ScatterDim *scatterdims[], mnsopts *opts); + +void free_scatter_dims(ScatterDim* dims[], int ndims); + +int get_num_files(mnsopts* opts); + +void get_num_divs(mnsopts* opts, int* nx, int* ny); + +void get_scatter_dims(int nc, int ndims, int nvars, ScatterDim* scatterdims[], mnsopts *opt); + +void get_scatter_extents(ScatterDim* scatterdims[], int ndims); + +void get_scatter_extents_iolayout(ScatterDim* scatterdims[], int ndims, int nxio, int nyio); + +void hyperslabcopy(nc_type type, size_t *dimlen, int *dimids, size_t *start, size_t *count, int ndim, char *ti, short *si, int *ii, float *fi, double *di, char *t, short *s, int *i, float *f, double *d); + +void mpp_compute_extent(size_t isg, size_t ieg, size_t ndivs, size_t* start, size_t* end); + +int mppncscatter(mnsopts* popts); + +void print_scatter_dims(ScatterDim* scatterdims[], int ndims); + +void printsizetarray(size_t *a, int n); + +void put_var(int nc, int *ncids, int ndims, int nvars, ScatterDim *scatterdims[], mnsopts *opt); + +void scatter_dims(int nc, int ndims, int nvars, ScatterDim* scatterdims[], mnsopts* opt); + +/*-------------------------------------------------------------------*/ + +#endif /* MPPNCSCATTER_H */ \ No newline at end of file diff --git a/src/tools/mppncscatter/opt.c b/src/tools/mppncscatter/opt.c new file mode 100755 index 0000000000..5d6a2c7e12 --- /dev/null +++ b/src/tools/mppncscatter/opt.c @@ -0,0 +1,186 @@ +#include "opt.h" + +/*-------------------------------------------------------------------*/ +void initmnsopts(mnsopts* popts) +{ + if (popts == NULL) + return; + + popts->dryrun = 0; + popts->filein = NULL; + popts->help = 0; + popts->nx = 0; + popts->ny = 0; + popts->nxio = 0; + popts->nyio = 0; + popts->prefix = 0; + popts->start = 0; + popts->verbose = 0; + popts->version = 0; + popts->width = 4; + popts->xdims = NULL; + popts->xdims_len = 0; + popts->ydims = NULL; + popts->ydims_len = 0; +} +/*-------------------------------------------------------------------*/ +void freemnsopts(mnsopts* popts) +{ + if (popts == NULL) return; + + if (popts->filein != NULL) { + free(popts->filein); + popts->filein = NULL; + } + + if (popts->prefix != NULL) { + free(popts->prefix); + popts->prefix = NULL; + } + + if (popts->xdims != NULL) { + freestringlist(&popts->xdims, NC_MAX_DIMS); + popts->xdims = NULL; + } + + if (popts->ydims != NULL) { + freestringlist(&popts->ydims, NC_MAX_DIMS); + popts->ydims = NULL; + } +} +/*-------------------------------------------------------------------*/ +void printusage() +{ + fprintf(stderr, USAGE); + printversion(); +} +/*-------------------------------------------------------------------*/ +void printversion() +{ + fprintf(stderr, "mppncscatter %s\n", MPPNCSCATTER_VERSION); + fprintf(stderr, "Built with NetCDF %s\n", nc_inq_libvers()); + fprintf(stderr, "Copyright (C) 2007,2009-2010,2013 Remik Ziemlinski\n\ +\n\ +This program comes with NO WARRANTY, to the extent permitted by law.\n\ +You may redistribute copies of this program\n\ +under the terms of the GNU General Public License.\n"); +} +/*-------------------------------------------------------------------*/ +int getmnsopts(int argc, char** argv, mnsopts* popts) +{ + int c; + char *token, *cp; + const char delimiters[] = ","; + int len = 0; + + if (popts == NULL) return -1; + + if (newstringlist(&popts->xdims, &c, NC_MAX_DIMS)) { + printf("ERROR: Failed to allocate memory for X dimension list.\n"); + exit(1); + } + + if (newstringlist(&popts->ydims, &c, NC_MAX_DIMS)) { + printf("ERROR: Failed to allocate memory for Y dimension list.\n"); + exit(1); + } + + while ( (c = getopt_long(argc, argv, "hi:j:np:s:vVw:x:y:X:Y:", long_options, 0)) + != -1 + ) + switch (c) + { + case 'i': + popts->nxio = atoi(optarg); + break; + + case 'j': + popts->nyio = atoi(optarg); + break; + + case 'n': + popts->dryrun = 1; + break; + + case 'p': + len = strlen(optarg); + popts->prefix = (char*)malloc(len+1); + strcpy(popts->prefix, optarg); + + case 's': + popts->start = atoi(optarg); + break; + + case 'x': + popts->nx = atoi(optarg); + break; + + case 'y': + popts->ny = atoi(optarg); + break; + + case 'v': + popts->version = 1; + break; + + case 'V': + popts->verbose = 1; + break; + + case 'w': + popts->width = atoi(optarg); + break; + + case ':': + fprintf(stderr, "Error, -%c without argument.\n\n", optopt); + popts->help = 1; + break; + + case '?': + fprintf(stderr, "Error, Unknown argument %c.\n\n", optopt); + popts->help = 1; + break; + + case 'h': + popts->help = 1; + break; + + case 'X': + getstringlist(optarg, &popts->xdims, &popts->xdims_len); + break; + + case 'Y': + getstringlist(optarg, &popts->ydims, &popts->ydims_len); + break; + } + + if (popts->help) { + printusage(); + return -1; + } + if (popts->version) { + printversion(); + return -1; + } + if (optind == argc) { + fprintf(stderr, "Error, missing operand after `%s'.\n\n", argv[argc - 1]); + printusage(); + return -1; + } + + /* get filename argument */ + argc -= optind; + argv += optind; + if ((argc < 1) || (argv[0] == NULL)) { + fprintf(stderr, "Error, input file required.\n\n"); + printusage(); + popts->filein = NULL; + return -1; + } else { + /* store filename */ + popts->filein = (char*)malloc(sizeof(char)*(strlen(argv[0]) + 1)); + strcpy(popts->filein, argv[0]); + } + + return 0; +} \ No newline at end of file diff --git a/src/tools/mppncscatter/opt.h b/src/tools/mppncscatter/opt.h new file mode 100755 index 0000000000..5572a2041b --- /dev/null +++ b/src/tools/mppncscatter/opt.h @@ -0,0 +1,80 @@ +#ifndef MPPNCSCATTER_OPT_H +#define MPPNCSCATTER_OPT_H + +#include "getopt.h" +#include "common.h" + +/*-------------------------------------------------------------------*/ +#define USAGE "\ +mppncscatter -- Decomposes single NetCDF file into many files (converse to mppnccombine). The output files are created in the current working directory by default and prefixed with the input file name, i.e. in.nc.0000 ...\n\ +\n\ +Usage: mppncscatter [OPTION...] in.nc\n\ +\n\ + -h, --help Give this usage message.\n\ + --usage \n\ + -i, --io-layout-x N Set io-layout for X dimension.\n\ + -j, --io-layout-y N Set io-layout for Y dimension.\n\ + -n, --dry-run Run without writing files.\n\ + -p, --prefix PATH Prefix path for output files.\n\ + -s, --start N Start file name suffix numbers from N (default is 0).\n\ + -V, --verbose Progressively output messages to stdout.\n\ + -v, --version Print program version.\n\ + -w, --width N Width for output filename suffix digits.\n\ + -w 4 (default) creates in.nc.0000 ...\n\ + -x, --npx N Try to split domain evenly into N columns.\n\ + -X, --xdims d1,... List of X dimension names to scatter\n\ + (for those not detectable through metadata).\n\ + -y, --npy N Try to split domain evenly into N rows.\n\ + -Y, --ydims d1,... List of Y dimension names to scatter\n\ + (for those not detectable through metadata).\n\ +\n\ +Report bugs to Remik . Ziemlinski @ noaa . gov.\n\ +" +/*-------------------------------------------------------------------*/ +typedef struct MNSOPTS { + char dryrun; /* If should do dry run. */ + char* filein; /* Input filename (allocated). */ + int help; /* give usage insructions */ + int nx; /* Number of columns to split file into. (Required) */ + int ny; /* Number of rows to split file into. (Required) */ + int nxio; /* io-layout for x dims. */ + int nyio; /* io-layout for y dims. */ + char* prefix; /* Output prefix. */ + int start; /* Start filename number suffix from this. */ + int version; /* give program version */ + int verbose; /* Verbose echos to stdout. */ + int width; /* Width of output filename digit suffix. */ + char** xdims; /* List of xdim names to scatter. */ + int xdims_len;/* Number of names in above list. */ + char** ydims; /* List of xdim names to scatter. */ + int ydims_len;/* Number of names in above list. */ +} mnsopts; + +int getmnsopts(int argc, char** argv, mnsopts* popts); +void printusage(void); +void printversion(void); +void initmnsopts(mnsopts* popts); +void freemnsopts(mnsopts* popts); + +/*-------------------------------------------------------------------*/ +static struct option const long_options[] = +{ + {"help", no_argument, 0, 'h'}, + {"io-layout-x", required_argument, 0, 'i'}, + {"io-layout-y", required_argument, 0, 'j'}, + {"usage", no_argument, 0, 'h'}, + {"dry-run", no_argument, 0, 'n'}, + {"start", required_argument, 0, 's'}, + {"version", no_argument, 0, 'v'}, + {"verbose", no_argument, 0, 'V'}, + {"width", required_argument, 0, 'w'}, + {"npx", required_argument, 0, 'x'}, + {"xdims", required_argument, 0, 'X'}, + {"npy", required_argument, 0, 'y'}, + {"ydims", required_argument, 0, 'Y'}, + {"prefix", required_argument, 0, 'p'}, + {0, 0, 0, 0} +}; + +#endif /* MPPNCSCATTER_OPT_H */ + diff --git a/src/tools/mppncscatter/scatterdim.c b/src/tools/mppncscatter/scatterdim.c new file mode 100755 index 0000000000..7fa448b2cd --- /dev/null +++ b/src/tools/mppncscatter/scatterdim.c @@ -0,0 +1,34 @@ +#include "scatterdim.h" + +ScatterDim* ScatterDim_new(int id, size_t len, const char * name, scatter_t scatter_type, int ndiv) { + ScatterDim* p = XMALLOC(ScatterDim,1); + if (p==NULL) return p; + + p->id = id; + p->len = len; + strcpy(p->name, name); + p->scatter_type = scatter_type; + p->scatter_ndiv = ndiv; + + p->scatter_start = XMALLOC(size_t, ndiv); + p->scatter_end = XMALLOC(size_t, ndiv); + p->scatter_len = XMALLOC(size_t, ndiv); + + return p; +} +/*-------------------------------------------------------------------*/ +void ScatterDim_free(ScatterDim* p) { + if (p == NULL) return; + + if (p->scatter_start) { + XFREE(p->scatter_start); + } + + if (p->scatter_end) { + XFREE(p->scatter_end); + } + + if (p->scatter_len) { + XFREE(p->scatter_len); + } +} diff --git a/src/tools/mppncscatter/scatterdim.h b/src/tools/mppncscatter/scatterdim.h new file mode 100755 index 0000000000..34971a3ff4 --- /dev/null +++ b/src/tools/mppncscatter/scatterdim.h @@ -0,0 +1,24 @@ +#ifndef SCATTERDIM_H +#define SCATTERDIM_H + +#include "common.h" + +typedef enum {NOSCATTER, SCATTERX, SCATTERY} scatter_t; + +typedef struct ScatterDimStruct { + int id; + size_t len; + char name[NC_MAX_NAME]; + + scatter_t scatter_type; + size_t* scatter_start; + size_t* scatter_end; + size_t* scatter_len; + size_t scatter_ndiv; /* Number of divisions. */ +} ScatterDim; + +void ScatterDim_free(ScatterDim* p); + +ScatterDim* ScatterDim_new(int id, size_t len, const char * name, scatter_t scatter_type, int ndiv); + +#endif /* SCATTERDIM_H */ \ No newline at end of file diff --git a/src/tools/mppncscatter/util.h b/src/tools/mppncscatter/util.h new file mode 100755 index 0000000000..9cd7ec5382 --- /dev/null +++ b/src/tools/mppncscatter/util.h @@ -0,0 +1,11 @@ +#ifndef MPPNCSCATTER_UTIL_H +#define MPPNCSCATTER_UTIL_H + +#include "math.h" + +/*-------------------------------------------------------------------*/ +#define EVEN(X) ( ((X) % 2) ? 0 : 1 ) +#define MAX(A,B) ( ((A) > (B)) ? (A) : (B) ) +#define ODD(X) ((X) % 2) + +#endif /* MPPNCSCATTER_UTIL_H */ \ No newline at end of file diff --git a/src/tools/ncexists/COPYING b/src/tools/ncexists/COPYING new file mode 100644 index 0000000000..93a221957b --- /dev/null +++ b/src/tools/ncexists/COPYING @@ -0,0 +1,159 @@ +TERMS AND CONDITIONS +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. +1. Source Code. + +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. +2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. +7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. +8. Termination. + +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. +11. Patents. + +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. diff --git a/src/tools/ncexists/do_make b/src/tools/ncexists/do_make deleted file mode 100755 index 4e6fdedf16..0000000000 --- a/src/tools/ncexists/do_make +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/tcsh -f -source /opt/modules/default/init/tcsh -module purge -module load ifort.9.1.041 -module load icc.9.1.045 -module load mpt-1.18 -module load idb.9.1.045 -module load scsl-1.5.1.0 -module load netcdf-4.0 -module list -setenv NC_BLKSZ 64K - -rm *.o ncexists >& /dev/null -make -f makefile_icc -cp ncexists ../../../bin diff --git a/src/tools/ncexists/do_make.static b/src/tools/ncexists/do_make.static deleted file mode 100755 index 868424b6f6..0000000000 --- a/src/tools/ncexists/do_make.static +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/tcsh -f -source /opt/modules/default/init/tcsh -module purge -module load ifort.9.1.041 -module load icc.9.1.045 -module load mpt-1.18 -module load idb.9.1.045 -module load scsl-1.5.1.0 -module load netcdf-4.0 -module list -setenv NC_BLKSZ 64K - -rm *.o ncexists >& /dev/null -make -f makefile_icc.static -cp ncexists ../../../bin.static diff --git a/src/tools/ncexists/env.gaea b/src/tools/ncexists/env.gaea new file mode 100644 index 0000000000..ec49db2dd9 --- /dev/null +++ b/src/tools/ncexists/env.gaea @@ -0,0 +1 @@ +STATIC := -static diff --git a/src/tools/ncexists/env.gfdl-ws b/src/tools/ncexists/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/ncexists/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/ncexists/env.pan b/src/tools/ncexists/env.pan new file mode 100644 index 0000000000..68cc14bc27 --- /dev/null +++ b/src/tools/ncexists/env.pan @@ -0,0 +1,2 @@ +LIBS2 := +CLIBS2 := diff --git a/src/tools/ncexists/env.zeus b/src/tools/ncexists/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/ncexists/fre-nctools.mk b/src/tools/ncexists/fre-nctools.mk new file mode 100644 index 0000000000..9f72c4fe6d --- /dev/null +++ b/src/tools/ncexists/fre-nctools.mk @@ -0,0 +1,44 @@ +# +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:34:57 fms Exp $ +# ------------------------------------------------------------------------------ +# FMS/FRE Project: Makefile to Build Regridding Executables +# ------------------------------------------------------------------------------ +# afy Ver 1.00 Initial version (Makefile, ver 17.0.4.2) June 10 +# afy Ver 1.01 Add rules to build MPI-based executable June 10 +# afy Ver 1.02 Simplified according to fre-nctools standards June 10 +# ------------------------------------------------------------------------------ +# Copyright (C) NOAA Geophysical Fluid Dynamics Laboratory, 2009-2011 +# This program is distributed under the terms of the GNU General Public +# License. See the file COPYING contained in this directory +# +# Designed and written by V. Balaji, Amy Langenhorst and Aleksey Yakovlev +# +include env.$(SITE) + +CC := icc +CFLAGS := -O3 -g -traceback +CFLAGS_O2:= -O2 -g -traceback +INCLUDES := -I${NETCDF_HOME}/include +CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) + +TARGETS := ncexists + +SOURCES := ncexists.c + +OBJECTS := $(SOURCES:c=o) + +HEADERS = fre-nctools.mk + +all: $(TARGETS) + +ncexists: $(OBJECTS) + $(CC) -o $@ $^ $(CLIBS) + +ncexists.o: ncexists.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + -rm -f *.o $(TARGETS) diff --git a/src/tools/ncexists/makefile_icc b/src/tools/ncexists/makefile_icc deleted file mode 100644 index 176277a073..0000000000 --- a/src/tools/ncexists/makefile_icc +++ /dev/null @@ -1,17 +0,0 @@ -# Makefile for the "ncexists" program -# -# Written by Hans Vahlenkamp (Hans.Vahlenkamp) -# Geophysical Fluid Dynamics Laboratory / NOAA -# Princeton Forrestal Campus -# Last updated: 05/15/08 - -NETCDFPATH = /usr/local/netcdf-4.0.1 -SOURCES = ncexists.c -OBJECTS = ncexists.o -CC = icc -CFLAGS = -O2 -I${NETCDFPATH}/include -LFLAGS = -L${NETCDFPATH}/lib/shared -LIBS = -lnetcdf -lhdf5_hl -lhdf5 -lmpi -lz - -ncexists: $(OBJECTS) - $(CC) $(CFLAGS) -o ncexists -s $(OBJECTS) $(LFLAGS) $(LIBS) diff --git a/src/tools/ncexists/makefile_icc.static b/src/tools/ncexists/makefile_icc.static deleted file mode 100644 index 9a9165ce55..0000000000 --- a/src/tools/ncexists/makefile_icc.static +++ /dev/null @@ -1,17 +0,0 @@ -# Makefile for the "ncexists" program -# -# Written by Hans Vahlenkamp (Hans.Vahlenkamp) -# Geophysical Fluid Dynamics Laboratory / NOAA -# Princeton Forrestal Campus -# Last updated: 05/15/08 - -NETCDFPATH = /usr/local/netcdf-4.0.1 -SOURCES = ncexists.c -OBJECTS = ncexists.o -CC = icc -CFLAGS = -O2 -I${NETCDFPATH}/include -LFLAGS = -L${NETCDFPATH}/lib -LIBS = -lnetcdf -lhdf5_hl -lhdf5 -lmpi -lz - -ncexists: $(OBJECTS) - $(CC) $(CFLAGS) -o ncexists -s $(OBJECTS) $(LFLAGS) $(LIBS) diff --git a/src/tools/ncexists/mk_ncexists b/src/tools/ncexists/mk_ncexists deleted file mode 100644 index 7feed6b101..0000000000 --- a/src/tools/ncexists/mk_ncexists +++ /dev/null @@ -1 +0,0 @@ -gcc ncexists.c -o ncexists -I/usr/local/netcdf-3.6.2/include -L/usr/local/netcdf-3.6.2/lib -lnetcdf diff --git a/src/tools/ncexists/ncexists.c b/src/tools/ncexists/ncexists.c new file mode 100644 index 0000000000..488194d23d --- /dev/null +++ b/src/tools/ncexists/ncexists.c @@ -0,0 +1,138 @@ +/* + Copyright 2011 NOAA Geophysical Fluid Dynamics Lab, Princeton, NJ + This program is distributed under the terms of the GNU General Public + License. See the file COPYING contained in this directory +*/ +#include +#include +#include +#include +#include +#include + +void handle_error(int status); + +int main (int argc, char **argv) +{ + + int status; + char *filename = NULL; + char *attr = NULL; + char *gattr = NULL; + int ncid; + char *var_name = NULL; + int vr_len; + int var_id; + int t_len; + int global = 0; + int c; + char *usage = "Usage: ncexists -f filename [ -g global_attribute || -v variable || -v variable -a attribute ]\n Returns 1 if variable or attribute is found, 0 if not found.\n"; + nc_type vr_type, t_type; + + + + if (argc == 1) + { + printf (usage); + //printf ("No arguments: exiting\n"); + return 0; + } + else + { + while ((c = getopt (argc, argv, "f:v:g:a:")) != -1) + { + switch (c) + { + case 'f': + filename = optarg; + break; + + case 'g': + gattr = optarg; + global = 1; + break; + + case 'v': + var_name = optarg; + break; + + case 'a': + attr= optarg; + break; + + + + case '?': + printf (usage); + return 1; + default: + printf (usage); + abort (); + } + } + + if (global == 1) + { + + status = nc_open(filename, 0, &ncid); + if (status != NC_NOERR) handle_error(status); + + status = nc_inq_att (ncid, NC_GLOBAL, gattr, &t_type, &t_len); + if (status == NC_NOERR) + { + printf ("1\n"); + } + else + { + printf ("0\n"); + } + } + else + { + status = nc_open(filename, 0, &ncid); + if (status != NC_NOERR) handle_error(status); + + status = nc_inq_varid (ncid, var_name, &var_id); + if (status == NC_NOERR) + { + if ( attr == NULL ) + { + printf ("1\n"); + } + else + { + status = nc_inq_att (ncid, var_id, attr, &vr_type, &vr_len); + if (status == NC_NOERR) + { + printf ("1\n"); + } + else + { + printf ("0\n"); + } + } + } + else + { + printf ("0\n"); + } + } + + + status = nc_close(ncid); /* close netCDF dataset */ + if (status != NC_NOERR) handle_error(status); + +} + + + exit(0); +} + +void handle_error(int status) +{ + if (status != NC_NOERR) + { + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(-1); + } +} diff --git a/src/tools/remap_land/Makefile b/src/tools/remap_land/Makefile deleted file mode 100644 index 22a83cad9e..0000000000 --- a/src/tools/remap_land/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-4.0.1 -HDF5PATH = /usr/local/hdf5-1.8.1 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I${HDF5PATH}/include -LDFLAGS = -L${NETCDFPATH}/lib/shared -L${HDF5PATH}/lib/shared -lm -lnetcdf -lhdf5_hl -lhdf5 -lz -DEFFLAG = -Duse_netCDF -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o gradient_c2l.o create_xgrid.o interp.o read_mosaic.o mpp.o mpp_domain.o mpp_io.o tool_util.o remap_land.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/mosaic_util.h \ - $(SHAREDIR)/interp.h $(SHAREDIR)/create_xgrid.h -remap_land: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -remap_land.o: $(COREDIR)/remap_land.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/remap_land.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - -gradient_c2l.o: $(SHAREDIR)/gradient_c2l.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/gradient_c2l.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -read_mosaic.o: $(SHAREDIR)/read_mosaic.c $(HEADERS) - $(CC) $(DEFFLAG) $(CFLAGS) -c $(SHAREDIR)/read_mosaic.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - - diff --git a/src/tools/remap_land/Makefile_mpi b/src/tools/remap_land/Makefile_mpi deleted file mode 100644 index 5a81429cd6..0000000000 --- a/src/tools/remap_land/Makefile_mpi +++ /dev/null @@ -1,51 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-4.0.1 -HDF5PATH = /usr/local/hdf5-1.8.1 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I${HDF5PATH}/include -LDFLAGS = -L${NETCDFPATH}/lib/shared -L${HDF5PATH}/lib/shared -lm -lnetcdf -lhdf5_hl -lhdf5 -lz -lmpi -DEFFLAG = -Duse_netCDF -Duse_libMPI -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o gradient_c2l.o create_xgrid.o interp.o read_mosaic.o mpp.o mpp_domain.o mpp_io.o tool_util.o remap_land.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/mosaic_util.h \ - $(SHAREDIR)/interp.h $(SHAREDIR)/create_xgrid.h -remap_land_parallel: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -remap_land.o: $(COREDIR)/remap_land.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/remap_land.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - -gradient_c2l.o: $(SHAREDIR)/gradient_c2l.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/gradient_c2l.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -read_mosaic.o: $(SHAREDIR)/read_mosaic.c $(HEADERS) - $(CC) $(DEFFLAG) $(CFLAGS) -c $(SHAREDIR)/read_mosaic.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(DEFFLAG) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - - diff --git a/src/tools/remap_land/env.gaea b/src/tools/remap_land/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/remap_land/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/remap_land/env.gfdl-ws b/src/tools/remap_land/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/remap_land/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/remap_land/env.pan b/src/tools/remap_land/env.pan index 626aa584eb..3d742259a5 100644 --- a/src/tools/remap_land/env.pan +++ b/src/tools/remap_land/env.pan @@ -1,6 +1,5 @@ -# GFDL did not build shared libs for 4.1.1. So we have to add explicit link to libcurl -LIBS2 := -lcurl -CLIBS2 := -lcurl +LIBS2 := +CLIBS2 := # GFDL uses the mpicc wrapper and Intel icc MPICC := mpicc diff --git a/src/tools/remap_land/env.zeus b/src/tools/remap_land/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/remap_land/fre-nctools.mk b/src/tools/remap_land/fre-nctools.mk index 16e8afc45e..bdb753ccef 100644 --- a/src/tools/remap_land/fre-nctools.mk +++ b/src/tools/remap_land/fre-nctools.mk @@ -1,5 +1,5 @@ # -# $Id: fre-nctools.mk,v 1.1.2.1.2.1 2012/06/06 16:44:34 Zhi.Liang Exp $ +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:35:06 fms Exp $ # ------------------------------------------------------------------------------ # FMS/FRE Project: Makefile to Build Regridding Executables # ------------------------------------------------------------------------------ diff --git a/src/tools/remap_land/remap_land.c b/src/tools/remap_land/remap_land.c index dbdcf56533..66660737fd 100644 --- a/src/tools/remap_land/remap_land.c +++ b/src/tools/remap_land/remap_land.c @@ -6,6 +6,7 @@ #include "read_mosaic.h" #include "mosaic_util.h" #include "tool_util.h" +#include "constant.h" #include "mpp.h" #include "mpp_domain.h" #include "mpp_io.h" @@ -13,10 +14,23 @@ #define COHORT_INDEX_NAME "cohort_index" #define COHORT_NAME "cohort" #define TILE_NAME "tile" -#define LON_NAME "lon" -#define LAT_NAME "lat" -#define TIMENAME "time" +#define LON_NAME "lon" +#define LAT_NAME "lat" +#define TIMENAME "time" +#define FRAC_NAME "frac" +#define SOIL_NAME "soil" +#define VEGN_NAME "vegn" +#define GLAC_NAME "glac" +#define LAKE_NAME "lake" +#define LEVEL_NAME "zfull" +#define N_ACCUM_NAME "n_accum" +#define NMN_ACM_NAME "nmn_acm" +#define THETA_AV_NAME "theta_av" +#define THETA_AV_PHEN_NAME "theta_av_phen" +#define THETA_AV_FIRE_NAME "theta_av_fire" +#define PSIST_AV_NAME "psist_av" #define D2R (M_PI/180.) +#define R2D (180./M_PI) char *usage[] = { "", @@ -26,62 +40,93 @@ char *usage[] = { " ", " remap_land --src_mosaic src_mosaic --src_restart src_restart ", " --dst_mosaic dst_msoaic --dst_restart dst_restart ", - " --dst_cold_restart dst_cold_restart [--remap_file remap_file] ", + " --dst_cold_restart dst_cold_restart ", + " --land_src_restart land_src_restart ", + " --land_dst_cold_restart land_dst_cold_restart ", + " [--remap_file remap_file] [--print_memory] ", " ", " remap_land remap land restart file from one mosaic grid to another mosaic grid ", - " remap_land takes the following flags, ", - " ", - " REQUIRED: ", - " ", - " --src_mosaic src_mosaic specify the source mosaic information. This file ", - " contains list of tile files which specify the grid ", - " information for each tile. ", - " ", - " --dst_mosaic dst_mosaic specify the destination mosaic information. This ", - " file contains list of tile files which specify the ", - " grid information for each tile. ", - " ", - " --src_restart src_restart specify the source restart file. ", - " ", - " --dst_restart dst_restart specify the restart file to be generated on ", - " destination grid. ", - " ", - " --dst_cold_restart file specify the cold restart file destination grid. ", - " This is the input file. The dst_cold_restart_file ", - " could be obtained by running the experiment ", - " for 1 day with --dst_mosaic using cold restart. ", - " ", - " ", - " OPTIONAL FLAGS ", - " ", - " ", - " --remap_file remap_file specify the file name that saves remapping ", - " information. If remap_file is specified and the ", - " file does not exist, remapping information will be ", - " calculated and stored in remap_file. If remap_file ", - " is specified and the file exists, remapping ", - " information will be read from remap_file. ", - " ", - " ", - " Example: remap land restart from C48 grid onto C180 grid. ", - " ", - " remap_land --src_mosaic /archive/z1l/tools/input/C48/C48_mosaic.nc ", - " --dst_mosaic /archive/z1l/tools/input//C180/C180_mosaic.nc ", - " --src_restart /archive/z1l/tools/input/land_src_restart/soil.res ", - " --dst_cold_restart /archive/z1l/tools/input/land_dst_cold_restart/soil.res ", - " --dst_restart soil.res ", - " ", + " remap_land takes the following flag s, ", + " ", + " REQUIRED: ", + " ", + " --src_mosaic src_mosaic specify the source mosaic information. This file ", + " contains list of tile files which specify the grid ", + " information for each tile. ", + " ", + " --dst_mosaic dst_mosaic specify the destination mosaic information. This ", + " file contains list of tile files which specify the ", + " grid information for each tile. ", + " ", + " --src_restart src_restart specify the source restart file. ", + " ", + " --dst_restart dst_restart specify the restart file to be generated on ", + " destination grid. ", + " ", + " --dst_cold_restart file specify the cold restart file destination grid. ", + " This is the input file. The dst_cold_restart_file ", + " could be obtained by running the experiment ", + " for 1 day with --dst_mosaic using cold restart. ", + " ", + " --file_type file_type spefify file type. Its value could be 'land', ", + " 'cana', 'snow', 'glac', 'lake', 'soil' or 'vegn'. ", + " when file_type is 'cana' or 'snow', need to ", + " specify --land_src_restart and --land_cold_restart ", + " ", + " OPTIONAL FLAGS ", + " ", + " ", + " --land_src_restart file specify the source file of land.res.nc. It is ", + " required when the restart file is snow.res or ", + " cana.res ", + " ", + " --land_dst_cold_restart file specify the destination file of land.res.nc. It is ", + " required when the restart file is snow.res or ", + " cana.res ", + " ", + " --remap_file remap_file specify the file name that saves remapping ", + " information. If remap_file is specified and the ", + " file does not exist, remapping information will be ", + " calculated and stored in remap_file. If remap_file ", + " is specified and the file exists, remapping ", + " information will be read from remap_file. ", + " ", + " --print_memory debug memory usage when it is set ", + " ", + " ", + " Example: remap land restart from C48 grid onto C180 grid. ", + " ", + " remap_land --src_mosaic C48/C48_mosaic.nc ", + " --dst_mosaic C180/C180_mosaic.nc ", + " --src_restart src_restart/soil.res ", + " --dst_cold_restart dst_cold_restart/soil.res ", + " --dst_restart dst_restart/soil.res ", + " --land_src_restart src_restart/land.res ", + " --land_dst_cold_restart dst_cold_restart/land.res ", + " ", NULL }; char grid_version[] = "0.2"; -char tagname[] = "$Name: siena_201205_z1l $"; - +char tagname[] = "$Name: tikal $"; +double distance(double lon1, double lat1, double lon2, double lat2); void get_actual_file_name(int nface, int face, const char *file_orig, char *file); -void full_search_nearest(int nface_src, const int *npts_src, const double *lon_src, const double *lat_src, - const int *tile_type_src, int npts_dst, const double *lon_dst, - const double *lat_dst, const int *tile_type_dst, int *idx_map, int *face_map); - +void get_land_tile_info(int fid, const char *name1, const char *name2, int nidx, const int *idx_in, const double *frac_in, + int nx, int ny, int ntile, int isc, int iec, int *count, double *frac, int *tag1, int *tag2, int *idx, int all_tile); +void full_search_nearest(int nface_src, int npts_src, const double *lon_src, const double *lat_src, + const int *mask_src, int npts_dst, const double *lon_dst, const double *lat_dst, + const int *mask_dst, int *idx_map, int *face_map); +void compress_int_data(int ntile, int npts, int nidx, int nidx_global, const int *land_count, + const int *data, int *data_global, int all_tile ); +void compress_double_data(int ntile, int npts, int nidx, int nidx_global, const int *land_count, + const double *data, double *data_global, int all_tile ); +const int LANDTYPE = 1; +const int SOILTYPE = 2; +const int GLACTYPE = 3; +const int LAKETYPE = 4; +const int VEGNTYPE = 5; +const int CANATYPE = 6; +const int SNOWTYPE = 7; int main(int argc, char* argv[]) { @@ -91,21 +136,42 @@ int main(int argc, char* argv[]) char *src_restart_file = NULL; char *dst_restart_file = NULL; char *dst_cold_restart = NULL; + char *land_src_restart = NULL; + char *land_cold_restart = NULL; char *remap_file = NULL; + char *file_type = NULL; + int face_dst; int nface_src = 0, nface_dst = 0; int nx_src, ny_src, nx_dst, ny_dst; - int nidx_tot_src, n_cohort, n_tile; + int ntile_src, ntile_cold, ntile_dst; + int nidx_tot_src, ncohort; int *fid_src=NULL; - int *cohort_data=NULL, *tile_data=NULL; - int *nidx_src=NULL, *start_pos=NULL; - int *idx_src=NULL, *idx_type_src=NULL; - + int *cohort_data=NULL, *tile_axis_data=NULL; + int *nidx_src=NULL, *nidx_land_src=NULL; + + int *idx_soil_src=NULL, *idx_glac_src=NULL, *idx_lake_src=NULL; + int *soil_count_src=NULL, *glac_count_src=NULL, *lake_count_src=NULL; + int *soil_tag_src=NULL, *glac_tag_src=NULL, *lake_tag_src=NULL, *vegn_tag_src=NULL; + double *soil_frac_src=NULL, *glac_frac_src=NULL, *lake_frac_src=NULL; + + int filetype; char history[1280]; double *x_src=NULL, *y_src=NULL; - int time_exist, ntime, l; + int time_exist, zaxis_exist, ntime, l; int *has_taxis=NULL, *var_type=NULL, *ndim_src=NULL, *nz_src=NULL; double *time_data=NULL; + int has_glac=0, has_lake=0; + int src_has_tile=0, cold_has_tile=0; + int src_has_cohort=0, cold_has_cohort=0; + int src_has_theta_av=0, cold_has_theta_av=0; + int src_has_theta_av_phen=0, cold_has_theta_av_phen=0; + int src_has_theta_av_fire=0, cold_has_theta_av_fire=0; + int src_has_psist_av=0, cold_has_psist_av=0; + int nz; + double *z_axis_data=NULL; + int print_memory=0; + int use_all_tile; int npes, nvar_src; int option_index, c; @@ -115,13 +181,17 @@ int main(int argc, char* argv[]) */ static struct option long_options[] = { - {"src_mosaic", required_argument, NULL, 'a'}, - {"dst_mosaic", required_argument, NULL, 'b'}, - {"src_restart", required_argument, NULL, 'c'}, - {"dst_restart", required_argument, NULL, 'o'}, - {"dst_cold_restart", required_argument, NULL, 'd'}, - {"remap_file", required_argument, NULL, 'r'}, - {"help", no_argument, NULL, 'h'}, + {"src_mosaic", required_argument, NULL, 'a'}, + {"dst_mosaic", required_argument, NULL, 'b'}, + {"src_restart", required_argument, NULL, 'c'}, + {"dst_restart", required_argument, NULL, 'o'}, + {"dst_cold_restart", required_argument, NULL, 'd'}, + {"file_type", required_argument, NULL, 't'}, + {"land_src_restart", required_argument, NULL, 'l'}, + {"land_cold_restart", required_argument, NULL, 'm'}, + {"remap_file", required_argument, NULL, 'r'}, + {"print_memory", no_argument, NULL, 'p'}, + {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0}, }; @@ -147,10 +217,22 @@ int main(int argc, char* argv[]) break; case 'd': dst_cold_restart = optarg; + break; + case 'l': + land_src_restart = optarg; + break; + case 'm': + land_cold_restart = optarg; break; + case 't': + file_type = optarg; + break; case 'r': remap_file = optarg; break; + case 'p': + print_memory = 1; + break; case '?': errflg++; break; @@ -161,7 +243,8 @@ int main(int argc, char* argv[]) if( !src_restart_file) errflg++; if( !dst_restart_file ) errflg++; if( !dst_cold_restart ) errflg++; - + if( !file_type) errflg++; + if (errflg) { char **u = usage; if(mpp_pe() == mpp_root_pe()) { @@ -171,14 +254,69 @@ int main(int argc, char* argv[]) if(!src_restart_file) mpp_error("remap_land: src_restart_file is not specified"); if(!dst_restart_file) mpp_error("remap_land: dst_restart_file is not specified"); if(!dst_cold_restart) mpp_error("remap_land: dst_cold_restart is not specified"); + if(!file_type) mpp_error("remap_land: file_type is not specified"); } mpp_error("remap_land: check the command line arguments"); } + if(print_memory) print_mem_usage("at the begining of remap_land"); + + /* write out arguments */ + if(mpp_pe() == mpp_root_pe()) { + printf("src_mosaic is %s\n", src_mosaic); + printf("dst_mosaic is %s\n", dst_mosaic); + printf("src_restart_file is %s\n", src_restart_file); + printf("dst_restart_file is %s\n", dst_restart_file); + printf("dst_cold_restart is %s\n", dst_cold_restart); + printf("file_type is %s\n", file_type); + if(land_src_restart) { + printf("land_src_restart is %s\n", land_src_restart); + printf("land_cold_restart is %s\n", land_cold_restart); + } + else { + printf("land_src_restart is not specified\n"); + printf("land_cold_restart is not specified\n"); + } + } + + /* file type must be the land, cana, snow, soil, lake, glac, vegn */ + if(!strcmp(file_type, "land")) + filetype = LANDTYPE; + else if(!strcmp(file_type, "soil")) + filetype = SOILTYPE; + else if(!strcmp(file_type, "cana") ) + filetype = CANATYPE; + else if(!strcmp(file_type, "snow")) + filetype = SNOWTYPE; + else if(!strcmp(file_type, "lake")) + filetype = LAKETYPE; + else if(!strcmp(file_type, "glac")) + filetype = GLACTYPE; + else if(!strcmp(file_type, "vegn") ) + filetype = VEGNTYPE; + else + mpp_error("remap_land: invalid option in --file_type"); + + /* when file_type is cana or snow, land_src_restart and land_cold_restart must be specified */ + if(filetype == LANDTYPE) { + if(land_src_restart) mpp_error("remap_land: land_src_restart must not be specified " + "when file_type is 'land'"); + if(land_cold_restart) mpp_error("remap_land: land_cold_restart must not be specified " + "when file_type is 'land'"); + land_src_restart = src_restart_file; + land_cold_restart = dst_cold_restart; + } + else { + if(!land_src_restart) mpp_error("remap_land: land_src_restart must be specified " + "when file_type is not 'land'"); + if(!land_cold_restart) mpp_error("remap_land: land_cold_restart must be specified " + "when file_type is not 'land'"); + } + npes = mpp_npes(); /*---------------------------------------------------------------------------- - get source grid size + get source and destination grid size --------------------------------------------------------------------------*/ { int *nx, *ny; @@ -190,7 +328,8 @@ int main(int argc, char* argv[]) read_mosaic_grid_sizes(src_mosaic, nx, ny); /* nx, ny of source should have the same value on each face */ for(n=1; n max_nidx) max_nidx = nidx[face_dst]; + } + + ntile_cold = mpp_get_dimlen(fid[0], TILE_NAME); + for(face_dst=1; face_dst 0) { + has_glac = 1; + goto GLAC_CHECK; + } + } + } + GLAC_CHECK: + if( mpp_pe() == mpp_root_pe() ) { + if(has_glac) + printf("remap_land: there is glac in cold restart file\n"); + else + printf("remap_land: there is no glac in cold restart file\n"); + } + + for(face_dst=0; face_dst 0) { + has_lake = 1; + goto LAKE_CHECK; + } + } + } + LAKE_CHECK: + if( mpp_pe() == mpp_root_pe() ) { + if(has_lake) + printf("remap_land: there is lake in cold restart file\n"); + else + printf("remap_land: there is no lake in cold restart file\n"); + } + for(face_dst=0; face_dstmax_nidx) max_nidx = nidx_land_src[n]; + } + frac_land_src = (double *)malloc(max_nidx*sizeof(double)); + idx_land_src = (int *)malloc(max_nidx*sizeof(int)); + + pos1 = 0; + pos2 = 0; + use_all_tile = 0; + if(filetype==LANDTYPE || filetype==CANATYPE || filetype==SNOWTYPE) use_all_tile = 1; + + for(n=0; n nidx_src[n])mpp_error("remap_land: idx is out of bound for soil consistency check"); + idx = idx_src[idx]; + i = idx%nx_src; + k = idx/nx_src; + j = k%ny_src; + k = k/ny_src; + p2 = n*nx_src*ny_src + j*nx_src+i; + if(p!=p2) mpp_error("remap_land: mismatch of tile_index for src soil check"); + if(soil_tag_src[ntile_src*p+k] == MPP_FILL_INT) mpp_error("remap_land: soil_tag_src is not defined for src soil check"); + } + } + } + } + } + free(frac_land_src); + free(idx_land_src); + if(filetype!=LANDTYPE)free(idx_src); + } + } + + /* define history attribute */ { int n; strcpy(history,argv[0]); @@ -366,156 +769,225 @@ int main(int argc, char* argv[]) strcat(history, argv[n]); } } + + if(print_memory) print_mem_usage("After initialization of source information"); + /*------------------------------------------------------------------------------------------ loop through each face of destination grid, first read the grid, then read the tile_index, then find the remapping index, then setup metadata for the destination file, last do the remapping and write out the data to dst_restart_file ----------------------------------------------------------------------------------------*/ { - double *x_tmp, *y_tmp; - int n, pos; - char cmd[1024]; - start_pos = (int *)malloc(nface_src*sizeof(int)); - + double *data_dst=NULL, *data_src=NULL; + int *idata_dst=NULL, *idata_src=NULL; + int *start_pos=NULL; + double *x_tmp=NULL, *y_tmp=NULL; + double *lon_axis_dst=NULL, *lat_axis_dst=NULL; + double *x_dst=NULL, *y_dst=NULL; + + int *idx_dst=NULL; + int *glac_tag_dst=NULL, *lake_tag_dst=NULL, *soil_tag_dst=NULL, *vegn_tag_dst=NULL; + int *idx_map_soil=NULL, *face_map_soil=NULL; + int *idx_map_glac=NULL, *face_map_glac=NULL; + int *idx_map_lake=NULL, *face_map_lake=NULL; + int *land_idx_map=NULL, *land_face_map=NULL; + double *glac_frac_cold=NULL, *lake_frac_cold=NULL, *soil_frac_cold=NULL, *tmp_frac_cold=NULL; + int *glac_count_cold=NULL, *lake_count_cold=NULL, *soil_count_cold=NULL; + int *glac_tag_cold=NULL, *lake_tag_cold=NULL, *soil_tag_cold=NULL, *vegn_tag_cold=NULL; + int *land_count_dst=NULL; + int *idx_map_land=NULL; + double *land_frac_dst=NULL; + + int isc_dst, iec_dst, jsc_dst, jec_dst, nxc_dst, nyc_dst; + int n, pos, has_int_var; + int layout[2]; + domain2D Dom_dst; + + lon_axis_dst = (double *)malloc(nx_dst*sizeof(double)); + lat_axis_dst = (double *)malloc(ny_dst*sizeof(double)); x_tmp = (double *) malloc(nx_dst*ny_dst*sizeof(double)); y_tmp = (double *) malloc(nx_dst*ny_dst*sizeof(double)); + start_pos = (int *)malloc(nface_src*sizeof(int)); - for(n=0; n 0 ) { + double totfrac; + + n = face_map_soil[i]; + if(n<0) { + printf("soil_count_cold=%d, face_map_soil=%d, pe=%d, i=%d\n", soil_count_cold[i], n, mpp_pe(), i); + mpp_error("remap_land: soil_count_cold >0 but face_map_soil<0"); + } + idx = idx_map_soil[i]; + p = n*nx_src*ny_src+idx; + count = soil_count_src[p]; + if( filetype != GLACTYPE && filetype != LAKETYPE ) { + pos = land_count_dst[i]; + totfrac = 0; + for(l=0; l 0 ) { + n = face_map_glac[i]; + idx = idx_map_glac[i]; + p = n*nx_src*ny_src+idx; + pos = land_count_dst[i]; + count = glac_count_src[p]; + if( count != 1) mpp_error("remap_land: glac_count_src should be 1"); + if( filetype != SOILTYPE && filetype != VEGNTYPE && filetype != LAKETYPE ){ + glac_tag_dst[ntile_dst*i+pos] = glac_tag_src[p]; + land_frac_dst[ntile_dst*i+pos] = glac_frac_cold[i]; /* preserve fraction in cold restart file */ + land_idx_map[ntile_dst*i+pos] = idx_glac_src[p]; + land_face_map[ntile_dst*i+pos] = n; + nidx_dst++; + } + land_count_dst[i]++; + } + } + if(has_lake) { + if( lake_count_cold[i] > 0 ) { + n = face_map_lake[i]; + idx = idx_map_lake[i]; + p = n*nx_src*ny_src+idx; + count = lake_count_src[p]; + pos = land_count_dst[i]; + if( count != 1) mpp_error("remap_land: lake_count_src should be 1"); + if( filetype != SOILTYPE && filetype != VEGNTYPE && filetype != GLACTYPE ) { + lake_tag_dst[ntile_dst*i+pos] = lake_tag_src[p]; + land_frac_dst[ntile_dst*i+pos] = lake_frac_cold[i]; /* preserve fraction in cold restart file */ + land_idx_map[ntile_dst*i+pos] = idx_lake_src[p];; + land_face_map[ntile_dst*i+pos] = n; + nidx_dst++; + } + land_count_dst[i]++; + } + } + } + } + nidx_dst_global = nidx_dst; + mpp_sum_int(1, &nidx_dst_global); + /* compute tile_index */ + for(i=0; i -1 ) { + idx_dst[ntile_dst*i+n] = n*nx_dst*ny_dst+i+isc_dst; + } + } + } + + /* define the metadata for dst_restart_file */ + { + int dim_time, dim_cohort_index, dim_lat, dim_lon; + int dim_tile_index, dim_cohort, dim_tile, dim_z; + + dim_lon = mpp_def_dim(fid_dst, LON_NAME, nx_dst); + dim_lat = mpp_def_dim(fid_dst, LAT_NAME, ny_dst); + dim_tile = mpp_def_dim(fid_dst, TILE_NAME, ntile_dst); + dim_tile_index = mpp_def_dim(fid_dst, TILE_INDEX_NAME, max(nidx_dst_global,1) ); + if(zaxis_exist) dim_z = mpp_def_dim(fid_dst, LEVEL_NAME, nz); + if(filetype==VEGNTYPE) { + dim_cohort = mpp_def_dim(fid_dst, COHORT_NAME, ncohort); + dim_cohort_index = mpp_def_dim(fid_dst, COHORT_INDEX_NAME, max(nidx_dst_global,1)); + } + if(time_exist)dim_time = mpp_def_dim(fid_dst, TIMENAME, NC_UNLIMITED); + + for(l=0; l0 ) continue; mpp_get_varname(fid_src[0], l, varname); + if(nidx_dst_global==0) { + if(strcmp(varname, LON_NAME) && strcmp(varname, LAT_NAME) && + strcmp(varname, LEVEL_NAME) && strcmp(varname, TILE_NAME) && + strcmp(varname, COHORT_NAME)) continue; + } + vid_dst = mpp_get_varid(fid_dst, varname); vid_src = mpp_get_varid(fid_src[0], varname); @@ -613,133 +1345,229 @@ int main(int argc, char* argv[]) } } else { /* when time axis does not exist, ndim should be the same for src_restart_file and dst_cold_restart */ - int ndim_dst; - vid_read = mpp_get_varid(fid_read, varname); - ndim_dst = mpp_get_var_ndim(fid_read, vid_read); - if( ndim_src[l] != ndim_dst) - mpp_error("remap_land: number of dimensions for the field in dst_read_restart " - "does not match that in src_restart_file when time does not exist"); - if(ndim_dst == 0) continue; - } - - /* when time axis exist, need to copy tile_index, cohort_index, lon and lat from dst_cold_restart - to dst_restart_file */ - if(time_exist) { - if(strcmp(varname, TILE_INDEX_NAME) == 0 || strcmp(varname, COHORT_INDEX_NAME) == 0 || - strcmp(varname, LON_NAME) == 0 || strcmp(varname, LAT_NAME) == 0) { - int varsize; - - /* here we are assuming the vanname will have dimension name as its varname. */ - if( has_taxis[l] ) mpp_error("remap_land: TILE_INDEX, COHORT_INDEX, LON and LAT should not depend on time"); - varsize = mpp_get_dimlen(fid_read, varname); - vid_read = mpp_get_varid(fid_read, varname); - data_dst = (double *)malloc(varsize*sizeof(double)); - mpp_get_var_value( fid_read, vid_read, data_dst ); - mpp_put_var_value( fid_dst, vid_dst, data_dst ); - continue; + int ndim_cold; + if( (strcmp(varname, THETA_AV_NAME) || cold_has_theta_av) && + (strcmp(varname, TILE_NAME) || cold_has_tile ) && + (strcmp(varname, COHORT_NAME) || cold_has_cohort ) && + (strcmp(varname, THETA_AV_PHEN_NAME) || cold_has_theta_av_phen) && + (strcmp(varname, THETA_AV_FIRE_NAME) || cold_has_theta_av_fire) && + (strcmp(varname, PSIST_AV_NAME) || cold_has_psist_av) ) { + vid_cold = mpp_get_varid(fid_cold, varname); + ndim_cold = mpp_get_var_ndim(fid_cold, vid_cold); + if( ndim_src[l] != ndim_cold) + mpp_error("remap_land: number of dimensions for the field in dst_read_restart " + "does not match that in src_restart_file when time does not exist"); } - } - else { - if(strcmp(varname, TILE_INDEX_NAME) == 0 || strcmp(varname, COHORT_INDEX_NAME) == 0) continue; } - - if(has_taxis[l]) - mpp_get_var_dimname(fid_src[0], vid_src, 1, dimname); - else - mpp_get_var_dimname(fid_src[0], vid_src, 0, dimname); - - if( strcmp(dimname, TILE_INDEX_NAME) && strcmp(dimname, COHORT_INDEX_NAME) ) continue; nz_dst = 1; if(!time_exist) { if(ndim_src[l] == 2) { - mpp_get_var_dimname(fid_read, vid_read, 1, dimname); - nz_dst = mpp_get_dimlen(fid_read, dimname); + mpp_get_var_dimname(fid_cold, vid_cold, 0, dimname); + nz_dst = mpp_get_dimlen(fid_cold, dimname); } if(nz_dst != nz_src[l]) mpp_error("remap_land: the src_restart and dst_cold_restart have the different dimension length."); } - if(var_type[l] == MPP_INT) idata_src = (int *)malloc(nidx_tot_src*nz_src[l]*sizeof(int)); - data_src = (double *)malloc(nidx_tot_src*nz_src[l]*sizeof(double)); pos = 0; for(m=0; m<4; m++) { start[m]=0; nread[m] = 1; } - - for(m=0; miec) continue; + p = p - isc; + if(count[p] > ntile) mpp_error("remap_land: number of tiles is greater than allowed ntiles on one grid cell"); + frac[ntile*p+count[p]] = frac_in[l]; + tag1[ntile*p+count[p]] = tmp1[l]; + if(tag2) tag2[ntile*p+count[p]] = tmp2[l]; + if(idx) { + if(all_tile) + idx[ntile*p+count[p]] = l; + else + idx[ntile*p+count[p]] = pos; + } + /* if(p==192) printf("idx=%d,l=%d,pos=%d,count=%d\n", idx[ntile*p+count[p]], l, pos, count[p]); */ + pos++; + count[p]++; + } + } + + free(tmp1); + if(tmp2) free(tmp2); + + + } + /******************************************************************** void full_search_nearest search the nearest point from the first of source grid to the last. ********************************************************************/ -void full_search_nearest(int nface_src, const int *npts_src, const double *lon_src, const double *lat_src, - const int *tile_type_src, int npts_dst, const double *lon_dst, - const double *lat_dst, const int *tile_type_dst, int *idx_map, int *face_map) +void full_search_nearest(int nface_src, int npts_src, const double *lon_src, const double *lat_src, + const int *mask_src, int npts_dst, const double *lon_dst, const double *lat_dst, + const int *mask_dst, int *idx_map, int *face_map) { - int i_dst, i_src, cur_tile_type; - int pos, m, idx_cur, face_cur; + int i_dst, i_src, l, face_cur; + int pos, m, ind_cur; double d_cur,d; double p1[2], p2[2]; for(i_dst=0; i_dst0) data_local = (double *)malloc(nidx*sizeof(double)); + for(i=0; i0) free(data_local); + +} + +/*------------------------------------------------------------------------- + void compress_int_data () + get global compressed data + ------------------------------------------------------------------------*/ +void compress_int_data(int ntile, int npts, int nidx, int nidx_global, const int *land_count, + const int *data, int *data_global, int all_tile ) +{ + int pos1, pos2, pos, n, i, count; + int *data_local=NULL; + + if(nidx>0) data_local = (int *)malloc(nidx*sizeof(int)); + for(i=0; i0) free(data_local); + + +} + + diff --git a/src/tools/river_regrid/Makefile b/src/tools/river_regrid/Makefile deleted file mode 100644 index 9fd8cfd068..0000000000 --- a/src/tools/river_regrid/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-3.6.2 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -LDFLAGS = -L${NETCDFPATH}/lib -lm -lnetcdf -DEFFLAG = -Duse_netCDF -LNFLAGS = -v -CC = icc - -OBJS = mosaic_util.o create_xgrid.o read_mosaic.o mpp.o mpp_domain.o mpp_io.o river_regrid.o tool_util.o interp.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/mosaic_util.h \ - $(SHAREDIR)/interp.h $(SHAREDIR)/create_xgrid.h -river_regrid: $(OBJS) - $(CC) $(LNFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -river_regrid.o: $(COREDIR)/river_regrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/river_regrid.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c - - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -interp.o: $(SHAREDIR)/interp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/interp.c - -read_mosaic.o: $(SHAREDIR)/read_mosaic.c $(HEADERS) - $(CC) $(DEFFLAG) $(CFLAGS) -c $(SHAREDIR)/read_mosaic.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - - diff --git a/src/tools/river_regrid/env.gaea b/src/tools/river_regrid/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/river_regrid/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/river_regrid/env.gfdl-ws b/src/tools/river_regrid/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/river_regrid/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/river_regrid/env.pan b/src/tools/river_regrid/env.pan index 626aa584eb..3d742259a5 100644 --- a/src/tools/river_regrid/env.pan +++ b/src/tools/river_regrid/env.pan @@ -1,6 +1,5 @@ -# GFDL did not build shared libs for 4.1.1. So we have to add explicit link to libcurl -LIBS2 := -lcurl -CLIBS2 := -lcurl +LIBS2 := +CLIBS2 := # GFDL uses the mpicc wrapper and Intel icc MPICC := mpicc diff --git a/src/tools/river_regrid/env.zeus b/src/tools/river_regrid/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/river_regrid/fre-nctools.mk b/src/tools/river_regrid/fre-nctools.mk index 2a193dc819..db02ac0f84 100644 --- a/src/tools/river_regrid/fre-nctools.mk +++ b/src/tools/river_regrid/fre-nctools.mk @@ -1,5 +1,5 @@ # -# $Id: fre-nctools.mk,v 1.1.2.1 2012/06/06 16:59:07 Zhi.Liang Exp $ +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:35:13 fms Exp $ # ------------------------------------------------------------------------------ # FMS/FRE Project: Makefile to Build Regridding Executables # ------------------------------------------------------------------------------ diff --git a/src/tools/river_regrid/river_regrid.c b/src/tools/river_regrid/river_regrid.c index 0769b65452..4315b2ee62 100644 --- a/src/tools/river_regrid/river_regrid.c +++ b/src/tools/river_regrid/river_regrid.c @@ -14,7 +14,7 @@ char *usage[] = { "", " river_regrid --mosaic mosaic_grid --river_src river_src_file [--output output_file] ", - " [--land_thresh land_thresh] ", + " [--land_thresh land_thresh] [--min_frac min_frac] [--read_land_mask] ", " ", "river_regrid will remap river network data from global regular lat-lon grid onto any ", "other grid (includes regular lat-lon grid and cubic grid ), which is specified ", @@ -41,10 +41,20 @@ char *usage[] = { " value is river_output. For one tile mosaic, the actual ", " result will be $output_file.nc. For multiple tile mosaic, ", " the result will be $output.tile#.nc. ", - "--land_thresh land_thresh Any grid cell with land fraction greater than land_thresh ", - " will be land points, otherwise is a ocean cell. Default ", - " value is 0 ", - " ", + " ", + "--land_thresh land_thresh Any grid cell with land fraction greater than ", + " 1-land_thresh will have land fraction = 1. ", + " Default value is 0 ", + " ", + " ", + "--min_frac min_frac Any grid cell with land fraction less than min_frac will ", + " have land fraction = 0. ", + " ", + "--read_land_mask Read the land fraction from file land_mask.tile#.nc if ", + " it is specified. If not, read the exchange grid and ", + " compute the land fraction. It is recommanded to set this ", + " option when atmosphere grid is a nested grid. ", + " ", NULL }; @@ -64,7 +74,7 @@ const char basin_name[] = "basin"; const char cellarea_name[] = "cellarea"; const char celllength_name[] = "celllength"; const char landfrac_name[] = "land_frac"; -const char tagname[] = "$Name: siena_201205_z1l $"; +const char tagname[] = "$Name: tikal $"; const char version[] = "0.1"; const int ncells = 3; char xaxis_name[128]; @@ -77,6 +87,7 @@ int sizeof_int = 0; int sizeof_double = 0; double suba_cutoff = 1.e12; double land_thresh = 0; +double min_frac = 0; typedef struct { int nx; @@ -110,7 +121,7 @@ typedef struct { void qsort_index(double array[], int start, int end, int rank[]); void get_source_data(const char *src_file, river_type *river_data); void get_mosaic_grid(const char *coupler_mosaic, const char *land_mosaic, - int ntiles, river_type *river_data, unsigned int *opcode); + int ntiles, river_type *river_data, unsigned int *opcode, int read_land_mask, int *great_circle_algorithm); void init_river_data(int ntiles, river_type *river_out, const river_type * const river_in); void calc_max_subA(const river_type *river_in, river_type *river_out, int ntiles, unsigned int opcode); @@ -123,7 +134,7 @@ void sort_basin(int ntiles, river_type* river_data); void check_river_data( ); void write_river_data(const char *river_src_file, const char *output_file, - river_type* river_out, const char *history, int ntiles); + river_type* river_out, const char *history, int ntiles, int great_circle_algorithm); double distance(double lon1, double lat1, double lon2, double lat2); int main(int argc, char* argv[]) @@ -138,6 +149,8 @@ int main(int argc, char* argv[]) char land_mosaic[256]; char land_mosaic_file[256]; char history[1024]; + int read_land_mask = 0; + int great_circle_algorithm = 0; river_type river_in; river_type *river_out; /* may be more than one tile */ @@ -149,6 +162,8 @@ int main(int argc, char* argv[]) {"river_src_file", required_argument, NULL, 'b'}, {"output", required_argument, NULL, 'c'}, {"land_thresh", required_argument, NULL, 'd'}, + {"min_frac", required_argument, NULL, 'e'}, + {"read_land_mask", no_argument, NULL, 'f'}, {0, 0, 0, 0}, }; @@ -172,7 +187,13 @@ int main(int argc, char* argv[]) case 'd': land_thresh = atof(optarg); break; -case '?': + case 'e': + min_frac = atof(optarg); + break; + case 'f': + read_land_mask = 1; + break; + case '?': errflg++; break; } @@ -224,7 +245,7 @@ case '?': } river_out = (river_type *)malloc(ntiles*sizeof(river_type)); - get_mosaic_grid(mosaic_file, land_mosaic, ntiles, river_out, &opcode); + get_mosaic_grid(mosaic_file, land_mosaic, ntiles, river_out, &opcode, read_land_mask, &great_circle_algorithm); init_river_data(ntiles, river_out, &river_in); @@ -238,7 +259,7 @@ case '?': check_river_data(ntiles, river_out); - write_river_data(river_src_file, output_file, river_out, history, ntiles); + write_river_data(river_src_file, output_file, river_out, history, ntiles, great_circle_algorithm); printf("Successfully running river_regrid and the following output file are generated.\n"); for(n=0; n 1 + 1.e-3) mpp_error("river_regrid: land_frac > 1 + 1.e-3" ); + if(river_data[n].landfrac[m] > 1 - land_thresh) river_data[n].landfrac[m] = 1; + if(fabs(river_data[n].landfrac[m]) < min_frac) river_data[n].landfrac[m] = 0; if(river_data[n].landfrac[m] > 1 || river_data[n].landfrac[m] < 0) mpp_error("river_regrid: land_frac should be between 0 or 1"); - } + } + + free(area); } /* n = 0, ntiles */ @@ -1136,16 +1197,16 @@ void check_river_data(int ntiles, river_type *river_data ) if( river_data[n].landfrac[jm1*nx+im1] == 0) { if(tocell!= tocell_missing || travel != travel_missing || basin != basin_missing || subA != subA_missing) { - printf("At ocean points (i=%d,j=%d), subA = %f, tocell = %d, travel = %d, basin = %d.\n ", - i, j, subA, tocell, travel, basin); + printf("At ocean points (i=%d,j=%d,t=%d), subA = %f, tocell = %d, travel = %d, basin = %d.\n ", + i, j, n+1, subA, tocell, travel, basin); mpp_error("river_regrid, subA, tocell, travel, or basin is not missing value for some ocean points"); } } else { if(tocell == tocell_missing || travel == travel_missing || basin == basin_missing || subA == subA_missing) { - printf("At river points (i=%d,j=%d), subA = %f, tocell = %d, travel = %d, basin = %d.\n ", - i, j, subA, tocell, travel, basin); + printf("At river points (i=%d,j=%d,t=%d), subA = %f, tocell = %d, travel = %d, basin = %d.\n ", + i, j, n+1, subA, tocell, travel, basin); mpp_error("river_regrid, subA, tocell, travel, or basin is missing value for some river points"); } } @@ -1158,12 +1219,12 @@ void check_river_data(int ntiles, river_type *river_data ) if(ioff == 1 && joff == 1) continue; if(river_data[n].tocell[jj*nxp2+ii] == tocell_missing) { ncoast_full_land++; - printf("At point (%d,%d), tocell = 0 and landfrac = 1 is a coast point\n", i, j); + printf("At point (i=%d,j=%d,t=%d), tocell = 0 and landfrac = 1 is a coast point\n", i, j, n+1); goto done_check; } } } - printf("At point (%d,%d), tocell = 0 and landfrac = 1 is a sink point\n", i, j); + printf("At point (i=%d,j=%d,t=%d), tocell = 0 and landfrac = 1 is a sink point\n", i, j, n+1); nsink++; done_check: continue; } @@ -1295,7 +1356,8 @@ void sort_basin(int ntiles, river_type* river_data) void write_river_data() write out river network output data which is on land grid. ----------------------------------------------------------------------------*/ -void write_river_data(const char *river_src_file, const char *output_file, river_type* river_data, const char *history, int ntiles) +void write_river_data(const char *river_src_file, const char *output_file, river_type* river_data, + const char *history, int ntiles, int great_circle_algorithm) { double *subA, *yt, *xt; int *tocell, *travel, *basin; @@ -1328,6 +1390,7 @@ void write_river_data(const char *river_src_file, const char *output_file, river fid = mpp_open(river_data[n].filename, MPP_WRITE); mpp_def_global_att(fid, "version", version); mpp_def_global_att(fid, "code_version", tagname); + if(great_circle_algorithm) mpp_def_global_att(fid, "great_circle_algorithm", "TRUE"); mpp_def_global_att(fid, "history", history); dimid[1] = mpp_def_dim(fid, gridx_name, nx); dimid[0] = mpp_def_dim(fid, gridy_name, ny); diff --git a/src/tools/runoff_regrid/env.gaea b/src/tools/runoff_regrid/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/runoff_regrid/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/runoff_regrid/env.gfdl-ws b/src/tools/runoff_regrid/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/runoff_regrid/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/runoff_regrid/env.pan b/src/tools/runoff_regrid/env.pan index 626aa584eb..3d742259a5 100644 --- a/src/tools/runoff_regrid/env.pan +++ b/src/tools/runoff_regrid/env.pan @@ -1,6 +1,5 @@ -# GFDL did not build shared libs for 4.1.1. So we have to add explicit link to libcurl -LIBS2 := -lcurl -CLIBS2 := -lcurl +LIBS2 := +CLIBS2 := # GFDL uses the mpicc wrapper and Intel icc MPICC := mpicc diff --git a/src/tools/runoff_regrid/env.zeus b/src/tools/runoff_regrid/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/runoff_regrid/fre-nctools.mk b/src/tools/runoff_regrid/fre-nctools.mk index 6a6cf1d29a..456725eec0 100644 --- a/src/tools/runoff_regrid/fre-nctools.mk +++ b/src/tools/runoff_regrid/fre-nctools.mk @@ -1,5 +1,5 @@ # -# $Id: fre-nctools.mk,v 1.1.2.1.2.1 2012/06/06 17:04:07 Zhi.Liang Exp $ +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:35:20 fms Exp $ # ------------------------------------------------------------------------------ # FMS/FRE Project: Makefile to Build Regridding Executables # ------------------------------------------------------------------------------ @@ -20,7 +20,7 @@ CFLAGS_O2:= -O2 -g -traceback INCLUDES := -I${NETCDF_HOME}/include -I./ -I../shared -I../../shared/mosaic CLIBS := -L${NETCDF_HOME}/lib -L${HDF5_HOME}/lib -lnetcdf -lhdf5_hl -lhdf5 -lz -limf $(CLIBS2) $(STATIC) -TARGETS := runoff_regrid +TARGETS := runoff_regrid runoff_regrid_parallel SOURCES := runoff_regrid.c SOURCES += create_xgrid.c gradient_c2l.c interp.c read_mosaic.c @@ -38,9 +38,15 @@ all: $(TARGETS) runoff_regrid: $(OBJECTS) mosaic_util.o mpp.o $(CC) -o $@ $^ $(CLIBS) +runoff_regrid_parallel: $(OBJECTS) mosaic_util_parallel.o mpp_parallel.o + $(MPICC) -o $@ $^ $(CLIBS) + mosaic_util.o: ../../shared/mosaic/mosaic_util.c $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -c $< +mosaic_util_parallel.o: ../../shared/mosaic/mosaic_util.c $(HEADERS) + $(MPICC) -Duse_libMPI $(CFLAGS) $(INCLUDES) -o $@ -c $< + read_mosaic.o: ../../shared/mosaic/read_mosaic.c $(HEADERS) $(CC) -Duse_netCDF $(CFLAGS) $(INCLUDES) -c $< @@ -59,6 +65,9 @@ mpp_domain.o: ../shared/mpp_domain.c $(HEADERS) mpp.o: ../shared/mpp.c $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< +mpp_parallel.o: ../shared/mpp.c $(HEADERS) + $(MPICC) -Duse_libMPI $(CFLAGS) $(INCLUDES) -o $@ -c $< + tool_util.o: ../shared/tool_util.c $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< diff --git a/src/tools/runoff_regrid/runoff_regrid.c b/src/tools/runoff_regrid/runoff_regrid.c index 2af36a3431..c5e5fda6ed 100644 --- a/src/tools/runoff_regrid/runoff_regrid.c +++ b/src/tools/runoff_regrid/runoff_regrid.c @@ -28,6 +28,7 @@ #include #include "mpp.h" #include "mpp_io.h" +#include "mpp_domain.h" #include "create_xgrid.h" #include "tool_util.h" @@ -87,7 +88,7 @@ char *usage[] = { " ", NULL}; -char tagname[] = "$Name: siena_201205_z1l $"; +char tagname[] = "$Name: tikal $"; typedef struct { int nx; @@ -112,6 +113,8 @@ typedef struct { int *i_out; int *j_out; double *xgrid_area; + int *imap; + int *jmap; } Remap_type; double distance(double lon1, double lat1, double lon2, double lat2); @@ -155,7 +158,7 @@ int main(int argc, char* argv[]) }; mpp_init(NULL,NULL); - if(mpp_npes() > 1) mpp_error("runoff_regrid: the tool is supposed to run on single processor"); + /* if(mpp_npes() > 1) mpp_error("runoff_regrid: the tool is supposed to run on single processor"); */ while ((c = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { switch (c) { case 'a': @@ -205,20 +208,28 @@ int main(int argc, char* argv[]) strcat(history, " "); strcat(history, argv[i]); } - /* get input grid */ get_input_grid(input_file, input_fld_name, &grid_in); + if(mpp_pe() == mpp_root_pe() )printf("\nNOTE from runoff_regrid: complete get_input_grid\n"); /* get output grid */ get_output_grid(output_mosaic, output_topog, sea_level, &grid_out); + if(mpp_pe() == mpp_root_pe() ) printf("\nNOTE from runoff_regrid: complete get_output_grid\n"); /* computing remapping information */ setup_remap(&grid_in, &grid_out, &remap); + if(mpp_pe() == mpp_root_pe() )printf("\nNOTE from runoff_regrid: complete setup_remap\n"); - /* do the remapping and write out data */ - process_data(input_file, input_fld_name, output_file, output_fld_name, &grid_in, &grid_out, &remap, history); + /* do the remapping and write out data */ + /* process data on the root pe */ + if(mpp_pe() == mpp_root_pe()) { + process_data(input_file, input_fld_name, output_file, output_fld_name, &grid_in, &grid_out, &remap, history); + } - printf("NOTE from runoff_regrid: succefully created runoff data %s\n", output_file); - + if(mpp_pe() == mpp_root_pe() ) printf("NOTE from runoff_regrid: succefully created runoff data %s\n", output_file); + + mpp_end(); + + return 0; } @@ -331,7 +342,7 @@ void get_output_grid(const char *mosaic, const char *topog_file, double sea_leve n_ext = 0; if(tmp[0] > -90 + EPSLN10 ) n_ext = 1; - printf("The south extension is %d\n", n_ext); + if(mpp_pe() == mpp_root_pe() ) printf("The south extension is %d\n", n_ext); nx = ni/2; ny = nj/2; ny_old = ny; @@ -394,6 +405,7 @@ void get_output_grid(const char *mosaic, const char *topog_file, double sea_leve ny = mpp_get_dimlen(fid, "ny"); if(nx != grid->nx || ny != grid->ny-n_ext) mpp_error("runoff_regrid: grid size mismatch between mosaic file and topog file"); + ny += n_ext; depth = (double *)malloc(nx*ny_old*sizeof(double)); grid->mask = (double *)malloc(nx*ny*sizeof(double)); vid = mpp_get_varid(fid, "depth"); @@ -404,48 +416,119 @@ void get_output_grid(const char *mosaic, const char *topog_file, double sea_leve if(depth[(j-n_ext)*nx+i] >sea_level) grid->mask[j*nx+i] = 1.0; } free(depth); - + + + } void setup_remap(const Grid_type *grid_in, const Grid_type *grid_out, Remap_type *remap) { int nx_in, ny_in, nx_out, ny_out; - int nxgrid, i; + int nxgrid, i, j, ii, jj, l, ll; int *i_in, *j_in, *i_out, *j_out; double *xgrid_area; + int npes, layout[2], nxgrid_local; + int isc, iec, jsc, jec, nxc, nyc; + domain2D domain; + double *xc=NULL, *yc=NULL; + int *imap=NULL, *jmap=NULL; + nx_in = grid_in ->nx; ny_in = grid_in ->ny; nx_out = grid_out ->nx; ny_out = grid_out ->ny; + npes = mpp_npes(); + mpp_define_layout(nx_out, ny_out, npes, layout); + mpp_define_domain2d(nx_out, ny_out, layout, 0, 0, &domain); + + mpp_get_compute_domain2d(domain, &isc, &iec, &jsc, &jec); + nxc = iec-isc+1; + nyc = jec-jsc+1; + xc = (double *)malloc((nxc+1)*(nyc+1)*sizeof(double)); + yc = (double *)malloc((nxc+1)*(nyc+1)*sizeof(double)); + + /* copy grid to local data */ + for(j=0; j<=nyc; j++) for(i=0; i<=nxc; i++) { + jj = j+jsc; + ii = i+isc; + xc[j*(nxc+1)+i] = grid_out->xc[jj*(nx_out+1)+ii]; + yc[j*(nxc+1)+i] = grid_out->yc[jj*(nx_out+1)+ii]; + } + i_in = (int *)malloc(MAXXGRID * sizeof(int )); j_in = (int *)malloc(MAXXGRID * sizeof(int )); i_out = (int *)malloc(MAXXGRID * sizeof(int )); j_out = (int *)malloc(MAXXGRID * sizeof(int )); xgrid_area = (double *)malloc(MAXXGRID * sizeof(double)); - - nxgrid = create_xgrid_1dx2d_order1(&nx_in, &ny_in, &nx_out, &ny_out, grid_in->xc1d, - grid_in->yc1d, grid_out->xc, grid_out->yc, + + nxgrid = create_xgrid_1dx2d_order1(&nx_in, &ny_in, &nxc, &nyc, grid_in->xc1d, + grid_in->yc1d, xc, yc, grid_in->mask, i_in, j_in, i_out, j_out, xgrid_area); + /* add isc and jsc to i_out and j_out */ + for(i=0; inxgrid = nxgrid; remap->i_in = (int *)malloc(nxgrid*sizeof(int)); remap->j_in = (int *)malloc(nxgrid*sizeof(int)); remap->i_out = (int *)malloc(nxgrid*sizeof(int)); remap->j_out = (int *)malloc(nxgrid*sizeof(int)); remap->xgrid_area = (double *)malloc(nxgrid*sizeof(double)); - for(i=0; ii_in[i] = i_in[i]; - remap->j_in[i] = j_in[i]; - remap->i_out[i] = i_out[i]; - remap->j_out[i] = j_out[i]; - remap->xgrid_area[i] = xgrid_area[i]; + + mpp_gather_field_int_root( nxgrid_local, i_in, remap->i_in); + mpp_gather_field_int_root( nxgrid_local, j_in, remap->j_in); + mpp_gather_field_int_root( nxgrid_local, i_out, remap->i_out); + mpp_gather_field_int_root( nxgrid_local, j_out, remap->j_out); + mpp_gather_field_double_root( nxgrid_local, xgrid_area, remap->xgrid_area); + + + /* compute the nearest ocean points for any land points */ + imap = (int *)malloc(nxc*nyc*sizeof(int)); + jmap = (int *)malloc(nxc*nyc*sizeof(int)); + remap->imap = (int *)malloc(nx_out*ny_out*sizeof(int)); + remap->jmap = (int *)malloc(nx_out*ny_out*sizeof(int)); + + for(i=0; imask[ll] == 0) { + nearest(nx_out, ny_out, grid_out->mask, grid_out->xt, grid_out->yt, + grid_out->xt[ll], grid_out->yt[ll], &(imap[l]), &(jmap[l]) ); + } + } + } + mpp_global_field_int(domain, nxc, nyc, imap, remap->imap); + mpp_global_field_int(domain, nxc, nyc, jmap, remap->jmap); + + + free(imap); + free(jmap); + + free(xc); + free(yc); free(i_in); free(j_in); free(i_out); free(j_out); free(xgrid_area); + mpp_delete_domain2d(&domain); } @@ -521,6 +604,7 @@ void process_data(const char *infile, const char *fld_name_in, const char *outfi /* loop through ntime */ for(n=0; n 0 && grid_out->mask[l] == 0) { - nearest(nx_out, ny_out, grid_out->mask, grid_out->xt, grid_out->yt, - grid_out->xt[l], grid_out->yt[l], &iout, &jout); + iout = remap->imap[l]; + jout = remap->jmap[l]; data_out[jout*nx_out+iout] += data_out[l]; data_out[l] = 0; } @@ -613,8 +697,9 @@ double distance(double lon1, double lat1, double lon2, double lat2) } /* find the nearest ocean point of a given land point. */ + void nearest(int nlon, int nlat, double *mask, const double *lon, const double *lat, - double plon, double plat, int *iout, int *jout) + double plon, double plat, int *iout, int *jout) { int i,j, n; double r, r1; @@ -632,4 +717,26 @@ void nearest(int nlon, int nlat, double *mask, const double *lon, const double * } } - + +/* do a radial search starting from (iref, jref). */ +/* #define MAX_ITER 1000 */ +/* void radial_search(int nlon, int nlat, double *mask, const double *lon, const double *lat, */ +/* double plon, double plat, int *iout, int *jout, int iref, int jref) */ +/* { */ + +/* iter = 0; */ +/* while (iter #include +#include +#include #ifdef use_libMPI #include #endif @@ -223,6 +225,34 @@ void mpp_sum_double(int count, double *data) }; /* mpp_sum_double */ +void mpp_min_double(int count, double *data) +{ + +#ifdef use_libMPI + int i; + double *minval; + minval = (double *)malloc(count*sizeof(double)); + MPI_Allreduce(data, minval, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + for(i=0; i MAX_BUFFER_SIZE) { + send_buffer = (double *)malloc(send_size*sizeof(double)); + } + else { + send_buffer = sBuffer; + } n = 0; for(k=0; kMAX_BUFFER_SIZE){ + recv_buffer = ( double *) malloc(recv_size*sizeof(double)); + } + else { + recv_buffer = rBuffer; + } mpp_recv_double(recv_buffer, recv_size, p ); n = 0; for(k=0;kMAX_BUFFER_SIZE) + free(recv_buffer); + else + recv_buffer=NULL; } } } - mpp_sync_self(); - - if(send_buffer != NULL) free(send_buffer); +/*z1l: mpp_sync is needed when running on multiple processor job. Otherwisde the memory +usage will increase. For example, remap_land will fail when running on 270 processors */ + mpp_sync(); + + if(send_buffer != NULL) { + if(send_size>MAX_BUFFER_SIZE) + free(send_buffer); + else + send_buffer = NULL; + } }; /* mpp_global_field_double */ /******************************************************************************* @@ -653,7 +757,7 @@ void mpp_gather_field_int_root(int lsize, int *ldata, int *gdata) mpp_sync_self(); if( pe != root_pe) { - if(lsize>0) mpp_send_int(ldata, lsize, p); + if(lsize>0) mpp_send_int(ldata, lsize, root_pe); } else { int cur_size; @@ -684,6 +788,65 @@ void mpp_gather_field_int_root(int lsize, int *ldata, int *gdata) }; /* mpp_gather_field_int_root */ + +/******************************************************************************* + void mpp_gather_field_double_root(int lsize, double *ldata, double *gdata) + gather double data onto root processor +*******************************************************************************/ +void mpp_gather_field_double_root(int lsize, double *ldata, double *gdata) +{ + int n, p, i; + double *rbuffer=NULL; + int *rsize=NULL; + + rsize = (int *)malloc(npes*sizeof(int)); + + /* all other pe except root pe will send data to root pe */ + if( pe != root_pe) { + mpp_send_int(&lsize, 1, root_pe); + } + + else { + for(p = 0; p0) mpp_send_double(ldata, lsize, root_pe); + } + else { + int cur_size; + n = 0; + cur_size = 0; + /* receive from other pe and fill the gdata */ + for(p = 0; p0) { + if( rsize[p] > cur_size ) { + if( rbuffer ) free(rbuffer); + rbuffer = ( double *) malloc(rsize[p]*sizeof(double)); + cur_size = rsize[p]; + } + mpp_recv_double(rbuffer, rsize[p], p ); + for(i=0; i=nfiles) mpp_error("mpp_io(mpp_get_global_att): invalid fid number, fid should be " "a nonnegative integer that less than nfiles"); @@ -499,6 +511,7 @@ void mpp_get_global_att(int fid, const char *name, void *val) name, files[fid].name ); netcdf_error(errmsg, status); } + switch(type) { case NC_DOUBLE:case NC_FLOAT: @@ -511,7 +524,15 @@ void mpp_get_global_att(int fid, const char *name, void *val) status = nc_get_att_short(files[fid].ncid, NC_GLOBAL, name, val); break; case NC_CHAR: - status = nc_get_att_text(files[fid].ncid, NC_GLOBAL, name, val); + status = nc_inq_attlen(files[fid].ncid, NC_GLOBAL, name, &attlen); + if(status != NC_NOERR) { + sprintf(errmsg, "mpp_io(mpp_get_global_att): Error in getting length of global attribute %s from file %s", + name, files[fid].name ); + netcdf_error(errmsg, status); + } + status = nc_get_att_text(files[fid].ncid, NC_GLOBAL, name, attval); + attval[attlen] = '\0'; + strncpy(val, attval, attlen+1); break; default: sprintf(errmsg, "mpp_io(mpp_get_global_att): global attribute %s in file %s has an invalid type, " @@ -711,6 +732,27 @@ int mpp_var_att_exist(int fid, int vid, const char *att) }; /* mpp_att_exist */ +/*************************************************************************** + int mpp_global_att_exist(int fid, const char *att) + check has the global attribute "att" or not. +***************************************************************************/ +int mpp_global_att_exist(int fid, const char *att) +{ + int status; + size_t attlen; + nc_type atttype; + + if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_global_att_exist): invalid fid number, fid should be " + "a nonnegative integer that less than nfiles"); + + status = nc_inq_att(files[fid].ncid, NC_GLOBAL, att, &atttype, &attlen); + if(status == NC_NOERR) + return 1; + else + return 0; + +}; /* mpp_att_exist */ + /*******************************************************************************/ /* */ @@ -842,6 +884,8 @@ void mpp_def_var_att(int fid, int vid, const char *attname, const char *attval) int ncid, fldid, status; char errmsg[512]; + if( mpp_pe() != mpp_root_pe() ) return; + if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_def_var_att): invalid fid number, fid should be " "a nonnegative integer that less than nfiles"); if(vid<0 || vid >=files[fid].nvar) mpp_error("mpp_io(mpp_def_var_att): invalid vid number, vid should be " @@ -1146,3 +1190,29 @@ int mpp_var_exist(int fid, const char *field) } +int get_great_circle_algorithm(int fid) +{ + char attval[256]; + char errmsg[512]; + int great_circle_algorithm = 0; + + if(fid<0 || fid >=nfiles) mpp_error("mpp_io(get_great_circle_algorithm): invalid fid number, fid should be " + "a nonnegative integer that less than nfiles"); + + if(mpp_global_att_exist(fid, "great_circle_algorithm")) { + mpp_get_global_att(fid, "great_circle_algorithm", attval); + + if(!strcmp(attval, "TRUE")) + great_circle_algorithm = 1; + else if(!strcmp(attval, "FALSE")) + great_circle_algorithm = 0; + else { + sprintf(errmsg, "mpp_io: global atribute 'great_circle_algorithm' " + "in file %s should have value 'TRUE' or 'FALSE'", files[fid].name); + mpp_error(errmsg); + } + } + + return great_circle_algorithm; +} + diff --git a/src/tools/shared/mpp_io.h b/src/tools/shared/mpp_io.h index a6c97073f4..eebf07e6b2 100644 --- a/src/tools/shared/mpp_io.h +++ b/src/tools/shared/mpp_io.h @@ -16,8 +16,9 @@ will be written out from root pe. #define MPP_INT NC_INT #define MPP_DOUBLE NC_DOUBLE #define MPP_CHAR NC_CHAR -#define MPP_ #define HEADER_BUFFER_VALUE (16384) +#define MPP_FILL_INT NC_FILL_INT +#define MPP_FILL_DOUBLE NC_FILL_DOUBLE int mpp_open(const char *file, int action); void mpp_close(int ncid); @@ -38,7 +39,7 @@ void mpp_get_var_dimname(int fid, int vid, int ind, char *name); char mpp_get_dim_cart(int fid, const char *name); void mpp_get_var_bndname(int fid, int vid, char *bndname); int mpp_var_att_exist(int fid, int vid, const char *att); - +int mpp_global_att_exist(int fid, const char *att); int mpp_def_dim(int fid, const char* name, int size); int mpp_def_var(int fid, const char* name, nc_type type, int ndim, const int *dims, int natts, ...); void mpp_def_global_att(int fid, const char *name, const char *val); @@ -54,4 +55,5 @@ int mpp_file_exist(const char *file); int mpp_field_exist(const char *file, const char *field); int mpp_var_exist(int fid, const char *field); int mpp_dim_exist(int fid, const char *dimname); +int get_great_circle_algorithm(int fid); #endif diff --git a/src/tools/shared/tool_util.c b/src/tools/shared/tool_util.c index 834d8bbccf..58c9a30791 100644 --- a/src/tools/shared/tool_util.c +++ b/src/tools/shared/tool_util.c @@ -1,4 +1,5 @@ #include +#include #include #include #include "constant.h" diff --git a/src/tools/transfer_to_mosaic_grid/Makefile b/src/tools/transfer_to_mosaic_grid/Makefile deleted file mode 100644 index 5a6b207bac..0000000000 --- a/src/tools/transfer_to_mosaic_grid/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# The following three directory may need to set. -NETCDFPATH = /usr/local/netcdf-3.6.2 -SHAREDIR = $(PWD)/../../shared/mosaic -COREDIR = $(PWD) -TOOLSHAREDIR = $(PWD)/../shared -#CFLAGS = -O0 -g -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -CFLAGS = -O2 -fast -I$(TOOLSHAREDIR) -I$(COREDIR) -I$(SHAREDIR) -I${NETCDFPATH}/include -I/usr/include -LDFLAGS = -L${NETCDFPATH}/lib -lm -lnetcdf -LNFLAGS = -v -CC = icc - -OBJSM = mpp.o mpp_domain.o mpp_io.o transfer_to_mosaic.o create_xgrid.o mosaic_util.o - -HEADERS = Makefile $(TOOLSHAREDIR)/mpp.h $(TOOLSHAREDIR)/mpp_domain.h \ - $(TOOLSHAREDIR)/mpp_io.h $(SHAREDIR)/create_xgrid.h \ - $(SHAREDIR)/mosaic_util.h - -transfer_to_mosaic_grid: $(OBJSM) - $(CC) $(LNFLAGS) -o $@ $(OBJSM) $(LDFLAGS) - -run: - transfer_to_mosaic -clean: - rm -f *.o transfer_to_mosaic - -transfer_to_mosaic.o: $(COREDIR)/transfer_to_mosaic.c $(HEADERS) - $(CC) $(CFLAGS) -c $(COREDIR)/transfer_to_mosaic.c - -mpp.o: $(TOOLSHAREDIR)/mpp.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp.c - -mpp_domain.o: $(TOOLSHAREDIR)/mpp_domain.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_domain.c - -mpp_io.o: $(TOOLSHAREDIR)/mpp_io.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/mpp_io.c - -create_xgrid.o: $(SHAREDIR)/create_xgrid.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/create_xgrid.c - -tool_util.o: $(TOOLSHAREDIR)/tool_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(TOOLSHAREDIR)/tool_util.c - -mosaic_util.o: $(SHAREDIR)/mosaic_util.c $(HEADERS) - $(CC) $(CFLAGS) -c $(SHAREDIR)/mosaic_util.c diff --git a/src/tools/transfer_to_mosaic_grid/env.gaea b/src/tools/transfer_to_mosaic_grid/env.gaea new file mode 100644 index 0000000000..6e992f2719 --- /dev/null +++ b/src/tools/transfer_to_mosaic_grid/env.gaea @@ -0,0 +1,4 @@ +# ORNL uses the cc wrapper +MPICC := cc +CC := icc +STATIC := -static diff --git a/src/tools/transfer_to_mosaic_grid/env.gfdl-ws b/src/tools/transfer_to_mosaic_grid/env.gfdl-ws new file mode 100644 index 0000000000..3d742259a5 --- /dev/null +++ b/src/tools/transfer_to_mosaic_grid/env.gfdl-ws @@ -0,0 +1,6 @@ +LIBS2 := +CLIBS2 := + +# GFDL uses the mpicc wrapper and Intel icc +MPICC := mpicc +CC := icc diff --git a/src/tools/transfer_to_mosaic_grid/env.pan b/src/tools/transfer_to_mosaic_grid/env.pan index 626aa584eb..3d742259a5 100644 --- a/src/tools/transfer_to_mosaic_grid/env.pan +++ b/src/tools/transfer_to_mosaic_grid/env.pan @@ -1,6 +1,5 @@ -# GFDL did not build shared libs for 4.1.1. So we have to add explicit link to libcurl -LIBS2 := -lcurl -CLIBS2 := -lcurl +LIBS2 := +CLIBS2 := # GFDL uses the mpicc wrapper and Intel icc MPICC := mpicc diff --git a/src/tools/transfer_to_mosaic_grid/env.zeus b/src/tools/transfer_to_mosaic_grid/env.zeus new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/tools/transfer_to_mosaic_grid/fre-nctools.mk b/src/tools/transfer_to_mosaic_grid/fre-nctools.mk index 5114646f86..7cfd5f7225 100644 --- a/src/tools/transfer_to_mosaic_grid/fre-nctools.mk +++ b/src/tools/transfer_to_mosaic_grid/fre-nctools.mk @@ -1,5 +1,5 @@ # -# $Id: fre-nctools.mk,v 19.0.2.1 2012/06/06 17:10:44 Zhi.Liang Exp $ +# $Id: fre-nctools.mk,v 20.0 2013/12/14 00:35:45 fms Exp $ # ------------------------------------------------------------------------------ # FMS/FRE Project: Makefile to Build Regridding Executables # ------------------------------------------------------------------------------