Skip to content

Commit

Permalink
feat(ArrayReaders): add better error trapping for binary input data
Browse files Browse the repository at this point in the history
* modify ArrayReaders to use standard errmsg variable
* standardize store_error calls in ArrayReaders
* modify list reader so cellid is only checked if no error condition
* add binary array input examples to mf6io
* add binary array input file specifications for each discretization type
* add binary list input file specifications
* add description of change to ReleaseNotes
  • Loading branch information
jdhughes-usgs committed Jul 18, 2023
1 parent e0d5231 commit 630d22d
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 121 deletions.
10 changes: 5 additions & 5 deletions doc/ReleaseNotes/develop.tex
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
% \item xxx
%\end{itemize}

%\textbf{\underline{BUG FIXES AND OTHER CHANGES TO EXISTING FUNCTIONALITY}} \\
%\underline{BASIC FUNCTIONALITY}
%\begin{itemize}
% \item xxx
\textbf{\underline{BUG FIXES AND OTHER CHANGES TO EXISTING FUNCTIONALITY}} \\
\underline{BASIC FUNCTIONALITY}
\begin{itemize}
\item Improve error message if the size of data read from a binary array file is inconsistent with READARRAY control line and variable description keywords.
% \item xxx
% \item xxx
%\end{itemize}
\end{itemize}

%\underline{INTERNAL FLOW PACKAGES}
%\begin{itemize}
Expand Down
10 changes: 7 additions & 3 deletions doc/mf6io/body.tex
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@

%General form of input instructions
\SECTION{Form of Input Instructions}
\input{form_of_input.tex}
\input{framework/form_of_input.tex}
\input{framework/array_data.tex}
\input{framework/binary_array_input}
\input{framework/list_data.tex}
\input{framework/binary_list_input}

%Processing of program input
\SECTION{Processing of Program Input}
\input{processing_of_input.tex}
\input{framework/processing_of_input.tex}

%Simulation name file
\newpage
Expand Down Expand Up @@ -59,7 +63,7 @@
%Binary files
\newpage
\SECTION{Description of Binary Output Files for the Groundwater Flow (GWF) and Groundwater Transport (GWT) Models }
\input{gwf/binaryoutput}
\input{framework/binaryoutput}

\newpage
\ifx\usgsdirector\undefined
Expand Down
48 changes: 14 additions & 34 deletions doc/mf6io/gwf/array_data.tex → doc/mf6io/framework/array_data.tex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
\subsection{Array Input (READARRAY)}
Some GWF Model packages require arrays of information to be provided by the user. This information is read using a generic READARRAY capability in \mf. Within this user guide, variables that are read with READARRAY are marked accordingly, as shown in example input instructions for a DATA block.
Some \mf Model packages require arrays of information to be provided by the user. This information is read using a generic READARRAY capability in \mf. Within this user guide, variables that are read with READARRAY are marked accordingly, as shown in example input instructions for a DATA block.

\begin{lstlisting}[style=blockdefinition]
BEGIN DATA
Expand Down Expand Up @@ -96,15 +96,15 @@ \subsubsection{READARRAY Examples}
\end{lstlisting}


Some arrays define information that is required for the entire model grid, or part of a model grid. This type of information is provided in a special type of data block called a ``GRIDDATA'' block. For example, hydraulic conductivity is required for every cell in the model grid. Hydraulic conductivity is read from a ``GRIDDATA'' block in the NPF Package input file. For GRIDDATA arrays with one value for every cell in the model grid, the arrays can optionally be read in a LAYERED format, in which an array is provided for each layer of the grid. Alternatively, the array can be read for the entire model grid. As an example, consider the GRIDDATA block for the IC Package shown below:
Some arrays define information that is required for the entire model grid, or part of a model grid. This type of information is provided in a special type of data block called a ``GRIDDATA'' block. For example, hydraulic conductivity is required for every cell in the model grid. Hydraulic conductivity is read from a ``GRIDDATA'' block in the \mf GWF NPF Package input file. For GRIDDATA arrays with one value for every cell in the model grid, the arrays can optionally be read in a LAYERED format, in which an array is provided for each layer of the grid. Alternatively, the array can be read for the entire model grid. As an example, consider the GRIDDATA block for the \mf GWF or GWT IC Package shown below:

\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwf-ic-griddata.dat}

Here, the initial heads for the model are provided in the \texttt{strt} array. If the optional LAYERED keyword is present, then a separate array is provided for each layer. If the LAYERED keyword is not present, then the entire starting head array is read at once. The LAYERED keyword may be useful to discretization packages of type DIS and DISV, which support the concept of layers. Models defined with the DISU Package are not layered.

For a structured DIS model, the READARRAY utility is used to read arrays that are dimensioned to the full size of the grid (of size \texttt{nlay*nrow*ncol}). This utility first reads an array name, which associates the input to be read with the desired array. For these arrays, an optional keyword ``LAYERED'' can be located next to the array name. If ``LAYERED'' is detected, then a control line is provided for each layer and the array is filled with values for each model layer. If the ``LAYERED'' keyword is absent, then a single control line is used and the entire array is filled at once.

For example, the following block shows one way the starting head array (STRT) could be specified for a model with 4 layers. Following the array name and the ``LAYERED'' keyword are four control lines, one for each layer.
For example, the following block shows one way the \mf GWF model starting head array (STRT) could be specified for a model with 4 layers. Following the array name and the ``LAYERED'' keyword are four control lines, one for each layer.

\begin{lstlisting}[style=inputfile]
STRT LAYERED
Expand All @@ -121,41 +121,21 @@ \subsubsection{READARRAY Examples}
CONSTANT 10.0 #applies to all cells in the grid
\end{lstlisting}

\subsection{List Input}
Some items consist of several variables, such as layer, row, column, stage, and conductance, for example. List input refers to a block of data with a separate item on each line. For some common list types, the first set of variables is a cell identifier (denoted as \texttt{cellid} in this guide), such as layer, row, and column. With lists, the input data for each item must start on a new line. All variables for an item are assumed to be contained in a single line. Each input variable has a data type, which can be Double Precision, Integer, or Character. Integers are whole numbers and must not include a decimal point or exponent. Double Precision numbers can include a decimal point and an exponent. If no decimal point is included in the entered value, then the decimal point is assumed to be at the right side of the value. Any printable character is allowed for character variables.

Variables starting with the letters I-N are most commonly integers; however, in some instances, a character string may start with the letters I-N. Variables starting with the letters A-H and O-Z are primarily double precision numbers; however, these variable names may also be used for character data. In \mf all variables are explicitly declared within the source code, as opposed to the implicit type declaration in previous MODFLOW versions. This explicit declaration means that the variable type can be easily determined from the source code.

Free formatting is used throughout the input instructions. With free format, values are not required to occupy a fixed number of columns in a line. Each value can occupy one or more columns as required to represent the value; however, the values must still be included in the prescribed order. One or more spaces, or a single comma optionally combined with spaces, must separate adjacent values. Also, a numeric value of zero must be explicitly represented with 0 and not by one or more spaces when free format is used, because detecting the difference between a space that represents 0 and a space that represents a value separator is not possible. Free format is similar to Fortran's list directed input.

Two capabilities included in Fortran's list-directed input are not included in the free-format input implemented in \mf. Null values in which input values are left unchanged from their previous values are not allowed. In general, MODFLOW's input values are not defined prior to their input. A ``/'' cannot be used to terminate an input line without including values for all the variables; data values for all required input variables must be explicitly specified on an input line. For character data, MODFLOW's free format implementation is less stringent than the list-directed input of Fortran. Fortran requires character data to be delineated by apostrophes. MODFLOW does not require apostrophes unless a blank or a comma is part of a character variable.

As an example of a list, consider the PERIOD block for the GHB Package. The input format is shown below:

\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwf-ghb-period.dat}

Each line represents a separate item, which consists of variables. In this case, the first variable of the item, \texttt{cellid} is an array of size \texttt{ncelldim}. The next two variables of the item are \texttt{bhead} and \texttt{cond}. Lastly, the item has two optional variables, \texttt{aux} and \texttt{boundname}. Three of the variables shown in the list are colored in blue. Variables that are colored in blue mean that they can be represented with a time series. The time series capability is described in the section on Time-Variable Input in this document.

The following is simple example of a PERIOD block for the GHB Package, which shows how a list is entered by the user.
In the next example, the ``LAYERED'' keyword is present and binary files are used for each layer. A control line with the ``BINARY'' keyword is required for each layer.

\begin{lstlisting}[style=inputfile]
BEGIN PERIOD 1
# lay row col stage cond
1 13 1 988.0 0.038
1 14 9 1045.0 0.038
END PERIOD
\end{lstlisting}

As described earlier in the section on ``Block and Keyword Input,'' block information can be read from a separate text file. To activate reading a list from separate text file, the first and only entry in the block must be a control line of the following form:

\begin{lstlisting}[style=blockdefinition]
OPEN/CLOSE <fname>
STRT LAYERED
OPEN/CLOSE strt.layer1.bin (BINARY) #layer1
OPEN/CLOSE strt.layer2.bin (BINARY) #layer2
OPEN/CLOSE strt.layer3.bin (BINARY) #layer3
OPEN/CLOSE strt.layer4.bin (BINARY) #layer4
\end{lstlisting}

\noindent where \texttt{fname} is the name of the file containing the list. Lists for the stress packages (CHD, WEL, DRN, RIV, GHB, RCH, and EVT) have an additional BINARY option. The BINARY option is not supported for the advanced stress packages (LAK, MAW, SFR, UZF). The BINARY options is specified as follows:
In the next example, the ``LAYERED'' keyword is absent. In this case, a single control line with the ``BINARY'' keyword is required and the binary file will include the entire data array.

\begin{lstlisting}[style=blockdefinition]
OPEN/CLOSE <fname> [(BINARY)]
\begin{lstlisting}[style=inputfile]
STRT
OPEN/CLOSE strt.bin (BINARY) #layers1-4
\end{lstlisting}

If the (BINARY) keyword is found on the control line, then the file is opened as an unformatted file on unit 99, and the list is read. There are a number of requirements for using the (BINARY) option for lists. All stress package lists begin with integer values for the \texttt{cellid} (layer, row, and column, for example). These values must be represented as integer numbers in the unformatted file. Also, all auxiliary data must be included in the binary file; auxiliary data must be represented as double precision numbers. Lastly, the (BINARY) option does not support entry of \texttt{boundname}, and so the BOUNDNAMES option should not be activated in the OPTIONS block for the package.
A consequence of the way binary input files have been implemented in \mf, simulated dependent variable binary output (for example, head and concentration) cannot be used as binary array input for a model. Instead, simulated dependent variable binary output must be processed and split into separate binary files for each layer or combined into a single three-dimensional array.
88 changes: 88 additions & 0 deletions doc/mf6io/framework/binary_array_input.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
\subsubsection{Description of Binary Array Input Files}
All floating point variables are written to the binary input files as DOUBLE PRECISION Fortran variables. Integer variables are written to the input files as Fortran integer variables. Some variables are character strings and are indicated as so in the following descriptions. Binary array data are written using the following two records:

\vspace{5mm}
\noindent Record 1: \texttt{KSTP,KPER,PERTIM,TOTIM,TEXT,M1,M2,M3} \\
\noindent Record 2: \texttt{DATA} \\

\vspace{5mm}
\noindent where

\begin{description} \itemsep0pt \parskip0pt \parsep0pt
\item \texttt{KSTP} is the time step number;
\item \texttt{KPER} is the stress period number;
\item \texttt{PERTIM} is the time value for the current stress period;
\item \texttt{TOTIM} is the total simulation time;
\item \texttt{TEXT} is a character string (character*16);
\item \texttt{M1} is the length of the data in the fastest varying direction;
\item \texttt{M2} is the length of the data in the second fastest varying direction;
\item \texttt{M3} can be any value but is typically 1 or the layer number for the data; and
\item \texttt{DATA} is the array data of size (M1*M2).
\end{description}

\noindent The values specified for \texttt{M1}, \texttt{M2}, and \texttt{M3} in Record 1 are dependent on the grid type and if the ``LAYERED'' keyword is present on the READARRAY control line. For binary array data, \texttt{KSTP}, \texttt{KPER}, \texttt{PERTIM}, \texttt{TOTIM}, and \texttt{TEXT} can be set to any value. Binary array input file specifications for each discretization type are given below.

\paragraph{DIS Grids}
For DIS grids, \texttt{M1=NCOL}, \texttt{M2=NROW}, and \texttt{M3=ILAY} when the ``LAYERED'' keyword is present on the READARRAY control line. For this case, record 1 and 2 should be written as:

\vspace{5mm}
\noindent Record 1: \texttt{KSTP,KPER,PERTIM,TOTIM,TEXT,M1,M2,M3} \\
\noindent Record 2: \texttt{((DATA(J,I,ILAY),J=1,NCOL),I=1,NROW)} \\

\vspace{5mm}
\noindent where

\begin{description} \itemsep0pt \parskip0pt \parsep0pt
\item \texttt{NCOL} is the number of columns;
\item \texttt{NROW} is the number of rows; and
\item \texttt{ILAY} is the layer number.
\end{description}

\noindent For DIS grids, \texttt{M1=NCOL*NROW*NLAY}, \texttt{M2=1}, and \texttt{M3=1} when the ``LAYERED'' keyword is absent on the READARRAY control line. For this case, record 1 and 2 should be written as:

\vspace{5mm}
\noindent Record 1: \texttt{KSTP,KPER,PERTIM,TOTIM,TEXT,M1,M2,M3} \\
\noindent Record 2: \texttt{(((DATA(J,I,K),J=1,NCOL),I=1,NROW),K=1,NLAY)} \\

\vspace{5mm}
\noindent where

\begin{description} \itemsep0pt \parskip0pt \parsep0pt
\item \texttt{NLAY} is the number of layers.
\end{description}

\paragraph{DISV Grids}
For DISV grids, \texttt{M1=NCPL}, \texttt{M2=1}, and \texttt{M3=ILAY} when the ``LAYERED'' keyword is present on the READARRAY control line. For this case, record 1 and 2 should be written as:

\vspace{5mm}
\noindent Record 1: \texttt{KSTP,KPER,PERTIM,TOTIM,TEXT,M1,M2,M3} \\
\noindent Record 2: \texttt{(DATA(J,ILAY),J=1,NCPL)} \\

\vspace{5mm}
\noindent where

\begin{description} \itemsep0pt \parskip0pt \parsep0pt
\item \texttt{NCPL} is the number of cells per layer.
\end{description}

\noindent For DISV grids, \texttt{M1=NCPL*NLAY}, \texttt{M2=1}, and \texttt{M3=1} when the ``LAYERED'' keyword is absent on the READARRAY control line. For this case, record 1 and 2 should be written as:

\vspace{5mm}
\noindent Record 1: \texttt{KSTP,KPER,PERTIM,TOTIM,TEXT,M1,M2,M3} \\
\noindent Record 2: \texttt{((DATA(J,K),J=1,NCPL),K=1,NLAY)} \\


\paragraph{DISU Grids}
For DISU grids, \texttt{M1=NODES}, \texttt{M2=1}, \texttt{M3=1}. For this case, record 1 and 2 should be written as:


\vspace{5mm}
\noindent Record 1: \texttt{KSTP,KPER,PERTIM,TOTIM,TEXT,M1,M2,M3} \\
\noindent Record 2: \texttt{(DATA(N),N=1,NODES)} \\

\vspace{5mm}
\noindent where

\begin{description} \itemsep0pt \parskip0pt \parsep0pt
\item \texttt{NODES} is the number cells in the model grid.
\end{description}
18 changes: 18 additions & 0 deletions doc/mf6io/framework/binary_list_input.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
\subsubsection{Description of Binary List Input Files}
All floating point variables are written to the binary input files as DOUBLE PRECISION Fortran variables. Integer variables are written to the input files as Fortran integer variables. Auxiliary variables can be included in binary list input files but as indicated previously binary list input files can not be used for packages that include BOUNDNAMES keyword in the OPTIONS block. The format of binary list data are described below.

\vspace{5mm}
\noindent Record 1: \texttt{(CELLID(N),(RLIST(I,N),I=1,NDAT)(AUXVAR(I,N),I=1, NAUX), N=1,NLIST)}\\

\noindent where

\begin{description} \itemsep0pt \parskip0pt \parsep0pt
\item \texttt{CELLID} is the cell identifier, and depends on the type of grid that is used for the simulation.;
\item \texttt{RLIST} is a double precision two-dimensional array of size (NDAT,NLIST) containing the stress package PERIOD data;
\item \texttt{NDAT} is the number of columns in RLIST, which is the number of columns of real data in the stress package PERIOD data;
\item \texttt{AUXVAR} is a double precision two-dimensional array of size (NAUX,NLIST) containing the auxilary data for the stress package PERIOD data;
\item \texttt{NAUX} is the number of columns in AUXVAR, which is the number of columns of real auxiliary data the in stress package PERIOD data;
\item \texttt{NLIST} is the size of the list;
\end{description}

\noindent For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. \texttt{NLIST} must be less than or equal to \texttt{MAXBOUND} for a stress package. \texttt{NAUX} is determined by the number of \texttt{AUXILIARY} variable names define in the OPTIONS block for the stress package.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 630d22d

Please sign in to comment.