diff --git a/docs/ocean/design_docs/harmonic_analysis/main.tex b/docs/ocean/design_docs/harmonic_analysis/main.tex
new file mode 100644
index 0000000000..b3831b8a71
--- /dev/null
+++ b/docs/ocean/design_docs/harmonic_analysis/main.tex
@@ -0,0 +1,439 @@
+\documentclass[11pt]{report}
+
+\usepackage{epsf,amsmath,amsfonts}
+\usepackage{graphicx}
+\usepackage{booktabs}
+\usepackage{color}
+\usepackage{natbib}
+\usepackage{multirow}
+\usepackage{hyperref}
+
+\setlength{\textwidth}{6.5in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\evensidemargin}{0in}
+\setlength{\textheight}{8in}
+\setlength{\topmargin}{0.5in}
+
+\newcommand{\ds}{\displaystyle}
+\setlength{\parskip}{1.2ex}
+\setlength{\parindent}{0mm}
+\newcommand{\bea}{\begin{eqnarray}}
+\newcommand{\eea}{\end{eqnarray}}
+\newcommand{\nn}{\nonumber}
+
+\def\Mark#1{{\textcolor{red}{\bf \textit{By Mark: } #1}}} % new text
+\def\Phillip#1{{\textcolor{cyan}{\bf \textit{By PhilW: } #1}}} % new text
+\def\Steven#1{{\textcolor{blue}{\bf \textit{By Steven: } #1}}} % new text
+\def\Luke#1{{\textcolor{green}{\bf \textit{By Luke: } #1}}} % new text
+\def\Comment#1{{\textcolor{magenta}{\bf \textit{Comment: } #1}}} % new text
+\begin{document}
+
+\title{MPAS-O Ocean Tidal Harmonic Decomposition }
+\author{Steven Brus, Brian Arbic, Kristin Barton, Nairita Pal, \\ Mark Petersen, Andrew Roberts, Joannes Westerink }
+
+
+
+\maketitle
+\tableofcontents
+
+%-----------------------------------------------------------------------
+
+\chapter{Summary}
+
+
+
+%The purpose of this section is to summarize what capability is to be added to the MPAS system through this design process. It should be clear what new code will do that the current code does not. Summarizing the primary challenges with respect to software design and implementation is also appropriate for this section. Finally, this statement should contain general statement with regard to what is ``success.''
+
+\section{MPAS-Ocean contributions}
+Decomposing the computed sea surface height into the amplitude and phase of the known tidal constituent frequencies is a common and useful way to visualize and validate tidal model results. These types of global plots are also valuable in assessing how changes in the model (mesh resolution, bathymetry, parameterizations, etc.) effect the tides globally.
+
+In a harmonic decomposition, the sea surface is approximated as a harmonic series with known constituent frequencies. The amplitudes and phases associated with these frequencies must be solved for in a manner that most closely matches the time series of the actual computed sea surface height with the series approximation. Once these amplitudes and phases are known, they can be plotted globally for each tidal constituent and compared with highly accurate data-assimilated tidal models.
+
+This type of analysis is implemented as a new analysis member in MPAS-Ocean. This allows the time interval at which the analysis is computed and written to file to be controlled using existing code infrastructure. It also allows this capability to be easily turned off for simulations which do not include tidal forcing.
+
+The methodology implemented is based on the harmonic least squares method \cite{westerink_lsq} implemented in the ADCIRC model \cite{Luettich1992ADCIRC} and borrows routines from the ADCIRC source code.
+
+\section{Science Questions}
+\begin{enumerate}
+ \item Assess the accuracy of MPAS-Ocean tidal simulations with observations and highly accurate, data-assimilated tidal models
+ \item Identify regions where the computed tidal solution is inaccurate to focus efforts on improving accuracy due to mesh resolution, bathymetry, dissipation parameterizations, etc.
+ \item Demonstrate how coupling with other E3SM components effects the computed tidal solution
+\end{enumerate}
+
+%-----------------------------------------------------------------------
+
+\chapter{Requirements}
+
+\section{Requirement: The harmonic analysis should decompose the computed sea surface height into amplitude and phase values for each major tidal constituent}
+The amplitudes and phases associated with the known constituent frequencies must be solved for in a manner that most closely matches the actual computed sea surface height with the series approximation. The method must be able to selectively and accurately separate closely spaced harmonics.
+
+\section{Requirement: Decomposition is calculated on-line during the simulations}
+The harmonic analysis capability should not require writing high-frequency global time-series to file. This would result in large storage requirements and require a subsequent step to compute the decomposition.
+
+\section{Requirement: Harmonic analysis should be able to be restarted at any point in the simulation}
+The restarted simulation should produce a result that is bit-for-bit with the uninterrupted simulation.
+
+\section{Requirement: The harmonic analysis should allow for general specification of the tidal constituent frequencies included in the analysis}
+Each of the major constituents should have namelist options which specify whether a given constituent is used in the analysis.
+
+\section{Requirement: The time period over which the harmonic analysis is performed should be user-specified}
+The harmonic analysis should not include the tidal-spin up period used to ramp the tidal forcing at the beginning of the simulation. Also, in some situations, additional time-series information does not improve the results of the decomposition.
+
+\section{Requirement: The interval at which the computed sea surface height is sampled for the harmonic analysis should be user-specified }
+This sampling interval can be used to controls the balance of accuracy and efficiency in the harmonic decomposition.
+%-----------------------------------------------------------------------
+
+\chapter{Algorithmic Formulations}
+Information in sections \ref{sec:astronomical_forcing}-\ref{sec:goverining_eqns} is reproduced here from the Tides Design Document for completeness.
+
+\section{Astronomical forcing}
+\label{sec:astronomical_forcing}
+The Newtonian equilibrium tidal potential is given by $\eta_{EQ}$. For the three largest semidiurnal tidal constituents, $\eta_{EQ}$ is given by equation (5) from \citet{chassignet_primer_2018} for $i=$ M$_{2}$, S$_{2}$, N$_{2}$ (applied 3 times and summed together), viz:
+\begin{equation}
+\eta_{EQ,i} = A_if_i(t_{ref})(1+k_{2,i}-h_{2,i})\cos^2(\phi)\cos\left[\omega_i(t-t_{ref}) + \chi_i(t_{ref}) + \nu_i(t_{ref}) + 2\lambda\right],
+\label{eq:Eq5}
+\end{equation}
+
+where the tidal amplitude is $A$, $f(t_{ref})$ is the the nodal factor accounting for the small modulations of amplitude (computed about once per year), $f(t_{ref})$ is slow modulation of amplitude (computed about once per year), the Love numbers $k_2$ and $h_2$ respectively account for the deformation of the solid earth due to the astronomical tidal forcing and the perturbation gravitational potential due to this deformation, $\phi$ is latitude, $\omega$ is tidal frequency, $t_{ref}$ is a reference time (often taken to be the beginning of a model run), $\chi(t_{ref})$ is the astronomical argument, and $\nu(t_ref)$ is the nodal factor accounting for the small modulations of phase, and $\lambda$ is longitude.
+
+For the diurnal constituents, the equilibrium tide is given by equation (6) of \citet{chassignet_primer_2018}, applied twice for $j=$ K$_{1}$ and O$_{1}$, viz:
+
+\begin{equation}
+\eta_{EQ,j} = A_j f_j(t_{ref}) (1+k_{2,j}-h_{2,j})\sin(2\phi)\cos\left[\omega_j(t-t_{ref}) + \chi_j(t_{ref}) + \nu_j(t_{ref}) + \lambda \right].
+\label{eq:Eq6}
+\end{equation}
+
+\section{Self-attraction and loading}
+\label{sec:SAL}
+
+Self-attraction and loading (SAL) constituent static file maps should be derived for SAL amplitude and phase from FES, for $k=$ M$_2$, S$_2$, N$_2$, K$_1$, and O$_1$. The maps can be used to compute $\eta_{SAL}$ as a sum, e.g., equation (12) from \citet{chassignet_primer_2018},
+
+\begin{equation}
+ \eta_{k,SAL}(\phi,\lambda) = A_m(\phi,\lambda)f(t_{ref})\cos\left[\omega (t-t_{ref}) + \chi(t_{ref}) + \nu(t_{ref}) - \phi_p(\phi,\lambda)\right],
+\label{eq:SAL}
+\end{equation}
+where $A_m(\phi,\lambda)$ is the amplitude of the SAL of the $k$ constituent as a function of latitude ($\lambda$) and longitude ($\phi$) and $\phi_p(\phi,\lambda)$ is the phase of SAL as function of lat/lon.
+Equation \ref{eq:SAL} takes amplitude and phase maps that provide a prediction with amplitude and phase using nodal factors and astronomical arguments.
+
+The self-attraction and loading harmonic constituents $A_m$ and $\phi_p$ can be derived from a harmonic analysis of self-attraction and loading maps produced by global tidal models, e.g., TPXO (\url{http://volkov.oce.orst.edu/tides/global.html}) or TUGO-m (\url{http://sirocco.obs-mip.fr/ocean-models/tugo/}).
+
+\section{Incorporation into governing equations}
+\label{sec:goverining_eqns}
+
+Once $\eta_{EQ}$ and $\eta_{SAL}$ are obtained, they can be used in an ocean model. For instance, in a shallow water model, we replace the term $\nabla \eta$ in the momentum equation with a gradient of $\eta$ referenced to the equilibrium tide and self-attraction and loading terms, viz:
+
+\begin{equation}
+ \nabla\eta \rightarrow \nabla\left( \eta - \eta_{EQ} - \eta_{SAL}\right)
+\end{equation}
+
+In essence, the equilibrium tide and self-attraction and loading terms reset the reference against which pressure gradients are computed.
+
+
+\begin{table}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|}
+\hline
+Constituent & $\omega\;\left(10^{-4}\,s^{-1}\right)$ & $A\;\left(\textrm{cm}\right)$ & $1+k_{2}-h_{2}$ & Period (solar days)\tabularnewline
+\hline
+\hline
+$\textrm{M}_{m}$ & 0.026392 & 2.2191 & 0.693 & 27.5546\tabularnewline
+\hline
+$\textrm{M}_{f}$ & 0.053234 & 4.2041 & 0.693 & 13.6608\tabularnewline
+\hline
+$\textrm{Q}_{1}$ & 0.6495854 & 1.9273 & 0.695 & 1.1195\tabularnewline
+\hline
+$\textrm{O}_{1}$ & 0.6759774 & 10.0661 & 0.695 & 1.0758\tabularnewline
+\hline
+$\textrm{P}_{1}$ & 0.7252295 & 4.6848 & 0.706 & 1.0027\tabularnewline
+\hline
+$\textrm{K}_{1}$ & 0.7292117 & 14.1565 & 0.736 & 0.9973\tabularnewline
+\hline
+$\textrm{N}_{2}$ & 1.378797 & 4.6397 & 0.693 & 0.5274\tabularnewline
+\hline
+$\textrm{M}_{2}$ & 1.405189 & 24.2334 & 0.693 & 0.5175\tabularnewline
+\hline
+$\textrm{S}_{2}$ & 1.454441 & 11.2743 & 0.693 & 0.5000\tabularnewline
+\hline
+$\textrm{K}_{2}$ & 1.458423 & 3.0684 & 0.693 & 0.4986\tabularnewline
+\hline
+\end{tabular}
+\label{tab:astronimcalFactors}
+\caption{Constituent-dependent frequencies $\omega$, astronomical forcing amplitudes A, and Love number combinations $1 + k_2 - h_2$ used to compute equilibrium tide $\eta_{EQ}$. The periods $2\pi/\omega$ are also given. Reproduced from Table 1 of \citet{chassignet_primer_2018, arbic2004accuracy}.}
+\end{center}
+\end{table}
+
+
+\section{Harmonic Least Squares Method}
+The method outlined here is described in more detail in \cite{westerink_lsq}.
+The computed sea-surface height $\eta(t)$ is sampled to obtain values $\eta(t_k)$ at time sampling points $t_k,~k=1,M$. The following harmonic series is used to approximate the sea surface height in the least-squares procedure:
+\begin{align}
+ g(t) = \sum_{j=1}^N(a_j\cos\omega_j t + b_j\sin\omega_j t).
+\end{align}
+In this equation, $a_j$ and $b_j$ are the unknown harmonic coefficients and $\omega_j$ are the frequencies associated with the $j=1,N$ tidal constituents. The error at a fiven sampling time between the approximate harmonic series and the computed sea surface height is
+\begin{align}
+ \varepsilon(t_k) = \sum_{j=1}^N(a_j\cos\omega_j t_k + b_j\sin\omega_j t_k) -\eta(t_k).
+\end{align}
+The sum of the squared error at all sampling times is
+\begin{align}
+ E = \sum_{k=1}^M\left(\varepsilon(t_k) \right)^2.
+\end{align}
+The error minimization between $g(t)$ and $f(t)$ is accomplished by requiring the partial derivatives of $E$with respect to each of the $a_j$ and $b_j$ coefficients to be zero:
+\begin{align}
+ \frac{\partial E}{\partial a_i} &= 0, \quad i=1,N \\
+ \frac{\partial E}{\partial b_i} &= 0, \quad i=1,N
+\end{align}
+Substituting for $E$:
+\begin{align}
+ \sum_{k=1}^M \left(2\varepsilon(t_k)\frac{\partial \varepsilon(t_k)}{\partial a_i}\right) &= 0, \quad i=1,N \\
+ \sum_{k=1}^M \left(2\varepsilon(t_k)\frac{\partial \varepsilon(t_k)}{\partial b_i}\right) &= 0, \quad i=1,N.
+\end{align}
+Substituting for the partial derivatives of $\varepsilon$ and dividing through by 2:
+\begin{align}
+ \sum_{k=1}^M \left(\varepsilon(t_k)\cos\omega_i t_k\right) &= 0, \quad i=1,N \\
+ \sum_{k=1}^M \left(\varepsilon(t_k)\sin\omega_i t_k\right) &= 0, \quad i=1,N
+\end{align}
+Substituting for $\varepsilon$ and rearranging:
+\begin{align}
+ \sum_{k=1}^M \left(\sum_{j=1}^N(a_j\cos\omega_j t_k + b_j\sin\omega_j t_k)\cos\omega_i t_k\right) &= \sum_{k=1}^M \eta(t_k)\cos\omega_i t_k, \quad i=1,N \\
+ \sum_{k=1}^M \left(\sum_{j=1}^N(a_j\cos\omega_j t_k + b_j\sin\omega_j t_k)\sin\omega_i t_k\right) &= \sum_{k=1}^M \eta(t_k)\sin\omega_i t_k, \quad i=1,N
+\end{align}
+Rearranging further:
+\begin{align}
+ \sum_{j=1}^N \left(a_j\sum_{k=1}^M(\cos\omega_j t_k\cos\omega_i t_k) + b_j\sum_{k=1}^M(\sin\omega_j t_k\cos\omega_i t_k)\right) &= \sum_{k=1}^M \eta(t_k)\cos\omega_i t_k, \quad i=1,N \\
+ \sum_{j=1}^N \left(a_j\sum_{k=1}^M(\cos\omega_j t_k\sin\omega_i t_k) + b_j\sum_{k=1}^M(\sin\omega_j t_k\sin\omega_i t_k)\right) &= \sum_{k=1}^M \eta(t_k)\sin\omega_i t_k, \quad i=1,N
+\end{align}
+This leads to the system of equations (example for 2 constituents):
+\begin{align}
+ \underbrace{\sum_{k=1}^M \begin{bmatrix}
+ \cos\omega_1 t_k\cos\omega_1 t_k & \sin\omega_1 t_k\cos\omega_1 t_k & \cos\omega_2 t_k\cos\omega_1 t_k & \sin\omega_2 t_k\cos\omega_1 t_k\\
+ \cos\omega_1 t_k\sin\omega_1 t_k & \sin\omega_1 t_k\sin\omega_1 t_k & \cos\omega_2 t_k\sin\omega_1 t_k & \sin\omega_2 t_k\sin\omega_1 t_k\\ \cos\omega_1 t_k\cos\omega_2 t_k & \sin\omega_1 t_k\cos\omega_2 t_k & \cos\omega_2 t_k\cos\omega_2 t_k & \sin\omega_2 t_k\cos\omega_2 t_k\\
+ \cos\omega_1 t_k\sin\omega_2 t_k & \sin\omega_1 t_k\sin\omega_2 t_k & \cos\omega_2 t_k\sin\omega_2 t_k & \sin\omega_2 t_k\sin\omega_2 t_k\\
+ \end{bmatrix}}_{\mathbf{M}}
+ \underbrace{\begin{bmatrix}
+ a_1 \\ b_1 \\ a_2 \\ b_2
+ \end{bmatrix}}_{\mathbf{a}}
+ =
+ \underbrace{\sum_{k=1}^M\begin{bmatrix}
+ \eta(t_k)\cos\omega_1 t_k \\
+ \eta(t_k)\sin\omega_1 t_k \\
+ \eta(t_k)\cos\omega_2 t_k \\
+ \eta(t_k)\sin\omega_2 t_k
+ \end{bmatrix}}_{\mathbf{f}}
+\end{align}
+For each mesh cell $l=1,K$ the linear system for that cell is solved
+\begin{align}
+ \mathbf{M}\mathbf{a}_l = \mathbf{f}_l.
+\end{align}
+Note that the LHS matrix $\mathbf{M}$ is the same for each cell. In addition, $\mathbf{M}$ is symmetric and in the code, only the lower triangular part is stored. The upper triangular part is filled out before the matrix is decomposed prior to solving each individual linear system for the mesh cells.
+Once the $a_j$ and $b_j$ coefficients are known, the amplitude and phase the the $j^\mathrm{th}$ constituent can be calculated as follows:
+\begin{align}
+ A_j &= \frac{\sqrt{a_j^2+b_j^2}}{f(t_{ref})}, \\
+ \Phi_j &= \arctan2(a_j,b_j) + \chi(t_{ref}) + \nu(t_{ref}),
+\end{align}
+%-----------------------------------------------------------------------
+
+\chapter{Design and Implementation}
+
+\section{Namelist options}
+\begin{verbatim}
+&AM_harmonicAnalysis
+ config_AM_harmonicAnalysis_enable = .true.
+ config_AM_harmonicAnalysis_compute_interval = 00:30:00
+ config_AM_harmonicAnalysis_start = 2012-11-01_00:00:00
+ config_AM_harmonicAnalysis_end = 2012-12-20_00:00:00
+ config_AM_harmonicAnalysis_output_stream = 'harmonicAnalysisOutput'
+ config_AM_harmonicAnalysis_restart_stream = 'harmonicAnalysisRestart'
+ config_AM_harmonicAnalysis_compute_on_startup = .false.
+ config_AM_harmonicAnalysis_write_on_startup = .false.
+ config_AM_harmonicAnalysis_use_M2 = .true.
+ config_AM_harmonicAnalysis_use_S2 = .true.
+ config_AM_harmonicAnalysis_use_N2 = .true.
+ config_AM_harmonicAnalysis_use_K2 = .true.
+ config_AM_harmonicAnalysis_use_K1 = .true.
+ config_AM_harmonicAnalysis_use_O1 = .true.
+ config_AM_harmonicAnalysis_use_Q1 = .true.
+ config_AM_harmonicAnalysis_use_P1 = .true.
+\end{verbatim}
+\section{Output stream}
+\begin{verbatim}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\end{verbatim}
+
+\section{Restart stream}
+\begin{verbatim}
+
+
+
+
+
+\end{verbatim}
+
+\section{Subroutine calls}
+The subroutines involved in computing the harmonic decomposition and how they function based on throughout the harmonic analysis period is summarized in \ref{tab:subroutines}
+\begin{table}[ht]
+\caption{Subroutine calls for harmonic analysis AM}
+\begin{center}
+\begin{tabular}{ll}
+ \hline
+ \multirow{5}{*}{Initialization} & {\tt ocn\_init\_harmonic\_analysis()} \\
+ &~~~~~ determine constituents selected in namelist \\
+ &~~~~~ {\tt tidal\_constituent\_factors()} \\
+ &~~~~~~~~~~ compute tidal constituent nodal factors \\
+ &~~~~~ zero out least squares matrix and vector \\ \cline{2-2}
+ \multirow{2}{*}{$t < t_{HAstart}$} & {\tt ocn\_compute\_harmonic\_analysis()} \\
+ &~~~~~ return \\ \cline{2-2}
+ \multirow{5}{*}{$t > t_{HAstart}$ \& $t < t_{HAend}$} & {\tt ocn\_compute\_harmonic\_analysis()} \\
+ &~~~~~ {\tt update\_least\_squares\_LHS\_matrix()} \\
+ &~~~~~~~~~~ sum $t_k$ contribution into $\mathbf{M}$ \\
+ &~~~~~ {\tt update\_least\_squares\_RHS\_vector()} \\
+ &~~~~~~~~~~ sum $t_k$ contribution into each $\mathbf{f}_l$\\ \cline{2-2}
+ \multirow{8}{*}{$t > t_{HAend}$ (first time)} & {\tt ocn\_compute\_harmonic\_analysis()} \\
+ &~~~~~ {\tt harmonic\_analysis\_solve()}\\
+ &~~~~~~~~~~ {\tt least\_squares\_decompose()}\\
+ &~~~~~~~~~~~~~~~ decompose $\mathbf{M}$ once\\
+ &~~~~~~~~~~ {\tt least\_squares\_solve()}\\
+ &~~~~~~~~~~~~~~~ solve each $\mathbf{M}\mathbf{a}_l=\mathbf{f}_l$ system\\
+ &~~~~~~~~~~ compute $A$ and $\Phi$ for each mesh cell and constituent\\
+ &~~~~~ separate solutions into output arrays \\ \cline{2-2}
+ \multirow{2}{*}{$t > t_{HAend}$ (subsequent times)} & {\tt ocn\_compute\_harmonic\_analysis()} \\
+ &~~~~~ return \\
+ \hline
+\end{tabular}
+\end{center}
+\label{tab:subroutines}
+\end{table}
+
+%-----------------------------------------------------------------------
+
+\chapter{Testing and Validation}
+
+The test case used is a 3-month global tidal simulation. This includes a 15 day tidal spin-up period. The harmonic analysis begins after the completion of the first 30 days and ends after an additional period of 49 days. The horizontal mesh can be found in Figure \ref{fig:mesh}. Globally, it is a 120km mesh with 30km resolution in the northwest Atlantic Ocean and 10km resolution in the Delaware bay region. The vertical mesh is the {\tt 100layerE3SMv1} configuration. Tidal potential forcing for the 8 major constituents ($M_2$, $S_2$, $N_2$, $K_2$, $K_1$, $O_1$, $Q_1$, $P_1$) is applied. The split explicit time integrator is used with a 5 minute baroclinic time step and a 15 second barotropic time step.
+
+The MPAS-Ocean results are compared with the data-assimilated TPXO8 model. Given the coarse mesh resolution and the lack of tuning, the results are not very accurate. However, the comparison does show that the harmonic analysis is being computed correctly. A direct water level comparison is shown in Figure \ref{fig:water_level}. The amplitude and phase plots are shown in \ref{fig:M2Amplitude}-\ref{fig:K1Phase}
+
+\begin{figure}
+ \centering
+ \includegraphics[width=4in]{cellWidth.png}
+ \caption{USDEQU120at30cr10}
+ \label{fig:mesh}
+\end{figure}
+\begin{figure}
+ \centering
+ \includegraphics[width=3.5in]{8537121.png}
+ \caption{Water level comparison}
+ \label{fig:water_level}
+\end{figure}
+\begin{figure}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{M2Amplitude_comparison_compressed.png}
+ \caption{$M_2$ amplitude comparison}
+ \label{fig:M2Amplitude}
+ \end{minipage}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{M2Phase_comparison_compressed.png}
+ \caption{$M_2$ phase comparison}
+ \label{fig:M2Phase}
+ \end{minipage}
+\end{figure}
+\begin{figure}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{N2Amplitude_comparison_compressed.png}
+ \caption{$N_2$ amplitude comparison}
+ \label{fig:N2Amplitude}
+ \end{minipage}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{N2Phase_comparison_compressed.png}
+ \caption{$N_2$ phase comparison}
+ \label{fig:N2Phase}
+ \end{minipage}
+\end{figure}
+\begin{figure}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{S2Amplitude_comparison_compressed.png}
+ \caption{$S_2$ amplitude comparison}
+ \label{fig:S2Amplitude}
+ \end{minipage}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{S2Phase_comparison_compressed.png}
+ \caption{$S_2$ phase comparison}
+ \label{fig:S2Phase}
+ \end{minipage}
+\end{figure}
+\begin{figure}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{O1Amplitude_comparison_compressed.png}
+ \caption{$O_1$ amplitude comparison}
+ \label{fig:O1Amplitude}
+ \end{minipage}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{O1Phase_comparison_compressed.png}
+ \caption{$O_1$ phase comparison}
+ \label{fig:O1Phase}
+ \end{minipage}
+\end{figure}
+\begin{figure}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{K1Amplitude_comparison_compressed.png}
+ \caption{$K_1$ amplitude comparison}
+ \label{fig:K1Amplitude}
+ \end{minipage}
+ \begin{minipage}{.5\textwidth}
+ \centering
+ \includegraphics[width=2.75in]{K1Phase_comparison_compressed.png}
+ \caption{$K_1$ phase comparison}
+ \label{fig:K1Phase}
+ \end{minipage}
+\end{figure}
+
+%-----------------------------------------------------------------------
+\bibliographystyle{unsrtnat}
+\bibliography{tides}
+
+
+\end{document}
+
diff --git a/docs/ocean/design_docs/harmonic_analysis/tides.bib b/docs/ocean/design_docs/harmonic_analysis/tides.bib
new file mode 100644
index 0000000000..0373ae0bff
--- /dev/null
+++ b/docs/ocean/design_docs/harmonic_analysis/tides.bib
@@ -0,0 +1,48 @@
+@incollection{chassignet_primer_2018,
+ title = {A {Primer} on {Global} {Internal} {Tide} and {Internal} {Gravity} {Wave} {Continuum} {Modeling} in {HYCOM} and {MITgcm}},
+ isbn = {978-1-72054-997-0},
+ url = {http://purl.flvc.org/fsu/fd/FSU\_libsubv1\_scholarship\_submission\_1536242074\_55feafcc},
+ language = {en},
+ urldate = {2018-10-23},
+ booktitle = {New {Frontiers} in {Operational} {Oceanography}},
+ publisher = {GODAE OceanView},
+ author = {Arbic, Brian K. and Alford, Matthew H. and Ansong, Joseph K. and Buijsman, Maarten C. and Ciotti, Robert B. and Farrar, J. Thomas and Hallberg, Robert W. and Henze, Christopher E. and Hill, Christopher N. and Luecke, Conrad A. and Menemenlis, Dimitris and Metzger, E. Joseph and Müeller, Malte and Nelson, Arin D. and Nelson, Bron C. and Ngodock, Hans E. and Ponte, Rui M. and Richman, James G. and Savage, Anna C. and Scott, Robert B. and Shriver, Jay F. and Simmons, Harper L. and Souopgui, Innocent and Timko, Patrick G. and Wallcraft, Alan J. and Zamudio, Luis and Zhao, Zhongxiang},
+ editor = {Chassignet, Eric P. and Pascual, Ananda and Tintoré, Joaquin and Verron, Jacques},
+ month = aug,
+ year = {2018},
+ doi = {10.17125/gov2018.ch13},
+ file = {Arbic et al. - 2018 - A Primer on Global Internal Tide and Internal Grav.pdf:/Users/pwolfram/Zotero/storage/TEDRP9CP/Arbic et al. - 2018 - A Primer on Global Internal Tide and Internal Grav.pdf:application/pdf}
+}
+
+@article{Luettich1992ADCIRC,
+ author={Luettich, R.A. and Westerink, J.J. and Scheffner, N.W.},
+ title = {{ADCIRC}: {An} {Advanced} {Three}-{Dimensional} {Circulation} {Model} for {Shelves}, {Coasts}, and {Estuaries}. {Report} 1. {Theory} and {Methodology} of {ADCIRC-2DDI} and {ADCIRC-3DL}.},
+ language = {en},
+ pages = {143},
+ year={1992}
+}
+
+@article{arbic2004accuracy,
+ title={The accuracy of surface elevations in forward global barotropic and baroclinic tide models},
+ author={Arbic, Brian K and Garner, Stephen T and Hallberg, Robert W and Simmons, Harper L},
+ journal={Deep Sea Research Part II: Topical Studies in Oceanography},
+ volume={51},
+ number={25-26},
+ pages={3069--3101},
+ year={2004},
+ publisher={Elsevier}
+}
+
+@article{westerink_lsq,
+author = {Westerink, J. J. and Connor, J. J. and Stolzenbach, K. D.},
+title = {A frequency–time domain finite element model for tidal circulation based on the least-squares harmonic analysis method},
+journal = {International Journal for Numerical Methods in Fluids},
+volume = {8},
+number = {7},
+pages = {813-843},
+keywords = {Shallow Water Equations, Iterative, Harmonic Analysis, Least Squares, Finite Element, Tides},
+doi = {10.1002/fld.1650080706},
+url = {https://onlinelibrary.wiley.com/doi/abs/10.1002/fld.1650080706},
+eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1002/fld.1650080706},
+year = {1988}
+}
diff --git a/src/core_ocean/Registry.xml b/src/core_ocean/Registry.xml
index 81f8b7fbbc..be834b1c05 100644
--- a/src/core_ocean/Registry.xml
+++ b/src/core_ocean/Registry.xml
@@ -97,7 +97,11 @@
/>
+
@@ -544,6 +548,10 @@
/>
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1354,6 +1394,7 @@
+
@@ -1760,6 +1801,7 @@
+
+
@@ -3008,6 +3054,27 @@
packages="tidalForcing"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core_ocean/analysis_members/Registry_sediment_flux_index.xml b/src/core_ocean/analysis_members/Registry_sediment_flux_index.xml
new file mode 100644
index 0000000000..0baed7a34a
--- /dev/null
+++ b/src/core_ocean/analysis_members/Registry_sediment_flux_index.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core_ocean/analysis_members/Registry_sediment_transport.xml b/src/core_ocean/analysis_members/Registry_sediment_transport.xml
new file mode 100644
index 0000000000..06d0c622da
--- /dev/null
+++ b/src/core_ocean/analysis_members/Registry_sediment_transport.xml
@@ -0,0 +1,272 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core_ocean/analysis_members/mpas_ocn_analysis_driver.F b/src/core_ocean/analysis_members/mpas_ocn_analysis_driver.F
index 86157ce16d..88781025c8 100644
--- a/src/core_ocean/analysis_members/mpas_ocn_analysis_driver.F
+++ b/src/core_ocean/analysis_members/mpas_ocn_analysis_driver.F
@@ -51,6 +51,9 @@ module ocn_analysis_driver
use ocn_moc_streamfunction
use ocn_ocean_heat_content
use ocn_mixed_layer_heat_budget
+ use ocn_sediment_flux_index
+ use ocn_sediment_transport
+ use ocn_harmonic_analysis
! use ocn_TEM_PLATE
implicit none
@@ -198,6 +201,9 @@ subroutine ocn_analysis_setup_packages(configPool, packagePool, iocontext, err)!
call mpas_pool_add_config(analysisMemberList, 'eddyProductVariables', 1)
call mpas_pool_add_config(analysisMemberList, 'mocStreamfunction', 1)
call mpas_pool_add_config(analysisMemberList, 'oceanHeatContent', 1)
+ call mpas_pool_add_config(analysisMemberList, 'sedimentFluxIndex', 1)
+ call mpas_pool_add_config(analysisMemberList, 'sedimentTransport', 1)
+ call mpas_pool_add_config(analysisMemberList, 'harmonicAnalysis', 1)
! call mpas_pool_add_config(analysisMemberList, 'temPlate', 1)
! DON'T EDIT BELOW HERE
@@ -1057,6 +1063,8 @@ subroutine ocn_bootstrap_analysis_members(domain, analysisMemberName, iErr)!{{{
call ocn_bootstrap_pointwise_stats(domain, err_tmp)
else if ( analysisMemberName(1:nameLength) == 'transectTransport' ) then
call ocn_init_transect_transport(domain, err_tmp)
+! else if ( analysisMemberName(1:nameLength) == 'sedimentFluxIndex' ) then
+! call ocn_init_sediment_flux_index(domain, err_tmp)
! else if ( analysisMemberName(1:nameLength) == 'temPlate' ) then
! call ocn_init_TEM_PLATE(domain, err_tmp)
end if
@@ -1128,6 +1136,12 @@ subroutine ocn_init_analysis_members(domain, analysisMemberName, iErr)!{{{
call ocn_init_ocean_heat_content(domain, err_tmp)
else if ( analysisMemberName(1:nameLength) == 'mixedLayerHeatBudget' ) then
call ocn_init_mixed_layer_heat_budget(domain,err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentFluxIndex' ) then
+ call ocn_init_sediment_flux_index(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentTransport' ) then
+ call ocn_init_sediment_transport(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'harmonicAnalysis' ) then
+ call ocn_init_harmonic_analysis(domain, err_tmp)
! else if ( analysisMemberName(1:nameLength) == 'temPlate' ) then
! call ocn_init_TEM_PLATE(domain, err_tmp)
! rpn is third to last
@@ -1224,6 +1238,12 @@ subroutine ocn_compute_analysis_members(domain, timeLevel, analysisMemberName, i
call ocn_compute_ocean_heat_content(domain, timeLevel, err_tmp)
else if ( analysisMemberName(1:nameLength) == 'mixedLayerHeatBudget' ) then
call ocn_compute_mixed_layer_heat_budget(domain, timeLevel, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentFluxIndex' ) then
+ call ocn_compute_sediment_flux_index(domain, timeLevel, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentTransport' ) then
+ call ocn_compute_sediment_transport(domain, timeLevel, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'harmonicAnalysis' ) then
+ call ocn_compute_harmonic_analysis(domain, timeLevel, err_tmp)
! else if ( analysisMemberName(1:nameLength) == 'temPlate' ) then
! call ocn_compute_TEM_PLATE(domain, timeLevel, err_tmp)
! rpn is third to last
@@ -1325,6 +1345,12 @@ subroutine ocn_restart_analysis_members(domain, analysisMemberName, iErr)!{{{
call ocn_restart_ocean_heat_content(domain, err_tmp)
else if ( analysisMemberName(1:nameLength) == 'mixedLayerHeatBudget' ) then
call ocn_restart_mixed_layer_heat_budget(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentFluxIndex' ) then
+ call ocn_restart_sediment_flux_index(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentTransport' ) then
+ call ocn_restart_sediment_transport(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'harmonicAnalysis' ) then
+ call ocn_restart_harmonic_analysis(domain, err_tmp)
! else if ( analysisMemberName(1:nameLength) == 'temPlate' ) then
! call ocn_restart_TEM_PLATE(domain, err_tmp)
! rpn is third to last
@@ -1420,6 +1446,12 @@ subroutine ocn_finalize_analysis_members(domain, analysisMemberName, iErr)!{{{
call ocn_finalize_ocean_heat_content(domain,err_tmp)
else if ( analysisMemberName(1:nameLength) == 'mixedLayerHeatBudget' ) then
call ocn_finalize_mixed_layer_heat_budget(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentFluxIndex' ) then
+ call ocn_finalize_sediment_flux_index(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'sedimentTransport' ) then
+ call ocn_finalize_sediment_transport(domain, err_tmp)
+ else if ( analysisMemberName(1:nameLength) == 'harmonicAnalysis' ) then
+ call ocn_finalize_harmonic_analysis(domain, err_tmp)
! else if ( analysisMemberName(1:nameLength) == 'temPlate' ) then
! call ocn_finalize_TEM_PLATE(domain, err_tmp)
! rpn is third to last
diff --git a/src/core_ocean/analysis_members/mpas_ocn_harmonic_analysis.F b/src/core_ocean/analysis_members/mpas_ocn_harmonic_analysis.F
new file mode 100644
index 0000000000..4d51fd608a
--- /dev/null
+++ b/src/core_ocean/analysis_members/mpas_ocn_harmonic_analysis.F
@@ -0,0 +1,821 @@
+! Copyright (c) 2013, Los Alamos National Security, LLC (LANS)
+! and the University Corporation for Atmospheric Research (UCAR).
+!
+! Unless noted otherwise source code is licensed under the BSD license.
+! Additional copyright and license information can be found in the LICENSE file
+! distributed with this code, or at http://mpas-dev.github.com/license.html
+!
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+!
+! ocn_harmonic_analysis
+!
+!> \brief MPAS ocean analysis mode member: harmonic_analysis
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> MPAS ocean analysis mode member: harmonic_analysis
+!>
+!> This module contains subroutines to compute the harmonic decomposition
+!> of the sea-surface-height timeseries into an amplitude and phase for a
+!> given number of tidal constituents.
+!>
+!> The subroutines that compute the harmonic decomposition are taken from the
+!> ADCIRC model developed by R.A. Luettich, Jr. (University of North Carolina at Chapel Hill)
+!> and J.J. Westerink (University of Notre Dame).
+!>
+!-----------------------------------------------------------------------
+
+module ocn_harmonic_analysis
+
+ use mpas_kind_types
+ use mpas_derived_types
+ use mpas_pool_routines
+ use mpas_timekeeping
+ use mpas_stream_manager
+ use mpas_constants
+ use ocn_constants
+ use ocn_config
+ use ocn_diagnostics_routines
+ use ocn_vel_tidal_potential, only: char_array,tidal_constituent_factors
+
+ implicit none
+ private
+ save
+
+ !--------------------------------------------------------------------
+ !
+ ! Public parameters
+ !
+ !--------------------------------------------------------------------
+
+ !--------------------------------------------------------------------
+ !
+ ! Public member functions
+ !
+ !--------------------------------------------------------------------
+
+ public :: ocn_init_harmonic_analysis, &
+ ocn_compute_harmonic_analysis, &
+ ocn_restart_harmonic_analysis, &
+ ocn_finalize_harmonic_analysis
+
+ !--------------------------------------------------------------------
+ !
+ ! Private module variables
+ !
+ !--------------------------------------------------------------------
+
+ type(char_array), dimension(37) :: constituentList
+ integer :: leastSquaresSolution
+
+!***********************************************************************
+
+contains
+
+!***********************************************************************
+!
+! routine ocn_init_harmonic_analysis
+!
+!> \brief Initialize MPAS-Ocean analysis member
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> This routine conducts all initializations required for the
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_init_harmonic_analysis(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ type (dm_info) :: dminfo
+ type (block_type), pointer :: block
+ type (mpas_pool_type), pointer :: harmonicAnalysisAMPool
+
+ integer, pointer :: nAnalysisConstituents
+ real (kind=RKIND), pointer :: harmonicAnalysisStart
+ real (kind=RKIND), pointer :: harmonicAnalysisEnd
+ real (kind=RKIND), dimension(:,:), pointer :: leastSquaresLHSMatrix
+ real (kind=RKIND), dimension(:,:), pointer :: leastSquaresRHSVector
+ real (kind=RKIND), dimension(:,:), pointer :: decomposedConstituentAmplitude
+ real (kind=RKIND), dimension(:,:), pointer :: decomposedConstituentPhase
+ real (kind=RKIND), dimension(:), pointer :: analysisConstituentFrequency
+ real (kind=RKIND), dimension(:), pointer :: analysisConstituentNodalAmplitude
+ real (kind=RKIND), dimension(:), pointer :: analysisConstituentNodalPhase
+ real (kind=RKIND), dimension(:), allocatable :: tidalConstituentAmplitude
+ real (kind=RKIND), dimension(:), allocatable :: tidalConstituentLoveNumbers
+ real (kind=RKIND), dimension(:), allocatable :: tidalConstituentAstronomical
+ integer, dimension(:), allocatable :: tidalConstituentType
+
+ type (MPAS_Time_Type) :: refTime
+ integer :: iCon
+
+ err = 0
+
+ leastSquaresSolution = 0
+
+ dminfo = domain % dminfo
+
+ block => domain % blocklist
+ do while (associated(block))
+ call mpas_pool_get_subpool(block % structs, 'harmonicAnalysisAM', harmonicAnalysisAMPool)
+
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'nAnalysisConstituents', nAnalysisConstituents)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'leastSquaresLHSMatrix', leastSquaresLHSMatrix)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'leastSquaresRHSVector', leastSquaresRHSVector)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'analysisConstituentFrequency', analysisConstituentFrequency)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'analysisConstituentNodalAmplitude', analysisConstituentNodalAmplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'analysisConstituentNodalPhase', analysisConstituentNodalPhase)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'decomposedConstituentAmplitude', decomposedConstituentAmplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'decomposedConstituentPhase', decomposedConstituentPhase)
+
+ call mpas_set_time(refTime, dateTimeString=config_tidal_potential_reference_time)
+
+ nAnalysisConstituents = 0
+ if (config_AM_harmonicAnalysis_use_M2) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'M2'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_S2) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'S2'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_N2) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'N2'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_K2) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'K2'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_K1) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'K1'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_O1) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'O1'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_Q1) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'Q1'
+ end if
+
+ if (config_AM_harmonicAnalysis_use_P1) then
+ nAnalysisConstituents = nAnalysisConstituents + 1
+ constituentList(nAnalysisConstituents)%constituent = 'P1'
+ end if
+
+ allocate(tidalConstituentAmplitude(nAnalysisConstituents))
+ allocate(tidalConstituentLoveNumbers(nAnalysisConstituents))
+ allocate(tidalConstituentAstronomical(nAnalysisConstituents))
+ allocate(tidalConstituentType(nAnalysisConstituents))
+
+ call tidal_constituent_factors(constituentList,nAnalysisConstituents,refTime, &
+ analysisConstituentFrequency, &
+ tidalConstituentAmplitude, &
+ tidalConstituentLoveNumbers, &
+ analysisConstituentNodalAmplitude, &
+ tidalConstituentAstronomical, &
+ analysisConstituentNodalPhase, &
+ tidalConstituentType, &
+ err)
+
+ if (.not. config_do_restart) then
+ leastSquaresRHSVector = 0.0_RKIND
+ leastSquaresLHSMatrix = 0.0_RKIND
+ end if
+
+
+ do iCon = 1,nAnalysisConstituents
+ call mpas_log_write('Constituent '//constituentList(iCon)%constituent)
+ call mpas_log_write(' Frequency $r', realArgs=(/ analysisConstituentFrequency(iCon) /))
+ call mpas_log_write(' Amplitude $r', realArgs=(/ tidalConstituentAmplitude(iCon) /))
+ call mpas_log_write(' LoveNumbers $r', realArgs=(/ tidalConstituentLoveNumbers(iCon) /))
+ call mpas_log_write(' NodalAmplitude $r', realArgs=(/ analysisConstituentNodalAmplitude(iCon) /))
+ call mpas_log_write(' Astronomical argument $r', realArgs=(/ tidalConstituentAstronomical(iCon) /))
+ call mpas_log_write(' NodalPhase $r', realArgs=(/ analysisConstituentNodalPhase(iCon) /))
+ call mpas_log_write(' Type $i', intArgs=(/ tidalConstituentType(iCon) /))
+ call mpas_log_write(' ')
+ end do
+
+ block => block % next
+ end do
+
+ end subroutine ocn_init_harmonic_analysis!}}}
+
+!***********************************************************************
+!
+! routine ocn_compute_harmonic_analysis
+!
+!> \brief Compute MPAS-Ocean analysis member
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> This routine conducts all computation required for this
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_compute_harmonic_analysis(domain, timeLevel, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(in) :: timeLevel
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ type (dm_info) :: dminfo
+ type (block_type), pointer :: block
+ type (mpas_pool_type), pointer :: statePool
+ type (mpas_pool_type), pointer :: meshPool
+ type (mpas_pool_type), pointer :: scratchPool
+ type (mpas_pool_type), pointer :: diagnosticsPool
+ type (mpas_pool_type), pointer :: harmonicAnalysisAMPool
+ type (mpas_time_type) :: current_time
+ type (mpas_time_type) :: harmonicAnalysisStart
+ type (mpas_time_type) :: harmonicAnalysisEnd
+
+ integer, pointer :: nCellsSolve
+ integer, pointer :: nAnalysisConstituents
+ real (kind=RKIND), pointer :: daysSinceStartOfSim
+ real (kind=RKIND), dimension(:), pointer :: ssh
+ real (kind=RKIND), dimension(:,:), pointer :: leastSquaresLHSMatrix
+ real (kind=RKIND), dimension(:,:), pointer :: leastSquaresRHSVector
+ real (kind=RKIND), dimension(:), pointer :: analysisConstituentFrequency
+ real (kind=RKIND), dimension(:), pointer :: analysisConstituentNodalAmplitude
+ real (kind=RKIND), dimension(:), pointer :: analysisConstituentNodalPhase
+ real (kind=RKIND), dimension(:,:), pointer :: decomposedConstituentAmplitude
+ real (kind=RKIND), dimension(:,:), pointer :: decomposedConstituentPhase
+ real (kind=RKIND), dimension(:), pointer :: M2Amplitude
+ real (kind=RKIND), dimension(:), pointer :: M2Phase
+ real (kind=RKIND), dimension(:), pointer :: S2Amplitude
+ real (kind=RKIND), dimension(:), pointer :: S2Phase
+ real (kind=RKIND), dimension(:), pointer :: N2Amplitude
+ real (kind=RKIND), dimension(:), pointer :: N2Phase
+ real (kind=RKIND), dimension(:), pointer :: K2Amplitude
+ real (kind=RKIND), dimension(:), pointer :: K2Phase
+ real (kind=RKIND), dimension(:), pointer :: K1Amplitude
+ real (kind=RKIND), dimension(:), pointer :: K1Phase
+ real (kind=RKIND), dimension(:), pointer :: O1Amplitude
+ real (kind=RKIND), dimension(:), pointer :: O1Phase
+ real (kind=RKIND), dimension(:), pointer :: Q1Amplitude
+ real (kind=RKIND), dimension(:), pointer :: Q1Phase
+ real (kind=RKIND), dimension(:), pointer :: P1Amplitude
+ real (kind=RKIND), dimension(:), pointer :: P1Phase
+
+ integer :: iCell
+ integer :: iCon
+ real (kind=RKIND) :: time
+
+ err = 0
+
+ dminfo = domain % dminfo
+
+ block => domain % blocklist
+ do while (associated(block))
+ call mpas_pool_get_subpool(block % structs, 'state', statePool)
+ call mpas_pool_get_subpool(block % structs, 'mesh', meshPool)
+ call mpas_pool_get_subpool(block % structs, 'diagnostics', diagnosticsPool)
+ call mpas_pool_get_subpool(block % structs, 'harmonicAnalysisAM', harmonicAnalysisAMPool)
+
+ call mpas_pool_get_dimension(block % dimensions, 'nCellsSolve', nCellsSolve)
+ call mpas_pool_get_array(diagnosticsPool, "daysSinceStartOfSim", daysSinceStartOfSim)
+ call mpas_pool_get_array(statePool, 'ssh', ssh, timeLevel)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'nAnalysisConstituents', nAnalysisConstituents)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'leastSquaresLHSMatrix', leastSquaresLHSMatrix)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'leastSquaresRHSVector', leastSquaresRHSVector)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'analysisConstituentFrequency', analysisConstituentFrequency)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'analysisConstituentNodalAmplitude', analysisConstituentNodalAmplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'analysisConstituentNodalPhase', analysisConstituentNodalPhase)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'decomposedConstituentAmplitude', decomposedConstituentAmplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'decomposedConstituentPhase', decomposedConstituentPhase)
+
+ ! get relevant time information
+ time = daysSinceStartOfSim*86400_RKIND
+ current_time = mpas_get_clock_time(domain % clock, MPAS_NOW, err)
+ call mpas_set_time(harmonicAnalysisStart, dateTimeString=config_AM_harmonicAnalysis_start)
+ call mpas_set_time(harmonicAnalysisEnd, dateTimeString=config_AM_harmonicAnalysis_end)
+
+ ! exit if harmonic analysis period has not begun yet
+ if (current_time .lt. harmonicAnalysisStart) then
+ call mpas_log_write('harmonicAnalysisAM exit: before HA period')
+ return
+ end if
+
+ ! update if within harmonic analysis period
+ if (current_time .le. harmonicAnalysisEnd) then
+ CALL update_least_squares_LHS_matrix(nAnalysisConstituents, &
+ time, &
+ analysisConstituentFrequency, &
+ leastSquaresLHSMatrix)
+
+ CALL update_least_squares_RHS_vector(nAnalysisConstituents, &
+ time, &
+ nCellsSolve, &
+ analysisConstituentFrequency, &
+ ssh, &
+ leastSquaresRHSVector)
+ call mpas_log_write('harmonicAnalysisAM update')
+ end if
+
+ ! solve harmonic analysis least squares system if harmonic analysis period is over
+ if ((current_time .ge. harmonicAnalysisEnd) .and. (leastSquaresSolution == 0)) then
+ call harmonic_analysis_solve(nCellsSolve, &
+ nAnalysisConstituents, &
+ leastSquaresLHSMatrix, &
+ leastSquaresRHSVector, &
+ analysisConstituentNodalAmplitude, &
+ analysisConstituentNodalPhase, &
+ decomposedConstituentAmplitude, &
+ decomposedConstituentPhase)
+
+ ! copy amplitude and phase solutions into corresponding arrays
+ do iCon = 1,nAnalysisConstituents
+ if (constituentList(iCon)%constituent == 'M2') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'M2Amplitude', M2Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'M2Phase', M2Phase)
+ M2Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ M2Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'S2') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'S2Amplitude', S2Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'S2Phase', S2Phase)
+ S2Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ S2Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'N2') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'N2Amplitude', N2Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'N2Phase', N2Phase)
+ N2Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ N2Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'K2') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'K2Amplitude', K2Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'K2Phase', K2Phase)
+ K2Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ K2Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'K1') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'K1Amplitude', K1Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'K1Phase', K1Phase)
+ K1Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ K1Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'O1') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'O1Amplitude', O1Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'O1Phase', O1Phase)
+ O1Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ O1Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'Q1') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'Q1Amplitude', Q1Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'Q1Phase', Q1Phase)
+ Q1Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ Q1Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ if (constituentList(iCon)%constituent == 'P1') then
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'P1Amplitude', P1Amplitude)
+ call mpas_pool_get_array(harmonicAnalysisAMPool, 'P1Phase', P1Phase)
+ P1Amplitude(:) = decomposedConstituentAmplitude(iCon,:)
+ P1Phase(:) = decomposedConstituentPhase(iCon,:)
+ endif
+ enddo
+
+ ! increment to indicate the system has been solved
+ leastSquaresSolution = leastSquaresSolution + 1
+ call mpas_log_write('harmonicAnalysisAM solve')
+
+ else if ((current_time .ge. harmonicAnalysisEnd) .and. (leastSquaresSolution > 0)) then
+ call mpas_log_write('harmonicAnalysisAM exit: past HA period')
+ end if
+
+ block => block % next
+ end do
+
+ end subroutine ocn_compute_harmonic_analysis!}}}
+
+!***********************************************************************
+!
+! routine ocn_restart_harmonic_analysis
+!
+!> \brief Save restart for MPAS-Ocean analysis member
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> This routine conducts computation required to save a restart state
+!> for the MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_restart_harmonic_analysis(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_restart_harmonic_analysis!}}}
+
+!***********************************************************************
+!
+! routine ocn_finalize_harmonic_analysis
+!
+!> \brief Finalize MPAS-Ocean analysis member
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> This routine conducts all finalizations required for this
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_finalize_harmonic_analysis(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+
+ err = 0
+
+ end subroutine ocn_finalize_harmonic_analysis!}}}
+
+!***********************************************************************
+!
+! routine update_least_squares_LHS_matrix
+!
+!> \brief Update Left Hand Side Matrix
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> Adapted from the ADCIRC code by R.A. Luettich and J.J. Westerink
+!
+!-----------------------------------------------------------------------
+
+ SUBROUTINE update_least_squares_LHS_matrix(nfreq,TIMELOC,hafreq,ha) !{{{
+
+ IMPLICIT NONE
+
+ INTEGER, INTENT(IN) :: nfreq ! number of analysis constituents
+ REAL(kind=RKIND), INTENT(IN) :: TIMELOC ! model time (sec)
+ REAL(kind=RKIND), DIMENSION(:), INTENT(IN) :: hafreq ! analysis contituent frequencies
+ REAL(kind=RKIND), DIMENSION(:,:), INTENT(INOUT) :: ha ! LHS matrix
+
+ INTEGER :: I,J,I1,I2,J1,J2
+ REAL(kind=RKIND) :: TF1,TF2
+
+! Update the Left Hand Side Matrix
+! Note: this is a symmetric matrix and therefore only store the
+! upper triangular part. The lower part will be filled out in
+! subroutine least_squares_decompose() prior to decomposition
+
+ do i=1,nfreq
+ do j=i,nfreq
+ i1=2*i-1
+ i2=i1+1
+ j1=2*j-1
+ j2=j1+1
+ tf1=hafreq(i)*TIMELOC
+ tf2=hafreq(j)*TIMELOC
+ ha(i1,j1) = ha(i1,j1) + cos(tf1)*cos(tf2)
+ ha(i1,j2) = ha(i1,j2) + cos(tf1)*sin(tf2)
+ ha(i2,j2) = ha(i2,j2) + sin(tf1)*sin(tf2)
+ if(i2.le.j1) ha(i2,j1) = ha(i2,j1) + sin(tf1)*cos(tf2)
+ end do
+ end do
+
+ return
+ end subroutine update_least_squares_LHS_matrix!}}}
+
+!***********************************************************************
+!
+! routine update_least_squares_RHS_vector
+!
+!> \brief Update Right Hand Side Vector
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> Adapted from the ADCIRC code by R.A. Luettich and J.J. Westerink
+!
+!-----------------------------------------------------------------------
+
+ SUBROUTINE update_least_squares_RHS_vector(nfreq,TIMEUD,NP,hafreq,GLOE,GLOELV) !{{{
+
+ IMPLICIT NONE
+
+ INTEGER, INTENT(IN) :: nfreq ! number of analysis consituents
+ REAL(kind=RKIND), INTENT(IN) :: TIMEUD ! model time
+ INTEGER, INTENT(IN) :: NP ! number of mesh cells
+ REAL(kind=RKIND), DIMENSION(:), INTENT(IN) :: hafreq ! analysis constituent frequencies
+ REAL(kind=RKIND), DIMENSION(:), INTENT(IN) :: GLOE ! sea surface height
+ REAL(kind=RKIND), DIMENSION(:,:), INTENT(INOUT) :: GLOELV ! RHS vector
+
+ INTEGER I,N,I1,I2
+ REAL(kind=RKIND) TF1,CTF1,STF1
+
+! Update the Right Hand Side Load Vectors
+ do i=1,nfreq
+ i1=2*i-1
+ i2=i1+1
+ tf1=hafreq(i)*TIMEUD
+ ctf1 = cos(tf1)
+ stf1 = sin(tf1)
+ do n=1,np
+ GLOELV(I1,N)=GLOELV(I1,N)+GLOE(N)*CTF1
+ GLOELV(I2,N)=GLOELV(I2,N)+GLOE(N)*STF1
+ end do
+ end do
+
+ return
+ end subroutine update_least_squares_RHS_vector!}}}
+
+!***********************************************************************
+!
+! routine harmonic_analysis_solve
+!
+!> \brief Solve the least squares system
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> Adapted from the ADCIRC code by R.A. Luettich and J.J. Westerink
+!
+!-----------------------------------------------------------------------
+
+ SUBROUTINE harmonic_analysis_solve(MNP,nfreq,hmat,GLOELV,haff,haface,emagt,phaseden) !{{{
+
+ IMPLICIT NONE
+
+ integer, intent(in) :: MNP ! number of mesh cells
+ integer, intent(in) :: nfreq ! number of analysis constituents
+ real(kind=RKIND), dimension(:,:), intent(in) :: hmat ! LHS matrix
+ real(kind=RKIND), dimension(:,:), intent(in) :: GLOELV ! RHS vector
+ real(kind=RKIND), dimension(:), intent(in) :: haff ! amplitude nodal factors
+ real(kind=RKIND), dimension(:), intent(in) :: haface ! phase nodal factors
+ real(kind=RKIND), dimension(:,:), intent(out) :: emagt ! constituent amplitudes
+ real(kind=RKIND), dimension(:,:), intent(out) :: phaseden ! constituent phases
+
+ integer J,N,K,I,I1,I2,IT,IFR
+ integer mm
+ real(kind=RKIND) :: convrd
+ REAL(kind=RKIND),ALLOCATABLE :: PHASEE(:),EMAG(:)
+ REAL(kind=RKIND),ALLOCATABLE :: hap(:),hax(:)
+ REAL(kind=RKIND),ALLOCATABLE :: ha(:,:)
+
+ convrd=180.0_RKIND/pii
+
+ mm = 2*nfreq
+ ALLOCATE ( PHASEE(nfreq),EMAG(nfreq) )
+ ALLOCATE ( hap(mm), hax(mm) )
+ ALLOCATE ( ha(mm,mm) )
+
+! Copy LHS matrix and decompose
+ do i = 1,mm
+ do j = 1,mm
+ ha(j,i) = hmat(j,i)
+ end do
+ end do
+ call least_squares_decompose(nfreq,ha)
+
+ DO N=1,MNP
+
+! At each node transfer the RHS vector and solve
+ do k=1,mm
+ hap(k) = GLOELV(k,n)
+ end do
+ call least_squares_solve(nfreq,ha,hap,hax)
+
+! Compute amplitude and phase for each constituent making sure that the
+! phase is between 0 and 360 deg.
+ do i=1,nfreq
+ i1=2*i-1
+ i2=i1+1
+ emag(i)=sqrt(hax(i1)*hax(i1)+hax(i2)*hax(i2))
+ emagt(i,n)=emag(i)/haff(i)
+ if((hax(i1).eq.0.0_RKIND).and.(hax(i2).eq.0.0_RKIND)) then
+ phasee(i)=0.0_RKIND
+ else
+ phasee(i) = atan2(hax(i2),hax(i1))
+ endif
+ phaseden(i,n)=phasee(i)+haface(i)
+ phaseden(i,n)=convrd*phaseden(i,n)
+ if(phaseden(i,n).lt.0.0_RKIND) phaseden(i,n)=phaseden(i,n)+360.0_RKIND
+ if(phaseden(i,n).ge.360.0_RKIND) phaseden(i,n)=phaseden(i,n)-360.0_RKIND
+ end do
+
+ end do
+
+ return
+ end subroutine harmonic_analysis_solve !}}}
+
+
+!***********************************************************************
+!
+! routine least_squares_decompose
+!
+!> \brief Fill out symmetric matrix and decompose
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> Adapted from the ADCIRC code by R.A. Luettich and J.J. Westerink
+!
+!-----------------------------------------------------------------------
+
+ subroutine least_squares_decompose(nfreq,ha) !{{{
+
+ implicit none
+
+ integer, intent(in) :: nfreq ! number of analysis constituents
+ real(kind=RKIND), dimension(:,:), intent(inout) :: ha ! LHS matrix
+
+ integer i,j,ir,ire,k,jr,mm
+
+ mm = 2*nfreq
+
+! Set up the lower triangular part of the LHS matrix
+
+ do j=1,mm
+ do i=j,mm
+ ha(i,j)=ha(j,i)
+ end do
+ end do
+
+! Decomposition of matrix
+
+ do 100 ir=1,mm
+ ire=ir+1
+ do 20 j=ire,mm
+ 20 ha(ir,j)=ha(ir,j)/ha(ir,ir)
+ if (ire.gt.mm) goto 100
+ do 40 j=ire,mm
+ do 40 k=ire,mm
+ 40 ha(k,j)=ha(k,j)-ha(k,ir)*ha(ir,j)
+ do 50 j=ire,mm
+ 50 ha(j,ir)=0.0_RKIND
+ 100 continue
+
+
+ end subroutine least_squares_decompose !}}}
+
+!***********************************************************************
+!
+! routine least_squares_solve
+!
+!> \brief Solves system a*x=b by l*d*l(tr) decomp in full storage mode
+!> \author Steven Brus
+!> \date July 2020
+!> \details
+!> Adapted from the ADCIRC code by R.A. Luettich and J.J. Westerink
+!
+!-----------------------------------------------------------------------
+
+ subroutine least_squares_solve(nfreq,ha,hap,hax) !{{{
+
+ implicit none
+
+ integer, intent(in) :: nfreq ! number of analysis constituents
+ real(kind=RKIND), dimension(:,:), intent(in) :: ha ! LHS matrix
+ real(kind=RKIND), dimension(:), intent(in) :: hap ! RHS vector
+ real(kind=RKIND), dimension(:), intent(out) :: hax ! solution vector
+
+ integer idecom,i,j,ir,ire,k,jr,mm
+ real(kind=RKIND),allocatable :: c(:),y(:)
+
+ mm = 2*nfreq
+
+ allocate ( c(mm),y(mm) )
+
+! solve for y by forward substitution for l*y=p
+
+ do 120 ir=1,mm
+ y(ir)=hap(ir)
+ do 110 jr=1,ir-1
+ 110 y(ir)=y(ir)-ha(jr,ir)*y(jr)
+ 120 continue
+
+! calculate c=d**(-1)*y
+
+ do 130 ir=1,mm
+ 130 c(ir)=y(ir)/ha(ir,ir)
+
+! solve for x by back-substituting for l(tr)*x=c
+
+ ir=mm
+ 140 continue
+ hax(ir)=c(ir)
+ do 150 jr=ir+1,mm
+ 150 hax(ir)=hax(ir)-ha(ir,jr)*hax(jr)
+ ir=ir-1
+ if(ir.ge.1) goto 140
+
+ end subroutine least_squares_solve!}}}
+
+end module ocn_harmonic_analysis
+
+! vim: foldmethod=marker
diff --git a/src/core_ocean/analysis_members/mpas_ocn_sediment_flux_index.F b/src/core_ocean/analysis_members/mpas_ocn_sediment_flux_index.F
new file mode 100644
index 0000000000..777a6fc00d
--- /dev/null
+++ b/src/core_ocean/analysis_members/mpas_ocn_sediment_flux_index.F
@@ -0,0 +1,318 @@
+! Copyright (c) 2013, Los Alamos National Security, LLC (LANS)
+! and the University Corporation for Atmospheric Research (UCAR).
+!
+! Unless noted otherwise source code is licensed under the BSD license.
+! Additional copyright and license information can be found in the LICENSE file
+! distributed with this code, or at http://mpas-dev.github.com/license.html
+!
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+!
+! ocn_sediment_flux_index
+!
+!> \brief MPAS ocean analysis mode member: sediment_flux_index
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/02/26
+!> \details
+!> MPAS ocean analysis mode member: sediment_flux_index
+!>
+!-----------------------------------------------------------------------
+
+module ocn_sediment_flux_index
+
+ use mpas_derived_types
+ use mpas_pool_routines
+ use mpas_dmpar
+ use mpas_timekeeping
+ use mpas_stream_manager
+
+ use ocn_constants
+ use ocn_diagnostics_routines
+
+ implicit none
+ private
+ save
+
+ !--------------------------------------------------------------------
+ !
+ ! Public parameters
+ !
+ !--------------------------------------------------------------------
+
+ !--------------------------------------------------------------------
+ !
+ ! Public member functions
+ !
+ !--------------------------------------------------------------------
+
+ public :: ocn_init_sediment_flux_index, &
+ ocn_compute_sediment_flux_index, &
+ ocn_restart_sediment_flux_index, &
+ ocn_finalize_sediment_flux_index
+
+ !--------------------------------------------------------------------
+ !
+ ! Private module variables
+ !
+ !--------------------------------------------------------------------
+
+!***********************************************************************
+
+contains
+
+!***********************************************************************
+!
+! routine ocn_init_sediment_flux_index
+!
+!> \brief Initialize MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/02/26
+!> \details
+!> This routine conducts all initializations required for the
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_init_sediment_flux_index(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_init_sediment_flux_index!}}}
+
+!***********************************************************************
+!
+! routine ocn_compute_sediment_flux_index
+!
+!> \brief Compute MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/02/26
+!> \details
+!> This routine conducts all computation required for this
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_compute_sediment_flux_index(domain, timeLevel, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(in) :: timeLevel
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ type (mpas_pool_type), pointer :: sedimentFluxIndexAMPool
+ type (dm_info) :: dminfo
+ type (block_type), pointer :: block
+ type (mpas_pool_type), pointer :: statePool
+ type (mpas_pool_type), pointer :: meshPool
+ type (mpas_pool_type), pointer :: diagnosticsPool
+
+ real (kind=RKIND), dimension(:,:), pointer :: velX, velY, velZ
+ real (kind=RKIND), dimension(:), pointer :: posX, posY
+ real (kind=RKIND), dimension(:), pointer :: sfiVAx, sfiVAy, sfiBx, sfiBy
+ logical, pointer :: on_a_sphere, use_lat_lon_coords
+ integer, pointer :: nCells, nVertLevels, nCellsSolve
+ integer k, iCell, i
+ err = 0
+
+ dminfo = domain % dminfo
+
+ block => domain % blocklist
+ do while (associated(block))
+ ! get dimensions
+ call mpas_pool_get_dimension(block % dimensions, 'nCells', nCells)
+ call mpas_pool_get_dimension(block % dimensions, 'nCellsSolve', nCellsSolve)
+ call mpas_pool_get_dimension(block % dimensions, 'nVertLevels', nVertLevels)
+
+ ! get pointers to pools
+ call mpas_pool_get_subpool(block % structs, 'state', statePool)
+ call mpas_pool_get_subpool(block % structs, 'mesh', meshPool)
+ call mpas_pool_get_subpool(block % structs, 'diagnostics', diagnosticsPool)
+ call mpas_pool_get_subpool(block % structs, 'sedimentFluxIndexAM', sedimentFluxIndexAMPool)
+
+ call mpas_pool_get_config(meshPool, 'on_a_sphere', on_a_sphere)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentFluxIndex_use_lat_lon_coords', use_lat_lon_coords)
+
+ if (.not. on_a_sphere) then
+ use_lat_lon_coords = .false.
+ end if
+
+ if (use_lat_lon_coords) then
+ call mpas_pool_get_array(meshPool, 'lonCell', posX)
+ call mpas_pool_get_array(meshPool, 'latCell', posY)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityZonal', velX)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityMeridional', velY)
+ else
+ call mpas_pool_get_array(meshPool, 'xCell', posX)
+ call mpas_pool_get_array(meshPool, 'yCell', posY)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityX', velX)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityY', velY)
+ end if
+
+ call mpas_pool_get_array(sedimentFluxIndexAMPool, 'sedimentFluxIndexVAX', sfiVAx)
+ call mpas_pool_get_array(sedimentFluxIndexAMPool, 'sedimentFluxIndexVAY', sfiVAy)
+ call mpas_pool_get_array(sedimentFluxIndexAMPool, 'sedimentFluxIndexBX', sfiBx)
+ call mpas_pool_get_array(sedimentFluxIndexAMPool, 'sedimentFluxIndexBY', sfiBy)
+ ! Computations which are functions of nCells, nEdges, or nVertices
+ ! must be placed within this block loop
+ ! Here are some example loops
+ do iCell = 1,nCellsSolve
+ sfiVAx(iCell) = (sum(velX(:,iCell))/float(nVertLevels))**3.0_RKIND
+ sfiVAy(iCell) = (sum(velY(:,iCell))/float(nVertLevels))**3.0_RKIND
+ sfiBx(iCell) = velX(1,iCell)**3.0_RKIND
+ sfiBy(iCell) = velY(1,iCell)**3.0_RKIND
+ end do
+
+ block => block % next
+ end do
+
+ end subroutine ocn_compute_sediment_flux_index!}}}
+
+!***********************************************************************
+!
+! routine ocn_restart_sediment_flux_index
+!
+!> \brief Save restart for MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/02/26
+!> \details
+!> This routine conducts computation required to save a restart state
+!> for the MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_restart_sediment_flux_index(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_restart_sediment_flux_index!}}}
+
+!***********************************************************************
+!
+! routine ocn_finalize_sediment_flux_index
+!
+!> \brief Finalize MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/02/26
+!> \details
+!> This routine conducts all finalizations required for this
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_finalize_sediment_flux_index(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_finalize_sediment_flux_index!}}}
+
+end module ocn_sediment_flux_index
+
+! vim: foldmethod=marker
diff --git a/src/core_ocean/analysis_members/mpas_ocn_sediment_transport.F b/src/core_ocean/analysis_members/mpas_ocn_sediment_transport.F
new file mode 100644
index 0000000000..4804684380
--- /dev/null
+++ b/src/core_ocean/analysis_members/mpas_ocn_sediment_transport.F
@@ -0,0 +1,545 @@
+! Copyright (c) 2013, Los Alamos National Security, LLC (LANS)
+! and the University Corporation for Atmospheric Research (UCAR).
+!
+! Unless noted otherwise source code is licensed under the BSD license.
+! Additional copyright and license information can be found in the LICENSE file
+! distributed with this code, or at http://mpas-dev.github.com/license.html
+!
+!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+!
+! ocn_sediment_transport
+!
+!> \brief MPAS ocean analysis mode member: sediment_transport
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/03/07
+!> \details
+!> MPAS ocean analysis mode member: sediment_transport
+!-----------------------------------------------------------------------
+
+module ocn_sediment_transport
+
+ use mpas_derived_types
+ use mpas_pool_routines
+ use mpas_dmpar
+ use mpas_timekeeping
+ use mpas_stream_manager
+
+ use ocn_constants
+ use ocn_diagnostics_routines
+
+ implicit none
+ private
+ save
+
+ !--------------------------------------------------------------------
+ !
+ ! Public parameters
+ !
+ !--------------------------------------------------------------------
+
+ !--------------------------------------------------------------------
+ !
+ ! Public member functions
+ !
+ !--------------------------------------------------------------------
+
+ public :: ocn_init_sediment_transport, &
+ ocn_compute_sediment_transport, &
+ ocn_restart_sediment_transport, &
+ ocn_finalize_sediment_transport
+
+ !--------------------------------------------------------------------
+ !
+ ! Private module variables
+ !
+ !--------------------------------------------------------------------
+
+!***********************************************************************
+
+contains
+
+!***********************************************************************
+!
+! routine ocn_init_sediment_transport
+!
+!> \brief Initialize MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/03/07
+!> \details
+!> This routine conducts all initializations required for the
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_init_sediment_transport(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_init_sediment_transport!}}}
+
+!***********************************************************************
+!
+! routine ocn_compute_sediment_transport
+!
+!> \brief Compute MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/03/07
+!> \details
+!> This routine conducts all computation required for this
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_compute_sediment_transport(domain, timeLevel, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(in) :: timeLevel
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ type (mpas_pool_type), pointer :: sedimentTransportAMPool
+ type (dm_info) :: dminfo
+ type (block_type), pointer :: block
+ type (mpas_pool_type), pointer :: statePool
+ type (mpas_pool_type), pointer :: meshPool
+ type (mpas_pool_type), pointer :: diagnosticsPool
+
+ real (kind=RKIND), pointer :: salpha, SD50, rho0, rhoS, Vh, Dv,Ws
+ real (kind=RKIND), pointer :: tau_ce, Erate, poro, tau_cd, Cd, Manning
+ real (kind=RKIND), dimension(:,:), pointer :: velX, velY, velZ
+ real (kind=RKIND), dimension(:), pointer :: posX, posY, bottomDepth, ssh
+ real (kind=RKIND), dimension(:), pointer :: sedFluxVAx, sedFluxVAy, sedFluxBx, sedFluxBy
+ real (kind=RKIND), dimension(:), pointer :: ero_flux, dep_flux
+ real (kind=RKIND), dimension(:), pointer :: bedld_x, bedld_y
+ real (kind=RKIND), dimension(:), pointer :: SSC_ref
+ real (kind=RKIND), dimension(:,:), pointer :: SSC
+ real (kind=RKIND), dimension(:,:), pointer :: zMid
+
+ logical, pointer :: on_a_sphere, use_lat_lon_coords
+ logical, pointer :: bedload, suspended
+ integer, pointer :: nCells, nVertLevels, nCellsSolve
+ character (len=StrKIND), pointer :: ws_formula, bedld_formula
+ character (len=StrKIND), pointer :: SSC_ref_formula
+
+ integer k, iCell, i
+ real ratio1, rho_R, ND50, Umag, Umagb, dstar, Chezy, Usf, RouseN
+ real cff1, cff2, cff3, cff4, cff5
+ real phicw, w_asym !! parameters related to waves, assigned ZEROs for just now
+ real tau_tide, tau_wave, tau_mean, theta_mean, theta_wave, theta_ce,theta_sf,za
+ real velXb, velYb, velXm, velYm
+ real phi_x1, phi_x2, phi_x, phi_y
+ real, parameter :: g = 9.81_RKIND
+ real, parameter :: eps = 1.0E-14_RKIND
+ real zCell
+ err = 0
+
+ dminfo = domain % dminfo
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_alpha',salpha)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_grain_size',SD50)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_drag_coefficient',Cd)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_grain_porosity',poro)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_erate',Erate)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_tau_ce',tau_ce)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_tau_cd',tau_cd)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_Manning_coef',Manning)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_water_density',rho0)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_grain_density',rhoS)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_kinematic_viscosity',Vh)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_vertical_diffusion_coefficient',Dv)
+
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_use_lat_lon_coords', use_lat_lon_coords)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_bedload', bedload)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_suspended', suspended)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_ws_formula', ws_formula)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_bedld_formula', bedld_formula)
+ call mpas_pool_get_config(ocnConfigs, 'config_AM_sedimentTransport_SSC_ref_formula', SSC_ref_formula)
+
+
+ block => domain % blocklist
+ do while (associated(block))
+ ! get dimensions
+ call mpas_pool_get_dimension(block % dimensions, 'nCells', nCells)
+ call mpas_pool_get_dimension(block % dimensions, 'nCellsSolve', nCellsSolve)
+ call mpas_pool_get_dimension(block % dimensions, 'nVertLevels', nVertLevels)
+
+ ! get pointers to pools
+ call mpas_pool_get_subpool(block % structs, 'state', statePool)
+ call mpas_pool_get_subpool(block % structs, 'mesh', meshPool)
+ call mpas_pool_get_subpool(block % structs, 'diagnostics', diagnosticsPool)
+ call mpas_pool_get_subpool(block % structs, 'sedimentTransportAM', sedimentTransportAMPool)
+
+ call mpas_pool_get_array(diagnosticsPool, 'zMid', zMid)
+ call mpas_pool_get_array(statePool, 'ssh', ssh, 1)
+ call mpas_pool_get_array(meshPool, 'bottomDepth', bottomDepth)
+ call mpas_pool_get_config(meshPool, 'on_a_sphere', on_a_sphere)
+ if (.not. on_a_sphere) then
+ use_lat_lon_coords = .false.
+ end if
+
+ if (use_lat_lon_coords) then
+ call mpas_pool_get_array(meshPool, 'lonCell', posX)
+ call mpas_pool_get_array(meshPool, 'latCell', posY)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityZonal', velX)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityMeridional', velY)
+ else
+ call mpas_pool_get_array(meshPool, 'xCell', posX)
+ call mpas_pool_get_array(meshPool, 'yCell', posY)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityX', velX)
+ call mpas_pool_get_array(diagnosticsPool, 'velocityY', velY)
+ end if
+
+
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentFallVelocity', Ws)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentErosionFlux', ero_flux)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentDepositionFlux', dep_flux)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentFluxVAX', sedFluxVAx)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentFluxVAY', sedFluxVAy)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentFluxBX', sedFluxBx)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentFluxBY', sedFluxBy)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentBedloadX', bedld_x)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentBedloadY', bedld_y)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentBottomReferenceConcentration', SSC_ref)
+ call mpas_pool_get_array(sedimentTransportAMPool, 'sedimentConcentration', SSC)
+
+!======> COMPUTE SedimentFallVelocity [m/s]
+ ! sieve diameter (SD50) to nominal diameter (ND50), Raudkivi [1990]
+ ND50 = SD50*1.1_RKIND
+ ! sediment/water density comparsion -> specific graivity
+ rho_R = rhoS/rho0-1
+ if (ws_formula == 'Goldstein-Coco2013') then
+ !Goldstein & Coco [2013]
+ Ws = (37.8_RKIND*ND50*rho_R*(1+100.0_RKIND*ND50))/ &
+ (0.383_RKIND+1E4*rho_R*Vh+1E2*ND50*rho_R**2)
+ elseif (ws_formula == 'Cheng1997') then
+ dstar = SD50* (rho_R*g/Vh**2.0_RKIND)**0.333_RKIND
+ Ws = Vh/SD50*(sqrt(25.0_RKIND+1.2_RKIND*dstar**2)-5.0_RKIND)**1.5_RKIND
+ elseif (ws_formula == 'VanRijn1993') then
+ if (SD50<1.0E-4) then
+ Ws = rho_R*g*SD50**2.0_RKIND/(18.0_RKIND*Vh)
+ elseif (SD50>1.0E-3) then
+ Ws = 1.1_RKIND*sqrt(rho_R*g*SD50)
+ else
+ Ws = 10.0_RKIND*Vh/SD50 *(sqrt(1.0_RKIND+0.01_RKIND*rho_R*g*SD50**3.0_RKIND/Vh**2.0_RKIND)-1)
+ end if
+ elseif (ws_formula == 'Soulsby1997') then
+ Ws = 10.36_RKIND*Vh/SD50 * (sqrt(1.0_RKIND+0.156_RKIND*rho_R*g*SD50**3.0_RKIND/(16.0_RKIND*Vh**2.0))-1)
+ else
+ print*,'please select the ws_formula from one of the following:'
+ print*, 'VanRijn1993, Soulsby1997, Cheng1997, Goldstein-Coco2013'
+ print*, 'Model will stop ...'
+ exit
+ end if
+!<======
+
+!======> COMPUTE SedimentTransportFlux [kg/m/s]
+ ! compute ratio1 in sedFlux = ratio1*U^3, Grawe et al. [2014]
+ ratio1 = salpha*Dv/Ws**2
+
+ do iCell = 1,nCellsSolve
+ velXm = sum(velX(:,iCell))/float(nVertLevels)
+ velYm = sum(velY(:,iCell))/float(nVertLevels)
+ velXb = velX(size(velX,1),iCell)
+ velYb = velY(size(velY,1),iCell)
+
+ sedFluxVAx(iCell) = ratio1*velXm**3.0_RKIND
+ sedFluxVAy(iCell) = ratio1*velYm**3.0_RKIND
+ sedFluxBx(iCell) = ratio1*velXb**3.0_RKIND
+ sedFluxBy(iCell) = ratio1*velYb**3.0_RKIND
+ end do
+!<======
+
+ cff1 = rho_R*g*SD50+eps
+ cff2 = sqrt(rho_R*g*SD50)*SD50*rhoS
+ !wave-related parameters
+ w_asym = 0.0_RKIND
+ phicw = 0.0_RKIND
+
+ do iCell = 1,nCellsSolve
+ velXm = sum(velX(:,iCell))/float(nVertLevels)
+ velYm = sum(velY(:,iCell))/float(nVertLevels)
+ velXb = velX(size(velX,1),iCell)
+ velYb = velY(size(velY,1),iCell)
+ Umag = sqrt(velXm**2.0_RKIND + velYm**2.0_RKIND)
+ Umagb = sqrt(velXb**2.0_RKIND + velYb**2.0_RKIND)
+
+ ! compute bottom friction Cd = [von_Karmann/(1+log(z0/h))]^2, von_karmann=0.4, z0=SD50/12, h=bottomDepth+ssh
+ cff3 = SD50/12.0_RKIND
+ cff4 = 1+log(cff3/(eps+ssh(iCell)+bottomDepth(iCell)))
+ Cd = (0.4_RKIND/cff4)**2.0_RKIND
+ ! compute shear velocity, tau= rho0*Cd*Umag**2 = rho0*Usf**2 => Usf=sqrt(Cd)*Umag
+ Usf = Umag * sqrt(Cd)
+ ! compute Rouse number, RouseN=Ws/(von_karmann*Usf)
+ RouseN = Ws/(0.4_RKIND*(Usf+eps))
+!! Rouse number (suspension parameter) indicates the balance between sediment suspension and settling. According to the
+!! equation of it, when Ws>Usf, which also means RouseN>2.5, there should be no sediment in suspension. To avoid the
+!! "Float-point exception" error when Usf is very small and RouseN is super huge, we mannually set a maximum value of
+!! 25 for RouseN, which is 10 times bigger than RouseN with ideally no suspended sediment.
+ RouseN = min(RouseN, 25.0_RKIND)
+
+ ! compute shear stress [m^2 s^{-2}]
+ tau_tide = Cd*Umagb**2.0_RKIND
+ tau_wave = 0.0_RKIND
+ tau_mean = tau_tide*(1.0_RKIND+1.2_RKIND*(tau_wave/(tau_wave+tau_tide+eps))**1.5_RKIND)
+
+!======> COMPUTE Suspended Transport [] <--- to be continued
+ if (suspended) then
+ ! surface erosion mass flux ero_flux in unit (kg m-2 s-1)
+ ero_flux(iCell) = (1.0_RKIND-poro)*Erate*MAX(tau_mean/tau_ce -1.0_RKIND, 0.0_RKIND)
+ end if
+!<======
+
+!======> COMPUTE SSC_ref: near-bottom suspended sediment concentration (reference concentration) [kg/m3]
+ ! Three equations:
+ ! 1) Lee2004,JGR; 2) Goldstein2014,Earth Surface Dynamics; 3) Zyserman-Fredsoe1994, J. Hydraul. Eng.
+ if (SSC_ref_formula == 'Lee2004') then
+ theta_sf = Usf**2.0_RKIND/cff1
+ SSC_ref(iCell) = 2.58_RKIND*(theta_sf*Usf/Ws)**1.45_RKIND
+ elseif (SSC_ref_formula == 'Goldstein2014') then
+ SSC_ref(iCell) = (0.328_RKIND*Umagb/(0.0688_RKIND+1E3*SD50))**2_RKIND
+ elseif (SSC_ref_formula == 'Zyserman-Fredsoe1994') then
+ theta_sf = tau_mean/cff1
+ theta_sf = max(theta_sf, 0.045_RKIND)
+ cff3 = 0.331_RKIND*(theta_sf-0.045_RKIND)**1.75_RKIND
+ cff4 = 1.0_RKIND+0.72_RKIND*(theta_sf-0.045_RKIND)**1.75_RKIND
+ SSC_ref(iCell) = cff3/cff4
+ else
+ print*, 'Please pick one SSC_ref_formula from the following three:'
+ print*, 'Lee2004, Goldstein2014,Zyserman-Fredsoe1994'
+ print*, 'Model will stop ...'
+ exit
+ endif
+!<======
+
+!======> Compute SSC based on the Rouse Profile
+ ! SSC(z) = SSC_ref*[z/za * (h-za)/(h-z)]**(-b), where b is the Rouse number (or suspension parameter)
+ ! b = Ws/(von_karmann*usf); za is reference height (0.01m), h is bottomDepth
+ ! zMid in MPAS-O is the distance under free surface and is negative most of the time
+ ! In the above equation, z means the depth above the bottom, so z=h+zMid --> h-z = -zMid
+!! Since the reference concentration is the largest SSC at height za above bed, we need make sure h+zMid>=za
+!! that is to say zMid = max(zMid,za-h)
+ za = 0.01_RKIND
+ if (SSC_ref_formula == 'Zyserman-Fredsoe1994') za=2.0_RKIND*SD50
+ do k=1,nVertLevels
+ zMid(k,iCell) = max(za-bottomDepth(iCell), zMid(k,iCell)) ! make sure -zMid>=za
+ zCell = bottomDepth(iCell)+zMid(k,iCell)+eps
+ cff3 = za/(bottomDepth(iCell)-za+eps)
+ if (zCell/bottomDepth(iCell) .lt. 0.5_RKIND) then
+ cff4 = -zMid(k,iCell)/zCell*cff3
+ SSC(k,iCell) = SSC_ref(iCell)*cff4**RouseN
+ else
+ cff4 = exp(-4.0_RKIND*RouseN*(zCell/bottomDepth(iCell)-0.5_RKIND))
+ SSC(k,iCell) = SSC_ref(iCell)*cff4*cff3**RouseN
+ endif
+ enddo !! k loop
+!<======
+
+!======> COMPUTE Bedload Transport [kg/m/s], using one of the three formulae define in bedld_formula
+ if (bedload) then
+ theta_mean = tau_mean/cff1
+ theta_wave = tau_wave/cff1
+ theta_ce = tau_ce/cff1
+
+ if (bedld_formula == 'Soulsby-Damgaard')then
+ cff3 = 0.5*(1.0_RKIND+SIGN(1.0_RKIND,theta_mean/theta_ce-1.0_RKIND))
+
+ phi_x1 = 12.0_RKIND*sqrt(theta_mean)*MAX(theta_mean-theta_ce,0.0_RKIND)
+ phi_x2 = 12.0_RKIND*(0.9534_RKIND+0.1907_RKIND*COS(2.0_RKIND*phicw))* &
+ sqrt(theta_wave)*theta_mean + &
+ 12.0_RKIND*(0.229_RKIND*w_asym*theta_wave**1.5_RKIND*COS(phicw))
+
+ if (ABS(phi_x2) .gt. phi_x1) then
+ phi_x = phi_x2
+ else
+ phi_x = phi_x1
+ end if
+
+ bedld_x(iCell) = phi_x*cff2*cff3
+
+ phi_y = 12.0_RKIND*0.1907_RKIND*theta_wave**2* &
+ (theta_mean*SIN(2.0_RKIND*phicw)+1.2_RKIND*w_asym*theta_wave*SIN(phicw)) &
+ /(theta_wave**1.5_RKIND + 1.5_RKIND*theta_mean**1.5_RKIND+eps)
+ bedld_y = phi_y*cff2*cff3
+
+ elseif (bedld_formula == 'Meyer-Peter-Meuller') then
+ cff3 = 1.0_RKIND/sqrt(velXb**4.0_RKIND+velYb**4.0_RKIND+eps)
+ phi_x = max(8.0_RKIND*(theta_mean-0.047_RKIND), 0.0_RKIND)*velXb**2.0_RKIND
+ phi_y = max(8.0_RKIND*(theta_mean-0.047_RKIND), 0.0_RKIND)*velYb**2.0_RKIND
+
+ bedld_x(iCell) = phi_x*cff2*cff3
+ bedld_y(iCell) = phi_y*cff2*cff3
+
+ elseif (bedld_formula == 'Engelund-Hansen') then
+ ! Chezy = 1/Manning * water_depth^(1/6) with unit [m^0.5 s^(-1)]
+ ! In ocean water, Manning coeffcient varies between [0.012 0.025],see P.C. Kerr et al, 2013 JGR-Ocean
+ Chezy = 1.0_RKIND/Manning*abs(ssh(iCell)+bottomDepth(iCell))**(1.0_RKIND/6.0_RKIND)
+ Chezy = max(20.0_RKIND, Chezy)
+ Chezy = min(100.0_RKIND, Chezy)
+ cff4 = 0.05_RKIND*Umag**4.0_RKIND*rhoS
+ cff5 = sqrt(g)*Chezy**3.0_RKIND*rho_R**2.0_RKIND*SD50
+ bedld_x(iCell) = cff4/cff5*velXb
+ bedld_y(iCell) = cff4/cff5*velYb
+ else
+ print*, 'pick one bedld_formula from the following three:'
+ print*, 'Soulsby-Damgaard, Meyer-Peter-Meuller, Engelund-Hansen'
+ print*, 'Model will stop ...'
+ exit
+ end if
+ end if
+
+ end do !! iCell loop
+
+ block => block % next
+ end do !! do while (associated(block)) loop
+
+ end subroutine ocn_compute_sediment_transport!}}}
+
+!***********************************************************************
+!
+! routine ocn_restart_sediment_transport
+!
+!> \brief Save restart for MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/03/07
+!> \details
+!> This routine conducts computation required to save a restart state
+!> for the MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_restart_sediment_transport(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_restart_sediment_transport!}}}
+
+!***********************************************************************
+!
+! routine ocn_finalize_sediment_transport
+!
+!> \brief Finalize MPAS-Ocean analysis member
+!> \author Zhendong Cao and Phillip J. Wolfram
+!> \date 2019/03/07
+!> \details
+!> This routine conducts all finalizations required for this
+!> MPAS-Ocean analysis member.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_finalize_sediment_transport(domain, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ type (domain_type), intent(inout) :: domain
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ err = 0
+
+ end subroutine ocn_finalize_sediment_transport!}}}
+
+end module ocn_sediment_transport
+
+! vim: foldmethod=marker
diff --git a/src/core_ocean/driver/mpas_ocn_core_interface.F b/src/core_ocean/driver/mpas_ocn_core_interface.F
index aeae86825d..dab9fe154a 100644
--- a/src/core_ocean/driver/mpas_ocn_core_interface.F
+++ b/src/core_ocean/driver/mpas_ocn_core_interface.F
@@ -113,6 +113,7 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{
logical, pointer :: thicknessFilterActive
logical, pointer :: splitTimeIntegratorActive
logical, pointer :: windStressBulkPKGActive
+ logical, pointer :: variableBottomDragPKGActive
logical, pointer :: tracerBudgetActive
logical, pointer :: landIcePressurePKGActive
logical, pointer :: landIceFluxesPKGActive
@@ -121,6 +122,7 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{
logical, pointer :: frazilIceActive
logical, pointer :: tidalForcingActive
logical, pointer :: tidalPotentialForcingPKGActive
+ logical, pointer :: vegetationDragPKGActive
logical, pointer :: inSituEOSActive
logical, pointer :: variableShortwaveActive
logical, pointer :: gmActive
@@ -152,6 +154,7 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{
logical, pointer :: config_use_tidal_potential_forcing
logical, pointer :: config_use_GM
logical, pointer :: config_use_Redi
+ logical, pointer :: config_use_vegetation_drag
logical, pointer :: config_use_time_varying_atmospheric_forcing
logical, pointer :: config_use_time_varying_land_ice_forcing
@@ -160,6 +163,7 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{
character (len=StrKIND), pointer :: config_pressure_gradient_type
character (len=StrKIND), pointer :: config_sw_absorption_type
+ logical, pointer :: config_use_variable_drag
logical, pointer :: config_use_bulk_wind_stress
logical, pointer :: config_use_bulk_thickness_flux
logical, pointer :: config_compute_active_tracer_budgets
@@ -231,6 +235,14 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{
windStressBulkPKGActive = .true.
end if
+ !
+ ! test for variable bottom drag of momentum, variableBottomDragPKG
+ call mpas_pool_get_package(packagePool, 'variableBottomDragPKGActive', variableBottomDragPKGActive)
+ call mpas_pool_get_config(configPool, 'config_use_variable_drag', config_use_variable_drag)
+ if ( config_use_variable_drag ) then
+ variableBottomDragPKGActive = .true.
+ end if
+
!
! test for tracer budget
!
@@ -297,6 +309,15 @@ function ocn_setup_packages(configPool, packagePool, iocontext) result(ierr)!{{{
tidalPotentialForcingPKGActive = .true.
end if
+ !
+ ! test for use of vegetation drag, vegetationDragPKGActive
+ !
+ call mpas_pool_get_package(packagePool, 'vegetationDragPKGActive', vegetationDragPKGActive)
+ call mpas_pool_get_config(configPool, 'config_use_vegetation_drag', config_use_vegetation_drag)
+ if (config_use_vegetation_drag) then
+ vegetationDragPKGActive = .true.
+ end if
+
!
! test for use of gm
!
diff --git a/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F b/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F
index d4c49a5fd2..0daa9a3cf1 100644
--- a/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F
+++ b/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F
@@ -56,7 +56,7 @@ module ocn_forward_mode
use ocn_surface_land_ice_fluxes
use ocn_frazil_forcing
use ocn_tidal_forcing
- use ocn_tidal_potential_forcing
+ use ocn_vel_tidal_potential
use ocn_tracer_hmix
use ocn_tracer_hmix_redi
@@ -210,7 +210,7 @@ function ocn_forward_mode_init(domain, startTimeStamp) result(ierr)!{{{
ierr = ior(ierr, err_tmp)
call ocn_tidal_forcing_init(err_tmp)
ierr = ior(ierr, err_tmp)
- call ocn_tidal_potential_forcing_init(domain,err_tmp)
+ call ocn_vel_tidal_potential_init(domain,err_tmp)
ierr = ior(ierr, err_tmp)
call ocn_tracer_hmix_init(err_tmp)
diff --git a/src/core_ocean/mode_init/Registry_hurricane.xml b/src/core_ocean/mode_init/Registry_hurricane.xml
index 59c4ec54ae..a024826d1b 100644
--- a/src/core_ocean/mode_init/Registry_hurricane.xml
+++ b/src/core_ocean/mode_init/Registry_hurricane.xml
@@ -39,4 +39,24 @@
description="Amplitude of sea level rise."
possible_values="Any real number."
/>
+
+
+
+
+
diff --git a/src/core_ocean/mode_init/Registry_tidal_boundary.xml b/src/core_ocean/mode_init/Registry_tidal_boundary.xml
index 5e2134cb7b..f1aacb6613 100644
--- a/src/core_ocean/mode_init/Registry_tidal_boundary.xml
+++ b/src/core_ocean/mode_init/Registry_tidal_boundary.xml
@@ -51,4 +51,60 @@
description="Fraction of the domain the plug should take up initially. Only in the y direction."
possible_values="Any real number between 0 and 1."
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core_ocean/mode_init/mpas_ocn_init_hurricane.F b/src/core_ocean/mode_init/mpas_ocn_init_hurricane.F
index 29867aa54c..8b265c69f1 100644
--- a/src/core_ocean/mode_init/mpas_ocn_init_hurricane.F
+++ b/src/core_ocean/mode_init/mpas_ocn_init_hurricane.F
@@ -83,6 +83,7 @@ subroutine ocn_init_setup_hurricane(domain, iErr)!{{{
type (block_type), pointer :: block_ptr
type (mpas_pool_type), pointer :: meshPool
+ type (mpas_pool_type), pointer :: forcingPool
type (mpas_pool_type), pointer :: statePool
type (mpas_pool_type), pointer :: tracersPool
type (mpas_pool_type), pointer :: verticalMeshPool
@@ -104,6 +105,7 @@ subroutine ocn_init_setup_hurricane(domain, iErr)!{{{
logical, pointer :: on_a_sphere
integer, dimension(:), pointer :: maxLevelCell
real (kind=RKIND), dimension(:), pointer :: ssh
+ real (kind=RKIND), dimension(:), pointer :: bottomDrag
real (kind=RKIND), dimension(:), pointer :: refBottomDepth, refZMid, &
vertCoordMovementWeights, bottomDepth, bottomDepthObserved, &
fCell, fEdge, fVertex, &
@@ -180,6 +182,7 @@ subroutine ocn_init_setup_hurricane(domain, iErr)!{{{
do while(associated(block_ptr))
call mpas_pool_get_subpool(block_ptr % structs, 'mesh', meshPool)
call mpas_pool_get_subpool(block_ptr % structs, 'state', statePool)
+ call mpas_pool_get_subpool(block_ptr % structs, 'forcing', forcingPool)
call mpas_pool_get_subpool(block_ptr % structs, 'verticalMesh', verticalMeshPool)
call mpas_pool_get_subpool(block_ptr % structs, 'diagnostics', diagnosticsPool)
call mpas_pool_get_subpool(statePool, 'tracers', tracersPool)
@@ -275,16 +278,8 @@ subroutine ocn_init_setup_hurricane(domain, iErr)!{{{
end if
end do
- ! shift coordinates to accomodate wetting and drying
- do k = 1, nVertLevels
- refBottomDepth(k) = refBottomDepth(k) - globalMinBottomDepth
- end do
-
do iCell = 1, nCellsSolve
- bottomDepth(iCell) = bottomDepth(iCell) - globalMinBottomDepth
- ssh(iCell) = ssh(iCell) + globalMinBottomDepth
-
! make sure depth is thick enough via ssh = TOTAL_DEPTH - bottomDepth
ssh(iCell) = - bottomDepth(iCell) + &
max(ssh(iCell) + bottomDepth(iCell), &
@@ -363,6 +358,24 @@ subroutine ocn_init_setup_hurricane(domain, iErr)!{{{
fVertex(iVertex) = 2.0_RKIND * omega * sin(latVertex(iVertex))
end do
+ ! Set depth-variable drag
+ if (config_use_variable_drag) then
+ call mpas_pool_get_array(forcingPool, 'bottomDrag', bottomDrag)
+ do iCell = 1, nCellsSolve
+ if (bottomDepth(iCell) <= config_hurricane_land_z_limit) then
+ bottomDrag(iCell) = config_hurricane_land_drag
+ else if (config_hurricane_land_z_limit < bottomDepth(iCell) .and. bottomDepth(iCell) < config_hurricane_marsh_z_limit) then
+ bottomDrag(iCell) = config_hurricane_marsh_drag
+ else if (config_hurricane_marsh_z_limit <= bottomDepth(iCell)) then
+ bottomDrag(iCell) = config_hurricane_channel_drag
+ else
+ call mpas_log_write('Default value for drag is not selected' &
+ // ' properly for bottomDepth of $r in cell $i!', &
+ realArgs=(/bottomDepth(iCell)/), intArgs=(/iCell/))
+ end if
+ end do
+ end if
+
block_ptr => block_ptr % next
end do
diff --git a/src/core_ocean/mode_init/mpas_ocn_init_tidal_boundary.F b/src/core_ocean/mode_init/mpas_ocn_init_tidal_boundary.F
index 15f81a80f6..9cd0016b2d 100644
--- a/src/core_ocean/mode_init/mpas_ocn_init_tidal_boundary.F
+++ b/src/core_ocean/mode_init/mpas_ocn_init_tidal_boundary.F
@@ -93,7 +93,7 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
type (mpas_pool_type), pointer :: verticalMeshPool
type (mpas_pool_type), pointer :: tracersPool
- integer :: iCell, k
+ integer :: iCell, k, N
! Define dimensions
integer, pointer :: nCellsSolve, nEdgesSolve, nVertLevels, nVertLevelsP1
@@ -101,14 +101,17 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
! Define arrays
integer, dimension(:), pointer :: maxLevelCell
+ integer, dimension(:), pointer :: vegetationMask
+ real (kind=RKIND), dimension(:), pointer :: vegetationHeight,vegetationDensity, vegetationDiameter
real (kind=RKIND), dimension(:), pointer :: yCell, refBottomDepth, bottomDepth, vertCoordMovementWeights, dcEdge
real (kind=RKIND), dimension(:), pointer :: tidalInputMask
+ real (kind=RKIND), dimension(:), pointer :: bottomDrag
real (kind=RKIND), dimension(:), pointer :: ssh
real (kind=RKIND), dimension(:,:), pointer :: layerThickness, restingThickness, zMid
real (kind=RKIND), dimension(:,:,:), pointer :: activeTracers, debugTracers
-
real (kind=RKIND), dimension(:), pointer :: interfaceLocations
real (kind=RKIND), parameter :: eps=1.0e-12
+ real (kind=RKIND) :: cff1,cff2,cff3, dep_mark1, dep_mark2 ! intermediate variables
iErr = 0
@@ -190,9 +193,19 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
end if
! Set refBottomDepth, bottomDepth, and maxLevelCell
- do k = 1, nVertLevels
- refBottomDepth(k) = config_tidal_boundary_right_bottom_depth * interfaceLocations(k+1)
- end do
+ if (min(config_tidal_boundary_left_bottom_depth, config_tidal_boundary_right_bottom_depth) < 0.0_RKIND) then
+ ! consider the case where there is wetting / drying and vertical mesh resolution is needed "on land"
+ do k = 1, nVertLevels
+ refBottomDepth(k) = config_tidal_boundary_left_bottom_depth + &
+ (config_tidal_boundary_right_bottom_depth - config_tidal_boundary_left_bottom_depth)* interfaceLocations(k+1)
+ end do
+ else
+ ! assumes we just need to build vertical mesh to deepest point (e.g., no "on land' vertical mesh)
+ do k = 1, nVertLevels
+ refBottomDepth(k) = \
+ max(config_tidal_boundary_left_bottom_depth, config_tidal_boundary_right_bottom_depth) * interfaceLocations(k+1)
+ end do
+ end if
if (config_tidal_boundary_use_distances) then
yMin = config_tidal_boundary_left_value
@@ -205,6 +218,78 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
(config_tidal_boundary_right_bottom_depth - config_tidal_boundary_left_bottom_depth)
end do
+ if (config_use_variable_drag) then
+ call mpas_pool_get_array(forcingPool, 'bottomDrag', bottomDrag)
+ do iCell = 1, nCellsSolve
+ bottomDrag(iCell) = config_tidal_forcing_left_Cd_or_n &
+ + (yCell(iCell) - yMin) / (yMax - yMin) * &
+ (config_tidal_forcing_right_Cd_or_n - config_tidal_forcing_left_Cd_or_n)
+ end do
+ end if
+
+ if (config_use_vegetation_drag) then
+ call mpas_pool_get_array(forcingPool, 'vegetationMask', vegetationMask)
+ vegetationMask = 0
+ call mpas_pool_get_array(forcingPool, 'vegetationDiameter', vegetationDiameter)
+ vegetationDiameter = config_idealized_vegetation_diameter
+ call mpas_pool_get_array(forcingPool, 'vegetationHeight', vegetationHeight)
+ vegetationHeight = config_idealized_vegetation_height
+ call mpas_pool_get_array(forcingPool, 'vegetationDensity', vegetationDensity)
+ vegetationDensity = config_idealized_vegetation_density
+ endif
+
+ if (config_use_idealized_transect) then
+ call mpas_pool_get_array(forcingPool, 'bottomDrag', bottomDrag)
+ config_idealized_transect_Lmarsh = 1.0_RKIND - config_idealized_transect_Lcoast &
+ - config_idealized_transect_Lshore
+ if (config_idealized_transect_Lmarsh .lt. 0.0_RKIND) then
+ call mpas_log_write("Lshore+Lcoast cannot be bigger than 1.0")
+ iErr = 1
+ endif
+ cff1 = yMax*config_idealized_transect_Lcoast
+ cff2 = yMax*config_idealized_transect_Lmarsh
+ cff3 = yMax*config_idealized_transect_Lshore
+ ! by defining the slopes and left_bottom_depth, the pre-defined right_bottom_depth won't work.
+ ! Need redefine it.
+ config_tidal_boundary_right_bottom_depth = config_tidal_boundary_left_bottom_depth + &
+ cff1*config_idealized_transect_Scoast + &
+ cff2*config_idealized_transect_Smarsh + &
+ cff3*config_idealized_transect_Sshore
+ do iCell = 1, nCellsSolve
+ if (yCell(iCell) .lt. cff1) then
+ bottomDepth(iCell) = config_tidal_boundary_left_bottom_depth &
+ + (yCell(iCell)-yMin)*config_idealized_transect_Scoast
+ dep_mark1 = bottomDepth(iCell)
+ bottomDrag(iCell) = config_idealized_transect_roughness
+ elseif (yCell(iCell) .lt. (cff1+cff2)) then
+ bottomDepth(iCell) = dep_mark1 + (yCell(iCell)-cff1)*config_idealized_transect_Smarsh
+ dep_mark2 = bottomDepth(iCell)
+ bottomDrag(iCell) = config_idealized_transect_roughness_marsh
+ if (config_use_vegetation_drag) vegetationMask(iCell) = 1
+ else
+ if (cff2 .eq. 0.0_RKIND) dep_mark2 = dep_mark1
+ bottomDepth(iCell) = dep_mark2 + (yCell(iCell)-cff1-cff2)*config_idealized_transect_Sshore
+ bottomDrag(iCell) = config_idealized_transect_roughness
+ endif
+ end do !! do iCell
+ else
+ ! if not config_idealized_transect, assign a constant slope
+ do iCell = 1, nCellsSolve
+ bottomDepth(iCell) = config_tidal_boundary_left_bottom_depth &
+ + (yCell(iCell) - yMin) / (yMax - yMin) * &
+ (config_tidal_boundary_right_bottom_depth - config_tidal_boundary_left_bottom_depth)
+ end do
+ end if !! if config_idealized_transect
+
+ if (config_tidal_boundary_right_bottom_depth < config_tidal_boundary_left_bottom_depth) then
+ call mpas_log_write('Right boundary must be deeper than left boundary!', MPAS_LOG_CRIT)
+ end if
+
+ ! Set refBottomDepth, bottomDepth, and maxLevelCell
+ do k = 1, nVertLevels
+ refBottomDepth(k) = config_tidal_boundary_right_bottom_depth * interfaceLocations(k+1)
+ end do
+
if (config_use_wetting_drying .and. config_tidal_start_dry .and. &
trim(config_tidal_boundary_layer_type) == 'zstar') then
do iCell = 1, nCellsSolve
@@ -281,6 +366,7 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
if (config_use_wetting_drying .and. config_tidal_start_dry) then
do iCell = 1, nCellsSolve
ssh(iCell) = -bottomDepth(iCell) + config_drying_min_cell_height*maxLevelCell(iCell)
+ ssh(iCell) = MAX(ssh(iCell),-config_tidal_forcing_monochromatic_baseline)
! also computes zMid
do k = 1, maxLevelCell(iCell)
layerThickness(k,iCell) = (ssh(iCell) + bottomDepth(iCell))/maxLevelCell(iCell)
@@ -307,7 +393,7 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
! Set tidal boundary mask
do iCell = 1, nCellsSolve
tidalInputMask(iCell) = 0.0_RKIND
- if (yCell(iCell) > (25.0e3 - dcEdgeMinGlobal/2.0_RKIND)) then
+ if (yCell(iCell) > (yMax - dcEdgeMinGlobal/2.0_RKIND)) then
tidalInputMask(iCell) = 1.0_RKIND
! spread it over multiple cells
!if (yCell(iCell) > (25.0e3 - 3*dcEdgeMinGlobal)) then
@@ -315,6 +401,11 @@ subroutine ocn_init_setup_tidal_boundary(domain, iErr)!{{{
end if
end do
+ ! check that there is some tidalInputMask
+ if (.not. sum(tidalInputMask) > 0) then
+ call mpas_log_write('Input mask for tidal case is not set!', MPAS_LOG_CRIT)
+ end if
+
! Set salinity
if ( associated(activeTracers) ) then
do iCell = 1, nCellsSolve
diff --git a/src/core_ocean/shared/Makefile b/src/core_ocean/shared/Makefile
index 1901178222..3db7fa8c08 100644
--- a/src/core_ocean/shared/Makefile
+++ b/src/core_ocean/shared/Makefile
@@ -66,13 +66,13 @@ OBJS = mpas_ocn_init_routines.o \
mpas_ocn_framework_forcing.o \
mpas_ocn_time_varying_forcing.o \
mpas_ocn_wetting_drying.o \
- mpas_ocn_tidal_potential_forcing.o
+ mpas_ocn_vel_tidal_potential.o
all: $(OBJS)
mpas_ocn_init_routines.o: mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_diagnostics.o mpas_ocn_gm.o mpas_ocn_forcing.o mpas_ocn_surface_land_ice_fluxes.o
-mpas_ocn_tendency.o: mpas_ocn_high_freq_thickness_hmix_del2.o mpas_ocn_tracer_surface_restoring.o mpas_ocn_thick_surface_flux.o mpas_ocn_tracer_short_wave_absorption.o mpas_ocn_tracer_advection.o mpas_ocn_tracer_hmix.o mpas_ocn_tracer_nonlocalflux.o mpas_ocn_surface_bulk_forcing.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_tracer_surface_flux_to_tend.o mpas_ocn_tracer_interior_restoring.o mpas_ocn_tracer_exponential_decay.o mpas_ocn_tracer_ideal_age.o mpas_ocn_tracer_TTD.o mpas_ocn_vmix.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_frazil_forcing.o mpas_ocn_tidal_forcing.o mpas_ocn_tracer_ecosys.o mpas_ocn_tracer_DMS.o mpas_ocn_tracer_MacroMolecules.o mpas_ocn_diagnostics.o mpas_ocn_wetting_drying.o mpas_ocn_tidal_potential_forcing.o
+mpas_ocn_tendency.o: mpas_ocn_high_freq_thickness_hmix_del2.o mpas_ocn_tracer_surface_restoring.o mpas_ocn_thick_surface_flux.o mpas_ocn_tracer_short_wave_absorption.o mpas_ocn_tracer_advection.o mpas_ocn_tracer_hmix.o mpas_ocn_tracer_nonlocalflux.o mpas_ocn_surface_bulk_forcing.o mpas_ocn_surface_land_ice_fluxes.o mpas_ocn_tracer_surface_flux_to_tend.o mpas_ocn_tracer_interior_restoring.o mpas_ocn_tracer_exponential_decay.o mpas_ocn_tracer_ideal_age.o mpas_ocn_tracer_TTD.o mpas_ocn_vmix.o mpas_ocn_constants.o mpas_ocn_config.o mpas_ocn_frazil_forcing.o mpas_ocn_tidal_forcing.o mpas_ocn_tracer_ecosys.o mpas_ocn_tracer_DMS.o mpas_ocn_tracer_MacroMolecules.o mpas_ocn_diagnostics.o mpas_ocn_wetting_drying.o mpas_ocn_tidal_potential_forcing.o mpas_ocn_vel_tidal_potential.o
mpas_ocn_diagnostics_routines.o: mpas_ocn_constants.o mpas_ocn_config.o
@@ -198,6 +198,8 @@ mpas_ocn_wetting_drying.o: mpas_ocn_diagnostics.o mpas_ocn_gm.o
mpas_ocn_tidal_potential_forcing.o: mpas_ocn_constants.o mpas_ocn_config.o
+mpas_ocn_vel_pressure_grad.o: mpas_ocn_constants.o
+
clean:
$(RM) *.o *.i *.mod *.f90
diff --git a/src/core_ocean/shared/mpas_ocn_tendency.F b/src/core_ocean/shared/mpas_ocn_tendency.F
index 1f129e6e0f..7b6977ec54 100644
--- a/src/core_ocean/shared/mpas_ocn_tendency.F
+++ b/src/core_ocean/shared/mpas_ocn_tendency.F
@@ -60,7 +60,7 @@ module ocn_tendency
use ocn_vel_forcing
use ocn_vmix
use ocn_wetting_drying
- use ocn_tidal_potential_forcing
+ use ocn_vel_tidal_potential
implicit none
private
@@ -321,31 +321,6 @@ subroutine ocn_tend_vel(tendPool, statePool, forcingPool, diagnosticsPool, meshP
!
call ocn_vel_vadv_tend(meshPool, normalVelocity, layerThicknessEdge, vertAleTransportTop, tend_normalVelocity, err)
- !
- ! velocity tendency: tidal potential (if needed)
- ! For RK4, subtract the tidal potential from the zMid array and store in a work array,
- ! Then point zMid to work array so the tidal potential terms are included inside the grad computed in ocn_vel_pressure_grad_tend
- ! zMid is pointed back to the typical value afterward, so the work array is not used in place of zMid elsewhere.
- !
- if (config_use_tidal_potential_forcing) then
- call ocn_compute_tidal_potential_forcing(meshPool, forcingPool, diagnosticsPool, err)
- end if
-
- if (config_use_tidal_potential_forcing .and. config_time_integrator == 'RK4') then
- call mpas_pool_get_array(forcingPool, 'tidalPotentialZMid', tidalPotentialZMid)
- call mpas_pool_get_array(forcingPool, 'tidalPotentialEta', tidalPotentialEta)
- call mpas_pool_get_array(meshPool, 'maxLevelCell', maxLevelCell)
-
- do iCell = 1, nCells
- do k = 1, maxLevelCell(iCell)
- tidalPotentialZMid(k,iCell) = zMid(k,iCell) - tidalPotentialEta(iCell) &
- - config_self_attraction_and_loading_beta * zMid(k,iCell)
- end do
- end do
-
- call mpas_pool_get_array(forcingPool, 'tidalPotentialZMid', zMid)
- end if
-
!
! velocity tendency: pressure gradient
!
@@ -362,10 +337,14 @@ subroutine ocn_tend_vel(tendPool, statePool, forcingPool, diagnosticsPool, meshP
inSituThermalExpansionCoeff,inSituSalineContractionCoeff)
endif
- if (config_use_tidal_potential_forcing .and. config_time_integrator == 'RK4') then
- ! point zMid back to usual array, to be safe
- call mpas_pool_get_array(diagnosticsPool, 'zMid', zMid)
- end if
+ !
+ ! velocity tendency: tidal potential (if needed)
+ !
+ call ocn_compute_tidal_potential_forcing(meshPool, forcingPool, diagnosticsPool, err)
+ if (config_time_integrator == 'RK4') then
+ ! for split explicit, tidal forcing is added in barotropic subsycles
+ call ocn_vel_tidal_potential_tend(meshPool, forcingPool, ssh, tend_normalVelocity, err)
+ endif
!
! velocity tendency: del2 dissipation, \nu_2 \nabla^2 u
diff --git a/src/core_ocean/shared/mpas_ocn_tidal_forcing.F b/src/core_ocean/shared/mpas_ocn_tidal_forcing.F
index f6fa320581..c5d80384b1 100644
--- a/src/core_ocean/shared/mpas_ocn_tidal_forcing.F
+++ b/src/core_ocean/shared/mpas_ocn_tidal_forcing.F
@@ -241,7 +241,8 @@ subroutine ocn_tidal_forcing_build_array(domain, meshPool, forcingPool, diagnost
! compute the tidalHeight
if (trim(config_tidal_forcing_model) == 'monochromatic') then
tidalHeight = config_tidal_forcing_monochromatic_amp * &
- SIN(2.0_RKIND*pii/config_tidal_forcing_monochromatic_period * daysSinceStartOfSim) - &
+ SIN(2.0_RKIND*pii/config_tidal_forcing_monochromatic_period * daysSinceStartOfSim - &
+ pii*config_tidal_forcing_monochromatic_phaseLag/180.0_RKIND) - &
config_tidal_forcing_monochromatic_baseline
!else if (trim(config_tidal_forcing_type) == 'data') then
! ! data option
diff --git a/src/core_ocean/shared/mpas_ocn_time_varying_forcing.F b/src/core_ocean/shared/mpas_ocn_time_varying_forcing.F
index ac0bf333a1..8009506862 100644
--- a/src/core_ocean/shared/mpas_ocn_time_varying_forcing.F
+++ b/src/core_ocean/shared/mpas_ocn_time_varying_forcing.F
@@ -364,7 +364,12 @@ subroutine post_atmospheric_forcing(block)!{{{
rhoAir = 1.225_RKIND
windStressCoefficientLimit = 0.0035_RKIND
- ramp = tanh((2.0_RKIND*daysSinceStartOfSim)/config_time_varying_atmospheric_forcing_ramp)
+ if (daysSinceStartOfSim >= config_time_varying_atmospheric_forcing_ramp_delay) then
+ ramp = tanh((2.0_RKIND*(daysSinceStartOfSim-config_time_varying_atmospheric_forcing_ramp_delay)) &
+ /config_time_varying_atmospheric_forcing_ramp)
+ else
+ ramp = 0.0_RKIND
+ end if
!$omp parallel
!$omp do schedule(runtime) private(windStressCoefficient)
diff --git a/src/core_ocean/shared/mpas_ocn_tidal_potential_forcing.F b/src/core_ocean/shared/mpas_ocn_vel_tidal_potential.F
similarity index 80%
rename from src/core_ocean/shared/mpas_ocn_tidal_potential_forcing.F
rename to src/core_ocean/shared/mpas_ocn_vel_tidal_potential.F
index 7cbeabc61c..b6c5bb2115 100644
--- a/src/core_ocean/shared/mpas_ocn_tidal_potential_forcing.F
+++ b/src/core_ocean/shared/mpas_ocn_vel_tidal_potential.F
@@ -7,7 +7,7 @@
!
!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!
-! ocn_tidal_potential_forcing
+! ocn_vel_tidal_potential
!
!> \brief MPAS ocean tidal potential forcing module
!> \author Steven Brus
@@ -19,7 +19,7 @@
!
!-----------------------------------------------------------------------
-module ocn_tidal_potential_forcing
+module ocn_vel_tidal_potential
use mpas_kind_types
use mpas_constants
@@ -28,7 +28,6 @@ module ocn_tidal_potential_forcing
use mpas_timekeeping
use mpas_timer
use ocn_constants
- use ocn_config
implicit none
private
@@ -46,8 +45,10 @@ module ocn_tidal_potential_forcing
!
!--------------------------------------------------------------------
- public :: ocn_compute_tidal_potential_forcing, &
- ocn_tidal_potential_forcing_init
+ public :: ocn_vel_tidal_potential_tend, &
+ ocn_compute_tidal_potential_forcing, &
+ ocn_vel_tidal_potential_init, &
+ tidal_constituent_factors
!--------------------------------------------------------------------
!
@@ -60,7 +61,7 @@ module ocn_tidal_potential_forcing
character(:), allocatable :: constituent
end type
type(char_array), dimension(37) :: constituentList
-
+ public :: char_array
!***********************************************************************
@@ -68,7 +69,101 @@ module ocn_tidal_potential_forcing
!***********************************************************************
!
-! routine ocn_tidal_potential_forcing_layer_thickness
+! routine ocn_vel_tidal_potential_tend
+!
+!> \brief Computes tendency term for tidal potential
+!> \author Steven Brus
+!> \date April 2020
+!> \details
+!> This routine computes the tidal potential tendency for momentum
+!> based on current state.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_vel_tidal_potential_tend(meshPool, forcingPool, ssh, tend, err)!{{{
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ real (kind=RKIND), dimension(:), intent(in) :: &
+ ssh !< Input: Sea surface height
+
+ type (mpas_pool_type), intent(in) :: meshPool !< Input: mesh information
+ type (mpas_pool_type), intent(in) :: forcingPool !< Input: forcinginformation
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ real (kind=RKIND), dimension(:,:), intent(inout) :: &
+ tend !< Input/Output: velocity tendency
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ integer :: iEdge, k, cell1, cell2, nEdges
+ integer, dimension(:), pointer :: nEdgesArray
+ integer, dimension(:), pointer :: maxLevelEdgeTop, maxLevelCell
+ integer, dimension(:,:), pointer :: cellsOnEdge, edgeMask
+
+ real (kind=RKIND), dimension(:), pointer :: dcEdge
+ real (kind=RKIND), dimension(:), pointer :: tidalPotentialEta
+ real (kind=RKIND), pointer :: config_self_attraction_and_loading_beta
+ real (kind=RKIND) :: invdcEdge
+ real (kind=RKIND) :: potentialGrad
+ logical, pointer :: config_use_tidal_potential_forcing
+
+ err = 0
+
+ if (.not. tidalPotentialOn) return
+
+ call mpas_pool_get_dimension(meshPool, 'nEdgesArray', nEdgesArray)
+ call mpas_pool_get_array(meshPool, 'maxLevelEdgeTop', maxLevelEdgeTop)
+ call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge)
+ call mpas_pool_get_array(meshPool, 'dcEdge', dcEdge)
+ call mpas_pool_get_array(meshPool, 'edgeMask', edgeMask)
+ call mpas_pool_get_array(forcingPool, 'tidalPotentialEta', tidalPotentialEta)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing', config_use_tidal_potential_forcing)
+ call mpas_pool_get_config(ocnConfigs, 'config_self_attraction_and_loading_beta', config_self_attraction_and_loading_beta)
+
+ nEdges = nEdgesArray( 1 )
+
+ !$omp do schedule(runtime) private(cell1, cell2, invdcEdge, potentialGrad, k)
+ do iEdge=1,nEdges
+ cell1 = cellsOnEdge(1,iEdge)
+ cell2 = cellsOnEdge(2,iEdge)
+ invdcEdge = 1.0_RKIND / dcEdge(iEdge)
+
+ potentialGrad = - gravity * invdcEdge * ( tidalPotentialEta(cell2) - tidalPotentialEta(cell1) &
+ + config_self_attraction_and_loading_beta*(ssh(cell2) - ssh(cell1)))
+
+ do k=1,maxLevelEdgeTop(iEdge)
+ tend(k,iEdge) = tend(k,iEdge) - edgeMask(k,iEdge) * potentialGrad
+ end do
+ end do
+ !$omp end do
+
+ end subroutine ocn_vel_tidal_potential_tend!}}}
+
+!***********************************************************************
+!
+! routine ocn_compute_tidal_potential_forcing
!
!> \brief Computes equilibrium tidal potential
!> \author Steven Brus
@@ -111,6 +206,7 @@ subroutine ocn_compute_tidal_potential_forcing(meshPool, forcingPool, diagnostic
!-----------------------------------------------------------------
integer, pointer :: nCells
+ real (kind=RKIND), pointer :: tidalPotentialRamp
real (kind=RKIND), dimension(:), pointer :: lonCell
integer, dimension(:), pointer :: maxLevelCell
@@ -132,6 +228,7 @@ subroutine ocn_compute_tidal_potential_forcing(meshPool, forcingPool, diagnostic
if ( .not. tidalPotentialOn ) return
+ call mpas_pool_get_config(ocnConfigs, 'config_tidal_potential_ramp', tidalPotentialRamp)
call mpas_pool_get_dimension(meshPool, 'nCells', nCells)
call mpas_pool_get_array(meshPool, 'lonCell', lonCell)
call mpas_pool_get_array(forcingPool, 'nTidalPotentialConstituents', nTidalConstituents)
@@ -146,7 +243,7 @@ subroutine ocn_compute_tidal_potential_forcing(meshPool, forcingPool, diagnostic
call mpas_pool_get_array(forcingPool, 'tidalPotentialEta', eta)
call mpas_pool_get_array(diagnosticsPool, "daysSinceStartOfSim", daysSinceStartOfSim)
- ramp = tanh((2.0_RKIND*daysSinceStartOfSim)/config_tidal_potential_ramp)
+ ramp = tanh((2.0_RKIND*daysSinceStartOfSim)/tidalPotentialRamp)
t = daysSinceStartOfSim*86400.0_RKIND
do iCell = 1, nCells
@@ -175,7 +272,7 @@ end subroutine ocn_compute_tidal_potential_forcing!}}}
!***********************************************************************
!
-! routine ocn_tidal_potential_forcing_init
+! routine ocn_vel_tidal_potential_init
!
!> \brief Initializes ocean tidal protential forcing module.
!> \author Steven Brus
@@ -186,11 +283,22 @@ end subroutine ocn_compute_tidal_potential_forcing!}}}
!
!-----------------------------------------------------------------------
- subroutine ocn_tidal_potential_forcing_init(domain,err)!{{{
+ subroutine ocn_vel_tidal_potential_init(domain,err)!{{{
type (domain_type), intent(inout) :: domain
integer, intent(out) :: err !< Output: error flag
+ logical, pointer :: config_use_tidal_potential_forcing
+ logical, pointer :: config_use_tidal_potential_forcing_M2
+ logical, pointer :: config_use_tidal_potential_forcing_S2
+ logical, pointer :: config_use_tidal_potential_forcing_N2
+ logical, pointer :: config_use_tidal_potential_forcing_K2
+ logical, pointer :: config_use_tidal_potential_forcing_K1
+ logical, pointer :: config_use_tidal_potential_forcing_O1
+ logical, pointer :: config_use_tidal_potential_forcing_Q1
+ logical, pointer :: config_use_tidal_potential_forcing_P1
+ character (len=StrKIND), pointer :: config_tidal_potential_reference_time
+
type (block_type), pointer :: block_ptr
type (mpas_pool_type), pointer :: forcingPool
type (mpas_pool_type), pointer :: meshPool
@@ -214,6 +322,17 @@ subroutine ocn_tidal_potential_forcing_init(domain,err)!{{{
err = 0
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing', config_use_tidal_potential_forcing)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_M2', config_use_tidal_potential_forcing_M2)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_S2', config_use_tidal_potential_forcing_S2)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_N2', config_use_tidal_potential_forcing_N2)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_K2', config_use_tidal_potential_forcing_K2)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_K1', config_use_tidal_potential_forcing_K1)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_O1', config_use_tidal_potential_forcing_O1)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_Q1', config_use_tidal_potential_forcing_Q1)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_tidal_potential_forcing_P1', config_use_tidal_potential_forcing_P1)
+ call mpas_pool_get_config(ocnConfigs, 'config_tidal_potential_reference_time', config_tidal_potential_reference_time)
+
block_ptr => domain % blocklist
do while(associated(block_ptr))
call mpas_pool_get_subpool(block_ptr % structs, 'forcing', forcingPool)
@@ -330,7 +449,7 @@ subroutine ocn_tidal_potential_forcing_init(domain,err)!{{{
end do
- end subroutine ocn_tidal_potential_forcing_init!}}}
+ end subroutine ocn_vel_tidal_potential_init!}}}
!***********************************************************************
@@ -636,7 +755,7 @@ function adjust_angle(arg) result(angle) !{{{
!***********************************************************************
-end module ocn_tidal_potential_forcing!}}}
+end module ocn_vel_tidal_potential!}}}
!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
! vim: foldmethod=marker
diff --git a/src/core_ocean/shared/mpas_ocn_vmix.F b/src/core_ocean/shared/mpas_ocn_vmix.F
index 10c33f6c41..c1f25a2af4 100644
--- a/src/core_ocean/shared/mpas_ocn_vmix.F
+++ b/src/core_ocean/shared/mpas_ocn_vmix.F
@@ -26,6 +26,7 @@ module ocn_vmix
use mpas_pool_routines
use mpas_timer
+ use mpas_constants
use ocn_constants
use ocn_config
use ocn_vmix_cvmix
@@ -485,6 +486,388 @@ subroutine ocn_vel_vmix_tend_implicit(meshPool, dt, kineticEnergyCell, vertViscT
end subroutine ocn_vel_vmix_tend_implicit!}}}
+!***********************************************************************
+!
+! routine ocn_vel_vmix_tend_implicit_variable
+!
+!> \brief Computes tendencies for implicit momentum vertical mixing
+!> with spatially-variable bottom drag
+!> \author Mark Petersen, Phillip J. Wolfram
+!> \date September 2011, September 2019
+!> \details
+!> This routine computes the tendencies for implicit vertical mixing for momentum
+!> using computed coefficients from spatially-variable bottom drag.
+!> Except for bottom drag coefficient, routine should be identifcal to
+!> ocn_vel_vmix_tend_implicit above.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_vel_vmix_tend_implicit_spatially_variable(meshPool, bottomDrag, dt, kineticEnergyCell, & !{{{
+ vertViscTopOfEdge, layerThickness, &
+ layerThicknessEdge, normalVelocity, err)
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ type (mpas_pool_type), intent(in) :: &
+ meshPool !< Input: mesh information
+
+ real (kind=RKIND), dimension(:,:), intent(in) :: &
+ kineticEnergyCell !< Input: kinetic energy at cell
+
+ real (kind=RKIND), dimension(:,:), intent(in) :: &
+ vertViscTopOfEdge !< Input: vertical mixing coefficients
+
+ real (kind=RKIND), intent(in) :: &
+ dt !< Input: time step
+
+ real (kind=RKIND), dimension(:,:), intent(in) :: &
+ layerThickness !< Input: thickness at cell center
+
+ real (kind=RKIND), dimension(:), intent(in) :: &
+ bottomDrag !< Input: bottomDrag at cell centeres
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ real (kind=RKIND), dimension(:,:), intent(inout) :: &
+ normalVelocity !< Input: velocity
+
+ real (kind=RKIND), dimension(:,:), intent(inout) :: &
+ layerThicknessEdge !< Input: thickness at edge
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ integer :: iEdge, k, cell1, cell2, N, nEdges
+ integer, pointer :: nVertLevels
+ real (kind=RKIND) :: implicitCd
+ integer, dimension(:), pointer :: nEdgesArray
+
+ integer, dimension(:), pointer :: maxLevelEdgeTop
+
+ integer, dimension(:,:), pointer :: cellsOnEdge
+
+ real (kind=RKIND), dimension(:), allocatable :: A, B, C, velTemp
+
+ err = 0
+
+ if(.not.velVmixOn) return
+
+ call mpas_pool_get_dimension(meshPool, 'nEdgesArray', nEdgesArray)
+ call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels)
+
+ call mpas_pool_get_array(meshPool, 'maxLevelEdgeTop', maxLevelEdgeTop)
+ call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge)
+
+ nEdges = nEdgesArray( 1 )
+
+ allocate(A(nVertLevels),B(nVertLevels),C(nVertLevels),velTemp(nVertLevels))
+ A(1)=0.0_RKIND
+
+ !$omp do schedule(runtime)
+ do iEdge = 1, nEdges
+ N = maxLevelEdgeTop(iEdge)
+ if (N .gt. 0) then
+
+ ! Compute A(k), B(k), C(k)
+ ! layerThicknessEdge is computed in compute_solve_diag, and is not available yet,
+ ! so recompute layerThicknessEdge here.
+ cell1 = cellsOnEdge(1,iEdge)
+ cell2 = cellsOnEdge(2,iEdge)
+ do k = 1, N
+ layerThicknessEdge(k,iEdge) = 0.5_RKIND * (layerThickness(k,cell1) + layerThickness(k,cell2))
+ end do
+
+ ! average cell-based implicit bottom drag to edges
+ implicitCd = 0.5_RKIND*(bottomDrag(cell1) + bottomDrag(cell2))
+
+ ! A is lower diagonal term
+ do k = 2, N
+ A(k) = -2.0_RKIND*dt*vertViscTopOfEdge(k,iEdge) &
+ / (layerThicknessEdge(k-1,iEdge) + layerThicknessEdge(k,iEdge)) &
+ / layerThicknessEdge(k,iEdge)
+ enddo
+
+ ! C is upper diagonal term
+ do k = 1, N-1
+ C(k) = -2.0_RKIND*dt*vertViscTopOfEdge(k+1,iEdge) &
+ / (layerThicknessEdge(k,iEdge) + layerThicknessEdge(k+1,iEdge)) &
+ / layerThicknessEdge(k,iEdge)
+ enddo
+
+ ! B is diagonal term
+ B(1) = 1.0_RKIND - C(1)
+ do k = 2, N-1
+ B(k) = 1.0_RKIND - A(k) - C(k)
+ enddo
+
+ ! Apply bottom drag boundary condition on the viscous term
+ ! second line uses sqrt(2.0*kineticEnergyEdge(k,iEdge))
+ ! use implicitCd from spatially variable bottom drag
+ B(N) = 1.0_RKIND - A(N) + dt*implicitCd &
+ * sqrt(kineticEnergyCell(N,cell1) + kineticEnergyCell(N,cell2)) / layerThicknessEdge(N,iEdge)
+
+ call tridiagonal_solve(A(2:N),B,C(1:N-1),normalVelocity(:,iEdge),velTemp,N)
+
+ normalVelocity(1:N,iEdge) = velTemp(1:N)
+ normalVelocity(N+1:nVertLevels,iEdge) = 0.0_RKIND
+
+ end if
+ end do
+ !$omp end do
+
+ deallocate(A,B,C,velTemp)
+
+ !--------------------------------------------------------------------
+
+ end subroutine ocn_vel_vmix_tend_implicit_spatially_variable!}}}
+
+
+!***********************************************************************
+!
+! routine ocn_vel_vmix_tend_implicit_variable_mannings
+!
+!> \brief Computes tendencies for implicit momentum vertical mixing
+!> with spatially-variable bottom drag using Mannings friction
+!> \author Mark Petersen, Phillip J. Wolfram
+!> \date September 2011, September 2019
+!> \details
+!> This routine computes the tendencies for implicit vertical mixing for momentum
+!> using computed coefficients from spatially-variable bottom drag.
+!> Except for bottom drag coefficient, routine should be identifcal to
+!> ocn_vel_vmix_tend_implicit above. Cd uses Mannings' n values for the
+!> Cd=g*n^2*h^{-1/3}.
+!
+!-----------------------------------------------------------------------
+
+ subroutine ocn_vel_vmix_tend_implicit_spatially_variable_mannings(meshPool, forcingPool, bottomDrag, dt, & !{{{
+ kineticEnergyCell, vertViscTopOfEdge, layerThickness, &
+ layerThicknessEdge, normalVelocity, ssh, bottomDepth, err)
+
+ !-----------------------------------------------------------------
+ !
+ ! input variables
+ !
+ !-----------------------------------------------------------------
+
+ type (mpas_pool_type), intent(in) :: &
+ meshPool !< Input: mesh information
+
+ type (mpas_pool_type), intent(inout) :: &
+ forcingPool !< Input: forcing information
+
+ real (kind=RKIND), dimension(:,:), intent(in) :: &
+ kineticEnergyCell !< Input: kinetic energy at cell
+
+ real (kind=RKIND), dimension(:,:), intent(in) :: &
+ vertViscTopOfEdge !< Input: vertical mixing coefficients
+
+ real (kind=RKIND), intent(in) :: &
+ dt !< Input: time step
+
+ real (kind=RKIND), dimension(:,:), intent(in) :: &
+ layerThickness !< Input: thickness at cell center
+
+ real (kind=RKIND), dimension(:), intent(in) :: &
+ bottomDrag !< Input: bottomDrag at cell centeres
+
+ real (kind=RKIND), dimension(:), pointer :: ssh
+
+ real (kind=RKIND), dimension(:), pointer :: bottomDepth
+
+ !-----------------------------------------------------------------
+ !
+ ! input/output variables
+ !
+ !-----------------------------------------------------------------
+
+ real (kind=RKIND), dimension(:,:), intent(inout) :: &
+ normalVelocity !< Input: velocity
+
+ real (kind=RKIND), dimension(:,:), intent(inout) :: &
+ layerThicknessEdge !< Input: thickness at edge
+
+ !-----------------------------------------------------------------
+ !
+ ! output variables
+ !
+ !-----------------------------------------------------------------
+
+ integer, intent(out) :: err !< Output: error flag
+
+ !-----------------------------------------------------------------
+ !
+ ! local variables
+ !
+ !-----------------------------------------------------------------
+
+ integer :: iEdge, k, cell1, cell2, N, nEdges
+ integer, pointer :: nVertLevels
+ real (kind=RKIND) :: implicitCd
+ integer, dimension(:), pointer :: nEdgesArray
+
+ integer, dimension(:), pointer :: maxLevelEdgeTop
+
+ integer, dimension(:,:), pointer :: cellsOnEdge
+
+ real (kind=RKIND), dimension(:), allocatable :: A, B, C, velTemp
+
+ ! vegetation_drag
+ logical, pointer :: config_use_vegetation_drag
+ logical, pointer :: config_use_vegetation_manning_equation
+ real (kind=RKIND), pointer :: config_vegetation_drag_coefficient
+ real (kind=RKIND), dimension(:), pointer :: vegetationHeight
+ real (kind=RKIND), dimension(:), pointer :: vegetationDiameter
+ real (kind=RKIND), dimension(:), pointer ::vegetationDensity
+ real (kind=RKIND), dimension(:), pointer ::vegetationManning
+ integer, dimension(:), pointer ::vegetationMask
+ real (kind=RKIND) :: old_bottom_Cd, lambda, beta, alpha, total_h
+ real (kind=RKIND) :: inundation_depth, von_karman, cff1, cff2, cff3, cff4
+ integer :: iCell, nCells
+ integer, pointer :: nCellsSolve
+
+ err = 0
+ von_karman = 0.4_RKIND
+
+ if(.not.velVmixOn) return
+
+ call mpas_pool_get_dimension(meshPool, 'nEdgesArray', nEdgesArray)
+ call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels)
+ call mpas_pool_get_dimension(meshPool, 'nCellsSolve', nCellsSolve)
+
+ call mpas_pool_get_array(meshPool, 'maxLevelEdgeTop', maxLevelEdgeTop)
+ call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge)
+
+ call mpas_pool_get_config(ocnConfigs, 'config_use_vegetation_drag', config_use_vegetation_drag)
+ call mpas_pool_get_config(ocnConfigs, 'config_use_vegetation_manning_equation', config_use_vegetation_manning_equation)
+ call mpas_pool_get_config(ocnConfigs, 'config_vegetation_drag_coefficient', config_vegetation_drag_coefficient)
+
+ call mpas_pool_get_array(forcingPool, 'vegetationMask', vegetationMask)
+ call mpas_pool_get_array(forcingPool, 'vegetationHeight', vegetationHeight)
+ call mpas_pool_get_array(forcingPool, 'vegetationDensity', vegetationDensity)
+ call mpas_pool_get_array(forcingPool, 'vegetationDiameter', vegetationDiameter)
+ call mpas_pool_get_array(forcingPool, 'vegetationManning', vegetationManning)
+
+ nEdges = nEdgesArray( 1 )
+ nCells = nCellsSolve
+
+ allocate(A(nVertLevels),B(nVertLevels),C(nVertLevels),velTemp(nVertLevels))
+ A(1)=0.0_RKIND
+
+ ! Compute bottomDrag (Manning roughness) induced by vegetation
+ if (config_use_vegetation_drag .AND. config_use_vegetation_manning_equation) then
+ do iCell = 1, nCells
+ if (vegetationDensity(iCell) * vegetationHeight(iCell) * vegetationDiameter(iCell) .eq. 0.0_RKIND) then
+ vegetationMask(iCell) = 0
+ endif
+ if (vegetationMask(iCell) .eq. 1) then
+ total_h = bottomDepth(iCell) + ssh(iCell)
+ old_bottom_Cd = gravity * bottomDrag(iCell)**2.0_RKIND * total_h**(1.0_RKIND/3.0_RKIND)
+ inundation_depth = MIN(vegetationHeight(iCell), total_h)
+ inundation_depth = MAX(inundation_depth, 1e-6)
+ lambda = vegetationDiameter(iCell) * vegetationDensity(iCell)
+ alpha = (config_vegetation_drag_coefficient*lambda/ &
+ (4.0_RKIND*von_karman**2.0_RKIND*inundation_depth**2.0_RKIND))**(1.0_RKIND/3.0_RKIND)
+ beta = 0.5_RKIND*alpha*inundation_depth*(1.0_RKIND - EXP(-2.0_RKIND*alpha*inundation_depth)) &
+ / (1.0_RKIND - EXP(-alpha*inundation_depth))**2.0_RKIND
+ cff1 = total_h**(2.0_RKIND/3.0_RKIND) &
+ * SQRT((0.5_RKIND*beta*lambda*config_vegetation_drag_coefficient*inundation_depth &
+ + old_bottom_Cd)/(gravity*total_h))
+ cff2 = (alpha*inundation_depth)**2.0_RKIND/(1.0_RKIND - EXP(-alpha*inundation_depth))
+ cff3 = (1.0_RKIND - EXP(-alpha*inundation_depth))/(alpha**2.0_RKIND*inundation_depth*total_h)
+ cff4 = LOG(total_h/inundation_depth) - (1.0_RKIND-inundation_depth/total_h) &
+ * (1.0_RKIND - 1.0_RKIND/(alpha*inundation_depth))
+ vegetationManning(iCell) = cff1/(cff2*(cff3+cff4))
+ vegetationManning(iCell) = MAX(bottomDrag(iCell), vegetationManning(iCell))
+ else
+ vegetationManning(iCell) = bottomDrag(iCell)
+ endif
+ enddo
+ endif
+
+ !$omp do schedule(runtime)
+ do iEdge = 1, nEdges
+ N = maxLevelEdgeTop(iEdge)
+ if (N .gt. 0) then
+
+ ! Compute A(k), B(k), C(k)
+ ! layerThicknessEdge is computed in compute_solve_diag, and is not available yet,
+ ! so recompute layerThicknessEdge here.
+ cell1 = cellsOnEdge(1,iEdge)
+ cell2 = cellsOnEdge(2,iEdge)
+ do k = 1, N
+ layerThicknessEdge(k,iEdge) = 0.5_RKIND * (layerThickness(k,cell1) + layerThickness(k,cell2))
+ end do
+
+ ! average cell-based implicit bottom drag to edges and convert Mannings n to Cd
+ if (config_use_vegetation_drag .AND. config_use_vegetation_manning_equation) then
+ implicitCd = gravity*(0.5_RKIND*(vegetationManning(cell1) + vegetationManning(cell2)))**2.0 * &
+ (0.5_RKIND * (ssh(cell1) + ssh(cell2) + bottomDepth(cell1) + bottomDepth(cell2)))**(-1.0_RKIND/3.0_RKIND)
+ else
+ implicitCd = gravity*(0.5_RKIND*(bottomDrag(cell1) + bottomDrag(cell2)))**2.0 * &
+ (0.5_RKIND * (ssh(cell1) + ssh(cell2) + bottomDepth(cell1) + bottomDepth(cell2)))**(-1.0_RKIND/3.0_RKIND)
+ endif
+
+ ! A is lower diagonal term
+ do k = 2, N
+ A(k) = -2.0_RKIND*dt*vertViscTopOfEdge(k,iEdge) &
+ / (layerThicknessEdge(k-1,iEdge) + layerThicknessEdge(k,iEdge)) &
+ / layerThicknessEdge(k,iEdge)
+ enddo
+
+ ! C is upper diagonal term
+ do k = 1, N-1
+ C(k) = -2.0_RKIND*dt*vertViscTopOfEdge(k+1,iEdge) &
+ / (layerThicknessEdge(k,iEdge) + layerThicknessEdge(k+1,iEdge)) &
+ / layerThicknessEdge(k,iEdge)
+ enddo
+
+ ! B is diagonal term
+ B(1) = 1.0_RKIND - C(1)
+ do k = 2, N-1
+ B(k) = 1.0_RKIND - A(k) - C(k)
+ enddo
+
+ ! Apply bottom drag boundary condition on the viscous term
+ ! second line uses sqrt(2.0*kineticEnergyEdge(k,iEdge))
+ ! use implicitCd from spatially variable bottom drag
+ B(N) = 1.0_RKIND - A(N) + dt*implicitCd &
+ * sqrt(kineticEnergyCell(N,cell1) + kineticEnergyCell(N,cell2)) / layerThicknessEdge(N,iEdge)
+
+ call tridiagonal_solve(A(2:N),B,C(1:N-1),normalVelocity(:,iEdge),velTemp,N)
+
+ normalVelocity(1:N,iEdge) = velTemp(1:N)
+ normalVelocity(N+1:nVertLevels,iEdge) = 0.0_RKIND
+
+ end if
+ end do
+ !$omp end do
+
+ deallocate(A,B,C,velTemp)
+
+ !--------------------------------------------------------------------
+
+ end subroutine ocn_vel_vmix_tend_implicit_spatially_variable_mannings!}}}
+
+
!***********************************************************************
!
! routine ocn_tracer_vmix_tend_implicit
@@ -650,6 +1033,7 @@ subroutine ocn_vmix_implicit(dt, meshPool, diagnosticsPool, statePool, forcingPo
integer :: iCell, timeLevel, k, cell1, cell2, iEdge, nCells, nEdges
integer, dimension(:), pointer :: nCellsArray, nEdgesArray
+ real (kind=RKIND), dimension(:), pointer :: bottomDrag, ssh, bottomDepth ! needed for depth-variable computation
real (kind=RKIND), dimension(:,:), pointer :: normalVelocity, layerThickness, layerThicknessEdge, vertViscTopOfEdge, &
vertDiffTopOfCell, kineticEnergyCell
real (kind=RKIND), dimension(:,:), pointer :: vertViscTopOfCell, nonLocalSurfaceTracerFlux, tracerGroupSurfaceFlux
@@ -678,6 +1062,7 @@ subroutine ocn_vmix_implicit(dt, meshPool, diagnosticsPool, statePool, forcingPo
call mpas_pool_get_subpool(forcingPool, 'tracersSurfaceFlux', tracersSurfaceFluxPool)
call mpas_pool_get_array(statePool, 'normalVelocity', normalVelocity, timeLevel)
call mpas_pool_get_array(statePool, 'layerThickness', layerThickness, timeLevel)
+ call mpas_pool_get_array(statePool, 'ssh', ssh, timeLevel)
call mpas_pool_get_array(diagnosticsPool, 'kineticEnergyCell', kineticEnergyCell)
call mpas_pool_get_array(diagnosticsPool, 'layerThicknessEdge', layerThicknessEdge)
@@ -690,11 +1075,14 @@ subroutine ocn_vmix_implicit(dt, meshPool, diagnosticsPool, statePool, forcingPo
call mpas_pool_get_array(meshPool, 'maxLevelCell', maxLevelCell)
call mpas_pool_get_array(meshPool, 'maxLevelEdgeTop', maxLevelEdgeTop)
call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge)
+ call mpas_pool_get_array(meshPool, 'bottomDepth', bottomDepth)
call mpas_pool_get_dimension(meshPool, 'nVertLevels', nVertLevels)
call mpas_pool_get_dimension(meshPool, 'nCellsArray', nCellsArray)
call mpas_pool_get_dimension(meshPool, 'nEdgesArray', nEdgesArray)
+ call mpas_pool_get_array(forcingPool, 'bottomDrag', bottomDrag)
+
call mpas_timer_start('vmix coefs', .false.)
call ocn_vmix_coefs(meshPool, statePool, forcingPool, diagnosticsPool, scratchPool, err, timeLevel)
call mpas_timer_stop('vmix coefs')
@@ -727,12 +1115,25 @@ subroutine ocn_vmix_implicit(dt, meshPool, diagnosticsPool, statePool, forcingPo
call mpas_timer_start('vmix solve momentum', .false.)
if (.not. (config_Rayleigh_friction .or. &
config_Rayleigh_bottom_friction .or. &
- config_Rayleigh_damping_depth_variable)) then
+ config_Rayleigh_damping_depth_variable .or. &
+ config_use_implicit_bottom_drag_variable .or. &
+ config_use_implicit_bottom_drag_variable_mannings)) then
call ocn_vel_vmix_tend_implicit(meshPool, dt, kineticEnergyCell, &
vertViscTopOfEdge, layerThickness, layerThicknessEdge, normalVelocity, err)
else
- call ocn_vel_vmix_tend_implicit_rayleigh(meshPool, dt, kineticEnergyCell, &
- vertViscTopOfEdge, layerThickness, layerThicknessEdge, normalVelocity, err)
+ if (config_use_implicit_bottom_drag_variable) then
+ call ocn_vel_vmix_tend_implicit_spatially_variable(meshPool, bottomDrag, dt, kineticEnergyCell, &
+ vertViscTopOfEdge, layerThickness, layerThicknessEdge, normalVelocity, err)
+ else if (config_use_implicit_bottom_drag_variable_mannings) then
+ ! update bottomDrag via Cd=g*n^2*h^(-1/3)
+ call ocn_vel_vmix_tend_implicit_spatially_variable_mannings(meshPool, forcingPool, bottomDrag, &
+ dt, kineticEnergyCell, &
+ vertViscTopOfEdge, layerThickness, layerThicknessEdge, normalVelocity, &
+ ssh, bottomDepth, err)
+ else if (config_Rayleigh_damping_depth_variable) then
+ call ocn_vel_vmix_tend_implicit_rayleigh(meshPool, dt, kineticEnergyCell, &
+ vertViscTopOfEdge, layerThickness, layerThicknessEdge, normalVelocity, err)
+ end if
end if
call mpas_timer_stop('vmix solve momentum')
diff --git a/testing_and_setup/compass/ocean/drying_slope/analysis/comparison.py b/testing_and_setup/compass/ocean/drying_slope/analysis/comparison.py
index 8f3805e2ae..8f09d8301d 100755
--- a/testing_and_setup/compass/ocean/drying_slope/analysis/comparison.py
+++ b/testing_and_setup/compass/ocean/drying_slope/analysis/comparison.py
@@ -79,9 +79,9 @@ def plot_MPASO(times, fileno, *args, **kwargs):
for atime in times:
# factor of 1e-16 needed to account for annoying round-off issue to get right time slices
plottime = int((float(atime)/0.2 + 1e-16)*24.0)
- ds = xr.open_mfdataset('output'+ fileno + '.nc')
+ ds = xr.open_dataset('output'+ fileno + '.nc')
print('{} {} {}'.format(atime, plottime, ds.isel(Time=plottime).xtime.values))
- ds = ds.drop(np.setdiff1d([i for i in ds.variables], ['yCell','ssh']))
+ ds = ds.drop_vars(np.setdiff1d([i for i in ds.variables], ['yCell','ssh']))
ymean = ds.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
x = ymean.yCell.values/1000.0
y = ymean.ssh.values
@@ -93,7 +93,7 @@ def plot_MPASO(times, fileno, *args, **kwargs):
def plot_tidal_forcing_comparison():
# data from MPAS-O on boundary
for fileno in ['1','2']:
- ds = xr.open_mfdataset('output' + fileno +'.nc')
+ ds = xr.open_dataset('output' + fileno +'.nc')
ympas = ds.ssh.where(ds.tidalInputMask).mean('nCells').values
x = np.linspace(0, 1.0, len(ds.xtime))*12.0
plt.plot(x, ympas, marker='o', label='MPAS-O forward' + fileno)
diff --git a/testing_and_setup/compass/ocean/drying_slope/analysis/comparison_above_land.py b/testing_and_setup/compass/ocean/drying_slope/analysis/comparison_above_land.py
new file mode 100755
index 0000000000..ec64971c02
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/analysis/comparison_above_land.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+"""
+
+Drying slope comparison betewen MPAS-O, analytical, and ROMS results from
+
+Warner, J. C., Defne, Z., Haas, K., & Arango, H. G. (2013). A wetting and
+drying scheme for ROMS. Computers & geosciences, 58, 54-61.
+
+Phillip J. Wolfram and Zhendong Cao
+04/30/2019
+
+"""
+
+import numpy as np
+import xarray as xr
+import matplotlib.pyplot as plt
+import pandas as pd
+
+# render statically by default
+plt.switch_backend('agg')
+
+def setup_fig():
+ fig, ax = plt.subplots(nrows=1,ncols=1, sharex=True, sharey=True)
+ fig.text(0.04, 0.5, 'Channel depth (m)', va='center', rotation='vertical')
+ fig.text(0.5, 0.02, 'Along channel distance (km)', ha='center')
+
+def setup_subplot():
+ plt.xlim(0,25)
+ plt.ylim(-11, 11)
+ ax = plt.gca()
+ ax.invert_yaxis()
+ ax.spines['top'].set_visible(False)
+ ax.spines['right'].set_visible(False)
+
+ x = np.linspace(0,25,100)
+ y = -10 + 20.0/25.0*x
+ plt.plot(x, y, 'k-', lw=3)
+
+def plot_data(rval='0.0025', dtime='0.05', datatype='analytical', *args, **kwargs):
+ datafile = 'data/r' + rval + 'd' + dtime + '-' + datatype + '.csv'
+ data = pd.read_csv(datafile, header=None)
+ measured=plt.scatter(data[0], data[1], *args, **kwargs)
+
+
+def plot_datasets(rval, times, fileno, plotdata=True):
+ for ii, dtime in enumerate(times):
+ if plotdata:
+ plot_data(rval=rval, dtime = dtime, datatype = 'analytical',
+ marker = '.', color = 'b', label='analytical')
+ plot_data(rval=rval, dtime = dtime, datatype = 'roms',
+ marker = '.', color = 'g', label='ROMS')
+ plot_MPASO([dtime], fileno, 'k-', lw=0.5, label='MPAS-O')
+
+ if plotdata:
+ if ii == 0:
+ plt.legend(frameon=False, loc='lower left')
+ place_time_labels(times)
+ plt.text(0.5, 5, 'r = ' + str(rval))
+
+
+def place_time_labels(times):
+ locs = [9.3, 7.2, 4.2, 2.2, 1.2, 0.2]
+ for atime, ay in zip(times, locs):
+ plt.text(25.2, -10+20*ay, atime + ' days', size=8)
+
+def plot_MPASO(times, fileno, *args, **kwargs):
+ for atime in times:
+ # factor of 1e-16 needed to account for annoying round-off issue to get right time slices
+ plottime = int((float(atime)/0.2 + 1e-16)*24.0)
+ ds = xr.open_dataset('output'+ fileno + '.nc')
+ print('{} {} {}'.format(atime, plottime, ds.isel(Time=plottime).xtime.values))
+ ds = ds.drop_vars(np.setdiff1d([i for i in ds.variables], ['yCell','ssh']))
+ ymean = ds.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
+ x = ymean.yCell.values/1000.0
+ y = ymean.ssh.values
+ #print('ymin={} ymax={}\n{}\n{}'.format(y.min(), y.max(),x, y))
+ plt.plot(x, -y, *args, **kwargs)
+ ds.close()
+
+
+def plot_tidal_forcing_comparison():
+ # data from MPAS-O on boundary
+ for fileno in ['']:
+ ds = xr.open_dataset('output' + fileno +'.nc')
+ ympas = ds.ssh.where(ds.tidalInputMask).mean('nCells').values
+ x = np.linspace(0, 1.0, len(ds.xtime))*12.0
+ plt.plot(x, ympas, marker='o', label='MPAS-O forward' + fileno)
+
+ # analytical case
+ x = np.linspace(0,12.0,100)
+ y = 20.0*np.sin(x*np.pi/12.0) - 10.0
+ plt.plot(x, y, lw=3, color='black', label='analytical')
+
+ plt.legend(frameon=False)
+ plt.ylabel('Tidal amplitude (m)')
+ plt.xlabel('Time (hrs)')
+ plt.suptitle('Tidal amplitude forcing (right side) for MPAS-O and analytical')
+ plt.savefig('tidalcomparison.png')
+
+
+def main():
+ ################ plot tidal forcing comparison ###############
+ plot_tidal_forcing_comparison()
+ ##############################################################
+
+ ################ plot drying front comparison ###############
+ setup_fig()
+ times = ['0.50', '0.05', '0.40', '0.15', '0.30', '0.25']
+
+ # subplot r = 0.01
+ setup_subplot()
+ plot_datasets(rval='0.01', times=times, fileno='', plotdata=False)
+
+ plt.suptitle('Drying slope for land topography')
+ for outtype in ['.png','.pdf']:
+ plt.savefig('dryingslopecomparison' + outtype)
+ ##############################################################
+
+
+if __name__ == "__main__":
+ main()
diff --git a/testing_and_setup/compass/ocean/drying_slope/forward_idealized_transect.xml b/testing_and_setup/compass/ocean/drying_slope/forward_idealized_transect.xml
new file mode 100644
index 0000000000..d1ea3a5578
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/forward_idealized_transect.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/forward_template.xml b/testing_and_setup/compass/ocean/drying_slope/forward_template.xml
index d47fb1f1e5..99427d5c1d 100644
--- a/testing_and_setup/compass/ocean/drying_slope/forward_template.xml
+++ b/testing_and_setup/compass/ocean/drying_slope/forward_template.xml
@@ -23,6 +23,7 @@
+
@@ -44,6 +45,7 @@
forcing.nc
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/forward_vegetation_properties.xml b/testing_and_setup/compass/ocean/drying_slope/forward_vegetation_properties.xml
new file mode 100644
index 0000000000..db1baf2b12
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/forward_vegetation_properties.xml
@@ -0,0 +1,24 @@
+
+
+
+ input
+ initial_only
+ forcing.nc
+
+
+
+
+
+
+
+
+ output
+ truncate
+ output.nc
+ 0000-00-00_00:12:00
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/init_idealized_transect.xml b/testing_and_setup/compass/ocean/drying_slope/init_idealized_transect.xml
new file mode 100644
index 0000000000..adf984b00c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/init_idealized_transect.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/init_template.xml b/testing_and_setup/compass/ocean/drying_slope/init_template.xml
index ed4c8e56f2..41e3b30ada 100644
--- a/testing_and_setup/compass/ocean/drying_slope/init_template.xml
+++ b/testing_and_setup/compass/ocean/drying_slope/init_template.xml
@@ -11,6 +11,7 @@
+
@@ -24,6 +25,7 @@
0000_00:00:01
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/init_vegetation_properties.xml b/testing_and_setup/compass/ocean/drying_slope/init_vegetation_properties.xml
new file mode 100644
index 0000000000..f072b0aefd
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/init_vegetation_properties.xml
@@ -0,0 +1,16 @@
+
+
+
+ output
+ forcing.nc
+ truncate
+ 0000_00:00:01
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/comparison.py b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/comparison.py
new file mode 100755
index 0000000000..8a6ec6ef54
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/comparison.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# coding: utf-8
+# Authors: Zhendong Cao, Phillip Wolfram
+# Date: May 2020
+
+# import libs
+import numpy as np
+import xarray as xr
+import matplotlib.pyplot as plt
+import os
+#import cv2
+# plot tidal amplitude at open boundary
+
+fname1 = 'NoVegetation'
+fname2 = 'ConstantVegManning'
+fname3 = 'VegManningEquation'
+
+# mpas-o
+ds1 = xr.open_dataset(fname1+'.nc')
+ds2 = xr.open_dataset(fname2+'.nc')
+ds3 = xr.open_dataset(fname3+'.nc')
+
+x = np.linspace(0, 1.0, len(ds1.xtime))*48.0
+ympas1 = ds1.ssh.where(ds1.tidalInputMask).mean('nCells').values
+ympas2 = ds2.ssh.where(ds2.tidalInputMask).mean('nCells').values
+ympas3 = ds3.ssh.where(ds3.tidalInputMask).mean('nCells').values
+
+plt.plot(x, ympas1, marker='o', label=fname1)
+plt.plot(x, ympas2, marker='^', label=fname2)
+plt.plot(x, ympas3, marker='*', label=fname3)
+
+# analytical
+x = np.linspace(0,48.0,100)
+y = 1.5*np.sin(x*np.pi/12.0) - 3.0
+plt.plot(x, y, 'k-', lw=3, label='analytical')
+
+plt.legend(frameon=False, loc='upper right', fontsize=8)
+plt.ylabel('Tidal amplitude (m)')
+plt.xlabel('Time (hrs)')
+plt.suptitle('Tidal amplitude forcing for test cases and analytical')
+plt.savefig('tidalcomparison.png',dpi=300)
+plt.close()
+
+# extract bottomDepth
+bottomDepth = ds1.bottomDepth.values.reshape((116, 4))[:,1]
+x_along = np.linspace(0,8,116)
+# plot water elevation at selected time slices
+times = np.linspace(0.0,2.0,41)
+ii = 0
+figname_prefix = 'Waterlevel'
+for atime in times:
+ plt.figure(figsize=(12,6))
+ plt.xlim(0, 8)
+ plt.ylim(-4, 0)
+ plottime = int((float(atime)/0.2)*24.0)
+ timestr = ds1.isel(Time=plottime).xtime.values
+ ymean = ds1.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
+ x = ymean.yCell.values/1000.0
+ y = ymean.ssh.values
+ plt.plot(x, y,'-k',label=fname1)
+
+ ymean = ds2.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
+ x = ymean.yCell.values/1000.0
+ y = ymean.ssh.values
+ plt.plot(x, y,'-b',label=fname2)
+
+ ymean = ds3.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
+ x = ymean.yCell.values/1000.0
+ y = ymean.ssh.values
+ plt.plot(x, y,'-g',label=fname3)
+
+ plt.fill_between(x=x_along,y1=-10*np.ones(x_along.shape), y2=-bottomDepth, color='grey',zorder=9)
+ plt.xlabel('Cross shore distance (km)')
+ plt.ylabel('Bathymetry (m)')
+ atime='%.2f'%atime
+ plt.title('time='+atime+'days')
+ plt.legend(frameon=False, loc='upper right')
+ figname = '{}{:02d}.png'.format(figname_prefix,ii)
+ plt.savefig(figname, dpi=100)
+ plt.close()
+ print('Time '+atime+ ' done!')
+ ii += 1
+# make a movie
+os.system("ffmpeg -r 1 -i Waterlevel%02d.png -vcodec mpeg4 -y movie.mp4")
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_analysis.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_analysis.xml
new file mode 100644
index 0000000000..0e7719e952
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_analysis.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+ output1.nc
+ vtk_output1
+ allOnCells
+ maxEdges=0
+ nVertLevels=0:10
+
+
+
+ output2.nc
+ vtk_output2
+ allOnCells
+ maxEdges=0
+ nVertLevels=0:10
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_driver.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_driver.xml
new file mode 100644
index 0000000000..7fa1481248
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_driver.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward1.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward1.xml
new file mode 100644
index 0000000000..49441e4608
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward1.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 36
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward2.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward2.xml
new file mode 100644
index 0000000000..00d63b2925
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward2.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 36
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward3.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward3.xml
new file mode 100644
index 0000000000..17523a4a61
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_forward3.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 36
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init1.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init1.xml
new file mode 100644
index 0000000000..9d78c2e1d3
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init1.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init2.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init2.xml
new file mode 100644
index 0000000000..8ba11a7e0b
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init2.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init3.xml b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init3.xml
new file mode 100644
index 0000000000..1795d47490
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/marsh_flooding/idealized_transect/config_init3.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/meshes/idealized_transect/config_driver.xml b/testing_and_setup/compass/ocean/drying_slope/meshes/idealized_transect/config_driver.xml
new file mode 100644
index 0000000000..e2cd1d2131
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/meshes/idealized_transect/config_driver.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/meshes/idealized_transect/config_init.xml b/testing_and_setup/compass/ocean/drying_slope/meshes/idealized_transect/config_init.xml
new file mode 100644
index 0000000000..aaf9ac4473
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/meshes/idealized_transect/config_init.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ 4
+ 116
+ 80.0
+
+ grid.nc
+
+
+ grid.nc
+ culled_mesh.nc
+
+
+ culled_mesh.nc
+ transectmesh.nc
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_analysis.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_analysis.xml
new file mode 100644
index 0000000000..bab938f3ef
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_analysis.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+ output.nc
+ vtk_output
+ allOnCells
+ maxEdges=0
+ nVertLevels=0:10
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_driver.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_driver.xml
new file mode 100644
index 0000000000..a34470b250
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_driver.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_forward.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_forward.xml
new file mode 100644
index 0000000000..7fdf0079ad
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_forward.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_init.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_init.xml
new file mode 100644
index 0000000000..2942b32514
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_above_land/1km/config_init.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/comparison.py b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/comparison.py
new file mode 100755
index 0000000000..0a4cb15021
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/comparison.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+"""
+
+Drying slope comparison betewen MPAS-O, analytical, and ROMS results from
+
+Warner, J. C., Defne, Z., Haas, K., & Arango, H. G. (2013). A wetting and
+drying scheme for ROMS. Computers & geosciences, 58, 54-61.
+
+Phillip J. Wolfram and Zhendong Cao
+04/30/2019
+
+"""
+
+import numpy as np
+import xarray as xr
+import matplotlib.pyplot as plt
+import pandas as pd
+
+# render statically by default
+plt.switch_backend('agg')
+
+def setup_fig():
+ fig, ax = plt.subplots(nrows=4,ncols=1, sharex=True, sharey=True, figsize=(6,8))
+ fig.text(0.02, 0.5, 'Channel depth (m)', va='center', rotation='vertical')
+ #fig.text(0.5, 0.02, 'Along channel distance (km)', ha='center')
+
+def setup_subplot():
+ plt.xlim(0,25)
+ plt.ylim(-1, 11)
+ ax = plt.gca()
+ ax.invert_yaxis()
+ ax.spines['top'].set_visible(False)
+ ax.spines['right'].set_visible(False)
+
+ x = np.linspace(0,25,100)
+ y = 10.0/25.0*x
+ plt.plot(x, y, 'k-', lw=3)
+
+
+def upper_plot():
+ plt.subplot(2,1,1)
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+
+
+def lower_plot():
+ plt.subplot(2,1,2)
+ setup_subplot()
+
+
+def plot_data(rval='0.0025', dtime='0.05', datatype='analytical', *args, **kwargs):
+ datafile = 'data/r' + rval + 'd' + dtime + '-' + datatype + '.csv'
+ data = pd.read_csv(datafile, header=None)
+ measured=plt.scatter(data[0], data[1], *args, **kwargs)
+
+
+def plot_datasets(rval, times, fileno, plotdata=True):
+ for ii, dtime in enumerate(times):
+ if plotdata:
+ plot_data(rval=rval, dtime = dtime, datatype = 'analytical',
+ marker = '.', color = 'b', label='analytical')
+ plot_data(rval=rval, dtime = dtime, datatype = 'roms',
+ marker = '.', color = 'g', label='ROMS')
+ plot_MPASO([dtime], fileno, 'k-', lw=0.5, label='MPAS-O')
+
+ if ii == 0:
+ plt.legend(frameon=False, loc='lower left')
+ place_time_labels(times)
+ plt.text(0.5, 5, 'Cd = ' + str(rval))
+
+
+def place_time_labels(times):
+ locs = [9.3, 7.2, 4.2, 2.2, 1.2, 0.2]
+ for atime, ay in zip(times, locs):
+ plt.text(25.2, ay, atime + ' days', size=8)
+
+def plot_MPASO(times, fileno, *args, **kwargs):
+ for atime in times:
+ # factor of 1e-16 needed to account for annoying round-off issue to get right time slices
+ plottime = int((float(atime)/0.2 + 1e-16)*24.0)
+ ds = xr.open_mfdataset('output'+ fileno + '.nc')
+ print('{} {} {}'.format(atime, plottime, ds.isel(Time=plottime).xtime.values))
+ ds = ds.drop(np.setdiff1d([i for i in ds.variables], ['yCell','ssh']))
+ ymean = ds.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
+ x = ymean.yCell.values/1000.0
+ y = ymean.ssh.values
+ #print('ymin={} ymax={}\n{}\n{}'.format(y.min(), y.max(),x, y))
+ plt.plot(x, -y, *args, **kwargs)
+ ds.close()
+
+
+def plot_tidal_forcing_comparison():
+ # data from MPAS-O on boundary
+ for fileno in ['1','2']:
+ ds = xr.open_mfdataset('output' + fileno +'.nc')
+ ympas = ds.ssh.where(ds.tidalInputMask).mean('nCells').values
+ x = np.linspace(0, 1.0, len(ds.xtime))*12.0
+ plt.plot(x, ympas, marker='o', label='MPAS-O forward' + fileno)
+
+ # analytical case
+ x = np.linspace(0,12.0,100)
+ y = 10.0*np.sin(x*np.pi/12.0) - 10.0
+ plt.plot(x, y, lw=3, color='black', label='analytical')
+
+ plt.legend(frameon=False)
+ plt.ylabel('Tidal amplitude (m)')
+ plt.xlabel('Time (hrs)')
+ plt.suptitle('Tidal amplitude forcing (right side) for MPAS-O and analytical')
+ plt.savefig('tidalcomparison.png')
+
+
+def main():
+ ################ plot tidal forcing comparison ###############
+ #plot_tidal_forcing_comparison()
+ ##############################################################
+
+ ################ plot drying front comparison ###############
+ times = ['0.50', '0.05', '0.40', '0.15', '0.30', '0.25']
+ setup_fig()
+
+ ##############################################################
+ plt.subplot(4,1,1)
+ plt.title('MPAS-O Drying slope comparison for variable Cd')
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+ plot_datasets(rval='1e-1 to 1e-2', times=times, fileno='4', plotdata=False)
+
+ plt.subplot(4,1,2)
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+ plot_datasets(rval='1e-2', times=times, fileno='2', plotdata=False)
+
+ plt.subplot(4,1,3)
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+ plot_datasets(rval='1e-2 to 1e-3', times=times, fileno='3', plotdata=False)
+
+ # subplot Cd=1e-2
+ plt.subplot(4,1,4)
+ setup_subplot()
+ plot_datasets(rval='1e-3', times=times, fileno='1', plotdata=False)
+ plt.xlabel('Along channel distance (km)')
+
+ for outtype in ['.png','.pdf']:
+ plt.savefig('dryingslopecomparison' + outtype, tight_layout=True)
+
+if __name__ == "__main__":
+ main()
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_analysis.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_analysis.xml
new file mode 100644
index 0000000000..4486af3861
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_analysis.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ output1.nc
+ vtk_output1
+ allOnCells
+ maxEdges=0
+ nVertLevels=0:10
+
+
+
+ output2.nc
+ vtk_output2
+ allOnCells
+ maxEdges=0
+ nVertLevels=0:10
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_driver.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_driver.xml
new file mode 100644
index 0000000000..e0545f3143
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_driver.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward1.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward1.xml
new file mode 100644
index 0000000000..7d0b0cfebe
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward1.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward2.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward2.xml
new file mode 100644
index 0000000000..f6a521a1d4
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward2.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward3.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward3.xml
new file mode 100644
index 0000000000..4d00eb90fc
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward3.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward4.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward4.xml
new file mode 100644
index 0000000000..78b6786916
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_forward4.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init.xml
new file mode 100644
index 0000000000..b4cbaafe9e
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init3.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init3.xml
new file mode 100644
index 0000000000..8f62cd66a9
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init3.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init4.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init4.xml
new file mode 100644
index 0000000000..9d178103e8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableCd/1km/config_init4.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/comparison.py b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/comparison.py
new file mode 100755
index 0000000000..ef9f2b295a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/comparison.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+"""
+
+Drying slope comparison betewen MPAS-O, analytical, and ROMS results from
+
+Warner, J. C., Defne, Z., Haas, K., & Arango, H. G. (2013). A wetting and
+drying scheme for ROMS. Computers & geosciences, 58, 54-61.
+
+Phillip J. Wolfram and Zhendong Cao
+04/30/2019
+
+"""
+
+import numpy as np
+import xarray as xr
+import matplotlib.pyplot as plt
+import pandas as pd
+
+# render statically by default
+plt.switch_backend('agg')
+
+def setup_fig():
+ fig, ax = plt.subplots(nrows=4,ncols=1, sharex=True, sharey=True, figsize=(6,8))
+ fig.text(0.02, 0.5, 'Channel depth (m)', va='center', rotation='vertical')
+ #fig.text(0.5, 0.02, 'Along channel distance (km)', ha='center')
+
+def setup_subplot():
+ plt.xlim(0,25)
+ plt.ylim(-1, 11)
+ ax = plt.gca()
+ ax.invert_yaxis()
+ ax.spines['top'].set_visible(False)
+ ax.spines['right'].set_visible(False)
+
+ x = np.linspace(0,25,100)
+ y = 10.0/25.0*x
+ plt.plot(x, y, 'k-', lw=3)
+
+
+def upper_plot():
+ plt.subplot(2,1,1)
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+
+
+def lower_plot():
+ plt.subplot(2,1,2)
+ setup_subplot()
+
+
+def plot_data(rval='0.0025', dtime='0.05', datatype='analytical', *args, **kwargs):
+ datafile = 'data/r' + rval + 'd' + dtime + '-' + datatype + '.csv'
+ data = pd.read_csv(datafile, header=None)
+ measured=plt.scatter(data[0], data[1], *args, **kwargs)
+
+
+def plot_datasets(rval, times, fileno, plotdata=True):
+ for ii, dtime in enumerate(times):
+ if plotdata:
+ plot_data(rval=rval, dtime = dtime, datatype = 'analytical',
+ marker = '.', color = 'b', label='analytical')
+ plot_data(rval=rval, dtime = dtime, datatype = 'roms',
+ marker = '.', color = 'g', label='ROMS')
+ plot_MPASO([dtime], fileno, 'k-', lw=0.5, label='MPAS-O')
+
+ if ii == 0:
+ plt.legend(frameon=False, loc='lower left')
+ place_time_labels(times)
+ plt.text(0.5, 5, 'n = ' + str(rval))
+
+
+def place_time_labels(times):
+ locs = [9.3, 7.2, 4.2, 2.2, 1.2, 0.2]
+ for atime, ay in zip(times, locs):
+ plt.text(25.2, ay, atime + ' days', size=8)
+
+def plot_MPASO(times, fileno, *args, **kwargs):
+ for atime in times:
+ # factor of 1e-16 needed to account for annoying round-off issue to get right time slices
+ plottime = int((float(atime)/0.2 + 1e-16)*24.0)
+ ds = xr.open_dataset('output'+ fileno + '.nc')
+ print('{} {} {}'.format(atime, plottime, ds.isel(Time=plottime).xtime.values))
+ ds = ds.drop_vars(np.setdiff1d([i for i in ds.variables], ['yCell','ssh']))
+ ymean = ds.isel(Time=plottime).groupby('yCell').mean(dim=xr.ALL_DIMS)
+ x = ymean.yCell.values/1000.0
+ y = ymean.ssh.values
+ #print('ymin={} ymax={}\n{}\n{}'.format(y.min(), y.max(),x, y))
+ plt.plot(x, -y, *args, **kwargs)
+ ds.close()
+
+
+def plot_tidal_forcing_comparison():
+ # data from MPAS-O on boundary
+ for fileno in ['1','2']:
+ ds = xr.open_dataset('output' + fileno +'.nc')
+ ympas = ds.ssh.where(ds.tidalInputMask).mean('nCells').values
+ x = np.linspace(0, 1.0, len(ds.xtime))*12.0
+ plt.plot(x, ympas, marker='o', label='MPAS-O forward' + fileno)
+
+ # analytical case
+ x = np.linspace(0,12.0,100)
+ y = 10.0*np.sin(x*np.pi/12.0) - 10.0
+ plt.plot(x, y, lw=3, color='black', label='analytical')
+
+ plt.legend(frameon=False)
+ plt.ylabel('Tidal amplitude (m)')
+ plt.xlabel('Time (hrs)')
+ plt.suptitle('Tidal amplitude forcing (right side) for MPAS-O and analytical')
+ plt.savefig('tidalcomparison.png')
+
+
+def main():
+ ################ plot tidal forcing comparison ###############
+ #plot_tidal_forcing_comparison()
+ ##############################################################
+
+ ################ plot drying front comparison ###############
+ times = ['0.50', '0.05', '0.40', '0.15', '0.30', '0.25']
+ setup_fig()
+
+ ##############################################################
+ plt.subplot(4,1,1)
+ plt.title('MPAS-O Drying slope comparison for variable Manning n')
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+ plot_datasets(rval='0.1 to 0.05', times=times, fileno='4', plotdata=False)
+
+ plt.subplot(4,1,2)
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+ plot_datasets(rval='0.05', times=times, fileno='3', plotdata=False)
+
+ plt.subplot(4,1,3)
+ plt.gca().set_xticklabels([])
+ setup_subplot()
+ plot_datasets(rval='0.05 to 0.01', times=times, fileno='2', plotdata=False)
+
+ # subplot Cd=1e-2
+ plt.subplot(4,1,4)
+ setup_subplot()
+ plot_datasets(rval='0.01', times=times, fileno='1', plotdata=False)
+ plt.xlabel('Along channel distance (km)')
+
+ for outtype in ['.png','.pdf']:
+ plt.savefig('dryingslopecomparisonManningn' + outtype, tight_layout=True)
+
+if __name__ == "__main__":
+ main()
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_analysis.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_analysis.xml
new file mode 100644
index 0000000000..9c80db2178
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_analysis.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_driver.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_driver.xml
new file mode 100644
index 0000000000..54842e5242
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_driver.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward1.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward1.xml
new file mode 100644
index 0000000000..80e9d4e525
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward1.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward2.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward2.xml
new file mode 100644
index 0000000000..416b88e0da
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward2.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward3.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward3.xml
new file mode 100644
index 0000000000..d632de095d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward3.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward4.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward4.xml
new file mode 100644
index 0000000000..7847dbabc7
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_forward4.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init.xml
new file mode 100644
index 0000000000..712c79c80a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init1.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init1.xml
new file mode 100644
index 0000000000..733717aa55
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init1.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init2.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init2.xml
new file mode 100644
index 0000000000..2b98af64e4
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init2.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init3.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init3.xml
new file mode 100644
index 0000000000..81edaf4441
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init3.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init4.xml b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init4.xml
new file mode 100644
index 0000000000..7a949e2dda
--- /dev/null
+++ b/testing_and_setup/compass/ocean/drying_slope/zstar_variableManningn/1km/config_init4.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/global_ocean/ARM60to10/init/define_base_mesh.py b/testing_and_setup/compass/ocean/global_ocean/ARM60to10/init/define_base_mesh.py
index d4d05bc1fb..4bd7564806 100755
--- a/testing_and_setup/compass/ocean/global_ocean/ARM60to10/init/define_base_mesh.py
+++ b/testing_and_setup/compass/ocean/global_ocean/ARM60to10/init/define_base_mesh.py
@@ -130,10 +130,10 @@ def plot_cartopy(nPlot, varName, var, map_name):
alpha=0.5,
linestyle='-', zorder=2)
ax.coastlines()
- gl.xlabels_top = False
- gl.xlabels_bottom = False
- gl.ylabels_right = False
- gl.ylabels_left = False
+ gl.top_labels = False
+ gl.bottom_labels = False
+ gl.right_labels = False
+ gl.left_labels = False
plt.colorbar(im, shrink=.9)
plt.title(varName)
diff --git a/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/config_base_mesh.xml
new file mode 100755
index 0000000000..5c4e244080
--- /dev/null
+++ b/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/config_base_mesh.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/config_driver_init.xml
new file mode 100644
index 0000000000..ec1eb184c8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/config_driver_init.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..e10e343db7
--- /dev/null
+++ b/testing_and_setup/compass/ocean/global_ocean/CA120to3/build_mesh/define_base_mesh.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+'''
+name: define_base_mesh
+authors: Phillip J. Wolfram
+
+This function specifies the resolution for a coastal refined mesh for the CA coast from SF to LA for
+Chris Jeffrey and Mark Galassi.
+It contains the following resolution resgions:
+ 1) a QU 120km global background resolution
+ 2) 3km refinement region along the CA coast from SF to LA, with 30km transition region
+
+'''
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ SFtoLA = {"include": [np.array([-124.0, -117.5, 34.2, 38.0])], # SF to LA
+ "exclude": [np.array([-122.1, -120.8, 37.7, 39.2])]} # SF Bay Delta
+
+ WestCoast = np.array([-136.0, -102.0, 22.0, 51])
+
+ print("****QU120 background mesh and 300m refinement from SF to LA****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 120.0 * km
+ params["region_box"] = SFtoLA
+ params["plot_box"] = WestCoast
+ params["dx_min_coastal"] = 3.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 30.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/config_base_mesh.xml
new file mode 100755
index 0000000000..5c4e244080
--- /dev/null
+++ b/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/config_base_mesh.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/config_driver_init.xml
new file mode 100644
index 0000000000..ec1eb184c8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/config_driver_init.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..7492b87619
--- /dev/null
+++ b/testing_and_setup/compass/ocean/global_ocean/HI120to12/build_mesh/define_base_mesh.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+'''
+name: define_base_mesh
+authors: Phillip J. Wolfram
+
+This function specifies a high resolution patch for
+Chris Jeffrey.
+
+'''
+import numpy as np
+
+def cellWidthVsLatLon():
+ lat = np.arange(-90, 90.01, 1.0)
+ lon = np.arange(-180, 180.01, 2.0)
+
+ km = 1000.0
+ # in kms
+ baseRes = 120.0
+ highRes = 12.0
+ latC = 20.0
+ lonC = -155.0
+ rad = 10.0
+
+ theta = np.minimum(np.sqrt(((lat-latC)*(lat-latC))[:,np.newaxis] + ((lon-lonC)*(lon-lonC))[np.newaxis,:])/rad, 1.0)
+
+ cellWidth = (baseRes*theta + (1.0-theta)*highRes)*np.ones((lon.size,lat.size))
+
+ return cellWidth, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_base_mesh.xml
deleted file mode 100755
index bc5606f2ad..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_base_mesh.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- jigsaw_to_MPAS.build_mesh
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..9177b99813
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_culled_mesh.xml
deleted file mode 100644
index 1571cf9f6a..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_culled_mesh.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- jigsaw_to_MPAS.inject_bathymetry
- culled_mesh.nc
-
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..9c49ba6246
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_driver_mesh.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_driver_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_driver.xml
deleted file mode 100644
index 765e605959..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_driver.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_driver.xml
new file mode 120000
index 0000000000..541fb6e756
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_driver.xml
@@ -0,0 +1 @@
+../../config_files/config_driver.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_init.xml
deleted file mode 100644
index c363038987..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_init.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mesh.nc
- USGS_stations.txt
- NOAA-COOPS_stations.txt
-
-
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_init.xml
new file mode 120000
index 0000000000..bf076f30f8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/config_init.xml
@@ -0,0 +1 @@
+../../config_files/config_init.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_driver.xml
new file mode 100644
index 0000000000..3bf0b55047
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_driver.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_forward.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_forward.xml
new file mode 100644
index 0000000000..e9a35e05ad
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_forward.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0009_00:00:00
+ 2012-01-01_00:00:00
+
+
+
+
+
+ 360
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_init.xml
new file mode 100644
index 0000000000..28820a032c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_init.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2012-01-01_00:00:00
+ 9.0
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_spinup.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_spinup.xml
new file mode 100644
index 0000000000..4a336d18df
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/synthetic_sandy/config_spinup.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0009_00:00:00
+ 2012-01-01_00:00:00
+
+
+
+
+
+ 360
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..db237e7535
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..38daa9cfec
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_driver_mesh.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/config_driver_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..ffd75cf45d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 120 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 120.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 30.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (10km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 10.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (2km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 2.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_driver.xml
new file mode 120000
index 0000000000..d11838e423
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_driver.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_driver.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..ca1772b126
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_forward_RK4.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 360
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_init.xml
new file mode 120000
index 0000000000..2dc0368d89
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD/sandy/config_init.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_init.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..db237e7535
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..38daa9cfec
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_driver_init.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/config_driver_init.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..ffd75cf45d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 120 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 120.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 30.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (10km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 10.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (2km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 2.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_driver.xml
new file mode 100644
index 0000000000..2bbc9940c7
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..9fc89ed3ef
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_forward_RK4.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 360
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_init.xml
new file mode 100644
index 0000000000..532d8b6659
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/config_init.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/vegetation_tif_to_mpas.config b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/vegetation_tif_to_mpas.config
new file mode 100644
index 0000000000..c13129b70c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2WD_veg/sandy/vegetation_tif_to_mpas.config
@@ -0,0 +1,19 @@
+# input tif files
+#input_location : '/lustre/scratch4/turquoise/zhendong/Delaware_Manning/'
+input_location : './'
+vegetation_mask_file : 'DelawareSM.tif'
+vegetation_height_file : 'Delaware.Height.2000-08.tif'
+vegetation_density_file : 'Delaware.Density.2000-08.tif'
+vegetation_diameter_file : 'Delaware.Size.2000-08.tif'
+Delaware_Manning_file : 'Chesapeake_and_Delaware_Bay_LambMap_DietrichN.tif'
+
+# input mpas grid file
+mpas_grid_file : 'mesh.nc'
+
+bottomDrag_file : 'forcing.nc'
+
+# output
+output_file : 'vegetationInfo_Delaware.nc'
+
+# plot and save interpolated data?
+figplot : True
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..9177b99813
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..9c49ba6246
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_driver_mesh.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/config_driver_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..56b5350cc0
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 240 background mesh and enhanced Atlantic (60km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 240.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 60.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (20km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 20.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (10km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 10.0 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (4km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 4.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_driver.xml
new file mode 100644
index 0000000000..ee0e2ef29a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_driver.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..2dc9db893d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_forward_RK4.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_forward_SE.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_forward_SE.xml
new file mode 100644
index 0000000000..8aaeaf3213
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_forward_SE.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_init.xml
new file mode 120000
index 0000000000..bf076f30f8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/sandy/config_init.xml
@@ -0,0 +1 @@
+../../config_files/config_init.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_driver.xml
new file mode 100644
index 0000000000..3bf0b55047
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_driver.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_forward.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_forward.xml
new file mode 100644
index 0000000000..055650f2a8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_forward.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0009_00:00:00
+ 2012-01-01_00:00:00
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_init.xml
new file mode 100644
index 0000000000..28820a032c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_init.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2012-01-01_00:00:00
+ 9.0
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_spinup.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_spinup.xml
new file mode 100644
index 0000000000..320ebcc0ab
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4/synthetic_sandy/config_spinup.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0009_00:00:00
+ 2012-01-01_00:00:00
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..db237e7535
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..38daa9cfec
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_driver_mesh.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/config_driver_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..56b5350cc0
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 240 background mesh and enhanced Atlantic (60km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 240.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 60.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (20km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 20.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (10km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 10.0 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (4km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 4.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_driver.xml
new file mode 120000
index 0000000000..d11838e423
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_driver.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_driver.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..1d63cbafa8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_forward_RK4.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_init.xml
new file mode 120000
index 0000000000..2dc0368d89
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/sandy/config_init.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_init.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_driver.xml
new file mode 100644
index 0000000000..3bf0b55047
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_driver.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_forward.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_forward.xml
new file mode 100644
index 0000000000..e9acddbe97
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_forward.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0009_00:00:00
+ 2012-01-01_00:00:00
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_init.xml
new file mode 100644
index 0000000000..a30482a0c1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_init.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2012-01-01_00:00:00
+ 9.0
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_spinup.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_spinup.xml
new file mode 100644
index 0000000000..e09a2a8115
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD/synthetic_sandy/config_spinup.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0009_00:00:00
+ 2012-01-01_00:00:00
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..db237e7535
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..38daa9cfec
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_driver_init.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/config_driver_init.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..56b5350cc0
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 240 background mesh and enhanced Atlantic (60km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 240.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 60.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (20km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 20.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (10km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 10.0 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (4km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 4.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_driver.xml
new file mode 100644
index 0000000000..2bbc9940c7
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..ca307f1176
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_forward_RK4.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 72
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_init.xml
new file mode 100644
index 0000000000..532d8b6659
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/config_init.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/vegetation_tif_to_mpas.config b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/vegetation_tif_to_mpas.config
new file mode 100644
index 0000000000..b146375705
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU240at60cr20rr4WD_veg/sandy/vegetation_tif_to_mpas.config
@@ -0,0 +1,18 @@
+# input tif files
+input_location : '/lustre/scratch4/turquoise/zhendong/Delaware_Manning/'
+vegetation_mask_file : 'DelawareSM.tif'
+vegetation_height_file : 'Delaware.Height.2000-08.tif'
+vegetation_density_file : 'Delaware.Density.2000-08.tif'
+vegetation_diameter_file : 'Delaware.Size.2000-08.tif'
+Delaware_Manning_file : 'Chesapeake_and_Delaware_Bay_LambMap_DietrichN.tif'
+
+# input mpas grid file
+mpas_grid_file : 'mesh.nc'
+
+bottomDrag_file : 'forcing.nc'
+
+# output
+output_file : 'vegetationInfo_Delaware.nc'
+
+# plot and save interpolated data?
+figplot : True
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_base_mesh.xml
deleted file mode 100755
index bc5606f2ad..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_base_mesh.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- jigsaw_to_MPAS.build_mesh
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..9177b99813
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_culled_mesh.xml
deleted file mode 100644
index 1571cf9f6a..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_culled_mesh.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- jigsaw_to_MPAS.inject_bathymetry
- culled_mesh.nc
-
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..9c49ba6246
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_driver_mesh.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_driver_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_driver.xml
deleted file mode 100644
index 765e605959..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_driver.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_driver.xml
new file mode 120000
index 0000000000..541fb6e756
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_driver.xml
@@ -0,0 +1 @@
+../../config_files/config_driver.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_init.xml
deleted file mode 100644
index c363038987..0000000000
--- a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_init.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mesh.nc
- USGS_stations.txt
- NOAA-COOPS_stations.txt
-
-
-
-
-
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_init.xml
new file mode 120000
index 0000000000..bf076f30f8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/sandy/config_init.xml
@@ -0,0 +1 @@
+../../config_files/config_init.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_base_mesh.xml
new file mode 100755
index 0000000000..de249353da
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_base_mesh.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+ 10.0
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_culled_mesh.xml
new file mode 100644
index 0000000000..5c62737241
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_culled_mesh.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.inject_bathymetry
+ culled_mesh.nc
+
+
+
+ --ignore_time
+ -l
+ maxEdges=0
+ allOnCells
+ culled_mesh.nc
+ culled_mesh_vtk
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_driver_init.xml
similarity index 100%
rename from testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/build_mesh/config_driver_init.xml
rename to testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/config_driver_init.xml
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..4e6b04ef2d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 60 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 60.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 15.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (5km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (2.5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 2.5 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (0.1km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 0.1 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_driver.xml
new file mode 100644
index 0000000000..be1976f5c8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_forward.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_forward.xml
new file mode 100644
index 0000000000..e15fccb393
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_forward.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 9000
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_init.xml
new file mode 100644
index 0000000000..79d4646136
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr100WD/sandy/config_init.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 144
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..db237e7535
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..38daa9cfec
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_driver_mesh.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/config_driver_mesh.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..dcb941aa2d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 60 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 60.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 15.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (5km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (2.5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 2.5 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (1km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 1.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_driver.xml
new file mode 120000
index 0000000000..d11838e423
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_driver.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_driver.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..a3a293cdee
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_forward_RK4.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1080
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_init.xml
new file mode 120000
index 0000000000..2dc0368d89
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD/sandy/config_init.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_init.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_base_mesh.xml
new file mode 120000
index 0000000000..db237e7535
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_base_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_base_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_culled_mesh.xml
new file mode 120000
index 0000000000..38daa9cfec
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_culled_mesh.xml
@@ -0,0 +1 @@
+../../config_files_WD/config_culled_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_driver_init.xml
new file mode 120000
index 0000000000..96c1be95a1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/config_driver_init.xml
@@ -0,0 +1 @@
+../../config_files/config_driver_mesh.xml
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..dcb941aa2d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 60 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 60.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 15.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (5km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (2.5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 2.5 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (1km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 1.0 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_driver.xml
new file mode 100644
index 0000000000..2bbc9940c7
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_forward_RK4.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_forward_RK4.xml
new file mode 100644
index 0000000000..8e114ddba6
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_forward_RK4.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1080
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_init.xml
new file mode 100644
index 0000000000..532d8b6659
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/config_init.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/vegetation_tif_to_mpas.config b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/vegetation_tif_to_mpas.config
new file mode 100644
index 0000000000..c13129b70c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1WD_veg/sandy/vegetation_tif_to_mpas.config
@@ -0,0 +1,19 @@
+# input tif files
+#input_location : '/lustre/scratch4/turquoise/zhendong/Delaware_Manning/'
+input_location : './'
+vegetation_mask_file : 'DelawareSM.tif'
+vegetation_height_file : 'Delaware.Height.2000-08.tif'
+vegetation_density_file : 'Delaware.Density.2000-08.tif'
+vegetation_diameter_file : 'Delaware.Size.2000-08.tif'
+Delaware_Manning_file : 'Chesapeake_and_Delaware_Bay_LambMap_DietrichN.tif'
+
+# input mpas grid file
+mpas_grid_file : 'mesh.nc'
+
+bottomDrag_file : 'forcing.nc'
+
+# output
+output_file : 'vegetationInfo_Delaware.nc'
+
+# plot and save interpolated data?
+figplot : True
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_base_mesh.xml
new file mode 100755
index 0000000000..de249353da
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_base_mesh.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+ 10.0
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_culled_mesh.xml
new file mode 100644
index 0000000000..5c62737241
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_culled_mesh.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.inject_bathymetry
+ culled_mesh.nc
+
+
+
+ --ignore_time
+ -l
+ maxEdges=0
+ allOnCells
+ culled_mesh.nc
+ culled_mesh_vtk
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_driver_init.xml
similarity index 100%
rename from testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr1/build_mesh/config_driver_init.xml
rename to testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/config_driver_init.xml
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..58e6df4a88
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 60 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 60.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 15.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (5km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (2.5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 2.5 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (0.25km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 0.25 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_driver.xml
new file mode 100644
index 0000000000..be1976f5c8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_forward.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_forward.xml
new file mode 100644
index 0000000000..545a53935f
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_forward.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2520
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_init.xml
new file mode 100644
index 0000000000..906d4d07d1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr250WD/sandy/config_init.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_base_mesh.xml
new file mode 100755
index 0000000000..de249353da
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_base_mesh.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+ 10.0
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_culled_mesh.xml
new file mode 100644
index 0000000000..5c62737241
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_culled_mesh.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.inject_bathymetry
+ culled_mesh.nc
+
+
+
+ --ignore_time
+ -l
+ maxEdges=0
+ allOnCells
+ culled_mesh.nc
+ culled_mesh_vtk
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_driver_init.xml
new file mode 100644
index 0000000000..5b34eec160
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/config_driver_init.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..67a4980a1a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/build_mesh/define_base_mesh.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 60 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 60.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 15.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (5km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 5.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware regional refinement (2.5km)****")
+ params["region_box"] = ct.Delaware_Region
+ params["plot_box"] = ct.Delaware
+ params["dx_min_coastal"] = 2.5 * km
+ params["trans_width"] = 175.0 * km
+ params["trans_start"] = 75.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ print("****Delaware Bay high-resolution (0.5km)****")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Delaware
+ params["restrict_box"] = ct.Delaware_restrict
+ params["dx_min_coastal"] = 0.5 * km
+ params["trans_width"] = 100.0 * km
+ params["trans_start"] = 17.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_driver.xml
new file mode 100644
index 0000000000..be1976f5c8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_forward.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_forward.xml
new file mode 100644
index 0000000000..cbd882545a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_forward.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1440
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_init.xml b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_init.xml
new file mode 100644
index 0000000000..906d4d07d1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/USDEQU60at15cr5rr500WD/sandy/config_init.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/config_files/config_base_mesh.xml
new file mode 100755
index 0000000000..15aee3c3cd
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files/config_base_mesh.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/config_files/config_culled_mesh.xml
new file mode 100644
index 0000000000..0fb680a0a5
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files/config_culled_mesh.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.inject_bathymetry
+ culled_mesh.nc
+
+
+ --ignore_time
+ -l
+ maxEdges=0
+ allOnCells
+ culled_mesh.nc
+ culled_mesh_vtk
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/config_files/config_driver.xml
new file mode 100644
index 0000000000..765e605959
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files/config_driver_mesh.xml b/testing_and_setup/compass/ocean/hurricane/config_files/config_driver_mesh.xml
new file mode 100644
index 0000000000..5b34eec160
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files/config_driver_mesh.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files/config_init.xml b/testing_and_setup/compass/ocean/hurricane/config_files/config_init.xml
new file mode 100644
index 0000000000..ca43dc6c9b
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files/config_init.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_base_mesh.xml b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_base_mesh.xml
new file mode 100755
index 0000000000..08fa3d10b1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_base_mesh.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+ 10.0
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_culled_mesh.xml b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_culled_mesh.xml
new file mode 100644
index 0000000000..bf1d9d2300
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_culled_mesh.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.inject_bathymetry
+ culled_mesh.nc
+
+
+ --ignore_time
+ -l
+ maxEdges=0
+ allOnCells
+ culled_mesh.nc
+ culled_mesh_vtk
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_driver.xml b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_driver.xml
new file mode 100644
index 0000000000..eb3901ef96
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_init.xml b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_init.xml
new file mode 100644
index 0000000000..906d4d07d1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/config_files_WD/config_init.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ USGS_stations.txt
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/forward_template.xml b/testing_and_setup/compass/ocean/hurricane/forward_template.xml
index c6e250d475..a39977d683 100644
--- a/testing_and_setup/compass/ocean/hurricane/forward_template.xml
+++ b/testing_and_setup/compass/ocean/hurricane/forward_template.xml
@@ -18,19 +18,23 @@
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
@@ -39,6 +43,9 @@
input.nc
+
+
+
points.nc
diff --git a/testing_and_setup/compass/ocean/hurricane/forward_variable_drag.xml b/testing_and_setup/compass/ocean/hurricane/forward_variable_drag.xml
new file mode 100644
index 0000000000..a90c6fbcd8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/forward_variable_drag.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+ input
+ initial_only
+ forcing.nc
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/forward_vegetation_drag.xml b/testing_and_setup/compass/ocean/hurricane/forward_vegetation_drag.xml
new file mode 100644
index 0000000000..f4f64fdcb5
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/forward_vegetation_drag.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ input
+ initial_only
+ forcing.nc
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/forward_wetting_drying_template.xml b/testing_and_setup/compass/ocean/hurricane/forward_wetting_drying_template.xml
new file mode 100644
index 0000000000..84e148250f
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/forward_wetting_drying_template.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/README b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/README
new file mode 100644
index 0000000000..d453cdfd07
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/README
@@ -0,0 +1,25 @@
+The code in this directory is provided by the infrastructure team (e.g. A-1) as part of the LDRD-DR project:
+Adaptation Science for Complex Natural-Engineered Systems (LDRD 20180033DR)
+
+It has been modified slightly from the original version to:
+ 1) output the wind and pressure data into the format used for time-varying atmospheric forcing in MPAS-O
+ 2) To use the initial date in the json file to create time stamps for the wind and pressure time snaps
+
+
+# Hurricane Winds
+
+A project to develop tools for creating sequences of vector wind and pressure fields from hurricane storm track data.
+
+Inputs are:
+1- json file with the hurricane TRACK (Sandy example is /data/ccia/data/forcings/hurricanes/mpaso_input/sandy/SANDY_017771.json )
+2- netcdf file with a list of long and lat of the mesh centroids (exampled used for Sandy is /data/ccia/data/forcings/hurricanes/mpaso_input/sandy/sandy.nc)
+note the file had the long not correct so the code (see note above) corrects the coordinates
+see lines 100-104 in winds_io/import_data.py
+ lon = np.array(temp_lon) - 2. * math.pi
+ for i in range(0, len(lon)):
+ if lon[i] <= -math.pi:
+ lon[i] += 2. * math.pi
+3- Holland parameter (just leave it 1 for now)
+4- Ambient pressure (constant) not need to be changed
+
+If you need to read a different list of centroids lat,long you just change the input netcdf
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/matplotlib_demo.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/matplotlib_demo.py
new file mode 100644
index 0000000000..d561d838bb
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/matplotlib_demo.py
@@ -0,0 +1,54 @@
+import sys
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib.patches import Circle
+
+def E(q, r0, x, y):
+ """Return the electric field vector E=(Ex,Ey) due to charge q at r0."""
+ den = np.hypot(x-r0[0], y-r0[1])**3
+ return q * (x - r0[0]) / den, q * (y - r0[1]) / den
+
+def example(nq):
+ # Grid of x, y points
+ nx, ny = 64, 64
+ x = np.linspace(-2, 2, nx)
+ y = np.linspace(-2, 2, ny)
+ X, Y = np.meshgrid(x, y)
+
+ # Create a multipole with nq charges of alternating sign, equally spaced
+ # on the unit circle.
+ charges = []
+ for i in range(nq):
+ q = i%2 * 2 - 1
+ charges.append((q, (np.cos(2*np.pi*i/nq), np.sin(2*np.pi*i/nq))))
+
+ # Electric field vector, E=(Ex, Ey), as separate components
+ Ex, Ey = np.zeros((ny, nx)), np.zeros((ny, nx))
+ for charge in charges:
+ ex, ey = E(*charge, x=X, y=Y)
+ Ex += ex
+ Ey += ey
+
+ fig = plt.figure()
+ ax = fig.add_subplot(111)
+
+ # Plot the streamlines with an appropriate colormap and arrow style
+ color = 2 * np.log(np.hypot(Ex, Ey))
+ ax.streamplot(x, y, Ex, Ey, color=color, linewidth=1, cmap=plt.cm.inferno,
+ density=2, arrowstyle='->', arrowsize=1.5)
+
+ # Add filled circles for the charges themselves
+ charge_colors = {True: '#aa0000', False: '#0000aa'}
+ for q, pos in charges:
+ ax.add_artist(Circle(pos, 0.05, color=charge_colors[q>0]))
+
+ ax.set_xlabel('$x$')
+ ax.set_ylabel('$y$')
+ ax.set_xlim(-2,2)
+ ax.set_ylim(-2,2)
+ ax.set_aspect('equal')
+ plt.show()
+
+if __name__=='__main__':
+ example(10)
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/simple_vector_example.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/simple_vector_example.py
new file mode 100644
index 0000000000..d22a806b0c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/simple_vector_example.py
@@ -0,0 +1,31 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+def example():
+ x,y = np.linspace(-1,1,2), np.linspace(-1,1,2)
+ A, B = np.zeros((2,2)), np.zeros((2,2))
+ A[0,0]=1
+ B[0,0]=-1
+ A[0,1]=1
+ B[0,1]=1
+ A[1,0]=-1
+ B[1,0]=-1
+ A[1,1]=-1
+ B[1,1]=1
+
+ fig = plt.figure()
+ ax = fig.add_subplot(111)
+
+ # Plot the streamlines.
+ ax.streamplot(x,y,A,B)
+
+ ax.set_xlabel('$x$')
+ ax.set_ylabel('$y$')
+ ax.set_xlim(-2,2)
+ ax.set_ylim(-2,2)
+ ax.set_aspect('equal')
+ plt.show()
+
+if __name__=='__main__':
+ example()
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/wind_vector_example.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/wind_vector_example.py
new file mode 100644
index 0000000000..0edab55dca
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/ad_hoc/wind_vector_example.py
@@ -0,0 +1,50 @@
+import sys
+import numpy as np
+import matplotlib.pyplot as plt
+#from matplotlib.patches import Circle
+import math
+
+def W(x, y):
+ """Return the wind vector given a wind speed."""
+ r = np.sqrt(x*x+y*y)
+ v = V(r)
+ if r>0:
+ costheta = x/r
+ sintheta = y/r
+ return [-sintheta*v,costheta*v]
+ else:
+ return [0,0]
+
+def V(r):
+ return 2*r*r*np.exp(-r)
+
+def example(n):
+ # Grid of x, y points
+ nx, ny = n, n
+ x = np.linspace(-2, 2, nx)
+ y = np.linspace(-2, 2, ny)
+
+ # Wind field vector components U,V
+ U, V = np.zeros((ny, nx)), np.zeros((ny, nx))
+ for j in range(ny-1,-1,-1):
+ for i in range(0,nx):
+ vv = W(x[i],y[j])
+ U[j,i]=vv[0]
+ V[j,i]=vv[1]
+
+ fig = plt.figure()
+ ax1 = fig.add_subplot(1,1,1)
+
+ # Plot the streamlines.
+ ax1.streamplot(x, y, U, V, color=np.sqrt(U*U+V*V), cmap='Spectral')
+ ax1.set_xlabel('$x$')
+ ax1.set_ylabel('$y$')
+ ax1.set_xlim(-2,2)
+ ax1.set_ylim(-2,2)
+ ax1.set_aspect('equal')
+ plt.title('Tangential Wind Vectors')
+ plt.show()
+
+if __name__=='__main__':
+ example(8)
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_inputs.txt b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_inputs.txt
new file mode 100755
index 0000000000..0ba8807765
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_inputs.txt
@@ -0,0 +1,5 @@
+SANDY_017771.json
+2 ! grid flag 1 = regular grid (need further inputs), 2 = nc file (need file name)
+mesh.nc
+1013 ! mbar, ambient pressure
+1. ! holland B parameter
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_model/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_model/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_model/hurricane.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_model/hurricane.py
new file mode 100644
index 0000000000..b83db9506f
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/hurricane_model/hurricane.py
@@ -0,0 +1,18 @@
+import datetime
+
+class Hurricane:
+ def __init__(self, center: tuple, extent: float, pcentral: float, deltap: float,
+ vmax: float, b: float, time: float, initial_datetime: datetime.datetime):
+ self.center = center # Position of the eye (lon,lat) in radians as tuple.
+ self.extent = extent # The maximum extent of the hurricane in kilometers.
+ self.vforward = [] # Forward velocity [ve, vn] in km/hr.
+ self.pcentral = pcentral # Central pressure in millibars.
+ self.deltap = deltap # Pressure difference in millibars.
+ self.vmax = vmax # The maximum gradient wind [ve, vn] in km/hr.
+ self.b = b # The Holland parameter, conventionally in the range [0.5,2.5]
+ self.time = time # Time of this trajectory point in hours.
+ self.ref_time = initial_datetime
+
+
+ def set_vf(self, vf: tuple):
+ self.vforward = vf
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/main.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/main.py
new file mode 100644
index 0000000000..214aec8e20
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/main.py
@@ -0,0 +1,73 @@
+from winds_io import import_data
+from winds_io import output_data
+from structures import geogrid
+import sys
+import numpy as np
+from winds import parameters
+from winds import wind_model
+
+def sim_hurricane():
+ # Read in the input file to check which grid we are using
+ print('Import user inputs')
+ traj_filename, grid_flag, grid_filename, ambient_pressure, holland_b_param = \
+ import_data.read_input_file('hurricane_inputs.txt')
+
+ # Read grid-specific parameters and create grid
+ print('Read-in grid')
+ grid = import_data.initialize_grid(grid_filename, grid_flag)
+
+ # Read hurricane trajectory and set hurricane parameters
+ print('Initialize hurricane trajectory data')
+ curr_hurricane = import_data.initialize_hurricane(traj_filename, ambient_pressure, holland_b_param)
+
+ # Define parameters
+ print('Define parameters')
+ params = define_params(curr_hurricane)
+
+ # Compute winds on grid
+ print('Compute winds')
+ winds = compute_winds(curr_hurricane, params, grid)
+
+ # Output results
+ print('Output results')
+ output_data.write_netcdf('out.nc', curr_hurricane, grid, winds)
+
+def compute_winds(curr_hurricane, params, grid: geogrid):
+ ntimes = len(curr_hurricane) - 1
+ mywinds = []
+ for it in range(0, ntimes):
+ print('Time iteration %d / %d' % (it + 1, len(curr_hurricane) - 1))
+ mywinds.append(wind_model.WindModel(params, curr_hurricane[it], grid))
+
+ return mywinds
+
+def define_params(curr_hurricane):
+ lat = []
+ for i in range(0, len(curr_hurricane)):
+ lat.append(curr_hurricane[i].center[1])
+ return parameters.Parameters(np.mean(lat))
+
+
+if __name__ == "__main__":
+ sim_hurricane()
+
+ print('Program executed succesfully')
+ sys.exit(0)
+ # # Read in the input file to check which grid we are using
+ # traj_filename, grid_flag, grid_filename = import_data.read_input_file('hurricane_inputs.txt')
+ #
+ # # Read hurricane trajectory
+ # traj = import_data.read_json(traj_filename)
+ #
+ # # Create trajectory object
+ # curr_hurricane = initialize_hurricane(traj)
+ #
+ # # Read grid-specific parameters
+ # if grid_flag == 1:
+ # xll, yll, cellsize, numcells_lat, numcells_lon = import_data.read_raster_inputs(grid_filename)
+ # else:
+ # coord = import_data.read_netcdf(grid_filename)
+
+ # Create the grid
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/plot_winds_on_mpaso_mesh.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/plot_winds_on_mpaso_mesh.py
new file mode 100644
index 0000000000..7ae696f1bb
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/plot_winds_on_mpaso_mesh.py
@@ -0,0 +1,64 @@
+# Author: Steven Brus
+# Date: April, 2020
+# Description: Plots syntetic wind/pressure timeseries on MPAS-O mesh
+
+import netCDF4
+import matplotlib.pyplot as plt
+import numpy as np
+import os
+import cartopy
+import cartopy.crs as ccrs
+import cartopy.feature as cfeature
+plt.switch_backend('agg')
+cartopy.config['pre_existing_data_dir'] = \
+ os.getenv('CARTOPY_DIR', cartopy.config.get('pre_existing_data_dir'))
+
+#######################################################################
+#######################################################################
+
+def plot_data(lon_grid,lat_grid,data,var_label,var_abrev,time):
+
+ fig = plt.figure()
+ ax1 = fig.add_subplot(1,1,1,projection=ccrs.PlateCarree())
+ levels = np.linspace(np.amin(data),np.amax(data),100)
+ cf = ax1.tricontourf(lon_grid,lat_grid,data,levels=levels,transform=ccrs.PlateCarree())
+ ax1.set_extent([0, 359.9, -90, 90], crs=ccrs.PlateCarree())
+ ax1.add_feature(cfeature.LAND, zorder=100)
+ ax1.add_feature(cfeature.LAKES, alpha=0.5, zorder=101)
+ ax1.add_feature(cfeature.COASTLINE, zorder=101)
+ ax1.set_title('interpolated data '+time.strip())
+ cbar = fig.colorbar(cf,ax=ax1)
+ cbar.set_label(var_label)
+
+ # Save figure
+ fig.tight_layout()
+ fig.savefig(var_abrev+'_'+str(i).zfill(4)+'.png',box_inches='tight')
+ plt.close()
+
+#######################################################################
+#######################################################################
+
+if __name__ == '__main__':
+
+ grid_file = 'mesh.nc'
+ data_file = 'out.nc'
+
+ grid_nc = netCDF4.Dataset(grid_file,'r')
+ lon_grid = grid_nc.variables['lonCell'][:]*180.0/np.pi
+ lat_grid = grid_nc.variables['latCell'][:]*180.0/np.pi
+
+ data_nc = netCDF4.Dataset(data_file,'r')
+ u_data = data_nc.variables['windSpeedU'][:]
+ v_data = data_nc.variables['windSpeedV'][:]
+ p_data = data_nc.variables['atmosPressure'][:]
+ xtime = data_nc.variables['xtime'][:]
+
+ for i in range(u_data.shape[0]-1):
+
+ print('Plotting vel: '+str(i))
+
+ data = np.sqrt(np.square(u_data[i,:]) + np.square(v_data[i,:]))
+ time_ls = [x.decode("utf-8") for x in xtime[i]]
+ time = ''.join(time_ls)
+ plot_data(lon_grid,lat_grid,data,'velocity magnitude','vel',time)
+ plot_data(lon_grid,lat_grid,p_data[i,:],'atmospheric pressure','pres',time)
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/profile_model/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/profile_model/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/profile_model/radialprofiles.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/profile_model/radialprofiles.py
new file mode 100644
index 0000000000..b9afede707
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/profile_model/radialprofiles.py
@@ -0,0 +1,73 @@
+import numpy as np
+import math
+
+class RadialProfile():
+
+ def __init__(self,n,extent):
+ self.profile = np.zeros(n,dtype=np.float64)
+ self.rvals = np.zeros(n,dtype=np.float64)
+ self.n = n
+ self.extent = extent
+ self.dr = extent/(n-1)
+ for i in range(0,n):
+ self.rvals[i] = i*self.dr
+
+ def getValue(self,r):
+ if r<0 or r>self.extent:
+ return 0.0
+ else:
+ k = int(r/self.dr)
+ return self.rvals[k]
+
+class PressureProfile(RadialProfile):
+ def __init__(self,n,extent,pcentral,deltap,rmax):
+ super().__init__(n,extent)
+ self.pcentral = pcentral
+ self.deltap = deltap
+ self.rmax = rmax
+
+class HollandPressureProfile(PressureProfile):
+ def __init__(self,n,extent,pcentral,deltap,rmax,b):
+ super().__init__(n,extent,pcentral,deltap,rmax)
+ self.b = b
+ for i in range(0,self.n):
+ r = self.rvals[i]
+ if r>0:
+ p = self.pcentral + self.deltap*math.exp(-pow(self.rmax/r,b))
+ else:
+ p = pcentral
+ self.profile[i] = p
+
+class WindSpeedProfile(RadialProfile):
+ def __init__(self,n,extent,rmax):
+ super().__init__(n,extent)
+ self.rmax = rmax
+ self.vmax = 0
+
+ def getVmax(self):
+ if self.vmax==0:
+ for i in range(0,self.n):
+ self.vmax = max(self.vmax,self.profile[i])
+ return self.vmax
+
+class HollandWindSpeedProfile(WindSpeedProfile):
+ def __init__(self,n,extent,rmax,deltap,rho,f,b,coriolis=False):
+ super().__init__(n,extent,rmax)
+ self.units_factor = 100 # To convert the leading term to m/s
+ # This factor comes from adopting millibars instead of Pascals, and km/hr instead of m/s.
+ self.deltap = deltap
+ self.rho = rho
+ self.f = f
+ self.b = b
+ for i in range(0,self.n):
+ r = self.rvals[i]
+ if r>0:
+ y = pow(rmax/r,b)
+ exp_term = self.units_factor*(deltap/rho)*b*y*math.exp(-y)
+ if coriolis == True:
+ v = math.sqrt(exp_term + 0.25*pow(r,2)*pow(f,2))+0.5*r*f
+ else:
+ v = math.sqrt(exp_term)
+ else:
+ v = 0.0
+ self.profile[i] = v * 3.6 # to convert to km/h
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/structures/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/structures/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/structures/geogrid.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/structures/geogrid.py
new file mode 100644
index 0000000000..83ba15e484
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/structures/geogrid.py
@@ -0,0 +1,89 @@
+import numpy as np
+
+class GeoGrid:
+ def __init__(self, lon: np.ndarray, lat: np.ndarray):
+ """
+ Constructor.
+ :param lon: longitude of the grid in radians, as numpy array
+ :param lat: latitude of the grid in radians, as numpy array
+ """
+ self.lon = lon
+ self.lat = lat
+ self.ncells = len(lon)
+
+
+
+
+ # '''
+ # A class that defines the structure, location, extent, and resolution of a geographic grid.
+ # The grid is not the same as a geospatial raster, but is related in that, while a raster numbers vertical cells
+ # starting from the top of the raster, the grid cells are numbered from the bottom. That is, a raster is oriented
+ # like a raster of pixels, while the geographic grid is oriented like a regular Cartesian grid of cells. The
+ # data in the grid is contained in a two-dimensional NumPy array. Because of this, the grid cell is indexed like
+ # a Fortran array (column major indexing, i.e. i=column, j=row).
+ # '''
+ # def __init__(self, lon, lat, nlon, nlat, cellsize, defaultValue=0.0):
+ # '''
+ # Constructor.
+ # :param lon: Lower-left longitude of the grid in decimal degrees.
+ # :param lat: Lower-left latitude of the grid in decimal degrees.
+ # :param nlon: The number of cells in longitude.
+ # :param nlat: The number of cells in latitude.
+ # :param cellsize: The size of a cell in the grid.
+ # '''
+ # self.lon = lon
+ # self.lat = lat
+ # self.nlon = nlon
+ # self.nlat = nlat
+ # self.cellsize = cellsize
+ # self.defaultValue = defaultValue
+ # self.grid = np.zeros([nlat,nlon],dtype=np.float64)
+ # self.bounds = [self.lon, self.lon + self.nlon*self.cellsize,
+ # self.lat, self.lat + self.nlat*self.cellsize]
+ #
+ #
+ # def put(self,i,j,v):
+ # if self.indexInside(i,j):
+ # self.grid[self.nlat-j-1,i]=v
+ #
+ # def getByIndex(self,i,j):
+ # if self.indexInside(i,j):
+ # return self.grid[self.nlat-j-1,i]
+ # else:
+ # return self.defaultValue
+ #
+ # def getByCoordinate(self,lon,lat):
+ # if self.coordinateInside(lon,lat):
+ # index = self.getIndex(lon,lat)
+ # return self.getByIndex(index[0],index[1])
+ # else:
+ # return self.defaultValue
+ #
+ # def clear(self):
+ # self.grid.fill(0.0)
+ #
+ # def indexInside(self,i,j):
+ # if i>=0 and i=0 and j=self.bounds[0] and lon<=self.bounds[1] and lat>=self.bounds[2] and lat<=self.bounds[3]:
+ # return True
+ # else:
+ # return False
+ #
+ # def getOrigin(self):
+ # return [self.lon,self.lat]
+ #
+ # def getCenter(self,i,j):
+ # clon = self.lon + (i+0.5)*self.cellsize
+ # clat = self.lat + (j+0.5)*self.cellsize
+ # return [clon,clat]
+ #
+ # def getIndex(self,lon,lat):
+ # i = int((lon-self.lon)/self.cellsize)
+ # j = int((lat-self.lat)/self.cellsize)
+ # return [i,j]
+ #
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/surface_model/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/surface_model/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/hurricane/test_hurricane.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/hurricane/test_hurricane.py
new file mode 100644
index 0000000000..a1241f3e6e
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/hurricane/test_hurricane.py
@@ -0,0 +1,26 @@
+import pytest
+from hurricane_model.hurricane import Hurricane
+
+def test_hurricane():
+ center = [1.0,2.0] # Position of the eye (lon,lat) in decimal degrees.
+ extent = 100.0 # The maximum extent of the hurricane in kilometers.
+ vforward = [3.0, 4.0] # Forward velocity [ve, vn] in km/hr.
+ pcentral = 200.0 # Central pressure in millibars.
+ deltap = 50.0 # Pressure difference in millibars.
+ vmax = 15.0 # The maximum gradient wind speed in km/hr.
+ b = 1.2 # The Holland parameter, conventionally in the range [0.5,2.5].
+
+ hurricane = Hurricane(center,extent)
+ hurricane.setVForward(vforward[0],vforward[1])
+ hurricane.setPCentral(pcentral)
+ hurricane.setDeltaP(deltap)
+ hurricane.setVMax(vmax)
+ hurricane.setB(b)
+
+ assert hurricane.center == center
+ assert hurricane.extent == extent
+ assert hurricane.vforward == vforward
+ assert hurricane.pcentral == pcentral
+ assert hurricane.deltap == deltap
+ assert hurricane.vmax == vmax
+ assert hurricane.b == b
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/structures/test_geogrid.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/structures/test_geogrid.py
new file mode 100644
index 0000000000..a42a5b54a6
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/structures/test_geogrid.py
@@ -0,0 +1,95 @@
+from structures.geogrid import GeoGrid
+
+def test_geogrid():
+ lon = -106.0
+ lat = 35
+ nlon = 8
+ nlat = 4
+ cellsize = 1.0
+ defaultValue = -1.0
+ grid = GeoGrid(lon,lat,nlon,nlat,cellsize,defaultValue = defaultValue)
+ assert grid.lon == lon
+ assert grid.lat == lat
+ assert grid.nlon == nlon
+ assert grid.nlat == nlat
+ assert grid.cellsize == cellsize
+ assert defaultValue == defaultValue
+
+ l = int(nlat/2)
+ k = int(nlon/2)
+ for j in range(0,l):
+ for i in range(0,k):
+ grid.put(i,j,1.0)
+ for i in range(k,nlon):
+ grid.put(i,j,2.0)
+ for j in range(l,nlat):
+ for i in range(0,k):
+ grid.put(i,j,3.0)
+ for i in range(k,nlon):
+ grid.put(i,j,4.0)
+
+ for j in range(0,l):
+ for i in range(0,k):
+ assert grid.getByIndex(i,j) == 1.0
+ for i in range(k,nlon):
+ assert grid.getByIndex(i,j) == 2.0
+ for j in range(l,nlat):
+ for i in range(0,k):
+ assert grid.getByIndex(i,j) == 3.0
+ for i in range(k,nlon):
+ assert grid.getByIndex(i,j) == 4.0
+
+ testcell = [3,3]
+ center = grid.getCenter(testcell[0],testcell[1])
+ centerx = lon + (testcell[0]+0.5)*cellsize
+ centery = lat + (testcell[1]+0.5)*cellsize
+ assert center[0] == centerx
+ assert center[1] == centery
+
+ index = grid.getIndex(centerx,centery)
+ assert index[0] == testcell[0]
+ assert index[1] == testcell[1]
+
+ value = grid.getByIndex(testcell[0],testcell[1])
+ testcoords = grid.getCenter(testcell[0],testcell[1])
+ valuec = grid.getByCoordinate(testcoords[0],testcoords[1])
+ assert value == valuec
+
+ origin = grid.getOrigin()
+ assert origin[0] == lon
+ assert origin[1] == lat
+
+ bounds = grid.bounds
+ assert bounds[0] == lon
+ assert bounds[1] == lon + nlon*cellsize
+ assert bounds[2] == lat
+ assert bounds[3] == lat + nlat*cellsize
+
+ assert grid.indexInside(-1,l) == False
+ assert grid.indexInside(k,l) == True
+ assert grid.indexInside(nlon,l) == False
+ assert grid.indexInside(k,-1) == False
+ assert grid.indexInside(k,l) == True
+ assert grid.indexInside(k,nlat) == False
+
+ assert grid.coordinateInside(bounds[0]+cellsize,bounds[2]+cellsize) == True
+ assert grid.coordinateInside(bounds[0]-cellsize,bounds[2]+cellsize) == False
+ assert grid.coordinateInside(bounds[0]+cellsize,bounds[2]-cellsize) == False
+
+ assert grid.coordinateInside(bounds[1]-cellsize,bounds[2]+cellsize) == True
+ assert grid.coordinateInside(bounds[1]-cellsize,bounds[2]-cellsize) == False
+ assert grid.coordinateInside(bounds[1]+cellsize,bounds[2]+cellsize) == False
+
+ assert grid.coordinateInside(bounds[0]+cellsize,bounds[3]-cellsize) == True
+ assert grid.coordinateInside(bounds[0]+cellsize,bounds[3]+cellsize) == False
+ assert grid.coordinateInside(bounds[0]-cellsize,bounds[3]+cellsize) == False
+
+ assert grid.coordinateInside(bounds[1]-cellsize,bounds[3]-cellsize) == True
+ assert grid.coordinateInside(bounds[1]-cellsize,bounds[3]+cellsize) == False
+ assert grid.coordinateInside(bounds[1]+cellsize,bounds[3]-cellsize) == False
+
+ grid.clear()
+ for j in range(0,nlat):
+ for i in range(0,nlon):
+ assert grid.getByIndex(i,j) == 0.0
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/utils/test_gis.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/utils/test_gis.py
new file mode 100644
index 0000000000..20d21f3c8b
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/utils/test_gis.py
@@ -0,0 +1,11 @@
+from geopy.distance import geodesic
+from utils.gis import geodistkm
+
+def test_gis():
+ albuquerque = [35.0844, -106.6504] #(lat,lon)
+ los_alamos = [35.8800, -106.3031] #(lat,lon)
+
+ result1 = geodesic(albuquerque,los_alamos).km
+ result2 = geodistkm(albuquerque[1],albuquerque[0],los_alamos[1],los_alamos[0])
+
+ assert result1 == result2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_parameters.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_parameters.py
new file mode 100644
index 0000000000..9548d921b1
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_parameters.py
@@ -0,0 +1,24 @@
+from winds.wind_model import PROFILE_TYPE
+from winds.parameters import Parameters
+import math
+
+def test_parameters():
+ gridsize = [10, 10]
+ nr = 100
+ wind_profile_type = PROFILE_TYPE.HOLLAND
+ grid_position = [-106.0,35.0]
+ cellsize = 2.0
+ siderealDay = 23.934 # A sidereal day in hrs.
+ omega = 2.0 * math.pi / siderealDay # The Earth's rotation rate in rad/hr.
+ rho = 1.225e9 # Air density at sea level in kg/m^3.
+ distance_unit = 'kilometers'
+ time_unit = 'hours'
+ pressure_unit = 'millibars'
+ # The Coriolis parameter should be 2*omega*sin(pi*|phi|/360), for phi in degrees latitude [-90,90].
+
+ params = Parameters(gridsize,nr,wind_profile_type)
+
+
+
+def eval_coriolis(lat,omega):
+ return 2*omega * math.sin(math.pi*math.fabs(lat)/360)
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocities.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocities.py
new file mode 100644
index 0000000000..479213735d
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocities.py
@@ -0,0 +1,23 @@
+from winds.velocities import Velocities
+import math
+
+def test_velocities():
+ # Forward velocity in km/hr.
+ vfe = -1.0 # Eastward .
+ vfn = 0.0 # Northward.
+ vg = 1.0 # Tangential gradient wind speed in km/hr.
+
+ veloc = Velocities(vfe,vfn)
+ r = 1.0 # Unit circle about the origin.
+ np = 360
+ dtheta = 2*math.pi/np
+ with open('test_velocities_out.csv','wt') as out:
+ out.write('x,y,vx,vy,r,theta_degrees\n')
+ for i in range(0,np):
+ theta = i*dtheta
+ degrees = 180.0*theta/math.pi
+ x = r*math.cos(theta)
+ y = r*math.sin(theta)
+ v = veloc.compute_wind_vector(vg,x,y)
+ out.write(str(x)+','+str(y)+','+str(v[0])+','+str(v[1])+','+str(r)+','+str(degrees)+'\n')
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocities_out.csv b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocities_out.csv
new file mode 100644
index 0000000000..6271e49f67
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocities_out.csv
@@ -0,0 +1,361 @@
+x,y,vx,vy,r,theta_degrees
+1.0,0.0,-1.0,1.0,1.0,0.0
+0.9998476951563913,0.01745240643728351,-1.0174524064372834,0.9998476951563913,1.0,1.0
+0.9993908270190958,0.03489949670250097,-1.034899496702501,0.9993908270190958,1.0,2.0
+0.9986295347545738,0.052335956242943835,-1.0523359562429437,0.9986295347545739,1.0,3.0
+0.9975640502598242,0.0697564737441253,-1.0697564737441254,0.9975640502598243,1.0,4.0
+0.9961946980917455,0.08715574274765817,-1.0871557427476581,0.9961946980917455,1.0,5.0
+0.9945218953682733,0.10452846326765347,-1.1045284632676535,0.9945218953682734,1.0,6.0
+0.992546151641322,0.12186934340514748,-1.1218693434051474,0.9925461516413221,1.0,7.0
+0.9902680687415704,0.13917310096006544,-1.1391731009600654,0.9902680687415704,1.0,8.0
+0.9876883405951378,0.15643446504023087,-1.156434465040231,0.9876883405951378,1.0,9.0
+0.984807753012208,0.17364817766693033,-1.1736481776669303,0.9848077530122081,1.0,10.0
+0.981627183447664,0.1908089953765448,-1.1908089953765448,0.981627183447664,1.0,10.999999999999998
+0.9781476007338057,0.20791169081775934,-1.2079116908177594,0.9781476007338057,1.0,12.0
+0.9743700647852352,0.224951054343865,-1.224951054343865,0.9743700647852352,1.0,13.000000000000002
+0.9702957262759965,0.24192189559966773,-1.2419218955996678,0.9702957262759965,1.0,14.0
+0.9659258262890683,0.25881904510252074,-1.2588190451025207,0.9659258262890683,1.0,14.999999999999998
+0.9612616959383189,0.27563735581699916,-1.275637355816999,0.9612616959383189,1.0,16.0
+0.9563047559630354,0.29237170472273677,-1.2923717047227368,0.9563047559630354,1.0,17.0
+0.9510565162951535,0.3090169943749474,-1.3090169943749475,0.9510565162951536,1.0,18.0
+0.9455185755993168,0.3255681544571567,-1.3255681544571567,0.9455185755993168,1.0,19.0
+0.9396926207859084,0.3420201433256687,-1.3420201433256687,0.9396926207859084,1.0,20.0
+0.9335804264972017,0.35836794954530027,-1.3583679495453003,0.9335804264972017,1.0,21.0
+0.9271838545667874,0.374606593415912,-1.374606593415912,0.9271838545667874,1.0,21.999999999999996
+0.9205048534524404,0.39073112848927377,-1.3907311284892738,0.9205048534524404,1.0,23.0
+0.9135454576426009,0.4067366430758002,-1.4067366430758002,0.913545457642601,1.0,24.0
+0.9063077870366499,0.42261826174069944,-1.4226182617406995,0.9063077870366499,1.0,25.0
+0.898794046299167,0.4383711467890774,-1.4383711467890774,0.898794046299167,1.0,26.000000000000004
+0.8910065241883679,0.45399049973954675,-1.4539904997395467,0.8910065241883679,1.0,27.0
+0.882947592858927,0.4694715627858908,-1.4694715627858908,0.882947592858927,1.0,28.0
+0.8746197071393957,0.48480962024633706,-1.4848096202463372,0.8746197071393959,1.0,29.0
+0.8660254037844387,0.49999999999999994,-1.5,0.8660254037844387,1.0,29.999999999999996
+0.8571673007021123,0.5150380749100542,-1.5150380749100543,0.8571673007021123,1.0,31.0
+0.848048096156426,0.5299192642332049,-1.529919264233205,0.848048096156426,1.0,32.0
+0.838670567945424,0.5446390350150271,-1.544639035015027,0.838670567945424,1.0,33.0
+0.8290375725550417,0.5591929034707469,-1.559192903470747,0.8290375725550417,1.0,34.0
+0.8191520442889918,0.573576436351046,-1.573576436351046,0.8191520442889919,1.0,35.0
+0.8090169943749475,0.5877852522924731,-1.5877852522924731,0.8090169943749475,1.0,36.0
+0.7986355100472928,0.6018150231520483,-1.6018150231520483,0.7986355100472928,1.0,37.0
+0.7880107536067219,0.6156614753256583,-1.6156614753256582,0.7880107536067219,1.0,38.0
+0.7771459614569709,0.6293203910498374,-1.6293203910498373,0.7771459614569709,1.0,39.0
+0.766044443118978,0.6427876096865393,-1.6427876096865393,0.7660444431189781,1.0,40.0
+0.754709580222772,0.6560590289905073,-1.6560590289905073,0.754709580222772,1.0,41.0
+0.7431448254773942,0.6691306063588582,-1.6691306063588582,0.7431448254773942,1.0,42.0
+0.7313537016191705,0.6819983600624985,-1.6819983600624986,0.7313537016191706,1.0,43.00000000000001
+0.7193398003386512,0.6946583704589973,-1.6946583704589973,0.7193398003386512,1.0,43.99999999999999
+0.7071067811865476,0.7071067811865476,-1.7071067811865475,0.7071067811865476,1.0,45.0
+0.6946583704589973,0.7193398003386512,-1.719339800338651,0.6946583704589973,1.0,46.0
+0.6819983600624985,0.7313537016191705,-1.7313537016191707,0.6819983600624986,1.0,47.0
+0.6691306063588582,0.7431448254773942,-1.7431448254773942,0.6691306063588582,1.0,48.0
+0.6560590289905073,0.754709580222772,-1.7547095802227721,0.6560590289905073,1.0,49.0
+0.6427876096865394,0.766044443118978,-1.766044443118978,0.6427876096865394,1.0,50.0
+0.6293203910498375,0.7771459614569709,-1.777145961456971,0.6293203910498375,1.0,51.0
+0.6156614753256583,0.788010753606722,-1.788010753606722,0.6156614753256583,1.0,52.00000000000001
+0.6018150231520484,0.7986355100472928,-1.7986355100472928,0.6018150231520484,1.0,53.0
+0.5877852522924731,0.8090169943749475,-1.8090169943749475,0.5877852522924731,1.0,54.0
+0.573576436351046,0.8191520442889918,-1.819152044288992,0.5735764363510462,1.0,55.0
+0.5591929034707468,0.8290375725550417,-1.8290375725550416,0.5591929034707468,1.0,56.0
+0.5446390350150271,0.838670567945424,-1.838670567945424,0.5446390350150271,1.0,57.00000000000001
+0.5299192642332049,0.8480480961564261,-1.848048096156426,0.5299192642332049,1.0,58.0
+0.5150380749100542,0.8571673007021123,-1.8571673007021123,0.5150380749100542,1.0,59.00000000000001
+0.5000000000000001,0.8660254037844386,-1.8660254037844386,0.5000000000000001,1.0,59.99999999999999
+0.4848096202463371,0.8746197071393957,-1.8746197071393957,0.4848096202463371,1.0,61.0
+0.46947156278589086,0.8829475928589269,-1.882947592858927,0.46947156278589086,1.0,62.0
+0.4539904997395468,0.8910065241883678,-1.8910065241883678,0.45399049973954686,1.0,63.0
+0.43837114678907746,0.898794046299167,-1.898794046299167,0.43837114678907746,1.0,64.0
+0.42261826174069944,0.9063077870366499,-1.90630778703665,0.42261826174069944,1.0,65.0
+0.4067366430758002,0.9135454576426009,-1.913545457642601,0.40673664307580026,1.0,66.0
+0.3907311284892737,0.9205048534524404,-1.9205048534524405,0.3907311284892737,1.0,67.00000000000001
+0.37460659341591196,0.9271838545667874,-1.9271838545667874,0.37460659341591196,1.0,68.0
+0.3583679495453004,0.9335804264972017,-1.9335804264972016,0.3583679495453004,1.0,68.99999999999999
+0.3420201433256688,0.9396926207859083,-1.9396926207859084,0.3420201433256689,1.0,70.0
+0.32556815445715676,0.9455185755993167,-1.945518575599317,0.3255681544571568,1.0,71.0
+0.30901699437494745,0.9510565162951535,-1.9510565162951536,0.3090169943749475,1.0,72.0
+0.29237170472273677,0.9563047559630354,-1.9563047559630355,0.29237170472273677,1.0,73.0
+0.27563735581699916,0.9612616959383189,-1.961261695938319,0.27563735581699916,1.0,74.0
+0.25881904510252074,0.9659258262890683,-1.9659258262890682,0.25881904510252074,1.0,75.00000000000001
+0.24192189559966767,0.9702957262759965,-1.9702957262759964,0.24192189559966767,1.0,76.0
+0.22495105434386492,0.9743700647852352,-1.9743700647852354,0.22495105434386492,1.0,77.00000000000001
+0.20791169081775945,0.9781476007338056,-1.9781476007338057,0.20791169081775945,1.0,78.0
+0.19080899537654492,0.981627183447664,-1.981627183447664,0.19080899537654492,1.0,79.0
+0.17364817766693041,0.984807753012208,-1.9848077530122081,0.17364817766693044,1.0,80.0
+0.15643446504023092,0.9876883405951378,-1.9876883405951378,0.15643446504023092,1.0,81.0
+0.13917310096006547,0.9902680687415704,-1.9902680687415704,0.13917310096006547,1.0,82.0
+0.12186934340514749,0.992546151641322,-1.992546151641322,0.12186934340514749,1.0,83.00000000000001
+0.10452846326765346,0.9945218953682733,-1.9945218953682735,0.10452846326765347,1.0,84.0
+0.08715574274765814,0.9961946980917455,-1.9961946980917455,0.08715574274765814,1.0,85.0
+0.06975647374412523,0.9975640502598242,-1.9975640502598244,0.06975647374412525,1.0,86.00000000000001
+0.052335956242943966,0.9986295347545738,-1.998629534754574,0.05233595624294397,1.0,87.0
+0.03489949670250108,0.9993908270190958,-1.9993908270190959,0.03489949670250108,1.0,87.99999999999999
+0.0174524064372836,0.9998476951563913,-1.9998476951563913,0.0174524064372836,1.0,89.0
+6.123233995736766e-17,1.0,-2.0,6.123233995736766e-17,1.0,90.0
+-0.017452406437283477,0.9998476951563913,-1.9998476951563913,-0.017452406437283477,1.0,91.0
+-0.034899496702500955,0.9993908270190958,-1.9993908270190959,-0.034899496702500955,1.0,92.0
+-0.05233595624294384,0.9986295347545738,-1.998629534754574,-0.05233595624294385,1.0,93.00000000000001
+-0.06975647374412533,0.9975640502598242,-1.9975640502598244,-0.06975647374412534,1.0,94.0
+-0.08715574274765824,0.9961946980917455,-1.9961946980917455,-0.08715574274765824,1.0,95.0
+-0.10452846326765355,0.9945218953682733,-1.9945218953682735,-0.10452846326765357,1.0,96.0
+-0.12186934340514737,0.9925461516413221,-1.992546151641322,-0.12186934340514737,1.0,97.0
+-0.13917310096006535,0.9902680687415704,-1.9902680687415704,-0.13917310096006535,1.0,98.0
+-0.1564344650402308,0.9876883405951378,-1.9876883405951378,-0.1564344650402308,1.0,99.00000000000001
+-0.1736481776669303,0.984807753012208,-1.9848077530122081,-0.17364817766693033,1.0,100.0
+-0.1908089953765448,0.981627183447664,-1.981627183447664,-0.1908089953765448,1.0,101.0
+-0.20791169081775934,0.9781476007338057,-1.9781476007338057,-0.20791169081775934,1.0,102.0
+-0.22495105434386503,0.9743700647852352,-1.9743700647852354,-0.22495105434386503,1.0,103.00000000000001
+-0.24192189559966779,0.9702957262759965,-1.9702957262759964,-0.24192189559966779,1.0,104.00000000000001
+-0.25881904510252085,0.9659258262890683,-1.9659258262890682,-0.25881904510252085,1.0,105.0
+-0.27563735581699905,0.9612616959383189,-1.961261695938319,-0.27563735581699905,1.0,106.0
+-0.29237170472273666,0.9563047559630355,-1.9563047559630355,-0.29237170472273666,1.0,107.0
+-0.30901699437494734,0.9510565162951536,-1.9510565162951536,-0.30901699437494734,1.0,108.0
+-0.32556815445715664,0.9455185755993168,-1.945518575599317,-0.32556815445715664,1.0,109.00000000000001
+-0.3420201433256687,0.9396926207859084,-1.9396926207859084,-0.3420201433256687,1.0,110.0
+-0.35836794954530027,0.9335804264972017,-1.9335804264972016,-0.35836794954530027,1.0,111.0
+-0.37460659341591207,0.9271838545667874,-1.9271838545667874,-0.37460659341591207,1.0,112.0
+-0.3907311284892738,0.9205048534524403,-1.9205048534524405,-0.3907311284892739,1.0,113.00000000000001
+-0.40673664307580026,0.9135454576426009,-1.9135454576426008,-0.40673664307580026,1.0,114.00000000000001
+-0.42261826174069933,0.90630778703665,-1.90630778703665,-0.42261826174069933,1.0,114.99999999999999
+-0.4383711467890775,0.8987940462991669,-1.898794046299167,-0.43837114678907757,1.0,116.0
+-0.45399049973954675,0.8910065241883679,-1.8910065241883678,-0.45399049973954675,1.0,117.0
+-0.4694715627858909,0.8829475928589269,-1.882947592858927,-0.4694715627858909,1.0,118.00000000000001
+-0.484809620246337,0.8746197071393959,-1.874619707139396,-0.484809620246337,1.0,119.0
+-0.4999999999999998,0.8660254037844387,-1.8660254037844388,-0.49999999999999983,1.0,119.99999999999999
+-0.5150380749100543,0.8571673007021123,-1.8571673007021123,-0.5150380749100543,1.0,121.0
+-0.5299192642332048,0.8480480961564261,-1.848048096156426,-0.5299192642332048,1.0,122.0
+-0.5446390350150271,0.838670567945424,-1.838670567945424,-0.5446390350150271,1.0,123.00000000000001
+-0.5591929034707467,0.8290375725550417,-1.8290375725550418,-0.5591929034707468,1.0,124.0
+-0.5735764363510462,0.8191520442889917,-1.8191520442889917,-0.5735764363510462,1.0,125.00000000000001
+-0.587785252292473,0.8090169943749475,-1.8090169943749475,-0.5877852522924731,1.0,126.0
+-0.6018150231520484,0.7986355100472927,-1.7986355100472928,-0.6018150231520484,1.0,127.00000000000003
+-0.6156614753256583,0.788010753606722,-1.788010753606722,-0.6156614753256583,1.0,128.0
+-0.6293203910498373,0.777145961456971,-1.777145961456971,-0.6293203910498373,1.0,129.0
+-0.6427876096865394,0.766044443118978,-1.766044443118978,-0.6427876096865394,1.0,130.0
+-0.6560590289905072,0.7547095802227721,-1.7547095802227721,-0.6560590289905072,1.0,131.0
+-0.6691306063588582,0.7431448254773942,-1.7431448254773942,-0.6691306063588582,1.0,132.0
+-0.6819983600624984,0.7313537016191706,-1.7313537016191707,-0.6819983600624984,1.0,133.0
+-0.6946583704589974,0.7193398003386511,-1.719339800338651,-0.6946583704589974,1.0,134.00000000000003
+-0.7071067811865475,0.7071067811865476,-1.7071067811865475,-0.7071067811865475,1.0,135.0
+-0.7193398003386513,0.6946583704589971,-1.6946583704589973,-0.7193398003386513,1.0,136.0
+-0.7313537016191705,0.6819983600624985,-1.6819983600624986,-0.7313537016191706,1.0,137.0
+-0.7431448254773941,0.6691306063588583,-1.6691306063588582,-0.7431448254773941,1.0,137.99999999999997
+-0.754709580222772,0.6560590289905073,-1.6560590289905073,-0.754709580222772,1.0,139.0
+-0.7660444431189779,0.6427876096865395,-1.6427876096865395,-0.7660444431189779,1.0,140.0
+-0.7771459614569709,0.6293203910498374,-1.6293203910498373,-0.7771459614569709,1.0,141.0
+-0.7880107536067219,0.6156614753256584,-1.6156614753256584,-0.7880107536067219,1.0,142.0
+-0.7986355100472929,0.6018150231520482,-1.601815023152048,-0.7986355100472929,1.0,143.0
+-0.8090169943749473,0.5877852522924732,-1.5877852522924734,-0.8090169943749473,1.0,144.0
+-0.8191520442889919,0.5735764363510459,-1.573576436351046,-0.8191520442889919,1.0,145.00000000000003
+-0.8290375725550416,0.5591929034707469,-1.559192903470747,-0.8290375725550416,1.0,146.0
+-0.8386705679454239,0.5446390350150273,-1.5446390350150274,-0.8386705679454239,1.0,147.0
+-0.848048096156426,0.5299192642332049,-1.529919264233205,-0.848048096156426,1.0,148.0
+-0.8571673007021122,0.5150380749100544,-1.5150380749100543,-0.8571673007021122,1.0,149.0
+-0.8660254037844387,0.49999999999999994,-1.5,-0.8660254037844387,1.0,150.00000000000003
+-0.8746197071393957,0.48480962024633717,-1.4848096202463372,-0.8746197071393957,1.0,151.0
+-0.882947592858927,0.4694715627858907,-1.4694715627858908,-0.882947592858927,1.0,152.0
+-0.8910065241883678,0.45399049973954686,-1.4539904997395467,-0.8910065241883678,1.0,153.0
+-0.898794046299167,0.4383711467890773,-1.4383711467890774,-0.898794046299167,1.0,154.00000000000003
+-0.9063077870366499,0.4226182617406995,-1.4226182617406995,-0.9063077870366499,1.0,155.0
+-0.9135454576426008,0.40673664307580043,-1.4067366430758004,-0.9135454576426008,1.0,156.0
+-0.9205048534524404,0.39073112848927377,-1.3907311284892738,-0.9205048534524404,1.0,157.0
+-0.9271838545667873,0.37460659341591224,-1.3746065934159122,-0.9271838545667873,1.0,158.0
+-0.9335804264972017,0.3583679495453002,-1.3583679495453003,-0.9335804264972017,1.0,159.0
+-0.9396926207859083,0.3420201433256689,-1.3420201433256689,-0.9396926207859084,1.0,160.0
+-0.9455185755993168,0.3255681544571566,-1.3255681544571565,-0.9455185755993168,1.0,161.00000000000003
+-0.9510565162951535,0.3090169943749475,-1.3090169943749475,-0.9510565162951535,1.0,162.0
+-0.9563047559630355,0.2923717047227366,-1.2923717047227365,-0.9563047559630355,1.0,163.00000000000003
+-0.9612616959383189,0.2756373558169992,-1.275637355816999,-0.9612616959383189,1.0,164.0
+-0.9659258262890682,0.258819045102521,-1.258819045102521,-0.9659258262890682,1.0,164.99999999999997
+-0.9702957262759965,0.24192189559966773,-1.2419218955996678,-0.9702957262759965,1.0,166.00000000000003
+-0.9743700647852351,0.2249510543438652,-1.2249510543438653,-0.9743700647852352,1.0,166.99999999999997
+-0.9781476007338057,0.20791169081775931,-1.2079116908177594,-0.9781476007338057,1.0,168.0
+-0.981627183447664,0.19080899537654497,-1.190808995376545,-0.981627183447664,1.0,169.0
+-0.984807753012208,0.17364817766693028,-1.1736481776669303,-0.9848077530122081,1.0,170.0
+-0.9876883405951377,0.15643446504023098,-1.156434465040231,-0.9876883405951378,1.0,171.0
+-0.9902680687415704,0.13917310096006533,-1.1391731009600654,-0.9902680687415704,1.0,172.00000000000003
+-0.992546151641322,0.12186934340514755,-1.1218693434051477,-0.992546151641322,1.0,173.0
+-0.9945218953682733,0.10452846326765373,-1.1045284632676537,-0.9945218953682733,1.0,174.0
+-0.9961946980917455,0.0871557427476582,-1.0871557427476581,-0.9961946980917455,1.0,175.00000000000003
+-0.9975640502598242,0.06975647374412552,-1.0697564737441256,-0.9975640502598243,1.0,175.99999999999997
+-0.9986295347545738,0.05233595624294381,-1.0523359562429437,-0.9986295347545739,1.0,177.00000000000003
+-0.9993908270190958,0.03489949670250114,-1.0348994967025011,-0.9993908270190958,1.0,178.0
+-0.9998476951563913,0.01745240643728344,-1.0174524064372834,-0.9998476951563913,1.0,179.0
+-1.0,1.2246467991473532e-16,-1.0000000000000002,-1.0,1.0,180.0
+-0.9998476951563913,-0.017452406437283637,-0.9825475935627164,-0.9998476951563913,1.0,181.0
+-0.9993908270190958,-0.0348994967025009,-0.9651005032974991,-0.9993908270190958,1.0,182.0
+-0.9986295347545738,-0.052335956242943564,-0.9476640437570565,-0.9986295347545739,1.0,183.0
+-0.9975640502598242,-0.06975647374412527,-0.9302435262558747,-0.9975640502598243,1.0,184.0
+-0.9961946980917455,-0.08715574274765794,-0.9128442572523421,-0.9961946980917455,1.0,185.0
+-0.9945218953682733,-0.1045284632676535,-0.8954715367323465,-0.9945218953682734,1.0,186.00000000000003
+-0.9925461516413221,-0.12186934340514731,-0.8781306565948527,-0.9925461516413221,1.0,186.99999999999997
+-0.9902680687415703,-0.13917310096006552,-0.8608268990399345,-0.9902680687415704,1.0,188.0
+-0.9876883405951378,-0.15643446504023073,-0.8435655349597693,-0.9876883405951378,1.0,189.0
+-0.984807753012208,-0.17364817766693047,-0.8263518223330695,-0.984807753012208,1.0,190.0
+-0.981627183447664,-0.19080899537654472,-0.8091910046234553,-0.981627183447664,1.0,191.0
+-0.9781476007338056,-0.2079116908177595,-0.7920883091822405,-0.9781476007338056,1.0,192.0
+-0.9743700647852352,-0.22495105434386498,-0.775048945656135,-0.9743700647852352,1.0,193.0
+-0.9702957262759965,-0.2419218955996675,-0.7580781044003324,-0.9702957262759966,1.0,194.0
+-0.9659258262890683,-0.2588190451025208,-0.7411809548974793,-0.9659258262890683,1.0,195.00000000000003
+-0.9612616959383189,-0.275637355816999,-0.724362644183001,-0.9612616959383189,1.0,196.0
+-0.9563047559630354,-0.29237170472273677,-0.7076282952772632,-0.9563047559630354,1.0,197.00000000000003
+-0.9510565162951536,-0.3090169943749473,-0.6909830056250528,-0.9510565162951536,1.0,198.00000000000003
+-0.9455185755993167,-0.32556815445715676,-0.6744318455428432,-0.9455185755993168,1.0,199.0
+-0.9396926207859084,-0.34202014332566866,-0.6579798566743313,-0.9396926207859084,1.0,200.0
+-0.9335804264972017,-0.35836794954530043,-0.6416320504546995,-0.9335804264972017,1.0,201.0
+-0.9271838545667874,-0.374606593415912,-0.625393406584088,-0.9271838545667874,1.0,202.0
+-0.9205048534524404,-0.39073112848927355,-0.6092688715107264,-0.9205048534524404,1.0,203.0
+-0.9135454576426009,-0.4067366430758002,-0.5932633569241997,-0.913545457642601,1.0,204.0
+-0.90630778703665,-0.4226182617406993,-0.5773817382593007,-0.90630778703665,1.0,205.0
+-0.8987940462991669,-0.43837114678907746,-0.5616288532109225,-0.898794046299167,1.0,206.00000000000003
+-0.8910065241883679,-0.45399049973954664,-0.5460095002604534,-0.8910065241883679,1.0,206.99999999999997
+-0.8829475928589269,-0.46947156278589086,-0.5305284372141091,-0.8829475928589269,1.0,208.00000000000003
+-0.8746197071393959,-0.48480962024633695,-0.515190379753663,-0.8746197071393959,1.0,209.00000000000003
+-0.8660254037844386,-0.5000000000000001,-0.4999999999999999,-0.8660254037844386,1.0,210.0
+-0.8571673007021123,-0.5150380749100542,-0.48496192508994584,-0.8571673007021123,1.0,211.0
+-0.8480480961564261,-0.5299192642332048,-0.4700807357667952,-0.8480480961564261,1.0,212.0
+-0.838670567945424,-0.5446390350150271,-0.4553609649849729,-0.838670567945424,1.0,213.0
+-0.8290375725550417,-0.5591929034707467,-0.4408070965292532,-0.8290375725550418,1.0,214.0
+-0.8191520442889918,-0.5735764363510462,-0.42642356364895384,-0.8191520442889918,1.0,215.0
+-0.8090169943749475,-0.587785252292473,-0.41221474770752686,-0.8090169943749476,1.0,216.0
+-0.7986355100472928,-0.6018150231520484,-0.3981849768479516,-0.7986355100472928,1.0,217.00000000000003
+-0.788010753606722,-0.6156614753256582,-0.3843385246743418,-0.788010753606722,1.0,218.00000000000003
+-0.7771459614569708,-0.6293203910498376,-0.3706796089501624,-0.7771459614569708,1.0,219.00000000000003
+-0.766044443118978,-0.6427876096865393,-0.35721239031346064,-0.7660444431189781,1.0,220.0
+-0.7547095802227721,-0.656059028990507,-0.34394097100949284,-0.7547095802227722,1.0,221.0
+-0.7431448254773942,-0.6691306063588582,-0.33086939364114176,-0.7431448254773942,1.0,222.0
+-0.7313537016191706,-0.6819983600624984,-0.31800163993750163,-0.7313537016191706,1.0,223.0
+-0.7193398003386511,-0.6946583704589973,-0.30534162954100263,-0.7193398003386512,1.0,224.0
+-0.7071067811865477,-0.7071067811865475,-0.29289321881345254,-0.7071067811865477,1.0,225.0
+-0.6946583704589973,-0.7193398003386512,-0.2806601996613488,-0.6946583704589973,1.0,226.00000000000003
+-0.6819983600624986,-0.7313537016191705,-0.26864629838082954,-0.6819983600624986,1.0,227.0
+-0.6691306063588581,-0.7431448254773944,-0.25685517452260564,-0.6691306063588581,1.0,228.00000000000003
+-0.6560590289905073,-0.754709580222772,-0.24529041977722799,-0.6560590289905073,1.0,229.00000000000003
+-0.6427876096865395,-0.7660444431189779,-0.2339555568810221,-0.6427876096865395,1.0,229.99999999999997
+-0.6293203910498378,-0.7771459614569706,-0.22285403854302943,-0.6293203910498378,1.0,230.99999999999997
+-0.6156614753256581,-0.7880107536067221,-0.21198924639327787,-0.6156614753256581,1.0,232.0
+-0.6018150231520483,-0.7986355100472928,-0.20136448995270717,-0.6018150231520483,1.0,233.0
+-0.5877852522924732,-0.8090169943749473,-0.19098300562505266,-0.5877852522924732,1.0,234.0
+-0.5735764363510464,-0.8191520442889916,-0.18084795571100842,-0.5735764363510464,1.0,235.0
+-0.5591929034707466,-0.8290375725550418,-0.17096242744495815,-0.5591929034707466,1.0,236.00000000000003
+-0.544639035015027,-0.8386705679454242,-0.16132943205457584,-0.544639035015027,1.0,237.00000000000003
+-0.529919264233205,-0.848048096156426,-0.15195190384357404,-0.529919264233205,1.0,238.0
+-0.5150380749100544,-0.8571673007021121,-0.14283269929788778,-0.5150380749100545,1.0,238.99999999999997
+-0.5000000000000004,-0.8660254037844385,-0.13397459621556151,-0.5000000000000004,1.0,239.99999999999997
+-0.48480962024633684,-0.8746197071393959,-0.12538029286060404,-0.4848096202463369,1.0,241.00000000000003
+-0.46947156278589075,-0.882947592858927,-0.11705240714107301,-0.46947156278589075,1.0,242.0
+-0.4539904997395469,-0.8910065241883678,-0.10899347581163221,-0.4539904997395469,1.0,243.0
+-0.43837114678907774,-0.8987940462991668,-0.10120595370083318,-0.43837114678907774,1.0,244.0
+-0.42261826174069916,-0.9063077870366502,-0.09369221296334984,-0.42261826174069916,1.0,245.00000000000003
+-0.4067366430758001,-0.913545457642601,-0.08645454235739902,-0.4067366430758001,1.0,246.00000000000003
+-0.3907311284892738,-0.9205048534524403,-0.07949514654755963,-0.3907311284892739,1.0,247.0
+-0.3746065934159123,-0.9271838545667873,-0.07281614543321269,-0.3746065934159123,1.0,248.0
+-0.3583679495453007,-0.9335804264972016,-0.06641957350279837,-0.3583679495453007,1.0,249.0
+-0.34202014332566855,-0.9396926207859084,-0.06030737921409146,-0.3420201433256686,1.0,250.00000000000003
+-0.32556815445715664,-0.9455185755993168,-0.054481424400683154,-0.32556815445715664,1.0,251.00000000000003
+-0.30901699437494756,-0.9510565162951535,-0.04894348370484647,-0.30901699437494756,1.0,252.0
+-0.2923717047227371,-0.9563047559630353,-0.043695244036964676,-0.2923717047227371,1.0,252.99999999999997
+-0.2756373558169989,-0.961261695938319,-0.038738304061680995,-0.2756373558169989,1.0,254.00000000000006
+-0.25881904510252063,-0.9659258262890683,-0.03407417371093169,-0.25881904510252063,1.0,255.0
+-0.24192189559966779,-0.9702957262759965,-0.029704273724003527,-0.24192189559966779,1.0,256.0
+-0.22495105434386525,-0.9743700647852351,-0.025629935214764754,-0.22495105434386528,1.0,257.0
+-0.2079116908177598,-0.9781476007338056,-0.021852399266194422,-0.2079116908177598,1.0,258.0
+-0.1908089953765446,-0.981627183447664,-0.018372816552335913,-0.19080899537654464,1.0,259.0
+-0.17364817766693033,-0.984807753012208,-0.015192246987791869,-0.17364817766693036,1.0,260.0
+-0.15643446504023104,-0.9876883405951377,-0.01231165940486223,-0.15643446504023106,1.0,261.0
+-0.13917310096006583,-0.9902680687415703,-0.009731931258429749,-0.13917310096006583,1.0,262.0
+-0.12186934340514717,-0.9925461516413221,-0.007453848358677906,-0.12186934340514717,1.0,263.0
+-0.10452846326765336,-0.9945218953682734,-0.005478104631726599,-0.10452846326765336,1.0,264.0
+-0.08715574274765825,-0.9961946980917455,-0.003805301908254455,-0.08715574274765825,1.0,265.0
+-0.06975647374412558,-0.9975640502598242,-0.0024359497401758023,-0.06975647374412558,1.0,266.0
+-0.052335956242944306,-0.9986295347545738,-0.0013704652454260557,-0.05233595624294431,1.0,267.0
+-0.03489949670250076,-0.9993908270190958,-0.0006091729809042379,-0.03489949670250076,1.0,268.00000000000006
+-0.017452406437283498,-0.9998476951563913,-0.00015230484360873042,-0.017452406437283498,1.0,269.0
+-1.8369701987210297e-16,-1.0,0.0,-1.8369701987210297e-16,1.0,270.0
+0.01745240643728313,-0.9998476951563913,-0.00015230484360873042,0.01745240643728313,1.0,271.0
+0.03489949670250128,-0.9993908270190958,-0.0006091729809042379,0.03489949670250128,1.0,272.0
+0.052335956242943946,-0.9986295347545738,-0.0013704652454260557,0.05233595624294395,1.0,273.0
+0.06975647374412522,-0.9975640502598243,-0.0024359497401756913,0.06975647374412522,1.0,274.0
+0.08715574274765789,-0.9961946980917455,-0.003805301908254455,0.08715574274765789,1.0,275.0
+0.10452846326765299,-0.9945218953682734,-0.005478104631726599,0.10452846326765299,1.0,275.99999999999994
+0.12186934340514768,-0.992546151641322,-0.007453848358678017,0.12186934340514768,1.0,277.00000000000006
+0.13917310096006547,-0.9902680687415704,-0.009731931258429638,0.13917310096006547,1.0,278.0
+0.15643446504023067,-0.9876883405951378,-0.01231165940486223,0.15643446504023067,1.0,279.0
+0.17364817766692997,-0.9848077530122081,-0.015192246987791869,0.17364817766692997,1.0,280.0
+0.1908089953765451,-0.9816271834476639,-0.018372816552336024,0.19080899537654514,1.0,281.0
+0.20791169081775943,-0.9781476007338056,-0.021852399266194422,0.20791169081775943,1.0,282.0
+0.22495105434386492,-0.9743700647852352,-0.025629935214764754,0.22495105434386492,1.0,283.0
+0.24192189559966742,-0.9702957262759966,-0.029704273724003416,0.24192189559966742,1.0,284.0
+0.2588190451025203,-0.9659258262890684,-0.03407417371093158,0.2588190451025203,1.0,285.0
+0.2756373558169994,-0.9612616959383188,-0.038738304061681106,0.27563735581699944,1.0,286.0
+0.2923717047227367,-0.9563047559630354,-0.043695244036964564,0.2923717047227367,1.0,287.0
+0.30901699437494723,-0.9510565162951536,-0.04894348370484636,0.30901699437494723,1.0,288.0
+0.3255681544571563,-0.945518575599317,-0.05448142440068304,0.3255681544571563,1.0,289.0
+0.342020143325669,-0.9396926207859083,-0.06030737921409168,0.342020143325669,1.0,290.00000000000006
+0.3583679495453004,-0.9335804264972017,-0.06641957350279826,0.3583679495453004,1.0,291.0
+0.37460659341591196,-0.9271838545667874,-0.07281614543321258,0.37460659341591196,1.0,292.0
+0.3907311284892735,-0.9205048534524405,-0.07949514654755951,0.3907311284892735,1.0,293.0
+0.40673664307579976,-0.9135454576426011,-0.08645454235739891,0.40673664307579976,1.0,294.0
+0.4226182617406996,-0.9063077870366498,-0.09369221296335006,0.42261826174069966,1.0,295.0
+0.4383711467890774,-0.898794046299167,-0.10120595370083296,0.4383711467890774,1.0,296.0
+0.45399049973954664,-0.891006524188368,-0.10899347581163199,0.45399049973954664,1.0,297.0
+0.4694715627858904,-0.8829475928589271,-0.1170524071410729,0.4694715627858904,1.0,298.0
+0.4848096202463373,-0.8746197071393956,-0.12538029286060437,0.4848096202463373,1.0,299.00000000000006
+0.5000000000000001,-0.8660254037844386,-0.1339745962155614,0.5000000000000001,1.0,300.00000000000006
+0.5150380749100542,-0.8571673007021123,-0.14283269929788767,0.5150380749100542,1.0,301.0
+0.5299192642332047,-0.8480480961564261,-0.15195190384357393,0.5299192642332047,1.0,302.0
+0.5446390350150266,-0.8386705679454243,-0.16132943205457573,0.5446390350150266,1.0,303.0
+0.559192903470747,-0.8290375725550416,-0.17096242744495838,0.559192903470747,1.0,304.0
+0.573576436351046,-0.8191520442889918,-0.1808479557110081,0.5735764363510462,1.0,305.0
+0.5877852522924729,-0.8090169943749476,-0.19098300562505244,0.5877852522924729,1.0,306.0
+0.6018150231520479,-0.798635510047293,-0.20136448995270684,0.601815023152048,1.0,307.0
+0.6156614753256585,-0.7880107536067218,-0.2119892463932782,0.6156614753256585,1.0,308.00000000000006
+0.6293203910498375,-0.7771459614569708,-0.2228540385430291,0.6293203910498376,1.0,309.0
+0.6427876096865393,-0.7660444431189781,-0.23395555688102188,0.6427876096865393,1.0,310.0
+0.656059028990507,-0.7547095802227722,-0.24529041977722776,0.656059028990507,1.0,311.0
+0.6691306063588578,-0.7431448254773946,-0.2568551745226053,0.6691306063588579,1.0,312.0
+0.6819983600624986,-0.7313537016191703,-0.26864629838082965,0.6819983600624986,1.0,313.0
+0.6946583704589973,-0.7193398003386511,-0.2806601996613488,0.6946583704589974,1.0,314.0
+0.7071067811865474,-0.7071067811865477,-0.2928932188134523,0.7071067811865474,1.0,315.0
+0.7193398003386509,-0.6946583704589976,-0.3053416295410024,0.7193398003386509,1.0,316.0
+0.7313537016191707,-0.6819983600624983,-0.31800163993750175,0.7313537016191707,1.0,317.00000000000006
+0.7431448254773942,-0.6691306063588581,-0.33086939364114176,0.7431448254773944,1.0,318.0
+0.7547095802227719,-0.6560590289905074,-0.3439409710094926,0.7547095802227719,1.0,319.0
+0.7660444431189778,-0.6427876096865396,-0.3572123903134604,0.7660444431189778,1.0,320.0
+0.7771459614569706,-0.6293203910498378,-0.37067960895016216,0.7771459614569706,1.0,321.0
+0.788010753606722,-0.6156614753256582,-0.3843385246743418,0.788010753606722,1.0,322.00000000000006
+0.7986355100472928,-0.6018150231520483,-0.39818497684795173,0.7986355100472928,1.0,323.0
+0.8090169943749473,-0.5877852522924734,-0.41221474770752664,0.8090169943749473,1.0,324.0
+0.8191520442889916,-0.5735764363510465,-0.4264235636489535,0.8191520442889916,1.0,325.0
+0.8290375725550418,-0.5591929034707466,-0.44080709652925343,0.8290375725550418,1.0,326.00000000000006
+0.838670567945424,-0.544639035015027,-0.455360964984973,0.838670567945424,1.0,327.0
+0.8480480961564258,-0.529919264233205,-0.4700807357667949,0.848048096156426,1.0,328.0
+0.8571673007021121,-0.5150380749100545,-0.4849619250899455,0.8571673007021121,1.0,329.0
+0.8660254037844384,-0.5000000000000004,-0.49999999999999956,0.8660254037844384,1.0,329.99999999999994
+0.8746197071393959,-0.4848096202463369,-0.5151903797536631,0.8746197071393959,1.0,331.0
+0.882947592858927,-0.4694715627858908,-0.5305284372141092,0.882947592858927,1.0,332.00000000000006
+0.8910065241883678,-0.45399049973954697,-0.546009500260453,0.8910065241883678,1.0,333.0
+0.8987940462991668,-0.4383711467890778,-0.5616288532109222,0.8987940462991668,1.0,333.99999999999994
+0.90630778703665,-0.4226182617406992,-0.5773817382593007,0.90630778703665,1.0,335.00000000000006
+0.913545457642601,-0.40673664307580015,-0.5932633569241998,0.913545457642601,1.0,336.0
+0.9205048534524403,-0.3907311284892739,-0.6092688715107262,0.9205048534524403,1.0,337.0
+0.9271838545667873,-0.37460659341591235,-0.6253934065840876,0.9271838545667873,1.0,338.0
+0.9335804264972015,-0.35836794954530077,-0.6416320504546992,0.9335804264972016,1.0,339.0
+0.9396926207859084,-0.3420201433256686,-0.6579798566743313,0.9396926207859084,1.0,340.0
+0.9455185755993168,-0.3255681544571567,-0.6744318455428433,0.9455185755993168,1.0,341.00000000000006
+0.9510565162951535,-0.3090169943749477,-0.6909830056250523,0.9510565162951535,1.0,342.0
+0.9563047559630353,-0.29237170472273716,-0.7076282952772628,0.9563047559630353,1.0,342.99999999999994
+0.9612616959383189,-0.27563735581699894,-0.724362644183001,0.961261695938319,1.0,344.00000000000006
+0.9659258262890683,-0.2588190451025207,-0.7411809548974793,0.9659258262890683,1.0,345.0
+0.9702957262759965,-0.24192189559966787,-0.7580781044003322,0.9702957262759965,1.0,346.0
+0.9743700647852351,-0.22495105434386534,-0.7750489456561347,0.9743700647852351,1.0,347.0
+0.9781476007338056,-0.20791169081775987,-0.7920883091822402,0.9781476007338056,1.0,348.0
+0.981627183447664,-0.19080899537654467,-0.8091910046234554,0.981627183447664,1.0,349.0
+0.984807753012208,-0.1736481776669304,-0.8263518223330696,0.9848077530122081,1.0,350.00000000000006
+0.9876883405951377,-0.1564344650402311,-0.8435655349597688,0.9876883405951378,1.0,351.0
+0.9902680687415703,-0.13917310096006588,-0.8608268990399341,0.9902680687415703,1.0,351.99999999999994
+0.9925461516413221,-0.12186934340514723,-0.8781306565948528,0.9925461516413221,1.0,353.0
+0.9945218953682733,-0.10452846326765342,-0.8954715367323466,0.9945218953682734,1.0,354.00000000000006
+0.9961946980917455,-0.08715574274765832,-0.9128442572523416,0.9961946980917455,1.0,355.0
+0.9975640502598242,-0.06975647374412564,-0.9302435262558744,0.9975640502598242,1.0,356.0
+0.9986295347545738,-0.05233595624294437,-0.9476640437570556,0.9986295347545739,1.0,357.0
+0.9993908270190958,-0.034899496702500823,-0.9651005032974992,0.9993908270190958,1.0,358.0
+0.9998476951563913,-0.01745240643728356,-0.9825475935627165,0.9998476951563913,1.0,359.0
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocity_grid.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocity_grid.py
new file mode 100644
index 0000000000..3aa96b027b
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/tests/winds/test_velocity_grid.py
@@ -0,0 +1,70 @@
+import numpy as np
+from structures.geogrid import GeoGrid
+from profile_model.radialprofiles import HollandWindSpeedProfile
+from winds.parameters import Parameters
+from winds.velocities import Velocities
+import matplotlib.pyplot as plt
+
+def test_velocity_grid():
+ # Grid of x, y points
+ n = 50
+ nr = 200
+ rmax = 40
+ cmin, cmax = -200 , 200
+ cellsize = (cmax-cmin)/n
+ x = np.linspace(cmin, cmax, n)
+ y = np.linspace(cmin, cmax, n)
+ U = GeoGrid(cmin,cmin,n,n,cellsize)
+ V = GeoGrid(cmin,cmin,n,n,cellsize)
+
+ params = Parameters()
+ b = 1.4
+ hc = [0,0]
+ vf = [0,10]
+ deltap = 100
+ coriol = False
+ profile = HollandWindSpeedProfile(nr,2*cmax,rmax,deltap,params.rho,params.getCoriolisMid(),b,coriolis=coriol)
+ vels = Velocities(vf[0],vf[1],profile.getVmax())
+ for j in range(0,n):
+ for i in range(0,n):
+ pt = U.getCenter(i,j)
+ r = np.sqrt(pow(pt[0]-hc[0],2)+pow(pt[1]-hc[1],2))
+ vg = profile.getValue(r)
+ vv = vels.compute_wind_vector(vg,pt[0],pt[1])
+ U.put(i,j,vv[0])
+ V.put(i,j,vv[1])
+
+ assert True # If we made it to here.
+
+ fig = plt.figure()
+
+ ax = fig.add_subplot(131)
+ ax.plot(profile.rvals, profile.profile)
+
+ ax.set(xlabel='r (km)', ylabel='wind speed (km/hr)',
+ title='Radial Wind')
+ ax1 = fig.add_subplot(133)
+
+ # Plot the streamlines.
+ # Matplotlib assume an ordinary row ordering, so the rows must be reversed before plotting.
+ Ug = U.grid
+ Vg = V.grid
+ Uplt = np.zeros([n,n])
+ Vplt = np.zeros([n,n])
+ for j in range(0,n):
+ jp = n-j-1
+ for i in range(0,n):
+ Uplt[jp,i]=Ug[j,i]
+ Vplt[jp,i]=Vg[j,i]
+
+ Vmag = np.sqrt(Ug*Ug+Vg*Vg)
+ ax1.streamplot(x, y, Uplt, Vplt, color=Vmag, cmap='Spectral')
+ ax1.set_xlabel('$x$')
+ ax1.set_ylabel('$y$')
+ ax1.set_xlim(cmin,cmax)
+ ax1.set_ylim(cmin,cmax)
+ ax1.set_aspect('equal')
+ plt.title('Wind Vectors')
+
+ plt.show()
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/gis.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/gis.py
new file mode 100644
index 0000000000..b2e1202b8a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/gis.py
@@ -0,0 +1,14 @@
+from geopy.distance import geodesic
+
+def geodistkm(x1,y1,x2,y2):
+ '''
+ Returns the geodesic distance in km given two pairs of (lon, lat) coordinates.
+ Note: Because it uses geopy, the coordinate order is reversed to (lat,lon)
+ before calling the geopy function.
+ :param x1: lon of the first point.
+ :param y1: lat of the first point.
+ :param x2: lon of the second point.
+ :param y2: lat of the second point.
+ :return: Geodesic distance between the two points in km.
+ '''
+ return geodesic((y1,x1),(y2,x2)).km
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/math.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/math.py
new file mode 100644
index 0000000000..98692fa172
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/utils/math.py
@@ -0,0 +1,7 @@
+
+def sign(x):
+ if(x>=0):
+ return 1
+ else:
+ return -1
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/parameters.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/parameters.py
new file mode 100644
index 0000000000..f65f0dce78
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/parameters.py
@@ -0,0 +1,41 @@
+import math
+from winds.wind_model import PROFILE_TYPE
+
+class Parameters:
+ def __init__(self, mean_lat: float, wind_profile_type=PROFILE_TYPE.HOLLAND):
+ """
+ Constructor.
+ :param mean_lat: mean latitude of the hurricane trajectory to compute the Coroilis factor in radians
+ Units are km, hr, and millibars for distance, wind, and pressure respectively, and lat in decimal degrees.
+ """
+ self.siderealDay = 23.934 # A sidereal day in hrs.
+ self.omega = 2.0 * math.pi / self.siderealDay # The Earth's rotation rate in rad/hr.
+
+ self.rho = 1.15 # Air density at sea level in kg/m^3.
+ self.wind_profile_type = wind_profile_type # The particular wind profile model being used.
+
+ # Earth radius in km
+ self.earth_radius = 6371.1
+
+
+ def get_coriolis(self, lat: float) -> float:
+ """
+ Returns the Coriolis parameter for a given latitude.
+ :param lat: in radians
+ :return: coriolis factor in rad/s to be consistent with Holland's model units
+ """
+ # The Coriolis parameter = 2*omega*sin(|phi|)
+ # 3600 to convert omega in rad/s
+ return 2.0 * self.omega / 3600. * math.sin(math.fabs(lat))
+
+
+ def get_pressure_unit(self):
+ return 'millibars'
+
+
+ def get_distance_unit(self):
+ return 'kilometers'
+
+
+ def get_time_unit(self):
+ return 'hours'
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/velocities.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/velocities.py
new file mode 100644
index 0000000000..4b9ba3e551
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/velocities.py
@@ -0,0 +1,47 @@
+import math
+
+
+class Velocities:
+
+ def __init__(self, vfe, vfn, vmax):
+ """
+ Initialize with the forward velocity components.
+ :param vfe: Eastward forward velocity (x-component in the Earth frame) in km/hr.
+ :param vfn: Northward forward velocity component (y-component in the Earth frame) in km/hr.
+ """
+ self.vf = []
+ self.vfmagn = []
+ self.xunitv = []
+ self.yunitv = []
+
+ self.set_vforward(vfe, vfn)
+ self.vmax = vmax
+
+ def set_vforward(self, vfe, vfn):
+ self.vf = [vfe, vfn]
+ self.vfmagn = math.sqrt(pow(vfe, 2) + pow(vfn, 2))
+ self.xunitv = [vfn/self.vfmagn, -vfe/self.vfmagn]
+ self.yunitv = [vfe/self.vfmagn, vfn/self.vfmagn]
+
+
+ def compute_wind_vector(self, vg, xe, yn):
+ """
+ Returns the velocity components [ve,vn] given the tangential gradient wind speed.
+ :param vg: The tangential (theta) gradient wind speed in the hurricane frame in km/hr.
+ :param xe: The eastern component of position relative to the local origin (the hurricane eye) in km.
+ :param yn: The northern component of position relative to the local origin (the hurricane eye) in km.
+ :return: [ve,vn] the eastward and nortward components of the wind velocity in the Earth frame in km/hr.
+ """
+ rmagn = math.sqrt(xe*xe + yn*yn)
+
+ costheta = (xe*self.xunitv[0] + yn*self.xunitv[1])/rmagn
+ sintheta = -(xe*self.xunitv[1] - yn*self.xunitv[0])/rmagn
+ theta_unitv = [-sintheta*self.xunitv[0]+costheta*self.yunitv[0],
+ -sintheta*self.xunitv[1]+costheta*self.yunitv[1]]
+ vgtheta = [theta_unitv[0]*vg, theta_unitv[1]*vg]
+ vfcorr = vg/self.vmax
+ ve = self.vf[0]*vfcorr + vgtheta[0]
+ vn = self.vf[1]*vfcorr + vgtheta[1]
+
+ return [ve, vn]
+
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/wind_model.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/wind_model.py
new file mode 100644
index 0000000000..4a876284d8
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds/wind_model.py
@@ -0,0 +1,88 @@
+from enum import Enum
+import numpy as np
+import winds.parameters as Parameters
+import hurricane_model as Hurricane
+import structures as Geogrid
+import matplotlib.pyplot as plt
+import math
+
+
+class PROFILE_TYPE(Enum):
+ HOLLAND = 'holland'
+ WILLOUGHBY = 'willoughby'
+
+class WindModel:
+ def __init__(self, params: Parameters, curr_hurricane: Hurricane, grid: Geogrid):
+ self.profile_type = params.wind_profile_type
+ if self.profile_type == PROFILE_TYPE.HOLLAND:
+
+ # Distance between the hurricane eye and the grid points
+ # Great circle distance in km
+ r = np.power(np.sin((grid.lat - curr_hurricane.center[1]) * 0.5), 2) + \
+ np.cos(grid.lat) * np.cos(curr_hurricane.center[1]) * \
+ np.power(np.sin((grid.lon - curr_hurricane.center[0]) * 0.5), 2)
+ r = 2.0 * params.earth_radius * np.arcsin(np.sqrt(r))
+
+ # Compute pressure
+ self.pressure_profile = holland_pressure_profile(curr_hurricane, r)
+
+ # Compute wind speed
+ self.wind_speed_profile = holland_windspeed_profile(params, curr_hurricane, r)
+
+ # plt.scatter(grid.lon, grid.lat, s=10., c=self.wind_speed_profile, alpha=1.)
+ # plt.show()
+
+ # Compute wind components
+ self.u, self.v = compute_components(self.wind_speed_profile, curr_hurricane, grid)
+
+ else:
+ raise 'Profile models other than Holland are not currently supported.'
+
+
+def holland_pressure_profile(hurricane: Hurricane, r: np.ndarray):
+ """
+ :param hurricane: class type Hurricane
+ :param r: distance between the eye of the hurricane and the grid points in km
+ """
+ return hurricane.pcentral + hurricane.deltap * np.exp(-np.power(hurricane.extent / r ,hurricane.b))
+
+
+def holland_windspeed_profile(params: Parameters, hurricane: Hurricane, r: np.ndarray, coriolis=False):
+ """
+ :param params: class parameters
+ :param hurricane: class Hurricane
+ :param r: distance between the eye of the hurricane and the grid points in km
+ :param coriolis: coriolis factor in rad/hrs
+ """
+
+ # Holland equation assumes:
+ # deltap in Pa
+ # density in kg/m3
+ # and returns m/s
+ units_factor = 100. # To convert the deltap from mbar to Pascals
+
+
+ y = np.power(hurricane.extent / r, hurricane.b)
+ exp_term = units_factor*(hurricane.deltap / params.rho) * hurricane.b * y * np.exp(-y)
+ if coriolis is True:
+ v = np.sqrt(exp_term + 0.25 * np.power(r * params.f, 2)) + 0.5 * r * params.f
+ else:
+ v = np.sqrt(exp_term)
+
+ v *= 3.6 # Conversion from m/s to km/h
+
+ return v
+
+def compute_components(wind_speed_profile, curr_hurricane: Hurricane, grid: Geogrid) -> (np.ndarray, np.ndarray):
+ # Compute components of vg
+ theta = np.arctan2(grid.lat - curr_hurricane.center[1], grid.lon - curr_hurricane.center[0])
+ theta += math.pi * 0.5
+ vg_x = wind_speed_profile * np.cos(theta)
+ vg_y = wind_speed_profile * np.sin(theta)
+
+ # Compute total velocity
+ ratio = wind_speed_profile / curr_hurricane.vmax
+ u = vg_x + curr_hurricane.vforward[0] * ratio
+ v = vg_y + curr_hurricane.vforward[1] * ratio
+
+ return u, v
\ No newline at end of file
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/__init__.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/import_data.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/import_data.py
new file mode 100644
index 0000000000..84af96b757
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/import_data.py
@@ -0,0 +1,156 @@
+import json
+from netCDF4 import Dataset
+import numpy as np
+import math
+from hurricane_model import hurricane
+from structures import geogrid
+import datetime
+
+def read_grid_file(grid_filename: str, grid_flag: int) -> (float, float):
+ if grid_flag == 1:
+ xll, yll, cellsize, numcells_lat, numcells_lon = read_raster_inputs(grid_filename)
+ lon, lat = setup_regular_grid(xll, yll, cellsize, numcells_lat, numcells_lon)
+ else:
+ lon, lat = read_netcdf(grid_filename)
+
+ return lon, lat
+
+def read_input_file(filename: str) -> (str, int, str, float, float):
+ try:
+ f = open(filename, "r")
+ except FileNotFoundError as fnf_error:
+ raise fnf_error
+
+ traj_filename = f.readline().rstrip('\n')
+ grid_flag = f.readline().rstrip('\n').split()
+ grid_flag = int(grid_flag[0])
+ grid_filename = f.readline().rstrip('\n')
+ ambient_pressure = f.readline().rstrip('\n').split()
+ ambient_pressure = float(ambient_pressure[0])
+ holland_b_param = f.readline().rstrip('\n').split()
+ holland_b_param = float(holland_b_param[0])
+
+ f.close()
+
+ return traj_filename, grid_flag, grid_filename, ambient_pressure, holland_b_param
+
+
+def setup_regular_grid(xll: float, yll: float, cellsize: float, numcells_lat: int, numcells_lon: int) -> (float, float):
+ npoints = numcells_lat * numcells_lon
+ lon = np.zeros((npoints, ))
+ lat = np.zeros((npoints, ))
+ k = 0
+ for i in range(0, numcells_lon):
+ for j in range(0, numcells_lat):
+ lon[k] = xll + (float(i) + 0.5) * cellsize
+ lat[k] = yll + (float(j) + 0.5) * cellsize
+ k += 1
+
+ lat = lat * math.pi / 180. # Convert to radians
+ lon = lon * math.pi / 180. # Convert to radians
+
+ return lon, lat
+
+
+def read_raster_inputs(filename: str) -> (float, float, float, int, int):
+ try:
+ f = open(filename, "r")
+ except FileNotFoundError as fnf_error:
+ raise fnf_error
+
+ # longitude of the south west corner in deg
+ temp = f.readline().rstrip('\n').split()
+ xll = float(temp[0])
+ # latitude of the south west corner in deg
+ temp = f.readline().rstrip('\n').split()
+ yll = float(temp[0])
+ # cell size in deg
+ temp = f.readline().rstrip('\n').split()
+ cellsize = float(temp[0])
+ # number of cells for latitude
+ temp = f.readline().rstrip('\n').split()
+ numcells_lat = int(temp[0])
+ # number of cells for longitude
+ temp = f.readline().rstrip('\n').split()
+ numcells_lon = int(temp[0])
+
+ f.close()
+
+ return xll, yll, cellsize, numcells_lat, numcells_lon
+
+
+def read_json(filename: str):
+ try:
+ with open(filename) as json_data:
+ json_raw = json.load(json_data)
+ return json_raw
+
+ except FileNotFoundError as fnf_error:
+ raise fnf_error
+
+
+def read_netcdf(filename: str) -> (float, float):
+ # http://unidata.github.io/netcdf4-python/#section1
+ # lat and lon from the netCDF file are assumed in radians
+ try:
+ nc = Dataset(filename)
+ temp_lat = nc.variables['latCell'][:]
+ temp_lon = nc.variables['lonCell'][:]
+
+ # Convert to numpy array for subsequent processing
+ lat = np.array(temp_lat)
+ lon = np.array(temp_lon) - 2. * math.pi
+ for i in range(0, len(lon)):
+ if lon[i] <= -math.pi:
+ lon[i] += 2. * math.pi
+
+ return lon, lat
+
+ except FileNotFoundError as fnf_error:
+ raise fnf_error
+
+
+def initialize_hurricane(traj_filename: str, ambient_pressure: float, holland_b_param: float) -> list:
+ # JSON Specs
+ # "timeUnits": "hours",
+ # "distanceUnits": "miles",
+ # "windspeedUnits": "knots",
+ # "pressureUnits": "mb",
+
+ json_raw = read_json(traj_filename)
+
+ ref_date = datetime.datetime.strptime(json_raw['initialTime'],'%Y-%m-%d_%H:%M:%S')
+
+ curr_hurricane = []
+ traj = json_raw['stormTrack']['features']
+
+ for it in range(0, len(traj)):
+ coord = traj[it]['geometry']['coordinates']
+ center_coord = [x * math.pi / 180. for x in coord] # degree to rad
+ extent = traj[it]['properties']['rMax'] * 1.60934 # miles to km
+ pmin = traj[it]['properties']['minP'] # in mbar
+ deltap = ambient_pressure - pmin # in mbar
+ time = traj[it]['properties']['time'] # in hrs
+ vmax = traj[it]['properties']['wMax'] * 1.852 # from knots to km/h
+
+ curr_hurricane.append(hurricane.Hurricane(tuple(center_coord), extent, pmin, deltap, vmax,
+ holland_b_param, time, ref_date))
+
+ # Compute the components of the forward velocity
+ for it in range(0, len(traj) - 1):
+ x1 = curr_hurricane[it].center[0]
+ y1 = curr_hurricane[it].center[1]
+
+ x2 = curr_hurricane[it + 1].center[0]
+ y2 = curr_hurricane[it + 1].center[1]
+
+ theta = math.atan2(y2 - y1, x2 - x1)
+ vf = traj[it]['properties']['vf'] * 1.852
+ curr_hurricane[it].set_vf((vf * math.cos(theta), vf * math.sin(theta)))
+
+ return curr_hurricane
+
+
+def initialize_grid(grid_filename: str, grid_flag: int) -> geogrid.GeoGrid:
+ lon, lat = read_grid_file(grid_filename, grid_flag)
+ return geogrid.GeoGrid(lon, lat)
diff --git a/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/output_data.py b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/output_data.py
new file mode 100644
index 0000000000..b6e3512517
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/hurricane_wind_pressure/winds_io/output_data.py
@@ -0,0 +1,48 @@
+import netCDF4
+import numpy as np
+import hurricane_model as Hurricane
+import structures as Geogrid
+import winds_io as WindModel
+import matplotlib.pyplot as plt
+import datetime
+
+def write_netcdf(filename: str, curr_hurricane: Hurricane, grid: Geogrid, winds: WindModel):
+ # http://unidata.github.io/netcdf4-python/#section1
+ rootgrp = netCDF4.Dataset(filename, "w", format="NETCDF3_64BIT_OFFSET")
+
+ # Declare dimensions
+ rootgrp.createDimension('nCells',grid.ncells)
+ rootgrp.createDimension('StrLen',64)
+ rootgrp.createDimension('Time',None)
+
+ # Declare variables
+ time = rootgrp.dimensions['Time'].name
+ ncells = rootgrp.dimensions['nCells'].name
+ time_var = rootgrp.createVariable('xtime','S1',('Time','StrLen'))
+ u_var = rootgrp.createVariable('windSpeedU',np.float64,(time,ncells))
+ v_var = rootgrp.createVariable('windSpeedV',np.float64,(time,ncells))
+ pres_var = rootgrp.createVariable('atmosPressure',np.float64,(time,ncells))
+
+ # Format time
+ ref_date = curr_hurricane[0].ref_time
+ xtime = []
+ for it in range(0,len(curr_hurricane)-1):
+ t = curr_hurricane[it].time
+ date = ref_date + datetime.timedelta(hours=np.float64(t))
+ xtime.append(date.strftime('%Y-%m-%d_%H:%M:%S'+45*' '))
+ xtime = np.asarray(xtime)
+ xtime_list = []
+ for t in xtime:
+ xtime_list.append(list(t))
+ time_var[:] = xtime_list
+
+ # Assign variables
+ kmh_to_mps = 0.277778
+ mbar_to_pa = 100.0
+ for it in range(0, len(curr_hurricane)-1):
+ u_var[it, :] = winds[it].u * kmh_to_mps
+ v_var[it, :] = winds[it].v * kmh_to_mps
+ pres_var[it, :] = winds[it].pressure_profile * mbar_to_pa
+
+ # Close
+ rootgrp.close()
diff --git a/testing_and_setup/compass/ocean/hurricane/init_template.xml b/testing_and_setup/compass/ocean/hurricane/init_template.xml
index 0c6a8711d5..898eb409fd 100644
--- a/testing_and_setup/compass/ocean/hurricane/init_template.xml
+++ b/testing_and_setup/compass/ocean/hurricane/init_template.xml
@@ -9,6 +9,12 @@
+
+
+
+
+
+
@@ -41,6 +47,7 @@
+
diff --git a/testing_and_setup/compass/ocean/hurricane/init_variable_drag.xml b/testing_and_setup/compass/ocean/hurricane/init_variable_drag.xml
new file mode 100644
index 0000000000..e62ecad5e4
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/init_variable_drag.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ output
+ forcing.nc
+ truncate
+ 0000_00:00:01
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/init_wetting_drying_template.xml b/testing_and_setup/compass/ocean/hurricane/init_wetting_drying_template.xml
new file mode 100644
index 0000000000..a055e0ad3c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/init_wetting_drying_template.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/maxwaterlevel_template.xml b/testing_and_setup/compass/ocean/hurricane/maxwaterlevel_template.xml
new file mode 100644
index 0000000000..c40cdacf52
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/maxwaterlevel_template.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ output
+ maxWaterLevel.nc
+ 00-01-00_00:00:00
+ 01-01-01_00:00:00
+ truncate
+ pnetcdf
+ timeSeriesStatsCustomAMPKG
+ 00-00-00_01:00:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ input;output
+ restarts/mpaso.rst.am.timeSeriesStatsCustom.$Y-$M-$D_$S.nc
+ output_interval
+ 0001-01-01_00:00:00
+ truncate
+ timeSeriesStatsCustomAMPKG
+ initial_only
+ stream:restart:output_interval
+
+
+
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/NOAA-COOPS_stations.txt b/testing_and_setup/compass/ocean/hurricane/sandy_stations/NOAA-COOPS_stations.txt
similarity index 100%
rename from testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/NOAA-COOPS_stations.txt
rename to testing_and_setup/compass/ocean/hurricane/sandy_stations/NOAA-COOPS_stations.txt
diff --git a/testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/USGS_stations.txt b/testing_and_setup/compass/ocean/hurricane/sandy_stations/USGS_stations.txt
similarity index 100%
rename from testing_and_setup/compass/ocean/hurricane/USDEQU120at30cr10rr2/sandy/USGS_stations.txt
rename to testing_and_setup/compass/ocean/hurricane/sandy_stations/USGS_stations.txt
diff --git a/testing_and_setup/compass/ocean/hurricane/concatenate_cfsr.py b/testing_and_setup/compass/ocean/hurricane/scripts/concatenate_cfsr.py
similarity index 73%
rename from testing_and_setup/compass/ocean/hurricane/concatenate_cfsr.py
rename to testing_and_setup/compass/ocean/hurricane/scripts/concatenate_cfsr.py
index 1a82fec108..91d2460c18 100644
--- a/testing_and_setup/compass/ocean/hurricane/concatenate_cfsr.py
+++ b/testing_and_setup/compass/ocean/hurricane/scripts/concatenate_cfsr.py
@@ -1,3 +1,7 @@
+# Author: Steven Brus
+# Date: August 2019
+# Description: This script concatenates a series of CFSR data files into a single file
+
import subprocess
import os
import glob
diff --git a/testing_and_setup/compass/ocean/hurricane/create_pointstats_file.py b/testing_and_setup/compass/ocean/hurricane/scripts/create_pointstats_file.py
similarity index 93%
rename from testing_and_setup/compass/ocean/hurricane/create_pointstats_file.py
rename to testing_and_setup/compass/ocean/hurricane/scripts/create_pointstats_file.py
index d89a72bf49..e1e9f17fc4 100644
--- a/testing_and_setup/compass/ocean/hurricane/create_pointstats_file.py
+++ b/testing_and_setup/compass/ocean/hurricane/scripts/create_pointstats_file.py
@@ -1,3 +1,8 @@
+# Author: Steven Brus
+# Date: August 2019
+# Description: Creates an input file for the pointwiseStats AM for a given mesh
+# based off of a list of station locations.
+
import netCDF4
import numpy as np
from scipy import spatial
@@ -76,7 +81,7 @@ def create_pointstats_file(mesh_file,stations_files):
pnt_ids = data_nc.createVariable('pointCellGlobalID',np.int32,(npts,))
# Set variables
- pnt_ids[:] = idx[:]
+ pnt_ids[:] = idx[:]+1
data_nc.close()
######################################################################################
diff --git a/testing_and_setup/compass/ocean/hurricane/interpolate_time_varying_forcing.py b/testing_and_setup/compass/ocean/hurricane/scripts/interpolate_time_varying_forcing.py
similarity index 83%
rename from testing_and_setup/compass/ocean/hurricane/interpolate_time_varying_forcing.py
rename to testing_and_setup/compass/ocean/hurricane/scripts/interpolate_time_varying_forcing.py
index b3e0cef560..d315a7b00b 100644
--- a/testing_and_setup/compass/ocean/hurricane/interpolate_time_varying_forcing.py
+++ b/testing_and_setup/compass/ocean/hurricane/scripts/interpolate_time_varying_forcing.py
@@ -1,3 +1,8 @@
+# Author: Steven Brus
+# Date: August, 2019
+# Description: Interpolates CFSR atmospheric reanalysis data onto the MPAS-O mesh and
+# creates an input file to support time varying atmospheric forcing in the model
+
import netCDF4
import matplotlib.pyplot as plt
import numpy as np
@@ -12,6 +17,7 @@
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from scipy import interpolate
+import write_forcing_file
plt.switch_backend('agg')
cartopy.config['pre_existing_data_dir'] = \
os.getenv('CARTOPY_DIR', cartopy.config.get('pre_existing_data_dir'))
@@ -72,34 +78,6 @@ def interpolate_data_to_grid(grid_file,data_file,var):
##################################################################################################
##################################################################################################
-def write_to_file(filename,data,var,xtime):
-
- if os.path.isfile(filename):
- data_nc = netCDF4.Dataset(filename,'a', format='NETCDF3_64BIT_OFFSET')
- else:
- data_nc = netCDF4.Dataset(filename,'w', format='NETCDF3_64BIT_OFFSET')
-
- # Find dimesions
- ncells = data.shape[1]
- nsnaps = data.shape[0]
-
- # Declare dimensions
- data_nc.createDimension('nCells',ncells)
- data_nc.createDimension('StrLen',64)
- data_nc.createDimension('Time',None)
-
- # Create time variable
- time = data_nc.createVariable('xtime','S1',('Time','StrLen'))
- time[:,:] = netCDF4.stringtochar(xtime)
-
- # Set variables
- data_var = data_nc.createVariable(var,np.float64,('Time','nCells'))
- data_var[:,:] = data[:,:]
- data_nc.close()
-
-##################################################################################################
-##################################################################################################
-
def plot_interp_data(lon_data,lat_data,data,lon_grid,lat_grid,interp_data,var_label,var_abrev,time):
@@ -154,7 +132,11 @@ def plot_interp_data(lon_data,lat_data,data,lon_grid,lat_grid,interp_data,var_la
# Interpolation of u and v velocities
lon_grid,lat_grid,u_interp,lon_data,lat_data,u_data,xtime = interpolate_data_to_grid(grid_file,wind_file,'U_GRD_L103')
+ # Write to NetCDF file
+ subprocess.call(['rm',forcing_file])
+ write_forcing_file.write_to_file(forcing_file,u_interp,'windSpeedU',xtime)
lon_grid,lat_grid,v_interp,lon_data,lat_data,v_data,xtime = interpolate_data_to_grid(grid_file,wind_file,'V_GRD_L103')
+ write_forcing_file.write_to_file(forcing_file,v_interp,'windSpeedV',xtime)
# Calculate and plot velocity magnitude
if args.plot:
@@ -168,8 +150,13 @@ def plot_interp_data(lon_data,lat_data,data,lon_grid,lat_grid,interp_data,var_la
plot_interp_data(lon_data,lat_data,data,lon_grid,lat_grid,interp_data,'velocity magnitude','vel',xtime[i])
+ del u_interp
+ del u_data
+ del v_interp
+ del v_data
# Interpolation of atmospheric pressure
lon_grid,lat_grid,p_interp,lon_data,lat_data,p_data,xtime = interpolate_data_to_grid(grid_file,pres_file,'PRMSL_L101')
+ write_forcing_file.write_to_file(forcing_file,p_interp,'atmosPressure',xtime)
# Plot atmopheric pressure
if args.plot:
@@ -179,10 +166,6 @@ def plot_interp_data(lon_data,lat_data,data,lon_grid,lat_grid,interp_data,var_la
print('Plotting pres: '+str(i))
plot_interp_data(lon_data,lat_data,p_data[i,:,:],lon_grid,lat_grid,p_interp[i,:],'atmospheric pressure','pres',xtime[i])
-
- # Write to NetCDF file
- subprocess.call(['rm',forcing_file])
- write_to_file(forcing_file,u_interp,'windSpeedU',xtime)
- write_to_file(forcing_file,v_interp,'windSpeedV',xtime)
- write_to_file(forcing_file,p_interp,'atmosPressure',xtime)
+ del p_interp
+ del p_data
diff --git a/testing_and_setup/compass/ocean/hurricane/scripts/spinup_time_varying_forcing.py b/testing_and_setup/compass/ocean/hurricane/scripts/spinup_time_varying_forcing.py
new file mode 100644
index 0000000000..d2620d13ff
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/scripts/spinup_time_varying_forcing.py
@@ -0,0 +1,72 @@
+# Author: Steven Brus
+# Date April, 2020
+# Description:
+# This creates a "dummy" time varying forcing file
+# with zero wind zero atmospheric pressure perturbation
+# for the tidal spinup run.
+#
+# The tidal spinup is run using this "dummy" atmospheric forcing
+# because the time varying atmospheric forcing for the
+# forward run requires information in the restart file.
+# The inclusion of this additional information in the restart
+# file is trigged by the use of time varying atmospheric forcing
+# in the tidal spinup.
+
+import netCDF4
+import matplotlib.pyplot as plt
+import numpy as np
+import glob
+import pprint
+import datetime
+import os
+import yaml
+import subprocess
+import argparse
+import write_forcing_file
+plt.switch_backend('agg')
+
+##################################################################################################
+##################################################################################################
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--start_time')
+ parser.add_argument('--spinup_length')
+ args = parser.parse_args()
+
+ # Files to interpolate to/from
+ grid_file = './mesh.nc'
+ forcing_file = 'spinup_atmospheric_forcing.nc'
+
+ # Setup timestamps
+ # (3 time snaps are needed because new data will be read in at the end of the simulation)
+ dtformat = '%Y-%m-%d_%H:%M:%S'
+ start_time = datetime.datetime.strptime(args.start_time,dtformat)
+ spinup_length = float(args.spinup_length)
+ xtime = []
+ xtime.append(args.start_time+45*' ')
+ next_time = start_time + datetime.timedelta(days=spinup_length)
+ xtime.append(datetime.datetime.strftime(next_time,dtformat)+45*' ')
+ next_time = next_time + datetime.timedelta(days=spinup_length)
+ xtime.append(datetime.datetime.strftime(next_time,dtformat)+45*' ')
+ xtime = np.array(xtime,'S64')
+ print(xtime)
+
+ # Get grid from grid file
+ grid_nc = netCDF4.Dataset(grid_file,'r')
+ lon_grid = grid_nc.variables['lonCell'][:]
+ ncells = lon_grid.size
+
+ # Initialize atmospheric forcing fields
+ u_data = np.zeros((3,ncells))
+ v_data = np.zeros((3,ncells))
+ p_data = np.zeros((3,ncells)) + 101325.0
+ print(p_data.shape)
+
+ # Write to NetCDF file
+ subprocess.call(['rm',forcing_file])
+ write_forcing_file.write_to_file(forcing_file,u_data,'windSpeedU',xtime)
+ write_forcing_file.write_to_file(forcing_file,v_data,'windSpeedV',xtime)
+ write_forcing_file.write_to_file(forcing_file,p_data,'atmosPressure',xtime)
+
diff --git a/testing_and_setup/compass/ocean/hurricane/scripts/vegetation_tif_to_mpas.py b/testing_and_setup/compass/ocean/hurricane/scripts/vegetation_tif_to_mpas.py
new file mode 100644
index 0000000000..e0f0665fb9
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/scripts/vegetation_tif_to_mpas.py
@@ -0,0 +1,223 @@
+# Author: Zhendong Cao
+# Date: July 2020
+# Description: This python script is used to generate vegetationInfo_Delaware.nc
+# by reading and interpolating the data of vegetation properties and
+# Manning's roughness coefficients from tif files to the MPAS-O grid file.
+
+####################################################################################################
+#################################### function to read tif files ####################################
+def read_tif(filename):
+
+ gtif = gdal.Open(filename)
+ if gtif is None:
+ print ('Unable to open tif file')
+ sys.exit(1)
+ band1 = gtif.GetRasterBand(1)
+ geotransform = gtif.GetGeoTransform()
+ data = band1.ReadAsArray()
+
+ # set negative vegetation data to zero
+ data[data<0.0]=0.0
+
+ # convert gettransform info to lat/lon
+ orig_lon, lon_res, a, orig_lat, b, lat_res = geotransform
+ nlat, nlon = data.shape
+ lat=[]
+ lon=[]
+
+ for i in range(nlat):
+ lat_i = orig_lat + i * lat_res
+ lat.append(lat_i)
+
+ for j in range(nlon):
+ lon_j = orig_lon + j * lon_res
+ lon.append(lon_j)
+
+ return data, lat, lon
+
+def mesh_tri(grid_file):
+
+ ncmesh = Dataset(grid_file,'r')
+ lon_mesh = np.rad2deg(ncmesh.variables['lonCell'][:])-360.0
+ #lon_mesh = np.rad2deg(np.mod(ncmesh.variables['lonCell'][:] + np.pi, 2.0*np.pi) - np.pi)
+ lat_mesh = np.rad2deg(ncmesh.variables['latCell'][:])
+ nEdgesOnCell = ncmesh.variables['nEdgesOnCell'][:]
+ cellsOnCell = ncmesh.variables['cellsOnCell'][:,:]
+
+ # Triangulate cells
+ triangles = Triangulation(lon_mesh,lat_mesh)
+
+ # Compute triangulation mask (needs to be vectorized)
+ mask = np.array(np.zeros((triangles.triangles.shape[0],)),dtype=bool)
+ ntri = triangles.neighbors.shape[0]
+ for i in range(ntri):
+ k = 0
+ for j in range(3):
+ n = triangles.triangles[i,j]
+ if nEdgesOnCell[n] != np.where(cellsOnCell[n,:] != 0)[0].size: # Mask triangles
+ k = k +1 # containing
+ if k == 3: # 3 boundary
+ mask[i] = True # cells
+ triangles.set_mask(mask)
+
+
+ return triangles
+
+######################## function to interpolate tif data to MPAS-O grid ###########################
+def interpolate_data_to_grid(data_file,grid_file,fill=0):
+
+ # get tif data info
+ data, lat_data, lon_data = read_tif(data_file)
+
+ # get MPAS-O grid data info
+ grid_nc = Dataset(grid_file, 'r')
+ lon_grid = grid_nc.variables['lonCell'][:]*180.0/np.pi-360
+ lat_grid = grid_nc.variables['latCell'][:]*180.0/np.pi
+ grid_points = np.column_stack((lon_grid, lat_grid))
+ ncells = lon_grid.size
+ interp_data = np.zeros((ncells))
+
+ # interpolate tif data onto new grid
+ interpolator = grid_interpolator((lon_data,lat_data[::-1]),np.flipud(data).T,
+ method='nearest',
+ bounds_error=False,fill_value=fill)
+ interp_data = interpolator(grid_points)
+
+ return lon_data,lat_data,data,lon_grid,lat_grid,interp_data
+
+############################### function to plot interpolated data #################################
+def plot_interp_data(lon_data,lat_data,data,lon_grid,lat_grid,interp_data,tri):
+
+ # plot original data
+ fig, ax = plt.subplots(1,2, figsize=(12,5))
+ levels = np.linspace(np.amin(data),np.amax(data),10)
+ lonn_data, latt_data = np.meshgrid(lon_data, lat_data)
+ cf = ax[0].contourf(lonn_data, latt_data, data, levels=levels)
+ ax[0].set_title('original data')
+ cbar = fig.colorbar(cf,ax=ax[0])
+
+ # plot interpolated data
+ lon_max = np.max(lon_data) + 5.0
+ lon_min = np.min(lon_data) - 5.0
+ lat_max = np.max(lat_data) + 5.0
+ lat_min = np.min(lat_data) - 5.0
+ levels = np.linspace(np.amin(interp_data),np.amax(interp_data),10)
+ cf = ax[1].tricontourf(tri, interp_data, levels=levels)
+ ax[1].set_xlim([lon_min,lon_max])
+ ax[1].set_ylim([lat_min,lat_max])
+ ax[1].set_title('interpolated data')
+ cbar = fig.colorbar(cf,ax=ax[1])
+
+####################################################################################################
+######################################### MAIN CODE ##############################################
+if __name__ == '__main__':
+ import yaml
+ import gdal,osr
+ import os
+ import sys
+ import pprint
+ import numpy as np
+ import matplotlib.pyplot as plt
+ from matplotlib.tri import Triangulation
+ from scipy.interpolate import RegularGridInterpolator as grid_interpolator
+ from netCDF4 import Dataset
+
+################################ read config file #################################################
+ pwd = os.getcwd()
+ f = open(pwd+'/vegetation_tif_to_mpas.config')
+ cfg = yaml.load(f, Loader=yaml.Loader)
+ pprint.pprint(cfg)
+
+ vegMask_file = cfg['input_location'] + cfg['vegetation_mask_file']
+ vegHeight_file = cfg['input_location'] + cfg['vegetation_height_file']
+ vegDensity_file = cfg['input_location'] + cfg['vegetation_density_file']
+ vegDiameter_file = cfg['input_location'] + cfg['vegetation_diameter_file']
+ Manning_file = cfg['input_location'] + cfg['Delaware_Manning_file']
+ grid_file = cfg['mpas_grid_file']
+ bottomDrag_file = cfg['bottomDrag_file']
+ figplot = cfg['figplot']
+ output_file = cfg['output_file']
+
+ tri = mesh_tri(grid_file)
+############################### data interpolation and plot ########################################
+ ##vegetation Mask
+ lon_veg, lat_veg, vegMask, lon_grid, lat_grid, interp_vegMask = interpolate_data_to_grid(vegMask_file, grid_file)
+ vegMask[vegMask==0]=0
+ vegMask[vegMask>0]=1
+ interp_vegMask[interp_vegMask==0]=0
+ interp_vegMask[interp_vegMask>0]=1
+ interp_vegMask = interp_vegMask.astype(int)
+ if (figplot):
+ plot_interp_data(lon_veg, lat_veg, vegMask, lon_grid, lat_grid, interp_vegMask, tri)
+ plt.savefig('vegetation_mask.png')
+
+ ##vegHeight
+ lon_veg, lat_veg, vegHght, lon_grid, lat_grid, interp_vegHght = interpolate_data_to_grid(vegHeight_file, grid_file)
+ if (figplot):
+ plot_interp_data(lon_veg, lat_veg, vegHght, lon_grid, lat_grid, interp_vegHght, tri)
+ plt.savefig('vegetation_height.png')
+
+ ##vegDensity
+ lon_veg, lat_veg, vegDens, lon_grid, lat_grid, interp_vegDens = interpolate_data_to_grid(vegDensity_file, grid_file)
+ if (figplot):
+ plot_interp_data(lon_veg, lat_veg, vegDens, lon_grid, lat_grid, interp_vegDens, tri)
+ plt.savefig('vegetation_density.png')
+
+ ##vegDiameter
+ lon_veg, lat_veg, vegDiam, lon_grid, lat_grid, interp_vegDiam = interpolate_data_to_grid(vegDiameter_file, grid_file)
+ if (figplot):
+ plot_interp_data(lon_veg, lat_veg, vegDiam, lon_grid, lat_grid, interp_vegDiam, tri)
+ plt.savefig('vegetation_diameter.png')
+
+ ##Manning
+ forcing_nc = Dataset(bottomDrag_file,'r')
+ manning_init = forcing_nc.variables['bottomDrag'][:]
+ lon_manning, lat_manning, manning, lon_grid, lat_grid, interp_manning = interpolate_data_to_grid(Manning_file, grid_file, fill=-9999)
+ interp_manning[interp_manning < 1e-5] = manning_init[interp_manning < 1e-5]
+ if (figplot):
+ plot_interp_data(lon_manning, lat_manning, manning, lon_grid, lat_grid, manning_init, tri)
+ plt.savefig('manning_init.png')
+ plot_interp_data(lon_manning, lat_manning, manning, lon_grid, lat_grid, interp_manning, tri)
+ plt.savefig('vegetation_manning.png')
+
+################################# output file generation ###########################################
+ if os.path.exists(output_file):
+ os.remove(output_file)
+
+ newfile = Dataset(output_file,'w', format='NETCDF3_64BIT_OFFSET')
+
+ # define dimension
+ newfile.createDimension('nCells',len(lat_grid))
+
+ # create variables
+ veg_mask = newfile.createVariable('vegetationMask', np.int32, ('nCells'))
+ veg_mask.standard_name='vegetation_mask'
+ veg_mask.units =''
+
+ veg_diam = newfile.createVariable('vegetationDiameter', np.float64, ('nCells'))
+ veg_diam.standard_name='stem diameter of each vegetation shoot'
+ veg_diam.units ='m'
+
+ veg_hght = newfile.createVariable('vegetationHeight', np.float64, ('nCells'))
+ veg_hght.standard_name='stem height of each vegetation shoot'
+ veg_hght.units ='m'
+
+ veg_dens = newfile.createVariable('vegetationDensity', np.float64, ('nCells'))
+ veg_dens.standard_name='stem numbers per unit area'
+ veg_dens.units ='m^{-2}'
+
+ Delaware_manning = newfile.createVariable('bottomDrag', np.float64, ('nCells'))
+ Delaware_manning.standard_name='bottom Manning roughness coefficient'
+ Delaware_manning.units ='s/m^{1/3}'
+
+ # assign variable values
+ veg_mask[:] = interp_vegMask[:]
+ veg_diam[:] = interp_vegDiam[:]
+ veg_hght[:] = interp_vegHght[:]
+ veg_dens[:] = interp_vegDens[:]
+ Delaware_manning[:] = interp_manning[:]
+
+ # close file
+ newfile.close()
+
+##!---------- end of script ---------
diff --git a/testing_and_setup/compass/ocean/hurricane/scripts/write_forcing_file.py b/testing_and_setup/compass/ocean/hurricane/scripts/write_forcing_file.py
new file mode 100644
index 0000000000..26c656091c
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/scripts/write_forcing_file.py
@@ -0,0 +1,38 @@
+# Author: Steven Brus
+# Date: April, 2020
+# Description: This function writes time-varying forcing data to an input file for the model run.
+
+import os
+import numpy as np
+import netCDF4
+
+##################################################################################################
+##################################################################################################
+
+def write_to_file(filename,data,var,xtime):
+
+ if os.path.isfile(filename):
+ data_nc = netCDF4.Dataset(filename,'a', format='NETCDF3_64BIT_OFFSET')
+ else:
+ data_nc = netCDF4.Dataset(filename,'w', format='NETCDF3_64BIT_OFFSET')
+
+ # Find dimesions
+ ncells = data.shape[1]
+ nsnaps = data.shape[0]
+
+ # Declare dimensions
+ data_nc.createDimension('nCells',ncells)
+ data_nc.createDimension('StrLen',64)
+ data_nc.createDimension('Time',None)
+
+ # Create time variable
+ time = data_nc.createVariable('xtime','S1',('Time','StrLen'))
+ time[:,:] = netCDF4.stringtochar(xtime)
+
+ # Set variables
+ data_var = data_nc.createVariable(var,np.float64,('Time','nCells'))
+ data_var[:,:] = data[:,:]
+ data_nc.close()
+
+##################################################################################################
+##################################################################################################
diff --git a/testing_and_setup/compass/ocean/hurricane/synthetic_hurricanes/SANDY_017771.json b/testing_and_setup/compass/ocean/hurricane/synthetic_hurricanes/SANDY_017771.json
new file mode 100644
index 0000000000..ae8efd5d01
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/synthetic_hurricanes/SANDY_017771.json
@@ -0,0 +1,2206 @@
+{
+ "stormId": "17771",
+ "name": "SANDY",
+ "description": "",
+ "date": "20121028",
+ "timeUnits": "hours",
+ "distanceUnits": "miles",
+ "windspeedUnits": "knots",
+ "pressureUnits": "mb",
+ "initialTime": "2012-01-04_00:00:00",
+ "stormTrack": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.7, 30.5]
+ },
+ "properties": {
+ "time": 144,
+ "vf": 10.6573,
+ "minP": 960,
+ "wMax": 65,
+ "rMax": 29.6751,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.0939,
+ "y": 0,
+ "value": 62.9054
+ },
+ {
+ "x": 89.0254,
+ "y": 0,
+ "value": 16.9449
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.5648, 30.6339]
+ },
+ "properties": {
+ "time": 145,
+ "vf": 10.6476,
+ "minP": 959.8746,
+ "wMax": 64.6601,
+ "rMax": 29.7844,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.2305,
+ "y": 0,
+ "value": 62.5808
+ },
+ {
+ "x": 89.3531,
+ "y": 0,
+ "value": 16.9182
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.4323, 30.7696]
+ },
+ "properties": {
+ "time": 146,
+ "vf": 10.6228,
+ "minP": 959.8169,
+ "wMax": 64.5268,
+ "rMax": 29.9093,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.3867,
+ "y": 0,
+ "value": 62.4562
+ },
+ {
+ "x": 89.728,
+ "y": 0,
+ "value": 16.9464
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.3011, 30.9055]
+ },
+ "properties": {
+ "time": 147,
+ "vf": 10.5783,
+ "minP": 959.7638,
+ "wMax": 64.5471,
+ "rMax": 30.036,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.545,
+ "y": 0,
+ "value": 62.4803
+ },
+ {
+ "x": 90.108,
+ "y": 0,
+ "value": 17.0151
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.1696, 31.0403]
+ },
+ "properties": {
+ "time": 148,
+ "vf": 10.5134,
+ "minP": 959.652,
+ "wMax": 64.6681,
+ "rMax": 30.1501,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.6876,
+ "y": 0,
+ "value": 62.6018
+ },
+ {
+ "x": 90.4503,
+ "y": 0,
+ "value": 17.1097
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.0364, 31.1723]
+ },
+ "properties": {
+ "time": 149,
+ "vf": 10.4312,
+ "minP": 959.4185,
+ "wMax": 64.8368,
+ "rMax": 30.237,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.7962,
+ "y": 0,
+ "value": 62.7693
+ },
+ {
+ "x": 90.7109,
+ "y": 0,
+ "value": 17.2155
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.9, 31.3]
+ },
+ "properties": {
+ "time": 150,
+ "vf": 10.3393,
+ "minP": 959,
+ "wMax": 65,
+ "rMax": 30.2815,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.8519,
+ "y": 0,
+ "value": 62.9314
+ },
+ {
+ "x": 90.8446,
+ "y": 0,
+ "value": 17.3174
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.7592, 31.4224]
+ },
+ "properties": {
+ "time": 151,
+ "vf": 10.2773,
+ "minP": 958.3563,
+ "wMax": 65.1146,
+ "rMax": 30.2732,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.8415,
+ "y": 0,
+ "value": 63.0461
+ },
+ {
+ "x": 90.8197,
+ "y": 0,
+ "value": 17.403
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.6141, 31.5405]
+ },
+ "properties": {
+ "time": 152,
+ "vf": 10.2726,
+ "minP": 957.5383,
+ "wMax": 65.1761,
+ "rMax": 30.2222,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.7778,
+ "y": 0,
+ "value": 63.1093
+ },
+ {
+ "x": 90.6667,
+ "y": 0,
+ "value": 17.4717
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.4652, 31.6558]
+ },
+ "properties": {
+ "time": 153,
+ "vf": 10.3186,
+ "minP": 956.6199,
+ "wMax": 65.1901,
+ "rMax": 30.1445,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.6806,
+ "y": 0,
+ "value": 63.1263
+ },
+ {
+ "x": 90.4334,
+ "y": 0,
+ "value": 17.5259
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.3129, 31.7698]
+ },
+ "properties": {
+ "time": 154,
+ "vf": 10.4105,
+ "minP": 955.6749,
+ "wMax": 65.1618,
+ "rMax": 30.0566,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.5708,
+ "y": 0,
+ "value": 63.1023
+ },
+ {
+ "x": 90.1699,
+ "y": 0,
+ "value": 17.568
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.1577, 31.8841]
+ },
+ "properties": {
+ "time": 155,
+ "vf": 10.5457,
+ "minP": 954.777,
+ "wMax": 65.0966,
+ "rMax": 29.9763,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.4703,
+ "y": 0,
+ "value": 63.0426
+ },
+ {
+ "x": 89.9288,
+ "y": 0,
+ "value": 17.6004
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73, 32]
+ },
+ "properties": {
+ "time": 156,
+ "vf": 10.7236,
+ "minP": 954,
+ "wMax": 65,
+ "rMax": 29.9217,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.4021,
+ "y": 0,
+ "value": 62.9525
+ },
+ {
+ "x": 89.7651,
+ "y": 0,
+ "value": 17.6256
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.8401, 32.1191]
+ },
+ "properties": {
+ "time": 157,
+ "vf": 10.949,
+ "minP": 953.3992,
+ "wMax": 64.8817,
+ "rMax": 29.9077,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.3846,
+ "y": 0,
+ "value": 62.8416
+ },
+ {
+ "x": 89.723,
+ "y": 0,
+ "value": 17.6471
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.6779, 32.2425]
+ },
+ "properties": {
+ "time": 158,
+ "vf": 11.2274,
+ "minP": 952.9556,
+ "wMax": 64.7687,
+ "rMax": 29.9322,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.4152,
+ "y": 0,
+ "value": 62.736
+ },
+ {
+ "x": 89.7966,
+ "y": 0,
+ "value": 17.6729
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.5131, 32.3712]
+ },
+ "properties": {
+ "time": 159,
+ "vf": 11.5603,
+ "minP": 952.6315,
+ "wMax": 64.6926,
+ "rMax": 29.9886,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.4858,
+ "y": 0,
+ "value": 62.6663
+ },
+ {
+ "x": 89.9658,
+ "y": 0,
+ "value": 17.7118
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.3453, 32.5064]
+ },
+ "properties": {
+ "time": 160,
+ "vf": 11.9493,
+ "minP": 952.3893,
+ "wMax": 64.6848,
+ "rMax": 30.07,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.5875,
+ "y": 0,
+ "value": 62.6631
+ },
+ {
+ "x": 90.21,
+ "y": 0,
+ "value": 17.7728
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.1744, 32.6489]
+ },
+ "properties": {
+ "time": 161,
+ "vf": 12.3961,
+ "minP": 952.1913,
+ "wMax": 64.7768,
+ "rMax": 30.1692,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.7115,
+ "y": 0,
+ "value": 62.7567
+ },
+ {
+ "x": 90.5075,
+ "y": 0,
+ "value": 17.8653
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72, 32.8]
+ },
+ "properties": {
+ "time": 162,
+ "vf": 12.9025,
+ "minP": 952,
+ "wMax": 65,
+ "rMax": 30.2787,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.8484,
+ "y": 0,
+ "value": 62.9778
+ },
+ {
+ "x": 90.8362,
+ "y": 0,
+ "value": 17.9985
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.8224, 32.9604]
+ },
+ "properties": {
+ "time": 163,
+ "vf": 13.3784,
+ "minP": 951.7829,
+ "wMax": 65.3819,
+ "rMax": 30.392,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 37.9901,
+ "y": 0,
+ "value": 63.3529
+ },
+ {
+ "x": 91.1761,
+ "y": 0,
+ "value": 18.1808
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.6445, 33.1301]
+ },
+ "properties": {
+ "time": 164,
+ "vf": 13.739,
+ "minP": 951.5282,
+ "wMax": 65.9342,
+ "rMax": 30.5064,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.1329,
+ "y": 0,
+ "value": 63.8936
+ },
+ {
+ "x": 91.5191,
+ "y": 0,
+ "value": 18.4161
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.4697, 33.3091]
+ },
+ "properties": {
+ "time": 165,
+ "vf": 13.9962,
+ "minP": 951.2292,
+ "wMax": 66.6645,
+ "rMax": 30.6198,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.2748,
+ "y": 0,
+ "value": 64.607
+ },
+ {
+ "x": 91.8595,
+ "y": 0,
+ "value": 18.7072
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.3016, 33.4971]
+ },
+ "properties": {
+ "time": 166,
+ "vf": 14.1653,
+ "minP": 950.8792,
+ "wMax": 67.5804,
+ "rMax": 30.7305,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.4132,
+ "y": 0,
+ "value": 65.5009
+ },
+ {
+ "x": 92.1916,
+ "y": 0,
+ "value": 19.057
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.1439, 33.6941]
+ },
+ "properties": {
+ "time": 167,
+ "vf": 14.266,
+ "minP": 950.4717,
+ "wMax": 68.6897,
+ "rMax": 30.8366,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.5457,
+ "y": 0,
+ "value": 66.5826
+ },
+ {
+ "x": 92.5097,
+ "y": 0,
+ "value": 19.4685
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71, 33.9]
+ },
+ "properties": {
+ "time": 168,
+ "vf": 14.3227,
+ "minP": 950,
+ "wMax": 70,
+ "rMax": 30.9358,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.6697,
+ "y": 0,
+ "value": 67.8596
+ },
+ {
+ "x": 92.8074,
+ "y": 0,
+ "value": 19.945
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.8731, 34.1146]
+ },
+ "properties": {
+ "time": 169,
+ "vf": 14.3909,
+ "minP": 949.4646,
+ "wMax": 71.5073,
+ "rMax": 31.0278,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.7847,
+ "y": 0,
+ "value": 69.3281
+ },
+ {
+ "x": 93.0834,
+ "y": 0,
+ "value": 20.4863
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.7636, 34.3374]
+ },
+ "properties": {
+ "time": 170,
+ "vf": 14.5024,
+ "minP": 948.8947,
+ "wMax": 73.1611,
+ "rMax": 31.119,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 38.8987,
+ "y": 0,
+ "value": 70.9393
+ },
+ {
+ "x": 93.3569,
+ "y": 0,
+ "value": 21.0791
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.6716, 34.568]
+ },
+ "properties": {
+ "time": 171,
+ "vf": 14.6511,
+ "minP": 948.3269,
+ "wMax": 74.8994,
+ "rMax": 31.2177,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 39.0221,
+ "y": 0,
+ "value": 72.6331
+ },
+ {
+ "x": 93.6531,
+ "y": 0,
+ "value": 21.7063
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.597, 34.8056]
+ },
+ "properties": {
+ "time": 172,
+ "vf": 14.8314,
+ "minP": 947.7975,
+ "wMax": 76.6601,
+ "rMax": 31.3329,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 39.1662,
+ "y": 0,
+ "value": 74.3491
+ },
+ {
+ "x": 93.9988,
+ "y": 0,
+ "value": 22.3507
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.5398, 35.0498]
+ },
+ "properties": {
+ "time": 173,
+ "vf": 15.0376,
+ "minP": 947.3431,
+ "wMax": 78.381,
+ "rMax": 31.4739,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 39.3423,
+ "y": 0,
+ "value": 76.0273
+ },
+ {
+ "x": 94.4216,
+ "y": 0,
+ "value": 22.9942
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.5, 35.3]
+ },
+ "properties": {
+ "time": 174,
+ "vf": 15.2646,
+ "minP": 947,
+ "wMax": 80,
+ "rMax": 31.6503,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 39.5629,
+ "y": 0,
+ "value": 77.6073
+ },
+ {
+ "x": 94.9509,
+ "y": 0,
+ "value": 23.6188
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.4792, 35.5556]
+ },
+ "properties": {
+ "time": 175,
+ "vf": 15.5058,
+ "minP": 946.7847,
+ "wMax": 81.4593,
+ "rMax": 31.867,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 39.8337,
+ "y": 0,
+ "value": 79.033
+ },
+ {
+ "x": 95.6009,
+ "y": 0,
+ "value": 24.2068
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.4861, 35.8162]
+ },
+ "properties": {
+ "time": 176,
+ "vf": 15.8328,
+ "minP": 946.6337,
+ "wMax": 82.7175,
+ "rMax": 32.1076,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.1345,
+ "y": 0,
+ "value": 80.2642
+ },
+ {
+ "x": 96.3228,
+ "y": 0,
+ "value": 24.7444
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.531, 36.0814]
+ },
+ "properties": {
+ "time": 177,
+ "vf": 16.3838,
+ "minP": 946.4633,
+ "wMax": 83.7378,
+ "rMax": 32.3497,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.4372,
+ "y": 0,
+ "value": 81.2649
+ },
+ {
+ "x": 97.0492,
+ "y": 0,
+ "value": 25.2185
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.6244, 36.3508]
+ },
+ "properties": {
+ "time": 178,
+ "vf": 17.3149,
+ "minP": 946.19,
+ "wMax": 84.483,
+ "rMax": 32.57,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.7125,
+ "y": 0,
+ "value": 81.999
+ },
+ {
+ "x": 97.7099,
+ "y": 0,
+ "value": 25.6158
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-70.7771, 36.6239]
+ },
+ "properties": {
+ "time": 179,
+ "vf": 18.772,
+ "minP": 945.7301,
+ "wMax": 84.9161,
+ "rMax": 32.7438,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.9298,
+ "y": 0,
+ "value": 82.4303
+ },
+ {
+ "x": 98.2315,
+ "y": 0,
+ "value": 25.922
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71, 36.9]
+ },
+ "properties": {
+ "time": 180,
+ "vf": 20.8617,
+ "minP": 945,
+ "wMax": 85,
+ "rMax": 32.8453,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 41.0566,
+ "y": 0,
+ "value": 82.5227
+ },
+ {
+ "x": 98.5358,
+ "y": 0,
+ "value": 26.1229
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.2985, 37.1771]
+ },
+ "properties": {
+ "time": 181,
+ "vf": 22.9098,
+ "minP": 943.9613,
+ "wMax": 84.7158,
+ "rMax": 32.8578,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 41.0723,
+ "y": 0,
+ "value": 82.2576
+ },
+ {
+ "x": 98.5735,
+ "y": 0,
+ "value": 26.2083
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-71.6556, 37.4477]
+ },
+ "properties": {
+ "time": 182,
+ "vf": 24.0469,
+ "minP": 942.7556,
+ "wMax": 84.1169,
+ "rMax": 32.8105,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 41.0131,
+ "y": 0,
+ "value": 81.6863
+ },
+ {
+ "x": 98.4314,
+ "y": 0,
+ "value": 26.1892
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.0482, 37.7035]
+ },
+ "properties": {
+ "time": 183,
+ "vf": 24.1401,
+ "minP": 941.5699,
+ "wMax": 83.2744,
+ "rMax": 32.7465,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.9332,
+ "y": 0,
+ "value": 80.8777
+ },
+ {
+ "x": 98.2396,
+ "y": 0,
+ "value": 26.082
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.4527, 37.936]
+ },
+ "properties": {
+ "time": 184,
+ "vf": 23.1226,
+ "minP": 940.5908,
+ "wMax": 82.2599,
+ "rMax": 32.7131,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.8913,
+ "y": 0,
+ "value": 79.901
+ },
+ {
+ "x": 98.1392,
+ "y": 0,
+ "value": 25.9047
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-72.8448, 38.1374]
+ },
+ "properties": {
+ "time": 185,
+ "vf": 20.9596,
+ "minP": 940.0052,
+ "wMax": 81.1446,
+ "rMax": 32.7599,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 40.9498,
+ "y": 0,
+ "value": 78.8252
+ },
+ {
+ "x": 98.2796,
+ "y": 0,
+ "value": 25.6759
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.2, 38.3]
+ },
+ "properties": {
+ "time": 186,
+ "vf": 17.635,
+ "minP": 940,
+ "wMax": 80,
+ "rMax": 32.9383,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 41.1729,
+ "y": 0,
+ "value": 77.7195
+ },
+ {
+ "x": 98.8149,
+ "y": 0,
+ "value": 25.4156
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.501, 38.4283]
+ },
+ "properties": {
+ "time": 187,
+ "vf": 15.0684,
+ "minP": 940.6754,
+ "wMax": 78.8194,
+ "rMax": 33.2859,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 41.6074,
+ "y": 0,
+ "value": 76.5778
+ },
+ {
+ "x": 99.8577,
+ "y": 0,
+ "value": 25.126
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-73.7605, 38.5738]
+ },
+ "properties": {
+ "time": 188,
+ "vf": 15.6224,
+ "minP": 941.7861,
+ "wMax": 77.2848,
+ "rMax": 33.7867,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 42.2334,
+ "y": 0,
+ "value": 75.0927
+ },
+ {
+ "x": 101.3602,
+ "y": 0,
+ "value": 24.7351
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74, 38.8]
+ },
+ "properties": {
+ "time": 189,
+ "vf": 20.5106,
+ "minP": 943,
+ "wMax": 75,
+ "rMax": 34.4144,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 43.018,
+ "y": 0,
+ "value": 72.8814
+ },
+ {
+ "x": 103.2431,
+ "y": 0,
+ "value": 24.148
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.2283, 39.1265]
+ },
+ "properties": {
+ "time": 190,
+ "vf": 22.2445,
+ "minP": 944.059,
+ "wMax": 71.9945,
+ "rMax": 35.1187,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 43.8984,
+ "y": 0,
+ "value": 69.9726
+ },
+ {
+ "x": 105.3562,
+ "y": 0,
+ "value": 23.3752
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.4, 39.4]
+ },
+ "properties": {
+ "time": 191,
+ "vf": 12.3061,
+ "minP": 945,
+ "wMax": 70,
+ "rMax": 35.7324,
+ "thetaMax": 0,
+ "overland": false,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 44.6655,
+ "y": 0,
+ "value": 68.0436
+ },
+ {
+ "x": 107.1972,
+ "y": 0,
+ "value": 22.8873
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.5, 39.5]
+ },
+ "properties": {
+ "time": 192,
+ "vf": 6.3975,
+ "minP": 946,
+ "wMax": 70,
+ "rMax": 36.1588,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 45.1985,
+ "y": 0,
+ "value": 68.0474
+ },
+ {
+ "x": 108.4764,
+ "y": 0,
+ "value": 22.9512
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.658, 39.5656]
+ },
+ "properties": {
+ "time": 193,
+ "vf": 10.1382,
+ "minP": 947.4082,
+ "wMax": 69.1725,
+ "rMax": 36.667,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 45.8338,
+ "y": 0,
+ "value": 67.2458
+ },
+ {
+ "x": 110.0011,
+ "y": 0,
+ "value": 22.7273
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-74.8931, 39.6367]
+ },
+ "properties": {
+ "time": 194,
+ "vf": 13.0918,
+ "minP": 949.2622,
+ "wMax": 67.0774,
+ "rMax": 37.3136,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 46.642,
+ "y": 0,
+ "value": 65.2122
+ },
+ {
+ "x": 111.9408,
+ "y": 0,
+ "value": 22.0914
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-75.1853, 39.7094]
+ },
+ "properties": {
+ "time": 195,
+ "vf": 15.1327,
+ "minP": 951.5052,
+ "wMax": 64.1637,
+ "rMax": 38.072,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 47.59,
+ "y": 0,
+ "value": 62.3827
+ },
+ {
+ "x": 114.216,
+ "y": 0,
+ "value": 21.1854
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-75.5141, 39.7799]
+ },
+ "properties": {
+ "time": 196,
+ "vf": 16.2308,
+ "minP": 954.0804,
+ "wMax": 60.8803,
+ "rMax": 38.9143,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 48.6429,
+ "y": 0,
+ "value": 59.1935
+ },
+ {
+ "x": 116.7429,
+ "y": 0,
+ "value": 20.1532
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-75.8593, 39.8445]
+ },
+ "properties": {
+ "time": 197,
+ "vf": 16.3763,
+ "minP": 956.9309,
+ "wMax": 57.6761,
+ "rMax": 39.8117,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 49.7647,
+ "y": 0,
+ "value": 56.0809
+ },
+ {
+ "x": 119.4352,
+ "y": 0,
+ "value": 19.1404
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-76.2, 39.9]
+ },
+ "properties": {
+ "time": 198,
+ "vf": 15.5667,
+ "minP": 960,
+ "wMax": 55,
+ "rMax": 40.7351,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 50.9188,
+ "y": 0,
+ "value": 53.4813
+ },
+ {
+ "x": 122.2052,
+ "y": 0,
+ "value": 18.2947
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-76.5194, 39.9442]
+ },
+ "properties": {
+ "time": 199,
+ "vf": 14.3441,
+ "minP": 963.2223,
+ "wMax": 53.1844,
+ "rMax": 41.6547,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 52.0683,
+ "y": 0,
+ "value": 51.7179
+ },
+ {
+ "x": 124.964,
+ "y": 0,
+ "value": 17.7272
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-76.8153, 39.9795]
+ },
+ "properties": {
+ "time": 200,
+ "vf": 13.2434,
+ "minP": 966.4989,
+ "wMax": 52.0954,
+ "rMax": 42.5402,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 53.1752,
+ "y": 0,
+ "value": 50.6609
+ },
+ {
+ "x": 127.6205,
+ "y": 0,
+ "value": 17.3958
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-77.0896, 40.0094]
+ },
+ "properties": {
+ "time": 201,
+ "vf": 12.2569,
+ "minP": 969.7223,
+ "wMax": 51.4828,
+ "rMax": 43.3654,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 54.2067,
+ "y": 0,
+ "value": 50.0668
+ },
+ {
+ "x": 130.0961,
+ "y": 0,
+ "value": 17.2192
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-77.3439, 40.0371]
+ },
+ "properties": {
+ "time": 202,
+ "vf": 11.3828,
+ "minP": 972.7853,
+ "wMax": 51.0963,
+ "rMax": 44.1099,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 55.1374,
+ "y": 0,
+ "value": 49.6924
+ },
+ {
+ "x": 132.3298,
+ "y": 0,
+ "value": 17.1152
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-77.58, 40.0662]
+ },
+ "properties": {
+ "time": 203,
+ "vf": 10.6279,
+ "minP": 975.5803,
+ "wMax": 50.6855,
+ "rMax": 44.7601,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 55.9501,
+ "y": 0,
+ "value": 49.2942
+ },
+ {
+ "x": 134.2803,
+ "y": 0,
+ "value": 17.0014
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-77.8, 40.1]
+ },
+ "properties": {
+ "time": 204,
+ "vf": 10.0107,
+ "minP": 978,
+ "wMax": 50,
+ "rMax": 45.3078,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 56.6347,
+ "y": 0,
+ "value": 48.6289
+ },
+ {
+ "x": 135.9233,
+ "y": 0,
+ "value": 16.7948
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-78.0057, 40.1409]
+ },
+ "properties": {
+ "time": 205,
+ "vf": 9.5272,
+ "minP": 979.9711,
+ "wMax": 48.8539,
+ "rMax": 45.7546,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 57.1933,
+ "y": 0,
+ "value": 47.5157
+ },
+ {
+ "x": 137.2639,
+ "y": 0,
+ "value": 16.4333
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-78.1994, 40.1879]
+ },
+ "properties": {
+ "time": 206,
+ "vf": 9.1416,
+ "minP": 981.5571,
+ "wMax": 47.3187,
+ "rMax": 46.123,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 57.6537,
+ "y": 0,
+ "value": 46.0238
+ },
+ {
+ "x": 138.3689,
+ "y": 0,
+ "value": 15.9404
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-78.3834, 40.2393]
+ },
+ "properties": {
+ "time": 207,
+ "vf": 8.8355,
+ "minP": 982.8555,
+ "wMax": 45.5299,
+ "rMax": 46.4358,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 58.0447,
+ "y": 0,
+ "value": 44.2854
+ },
+ {
+ "x": 139.3074,
+ "y": 0,
+ "value": 15.361
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-78.56, 40.293]
+ },
+ "properties": {
+ "time": 208,
+ "vf": 8.594,
+ "minP": 983.9637,
+ "wMax": 43.6234,
+ "rMax": 46.7123,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 58.3903,
+ "y": 0,
+ "value": 42.4323
+ },
+ {
+ "x": 140.1368,
+ "y": 0,
+ "value": 14.7402
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-78.7315, 40.3472]
+ },
+ "properties": {
+ "time": 209,
+ "vf": 8.4073,
+ "minP": 984.9794,
+ "wMax": 41.7349,
+ "rMax": 46.9686,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 58.7108,
+ "y": 0,
+ "value": 40.5965
+ },
+ {
+ "x": 140.9059,
+ "y": 0,
+ "value": 14.1233
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-78.9, 40.4]
+ },
+ "properties": {
+ "time": 210,
+ "vf": 8.2722,
+ "minP": 986,
+ "wMax": 40,
+ "rMax": 47.2188,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 59.0235,
+ "y": 0,
+ "value": 38.9102
+ },
+ {
+ "x": 141.6564,
+ "y": 0,
+ "value": 13.5561
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-79.0671, 40.45]
+ },
+ "properties": {
+ "time": 211,
+ "vf": 8.1243,
+ "minP": 987.0968,
+ "wMax": 38.5295,
+ "rMax": 47.4714,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 59.3393,
+ "y": 0,
+ "value": 37.4808
+ },
+ {
+ "x": 142.4143,
+ "y": 0,
+ "value": 13.0761
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-79.2308, 40.4981]
+ },
+ "properties": {
+ "time": 212,
+ "vf": 7.8959,
+ "minP": 988.2356,
+ "wMax": 37.3336,
+ "rMax": 47.7213,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 59.6517,
+ "y": 0,
+ "value": 36.3184
+ },
+ {
+ "x": 143.164,
+ "y": 0,
+ "value": 12.6875
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-79.3886, 40.5457]
+ },
+ "properties": {
+ "time": 213,
+ "vf": 7.5881,
+ "minP": 989.3559,
+ "wMax": 36.3975,
+ "rMax": 47.9613,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 59.9516,
+ "y": 0,
+ "value": 35.4087
+ },
+ {
+ "x": 143.8838,
+ "y": 0,
+ "value": 12.3859
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-79.5378, 40.5942]
+ },
+ "properties": {
+ "time": 214,
+ "vf": 7.2086,
+ "minP": 990.397,
+ "wMax": 35.7064,
+ "rMax": 48.1855,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 60.2319,
+ "y": 0,
+ "value": 34.7373
+ },
+ {
+ "x": 144.5566,
+ "y": 0,
+ "value": 12.167
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-79.6758, 40.6452]
+ },
+ "properties": {
+ "time": 215,
+ "vf": 6.7741,
+ "minP": 991.2986,
+ "wMax": 35.2455,
+ "rMax": 48.3898,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 60.4872,
+ "y": 0,
+ "value": 34.2899
+ },
+ {
+ "x": 145.1693,
+ "y": 0,
+ "value": 12.0263
+ }
+ ]
+ }
+ }
+ },
+ {
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-79.8, 40.7]
+ },
+ "properties": {
+ "time": 216,
+ "vf": 6.3143,
+ "minP": 992,
+ "wMax": 35,
+ "rMax": 48.5707,
+ "thetaMax": 0,
+ "overland": true,
+ "windData": {
+ "coordinateSystem": "cartesian",
+ "samplePoints": [
+ {
+ "x": 60.7133,
+ "y": 0,
+ "value": 34.0521
+ },
+ {
+ "x": 145.712,
+ "y": 0,
+ "value": 11.9596
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/testing_and_setup/compass/ocean/hurricane/synthetic_hurricanes/SANDY_017771_hurricane_inputs.txt b/testing_and_setup/compass/ocean/hurricane/synthetic_hurricanes/SANDY_017771_hurricane_inputs.txt
new file mode 100755
index 0000000000..c744feed3f
--- /dev/null
+++ b/testing_and_setup/compass/ocean/hurricane/synthetic_hurricanes/SANDY_017771_hurricane_inputs.txt
@@ -0,0 +1,5 @@
+SANDY_017771.json
+2 ! grid flag 1 = regular grid (need further inputs), 2 = nc file (need file name)
+mesh.nc
+1013 ! mbar, ambient pressure
+1. ! holland B parameter
diff --git a/testing_and_setup/compass/ocean/jigsaw_to_MPAS/build_mesh.py b/testing_and_setup/compass/ocean/jigsaw_to_MPAS/build_mesh.py
index 7d3845001a..f43dae3efd 100755
--- a/testing_and_setup/compass/ocean/jigsaw_to_MPAS/build_mesh.py
+++ b/testing_and_setup/compass/ocean/jigsaw_to_MPAS/build_mesh.py
@@ -73,8 +73,8 @@ def build_mesh(
color='gray',
alpha=0.5,
linestyle='-', zorder=2)
- gl.xlabels_top = False
- gl.ylabels_right = False
+ gl.top_labels = False
+ gl.right_labels = False
plt.title(
'Grid cell size, km, min: {:.1f} max: {:.1f}'.format(
cellWidth.min(),cellWidth.max()))
diff --git a/testing_and_setup/compass/ocean/surface_waves/analysis/comparison.py b/testing_and_setup/compass/ocean/surface_waves/analysis/comparison.py
index 3226122ac2..7cd3401802 100755
--- a/testing_and_setup/compass/ocean/surface_waves/analysis/comparison.py
+++ b/testing_and_setup/compass/ocean/surface_waves/analysis/comparison.py
@@ -22,10 +22,11 @@
# data from MPAS-O on boundary
ds = xr.open_mfdataset('output.nc')
-ds.ssh.where(ds.tidalInputMask).mean('nCells').plot(marker='o', label='MPAS-O')
+mask = ds.where(ds.yCell.values.min() == ds.yCell)
+mask.ssh.mean('nCells').plot(marker='o', label='MPAS-O')
plt.legend()
-plt.ylabel('Tidal amplitude (m)')
-plt.xlabel('Time (hrs)')
+plt.ylabel('ssh amplitude (m)')
+plt.xlabel('Time (min)')
plt.savefig('tidalcomparison.png')
diff --git a/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_analysis.xml b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_analysis.xml
new file mode 100644
index 0000000000..5114a4c016
--- /dev/null
+++ b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_analysis.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_driver.xml b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_driver.xml
new file mode 100644
index 0000000000..f7ea893e5e
--- /dev/null
+++ b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_driver.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_forward.xml b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_forward.xml
new file mode 100644
index 0000000000..4a966d98e5
--- /dev/null
+++ b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_forward.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ init.nc
+
+
+ init.nc
+
+
+ input
+ initial_only
+ forcing.nc
+
+
+
+
+
+
+ output
+ truncate
+ output.nc
+ 0000-00-00_00:02:00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ init.nc
+
+
+ 4
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_init1.xml b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_init1.xml
new file mode 100644
index 0000000000..97b5e5072f
--- /dev/null
+++ b/testing_and_setup/compass/ocean/surface_waves/variable_drag/1km/config_init1.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+
+
+ output
+ forcing.nc
+ truncate
+ 0000_00:00:01
+
+
+
+
+
+
+ output
+ 0000_00:01:00
+ truncate
+ ocean.nc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 6
+ 30
+ 1000.0
+
+ grid.nc
+
+
+ grid.nc
+ culled_mesh.nc
+
+
+ culled_mesh.nc
+ mesh.nc
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/templates/analysis_members/sediment_flux_index.xml b/testing_and_setup/compass/ocean/templates/analysis_members/sediment_flux_index.xml
new file mode 100644
index 0000000000..b9c2c89c08
--- /dev/null
+++ b/testing_and_setup/compass/ocean/templates/analysis_members/sediment_flux_index.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ single_file
+ sedimentFluxIndexOutput
+ 01-00-00_00:00:00
+ truncate
+ 00-00-00_00:01:00
+ analysis_members/sedimentFluxIndex.$Y-$M-$D_$h.$m.$s.nc
+ 0001-01-01_00:00:00
+ sedimentFluxIndexAMPKG
+ output
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/templates/analysis_members/sediment_transport.xml b/testing_and_setup/compass/ocean/templates/analysis_members/sediment_transport.xml
new file mode 100644
index 0000000000..1d62acb1ad
--- /dev/null
+++ b/testing_and_setup/compass/ocean/templates/analysis_members/sediment_transport.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ single_file
+ sedimentTransportOutput
+ 01-00-00_00:00:00
+ truncate
+ 00-00-00_00:01:00
+ analysis_members/sedimentTransport.$Y-$M-$D_$h.$m.$s.nc
+ 0001-01-01_00:00:00
+ sedimentTransportAMPKG
+ output
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_base_mesh.xml b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_base_mesh.xml
new file mode 100755
index 0000000000..9284f80658
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_base_mesh.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.build_mesh
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_culled_mesh.xml b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_culled_mesh.xml
new file mode 100644
index 0000000000..1571cf9f6a
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_culled_mesh.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jigsaw_to_MPAS.inject_bathymetry
+ culled_mesh.nc
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_driver_init.xml b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_driver_init.xml
new file mode 100644
index 0000000000..5b34eec160
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/config_driver_init.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/define_base_mesh.py b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/define_base_mesh.py
new file mode 100755
index 0000000000..22628e6d5f
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/build_mesh/define_base_mesh.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import numpy as np
+import jigsaw_to_MPAS.coastal_tools as ct
+
+def cellWidthVsLatLon():
+ km = 1000.0
+
+ params = ct.default_params
+
+ print("****QU 120 background mesh and enhanced Atlantic (30km)****")
+ params["mesh_type"] = "QU"
+ params["dx_max_global"] = 120.0 * km
+ params["region_box"] = ct.Atlantic
+ params["restrict_box"] = ct.Atlantic_restrict
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 30.0 * km
+ params["trans_width"] = 5000.0 * km
+ params["trans_start"] = 500.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(params)
+
+ print("****Northeast refinement (10km)***")
+ params["region_box"] = ct.Delaware_Bay
+ params["plot_box"] = ct.Western_Atlantic
+ params["dx_min_coastal"] = 10.0 * km
+ params["trans_width"] = 600.0 * km
+ params["trans_start"] = 400.0 * km
+
+ cell_width, lon, lat = ct.coastal_refined_mesh(
+ params, cell_width, lon, lat)
+
+ return cell_width / 1000, lon, lat
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_driver.xml b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_driver.xml
new file mode 100644
index 0000000000..765e605959
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_driver.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_forward.xml b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_forward.xml
new file mode 100644
index 0000000000..5a44fc277e
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_forward.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 360
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_init.xml b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_init.xml
new file mode 100644
index 0000000000..16879687b5
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/USDEQU120at30cr10/harmonic_analysis_test/config_init.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+ NOAA-COOPS_stations.txt
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/forward_template.xml b/testing_and_setup/compass/ocean/tides/forward_template.xml
new file mode 100644
index 0000000000..58df5b8096
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/forward_template.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ input.nc
+
+
+ input.nc
+
+
+ points.nc
+ input
+ initial_only
+ single_file
+ forward;analysis
+
+
+
+
+
+
+ 24:00:00
+
+
+
+
+
+
+
+
+
+
+ pointwiseStats.nc
+ output
+ forward;analysis
+ 00:30:00
+ pointwiseStatsAMPKG
+ truncate
+ netcdf
+ single_file
+
+
+
+
+
+
+
+
+
+ harmonicAnalysis.nc
+ output
+ forward;analysis
+ 90_00:00:00
+ harmonicAnalysisAMPKG
+ truncate
+ single_file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ restarts/mpaso.rst.am.harmonicAnalysisRestart.$Y-$M-$D_$h.$m.$s.nc
+ output_interval
+ input;output
+ forward;analysis
+ stream:restart:output_interval
+ initial_only
+ harmonicAnalysisAMPKG
+ truncate
+ single_file
+ 0001-01-01_00:00:00
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/init_template.xml b/testing_and_setup/compass/ocean/tides/init_template.xml
new file mode 100644
index 0000000000..898eb409fd
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/init_template.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mesh.nc
+
+
+ mesh.nc
+ input
+ initial_only
+
+
+
+
+
+ output
+ 0000_00:00:01
+ truncate
+ ocean.nc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing_and_setup/compass/ocean/tides/scripts/create_pointstats_file.py b/testing_and_setup/compass/ocean/tides/scripts/create_pointstats_file.py
new file mode 100644
index 0000000000..e1e9f17fc4
--- /dev/null
+++ b/testing_and_setup/compass/ocean/tides/scripts/create_pointstats_file.py
@@ -0,0 +1,101 @@
+# Author: Steven Brus
+# Date: August 2019
+# Description: Creates an input file for the pointwiseStats AM for a given mesh
+# based off of a list of station locations.
+
+import netCDF4
+import numpy as np
+from scipy import spatial
+import matplotlib.pyplot as plt
+import argparse
+plt.switch_backend('agg')
+
+######################################################################################
+######################################################################################
+
+def lonlat2xyz(lon,lat):
+
+ R = 6378206.4
+ x = R*np.multiply(np.cos(lon),np.cos(lat))
+ y = R*np.multiply(np.sin(lon),np.cos(lat))
+ z = R*np.sin(lat)
+
+ return x,y,z
+
+######################################################################################
+######################################################################################
+
+def create_pointstats_file(mesh_file,stations_files):
+
+ # Read in station locations
+ lon = []
+ lat = []
+ for stations_file in stations_files:
+ f = open(stations_file,'r')
+ lines = f.read().splitlines()
+ for line in lines:
+ lon.append(line.split()[0])
+ lat.append(line.split()[1])
+
+ # Convert station locations
+ lon = np.radians(np.array(lon,dtype=np.float32))
+ lon_idx, = np.where(lon < 0.0)
+ lon[lon_idx] = lon[lon_idx] + 2.0*np.pi
+ lat = np.radians(np.array(lat,dtype=np.float32))
+ stations = np.vstack((lon,lat)).T
+ #x,y,z = lonlat2xyz(lon,lat)
+ #stations = np.vstack((x,y,z)).T
+
+ # Read in cell center coordinates
+ mesh_nc = netCDF4.Dataset(mesh_file,'r')
+ lonCell = np.array(mesh_nc.variables["lonCell"][:])
+ latCell = np.array(mesh_nc.variables["latCell"][:])
+ meshCells = np.vstack((lonCell,latCell)).T
+ #x,y,z = lonlat2xyz(lonCell,latCell)
+ #meshCells = np.vstack((x,y,z)).T
+
+ # Find nearest cell center to each station
+ tree = spatial.KDTree(meshCells)
+ d,idx = tree.query(stations)
+
+ # Plot the station locations and nearest cell centers
+ plt.figure()
+ plt.plot(lonCell[idx],latCell[idx],'.')
+ plt.plot(lon,lat,'.')
+ plt.savefig('station_locations.png')
+
+ # Open netCDF file for writing
+ data_nc = netCDF4.Dataset('points.nc','w', format='NETCDF3_64BIT_OFFSET')
+
+ # Find dimesions
+ npts = idx.shape[0]
+ ncells = lonCell.shape[0]
+
+ # Declare dimensions
+ data_nc.createDimension('nCells',ncells)
+ data_nc.createDimension('StrLen',64)
+ data_nc.createDimension('nPoints',npts)
+
+ # Declear variables
+ npts = data_nc.dimensions['nPoints'].name
+ pnt_ids = data_nc.createVariable('pointCellGlobalID',np.int32,(npts,))
+
+ # Set variables
+ pnt_ids[:] = idx[:]+1
+ data_nc.close()
+
+######################################################################################
+######################################################################################
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--mesh_file', help='file that contains the MPAS mesh information')
+ parser.add_argument('--station_files', action='append', help='list of files that contain station information')
+ args = parser.parse_args()
+
+ #mesh_file = 'culled_mesh.nc'
+ #stations_files= ['USGS_stations/stations_all.txt','NOAA-COOPS_stations/stations.txt']
+
+ create_pointstats_file(args.mesh_file,args.station_files)
+