diff --git a/CVMix_tools/code_consistency.py b/CVMix_tools/code_consistency.py index 759ea85bd..827618734 100755 --- a/CVMix_tools/code_consistency.py +++ b/CVMix_tools/code_consistency.py @@ -220,12 +220,14 @@ def check_r8_settings(self, file_and_line, line, comment_char="!"): fortran_files = [] # pylint: disable=C0103 python_files = [] # pylint: disable=C0103 + perl_files = [] # pylint: disable=C0103 for root, dirs, files in os.walk(CVMIX_ROOT): for thisfile in files: if thisfile.endswith(".F90"): fortran_files.append(os.path.join(root, thisfile)) elif thisfile.endswith(".py"): python_files.append(os.path.join(root, thisfile)) + perl_files.append(os.path.join(CVMIX_ROOT, 'doc', 'protex')) # Use logging to write messages to stdout logging.basicConfig(format='%(message)s', level=logging.DEBUG) @@ -267,7 +269,21 @@ def check_r8_settings(self, file_and_line, line, comment_char="!"): PYTHON_ERROR_COUNT = Tests.process() LOGGER.info("Python errors found: %d", PYTHON_ERROR_COUNT) - if FORTRAN_ERROR_COUNT + PYTHON_ERROR_COUNT > 0: + # Perl error checks + LOGGER.info("\nCheck perl files for coding standard violations:") + for thisfile in perl_files: + with open(thisfile, "r") as perl_file: + line_cnt = 0 + for thisline in perl_file.readlines(): + line_without_cr = thisline.rstrip("\n") + line_cnt = line_cnt + 1 + file_and_line_number = "%s:%d" % (thisfile, line_cnt) + Tests.check_for_hard_tabs(file_and_line_number, line_without_cr) + Tests.check_for_trailing_whitespace(file_and_line_number, line_without_cr) + PERL_ERROR_COUNT = Tests.process() + LOGGER.info("Perl errors found: %d", PERL_ERROR_COUNT) + + if FORTRAN_ERROR_COUNT + PYTHON_ERROR_COUNT + PERL_ERROR_COUNT > 0: LOGGER.info("\nTotal error count: %d", FORTRAN_ERROR_COUNT + PYTHON_ERROR_COUNT) sys.exit(1) diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 000000000..a3aefbebb --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +protex_out/* diff --git a/doc/make_protex_file b/doc/make_protex_file index d0f196665..ed8ae56d9 100755 --- a/doc/make_protex_file +++ b/doc/make_protex_file @@ -1,9 +1,19 @@ -#!/bin/bash +#!/bin/bash -e SRC=../src DRIVE=$SRC/drivers SHARE=$SRC/shared -f90pdf \ + +mkdir -p protex_out +rm -f protex_out/protex_documentation.* +./protex -s -F -g +n \ + $SRC/cvmix_driver.F90 \ + $DRIVE/cvmix_bgrnd_BL.F90 \ + $DRIVE/cvmix_shear_drv.F90 \ + $DRIVE/cvmix_tidal_Simmons.F90 \ + $DRIVE/cvmix_ddiff_drv.F90 \ + $DRIVE/cvmix_kpp_drv.F90 \ + $SRC/cvmix_io.F90 \ $SHARE/cvmix_kinds_and_types.F90 \ $SHARE/cvmix_background.F90 \ $SHARE/cvmix_shear.F90 \ @@ -13,14 +23,10 @@ f90pdf \ $SHARE/cvmix_convection.F90 \ $SHARE/cvmix_math.F90 \ $SHARE/cvmix_put_get.F90 \ - $SHARE/cvmix_utils.F90 \ - $SRC/cvmix_driver.F90 \ - $DRIVE/cvmix_bgrnd_BL.F90 \ - $DRIVE/cvmix_shear_drv.F90 \ - $DRIVE/cvmix_tidal_Simmons.F90 \ - $DRIVE/cvmix_ddiff_drv.F90 \ - $DRIVE/cvmix_kpp_drv.F90 \ - $SRC/cvmix_io.F90 + $SHARE/cvmix_utils.F90 > \ + protex_out/protex_documentation.tex -rm -f output.tex -mv -f output.pdf protex_documentation.pdf +cd protex_out +pdflatex protex_documentation.tex +pdflatex protex_documentation.tex +cp -f protex_documentation.pdf ../ diff --git a/doc/protex b/doc/protex new file mode 100755 index 000000000..d371b2d80 --- /dev/null +++ b/doc/protex @@ -0,0 +1,1255 @@ +#!/usr/bin/perl +# +# $Id: protex,v 1.2 2009/09/16 14:05:52 bmy Exp $ +# +# MNL note: +# This script was downloaded from +# https://github.com/geoschem/geos-chem/blob/v8-03-01/doc/protex +# I also brought in some updates from J. K. Dewhurst's script found at +# https://sourceforge.net/p/elk/discussion/897822/thread/37afb1f97d/#4ecb +# to account for things like perl no longer supporting a change in +# the array-indexing (older protex versions forced indexing to be 1-based +# but now it is 0-based). I also liked Dewhurst's title page. +# +#BOP +# +# !ROUTINE: ProTeX v. 2.00 - Translates DAO Prologues to LaTeX +# +# !INTERFACE: +# protex [-hbgACFS] ] [+-nlsxf] [src_file(s)] +# +# !DESCRIPTION: +# Perl filter to produce a \LaTeX compatible document +# from a DAO Fortran source code with standard Pro\TeX +# prologues. If source files are not specified it +# reads from stdin; output is always to stdout. +# +# \noindent +# {\bf Command Line Switches:} \vspace{0.2cm} +# +# \begin{center} +# \begin{tabular}{|c|l|} \hline \hline +# -h & Help mode: list command line options \\ \hline +# -b & Bare mode, meaning no preamble, etc. \\ \hline +# -i & internal mode: omit prologues marked !BOPI \\ \hline +# -g & Use GEOS style. Implies -n unless overidden. +# +/-n & New Page for each subsection (wastes paper) \\ \hline +# +/-l & Listing mode, default is prologues only \\ \hline +# +/-s & Shut-up mode, i.e., ignore any code from BOC to EOC \\ \hline +# +/-x & No LaTeX mode, i.e., put !DESCRIPTION: in verbatim mode \\ \hline +# +/-f & No source file info \\ \hline +# -A & Ada code \\ \hline +# -C & C++ code \\ \hline +# -F & F90 code (default) \\ \hline +# -S & Shell script \\ \hline \hline +# \end{tabular} +# \end{center} +# +# The options can appear in any order. The options, -h and -b, affect +# the input from all files listed on command-line input. Each of the +# remaining options affects only the input from the files listed after +# the option and prior to any overriding option. The plus sign +# turns off the option. For example, the command-line input, +# \bv +# protex -bnS File1 -F File2.f +n File3.f +# \ev +# will cause the option, {\tt -n} to affect the input from the files, +# {\tt File} and {\tt File2.f}, but not from {\tt File3.f}. The +# {\tt -S} option is implemented for {\tt File1} but is overridden by +# the {\tt -F} for files {\tt File2.f} and {\tt File3.f}. +# +# +# !SEE ALSO: +# For a more detailed description of ProTeX functionality, +# DAO Prologue and other conventions, consult: +# +# Sawyer, W., and A. da Silva, 1997: ProTeX: A Sample +# Fortran 90 Source Code Documentation System. +# DAO Office Note 97-11 +# +# +# !REVISION HISTORY: +# +# 20Dec1995 da Silva First experimental version +# 10Nov1996 da Silva First internal release (v1.01) +# 28Jun1997 da Silva Modified so that !DESCRIPTION can appear after +# !INTERFACE, and !INPUT PARAMETERS etc. changed to italics. +# 02Jul1997 Sawyer Added shut-up mode +# 20Oct1997 Sawyer Added support for shell scripts +# 11Mar1998 Sawyer Added: file name, date in header, C, script support +# 05Aug1998 Sawyer Fixed LPChang-bug-support-for-files-with-underscores +# 10Oct1998 da Silva Introduced -f option for removing source file info +# from subsection, etc. Added help (WS). +# 06Dec1999 C. Redder Added LaTeX command "\label{sec:prologues}" just +# after the beginning of the proglogue section. +# 13Dec1999 C. Redder Increased flexbility in command-line +# interface. The options can appear in any +# order which will allow the user to implement +# options for select files. +# 01Feb1999 C. Redder Added \usepackage commands to preamble of latex +# document to include the packages amsmath, epsfig +# and hangcaption. +# 10May2000 C. Redder Revised LaTeX command "\label{sec:prologues}" +# to "\label{app:ProLogues}" +# 10/10/2002 da Silva Introduced ARGUMENTS keyword, touch ups. +# +# 15Jan2003 R. Staufer Modified table of contents to print only section headers - no descriptions +# +# 25Feb2003 R. Staufer Added BOPI/EOPI and -i (internal) switch to provide the option of omitting prologue information from output files. +# 28Jul2009 R. Yantosca Hack added to suppress printing "Fortran" if we +# are using the "!MODULE" tag for shell scripts or +# Makefiles. +# +#EOP +#---------------------------------------------------------------------------- + +# Keep this if you don't know what it does... +# ------------------------------------------- +### $[ = 1; # set array base to 1 (removed to maintain Perl 5.30 compatibility) + $, = ' '; # set output field separator + $\ = "\n"; # set output record separator + +# Set valid options lists +# ----------------------- + $GlobOptions = 'hbg'; # Global options (i.e for all files) + $LangOptions = 'ACFS'; # Options for setting programming languages + $SwOptions = 'flinsx'; # Options that can change for each input + # file + $RegOptions = "$GlobOptions$LangOptions"; + # Scan for global options until first first + # file is processed. + +# Scan for global options +# ----------------------- + $NFiles = 0; +Arg: + foreach $arg (@ARGV) { + $option = &CheckOpts ( $arg, $RegOptions, $SwOptions ) + 1; + if ( $option ) { + $rc = &GetOpts ( $arg, $GlobOptions ); + next Arg; } + + else { $NFiles++; +}# end if +}# end foreach + +# If all input arguments are options, then assume the +# filename, "-", for the standard input +# -------------------------------------------------- + if ( $NFiles == 0 ) { push (@ARGV, "-"); } + +# Implement help option +# --------------------- + if ( $opt_h ) { + &print_help(); + exit(); +} #end if + +# -g implies -n +# --------------------- + if ( $opt_g ) { + $opt_n=1; +}#end if + +# Optional Prologue Keywords +# -------------------------- + @keys = ( "!INTERFACE:", + "!USES:", + "!PUBLIC TYPES:", + "!PRIVATE TYPES:", + "!PUBLIC MEMBER FUNCTIONS:", + "!PRIVATE MEMBER FUNCTIONS:", + "!PUBLIC DATA MEMBERS:", + "!PARAMETERS:", + "!ARGUMENTS:", + "!IMPORT STATE:", + "!EXPORT STATE:", + "!INTERNAL STATE:", + "!DEFINED PARAMETERS:", + "!INPUT PARAMETERS:", + "!INPUT/OUTPUT PARAMETERS:", + "!OUTPUT PARAMETERS:", + "!RETURN VALUE:", + "!REVISION HISTORY:", + "!BUGS:", + "!SEE ALSO:", + "!SYSTEM ROUTINES:", + "!FILES USED:", + "!REMARKS:", + "!TO DO:", + "!CALLING SEQUENCE:", + "!AUTHOR:", + "!CALLED FROM:", + "!LOCAL VARIABLES:" ); + +# Initialize these for clarity +# ---------------------------- + $intro = 0; # doing introduction? + $prologue = 0; # doing prologue? + $first = 1; # first prologue? + $source = 0; # source code mode? + $verb = 0; # verbatim mode? + $tpage = 0; # title page? + $begdoc = 0; # has \begin{document} been written? + $inspec = 0; # are we processing state specs + $initem = 0; # are we processing state specs item + +# Initial LaTeX stuff +# ------------------- + &print_notice(); + &print_preamble(); # \documentclass, text dimensions, etc. + &print_macros(); # short-hand LaTeX macros + +# Main loop -- for each command-line argument +# ------------------------------------------- +ARG: + foreach $arg (@ARGV) { + +# Scan for non-global command-line options +# ---------------------------------------- + $option = &CheckOpts ( $arg, $RegOptions, $SwOptions, "quiet" ) + 1; + if ( $option ) { + &GetOpts ( $arg, $SwOptions ); + &SetOpt ( $arg, $LangOptions ); + next ARG; + +}# end if + +# Determine the type of code, set corresponding search strings +# ------------------------------------------------------------ +# if ( $opt_F ) { # FORTRAN + $comment_string = '!'; # ------- + $boi_string = '!BOI'; + $eoi_string = '!EOI'; + $bop_string = '!BOP'; + $eop_string = '!EOP'; + $bopi_string = '!BOPI'; + $eopi_string = '!EOPI'; + $boc_string = '!BOC'; + $eoc_string = '!EOC'; + $boe_string = '!BOE'; + $eoe_string = '!EOE'; +#}# end if + + if ( $opt_A ) { # ADA + $comment_string = '--'; # --- + $boi_string = '--BOI'; + $eoi_string = '--EOI'; + $bop_string = '--BOP'; + $eop_string = '--EOP'; + $bopi_string = '--BOPI'; + $eopi_string = '--EOPI'; + $boc_string = '--BOC'; + $eoc_string = '--EOC'; + $boe_string = '--BOE'; + $eoe_string = '--EOE'; +}# end if + + if ( $opt_C ) { + $comment_string = '//'; # C + $boi_string = '//BOI'; # - + $eoi_string = '//EOI'; + $bop_string = '//BOP'; + $eop_string = '//EOP'; + $bopi_string = '//BOPI'; + $eopi_string = '//EOPI'; + $boc_string = '//BOC'; + $eoc_string = '//EOC'; + $boe_string = '//BOE'; + $eoe_string = '//EOE'; +}# end if + + if ( $opt_S ) { # Script + $comment_string = '#'; # ------ + $boi_string = '#BOI'; + $eoi_string = '#EOI'; + $bop_string = '#BOP'; + $eop_string = '#EOP'; + $bopi_string = '#BOPI'; + $eopi_string = '#EOPI'; + $boc_string = '#BOC'; + $eoc_string = '#EOC'; + $boe_string = '#BOE'; + $eoe_string = '#EOE'; +}# end if + +# Set file name parameters +# ------------------------ + $InputFile = $arg; + @all_path_components = split( /\//, $InputFile ); + $FileBaseName = pop ( @all_path_components ); + $FileBaseName =~ s/_/\\_/g; + if ( $InputFile eq "-" ) {$FileBaseName = "Standard Input";} + +# Set date +# -------- + $Date = `date`; + +# Open current file +# ----------------- + open ( InputFile, "$InputFile" ) + or print STDERR "Unable to open $InputFile: $!"; + +# Print page header +# ----------------- + + if($opt_g) { + $shname = " "; + $lnname = " "; + $units = " "; + $dims = " "; + $locs = " "; } + else { + printf "\n\\markboth{Left}{Source File: %s, Date: %s}\n\n", + $FileBaseName, $Date; + }# endif + +LINE: +# Inner loop --- for processing each line of the input file +# --------------------------------------------------------- + while ( ) { + chop; # strip record separator + +# !PARAMETERS: really mean !ARGUMENTS: +# ------------------------------------ +# s/!PARAMETERS:/!ARGUMENTS:/g; + + @Fld = split(' ', $_, 9999); + +# Straight quote +# -------------- + if ( ($Fld[0] eq '!QUOTE:') || ($opt_g && ($Fld[0] eq '!!GEOS!!') ) ) { + if($opt_g) {printf "\n";} + for ($i = 1; $i < $#Fld; $i++) { + printf '%s ', $Fld[$i]; +}# end for + print " "; + next LINE; +}# end if + +# Handle optional Title Page and Introduction +# ------------------------------------------- + if ($Fld[0] eq $boi_string) { + print ' '; + $intro = 1; + next LINE; +}# end if + + if ($Fld[1] eq '!TITLE:') { + if ( $intro ) { + shift @Fld; + shift @Fld; + @title = @Fld; + $tpage = 1; + next LINE; +}# end if +}# end if + + if ($Fld[1] eq '!AUTHORS:') { + if ( $intro ) { + shift @Fld; + shift @Fld; + @author = @Fld; + $tpage = 1; + next LINE; +}# end if +}# end if + + if ($Fld[1] eq '!AFFILIATION:') { + if ( $intro ) { + shift @Fld; + shift @Fld; + @affiliation = @Fld; + $tpage = 1; + next LINE; +}# end if +}# end if + + if ($Fld[1] eq '!DATE:') { + if ( $intro ) { + shift @Fld; + shift @Fld; + @date = @Fld; + $tpage = 1; + next LINE; +}# end if +}# end if + + if ($Fld[1] eq '!INTRODUCTION:') { + if ( $intro ) { + &do_beg(); + print ' '; + print '%..............................................'; + shift @Fld; + shift @Fld; + if($opt_g) { + print "\\part{\\Large @Fld}";} + else{ + print "\\section{@Fld}"; +}# end if + next LINE; +}# end if +}# end if + + +# End of introduction +# ------------------- + if ($Fld[0] eq $eoi_string) { + print ' '; + print '%/////////////////////////////////////////////////////////////'; + print "\\newpage"; + $intro = 0; + next LINE; +}# end if + +# Beginning of prologue +# --------------------- + if ($Fld[0] eq $bop_string) { + if ( $source ) { &do_eoc(); } + print ' '; + print '%/////////////////////////////////////////////////////////////'; + &do_beg(); + if ($first == 0 && $opt_n==0) { + ### print "\\newpage"; + print " "; + print "\\mbox{}\\hrulefill\\ "; + print " ";} + else { + unless($opt_b || $opt_g) { + print "\\section{Routine/Function Prologues} \\label{app:ProLogues}"; + } +}# end if + + $first = 0; + $prologue = 1; + $verb = 0; + $source = 0; + $inspec = 0; + &set_missing(); # no required keyword yet + next LINE; +}# end if + +# Beginning of internal prologue +# ------------------------------ + if ($Fld[0] eq $bopi_string) { + if ($opt_i) {$prologue = 0;} + else { + if ($source) { &do_eoc(); } + print ' '; + print '%/////////////////////////////////////////////////////////////'; + &do_beg(); + if ($first ==0 && $opt_n==0) { + ### print "\\newpage"; + print " "; + print "\\mbox{}\\hrulefill\\"; + print " ";} + else { + unless($opt_b || $opt_g) { + print "\\section{Routine/Function Prologues} \\label{app:ProLogues}"; + } +}# endif + $first = 0; + $prologue = 1; + $verb = 0; + $source = 0; + $inspec = 0; + &set_missing(); # no required keyword yet + next LINE; + }# endelse + }# endif + +# A new subroutine/function +# ------------------------- + if ($Fld[1] eq '!ROUTINE:' ) { + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + if ( $opt_n && $not_first ) { printf "\\newpage\n"; } + unless ($opt_f) {printf "\\subsubsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsubsection{%s }\n\n", $_;} + $have_name = 1; + $not_first = 1; + next LINE; +}# end if +}# end if + +# A new Module +# ------------ + if ($Fld[1] eq '!MODULE:' ) { + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + if ( $opt_n && $not_first ) { printf "\\newpage\n"; } + if($opt_g) { + printf "\\section [%s] {Module %s }\n\n", $_,$_;} + else { +#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#%%% Hack added by Bob Yantosca to suppress printing "Fortran" if we are +#%%% using the "!MODULE" tag for shell scripts or Makefiles. (bmy, 7/28/09) + if ( $opt_S ) { + #---------------------------------------- + # Shell scripts: don't print "Fortran" + #---------------------------------------- + unless($opt_f) {printf "\\subsection{Module Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsection{Module Interface %s }\n\n", $_;} + } else { + #---------------------------------------- + # F90 code: do print "Fortran" + #---------------------------------------- + unless($opt_f) {printf "\\subsection{Fortran: Module Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsection{Fortran: Module Interface %s }\n\n", $_;} + } +#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } # endif + + $have_name = 1; + $have_intf = 1; # fake it, it does not need one. + $not_first = 1; + next LINE; +}# end if +}# end if + +# A new include file +# ------------------ + if ($Fld[1] eq '!INCLUDE:' ) { + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + if ( $opt_n && $not_first ) { printf "\\newpage\n"; } + unless($opt_f) {printf "\\subsubsection{Include File %s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsubsection{Include File %s }\n\n", $_;} + $have_name = 1; + $have_intf = 1; # fake it, it does not need one. + $not_first = 1; + next LINE; +}# end if +}# end if + +# A new INTERNAL subroutine/function +# ---------------------------------- + if ($Fld[1] eq '!IROUTINE:') { # Internal routine + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + @words = split " ", $_; + if ( $opt_n && $not_first ) {printf "\\newpage\n";} + if($opt_g) {printf "\\subsection [$words[0]] {$_}\n\n";} + else {printf "\\subsubsection [$words[0]] {$_}\n\n";} + $have_name = 1; + next LINE; +}# end if +}# end if + +# A new CONTAINED subroutine/function +# ---------------------------------- + + if ($Fld[1] eq '!CROUTINE:') { # Contained routine + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + @words = split " ", $_; + printf "\\subsubsection [$words[0]] {$_}\n\n"; + $have_name = 1; + next LINE; +}# end if +}# end if + +# A new CLASS +# ------------ + if ($Fld[1] eq '!CLASS:' ) { + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + if ( $opt_n && $not_first ) { printf "\\newpage\n"; } + unless($opt_f) {printf "\\subsection{C++: Class Interface %s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsection{C++: Class Interface %s }\n\n", $_;} + $have_name = 1; + $have_intf = 1; # fake it, it does not need one. + $not_first = 1; + next LINE; +}# end if +}# end if + +# A new Method +# ------------------------- + if ($Fld[1] eq '!METHOD:' ) { + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + if ( $opt_n && $not_first ) { printf "\\newpage\n"; } + unless ($opt_f) {printf "\\subsubsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsubsection{%s }\n\n", $_;} + $have_name = 1; + $not_first = 1; + next LINE; +}# end if +}# end if + +# A new function +# ------------------------- + if ($Fld[1] eq '!FUNCTION:' ) { + if ($prologue) { + shift @Fld; + shift @Fld; + $_ = join(' ', @Fld); + $name_is = $_; + s/_/\\_/g; # Replace "_" with "\_" + if ( $opt_n && $not_first ) { printf "\\newpage\n"; } + unless ($opt_f) {printf "\\subsubsection{%s (Source File: %s)}\n\n", $_, $FileBaseName;} + else {printf "\\subsubsection{%s }\n\n", $_;} + $have_name = 1; + $not_first = 1; + next LINE; +}# end if +}# end if + +# Description: what follows will be regular LaTeX (no verbatim) +# ------------------------------------------------------------- + if (/!DESCRIPTION:/) { + if ($prologue) { + if ($verb) { + printf "\\end{verbatim}"; + printf "\n{\\sf \\bf DESCRIPTION:\\\\ }\n\n"; + $verb = 0; } + else { # probably never occurs +}# end if + if ($opt_x) { + printf "\\begin{verbatim} "; + $verb = 1; + $first_verb = 1; } + else { + for ($i = 2; $i < $#Fld; $i++) { + printf '%s ', $Fld[$i]; +}# end for +}# end if + ### print " "; + $have_desc = 1; + next LINE; +}# end if +}# end if + +# Handle optional keywords (these will appear as verbatim) +# -------------------------------------------------------- + if ($prologue) { +KEY: foreach $key ( @keys ) { + if ( /$key/ ) { + if ($verb) { + printf "\\end{verbatim}"; + $verb = 0; +}# end if + $k = sprintf('%s', $key); + $ln = length($k); + $_ = $key; + if(opt_g) { + if( /IMPORT STATE/ || /EXPORT STATE/ || /INTERNAL STATE/ ) { + if($inspec) { + &beg_item(); +}# end if + printf "\n \\bigskip \n {\\bf %s} \n \n", substr($k, 1, $ln - 2); + &hed_item(); + $inspec = 1; + $initem = 0; + next LINE; + } else { + printf "{\\bf %s}\n", substr($k, 1, $ln - 2); } # italics +}# end if + else { + if( /USES/ || /INPUT/ || /OUTPUT/ || /PARAMETERS/ || + /VALUE/ || /ARGUMENTS/ ) { + printf "{\\em %s}\n", substr($k, 1, $ln - 2); } # italics + else { + printf "{\\sf %s}\n", substr($k, 1, $ln - 2); # san serif +}# end if +}# end if + + printf "\\begin{verbatim} "; + $verb = 1; + $first_verb = 1; + if ( $key eq "!INTERFACE:" ) { $have_intf = 1; } + if ( $key eq "!CALLING SEQUENCE:" ) { $have_intf = 1; } + if ( $key eq "!REVISION HISTORY:" ) { $have_hist = 1; } + next LINE; +}# end if +}# end foreach +}# end if + +# End of prologue +# --------------- + if ($Fld[0] eq $eop_string) { + if ($verb) { + print "\\end{verbatim}"; + $verb = 0; +}# end if + if ($opt_g && $inspec) { + &beg_item(); + $inspec = 0; +}# end if + $prologue = 0; +# &check_if_all_there(); # check if all required keywords are there. + if ( $opt_l ) { + $Fld[0] = $boc_string;} + else { next LINE; } +}# end if + + unless ( $opt_s ) { + +# End of Internal Prologue +# ------------------------ + + if ($Fld[0] eq $eopi_string) { + if ($verb) { + print "\\end{verbatim}"; + $verb = 0; +}# endif + if ($opt_g && $inspec) { + &beg_item(); + $inspec = 0; +}# endif + $prologue = 0; +# &check_if_all_there(); # check if all required keywords are there. + if ($opt_l) { + $Fld[0] = $boc_string;} + else { next LINE; } +}# endif + +# +# Beginning of source code section +# -------------------------------- + if ($Fld[0] eq $boc_string) { + print ' '; + print '%/////////////////////////////////////////////////////////////'; + $first = 0; + $prologue = 0; + $source = 1; + ### printf "\\subsubsection*{CONTENTS:}\n\n", $Fld[2]; + ###printf "{\\sf CONTENTS:}"; + printf "\n \\begin{verbatim}\n"; + $verb = 1; + next LINE; +}# end if + +# End of source code +# ------------------ + if ($Fld[0] eq $eoc_string) { + &do_eoc(); + $prologue = 0; + next LINE; +}# end if + +# Beginning of example prologue +# ----------------------------- + if ($Fld[0] eq $boe_string) { + if ( $source ) { &do_eoc(); } + print ' '; + print '%/////////////////////////////////////////////////////////////'; + $first = 0; + $prologue = 1; + $verb = 0; + $source = 0; + next LINE; +}# end if + +# End of example prologue +# ----------------------- + if ($Fld[0] eq $eoe_string) { + if ($verb) { + print "\\end{verbatim}"; + $verb = 0; +}# end if + $prologue = 0; + if ( $opt_l ) { + $Fld[0] = $boc_string;} + else { next LINE; } +}# end if + +}# end unless + +# Prologue or Introduction, print regular line (except for !) +# ----------------------------------------------------------- + if ($prologue||$intro) { + if ( $verb && $#Fld == 1 && ( $Fld[0] eq $comment_string ) ) { + next LINE; # to eliminate excessive blanks +}# end if + if($opt_g) { + if ( $verb && $#Fld == 2 && ( $Fld[0] eq 'implicit' ) ) { + next LINE; +}# end if + if ( $verb && $#Fld == 1 && ( $Fld[0] eq 'private' ) ) { + next LINE; +}# end if +}# endif + if ( $Fld[1] eq "\\ev" ) { # special handling + $_ = $comment_string . " \\end{verbatim}"; +}# end if + s/^$comment_string/ /; # replace comment string with blank +# $line = sprintf('%s', $_); # not necessary -- comment str is absent +# $ln = length($line); # not necessary -- comment str is absent + if($opt_g && $inspec) { + if ( $Fld[0] eq "call" ) { + &beg_item(); + next LINE; + } + if ( $Fld[1] eq "=" ) { + &prc_item(); + } + } else { + unless ( $first_verb ) { printf "\n "; } + printf '%s', $_; + } +# printf '%s', substr($line, 1, $ln - 1); # comment str is absent + $first_verb = 0; + next LINE; +}# end if + +# Source code: print the full line +# -------------------------------- + if ($source) { + print $_; + next LINE; +}# end if + +}# end inner loop for processing each line of the input file + # --------------------------------------------------------- + +}# end main loop for each command-line argument + # -------------------------------------------- + print $_; + if ( $source ) { &do_eoc(); } + print '%...............................................................'; + + # see comment above where these are originally set. + #print "\\setlength{\\parskip}{\\oldparskip}"; + #print "\\setlength{\\parindent}{\\oldparindent}"; + #print "\\setlength{\\baselineskip}{\\oldbaselineskip}"; + + unless ( $opt_b ) { + print "\\end{document}"; +}#end unless + + +#---------------------------------------------------------------------- + + sub CheckOpts +# Checks options against a given list. Outputs error message +# for any invalid option. +# +# Usage: +# $rc = &CheckOpts ( options, valid_reg_options, +# valid_sw_options, +# quiet_mode ) +# +# character: options - options to be checked. (e.g. -df+x) The +# list must begin with a positive or +# negative sign. If no sign appears at the +# beginning or by itself, then the argument +# is not recognized as a list of options. +# character: valid_reg_options - list of valid regular options. +# (i.e. options that are associated only +# eith negative sign.) +# character: valid_sw_options - list of valid switch options. +# (i.e. options that can be associated with +# either a positive or negative sign. +# logical: quiet mode (optional) If true then print no error +# messages. +# integer: rc - return code +# = -1 if the arguement, options, is +# not recognized as a list of options +# = 0 if all options are valid. +# > 0 for the number of invalid options. +# +{ local($options, + $valid_reg_options, + $valid_sw_options, + $quiet_mode ) = @_; + + if ( $options eq "+" || + $options eq "-" ) {return -1} + + local(@Options) = split( / */, $options ); + if ( $Options[ $[ ] ne "-" && + $Options[ $[ ] ne "+" ) {return -1;} + + local($option, $option_sign, $valid_list, $pos); + local($errs) = 0; + foreach $option ( @Options ) { + if ( $option eq "-" || + $option eq "+" ) {$option_sign = $option;} + else { + if ( $option_sign eq "-" ) + { $valid_list = $valid_reg_options + . $valid_sw_options; } + else + { $valid_list = $valid_sw_options; } + $pos = index ($valid_list,$option); + if ( $pos < $[ && + $quiet_mode ) { + $errs++; + print STDERR "Invalid option: $option_sign$option \n"; + +}# end if +}# end if +}# end foreach + return $errs; + +}#end sub GetOpts + + sub GetOpts +# Gets options. If an option is valid, then opt_[option] is +# set to 0 or 1 as a side effect if the option is preceeded by +# a positive or negative sign. +# +# Usage: +# $rc = &GetOpts ( options, valid_options ) +# +# character: options - options to be checked. (e.g. -df+x) The +# list must begin with a positive or +# negative sign. If no sign appears at the +# beginning or by itself, then the argument +# is not recognized as a list of options. +# character: valid_options - list of valid options (e.g. dfhx) +# integer: rc - return code +# = -1 if the arguement, options, is +# not recognized as a list of options. +# = 0 otherwise +# +{ local($options,$valid_options) = @_; + + if ( $options eq "+" || + $options eq "-" ) {return -1} + + local(@Options) = split( / */, $options ); + if ( $Options[ $[ ] ne "-" && + $Options[ $[ ] ne "+" ) {return -1;} + + local($option, $option_sign); + + foreach $option ( @Options ) { + + if ( $option eq "-" || + $option eq "+" ) { + $option_sign = $option; } + + else { + + if ( index ($valid_options,$option) >= $[ ) { + if ( $option_sign eq "-" ) {${"opt_$option"} = 1;} + if ( $option_sign eq "+" ) {${"opt_$option"} = 0;}; + +}# end if +}# end if +}# end foreach + + return 0; +}#end sub GetOpts + + sub SetOpt +# Sets option flags. For the last input option that is in a +# list, the flag opt_[option] is set to 1 as a side effect. +# For all other options in the list, opt_[option] is set to 0. +# +# Usage: +# $rc = &SetOpt ( options, valid_options ) +# +# character: options - options to be checked. (e.g. -df+x) The +# list must begin with a positive or +# negative sign. If no sign appears at the +# beginning or by itself, then the argument +# is not recognized as a list of options. +# character: valid_options - list of valid options (e.g. def ) +# integer: rc - return code +# = -1 if the arguement, options, is +# not recognized as a list of options. +# = 0 otherwise +# Note: For the examples provided for the input arguments, +# $opt_d = 0, $opt_e = 0, and $opt_f = 1, since the +# input option, -f, was the last in the argument, +# option. +# +{ local($options,$valid_options) = @_; + + if ( $options eq "+" || + $options eq "-" ) {return -1} + + local(@Options) = split( / */, $options ); + local(@ValidOptions) = split( / */, $valid_options ); + if ( $Options[ $[ ] ne "-" && + $Options[ $[ ] ne "+" ) {return -1;} + + local($option, $option_sign); + + foreach $option ( @Options ) { + if ( $option ne "-" && + $option ne "+" ) { + + if ( index ($valid_options,$option) >= $[ ) { + foreach $valid_option (@ValidOptions ) { + ${"opt_$valid_option"} = 0; + +}# end foreach + ${"opt_$option"} = 1; +}# end if +}# end if +}# end foreach + + return 0; +}#end sub SetOpt + +sub print_help { + + print "Usage: protex [-hbACFS] [+-nlsxf] [src_file(s)]"; + print " "; + print " Options:"; + print " -h Help mode: list command line options"; + print " -b Bare mode, meaning no preamble, etc."; + print " +-n New Page for each subsection (wastes paper)"; + print " +-l Listing mode, default is prologues only"; + print " +-s Shut-up mode, i.e., ignore any code from BOC to EOC"; + print " +-x No LaTeX mode, i.e., put !DESCRIPTION: in verbatim mode"; + print " +-f No source file info"; + print " -A Ada code"; + print " -C C++ code"; + print " -F F90 code"; + print " -S Shell script"; + print " "; + print " The options can appear in any order. The options, -h and -b,"; + print " affect the input from all files listed on command-line input."; + print " Each of the remaining options effects only the input from the"; + print " files listed after the option and prior to any overriding"; + print " option. The plus sign turns off the option."; +}# end sub print_help + +sub print_notice { + + print "% **** IMPORTANT NOTICE *****" ; + print "% This LaTeX file has been automatically produced by ProTeX v. 1.1"; + print "% Any changes made to this file will likely be lost next time"; + print "% this file is regenerated from its source."; + print " "; + +}# sub print_notice + +sub print_preamble { + + unless ( $opt_b ) { + print "%------------------------ PREAMBLE --------------------------"; + print "\\documentclass[11pt]{article}"; + print "\\usepackage{amsmath}"; + print "\\usepackage{epsfig}"; + print "\\usepackage{color}"; + print "\\usepackage[colorlinks=true,linkcolor=blue,linktocpage=true]{hyperref}"; + print "\\textheight 9in"; + print "\\topmargin 0pt"; + print "\\headsep 1cm"; + print "\\headheight 0pt"; + print "\\textwidth 6in"; + print "\\oddsidemargin 0in"; + print "\\evensidemargin 0in"; + print "\\marginparpush 0pt"; + print "\\pagestyle{myheadings}"; + print "\\markboth{}{}"; + print "%-------------------------------------------------------------"; +}# end unless + + # in your main document before you include any protex-generated files + # for the first time, if you define these three variables as length + # settings (like this:) + # \newlength{\oldparskip} + # \newlength{\oldparindent} + # \newlength{\oldbaselineskip} + # then 1) comment in all the lines below, and 2) find the 3 reset lines + # further down and comment in them as well. + # then protex will override the paragraph and skip settings during + # the source sections, but will restore the original document settings + # at the end. if someone can figure out how to check to see if a + # latex variable exists, and do a conditional section, we could make + # this fully self-contained. + # nsc feb 2003 + + #print "\\setlength{\\oldparskip}{\\parskip}"; + print "\\setlength{\\parskip}{0pt}"; + #print "\\setlength{\\oldparindent}{\\parindent}"; + print "\\setlength{\\parindent}{0pt}"; + #print "\\setlength{\\oldbaselineskip}{\\baselineskip}"; + print "\\setlength{\\baselineskip}{11pt}"; + +}# end sub print_preamble + +sub print_macros { + + print " "; + print "%--------------------- SHORT-HAND MACROS ----------------------"; + print "\\def\\bv{\\begin{verbatim}}"; + print "\\def\\ev\{\\end\{verbatim}}"; + print "\\def\\be{\\begin{equation}}"; + print "\\def\\ee{\\end{equation}}"; + print "\\def\\bea{\\begin{eqnarray}}"; + print "\\def\\eea{\\end{eqnarray}}"; + print "\\def\\bi{\\begin{itemize}}"; + print "\\def\\ei{\\end{itemize}}"; + print "\\def\\bn{\\begin{enumerate}}"; + print "\\def\\en{\\end{enumerate}}"; + print "\\def\\bd{\\begin{description}}"; + print "\\def\\ed{\\end{description}}"; + print "\\def\\({\\left (}"; + print "\\def\\){\\right )}"; + print "\\def\\[{\\left [}"; + print "\\def\\]{\\right ]}"; + print "\\def\\<{\\left \\langle}"; + print "\\def\\>{\\right \\rangle}"; + print "\\def\\cI{{\\cal I}}"; + print "\\def\\diag{\\mathop{\\rm diag}}"; + print "\\def\\tr{\\mathop{\\rm tr}}"; + print "%-------------------------------------------------------------"; + +}# end sub print_macros + +sub do_beg { + unless ( $opt_b ) { + if ( $begdoc == 0 ) { + if ( $tpage ) { + print "\\title{@title}"; + print "\\author{{\\sc @author}\\\\ {\\em @affiliation}}"; + print "\\date{@date}"; + } + print "\\begin{document}"; + if ( $tpage ) { + print "\\pagecolor[rgb]{1,0.95,0.85}"; + print "\\fcolorbox{black}{white}{\\fbox{"; + print "\\begin{minipage}[t]{\\linewidth}"; + print "\\maketitle"; + print "\\end{minipage}}}"; + print "\\thispagestyle{empty}"; + print "\\newpage"; + print "\\pagecolor{white}"; + } + print "\\tableofcontents"; + print "\\newpage"; + $begdoc = 1; + } + } +}# end sub do_beg + +sub do_eoc { + print ' '; + if ($verb) { + print "\\end{verbatim}"; + $verb = 0; + } + $source = 0; +}# end sub do_eoc + +sub set_missing { + + $have_name = 0; # have routine name? + $have_desc = 0; # have description? + $have_intf = 0; # have interface? + $have_hist = 0; # have revision history? + $name_is = "UNKNOWN"; + +}# end sub set_missing + + +sub check_if_all_there { + +$have_name || +die "ProTeX: invalid prologue, missing !ROUTINE: or !IROUTINE: in <$name_is>"; + +$have_desc || +die "ProTeX: invalid prologue, missing !DESCRIPTION: in <$name_is>"; + +$have_intf || +die "ProTeX: invalid prologue, missing !INTERFACE: in <$name_is>"; + +$have_hist || + die "ProTeX: invalid prologue, missing !REVISION HISTORY: in <$name_is>"; + +}# end sub check_if_all_there + +sub hed_item { + printf "\\bigskip\n{ \\bf \\sf \n"; + printf "\\makebox[.9 in][l]{Short Name } \n"; + printf "\\makebox[.9 in][l]{Units } \n"; + printf "\\makebox[.7 in][l]{Dims } \n"; + printf "\\makebox[.7 in][l]{Vert Loc } \n"; + printf "\\makebox[4. in][l]{Long Name } \n"; + printf "} \n \n"; + } + +sub beg_item { + if($initem) { + if($intv){ + printf "\\makebox[1.05 in][l]{\$\\overline{\\rm \\bf %s}\$} \n", $shname; + } else { + printf "\\makebox[1.05 in][l]{\\bf %s } \n", $shname; + } + printf "\\makebox[.9 in][l]{%s} \n", $units; + if($dims ne " ") { + if($dims eq 'GEOS\_DIMSHORZONLY') {printf "\\makebox[.7 in][l]{HorzOnly}\n";} + if($dims eq 'GEOS\_DIMSHORZVERT') {printf "\\makebox[.7 in][l]{HorzVert}\n";} + if($dims eq 'GEOS\_DIMSVERTONLY') {printf "\\makebox[.7 in][l]{VertOnly}\n";} + if($dims eq 'GEOS\_DIMSTILEONLY') {printf "\\makebox[.7 in][l]{TileOnly}\n";} + if($dims eq 'GEOS\_DIMSTILETILE') {printf "\\makebox[.7 in][l]{TileTile}\n";} + } + if($locs ne " ") { + if($locs eq 'GEOS\_VLOCATIONCENTER') {printf "\\makebox[.7 in][l]{Center}\n";} + if($locs eq 'GEOS\_VLOCATIONEDGE' ) {printf "\\makebox[.7 in][l]{Edge }\n";} + if($locs eq 'GEOS\_VLOCATIONNONE' ) {printf "\\makebox[.7 in][l]{None }\n";} + } + printf "\\makebox[4 in][l]{\\small %s}\\newline\n", $lnname; + } + $initem=1; + $dims=' '; + $locs=' '; + $intv=0; +} + +sub prc_units { + s/\+1//g; + s/([a-zA-Z])\+([1-9][0-9]*)/{\1}\$^{\2}\$/g; + s/\-([1-9][0-9]*)/\$^{-\1}\$/g; +} + +sub prc_item { +# Attribute name is the first field + $name = uc($Fld[0]); +# Attribute value begins at the third field + @value=@Fld; + shift(@value); + shift(@value); + $_ = join(' ', @value); +# Clean the value + s/_/\\_/g; + s/\'//g; + s/\"//g; + s/,//g; + s/&//g; + if($name eq "UNITS" ){ &prc_units();} + if($name ne "UNITS" ){ s/ //g;} + if($name eq "SHORT_NAME"){ $shname = $_;} + if($name eq "LONG_NAME" ){ $lnname = $_;} + if($name eq "UNITS" ){ $units = $_;} + if($name eq "DIMS" ){ $dims = uc($_);} + if($name eq "VLOCATION" ){ $locs = uc($_);} + if($name eq "AVERAGING_INTERVAL" ){ $intv = 1;} +} diff --git a/doc/protex_documentation.pdf b/doc/protex_documentation.pdf index e28174fde..0c1bdf4b1 100644 Binary files a/doc/protex_documentation.pdf and b/doc/protex_documentation.pdf differ diff --git a/src/cvmix_driver.F90 b/src/cvmix_driver.F90 index 7bf926de9..5892f7768 100644 --- a/src/cvmix_driver.F90 +++ b/src/cvmix_driver.F90 @@ -1,6 +1,16 @@ -!BOP +!BOI + +! !TITLE: In-code documentation for CVMix +! !AUTHORS: Many contributors from GFDL, LANL, and NCAR +! !AFFILIATION: GFDL, LANL, and NCAR +! !DATE: \today + +!EOI + +Program cvmix_driver + + !BOP -! \newpage ! !MODULE: Main Program (Stand-Alone) ! !ROUTINE: cvmix_driver @@ -13,8 +23,6 @@ ! !INTERFACE: -Program cvmix_driver - ! !USES: use cvmix_kinds_and_types, only : cvmix_r8, & @@ -23,6 +31,7 @@ Program cvmix_driver !EOP !BOC + integer :: nlev, max_nlev real(kind=cvmix_r8) :: ocn_depth character(len=cvmix_strlen) :: mix_type @@ -53,4 +62,6 @@ Program cvmix_driver print*, "WARNING: mix_type = '", trim(mix_type), "' is not supported by this driver." end select +!EOC + End Program cvmix_driver diff --git a/src/cvmix_io.F90 b/src/cvmix_io.F90 index 9ca4d143d..6e4c3c21e 100644 --- a/src/cvmix_io.F90 +++ b/src/cvmix_io.F90 @@ -101,9 +101,6 @@ subroutine cvmix_io_open(file_id, file_name, file_format, read_only) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: file_name, file_format logical, optional, intent(in) :: read_only @@ -199,9 +196,6 @@ subroutine cvmix_input_read_1d_double(file_id, var_name, local_copy) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name @@ -288,9 +282,6 @@ subroutine cvmix_input_read_2d_integer(file_id, var_name, local_copy) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name @@ -378,9 +369,6 @@ subroutine cvmix_input_read_2d_double(file_id, var_name, local_copy) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name @@ -468,9 +456,6 @@ subroutine cvmix_input_read_3d_double(file_id, var_name, local_copy) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name @@ -559,9 +544,6 @@ subroutine cvmix_output_write_single_col(file_id, CVmix_vars, var_names, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id type(cvmix_data_type) , intent(in) :: CVmix_vars @@ -790,9 +772,6 @@ subroutine cvmix_output_write_multi_col(file_id, CVmix_vars, var_names) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id type(cvmix_data_type), dimension(:), intent(in) :: CVmix_vars @@ -871,19 +850,19 @@ subroutine cvmix_output_write_multi_col(file_id, CVmix_vars, var_names) do icol=1,ncol lcl_Mdiff(icol,:) = CVmix_vars(icol)%Mdiff_iface(1:nlev+1) end do - endif + end if if (trim(var_name).eq."Tdiff_iface") then allocate(lcl_Tdiff(ncol,nlev+1)) do icol=1,ncol lcl_Tdiff(icol,:) = CVmix_vars(icol)%Tdiff_iface(1:nlev+1) end do - endif + end if if (trim(var_name).eq."Sdiff_iface") then allocate(lcl_Sdiff(ncol,nlev+1)) do icol=1,ncol lcl_Sdiff(icol,:) = CVmix_vars(icol)%Sdiff_iface(1:nlev+1) end do - endif + end if end do call netcdf_check(nf90_enddef(file_id)) @@ -985,9 +964,6 @@ subroutine cvmix_output_write_2d_double(file_id, var_name, dim_names, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name @@ -1060,9 +1036,6 @@ subroutine cvmix_output_write_3d_double(file_id, var_name, dim_names, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name @@ -1128,9 +1101,6 @@ subroutine cvmix_output_write_att_integer(file_id, att_name, att_val, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: att_name @@ -1193,9 +1163,6 @@ subroutine cvmix_output_write_att_real(file_id, att_name, att_val, var_name) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: att_name @@ -1258,9 +1225,6 @@ subroutine cvmix_output_write_att_string(file_id, att_name, att_val, var_name) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: att_name, att_val @@ -1322,9 +1286,6 @@ subroutine cvmix_io_close(file_id) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id @@ -1412,9 +1373,6 @@ subroutine cvmix_io_close_all !\\ !\\ -! !USES: -! Only those used by entire module. - ! !LOCAL VARIABLES: integer :: fid @@ -1444,9 +1402,6 @@ function get_file_name(file_id) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id @@ -1488,9 +1443,6 @@ function get_file_type(file_id) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id @@ -1533,9 +1485,6 @@ function cvmix_input_get_netcdf_dim(file_id, dim_name) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: dim_name @@ -1590,9 +1539,6 @@ function get_netcdf_varid(file_id, var_name, xtype, ndims) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: file_id character(len=*), intent(in) :: var_name diff --git a/src/drivers/cvmix_bgrnd_BL.F90 b/src/drivers/cvmix_bgrnd_BL.F90 index a7947e3de..f943c9878 100644 --- a/src/drivers/cvmix_bgrnd_BL.F90 +++ b/src/drivers/cvmix_bgrnd_BL.F90 @@ -1,5 +1,4 @@ !BOP -!\newpage ! !ROUTINE: cvmix_BL_driver ! !DESCRIPTION: A routine to test the Bryan-Lewis implementation of static diff --git a/src/drivers/cvmix_ddiff_drv.F90 b/src/drivers/cvmix_ddiff_drv.F90 index 713ee4636..051c56dd8 100644 --- a/src/drivers/cvmix_ddiff_drv.F90 +++ b/src/drivers/cvmix_ddiff_drv.F90 @@ -1,5 +1,4 @@ !BOP -!\newpage ! !ROUTINE: cvmix_ddiff_driver ! !DESCRIPTION: A routine to test the double diffusion mixing module. diff --git a/src/drivers/cvmix_kpp_drv.F90 b/src/drivers/cvmix_kpp_drv.F90 index 46d702896..6969e2130 100644 --- a/src/drivers/cvmix_kpp_drv.F90 +++ b/src/drivers/cvmix_kpp_drv.F90 @@ -1,5 +1,4 @@ !BOP -!\newpage ! !ROUTINE: cvmix_kpp_driver ! !DESCRIPTION: A routine to test the KPP module. diff --git a/src/drivers/cvmix_shear_drv.F90 b/src/drivers/cvmix_shear_drv.F90 index fce415200..9cf92663b 100644 --- a/src/drivers/cvmix_shear_drv.F90 +++ b/src/drivers/cvmix_shear_drv.F90 @@ -1,5 +1,4 @@ !BOP -!\newpage ! !ROUTINE: cvmix_shear_driver ! !DESCRIPTION: A routine to test the Large, et al., implementation of shear diff --git a/src/drivers/cvmix_tidal_Simmons.F90 b/src/drivers/cvmix_tidal_Simmons.F90 index e16fa75ed..caa4a98a8 100644 --- a/src/drivers/cvmix_tidal_Simmons.F90 +++ b/src/drivers/cvmix_tidal_Simmons.F90 @@ -1,5 +1,4 @@ !BOP -!\newpage ! !ROUTINE: cvmix_tidal_driver ! !DESCRIPTION: A routine to test the Simmons implementation of tidal mixing. diff --git a/src/shared/cvmix_background.F90 b/src/shared/cvmix_background.F90 index 4cae3bfe8..af9c4fe1c 100644 --- a/src/shared/cvmix_background.F90 +++ b/src/shared/cvmix_background.F90 @@ -120,9 +120,6 @@ subroutine cvmix_init_bkgnd_scalar(bkgnd_Tdiff, bkgnd_Mdiff, old_vals, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), intent(in) :: bkgnd_Tdiff real(cvmix_r8), intent(in) :: bkgnd_Mdiff @@ -192,9 +189,6 @@ subroutine cvmix_init_bkgnd_1D(bkgnd_Tdiff, bkgnd_Mdiff, ncol, old_vals, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), dimension(:), intent(in) :: bkgnd_Tdiff real(cvmix_r8), dimension(:), intent(in) :: bkgnd_Mdiff @@ -224,7 +218,7 @@ subroutine cvmix_init_bkgnd_1D(bkgnd_Tdiff, bkgnd_Mdiff, ncol, old_vals, & "containing max_nlev!" stop 1 end if - endif + end if CVmix_bkgnd_params_out => CVmix_bkgnd_params_saved if (present(CVmix_bkgnd_params_user)) then @@ -293,9 +287,6 @@ subroutine cvmix_init_bkgnd_2D(bkgnd_Tdiff, bkgnd_Mdiff, ncol, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), dimension(:,:), intent(in) :: bkgnd_Tdiff real(cvmix_r8), dimension(:,:), intent(in) :: bkgnd_Mdiff @@ -369,10 +360,9 @@ subroutine cvmix_init_bkgnd_BryanLewis_wrap(CVmix_vars, bl1, bl2, bl3, bl4, & CVmix_bkgnd_params_user) ! !DESCRIPTION: -! Calls cvmix_init_bkgnd_BryanLewis_low -! -! !USES: -! Only those used by entire module. +! Calls cvmix\_init\_bkgnd\_BryanLewis\_low +!\\ +!\\ ! !INPUT PARAMETERS: ! Contains depth and nlev @@ -436,9 +426,8 @@ subroutine cvmix_init_bkgnd_BryanLewis_low(max_nlev, zw, bl1, bl2, bl3, bl4, & ! \item[] bl4 $= 2500$ m ! \end{itemize} ! However, more recent usage of their scheme may warrant different settings. -! -! !USES: -! Only those used by entire module. +!\\ +!\\ ! !INPUT PARAMETERS: integer, intent(in) :: max_nlev @@ -523,9 +512,6 @@ subroutine cvmix_coeffs_bkgnd_wrap(CVmix_vars, colid, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: ! Need to know column for pulling data from static_[MT]diff @@ -584,9 +570,6 @@ subroutine cvmix_coeffs_bkgnd_low(Mdiff_out, Tdiff_out, nlev, max_nlev, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: ! Need to know column for pulling data from static_[MT]diff @@ -636,9 +619,6 @@ function cvmix_bkgnd_lvary_horizontal(CVmix_bkgnd_params_test) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_bkgnd_params_type), intent(in) :: CVmix_bkgnd_params_test @@ -665,9 +645,6 @@ function cvmix_bkgnd_static_Mdiff(CVmix_bkgnd_params_user,kw,colid) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_bkgnd_params_type), target, optional, intent(in) :: & CVmix_bkgnd_params_user @@ -729,9 +706,6 @@ function cvmix_bkgnd_static_Tdiff(CVmix_bkgnd_params_user,kw,colid) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_bkgnd_params_type), target, optional, intent(in) :: & CVmix_bkgnd_params_user @@ -793,9 +767,6 @@ subroutine cvmix_put_bkgnd_int(varname, val, CVmix_bkgnd_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -838,9 +809,6 @@ subroutine cvmix_put_bkgnd_real(varname, val, CVmix_bkgnd_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -905,9 +873,6 @@ subroutine cvmix_put_bkgnd_real_1D(varname, val, CVmix_bkgnd_params_user, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), dimension(:), intent(in) :: val @@ -1030,9 +995,6 @@ subroutine cvmix_put_bkgnd_real_2D(varname, val, ncol, nlev, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), dimension(:,:), intent(in) :: val @@ -1118,9 +1080,6 @@ function cvmix_get_bkgnd_real_2D(varname, CVmix_bkgnd_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_bkgnd_params_type), target, optional, intent(in) :: & diff --git a/src/shared/cvmix_convection.F90 b/src/shared/cvmix_convection.F90 index 698791689..716f0abdb 100644 --- a/src/shared/cvmix_convection.F90 +++ b/src/shared/cvmix_convection.F90 @@ -102,13 +102,6 @@ subroutine cvmix_init_conv(convect_diff, convect_visc, lBruntVaisala, & !\\ !\\ -! !USES: -! Only those used by entire module. - -! !OUTPUT PARAMETERS: - type (cvmix_conv_params_type), optional, intent(inout) :: & - CVmix_conv_params_user - ! !INPUT PARAMETERS: real(cvmix_r8), intent(in) :: & convect_diff, &! diffusivity to parameterize convection @@ -118,6 +111,10 @@ subroutine cvmix_init_conv(convect_diff, convect_visc, lBruntVaisala, & logical, intent(in), optional :: lnoOBL ! False => apply in OBL too character(len=cvmix_strlen), optional, intent(in) :: old_vals +! !OUTPUT PARAMETERS: + type (cvmix_conv_params_type), optional, intent(inout) :: & + CVmix_conv_params_user + !EOP !BOC @@ -181,9 +178,6 @@ subroutine cvmix_coeffs_conv_wrap(CVmix_vars, CVmix_conv_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type (cvmix_conv_params_type), optional, target, intent(in) :: & @@ -249,9 +243,6 @@ subroutine cvmix_coeffs_conv_low(Mdiff_out, Tdiff_out, Nsqr, dens, dens_lwr,& !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: nlev, max_nlev @@ -374,9 +365,6 @@ subroutine cvmix_put_conv_int(varname, val, CVmix_conv_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -420,9 +408,6 @@ subroutine cvmix_put_conv_real(varname, val, CVmix_conv_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -471,9 +456,6 @@ subroutine cvmix_put_conv_logical(varname, val, CVmix_conv_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname logical, intent(in) :: val @@ -519,9 +501,6 @@ function cvmix_get_conv_real(varname, CVmix_conv_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_conv_params_type), optional, target, intent(in) :: & diff --git a/src/shared/cvmix_ddiff.F90 b/src/shared/cvmix_ddiff.F90 index 7dfd7bb87..0b7e2f2ed 100644 --- a/src/shared/cvmix_ddiff.F90 +++ b/src/shared/cvmix_ddiff.F90 @@ -176,10 +176,9 @@ subroutine cvmix_init_ddiff(CVmix_ddiff_params_user, strat_param_max, & ! \end{eqnarray*} ! $\kappa$ is stored in \verb|CVmix_vars%diff_iface(:,1)|, while the modified value ! for non-temperature tracers is stored in \verb|CVmix_vars%diff_iface(:,2)|. -! Note that CVMix assumes units are |'mks'|.\\ +! Note that CVMix assumes units are |'mks'|. +!\\ !\\ -! !USES: -! Only those used by entire module. ! !INPUT PARAMETERS: real(cvmix_r8), optional, intent(in) :: strat_param_max, & @@ -303,9 +302,6 @@ subroutine cvmix_coeffs_ddiff_wrap(CVmix_vars, CVmix_ddiff_params_user) ! parameterization. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_ddiff_params_type), optional, target, intent(in) :: & @@ -361,9 +357,6 @@ subroutine cvmix_coeffs_ddiff_low(Tdiff_out, Sdiff_out, strat_param_num, & ! parameterization. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_ddiff_params_type), optional, target, intent(in) :: & @@ -453,9 +446,6 @@ subroutine cvmix_put_ddiff_str(varname, val, CVmix_ddiff_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname, val @@ -508,9 +498,6 @@ subroutine cvmix_put_ddiff_real(varname, val, CVmix_ddiff_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -568,9 +555,6 @@ subroutine cvmix_put_ddiff_int(varname, val, CVmix_ddiff_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -616,9 +600,6 @@ function cvmix_get_ddiff_real(varname, CVmix_ddiff_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_ddiff_params_type), optional, target, intent(inout) :: & diff --git a/src/shared/cvmix_kinds_and_types.F90 b/src/shared/cvmix_kinds_and_types.F90 index a8682db74..074bd4f9f 100644 --- a/src/shared/cvmix_kinds_and_types.F90 +++ b/src/shared/cvmix_kinds_and_types.F90 @@ -1,12 +1,3 @@ -!BOI - -! !TITLE: In-code documentation for CVMix -! !AUTHORS: Many contributors from GFDL, LANL, and NCAR -! !AFFILIATION: GFDL, LANL, and NCAR -! !DATE: \today - -!EOI - module cvmix_kinds_and_types !BOP @@ -99,6 +90,12 @@ module cvmix_kinds_and_types ! Langmuir number real(cvmix_r8) :: LangmuirNumber ! units: unitless + ! Stokes Similarity Parameter + real(cvmix_r8) :: StokesMostXi + ! units: unitless + ! Numerical limit of Ocean Boundary Layer Depth + real(cvmix_r8) :: zBottomOceanNumerics + ! units: m ! A time-invariant coefficient needed for Simmons, et al. tidal mixing real(cvmix_r8) :: SimmonsCoeff diff --git a/src/shared/cvmix_kpp.F90 b/src/shared/cvmix_kpp.F90 index 9c06b35f6..f1200d199 100644 --- a/src/shared/cvmix_kpp.F90 +++ b/src/shared/cvmix_kpp.F90 @@ -79,6 +79,8 @@ module cvmix_kpp public :: cvmix_kpp_compute_bulk_Richardson public :: cvmix_kpp_compute_turbulent_scales public :: cvmix_kpp_compute_unresolved_shear + public :: cvmix_kpp_composite_Gshape !STOKES_MOST + public :: cvmix_kpp_compute_StokesXi !STOKES_MOST ! These are public for testing, may end up private later public :: cvmix_kpp_compute_shape_function_coeffs public :: cvmix_kpp_compute_kOBL_depth @@ -175,6 +177,7 @@ module cvmix_kpp integer :: handle_old_vals ! Logic flags to dictate if / how various terms are computed + logical :: lStokesMOST ! True => use Stokes Similarty package logical :: lscalar_Cv ! True => use the scalar Cv value logical :: lEkman ! True => compute Ekman depth limit logical :: lMonOb ! True => compute Monin-Obukhov limit @@ -220,7 +223,7 @@ module cvmix_kpp subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, & vonkarman, Cstar, zeta_m, zeta_s, surf_layer_ext, & Cv, interp_type, interp_type2, MatchTechnique, & - old_vals, lEkman, lMonOb, lnoDGat1, & + old_vals, lEkman, lStokesMOST, lMonOb, lnoDGat1, & lenhanced_diff, lnonzero_surf_nonlocal, & Langmuir_mixing_str, Langmuir_entrainment_str, & l_LMD_ws, CVmix_kpp_params_user) @@ -229,9 +232,6 @@ subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, & ! Initialization routine for KPP mixing. !\\ !\\ -! -! !USES: -! Only those used by entire module. ! !INPUT PARAMETERS: real(cvmix_r8), optional, intent(in) :: ri_crit, & @@ -251,6 +251,7 @@ subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, & Langmuir_mixing_str, & Langmuir_entrainment_str logical, optional, intent(in) :: lEkman, & + lStokesMOST, & lMonOb, & lnoDGat1, & lenhanced_diff, & @@ -478,6 +479,12 @@ subroutine cvmix_init_kpp(ri_crit, minOBLdepth, maxOBLdepth, minVtsqr, & cvmix_kpp_params_user) end if + if (present(lStokesMOST)) then + call cvmix_put_kpp('lStokesMOST',lStokesMOST , CVmix_kpp_params_user) + else + call cvmix_put_kpp('lStokesMOST', .false., CVmix_kpp_params_user) + end if + if (present(lEkman)) then call cvmix_put_kpp('lEkman', lEkman, CVmix_kpp_params_user) else @@ -591,9 +598,6 @@ subroutine cvmix_coeffs_kpp_wrap(CVmix_vars, CVmix_kpp_params_user) ! parameterization. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_kpp_params_type), intent(in), optional, target :: & @@ -639,7 +643,9 @@ subroutine cvmix_coeffs_kpp_wrap(CVmix_vars, CVmix_kpp_params_user) CVmix_vars%SurfaceBuoyancyForcing, & nlev, max_nlev, & CVmix_vars%LangmuirEnhancementFactor, & + CVmix_vars%StokesMostXi, & CVmix_kpp_params_user) + call cvmix_update_wrap(CVmix_kpp_params_in%handle_old_vals, max_nlev, & Mdiff_out = CVmix_vars%Mdiff_iface, & new_Mdiff = new_Mdiff, & @@ -660,17 +666,14 @@ end subroutine cvmix_coeffs_kpp_wrap subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & old_Mdiff, old_Tdiff, old_Sdiff, OBL_depth, & kOBL_depth, Tnonlocal, Snonlocal, surf_fric,& - surf_buoy, nlev, max_nlev, & - Langmuir_EFactor, CVmix_kpp_params_user) + surf_buoy, nlev, max_nlev, Langmuir_EFactor,& + StokesXI,CVmix_kpp_params_user) ! !DESCRIPTION: ! Computes vertical diffusion coefficients for the KPP boundary layer mixing ! parameterization. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_kpp_params_type), intent(in), optional, target :: & @@ -688,7 +691,7 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & kOBL_depth ! Langmuir enhancement factor real(cvmix_r8), intent(in), optional :: Langmuir_EFactor - + real(cvmix_r8), intent(in), optional :: StokesXI ! !INPUT/OUTPUT PARAMETERS: real(cvmix_r8), dimension(max_nlev+1), intent(inout) :: Mdiff_out, & Tdiff_out, & @@ -753,6 +756,9 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & real(cvmix_r8) :: MixingCoefEnhancement real(cvmix_r8) :: ShapeNoMatchAtS + ! Parameters for Stokes_MOST + real(cvmix_r8) :: Gcomposite, Hsigma, sigh, T_NLenhance , S_NLenhance , XIone + ! Constant from params integer :: interp_type2, MatchTechnique @@ -790,6 +796,149 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & delta = (OBL_depth+zt(ktup))/(zt(ktup)-zt(ktup+1)) end if + if ( CVmix_kpp_params_in%lStokesMOST ) then ! Stokes_MOST + + ! (2a) Compute turbulent scales at OBL depth + call cvmix_kpp_compute_turbulent_scales(cvmix_one, OBL_depth, & + surf_buoy, surf_fric, & + StokesXI, wm_OBL, ws_OBL, & + CVmix_kpp_params_user) + + ! (2b) Compute diffusivities at OBL depth + col_centers(1) = zt(kwup) + col_widths(1) = zw(kwup) - zw(kwup+1) + Mdiff_vals(1) = old_Mdiff(kwup+1) + Tdiff_vals(1) = old_Tdiff(kwup+1) + Sdiff_vals(1) = old_Sdiff(kwup+1) + if (kwup.eq.nlev) then + col_centers(2) = zw(kwup+1) + col_widths(2) = 1.0_cvmix_r8 !Value doesn't matter, will divide into zero + Mdiff_vals(2) = old_Mdiff(kwup+1) !Mdiff_out(kwup+1) + Tdiff_vals(2) = old_Tdiff(kwup+1) + Sdiff_vals(2) = old_Sdiff(kwup+1) + else + col_centers(2) = zt(kwup+1) + col_widths(2) = zw(kwup+1) - zw(kwup+2) + Mdiff_vals(2) = old_Mdiff(kwup+2) + Tdiff_vals(2) = old_Tdiff(kwup+2) + Sdiff_vals(2) = old_Sdiff(kwup+2) + end if + if (kwup.eq.1) then + Mdiff_OBL = cvmix_kpp_compute_nu_at_OBL_depth_LMD94(col_centers, & + col_widths, & + Mdiff_vals, OBL_depth, & + dnu_dz=dMdiff_OBL) + Tdiff_OBL = cvmix_kpp_compute_nu_at_OBL_depth_LMD94(col_centers, & + col_widths, & + Tdiff_vals, OBL_depth, & + dnu_dz=dTdiff_OBL) + Sdiff_OBL = cvmix_kpp_compute_nu_at_OBL_depth_LMD94(col_centers, & + col_widths, & + Sdiff_vals, OBL_depth, & + dnu_dz=dSdiff_OBL) + else ! interp_type == 'LMD94' and kwup > 1 + Mdiff_OBL = cvmix_kpp_compute_nu_at_OBL_depth_LMD94(col_centers, & + col_widths, & + Mdiff_vals, OBL_depth, & + old_Mdiff(kwup), & + dnu_dz=dMdiff_OBL) + Tdiff_OBL = cvmix_kpp_compute_nu_at_OBL_depth_LMD94(col_centers, & + col_widths, & + Tdiff_vals, OBL_depth, & + old_Tdiff(kwup), & + dnu_dz=dTdiff_OBL) + Sdiff_OBL = cvmix_kpp_compute_nu_at_OBL_depth_LMD94(col_centers, & + col_widths, & + Sdiff_vals, OBL_depth, & + old_Sdiff(kwup), & + dnu_dz=dSdiff_OBL) + end if + + ! (3a) Compute turbulent scales at interfaces throughout column + sigma = -zw(1:nlev+1)/OBL_depth + call cvmix_kpp_compute_turbulent_scales(sigma, OBL_depth, surf_buoy, & !_1d + surf_fric, xi=StokesXI, w_m=w_m, w_s=w_s, & + CVmix_kpp_params_user = CVmix_kpp_params_user) + + do kw=2,kwup ! OBL overwrite loop to kwup + ! (3b) Evaluate G(sigma) >= 0 at each cell interface + Gcomposite = cvmix_kpp_composite_shape(sigma(kw)) + sigh = MAX(CVmix_kpp_params_in%surf_layer_ext, MIN(sigma(kw) ,cvmix_one)) + Hsigma = ((sigh - CVmix_kpp_params_in%surf_layer_ext) / & + (cvmix_one - CVmix_kpp_params_in%surf_layer_ext) )**2 +! Hsigma = MAX( cvmix_zero , MIN( cvmix_one , Hsigma ) ) + + ! (3c) Compute nonlocal term at each cell interface + if (.not.lstable) then + Tnonlocal(kw) = 4.7 * Gcomposite ! LMD 6.26 Gcubic + Snonlocal(kw) = 4.7 * Gcomposite + else + Tnonlocal(kw) = cvmix_zero + Snonlocal(kw) = cvmix_zero + end if + + ! (3d) Diffusivity = (OBL_depth * turbulent scale * G(sigma) + Xdiff_OBL * Hsigma) + OBL_Mdiff(kw) = OBL_depth * w_m(kw) * Gcomposite + Mdiff_OBL * Hsigma + OBL_Tdiff(kw) = OBL_depth * w_s(kw) * Gcomposite + Tdiff_OBL * Hsigma + OBL_Sdiff(kw) = OBL_depth * w_s(kw) * Gcomposite + Sdiff_OBL * Hsigma + + end do + + ! (4) Compute the enhanced diffusivity + ! (4a) Compute shape function at last cell center in OBL + sigma_ktup = -zt(ktup)/OBL_depth + Gcomposite = cvmix_kpp_composite_shape(sigma_ktup) + sigh = MAX(CVmix_kpp_params_in%surf_layer_ext, MIN(sigma_ktup ,cvmix_one)) + Hsigma = ( (sigh - CVmix_kpp_params_in%surf_layer_ext) / & + (cvmix_one - CVmix_kpp_params_in%surf_layer_ext) )**2 + + ! (4b) Compute turbulent scales at last cell center in OBL + call cvmix_kpp_compute_turbulent_scales(sigma_ktup, OBL_depth, surf_buoy, & !0d + surf_fric, StokesXI, wm_ktup, ws_ktup, & + CVmix_kpp_params_user) + + ! (4c) Diffusivity at last cell center in OBL + Mdiff_ktup = OBL_depth * wm_ktup * Gcomposite + Mdiff_OBL * Hsigma + Tdiff_ktup = OBL_depth * ws_ktup * Gcomposite + Tdiff_OBL * Hsigma + Sdiff_ktup = OBL_depth * ws_ktup * Gcomposite + Sdiff_OBL * Hsigma + + if (CVmix_kpp_params_in%lenhanced_diff) then + if ((ktup.eq.kwup).or.(ktup.eq.kwup-1)) then + T_NLenhance = Tnonlocal(ktup+1) + S_NLenhance = Snonlocal(ktup+1) + call cvmix_kpp_compute_enhanced_diff(Mdiff_ktup, & + Tdiff_ktup, & + Sdiff_ktup, & + Mdiff_out(ktup+1), & + Tdiff_out(ktup+1), & + Sdiff_out(ktup+1), & + OBL_Mdiff(ktup+1), & + OBL_Tdiff(ktup+1), & + OBL_Sdiff(ktup+1), & + T_NLenhance , & + S_NLenhance , & + delta, lkteqkw=(ktup.eq.kwup)) + else + print*, "ERROR: ktup should be either kwup or kwup-1!" + print*, "ktup = ", ktup, " and kwup = ", kwup + stop 1 + end if + else + if ( kwup .eq. ktup ) then + OBL_Mdiff(ktup+1) = old_Mdiff(ktup+1) + OBL_Tdiff(ktup+1) = old_Tdiff(ktup+1) + OBL_Sdiff(ktup+1) = old_Sdiff(ktup+1) + end if + end if + + ! (5) Combine interior and boundary coefficients + + Mdiff_out(2:ktup+1) = OBL_Mdiff(2:ktup+1) + Tdiff_out(2:ktup+1) = OBL_Tdiff(2:ktup+1) + Sdiff_out(2:ktup+1) = OBL_Sdiff(2:ktup+1) + else ! not Stokes_MOST + + XIone = cvmix_one ! (2) Compute coefficients of shape function ! A no-match case is stored for use in Langmuir scheme NMshape(1) = cvmix_zero @@ -825,7 +974,7 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & ! (2a) Compute turbulent scales at OBL depth call cvmix_kpp_compute_turbulent_scales(cvmix_one, OBL_depth, & surf_buoy, surf_fric, & - wm_OBL, ws_OBL, & + XIone, wm_OBL, ws_OBL, & CVmix_kpp_params_user) if (CVMix_KPP_Params_in%Langmuir_Mixing_Opt & .eq. LANGMUIR_MIXING_LWF16) then @@ -1016,8 +1165,8 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & OBL_Sdiff = cvmix_zero sigma = -zw(1:nlev+1)/OBL_depth ! (3a) Compute turbulent scales throghout column - call cvmix_kpp_compute_turbulent_scales(sigma, OBL_depth, surf_buoy, & - surf_fric, w_m, w_s, & + call cvmix_kpp_compute_turbulent_scales(sigma, OBL_depth, surf_buoy, & + surf_fric, XIone, w_m, w_s, & CVmix_kpp_params_user) do kw=2,kwup ! (3b) Evaluate G(sigma) at each cell interface @@ -1058,8 +1207,8 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & SshapeAtS = cvmix_math_evaluate_cubic(Sshape, sigma_ktup) ! (4b) Compute turbulent scales at last cell center in OBL call cvmix_kpp_compute_turbulent_scales(sigma_ktup, OBL_depth, surf_buoy, & - surf_fric, wm_ktup, ws_ktup, & - CVmix_kpp_params_user) + surf_fric, XIone, wm_ktup, ws_ktup, & + CVmix_kpp_params_user) if (CVMix_KPP_Params_in%Langmuir_Mixing_Opt & .eq. LANGMUIR_MIXING_LWF16) then ! enhance the turbulent velocity scale @@ -1090,6 +1239,12 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & print*, "ktup = ", ktup, " and kwup = ", kwup stop 1 end if + else + if ( kwup .eq. ktup ) then + OBL_Mdiff(ktup+1) = old_Mdiff(ktup+1) + OBL_Tdiff(ktup+1) = old_Tdiff(ktup+1) + OBL_Sdiff(ktup+1) = old_Sdiff(ktup+1) + end if end if ! (5) Combine interior and boundary coefficients @@ -1097,6 +1252,8 @@ subroutine cvmix_coeffs_kpp_low(Mdiff_out, Tdiff_out, Sdiff_out, zw, zt, & Tdiff_out(2:ktup+1) = OBL_Tdiff(2:ktup+1) Sdiff_out(2:ktup+1) = OBL_Sdiff(2:ktup+1) + end if ! lStokesMOST + !EOC end subroutine cvmix_coeffs_kpp_low @@ -1112,9 +1269,6 @@ subroutine cvmix_put_kpp_real(varname, val, CVmix_kpp_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -1197,9 +1351,6 @@ subroutine cvmix_put_kpp_int(varname, val, CVmix_kpp_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -1251,9 +1402,6 @@ subroutine cvmix_put_kpp_logical(varname, val, CVmix_kpp_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname logical, intent(in) :: val @@ -1277,6 +1425,8 @@ subroutine cvmix_put_kpp_logical(varname, val, CVmix_kpp_params_user) CVmix_kpp_params_out%lscalar_Cv = val case ('lEkman') CVmix_kpp_params_out%lEkman = val + case ('lStokesMOST') + CVmix_kpp_params_out%lStokesMOST = val case ('lMonOb') CVmix_kpp_params_out%lMonOb = val case ('lnoDGat1') @@ -1308,9 +1458,6 @@ function cvmix_get_kpp_real(varname, CVmix_kpp_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_kpp_params_type), optional, target, intent(in) :: & @@ -1381,24 +1528,23 @@ end function cvmix_get_kpp_real subroutine cvmix_kpp_compute_OBL_depth_low(Ri_bulk, zw_iface, OBL_depth, & kOBL_depth, zt_cntr, surf_fric, & - surf_buoy, Coriolis, & + surf_buoy, Coriolis,Xi, zBottom, & CVmix_kpp_params_user) ! !DESCRIPTION: -! Computes the depth of the ocean boundary layer (OBL) for a given column. +! Computes the depth of the ocean boundary layer (\verb|OBL_depth|) for a given column. +! Ri\_bulk(h) = Ricr; h < -zBottom, (stable+lMonOb) 0 < h < vonKaraman Lstar !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), dimension(:), intent(in) :: Ri_bulk real(cvmix_r8), dimension(:), target, intent(in) :: zw_iface, & zt_cntr + real(cvmix_r8), dimension(:), optional, intent(in) :: Xi, surf_buoy real(cvmix_r8), optional, intent(in) :: surf_fric, & - surf_buoy, & - Coriolis + Coriolis, & + zBottom type(cvmix_kpp_params_type), optional, target, intent(in) :: & CVmix_kpp_params_user @@ -1412,7 +1558,7 @@ subroutine cvmix_kpp_compute_OBL_depth_low(Ri_bulk, zw_iface, OBL_depth, & real(kind=cvmix_r8), dimension(:), pointer :: depth real(kind=cvmix_r8), dimension(4) :: coeffs real(kind=cvmix_r8) :: Ekman, MoninObukhov, OBL_Limit - integer :: nlev, k + integer :: nlev, k, kRi logical :: lstable type(cvmix_kpp_params_type), pointer :: CVmix_kpp_params_in @@ -1461,13 +1607,82 @@ subroutine cvmix_kpp_compute_OBL_depth_low(Ri_bulk, zw_iface, OBL_depth, & ! if lEkman = .true., OBL_depth must be between the surface and the Ekman ! depth. Similarly, if lMonOb = .true., OBL_depth must be between the ! surface and the Monin-Obukhov depth + + if ( CVmix_kpp_params_in%lStokesMOST ) then + ! OBL_depth must be at or above 1) zbottom, the effective ocean bottom, + if ( present(zBottom) ) then + OBL_limit = abs(zBottom) + else + OBL_limit = abs(zt_cntr(nlev)) + end if + + ! (1) Find k such that Ri_bulk at level k+1 > Ri_crit + do k=0,size(Ri_bulk)-1 + kRi = k+1 + if (Ri_bulk(k+1).gt.CVmix_kpp_params_in%ri_crit) & + exit + end do + + if (k.eq.size(Ri_bulk)) then + OBL_depth = OBL_limit + elseif (k.eq.0) then + OBL_depth = abs(zt_cntr(1)) + else + + ! (2) Interpolation + if (k.eq.1) then + call cvmix_math_poly_interp(coeffs, CVmix_kpp_params_in%interp_type, & + depth(k:k+1), Ri_bulk(k:k+1)) + else + call cvmix_math_poly_interp(coeffs, CVmix_kpp_params_in%interp_type, & + depth(k:k+1), Ri_bulk(k:k+1), depth(k-1), & + Ri_bulk(k-1)) + end if + coeffs(1) = coeffs(1)-CVmix_kpp_params_in%ri_crit + + OBL_depth = -cvmix_math_cubic_root_find(coeffs, 0.5_cvmix_r8 * & + (depth(k)+depth(k+1))) + + ! (3) OBL_depth needs to be at or below the center of the top level + ! Note: OBL_depth can only be computed to be above this point if k=1, + if (k.eq.1) OBL_depth = max(OBL_depth, -zt_cntr(1)) + end if ! -zt_cntr(1) < OBL_depth < OBL_limit + + ! (5) the modified MoninObukhov limit (= vonk*Lstar) if stable and lMonOb=True + if (CVmix_kpp_params_in%lMonOb ) then + if ( present(Xi) .and. present(surf_buoy) ) then + MoninObukhov = OBL_limit + do k = 0, kRi-1 + if (surf_buoy(k+1) .gt. cvmix_zero) MoninObukhov = & + surf_fric**3 / (surf_buoy(k+1) * (cvmix_one-Xi(k+1))) + if ( MoninObukhov .lt. abs(zt_cntr(k+1)) ) & + exit + end do + if (k.eq.0) then + OBL_limit = abs(zt_cntr(1)) + elseif (k.lt.kRi) then + OBL_limit = min( OBL_limit, abs(zw_iface(k)) ) + end if + + else + print*, "ERROR: Stokes_XI and surf_buoy both must be present if lMonOb=true with Stokes_Most package" + stop 1 + end if + end if ! lMonOb + + ! (4) OBL_depth must be at or above OBL_limit -zt_cntr(1) < OBL_depth < OBL_limit + OBL_depth = min(OBL_depth, OBL_limit ) + kOBL_depth = cvmix_kpp_compute_kOBL_depth(zw_iface, zt_cntr, OBL_depth) + + else ! not Stokes_MOST + OBL_limit = abs(zt_cntr(nlev)) ! Since depth gets more negative as you go deeper, that translates into ! OBL_depth = max(abs(computed depth), abs(Ekman depth), abs(M-O depth)) if (CVmix_kpp_params_in%lEkman) then ! Column is stable if surf_buoy > 0 - lstable = (surf_buoy.gt.cvmix_zero) + lstable = (surf_buoy(nlev).gt.cvmix_zero) if (Coriolis.ne.cvmix_zero .and. lstable) then Ekman = 0.7_cvmix_r8*surf_fric/abs(Coriolis) @@ -1480,10 +1695,10 @@ subroutine cvmix_kpp_compute_OBL_depth_low(Ri_bulk, zw_iface, OBL_depth, & if (CVmix_kpp_params_in%lMonOb) then ! Column is stable if surf_buoy > 0 - lstable = (surf_buoy.gt.cvmix_zero) + lstable = (surf_buoy(nlev).gt.cvmix_zero) if (lstable) then - MoninObukhov = surf_fric**3/(surf_buoy*CVmix_kpp_params_in%vonkarman) + MoninObukhov = surf_fric**3/(surf_buoy(nlev)*CVmix_kpp_params_in%vonkarman) else MoninObukhov = abs(zt_cntr(nlev)) end if @@ -1535,6 +1750,8 @@ subroutine cvmix_kpp_compute_OBL_depth_low(Ri_bulk, zw_iface, OBL_depth, & OBL_depth = min(OBL_depth, CVmix_kpp_params_in%maxOBLdepth) kOBL_depth = cvmix_kpp_compute_kOBL_depth(zw_iface, zt_cntr, OBL_depth) + end if ! lStokesMOST + !EOC end subroutine cvmix_kpp_compute_OBL_depth_low @@ -1547,17 +1764,14 @@ end subroutine cvmix_kpp_compute_OBL_depth_low function cvmix_kpp_compute_kOBL_depth(zw_iface, zt_cntr, OBL_depth) ! !DESCRIPTION: -! Computes the index of the level and interface above OBL\_depth. The index is +! Computes the index of the level and interface above \verb|OBL_depth|. The index is ! stored as a real number, and the integer index can be solved for in the ! following way:\\ -! \verb|kt| = index of cell center above OBL\_depth = \verb|nint(kOBL_depth)-1| -! \verb|kw| = index of interface above OBL\_depth = \verb|floor(kOBL_depth)| +! \verb|kt| = index of cell center above \verb|OBL_depth| = \verb|nint(kOBL_depth)-1| +! \verb|kw| = index of interface above \verb|OBL_depth| = \verb|floor(kOBL_depth)| !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), dimension(:), intent(in) :: zw_iface, zt_cntr real(cvmix_r8), intent(in) :: OBL_depth @@ -1608,11 +1822,11 @@ subroutine cvmix_kpp_compute_enhanced_diff(Mdiff_ktup, Tdiff_ktup, & ! !DESCRIPTION: ! The enhanced mixing described in Appendix D of LMD94 changes the diffusivity -! values at the interface between the cell center above OBL\_depth and the one -! below it, based on a weighted average of how close to each center OBL\_depth -! is. Note that we need to know whether OBL\_depth is above this interface or +! values at the interface between the cell center above \verb|OBL_depth| and the one +! below it, based on a weighted average of how close to each center \verb|OBL_depth| +! is. Note that we need to know whether \verb|OBL_depth| is above this interface or ! below it - we do this by comparing the indexes of the cell center above -! OBL\_depth (ktup) and the cell interface above OBL\_depth(kwup). +! \verb|OBL_depth| (\verb|ktup|) and the cell interface above \verb|OBL_depth|(\verb|kwup|). !\\ !\\ @@ -1715,13 +1929,11 @@ end subroutine cvmix_kpp_compute_enhanced_diff subroutine cvmix_kpp_compute_OBL_depth_wrap(CVmix_vars, CVmix_kpp_params_user) ! !DESCRIPTION: -! Computes the depth of the ocean boundary layer (OBL) for a given column. +! Computes the depth of the ocean boundary layer (\verb|CVmix_vars%BoundaryLayerDepth|) +! for a given column. !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_kpp_params_type), optional, target, intent(in) :: & CVmix_kpp_params_user @@ -1733,18 +1945,22 @@ subroutine cvmix_kpp_compute_OBL_depth_wrap(CVmix_vars, CVmix_kpp_params_user) !BOC ! Local variables - real(cvmix_r8) :: lcl_obl_depth, lcl_kobl_depth +! real(cvmix_r8) :: lcl_obl_depth, lcl_kobl_depth + real(cvmix_r8), dimension(1) :: lcl_Xi, lcl_sfcBuoy + lcl_Xi(1) = CVmix_vars%StokesMostXi + lcl_sfcBuoy(1) = CVmix_vars%SurfaceBuoyancyForcing call cvmix_kpp_compute_OBL_depth(CVmix_vars%BulkRichardson_cntr, & CVmix_vars%zw_iface, & - lcl_obl_depth, lcl_kobl_depth, & + CVmix_vars%BoundaryLayerDepth, & + CVmix_vars%kOBL_depth, & CVmix_vars%zt_cntr, & CVmix_vars%SurfaceFriction, & - CVmix_vars%SurfaceBuoyancyForcing, & + lcl_sfcBuoy, & CVmix_vars%Coriolis, & + lcl_Xi , & + CVmix_vars%zBottomOceanNumerics, & CVmix_kpp_params_user) - call cvmix_put(CVmix_vars, 'OBL_depth', lcl_obl_depth) - call cvmix_put(CVmix_vars, 'kOBL_depth', lcl_kobl_depth) !EOC @@ -1769,9 +1985,6 @@ function cvmix_kpp_compute_bulk_Richardson(zt_cntr, delta_buoy_cntr, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: ! * zt_cntr is level-center height (d in LMD94, units: m) ! * delta_buoy_cntr is the mean buoyancy estimate over surface layer minus @@ -1786,15 +1999,15 @@ function cvmix_kpp_compute_bulk_Richardson(zt_cntr, delta_buoy_cntr, & ! * Nsqr_iface: squared buoyancy frequency at interfaces (units: 1/s^2) ! * Vt_sqr_cntr: squared unresolved shear term (units m^2/s^2) ! See note in description about what values should be passed in + ! * bfsfc: surface buoyancy flux (units: m^2/s^3) real(cvmix_r8), dimension(size(zt_cntr)), intent(in), optional :: & - ws_cntr, Vt_sqr_cntr + bfsfc, ws_cntr, Vt_sqr_cntr real(cvmix_r8), dimension(size(zt_cntr)+1), intent(in), optional :: & N_iface, Nsqr_iface ! * EFactor: Langmuir enhancement factor for entrainment (units: none) ! * LaSL: surface layer averaged Langmuir number (units: none) - ! * bfsfc: surface buoyancy flux (units: m^2/s^3) ! * ustar: friction velocity (units: m/s) - real(cvmix_r8), intent(in), optional :: EFactor, LaSL, bfsfc, ustar + real(cvmix_r8), intent(in), optional :: EFactor, LaSL, ustar type(cvmix_kpp_params_type), intent(in), optional, target :: & CVmix_kpp_params_user @@ -1869,7 +2082,7 @@ end function cvmix_kpp_compute_bulk_Richardson subroutine cvmix_kpp_compute_turbulent_scales_0d(sigma_coord, OBL_depth, & surf_buoy_force, & surf_fric_vel, & - w_m, w_s, & + xi, w_m, w_s, & CVmix_kpp_params_user) ! !DESCRIPTION: @@ -1878,12 +2091,10 @@ subroutine cvmix_kpp_compute_turbulent_scales_0d(sigma_coord, OBL_depth, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), intent(in) :: sigma_coord real(cvmix_r8), intent(in) :: OBL_depth, surf_buoy_force, surf_fric_vel + real(cvmix_r8), optional, intent(in) :: xi type(cvmix_kpp_params_type), intent(in), optional, target :: & CVmix_kpp_params_user @@ -1896,8 +2107,15 @@ subroutine cvmix_kpp_compute_turbulent_scales_0d(sigma_coord, OBL_depth, & ! Local variables real(cvmix_r8), dimension(1) :: sigma, lcl_wm, lcl_ws + real(cvmix_r8) :: lcl_XI logical :: compute_wm, compute_ws + if( present( xi ) ) then + lcl_XI = xi + else + lcl_XI = cvmix_zero ! NO WAVES + end if + compute_wm = present(w_m) compute_ws = present(w_s) sigma(1) = sigma_coord @@ -1908,17 +2126,20 @@ subroutine cvmix_kpp_compute_turbulent_scales_0d(sigma_coord, OBL_depth, & if (compute_wm.and.compute_ws) then call cvmix_kpp_compute_turbulent_scales(sigma, OBL_depth, & surf_buoy_force, surf_fric_vel, & + xi = lcl_XI, & w_m = lcl_wm, w_s = lcl_ws, & CVmix_kpp_params_user=CVmix_kpp_params_user) else if (compute_wm) & call cvmix_kpp_compute_turbulent_scales(sigma, OBL_depth, & surf_buoy_force,surf_fric_vel,& + xi = lcl_XI, & w_m = lcl_wm, & CVmix_kpp_params_user=CVmix_kpp_params_user) if (compute_ws) & call cvmix_kpp_compute_turbulent_scales(sigma, OBL_depth, & surf_buoy_force,surf_fric_vel,& + xi = lcl_XI, & w_s = lcl_ws, & CVmix_kpp_params_user=CVmix_kpp_params_user) end if @@ -1940,7 +2161,7 @@ end subroutine cvmix_kpp_compute_turbulent_scales_0d subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, & OBL_depth, & surf_buoy_force, & - surf_fric_vel, & + surf_fric_vel, xi, & w_m, w_s, & CVmix_kpp_params_user) @@ -1954,12 +2175,10 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), dimension(:), intent(in) :: sigma_coord real(cvmix_r8), intent(in) :: OBL_depth, surf_buoy_force, surf_fric_vel + real(cvmix_r8), optional, intent(in) :: xi type(cvmix_kpp_params_type), intent(in), optional, target :: & CVmix_kpp_params_user @@ -1975,6 +2194,7 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, & logical :: compute_wm, compute_ws, l_LMD_ws real(cvmix_r8), dimension(size(sigma_coord)) :: zeta, sigma_loc real(cvmix_r8) :: vonkar, surf_layer_ext + real(cvmix_r8) :: chi_m, chi_s, L_StokesL type(cvmix_kpp_params_type), pointer :: CVmix_kpp_params_in n_sigma = size(sigma_coord) @@ -1991,6 +2211,67 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, & vonkar = CVmix_kpp_params_in%vonkarman surf_layer_ext = CVmix_kpp_params_in%surf_layer_ext + if ( CVmix_kpp_params_in%lStokesMOST ) then + if (present(xi)) then + L_StokesL = cvmix_one - xi + + if (surf_fric_vel.gt.cvmix_zero) then + sigma_loc(:) = min(cvmix_one , sigma_coord(:)) + zeta(:) = sigma_loc(:) * OBL_depth * surf_buoy_force * vonkar / & + (surf_fric_vel**3) + if (compute_wm) then + chi_m = compute_Stokes_chi( xi , lchi_m=.true. ) + do kw=1,n_sigma + w_m(kw) = compute_phi_inv(zeta(kw),CVmix_kpp_params_in, L_StokesL, lphi_m=.true.)*& + vonkar*surf_fric_vel / chi_m + end do + end if + if (compute_ws) then + chi_s = compute_Stokes_chi( xi , lchi_s=.true. ) + do kw=1,n_sigma + w_s(kw) = compute_phi_inv(zeta(kw),CVmix_kpp_params_in, L_StokesL, lphi_s=.true.)*& + vonkar*surf_fric_vel / chi_s + end do + end if + + else ! surf_fric_vel = 0 + if (compute_wm) then + if (surf_buoy_force.ge.cvmix_zero) then ! STABLE + w_m = cvmix_zero + else ! convective limit + chi_m = compute_Stokes_chi( xi , lchi_m=.true. ) + L_StokesL = cvmix_one - xi + do kw=1,n_sigma + w_m(kw) = -surf_buoy_force * real(14,cvmix_r8) * sigma_coord(kw) * & + OBL_depth * vonkar * L_StokesL + w_m(kw) = vonkar*(w_m(kw)**(cvmix_one/real(3,cvmix_r8))) / chi_m + end do + end if + end if ! compute_wm + + if (compute_ws) then + if (surf_buoy_force.ge.cvmix_zero) then ! STABLE + w_s = cvmix_zero + else + chi_s = compute_Stokes_chi( xi , lchi_s=.true. ) + L_StokesL = cvmix_one - xi + do kw=1,n_sigma ! convective limit + w_s(kw) = -surf_buoy_force * real(25,cvmix_r8) * sigma_coord(kw) * & + OBL_depth * vonkar * L_StokesL + w_s(kw) = vonkar*(w_s(kw)**(cvmix_one/real(3,cvmix_r8))) / chi_s + end do + end if ! surf_buoy_force >= 0 + end if ! compute_ws + + end if ! surf_fric_vel != 0 + + else + print*, "ERROR: Similarity xi must be present in 1d_sigma to use Stokes_MOST package!" + stop 1 + end if ! lStokesMOST and xi not present + + else ! not lStokesMOST + if (surf_fric_vel.ne.cvmix_zero) then if ((surf_buoy_force.ge.cvmix_zero) .and. l_LMD_ws) then sigma_loc(:) = sigma_coord(:) @@ -2065,35 +2346,36 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma(sigma_coord, & end if ! surf_buoy_force >= 0 end if ! compute_ws end if ! surf_fric_vel != 0 - + end if ! lStokesMOST !EOC end subroutine cvmix_kpp_compute_turbulent_scales_1d_sigma +!BOP + +! !IROUTINE: cvmix_kpp_compute_turbulent_scales_1d_OBL +! !INTERFACE: + subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, & OBL_depth, & surf_buoy_force, & surf_fric_vel, & - w_m, w_s, & + xi, w_m, w_s, & CVmix_kpp_params_user) ! !DESCRIPTION: ! Computes the turbulent velocity scales for momentum (\verb|w_m|) and scalars ! (\verb|w_s|) given a single $\sigma$ coordinate and an array of boundary ! layer depths. Note that the turbulent scales are a continuous function, so -! there is no restriction to only evaluating this routine at interfaces or -! cell centers. Also, if $\sigma >$ \verb|surf_layer_ext| (which is typically -! 0.1), \verb|w_m| and \verb|w_s| will be evaluated at the latter value. +! they are evaluated at sigma\_coord * OBL\_depth(z) using surf\_buoy\_force(z) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), intent(in) :: sigma_coord real(cvmix_r8), intent(in) :: surf_fric_vel real(cvmix_r8), dimension(:), intent(in) :: surf_buoy_force, OBL_depth + real(cvmix_r8), dimension(:), intent(in), optional :: xi type(cvmix_kpp_params_type), intent(in), optional, target :: & CVmix_kpp_params_user @@ -2109,6 +2391,7 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, & logical :: compute_wm, compute_ws, l_LMD_ws real(cvmix_r8), dimension(size(surf_buoy_force)) :: zeta, sigma_loc real(cvmix_r8) :: vonkar, surf_layer_ext + real(cvmix_r8) :: chi_m,chi_s,L_StokesL type(cvmix_kpp_params_type), pointer :: CVmix_kpp_params_in n_sigma = size(surf_buoy_force) @@ -2125,6 +2408,62 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, & vonkar = CVmix_kpp_params_in%vonkarman surf_layer_ext = CVmix_kpp_params_in%surf_layer_ext + if ( CVmix_kpp_params_in%lStokesMOST ) then + if (present(xi)) then + + if (surf_fric_vel.ne.cvmix_zero) then + zeta(:) = sigma_coord*OBL_depth(:)*surf_buoy_force(:)*vonkar / & + (surf_fric_vel**3) + if (compute_wm) then + do kw = 1,n_sigma + chi_m = compute_Stokes_chi( xi(kw) , lchi_m=.true. ) + L_StokesL = cvmix_one - xi(kw) !wgl - xi + w_m(kw)=compute_phi_inv(zeta(kw),CVmix_kpp_params_in,L_StokesL,lphi_m=.true.) * & + vonkar*surf_fric_vel / chi_m + end do + end if + + if (compute_ws) then + do kw = 1,n_sigma + chi_s = compute_Stokes_chi( xi(kw) , lchi_s=.true. ) + w_s(kw)=compute_phi_inv(zeta(kw),CVmix_kpp_params_in,L_StokesL,lphi_s=.true.) * & + vonkar*surf_fric_vel / chi_s + end do + end if + + else ! surf_fric_vel = 0 + if (compute_wm) then + do kw = 1,n_sigma + if (surf_buoy_force(kw).ge.cvmix_zero) then ! STABLE + w_m(kw) = cvmix_zero + else ! convective limit + L_StokesL = cvmix_one - xi(kw) + w_m(kw) = -surf_buoy_force(kw) * real(14,cvmix_r8) * sigma_coord * & + OBL_depth(kw) * vonkar * L_StokesL + w_m(kw) =vonkar*(w_m(kw)**(cvmix_one/real(3,cvmix_r8))) / compute_Stokes_chi(xi(kw),lchi_m=.true.) + end if + end do + end if + if (compute_ws) then + do kw = 1,n_sigma + if (surf_buoy_force(kw).ge.cvmix_zero) then ! STABLE + w_s(kw) = cvmix_zero + else + L_StokesL = cvmix_one - xi(kw) + w_s(kw) = -surf_buoy_force(kw) * real(25,cvmix_r8) * sigma_coord * & + OBL_depth(kw) * vonkar * L_StokesL + w_s(kw) =vonkar*(w_s(kw)**(cvmix_one/real(3,cvmix_r8))) / compute_Stokes_chi(xi(kw),lchi_s=.true.) + end if ! surf_buoy_force >= 0 + end do + end if ! compute_ws + end if ! surf_fric_vel = 0 + else + print*, "ERROR: Similarity xi must be present in 1d_OBL to use Stokes_MOST package!" + stop 1 + end if ! lStokesMOST but xi not present + + else ! not lStokesMOST + if (surf_fric_vel.ne.cvmix_zero) then sigma_loc = min(surf_layer_ext, sigma_coord) if (l_LMD_ws) then @@ -2176,7 +2515,7 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, & ! w_m = vonkar * u* / phi_m ! = vonkar * ((u*/phi_m)^3)^1/3 w_m(kw) = vonkar*(w_m(kw)**(cvmix_one/real(3,cvmix_r8))) - endif + end if end do end if ! compute_wm @@ -2200,6 +2539,7 @@ subroutine cvmix_kpp_compute_turbulent_scales_1d_OBL(sigma_coord, & end do end if ! compute_ws end if ! surf_fric_vel != 0 + end if ! lStokesMOST !EOC @@ -2226,9 +2566,6 @@ function cvmix_kpp_compute_unresolved_shear(zt_cntr, ws_cntr, N_iface, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: ! zt_cntr: height at center of cell (units: m) ! ws_cntr: w_s (turbulent scale factor) at center of cell (units: m/s) @@ -2238,11 +2575,12 @@ function cvmix_kpp_compute_unresolved_shear(zt_cntr, ws_cntr, N_iface, & ! note that you must provide exactly one of these two inputs! real(cvmix_r8), dimension(size(zt_cntr)+1), intent(in), optional :: & N_iface, Nsqr_iface + ! bfsfc: surface buoyancy flux above cell centers (units: m^2/s^3) + real(cvmix_r8), dimension(size(zt_cntr)), intent(in), optional :: bfsfc ! EFactor: Langmuir enhancement factor (units: none) ! LaSL: surface layer averaged Langmuir number (units: none) - ! bfsfc: surface buoyancy flux (units: m^2/s^3) ! ustar: friction velocity (units: m/s) - real(cvmix_r8), intent(in), optional :: EFactor, LaSL, bfsfc, ustar + real(cvmix_r8), intent(in), optional :: EFactor, LaSL, ustar type(cvmix_kpp_params_type), intent(in), optional, target :: & CVmix_kpp_params_user @@ -2256,6 +2594,9 @@ function cvmix_kpp_compute_unresolved_shear(zt_cntr, ws_cntr, N_iface, & ! Local variables integer :: kt, nlev real(cvmix_r8) :: Cv, Vtc + logical :: lwstar ! use wstar rather than w_s + real(cvmix_r8) :: wstar ! convective velocity scale + real(cvmix_r8) :: ws_wstar ! ratio in limit of pure convection ! N_cntr: buoyancy frequency at cell centers, derived from either N_iface ! or Nsqr_iface (units: 1/s) real(cvmix_r8), dimension(size(zt_cntr)) :: N_cntr @@ -2309,6 +2650,39 @@ function cvmix_kpp_compute_unresolved_shear(zt_cntr, ws_cntr, N_iface, & end if end if + if ( CVmix_kpp_params_in%lStokesMOST ) then + if (present(N_iface)) then + lwstar = .false. ! .true. + + ws_wstar = CVmix_kpp_params_in%vonkarman * real(25,cvmix_r8) ! * & + ws_wstar = CVmix_kpp_params_in%vonkarman * ws_wstar**(cvmix_one/real(3,cvmix_r8)) + + + Vtc = sqrt(0.2_cvmix_r8 *3.8409_cvmix_r8 /ws_wstar) /CVmix_kpp_params_in%Ri_crit + + Cv = 1.4_cvmix_r8 + + do kt=1,nlev + if (lwstar ) then + wstar = (MAX(0.0 , zt_cntr(kt) * bfsfc(kt) ))**(cvmix_one/real(3,cvmix_r8)) + cvmix_kpp_compute_unresolved_shear(kt) = & + -zt_cntr(kt) * N_iface(kt) * Cv * Vtc * wstar + else + cvmix_kpp_compute_unresolved_shear(kt) = & + -zt_cntr(kt) * N_iface(kt) * Cv * Vtc * ws_cntr(kt) / ws_wstar + end if + + if (cvmix_kpp_compute_unresolved_shear(kt).lt. & + CVmix_kpp_params_in%minVtsqr) then + cvmix_kpp_compute_unresolved_shear(kt) = CVmix_kpp_params_in%minVtsqr + end if + enddo + else + print*, "ERROR: StokesMOST package requires N_iface in cvmix_kpp_compute_unresolved_shear " + stop 1 + end if + else ! not lStokesMOST + ! options for Langmuir enhanced entrainment select case (CVmix_kpp_params_in%Langmuir_Entrainment_Opt) @@ -2354,7 +2728,7 @@ function cvmix_kpp_compute_unresolved_shear(zt_cntr, ws_cntr, N_iface, & stop 1 end if ! only apply Langmuir enhanced entrainment under unstable condition - if (bfsfc CVmix_kpp_params_saved + if (present(CVmix_kpp_params_user)) then + CVmix_kpp_params_in => CVmix_kpp_params_user + end if + + if ( CVmix_kpp_params_in%lStokesMOST ) then + + ! Move bottom of cell kSL up to Surface Layer Extent = SLDepth + uS_TMP = uS(kSL+1) + vS_TMP = vS(kSL+1) + uSbar_TMP = uSbar(kSL) + vSbar_TMP = vSbar(kSL) + uS(kSL+1) = uS_SLD + vS(kSL+1) = vS_SLD + uSbar(kSL)= uSbar_SLD + vSbar(kSL)= vSbar_SLD + + CempCGm= 3.5_cvmix_r8 + + ustar = MAX( surf_fric_vel , 1.e-4_cvmix_r8 ) ! > 0 + taux0 = ustar**2 * cos(omega_w2x) + tauy0 = ustar**2 * sin(omega_w2x) + Stk0 = sqrt( uS(1)**2 + vS(1)**2 ) + BLDepth = SLDepth / CVmix_kpp_params_in%surf_layer_ext + + ! Parameterized Buoyancy production of TKE + PBfact = 0.110_cvmix_r8 + PB = PBfact * MAX( -surf_buoy_force * BLdepth , cvmix_zero ) + + ! Compute Both Shear Production Terms down from Surface = initial top values + PU = 0.0 + PS = 0.0 + dtop = 0.0 + delU = uE(1) - uE(2) + delV = vE(1) - vE(2) + tauEtop = (taux0 * delU + tauy0 * delV ) / (zk(1) - zk(2) ) + tauxtop = taux0 + tauytop = tauy0 + + do ktmp = 1, kSL + ! SLdepth can be between cell interfaces kSL and kSL+1 + delH = min( max(cvmix_zero, SLdepth - dtop), (zi(ktmp) - zi(ktmp+1) ) ) + dbot = MIN( dtop + delH , SLdepth) + sigbot = dbot / BLdepth + Gbot = cvmix_kpp_composite_shape(sigbot) + TauMAG = ustar * ustar * Gbot / sigbot + delU = uE(ktmp) - uE(ktmp+1) + delV = vE(ktmp) - vE(ktmp+1) + Omega_E2x= atan2( delV , delU ) + cosOmega = cos(Omega_E2x) + sinOmega = sin(Omega_E2x) + tauCG = CempCGm * Gbot * (taux0 * cosOmega - tauy0 * sinOmega) + ! tauDG = sqrt( TauMAG**2 - tauCG**2 ) ! G + tauDG = TauMAG ! E + tauxbot = tauDG * cosOmega - tauCG * sinOmega + tauybot = tauDG * sinOmega + tauCG * cosOmega + tauEbot = (tauxbot * delU + tauybot * delV) / (zk(ktmp) - zk(ktmp+1) ) + + ! Increment Eulerian Shear Production + Pinc = 0.5_cvmix_r8 * (tauEbot + tauEtop) * delH + PU = PU + MAX( Pinc , cvmix_zero ) + + ! Increment Stokes Shear Production + Pinc = tauxtop*uS(ktmp) - tauxbot*uS(ktmp+1) + tauytop*vS(ktmp) - tauybot*vS(ktmp+1) + Pinc = Pinc - (tauxtop-tauxbot) * uSbar(ktmp) - (tauytop-tauybot) * vSbar(ktmp) + PS = PS + MAX( Pinc , cvmix_zero ) + + ! Bottom becomes next top + dtop = dbot + tauxtop = tauxbot + tauytop = tauybot + tauEtop = tauEbot + enddo + + ! Compute Stokes similarity parameter + StokesXI = PS / MAX( PU + PS + PB , 1.e-12_cvmix_r8 ) + + + ! Restore bottom of cell kSL at zi(kSL+1) with stored Stokes Drift ; ditto average over cell kSL + uS(kSL+1) = uS_TMP + vS(kSL+1) = vS_TMP + uSbar(kSL) = uSbar_TMP + vSbar(kSL) = vSbar_TMP + + else ! not lStokesMOST + StokesXI = cvmix_zero + end if + +!EOC - end function cvmix_kpp_ustokes_SL_model + end subroutine cvmix_kpp_compute_StokesXi end module cvmix_kpp diff --git a/src/shared/cvmix_math.F90 b/src/shared/cvmix_math.F90 index 64d6a302b..f9c0df7b4 100644 --- a/src/shared/cvmix_math.F90 +++ b/src/shared/cvmix_math.F90 @@ -216,9 +216,6 @@ function cvmix_math_evaluate_cubic(coeffs, x_in, fprime) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: real(cvmix_r8), dimension(4), intent(in) :: coeffs real(cvmix_r8), intent(in) :: x_in diff --git a/src/shared/cvmix_put_get.F90 b/src/shared/cvmix_put_get.F90 index 44ba53664..a28b4f52b 100644 --- a/src/shared/cvmix_put_get.F90 +++ b/src/shared/cvmix_put_get.F90 @@ -57,9 +57,6 @@ subroutine cvmix_put_int(CVmix_vars, varname, val, nlev_in) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -118,9 +115,6 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -298,9 +292,6 @@ subroutine cvmix_put_real_1D(CVmix_vars, varname, val, nlev_in) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), dimension(:), intent(in) :: val @@ -465,9 +456,6 @@ subroutine cvmix_put_real_2D(CVmix_vars, varname, val, nlev_in) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), dimension(:,:), intent(in) :: val @@ -524,9 +512,6 @@ subroutine cvmix_put_global_params_int(CVmix_params, varname, val) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -561,9 +546,6 @@ subroutine cvmix_put_global_params_real(CVmix_params, varname, val) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val diff --git a/src/shared/cvmix_shear.F90 b/src/shared/cvmix_shear.F90 index da897009e..a6a1f2fa5 100644 --- a/src/shared/cvmix_shear.F90 +++ b/src/shared/cvmix_shear.F90 @@ -127,7 +127,7 @@ subroutine cvmix_init_shear(CVmix_shear_params_user, mix_scheme, & ! the interior mixing scheme laid out in Large et al. !\\ !\\ -! PP requires setting $\nu_0$ (\verb|PP_nu_zero| in this routine), $alpha$ +! PP requires setting $\nu_0$ (\verb|PP_nu_zero| in this routine), $\alpha$ ! (\verb|PP_alpha|), and $n$ (\verb|PP_exp|), and returns ! \begin{eqnarray*} ! \nu_{PP} & = & \frac{\nu_0}{(1+\alpha \textrm{Ri})^n} + \nu_b \\ @@ -149,9 +149,8 @@ subroutine cvmix_init_shear(CVmix_shear_params_user, mix_scheme, & ! 0 & \textrm{Ri}_0 < \textrm{Ri} ! \end{array} \right. ! $$ -! -! !USES: -! Only those used by entire module. +!\\ +!\\ ! !INPUT PARAMETERS: character(len=*), optional, intent(in) :: mix_scheme, & @@ -289,9 +288,6 @@ subroutine cvmix_coeffs_shear_wrap(CVmix_vars, CVmix_shear_params_user) ! is needed at both T-points and U-points. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_shear_params_type), target, optional, intent(in) :: & @@ -345,9 +341,6 @@ subroutine cvmix_coeffs_shear_low(Mdiff_out, Tdiff_out, RICH, nlev, & ! is needed at both T-points and U-points. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_shear_params_type), target, optional, intent(in) :: & @@ -441,9 +434,6 @@ subroutine cvmix_put_shear_int(varname, val, CVmix_shear_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -487,9 +477,6 @@ subroutine cvmix_put_shear_real(varname, val, CVmix_shear_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -548,9 +535,6 @@ subroutine cvmix_put_shear_str(varname, val, CVmix_shear_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname character(len=*), intent(in) :: val @@ -595,9 +579,6 @@ function cvmix_get_shear_real(varname, CVmix_shear_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_shear_params_type), optional, target, intent(in) :: & @@ -653,9 +634,6 @@ function cvmix_get_shear_str(varname, CVmix_shear_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_shear_params_type), optional, target, intent(in) :: & diff --git a/src/shared/cvmix_tidal.F90 b/src/shared/cvmix_tidal.F90 index dc6dc8057..4e4efb5f0 100644 --- a/src/shared/cvmix_tidal.F90 +++ b/src/shared/cvmix_tidal.F90 @@ -151,9 +151,8 @@ subroutine cvmix_init_tidal(CVmix_tidal_params_user, mix_scheme, efficiency,& ! mixing scheme. ! - set \verb|mix_scheme = 'schmittner'| to use the Schmittner ! mixing scheme. -! -! !USES: -! Only those used by entire module. +!\\ +!\\ ! !INPUT PARAMETERS: character(len=*), optional, intent(in) :: mix_scheme, old_vals @@ -317,9 +316,6 @@ subroutine cvmix_coeffs_tidal_wrap(CVmix_vars, & ! parameterizations. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_tidal_params_type), target, optional, intent(in) :: & @@ -393,9 +389,6 @@ subroutine cvmix_coeffs_tidal_low(Mdiff_out, Tdiff_out, Nsqr, OceanDepth, & ! parameterizations. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_tidal_params_type), target, optional, intent(in) :: & @@ -483,9 +476,6 @@ subroutine cvmix_coeffs_tidal_schmittner & ! parameterizations. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_tidal_params_type), target, optional, intent(in) :: & @@ -550,8 +540,9 @@ subroutine cvmix_coeffs_tidal_schmittner & end subroutine cvmix_coeffs_tidal_schmittner !BOP - !IROUTINE: cvmix_compute_vert_dep - !INTERFACE: + +! !IROUTINE: cvmix_compute_vert_dep +! !INTERFACE: function cvmix_compute_vert_dep(zw, zt, nlev, CVmix_tidal_params) @@ -560,9 +551,6 @@ function cvmix_compute_vert_dep(zw, zt, nlev, CVmix_tidal_params) ! mixing. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_tidal_params_type), intent(in) :: CVmix_tidal_params @@ -604,8 +592,9 @@ function cvmix_compute_vert_dep(zw, zt, nlev, CVmix_tidal_params) end function cvmix_compute_vert_dep !BOP - !IROUTINE: cvmix_compute_vert_dep_Schmittner - !INTERFACE: + +! !IROUTINE: cvmix_compute_vert_dep_Schmittner +! !INTERFACE: function cvmix_compute_vert_dep_Schmittner(zw, nlev, CVmix_tidal_params) @@ -614,9 +603,6 @@ function cvmix_compute_vert_dep_Schmittner(zw, nlev, CVmix_tidal_params) ! mixing. !\\ !\\ -! -! !USES: -! only those used by entire module. ! !INPUT PARAMETERS: type(cvmix_tidal_params_type), intent(in) :: CVmix_tidal_params @@ -648,6 +634,7 @@ function cvmix_compute_vert_dep_Schmittner(zw, nlev, CVmix_tidal_params) end function cvmix_compute_vert_dep_Schmittner !BOP + ! !IROUTINE: cvmix_compute_Simmons_invariant_wrap ! !INTERFACE: @@ -661,9 +648,6 @@ subroutine cvmix_compute_Simmons_invariant_wrap(CVmix_vars, CVmix_params, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_global_params_type), intent(in) :: CVmix_params real(cvmix_r8), intent(in) :: energy_flux @@ -714,9 +698,6 @@ subroutine cvmix_compute_Simmons_invariant_low(nlev, energy_flux, rho, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: nlev real(cvmix_r8), intent(in) :: energy_flux, rho @@ -751,6 +732,7 @@ subroutine cvmix_compute_Simmons_invariant_low(nlev, energy_flux, rho, & end subroutine cvmix_compute_Simmons_invariant_low !BOP + ! !IROUTINE: cvmix_compute_Schmittner_invariant_wrap ! !INTERFACE: @@ -764,9 +746,6 @@ subroutine cvmix_compute_Schmittner_invariant_wrap(CVmix_vars, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_global_params_type), intent(in) :: CVmix_params type(cvmix_tidal_params_type), target, optional, intent(in) :: & @@ -801,6 +780,7 @@ subroutine cvmix_compute_Schmittner_invariant_wrap(CVmix_vars, & end subroutine cvmix_compute_Schmittner_invariant_wrap !BOP + ! !IROUTINE: cvmix_compute_Schmittner_invariant_low ! !INTERFACE: @@ -814,9 +794,6 @@ subroutine cvmix_compute_Schmittner_invariant_low(nlev, VertDep, efficiency, rho !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: nlev real(cvmix_r8), intent(in) :: efficiency @@ -864,6 +841,7 @@ subroutine cvmix_compute_Schmittner_invariant_low(nlev, VertDep, efficiency, rho end subroutine cvmix_compute_Schmittner_invariant_low !BOP + ! !IROUTINE: cvmix_compute_SchmittnerCoeff_wrap ! !INTERFACE: @@ -876,9 +854,6 @@ subroutine cvmix_compute_SchmittnerCoeff_wrap(CVmix_vars, nlev, energy_flux, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: nlev real(cvmix_r8), dimension(2:nlev+1), intent(in) :: energy_flux @@ -910,6 +885,7 @@ subroutine cvmix_compute_SchmittnerCoeff_wrap(CVmix_vars, nlev, energy_flux, & end subroutine cvmix_compute_SchmittnerCoeff_wrap !BOP + ! !IROUTINE: cvmix_compute_SchmittnerCoeff_low ! !INTERFACE: @@ -924,9 +900,6 @@ subroutine cvmix_compute_SchmittnerCoeff_low(nlev, energy_flux, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: nlev real(cvmix_r8), dimension(2:nlev+1,2:nlev+1), intent(in) :: exp_hab_zetar @@ -966,6 +939,7 @@ subroutine cvmix_compute_SchmittnerCoeff_low(nlev, energy_flux, & end subroutine cvmix_compute_SchmittnerCoeff_low !BOP + ! !IROUTINE: cvmix_compute_socn_tidal_invariant_wrap ! !INTERFACE: @@ -977,9 +951,6 @@ subroutine cvmix_compute_socn_tidal_invariant_wrap(CVmix_vars, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: type(cvmix_tidal_params_type), target, optional, intent(in) :: & CVmix_tidal_params_user @@ -1025,9 +996,6 @@ subroutine cvmix_compute_socn_tidal_invariant_low(nlev, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: nlev real(cvmix_r8), intent(in) :: lat @@ -1077,9 +1045,6 @@ subroutine cvmix_put_tidal_int(varname, val, CVmix_tidal_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname integer, intent(in) :: val @@ -1110,6 +1075,8 @@ subroutine cvmix_put_tidal_int(varname, val, CVmix_tidal_params_user) end subroutine cvmix_put_tidal_int +!BOP + ! !IROUTINE: cvmix_put_tidal_logical ! !INTERFACE: @@ -1120,9 +1087,6 @@ subroutine cvmix_put_tidal_logical(varname, val, CVmix_tidal_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname logical(cvmix_log_kind),intent(in) :: val @@ -1165,9 +1129,6 @@ subroutine cvmix_put_tidal_real(varname, val, CVmix_tidal_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname real(cvmix_r8), intent(in) :: val @@ -1222,9 +1183,6 @@ subroutine cvmix_put_tidal_str(varname, val, CVmix_tidal_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname character(len=*), intent(in) :: val @@ -1269,9 +1227,6 @@ function cvmix_get_tidal_real(varname, CVmix_tidal_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_tidal_params_type), optional, target, intent(in) :: & @@ -1324,9 +1279,6 @@ function cvmix_get_tidal_str(varname, CVmix_tidal_params_user) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname type(cvmix_tidal_params_type), optional, target, intent(in) :: & diff --git a/src/shared/cvmix_utils.F90 b/src/shared/cvmix_utils.F90 index fb37f3534..0d5c7ab2f 100644 --- a/src/shared/cvmix_utils.F90 +++ b/src/shared/cvmix_utils.F90 @@ -51,9 +51,6 @@ subroutine cvmix_update_wrap(old_vals, nlev, Mdiff_out, new_Mdiff, & !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: integer, intent(in) :: old_vals, nlev real(cvmix_r8), dimension(nlev+1), optional, intent(in) :: new_Mdiff, & @@ -116,9 +113,6 @@ function cvmix_att_name(varname) !\\ !\\ -! !USES: -! Only those used by entire module. - ! !INPUT PARAMETERS: character(len=*), intent(in) :: varname