diff --git a/.github/workflows/io_gnu_yml.old b/.github/workflows/io_gnu.yml similarity index 100% rename from .github/workflows/io_gnu_yml.old rename to .github/workflows/io_gnu.yml diff --git a/.github/workflows/regtest_gnu.yml b/.github/workflows/regtest_gnu.yml new file mode 100644 index 000000000..3dd5f6d62 --- /dev/null +++ b/.github/workflows/regtest_gnu.yml @@ -0,0 +1,125 @@ +name: regtest_gnu +on: [push, pull_request, workflow_dispatch] + +# Cancel in-progress workflows when pushing to a branch +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + cache_key: gnu11-1 + CC: gcc-10 + FC: gfortran-10 + CXX: g++-10 + + +# Split into a steup step, and a WW3 build step which +# builds multiple switches in a matrix. The setup is run once and +# the environment is cached so each build of WW3 can share the dependencies. + +jobs: + setup: + runs-on: ubuntu-latest + + steps: + - name: checkout-ww3 + if: steps.cache-env.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + path: ww3 + # Cache spack, OASIS, and compiler + # No way to flush Action cache, so key may have # appended + - name: cache-env + id: cache-env + uses: actions/cache@v3 + with: + path: | + spack + ~/.spack + work_oasis3-mct + key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('ww3/model/ci/spack_gnu.yaml') }} + + # Build WW3 spack environment + - name: install-dependencies-with-spack + if: steps.cache-env.outputs.cache-hit != 'true' + run: | + # Install NetCDF, ESMF, g2, etc using Spack + sudo apt install cmake + git clone -c feature.manyFiles=true https://github.com/JCSDA/spack.git + source spack/share/spack/setup-env.sh + spack env create ww3-gnu ww3/model/ci/spack_gnu.yaml + spack env activate ww3-gnu + spack compiler find + spack external find cmake + spack add mpich@3.4.2 + spack concretize + spack install --dirty -v + + - name: build-oasis + if: steps.cache-env.outputs.cache-hit != 'true' + run: | + source spack/share/spack/setup-env.sh + spack env activate ww3-gnu + export WWATCH3_DIR=${GITHUB_WORKSPACE}/ww3/model + export OASIS_INPUT_PATH=${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.14/input/oasis3-mct + export OASIS_WORK_PATH=${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.14/input/work_oasis3-mct + cd ww3/regtests/ww3_tp2.14/input/oasis3-mct/util/make_dir + cmake . + make VERBOSE=1 + cp -r ${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.14/input/work_oasis3-mct ${GITHUB_WORKSPACE} + + regtest_gnu: + needs: setup + runs-on: ubuntu-latest + + steps: + - name: install-dependencies + run: | + sudo apt-get update + sudo apt-get install doxygen gcovr valgrind + + - name: checkout-ww3 + uses: actions/checkout@v3 + with: + path: ww3 + + - name: cache-env + id: cache-env + uses: actions/cache@v3 + with: + path: | + spack + ~/.spack + work_oasis3-mct + key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('ww3/model/ci/spack_gnu.yaml') }} + + - name: build-ww3 + run: | + source spack/share/spack/setup-env.sh + spack env activate ww3-gnu + set -x + cd ww3 + export CC=mpicc + export FC=mpif90 + export OASISDIR=${GITHUB_WORKSPACE}/work_oasis3-mct + mkdir build && cd build + export LD_LIBRARY_PATH="/home/runner/work/WW3/WW3/spack/var/spack/environments/ww3-gnu/.spack-env/view/:$LD_LIBRARY_PATH" + cmake -DSWITCH=${GITHUB_WORKSPACE}/ww3/regtests/unittests/data/switch.io -DCMAKE_BUILD_TYPE=Debug .. + make -j2 VERBOSE=1 + ${GITHUB_WORKSPACE}/ww3/model/bin/ww3_from_ftp.sh + cd ${GITHUB_WORKSPACE}/ww3/regtests + ./bin/run_cmake_test -o all -S -T -s PR1_MPI -w work_PR1_MPI -f -p mpirun -n 24 ../model ww3_tp2.5 + cd ww3_tp2.5 + ls -l + cd work_PR1_MPI + pwd + ls -l + ncdump -h out_pnt.ww3.nc > ncdump_out.txt + cat ncdump_out.txt + pwd + cat ${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.5/out_pnt_ncdump.txt + cmp ${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.5/out_pnt_ncdump.txt ncdump_out.txt + + + + diff --git a/docs/regtests.md b/docs/regtests.md new file mode 100644 index 000000000..21df2da01 --- /dev/null +++ b/docs/regtests.md @@ -0,0 +1,953 @@ +# How to Run the Regtests + +## Set Up Model Environment + +Copy and rename the switch file: +cp /home/ed/WW3/regtests/unittests/data/switch.io model/switch_IO + +Run this command: + +./model/bin/w3_setup /home/ed/WW3/model -c tmpl -s IO + + ***************************** + *** WAVEWATCH III setup *** + ***************************** + + +[INFO] local env file wwatch3.env found in /home/ed/WW3/model/bin/wwatch3.env + Setup file /home/ed/WW3/model/bin/wwatch3.env found + Source directory : /home/ed/WW3/model + Scratch directory : /home/ed/WW3/model/tmp + Save source code : yes + Save listings : yes + Update settings ? [y/n] y + + Creating new set-up : + + Scratch space [/home/ed/WW3/model/tmp] : + Save source code files (*.f) [yes] : + Save listing files [yes] : + + Modified set up : + Scratch directory : /home/ed/WW3/model/tmp + Save sources : yes + Save listings : yes + New settings OK ? [y/n] y + + Setup comp & link files + copy /home/ed/WW3/model/bin/comp.tmpl => /home/ed/WW3/model/bin/comp + copy /home/ed/WW3/model/bin/link.tmpl => /home/ed/WW3/model/bin/link + copy /home/ed/WW3/model/bin/ad3.tmpl => /home/ed/WW3/model/bin/ad3 + + Setup switch file + /home/ed/WW3/model/bin/switch_IO => /home/ed/WW3/model/bin/switch + + Create required model subdirectories + +Finished setting up WAVEWATCH III + + +## Compile WW3 + +Install dependencies with spack as shown in .github/workflow/io_gnu.yml. + +Build WW3 binaries like this: + +cmake -DSWITCH=/home/ed/ww3/regtests/unittests/data/switch.io -DCMAKE_BUILD_TYPE=Debug -DCMAKE_Fortran_FLAGS="-g" -DCMAKE_C_FLAGS="-g" .. +make VERBOSE=1 -j2 +make test + +## Download Test Data + +Download the test data by running the shell script: model/bin/ww3_from_ftp.sh. + +## Run Some Stuff + +In the build directory there is a file ww3_grid.inp. In the build directory execute: +
+./bin/ww3_grid
+
+ +Expect the following output: + +
+
+                   *** WAVEWATCH III Grid preprocessor ***    
+               ===============================================
+
+  Comment character is '$'
+
+  Grid name : 1-D REFRACTION X              
+
+
+  Spectral discretization : 
+ --------------------------------------------------
+       Number of directions        :  24
+       Directional increment (deg.):  15.0
+       First direction       (deg.):   0.0
+       Number of frequencies       :   3
+       Frequency range        (Hz) :   0.0800-0.1250
+       Increment factor            :   1.250
+
+
+  Model definition :
+ --------------------------------------------------
+       Dry run (no calculations)   :  ---/NO
+       Propagation in X-direction  :  YES/--
+       Propagation in Y-direction  :  ---/NO
+       Refraction                  :  YES/--
+       Current-induced k-shift     :  ---/NO
+       Source term calc. and int.  :  ---/NO
+
+
+  Time steps : 
+ --------------------------------------------------
+       Maximum global time step      (s) :  300.00
+       Maximum CFL time step X-Y     (s) :  300.00
+       Maximum CFL time step k-theta (s) :  150.00
+       Minimum source term time step (s) :  300.00
+
+  Preprocessing namelists ...
+  Preprocessing namelists finished.
+
+
+  Stresses (T&C 96)
+ --------------------------------------------------
+
+
+  Linear input not defined.
+
+
+  Wind input not defined.
+
+
+  Nonlinear interactions not defined.
+
+
+  Dissipation not defined.
+
+
+  Bottom friction not defined.
+
+
+  Surf breaking not defined.
+
+
+  Triad interactions not defined.
+
+
+  Bottom scattering not defined.
+
+
+  Propagation scheme : 
+ --------------------------------------------------
+       Type of scheme (structured) : First order upstream          
+                                     (user def. values)
+       CFLmax depth refraction     :    0.750
+
+
+  Ice scattering not defined.
+
+
+  Spectral output on full grid (default values) :  
+ --------------------------------------------------
+       Second order pressure at K=0:   0   1   3
+       Spectrum of Uss             :   0   1   3
+       Frequency spectrum          :   0   1   3
+       Partions of Uss             :   0   1
+       Partition wavenumber # 1   :  0.063
+
+  Miscellaneous (default values) :  
+ --------------------------------------------------
+       Ice concentration cut-offs  :    0.50  0.50
+       Wind input reduction factor in presence of 
+         ice :  1.00
+         (0.0==> no reduction and 1.0==> no wind
+         input with 100% ice cover)
+       Space-time extremes DX-Y set to default 1000 m
+       Space-time extremes Dt set to default 1200 s
+       Compression of track output  :   T
+
+    Dynamic source term integration scheme :
+       Xp                      (-) :    0.150
+       Xr                      (-) :    0.100
+       Xfilt                   (-) :    0.050
+
+    Wave field partitioning :
+       Levels                  (-) :  100
+       Minimum wave height     (m) :    0.050
+       Wind area multiplier    (-) :    1.700
+       Cut-off wind sea fract. (-) :    0.333
+       Combine wind seas           :  YES/--
+       Number of swells in fld out :    5
+       Partitioning method         :  WW3 default                                  
+
+    Miche-style limiting wave height :
+       Hs,max/d factor         (-) :    1.600
+       Hrms,max/d factor       (-) :    1.131
+       Limiter activated           :  ---/NO
+
+    Calendar type                  :  standard
+
+
+  Equivalent namelists ...
+
+  &PRO1 CFLTM = 0.75 /
+  &UNST UGBCCFL =  T, UGOBCAUTO =  T, UGOBCDEPTH = -10.000, UGOBCFILE=unset,
+,  EXPFSN =  T,EXPFSPSI =  F,  EXPFSFCT =  F,IMPFSN =  F,EXPTOTAL=  F,  IMPTOTAL=  F,IMPREFRACTION=  F,  IMPFREQSHIFT=  F, IMPSOURCE=  F,  SETUP_APPLY_WLV=  T,  JGS_TERMINATE_MAXITER=  T,  JGS_TERMINATE_DIFFERENCE=  T,  JGS_TERMINATE_NORM=  F,  JGS_LIMITER=  F,  JGS_LIMITER_FUNC=  1,  JGS_USE_JACOBI=  T,  JGS_BLOCK_GAUSS_SEIDEL=  T,  JGS_MAXITER=  100,  JGS_PMIN=   1.000,  JGS_DIFF_THR=   0.000,  JGS_NORM_THR=   0.000,  JGS_NLEVEL=  0,  JGS_SOURCE_NONLINEAR=  F
+
+  &OUTS P2SF  = 0, I1P2SF = 1, I2P2SF = 15,
+        US3D  = 0, I1US3D =  1, I2US3D =  3,
+        USSP  = 0, IUSSP  =  1,
+        E3D   = 0, I1E3D  =  1, I2E3D  =  3,
+        TH1MF = 0, I1TH1M =  1, I2TH1M =  3,
+        STH1MF= 0, I1STH1M=  1, I2STH1M=  3,
+        TH2MF = 0, I1TH2M =  1, I2TH2M =  3,
+        STH2MF= 0, I1STH2M=  1, I2STH2M=  3 /
+  &MISC CICE0 = 0.500, CICEN = 0.500, LICE =      0.0, PMOVE = 0.500,
+        XSEED = 1.000, FLAGTR = 0, XP = 0.150, XR = 0.100, XFILT = 0.050
+        IHM =  100, HSPM = 0.050, WSM = 1.700, WSC = 0.333, FLC = .TRUE.
+        NOSW =  5, FMICHE = 1.600, RWNDC = 1.000, WCOR1 = 99.00, WCOR2 =  0.00,
+        FACBERG = 1.0, GSHIFT =   0.000E+00, STDX =   -1.00, STDY =  -1.00,
+        STDT =   -1.00, ICEHMIN = 0.20, ICEHFAC = 1.00,
+        ICEHINIT = 0.50, ICEDISP =  F, ICEHDISP = 0.60,
+        ICESLN =   1.00, ICEWIND =   1.00, ICESNL =   1.00, ICESDS =  1.00,
+        ICEDDISP = 80.00, ICEFDISP =  2.00, CALTYPE = standard , TRCKCMPR =   T,
+        BTBET  =   1.20 /
+
+  Equivalent namelists finished.
+
+
+  The spatial grid: 
+ --------------------------------------------------
+
+       Grid type                   : rectilinear
+       Coordinate system           : Cartesian
+       Index closure type          : none
+       Dimensions                  :     13       3
+       Increments             (km) :    5.00    5.00
+       X range                (km) :   -5.00   55.00
+       Y range                (km) :   -5.00    5.00
+
+       Bottom level unit           :    10
+       Limiting depth          (m) :   -1.00
+       Minimum depth           (m) :    1.00
+       Scale factor                :   -1.00
+       Layout indicator            :     2
+       Format indicator            :     1
+
+       Sub-grid information        : Not available.
+  Processing boundary points
+  Processing excluded points
+
+  Input boundary points : 
+ --------------------------------------------------
+       Number of boundary points   :     1
+
+         Nr.|   IX  |   IY  |     X     |     Y     
+       -----|-------|-------|-----------|-----------
+          1 |     2 |     2 |     0.0E3 |     0.0E3
+
+  Excluded points : 
+ --------------------------------------------------
+       Number of excluded points   :    25
+
+
+  Status map, printed in     1 part(s) 
+ -----------------------------------
+
+   3 3 3 3 3 3 3 3 3 3 3 3 0
+   3 2 1 1 1 1 1 1 1 1 1 1 0
+   3 3 3 3 3 3 3 3 3 3 3 3 0
+  
+  Legend : 
+ -----------------------------
+    0 : Land point            
+    1 : Sea point             
+    2 : Active boundary point 
+    3 : Excluded point        
+
+
+  Output boundary points : 
+ --------------------------------------------------
+       No boundary points.
+
+
+  Writing model definition file ...
+
+
+  Summary grid statistics : 
+ --------------------------------------------------
+       Number of longitudes      :        13
+       Number of latitudes       :         3
+       Number of grid points     :        39
+       Number of sea points      :        11 (28.2%)
+       Number of input b. points :         1
+       Number of land points     :         3
+       Number of excluded points :        25
+
+
+  End of program 
+ ========================================
+         WAVEWATCH III Grid preprocessor 
+
+ + +## Running a Regtest + +
+
+ed@Pooh-Bah:~/ww3/regtests/ww3_tp1.1/input$ ../../../build/bin/ww3_grid 
+
+                   *** WAVEWATCH III Grid preprocessor ***    
+               ===============================================
+
+  Grid name : 1-D PROPAGATION EQUATOR       
+
+
+  Spectral discretization : 
+ --------------------------------------------------
+       Number of directions        :   4
+       Directional increment (deg.):  90.0
+       First direction       (deg.):   0.0
+       Number of frequencies       :   3
+       Frequency range        (Hz) :   0.0368-0.0445
+       Increment factor            :   1.100
+
+
+  Model definition :
+ --------------------------------------------------
+       Dry run (no calculations)   :  ---/NO
+       Propagation in X-direction  :  YES/--
+       Propagation in Y-direction  :  ---/NO
+       Refraction                  :  ---/NO
+       Current-induced k-shift     :  ---/NO
+       Source term calc. and int.  :  ---/NO
+
+
+  Time steps : 
+ --------------------------------------------------
+       Maximum global time step      (s) : 3600.00
+       Maximum CFL time step X-Y     (s) : 3600.00
+       Maximum CFL time step k-theta (s) : 3600.00
+       Minimum source term time step (s) : 3600.00
+
+  Preprocessing namelists ...
+  Preprocessing namelists finished.
+
+
+  Stresses (T&C 96)
+ --------------------------------------------------
+
+
+  Linear input not defined.
+
+
+  Wind input not defined.
+
+
+  Nonlinear interactions not defined.
+
+
+  Dissipation not defined.
+
+
+  Bottom friction not defined.
+
+
+  Surf breaking not defined.
+
+
+  Triad interactions not defined.
+
+
+  Bottom scattering not defined.
+
+
+  Propagation scheme : 
+ --------------------------------------------------
+       Type of scheme (structured) : First order upstream          
+                                     (default values)  
+       CFLmax depth refraction     :    0.700
+
+
+  Ice scattering not defined.
+
+
+  Spectral output on full grid (default values) :  
+ --------------------------------------------------
+       Second order pressure at K=0:   0   1   3
+       Spectrum of Uss             :   0   1   3
+       Frequency spectrum          :   0   1   3
+       Partions of Uss             :   0   1
+       Partition wavenumber # 1   :  0.063
+
+  Miscellaneous (default values) :  
+ --------------------------------------------------
+       Ice concentration cut-offs  :    0.50  0.50
+       Wind input reduction factor in presence of 
+         ice :  1.00
+         (0.0==> no reduction and 1.0==> no wind
+         input with 100% ice cover)
+       Space-time extremes DX-Y set to default 1000 m
+       Space-time extremes Dt set to default 1200 s
+       Compression of track output  :   T
+
+    Dynamic source term integration scheme :
+       Xp                      (-) :    0.150
+       Xr                      (-) :    0.100
+       Xfilt                   (-) :    0.050
+
+    Wave field partitioning :
+       Levels                  (-) :  100
+       Minimum wave height     (m) :    0.050
+       Wind area multiplier    (-) :    1.700
+       Cut-off wind sea fract. (-) :    0.333
+       Combine wind seas           :  YES/--
+       Number of swells in fld out :    5
+       Partitioning method         :  WW3 default                                  
+
+    Miche-style limiting wave height :
+       Hs,max/d factor         (-) :    1.600
+       Hrms,max/d factor       (-) :    1.131
+       Limiter activated           :  ---/NO
+
+    Calendar type                  :  standard
+
+
+  Equivalent namelists ...
+
+  &PRO1 CFLTM = 0.70 /
+  &UNST UGBCCFL =  T, UGOBCAUTO =  T, UGOBCDEPTH = -10.000, UGOBCFILE=unset,
+,  EXPFSN =  T,EXPFSPSI =  F,  EXPFSFCT =  F,IMPFSN =  F,EXPTOTAL=  F,  IMPTOTAL=  F,IMPREFRACTION=  F,  IMPFREQSHIFT=  F, IMPSOURCE=  F,  SETUP_APPLY_WLV=  T,  JGS_TERMINATE_MAXITER=  T,  JGS_TERMINATE_DIFFERENCE=  T,  JGS_TERMINATE_NORM=  F,  JGS_LIMITER=  F,  JGS_LIMITER_FUNC=  1,  JGS_USE_JACOBI=  T,  JGS_BLOCK_GAUSS_SEIDEL=  T,  JGS_MAXITER=  100,  JGS_PMIN=   1.000,  JGS_DIFF_THR=   0.000,  JGS_NORM_THR=   0.000,  JGS_NLEVEL=  0,  JGS_SOURCE_NONLINEAR=  F
+
+  &OUTS P2SF  = 0, I1P2SF = 1, I2P2SF = 15,
+        US3D  = 0, I1US3D =  1, I2US3D =  3,
+        USSP  = 0, IUSSP  =  1,
+        E3D   = 0, I1E3D  =  1, I2E3D  =  3,
+        TH1MF = 0, I1TH1M =  1, I2TH1M =  3,
+        STH1MF= 0, I1STH1M=  1, I2STH1M=  3,
+        TH2MF = 0, I1TH2M =  1, I2TH2M =  3,
+        STH2MF= 0, I1STH2M=  1, I2STH2M=  3 /
+  &MISC CICE0 = 0.500, CICEN = 0.500, LICE =      0.0, PMOVE = 0.500,
+        XSEED = 1.000, FLAGTR = 0, XP = 0.150, XR = 0.100, XFILT = 0.050
+        IHM =  100, HSPM = 0.050, WSM = 1.700, WSC = 0.333, FLC = .TRUE.
+        NOSW =  5, FMICHE = 1.600, RWNDC = 1.000, WCOR1 = 99.00, WCOR2 =  0.00,
+        FACBERG = 1.0, GSHIFT =   0.000E+00, STDX =   -1.00, STDY =  -1.00,
+        STDT =   -1.00, ICEHMIN = 0.20, ICEHFAC = 1.00,
+        ICEHINIT = 0.50, ICEDISP =  F, ICEHDISP = 0.60,
+        ICESLN =   1.00, ICEWIND =   1.00, ICESNL =   1.00, ICESDS =  1.00,
+        ICEDDISP = 80.00, ICEFDISP =  2.00, CALTYPE = standard , TRCKCMPR =   T,
+        BTBET  =   1.20 /
+
+  Equivalent namelists finished.
+
+
+  The spatial grid: 
+ --------------------------------------------------
+
+       Grid type                   : rectilinear
+       Coordinate system           : spherical
+       Index closure type          : simple
+       Dimensions                  :    360       3
+
+       Increments           (deg.) :    1.0000    1.0000
+       Longitude range      (deg.) : -180.0000  179.0000
+       Latitude range       (deg.) :   -1.0000    1.0000
+
+       Bottom level unit           :    50
+       Limiting depth          (m) :   -5.00
+       Minimum depth           (m) :    5.75
+       Scale factor                :-2500.00
+       Layout indicator            :     2
+       Format indicator            :     1
+       File name                   : ../input/1-D.depth
+
+       Sub-grid information        : Not available.
+  Processing boundary points
+  Processing excluded points
+
+  Input boundary points : 
+ --------------------------------------------------
+       No boundary points.
+
+
+  Excluded points : 
+ --------------------------------------------------
+       Number of excluded points   :   720
+
+
+  Status map, printed in     5 part(s) 
+ -----------------------------------
+
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+  
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+  
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+  
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+  
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+   3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+  
+  Legend : 
+ -----------------------------
+    0 : Land point            
+    1 : Sea point             
+    2 : Active boundary point 
+    3 : Excluded point        
+
+
+  Output boundary points : 
+ --------------------------------------------------
+       No boundary points.
+
+
+  Writing model definition file ...
+
+
+  Summary grid statistics : 
+ --------------------------------------------------
+       Number of longitudes      :       360
+       Number of latitudes       :         3
+       Number of grid points     :      1080
+       Number of sea points      :       360 (33.3%)
+       Number of input b. points :         0
+       Number of land points     :         0
+       Number of excluded points :       720
+
+
+  End of program 
+ ========================================
+         WAVEWATCH III Grid preprocessor 
+
+ed@Pooh-Bah:~/ww3/regtests/ww3_tp1.1/input$ ../../../build/bin/ww3_strt 
+
+                  *** WAVEWATCH III  Initial conditions ***   
+               ===============================================
+
+  Comment character is '$'
+
+  Grid name : 1-D PROPAGATION EQUATOR       
+
+
+  Initial field ITYPE = 1
+ --------------------------------------------------
+  Negative SIX was provided by user.         
+  WW3 will create a gaussian distribution    
+  that is circular in real space. 
+       Gaussian / cosine power spectrum 
+
+       Peak frequency and spread (Hz)    :    0.0405  0.0001
+       Mean direction (Naut., degr.)     :  270.0
+       Cosine power of dir. distribution :  200
+       Mean longitude and spread (degr.) :    0.00    0.01
+       Mean latitude and spread (degr.)  :    0.00    2.00
+       Maximum wave height               :    2.50
+
+
+  Location : TEST E(f)
+  Spectrum : Unscaled 1-D  Extreme value :  0.100E+01  
+
+           +-------+
+ 0.990E+00 +   *   |
+           |       |
+ 0.770E+00 +       |
+           |       |
+ 0.550E+00 +       |
+           |       |
+ 0.330E+00 +       |
+           |       |
+ 0.110E+00 +       |
+           +-*-|-*-+
+             0.040
+ 
+
+  Location : TEST 2-D
+  Spectrum : Energy (Normalized)   Maximum value :  0.706E+01 m2s
+
+       ang.|  frequencies (Hz) 
+       deg.| 0.040
+       ----+---|---+
+         N |       |
+         E |       |
+         S |       |
+         W |   *   |
+       ----+-------+
+ 
+
+       Converting energy to action ... 
+
+ Variable: Hs Max.:  0.250E+01 m
+ 
+             1      23      45      67      89     111     133     155     177     199     221     243     265     287     309     331     353
+       +-------------------------------------------------------------------+
+     3 |                                                                   |
+       | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
+       |                                                                   |
+       +-------------------------------------------------------------------+
+             1      23      45      67      89     111     133     155     177     199     221     243     265     287     309     331     353
+ 
+
+       Writing restart file  ... 
+
+
+  End of program 
+ =========================================
+         WAVEWATCH III Initial conditions 
+
+ed@Pooh-Bah:~/ww3/regtests/ww3_tp1.1/input$ ../../../build/bin/ww3_prep 
+
+                 *** WAVEWATCH III  Input pre-processing ***  
+               ===============================================
+
+
+ *** WAVEWATCH III ERROR IN W3PREP : 
+     ERROR IN OPENING INPUT FILE
+     IOSTAT =    2
+
+ +## Running WW3 + +These are the steps: +* ww3_grid (generate mod_def.ww3 file). +* ww3_strt (generate initial conditions). +* ww3_prep (generate ice.ww3 file). +* ww3_shel (run the model). +* ww3_outf (print out wave heights). +* ww3_outp (print out some spectra). + +## run_cmake_test + +There is a script called run_cmake_test. It seems relevant: + +
+
+ed@Pooh-Bah:~/ww3/regtests$ ./bin/run_cmake_test -o all -S -T -s PR1_MPI -w work_PR1_MPI              -f -p mpirun -n 24 ../model ww3_tp1.1
+ 
+ Running now options: run_cmake_test -o all -S -T -s PR1_MPI -w work_PR1_MPI -f -p mpirun -n 24 ../model ww3_tp2.1
+ 
+   Building WW3, exes will be in /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/exe
+   Build log is in /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/build.log
+ 
+ 
+                    ==================================   
+                  ======> TEST RUN WAVEWATCH III <====== 
+                    ==================================   
+ 
+#############################################################################
+#                                                                           #
+# ww3_tp2.1 Test script for WW-III, two-dimensional propagation.            #
+#           Propagation under angle with grid.                              #
+#                                                                           #
+# Model should be compiled with the switches :                              #
+#                                                                           #
+#   !/LN0 !/ST0 !/NL0 !/BT0 !/DB0 !/TR0 !/BS0                               #
+#                        Select the 'no source terms' option.               #
+#   !/PRn                Selecting one of the propagation schemes.          #
+#                         1: First order.                                   #
+#                         2: UQ with diffusion term.                        #
+#                         3: UQ with averaging.                             #
+#   !/WNX1 !/WNT1 !/CRX1 !/CRT1      Wind and current interpolation.        #
+#   !/O0 !/O1 !/O2 !/O3 !/O4 !/O5 !/O6 !/O7   Sdt out output options.       #
+#                                                                           #
+# Remarks :                                                                 #
+#                                                                           #
+# - Test case input (default):                                              #
+#   * ww3_grid.inp : (default)                                              #
+#     + Spatial grid: 43 x 43 rectilinear Cartesian grid                    #
+#       - dx = 1 km, dy = 1 km                                              #
+#       - Xrange = -60:360 km, Yrange = -60:360 km                          #
+#       - land mask defined                                                 #
+#     + Spectral grid: ntheta = 24, nf =  3, f1 = 0.03679, fgamma = 1.1     #
+#   * ww3_grid_b.inp :                                                      #
+#     + Spatial grid: 273 x 274 rectilinear Cartesian grid                  #
+#       - dx = 16 km, dy = 16 km                                            #
+#       - Xrange = 0:4352 km, Yrange = 0:4368 km                            #
+#       - no land mask defined                                              #
+#     + Spectral grid: ntheta = 12, nf =  3, f1 = 0.03679, fgamma = 1.1     #
+#   * ww3_grid_c.inp :                                                      #
+#     + Spatial grid: 226 x 331 curvilinear Cartesian grid                  #
+#       - dx and dy are variable                                            #
+#       - Xrange = 1040.39:7000.00 km, Yrange = 2000.00:7959.61 km          #
+#       - input grid coordinates: grd.IDLA1.dat                        #
+#       - no land mask defined                                              #
+#     + Spectral grid: ntheta = 12, nf =  3, f1 = 0.03679, fgamma = 1.1     #
+#   * map2_1.gs: GrADS script for the default grid.                         #
+#   * switch options (mostly self-explanatory).                             #
+#     + switch_PR1      : First order scheme                                #
+#     + switch_PR2_UNO  : UNO scheme with diffusion (off)                   #
+#     + switch_PR2_UQ   : UQ scheme with diffusion (off)                    #
+#     + switch_PR3_UNO  : UNO scheme with averaging (off)                   #
+#     + switch_PR3_UQ   : UQ scheme with averaging (off) (default)          #
+#     + switch_PR1_MPI                                                      #
+#     + switch_PR2_UNO_MPI                                                  #
+#     + switch_PR2_UQ_MPI                                                   #
+#     + switch_PR3_UNO_MPI                                                  #
+#     + switch_PR3_UQ_MPI                                                   #
+#                                                                           #
+#  Sample run_test commands :                                               #
+#   (Note: mpirun commands differ by local system)                          #
+#  ./bin/run_test                             -s PR1   ../model ww3_tp2.1   #
+#  ./bin/run_test -n 3 -p mpirun -f           -s PR1   ../model ww3_tp2.1   # 
+#  ./bin/run_test -g c        -n 3 -p mpirun -s PR3_UQ_MPI \                #          
+#       -w work_c_curv ../model ww3_tp2.1                                   #
+#  ./bin/run_test -g b_pseudo -n 3 -p mpirun -s PR3_UQ_MPI \                #          
+#       -w work_b_curv ../model ww3_tp2.1                                   #
+#                                                                           #
+#                                              Hendrik Tolman, Jun 2002     #
+#                                                   Last Mod : Dec 2013     #
+#                                                                           #
+#    Copyright 2009-2013 National Weather Service (NWS),                    #
+#       National Oceanic and Atmospheric Administration.  All rights        #
+#       reserved.  WAVEWATCH III is a trademark of the NWS.                 #
+#       No unauthorized use without permission.                             #
+#                                                                           #
+#############################################################################
+ 
+ Input directory: /home/ed/ww3/regtests/ww3_tp2.1/input
+ Switch file: /home/ed/ww3/regtests/ww3_tp2.1/input/switch_PR1_MPI
+ 
+ 
++--------------------+
+|  Grid preprocessor |
++--------------------+
+ 
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_grid.inp
+   Screen output routed to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_grid.out
+ 
++--------------------+
+| Initial conditions |
++--------------------+
+ 
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_strt.inp
+   Screen output routed to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_strt.out
+ 
++--------------------+
+|    Main program    |
++--------------------+
+ 
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_shel.inp
+   Screen output copied to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_shel.out
+
+                     *** WAVEWATCH III Program shell ***      
+               ===============================================
+
+  Comment character is '$'
+
+
+  Input fields : 
+ --------------------------------------------------
+       water levels   ---/NO                      
+       currents       ---/NO                      
+       winds          ---/NO                      
+       ice fields     ---/NO                      
+       momentum       ---/NO                      
+       air density    ---/NO                      
+       mean param.    ---/NO                      
+       1D spectra     ---/NO                      
+       2D spectra     ---/NO                      
+ 
+            Fields   : Wave height         
+                       Peak frequency      
+                       Mean wave dir. a1b1 
+                       Peak direction      
+            Fields   : no fields defined
+
+  Initializations :
+ --------------------------------------------------
+
+  Time interval : 
+ --------------------------------------------------
+       Starting time : 1968/06/06 00:00:00 UTC
+       Ending time   : 1968/06/06 05:00:00 UTC
+
+
+  Output requests : 
+ --------------------------------------------------
+       No dedicated output process, any file system.
+
+       Type 1 : Fields of mean wave parameters
+      -----------------------------------------
+            From     : 1968/06/06 00:00:00 UTC
+            To       : 1968/06/08 00:00:00 UTC
+            Interval :            00:06:00
+
+            output dates out of run dates : Restart files second request deactivated
+       Wave model ...
+
+  Running model without input fields
+ --------------------------------------------------
+
+  WAVEWATCH III calculating for 1968/06/06 00:00:00 UTC at 06:08:54
+
+ *** WAVEWATCH III WARNING IN W3IOBC : 
+     INPUT FILE WITH BOUNDARY CONDITIONS NOT FOUND
+     BOUNDARY CONDITIONS WILL NOT BE UPDATED     1
+
+  WAVEWATCH III calculating for 1968/06/06 00:06:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:12:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:18:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:24:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:30:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:36:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:42:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:48:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 00:54:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 01:00:00 UTC at 06:08:54
+  WAVEWATCH III calculating for 1968/06/06 01:06:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:12:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:18:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:24:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:30:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:36:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:42:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:48:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 01:54:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:00:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:06:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:12:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:18:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:24:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:30:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:36:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:42:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:48:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 02:54:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 03:00:00 UTC at 06:08:55
+  WAVEWATCH III calculating for 1968/06/06 03:06:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:12:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:18:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:24:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:30:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:36:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:42:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:48:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 03:54:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:00:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:06:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:12:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:18:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:24:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:30:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:36:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:42:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:48:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 04:54:00 UTC at 06:08:56
+  WAVEWATCH III calculating for 1968/06/06 05:00:00 UTC at 06:08:56
+  WAVEWATCH III reached the end of a computation loop at 06:08:56
+
+  Initialization time :      0.79 s
+  Elapsed time        :      3.09 s
+
+  End of program 
+ ====================================
+         WAVEWATCH III Program shell 
+
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+[WARNING] yaksa: 2 leaked handle pool objects
+ 
++--------------------+
+|   Gridded output   |
++--------------------+
+ 
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_outf_flds_hrly.inp
+   Screen output routed to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_outf_flds_hrly.out
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_outf.inp
+   Screen output routed to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_outf.out
+ 
++--------------------+
+| NC Gridded output  |
++--------------------+
+ 
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_ounf_flds_hrly.inp
+   Screen output routed to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_ounf_flds_hrly.out
+   Processing /home/ed/ww3/regtests/ww3_tp2.1/input/ww3_ounf.inp
+   Screen output routed to /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI/ww3_ounf.out
+ 
+ 
+Files in /home/ed/ww3/regtests/ww3_tp2.1/work_PR1_MPI :
+ 
+total 3024
+drwxrwxr-x 9 ed ed    4096 Apr  2 06:08 build
+-rw-rw-r-- 1 ed ed  395213 Apr  2 06:08 build.log
+drwxrwxr-x 9 ed ed    4096 Apr  2 06:07 build_SHRD
+drwxrwxr-x 2 ed ed    4096 Apr  2 06:07 exe
+-rw-rw-r-- 1 ed ed      32 Apr  2 06:08 finished
+-rw-rw-r-- 1 ed ed    5649 Apr  2 06:08 log.ww3
+-rw-rw-r-- 1 ed ed   47737 Apr  2 06:08 mod_def.ww3
+-rw-rw-r-- 1 ed ed 1214926 Apr  2 06:08 out_grd.ww3
+-rw-rw-r-- 1 ed ed  280800 Apr  2 06:08 restart.ww3
+-rw-rw-r-- 1 ed ed     443 Apr  2 06:08 time_count.txt
+-rw-rw-r-- 1 ed ed  384096 Apr  2 06:08 ww3.196806.nc
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060600.dir
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060600.fp
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060600.hs
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060601.dir
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060601.fp
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060601.hs
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060602.dir
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060602.fp
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060602.hs
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060603.dir
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060603.fp
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060603.hs
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060604.dir
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060604.fp
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060604.hs
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060605.dir
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060605.fp
+-rw-rw-r-- 1 ed ed   22358 Apr  2 06:08 ww3.68060605.hs
+-rw-rw-r-- 1 ed ed   13246 Apr  2 06:08 ww3_grid.out
+-rw-rw-r-- 1 ed ed    3040 Apr  2 06:08 ww3_ounf_flds_hrly.out
+-rw-rw-r-- 1 ed ed    6355 Apr  2 06:08 ww3_ounf.out
+-rw-rw-r-- 1 ed ed    1776 Apr  2 06:08 ww3_outf_flds_hrly.out
+-rw-rw-r-- 1 ed ed  247323 Apr  2 06:08 ww3_outf.out
+-rw-rw-r-- 1 ed ed    5551 Apr  2 06:08 ww3_shel.out
+-rw-rw-r-- 1 ed ed    3405 Apr  2 06:08 ww3_strt.out
+ 
+ 
+                    ==================================   
+                  ======>  END OF WAVEWATCH III  <====== 
+                    ==================================   
+ 
+ +## References + +https://github.com/NOAA-EMC/WW3/wiki/Developer-Guide#regression-testing-in-wavewatch-iii + +WaveWatch III Installation, retrieved from https://www.youtube.com/watch?v=cyyIKqm9R2s&t=1s on Apr 2, 2024. + +file:///home/ed/Downloads/10.WAVEWATCHIII_install.Tolman.pdf \ No newline at end of file diff --git a/model/src/gx_outp.F90 b/model/src/gx_outp.F90 index d34fdbaa7..dacfa69db 100644 --- a/model/src/gx_outp.F90 +++ b/model/src/gx_outp.F90 @@ -165,7 +165,11 @@ PROGRAM GXOUTP #endif USE W3ODATMD, ONLY: W3SETO, W3NOUT USE W3IOGRMD, ONLY: W3IOGR - USE W3IOPOMD, ONLY: W3IOPO + !!!MTM + !!!USE W3IOPOMD, ONLY: W3IOPO + USE W3IOPOMD + USE netcdf + USE W3SERVMD, ONLY : ITRACE, NEXTLN, EXTCDE #ifdef W3_S USE W3SERVMD, ONLY : STRACE @@ -277,7 +281,7 @@ PROGRAM GXOUTP !--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! 3. Read general data and first fields from file ! - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) ALLOCATE ( FLREQ(NOPTS) ) ! WRITE (NDSO,930) @@ -369,7 +373,7 @@ PROGRAM GXOUTP DO DTEST = DSEC21 ( TIME , TOUT ) IF ( DTEST .GT. 0. ) THEN - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) IF ( IOTEST .EQ. -1 ) THEN WRITE (NDSO,998) EXIT diff --git a/model/src/w3iopomd.F90 b/model/src/w3iopomd.F90 index 0c15ea8c6..b7f84df89 100644 --- a/model/src/w3iopomd.F90 +++ b/model/src/w3iopomd.F90 @@ -65,7 +65,7 @@ MODULE W3IOPOMD ! Name Type Scope Description ! ---------------------------------------------------------------- ! VEROPT C*10 Private Point output file version number. - ! IDSTR C*32 Private Point output file ID string. + ! IDSTR C*31 Private Point output file ID string. ! ---------------------------------------------------------------- ! ! 3. Subroutines and functions : @@ -118,6 +118,99 @@ MODULE W3IOPOMD CHARACTER(LEN=10), PARAMETER, PRIVATE :: VEROPT = '2021-04-06' CHARACTER(LEN=31), PARAMETER, PRIVATE :: & IDSTR = 'WAVEWATCH III POINT OUTPUT FILE' + + !> Dimension name for the netCDF point output file, for NOPTS, the + !> Number of Output Points. + character(*), parameter, private :: DNAME_NOPTS = 'NOPTS' + + !> Dimension name for the netCDF point output file, for NSPEC. + character(*), parameter, private :: DNAME_NSPEC = 'NSPEC' + + !> Dimension name for the netCDF point output file, for VSIZE. This + !> is for the vector size for points, which is 2. + character(*), parameter, private :: DNAME_VSIZE = 'VSIZE' + + !> Dimension name for the netCDF point output file, for + !> NAMELEN. This is the length of the PTNME strings, which contains + !> the names of the points. + character(*), parameter, private :: DNAME_NAMELEN = 'NAMELEN' + + !> Dimension name for the netCDF point output file, for GRDIDLEN, + !> this is the length of the GRDID character array. + character(*), parameter, private :: DNAME_GRDIDLEN = 'GRDIDLEN' + + !> Dimension name for the netCDF point output file, for TIME. + character(*), parameter, private :: DNAME_TIME = 'TIME' + + !> Variable name for the netCDF point output file, for NK. + character(*), parameter, private :: VNAME_NK = 'NK' + + !> Variable name for the netCDF point output file, for MTH. + character(*), parameter, private :: VNAME_NTH = 'NTH' + + !> Variable name for the netCDF point output file, for PTLOC. + character(*), parameter, private :: VNAME_PTLOC = 'PTLOC' + + !> Variable name for the netCDF point output file, for PTNME. + character(*), parameter, private :: VNAME_PTNME = 'PTNME' + + !> Variable name for the netCDF point output file, for TIME. + character(*), parameter, private :: VNAME_TIME = 'TIME' + + !> Variable name for the netCDF point output file, for IW. + character(*), parameter, private :: VNAME_IW = 'IW' + + !> Variable name for the netCDF point output file, for II. + character(*), parameter, private :: VNAME_II = 'II' + + !> Variable name for the netCDF point output file, for IL. + character(*), parameter, private :: VNAME_IL = 'IL' + + !> Variable name for the netCDF point output file, for DPO. + character(*), parameter, private :: VNAME_DPO = 'DPO' + + !> Variable name for the netCDF point output file, for WAO. + character(*), parameter, private :: VNAME_WAO = 'WAO' + + !> Variable name for the netCDF point output file, for WDO. + character(*), parameter, private :: VNAME_WDO = 'WDO' + + !> Variable name for the netCDF point output file, for TAUAO. + character(*), parameter, private :: VNAME_TAUAO = 'TAUAO' + + !> Variable name for the netCDF point output file, for TAIDO. + character(*), parameter, private :: VNAME_TAIDO = 'TAIDO' + + !> Variable name for the netCDF point output file, for DAIRO. + character(*), parameter, private :: VNAME_DAIRO = 'DAIRO' + + !> Variable name for the netCDF point output file, for ZET_SETO. + character(*), parameter, private :: VNAME_ZET_SETO = 'ZET_SETO' + + !> Variable name for the netCDF point output file, for ASO. + character(*), parameter, private :: VNAME_ASO = 'ASO' + + !> Variable name for the netCDF point output file, for CAO. + character(*), parameter, private :: VNAME_CAO = 'CAO' + + !> Variable name for the netCDF point output file, for CDO. + character(*), parameter, private :: VNAME_CDO = 'CDO' + + !> Variable name for the netCDF point output file, for ICEO. + character(*), parameter, private :: VNAME_ICEO = 'ICEO' + + !> Variable name for the netCDF point output file, for ICEHO. + character(*), parameter, private :: VNAME_ICEHO = 'ICEHO' + + !> Variable name for the netCDF point output file, for ICEFO. + character(*), parameter, private :: VNAME_ICEFO = 'ICEFO' + + !> Variable name for the netCDF point output file, for GRDID. + character(*), parameter, private :: VNAME_GRDID = 'GRDID' + + !> Variable name for the netCDF point output file, for SPCO. + character(*), parameter, private :: VNAME_SPCO = 'SPCO' + !/ CONTAINS !/ ------------------------------------------------------------------- / @@ -1024,6 +1117,687 @@ SUBROUTINE W3IOPE ( A ) !/ END SUBROUTINE W3IOPE + !> Read point output in netCDF format. + !> + !> @param[out] IOTST Test indictor for reading. + !> @param[in] IMOD Model number for W3GDAT etc. + !> @param[in] filename Name of file to read. + !> @param[inout] ncerr Error code, 0 for success, netCDF error code + !> otherwise. + !> + !> @author Edward Hartnett @date 1-Nov-2023 + !> + SUBROUTINE W3IOPON_READ(IOTST, IMOD, filename, ncerr) + USE NetCDF + USE W3GDATMD, ONLY: NTH, NK, NSPEC, FILEXT + USE W3ODATMD, ONLY: NDST, NDSE, IPASS => IPASS2, NOPTS, IPTINT, & + IL, IW, II, PTLOC, PTIFAC, DPO, WAO, WDO, & + ASO, CAO, CDO, SPCO, PTNME, O2INIT, FNMPRE, & + GRDID, ICEO, ICEHO, ICEFO + USE W3SERVMD, ONLY: EXTCDE +#ifdef W3_FLX5 + USE W3ODATMD, ONLY: TAUAO, TAUDO, DAIRO +#endif +#ifdef W3_SETUP + USE W3ODATMD, ONLY: ZET_SETO +#endif + IMPLICIT NONE + + INTEGER, INTENT(OUT) :: IOTST + INTEGER, INTENT(IN), OPTIONAL :: IMOD + character(*), intent(in) :: filename + integer, intent(inout) :: ncerr + INTEGER :: MK,MTH + integer :: fh + integer :: d_nopts, d_nspec, d_vsize, d_namelen, d_grdidlen + integer :: d_nopts_len, d_nspec_len, d_vsize_len, d_namelen_len, d_grdidlen_len + integer :: v_idtst, v_vertst, v_nk, v_nth, v_ptloc, v_ptnme + integer :: v_iw, v_ii, v_il, v_dpo, v_wao, v_wdo, v_tauao + integer :: v_taido, v_dairo, v_zet_seto, v_aso, v_cao, v_cdo, v_iceo + integer :: v_iceho, v_icefo, v_grdid, v_spco + + IOTST = 0 + IF ( IPASS.EQ.1 ) THEN + ! Open the netCDF file. + ncerr = nf90_open(filename, NF90_NOWRITE, fh) + if (ncerr .ne. 0) return + + ! Read and check the version: + ! TO DO add reading of IDTST and VERTST and make checks: + ! IF ( IDTST .NE. IDSTR ) THEN + ! WRITE (NDSE,902) IDTST, IDSTR + ! CALL EXTCDE ( 10 ) + ! END IF + ! IF ( VERTST .NE. VEROPT ) THEN + ! WRITE (NDSE,903) VERTST, VEROPT + ! CALL EXTCDE ( 11 ) + ! END IF + + + ! Read the dimension information for NOPTS. + ncerr = nf90_inq_dimid(fh, DNAME_NOPTS, d_nopts) + if (ncerr .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_nopts, len = d_nopts_len) + if (ncerr .ne. 0) return + + ! Read the dimension information for NSPEC. + ncerr = nf90_inq_dimid(fh, DNAME_NSPEC, d_nspec) + if (ncerr .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_nspec, len = d_nspec_len) + if (ncerr .ne. 0) return + + ! Read the dimension information for VSIZE. + ncerr = nf90_inq_dimid(fh, DNAME_VSIZE, d_vsize) + if (ncerr .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_vsize, len = d_vsize_len) + if (ncerr .ne. 0) return + + ! Read the dimension information for NAMELEN. + ncerr = nf90_inq_dimid(fh, DNAME_NAMELEN, d_namelen) + if (ncerr .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_namelen, len = d_namelen_len) + if (ncerr .ne. 0) return + + ! Read the dimension information for GRDIDLEN. + ncerr = nf90_inq_dimid(fh, DNAME_GRDIDLEN, d_grdidlen) + if (ncerr .ne. 0) return + ncerr = nf90_inquire_dimension(fh, d_grdidlen, len = d_grdidlen_len) + if (ncerr .ne. 0) return + + ! Read scalar variables. + ncerr = nf90_inq_varid(fh, VNAME_NK, v_nk) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_nk, MK) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_NTH, v_nth) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_nth, MTH) + if (ncerr .ne. 0) return + + !read in written variables NK, NTH as MK and MTH + !and ensure they match + IF (NK.NE.MK .OR. NTH.NE.MTH) THEN + WRITE (NDSE,904) MK, MTH, NK, NTH + CALL EXTCDE ( 12 ) + END IF + + ! Read vars with nopts as a dimension. + ncerr = nf90_inq_varid(fh, VNAME_PTLOC, v_ptloc) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_ptloc, PTLOC) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_PTNME, v_ptnme) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_ptnme, PTNME) + if (ncerr .ne. 0) return + END IF + + !missing variable TIME??? + + ! All of the below variables are missing the "time" dimension... + ! the time dimension being read should be for "IPASS" + ncerr = nf90_inq_varid(fh, VNAME_IW, v_iw) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_iw, IW) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_II, v_ii) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_ii, II) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_IL, v_il) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_il, IL) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_DPO, v_dpo) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_dpo, DPO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_WAO, v_wao) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_wao, WAO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_WDO, v_wdo) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_wdo, WDO) + if (ncerr .ne. 0) return +#ifdef W3_FLX5 + ncerr = nf90_inq_varid(fh, VNAME_TAUAO, v_tauao) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_tauao, TAUAO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_TAIDO, v_taido) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_taido, TAIDO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_DAIRO, v_dairo) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_dairo, DAIRO) + if (ncerr .ne. 0) return +#endif +#ifdef W3_SETUP + ncerr = nf90_inq_varid(fh, ZET_SETO, v_zet_seto) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_zet_seto, ZET_SETO) + if (ncerr .ne. 0) return +#endif + ncerr = nf90_inq_varid(fh, VNAME_ASO, v_aso) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_aso, ASO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_CAO, v_cao) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_cao, CAO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_CDO, v_cdo) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_cdo, CDO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_ICEO, v_iceo) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_iceo, ICEO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_ICEHO, v_iceho) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_iceho, ICEHO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_ICEFO, v_icefo) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_icefo, ICEFO) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_GRDID, v_grdid) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_grdid, GRDID) + if (ncerr .ne. 0) return + ncerr = nf90_inq_varid(fh, VNAME_SPCO, v_spco) + if (ncerr .ne. 0) return + ncerr = nf90_get_var(fh, v_spco, SPCO) + if (ncerr .ne. 0) return + + ! Close the file. + ncerr = nf90_close(fh) + if (ncerr .ne. 0) return + +902 FORMAT (/' *** WAVEWATCH III ERROR IN W3IOPON :'/ & + ' ILEGAL IDSTR, READ : ',A/ & + ' CHECK : ',A/) +903 FORMAT (/' *** WAVEWATCH III ERROR IN W3IOPON :'/ & + ' ILEGAL VEROPT, READ : ',A/ & + ' CHECK : ',A/) +904 FORMAT (/' *** WAVEWATCH III ERROR IN W3IOPO :'/ & + ' ERROR IN SPECTRA, MK, MTH : ',2I8/ & + ' ARRAY DIMENSIONS : ',2I8/) + + + END SUBROUTINE W3IOPON_READ + + !/ ------------------------------------------------------------------- / + !> + !> @brief Write point output in netCDF format. + !> + !> @param[in] IMOD Model number for W3GDAT etc. + !> @param[in] filename Name of file to write. + !> @param[in] timestep_only Will be 0 if whole model run should be + !> written, 1 if only one timestep should be written. + !> @param[inout] ncerr Error code, 0 for success, netCDF error code + !> otherwise. + !> + !> @author Edward Hartnett @date 1-Nov-2023 + !> + SUBROUTINE W3IOPON_WRITE(timestep_only, IMOD, filename, ncerr) + use netcdf + USE W3GDATMD, ONLY: NTH, NK, NSPEC, FILEXT + USE W3WDATMD, ONLY: TIME + USE W3ODATMD, ONLY: NDST, NDSE, IPASS => IPASS2, NOPTS, IPTINT, & + IL, IW, II, PTLOC, PTIFAC, DPO, WAO, WDO, & + ASO, CAO, CDO, SPCO, PTNME, O2INIT, FNMPRE, & + GRDID, ICEO, ICEHO, ICEFO +#ifdef W3_FLX5 + USE W3ODATMD, ONLY: TAUAO, TAUDO, DAIRO +#endif +#ifdef W3_SETUP + USE W3ODATMD, ONLY: ZET_SETO +#endif + + IMPLICIT NONE + integer, intent(in) :: timestep_only ! 1 if only timestep should be written. + INTEGER, INTENT(IN) :: IMOD + character(*), intent(in) :: filename + integer, intent(inout) :: ncerr + integer :: fh, ndim, nvar, fmt, itime + integer :: d_nopts, d_nspec, d_vsize, d_namelen, d_grdidlen, d_time + integer :: v_idtst, v_vertst, v_nk, v_nth, v_ptloc, v_ptnme, v_time + integer :: v_iw, v_ii, v_il, v_dpo, v_wao, v_wdo, v_tauao + integer :: v_taido, v_dairo, v_zet_seto, v_aso, v_cao, v_cdo, v_iceo + integer :: v_iceho, v_icefo, v_grdid, v_spco +!!JDM - defined in module above CHARACTER(LEN=31), PARAMETER :: IDSTR = 'WAVEWATCH III POINT OUTPUT FILE' +!!JDM - defined in module above CHARACTER(LEN=10), PARAMETER :: VEROPT = '2021-04-06' + + write(*,*) 'JDM in write', IPASS, timestep_only + !If first pass, or if you are writting a file for every time-step: + IF ( IPASS.EQ.1 .OR. timestep_only.EQ.1 ) THEN + ! Create the netCDF file. + ncerr = nf90_create(filename, NF90_NETCDF4, fh) + if (ncerr .ne. 0) return + + write(*,*)'JDM a' + ! Define dimensions. + ncerr = nf90_def_dim(fh, DNAME_NOPTS, NOPTS, d_nopts) + if (ncerr .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_NSPEC, NSPEC, d_nspec) + if (ncerr .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_VSIZE, 2, d_vsize) + if (ncerr .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_NAMELEN, 40, d_namelen) + if (ncerr .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_GRDIDLEN, 13, d_grdidlen) + if (ncerr .ne. 0) return + ncerr = nf90_def_dim(fh, DNAME_TIME, NF90_UNLIMITED, d_time) + if (ncerr .ne. 0) return + + write(*,*) 'JDM b' + ! Define global attributes. + ncerr = nf90_put_att(fh, NF90_GLOBAL, 'title', IDSTR) + if (ncerr .ne. 0) return + ncerr = nf90_put_att(fh, NF90_GLOBAL, 'version', VEROPT) + if (ncerr .ne. 0) return + + write(*,*) 'JDM c' + ! Define scalar variables. + ncerr = nf90_def_var(fh, VNAME_NK, NF90_INT, v_nk) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_NTH, NF90_INT, v_nth) + if (ncerr .ne. 0) return + + write(*,*) 'JDM d' + ! Define vars with nopts as a dimension. + ncerr = nf90_def_var(fh, VNAME_PTLOC, NF90_FLOAT, (/d_vsize, d_nopts/), v_ptloc) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_PTNME, NF90_CHAR, (/d_namelen, d_nopts/), v_ptnme) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_TIME, NF90_INT, (/d_vsize, d_time/),v_time) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_IW, NF90_INT, (/d_nopts, d_time/), v_iw) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_II, NF90_INT, (/d_nopts, d_time/), v_ii) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_IL, NF90_INT, (/d_nopts, d_time/), v_il) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_DPO, NF90_FLOAT, (/d_nopts, d_time/), v_dpo) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_WAO, NF90_FLOAT, (/d_nopts, d_time/), v_wao) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_WDO, NF90_FLOAT, (/d_nopts, d_time/), v_wdo) + if (ncerr .ne. 0) return + +#ifdef W3_FLX5 + ncerr = nf90_def_var(fh, VNAME_TAUAO, NF90_FLOAT, (/d_nopts, d_time/), v_tauao) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_TAIDO, NF90_FLOAT, (/d_nopts, d_time/), v_taido) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_DAIRO, NF90_FLOAT, (/d_nopts, d_time/), v_dairo) + if (ncerr .ne. 0) return +#endif +#ifdef W3_SETUP + ncerr = nf90_def_var(fh, VNAME_ZET_SETO, NF90_FLOAT, (/d_nopts, d_time/), v_zet_seto) + if (ncerr .ne. 0) return +#endif + ncerr = nf90_def_var(fh, VNAME_ASO, NF90_FLOAT, (/d_nopts, d_time/), v_aso) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_CAO, NF90_FLOAT, (/d_nopts, d_time/), v_cao) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_CDO, NF90_FLOAT, (/d_nopts, d_time/), v_cdo) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_ICEO, NF90_FLOAT, (/d_nopts, d_time/), v_iceo) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_ICEHO, NF90_FLOAT, (/d_nopts, d_time/), v_iceho) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_ICEFO, NF90_FLOAT, (/d_nopts, d_time/), v_icefo) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_GRDID, NF90_CHAR, (/d_grdidlen, d_nopts, d_time/), v_grdid) + if (ncerr .ne. 0) return + ncerr = nf90_def_var(fh, VNAME_SPCO, NF90_FLOAT, (/d_nspec, d_nopts, d_time/), v_spco) + if (ncerr .ne. 0) return + + write(*,*) 'JDM bb' + ncerr = nf90_enddef(fh) + if (ncerr .ne. 0) return + + write(*,*) 'JDM c' + ! Write the scalar data. + ncerr = nf90_put_var(fh, v_nk, NK) + if (ncerr .ne. 0) return + ncerr = nf90_put_var(fh, v_nth, NTH) + if (ncerr .ne. 0) return + + write(*,*) 'JDM e' + ! Write the data with NOPTS as a dimension. + ncerr = nf90_put_var(fh, v_ptloc, PTLOC) + if (ncerr .ne. 0) return + ncerr = nf90_put_var(fh, v_ptnme, PTNME) + if (ncerr .ne. 0) return + + ELSE + write(*,*) 'JDM else' + ncerr = nf90_open(filename, nf90_write, fh) + if (ncerr .ne. 0) return + END IF + + IF ( timestep_only.EQ.1 ) THEN + itime=1 + ELSE + itime=IPASS + END IF + + + + ! TO DO ADD TIME VARIABLE + write(*,*) 'JDM f 0', TIME + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_TIME, v_time) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_time, TIME, start = (/ 1, itime/), & + count = (/ 2, 1 /)) + if (ncerr .ne. 0) return + + + ! set IW, II and IL to 0 because it is not used and gives & + ! outlier values in out_pnt.points - TODO: REMOVE??? + IW = 0 + II = 0 + IL = 0 + + write(*,*) 'JDM f 1' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_IW, v_iw) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_iw, IW, start = (/ 1, itime/), & + count = (/ NOPTS, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'IW:', IW + write(*,*) 'JDM f 2' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_II, v_ii) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_ii, II, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 3' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_IL, v_il) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_il, IL, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 4' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_DPO, v_dpo) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_dpo, DPO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 5' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_WAO, v_wao) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_wao, WAO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + + write(*,*) 'JDM f 5b' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_WDO, v_wdo) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_wdo, WDO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + + +#ifdef W3_FLX5 + write(*,*) 'JDM f 6' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_TAUAO, v_tauao) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_tauao, TAUAO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 7' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_TAIDO, v_taido) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_taido, TAIDO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 8' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_DAIRO, v_dairo) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_dairo, DAIRO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return +#endif +#ifdef W3_SETUP + write(*,*) 'JDM f 9' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_ZET_SETO, v_zet_seto) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_zet_seto, ZET_SETO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return +#endif + write(*,*) 'JDM f 10' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_ASO, v_aso) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_aso, ASO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 11' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_CAO, v_cao) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_cao, CAO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 11 b' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_CDO, v_cdo) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_cdo, CDO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + + + write(*,*) 'JDM f 12' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_ICEO, v_iceo) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_iceo, ICEO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 13' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_ICEHO, v_iceho) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_iceho, ICEHO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 14' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_ICEFO, v_icefo) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_icefo, ICEFO, start = (/ 1, itime/), & + count = (/ nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 15' + write(*,*) 'GRDID:',GRDID + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_GRDID, v_grdid) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_grdid, GRDID, start = (/ 1, 1, itime/), & + count = (/ 13, nopts, 1 /)) + if (ncerr .ne. 0) return + write(*,*) 'JDM f 16' + IF ( itime > 1 ) THEN + ncerr = nf90_inq_varid(fh, VNAME_SPCO, v_spco) + if (ncerr .ne. 0) return + END IF + ncerr = nf90_put_var(fh, v_spco, SPCO, start = (/ 1, 1, itime/), & + count = (/nspec, nopts, 1 /)) + if (ncerr .ne. 0) return + + write(*,*) 'JDM g' + ! Close the file. + ncerr = nf90_close(fh) + if (ncerr .ne. 0) return + + END SUBROUTINE W3IOPON_WRITE + + !> Read/write point output in netCDF format. + !> + !> @param[in] INXOUT String indicating read/write. Must be 'READ' or + !> 'WRITE'. + !> @param[in] NDSOP File unit number. + !> @param[out] IOTST Error code: + !> - 0 No error. + !> - -1 Unexpected end of file when reading. + !> @param[in] IMOD Model number for W3GDAT etc. +#ifdef W3_ASCII + !> @param[in] NDSOA File unit number for ASCII output. +#endif + !> + !> @author Edward Hartnett @date 1-Nov-2023 + SUBROUTINE W3IOPON ( INXOUT, NDSOP, IOTST, IMOD & +#ifdef W3_ASCII + ,NDSOA & +#endif + ) + USE W3GDATMD, ONLY: W3SETG + USE W3WDATMD, ONLY: W3SETW + USE W3ODATMD, ONLY: W3SETO, W3DMO2 + !/ + USE W3GDATMD, ONLY: NTH, NK, NSPEC, FILEXT + USE W3WDATMD, ONLY: TIME + USE W3ODATMD, ONLY: NDST, NDSE, IPASS => IPASS2, NOPTS, IPTINT, & + IW, PTLOC, PTIFAC, WAO, WDO, & + SPCO, PTNME, O2INIT, FNMPRE +#ifdef W3_FLX5 + USE W3ODATMD, ONLY: TAUAO, TAUDO, DAIRO +#endif + USE W3ODATMD, ONLY : OFILES + !/ +#ifdef W3_SETUP + USE W3ODATMD, ONLY: ZET_SETO +#endif + !/ + USE W3SERVMD, ONLY: EXTCDE +#ifdef W3_S + USE W3SERVMD, ONLY: STRACE +#endif + use netcdf + IMPLICIT NONE + + CHARACTER, INTENT(IN) :: INXOUT*(*) + INTEGER, INTENT(IN) :: NDSOP + INTEGER, INTENT(OUT) :: IOTST + INTEGER, INTENT(IN), OPTIONAL :: IMOD +#ifdef W3_ASCII + INTEGER, INTENT(IN), OPTIONAL :: NDSOA +#endif + + CHARACTER(LEN=15) :: TIMETAG + INTEGER :: IGRD, MK, MTH + character(len = 124) :: filename + integer :: ncerr + +#ifdef W3_S + CALL STRACE (IENT, 'W3IOPON') +#endif + ! IPASS essentially is the time variable dimension + IPASS = IPASS + 1 + + ! Optimistically assume success. + IOTST = 0 + + ! Has a model number been specified? + IF (PRESENT(IMOD)) THEN + IGRD = IMOD + ELSE + IGRD = 1 + END IF + + CALL W3SETO(IGRD, NDSE, NDST) + CALL W3SETG(IGRD, NDSE, NDST) + CALL W3SETW(IGRD, NDSE, NDST) + + ! INXOUT must be 'READ' or 'WRITE'. + IF (INXOUT .NE. 'READ' .AND. INXOUT .NE. 'WRITE') THEN + WRITE (NDSE, 900) INXOUT + CALL EXTCDE(1) + END IF + +!JDM Not sure this next section is really needed in the necdf context, +!commenting out but leaving it as a placeholder for now + +! ! Ensure read/write are not mixed +! IF ( IPASS.EQ.1 .AND. OFILES(2) .EQ. 0 ) THEN +! WRITE = INXOUT.EQ.'WRITE' +! ELSE +! IF ( WRITE .AND. INXOUT.EQ.'READ' ) THEN +! WRITE (NDSE,901) INXOUT +! CALL EXTCDE ( 2 ) +! END IF +! END IF + + ! Determine filename. + filename = '' + IF ( OFILES(2) .EQ. 1 ) THEN + ! Create TIMETAG for file name using YYYYMMDD.HHMMS prefix + WRITE(TIMETAG,"(i8.8,'.'i6.6)")TIME(1),TIME(2) + filename = transfer(FNMPRE(:LEN_TRIM(FNMPRE))//TIMETAG//'out_pnt.'//FILEXT(:LEN_TRIM(FILEXT))//'.nc', filename) + ELSE + filename = transfer(FNMPRE(:LEN_TRIM(FNMPRE))//'out_pnt.'//FILEXT(:LEN_TRIM(FILEXT))//'.nc', filename) + END IF + + ! Do a read or a write of the point file. + IF (INXOUT .EQ. 'READ') THEN + CALL W3IOPON_READ(IOTST, IMOD, filename, ncerr) + ELSE + CALL W3IOPON_WRITE(OFILES(2), IMOD, filename, ncerr) + ENDIF + if (ncerr .ne. 0) then + print *, nf90_strerror(ncerr) + CALL EXTCDE(21) + endif + + !/ + !/ End of W3IOPON ----------------------------------------------------- / + !/ + +900 FORMAT (/' *** WAVEWATCH III ERROR IN W3IOPO :'/ & + ' ILEGAL INXOUT VALUE: ',A/) +901 FORMAT (/' *** WAVEWATCH III ERROR IN W3IOPO :'/ & + ' MIXED READ/WRITE, LAST REQUEST: ',A/) + END SUBROUTINE W3IOPON + + !/ ------------------------------------------------------------------- / !> Read or write point output. !> !> This subroutine can either read or write the point output file, @@ -1045,12 +1819,12 @@ END SUBROUTINE W3IOPE !> -------------|------|----------|-------- !> 40 | character*40 | IDTST | ID string !> 4 | integer | VERTST | Model definition file version number - !> 4 | integer | NK | Dimension of frequency - !> 4 | integer | MTH | Directionality of the frequency + !> 4 | integer | NK | Number of discrete wavenumbers + !> 4 | integer | NTH | Number of discrete directions. !> 4 | integer | NOPTS | Number of output points. !> 8*NOPTS | integer(2,NOPTS) | PTLOC | Point locations !> 7*NOPTS | character*7 | PTNME | Point names - !> 8 | integer(2) | TIME | Time + !> 8 | integer(2) | TIME | Valid time !> reclen*NOPTS | * | * | records !> !> Each record contains: @@ -1254,7 +2028,7 @@ SUBROUTINE W3IOPO ( INXOUT, NDSOP, IOTST, IMOD & CALL EXTCDE ( 1 ) END IF ! - ! IF ( IPASS.EQ.1 ) THEN + ! First pass to this file and we are only writing 1 file for all time IF ( IPASS.EQ.1 .AND. OFILES(2) .EQ. 0) THEN WRITE = INXOUT.EQ.'WRITE' ELSE @@ -1267,10 +2041,10 @@ SUBROUTINE W3IOPO ( INXOUT, NDSOP, IOTST, IMOD & ! open file ---------------------------------------------------------- * ! IF ( IPASS.EQ.1 .AND. OFILES(2) .EQ. 0 ) THEN - ! + I = LEN_TRIM(FILEXT) J = LEN_TRIM(FNMPRE) - ! + #ifdef W3_T WRITE (NDST,9001) FNMPRE(:J)//'out_pnt.'//FILEXT(:I) #endif @@ -1389,7 +2163,7 @@ SUBROUTINE W3IOPO ( INXOUT, NDSOP, IOTST, IMOD & ! IF ( WRITE ) THEN WRITE (NDSOP) & - IDSTR, VEROPT, NK, NTH, NOPTS + IDSTR, VEROPT, NK, NTH, NOPTS #ifdef W3_ASCII WRITE (NDSOA,*) & 'IDSTR, VEROPT, NK, NTH, NOPTS:', & @@ -1411,6 +2185,7 @@ SUBROUTINE W3IOPO ( INXOUT, NDSOP, IOTST, IMOD & WRITE (NDSE,904) MK, MTH, NK, NTH CALL EXTCDE ( 12 ) END IF + !JDM: what is this???? IF ( .NOT. O2INIT ) & CALL W3DMO2 ( IGRD, NDSE, NDST, NOPTS ) END IF @@ -1495,7 +2270,7 @@ SUBROUTINE W3IOPO ( INXOUT, NDSOP, IOTST, IMOD & #endif 'ASO(I), CAO(I), CDO(I), ICEO(I), ICEHO(I):', & ASO(I), CAO(I), CDO(I), ICEO(I), ICEHO(I), & - 'ICEFO(I), GRDID(I), (SPCO(J,I),J=1,NSPEC):', & + 'ICEFO(I), GRDID(I), (SPCO(J,I),J=1,NSPEC):', & ICEFO(I), GRDID(I), (SPCO(J,I),J=1,NSPEC) #endif ELSE diff --git a/model/src/w3wavemd.F90 b/model/src/w3wavemd.F90 index c144ab8d8..095e800de 100644 --- a/model/src/w3wavemd.F90 +++ b/model/src/w3wavemd.F90 @@ -442,6 +442,8 @@ SUBROUTINE W3WAVE ( IMOD, ODAT, TEND, STAMP, NO_OUT & USE W3IOGRMD USE W3IOGOMD USE W3IOPOMD + USE netcdf + !!!MTM USE W3IOTRMD USE W3IORSMD USE W3IOBCMD @@ -2601,7 +2603,7 @@ SUBROUTINE W3WAVE ( IMOD, ODAT, TEND, STAMP, NO_OUT & ! Gets the necessary spectral data ! CALL W3IOPE ( VA ) - CALL W3IOPO ( 'WRITE', NDS(8), ITEST, IMOD & + CALL W3IOPON ( 'WRITE', NDS(8), ITEST, IMOD & #ifdef W3_ASCII ,NDS(15) & #endif diff --git a/model/src/wmiopomd.F90 b/model/src/wmiopomd.F90 index 73e036535..6de789165 100644 --- a/model/src/wmiopomd.F90 +++ b/model/src/wmiopomd.F90 @@ -714,7 +714,9 @@ SUBROUTINE WMIOPO ( TOUT ) USE W3ODATMD, ONLY: W3SETO USE WMMDATMD, ONLY: WMSETM USE W3CSPCMD, ONLY: W3CSPC - USE W3IOPOMD, ONLY: W3IOPO + USE W3IOPOMD + USE netcdf + !!! MTM ! USE W3GDATMD, ONLY: NK, NTH, NSPEC, XFR, FR1, TH, SGRDS USE W3WDATMD, ONLY: TIME @@ -1176,9 +1178,9 @@ SUBROUTINE WMIOPO ( TOUT ) ! TIME = TOUT ! - CALL W3IOPO ( 'WRITE', MDSUP, II, 0 & + CALL W3IOPON ( 'WRITE', MDSUP, II, 0 & #ifdef W3_ASCII - ,MDSUPA & + ,MDSUPA & #endif ) ! diff --git a/model/src/ww3_ounp.F90 b/model/src/ww3_ounp.F90 index c35ff6e98..68426d004 100644 --- a/model/src/ww3_ounp.F90 +++ b/model/src/ww3_ounp.F90 @@ -184,7 +184,9 @@ PROGRAM W3OUNP USE W3ODATMD, ONLY: W3SETO, W3NOUT USE W3ODATMD, ONLY: IAPROC, NAPROC, NAPERR, NAPOUT, DIMP USE W3IOGRMD, ONLY: W3IOGR - USE W3IOPOMD, ONLY: W3IOPO + USE W3IOPOMD + USE netcdf + !!!MTM USE W3SERVMD, ONLY : ITRACE, NEXTLN, EXTCDE, STRSPLIT #ifdef W3_S USE W3SERVMD, ONLY : STRACE @@ -387,7 +389,7 @@ PROGRAM W3OUNP !--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! 3. Read general data and first fields from file ! - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) ! IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,930) DO I=1, NOPTS @@ -604,7 +606,7 @@ PROGRAM W3OUNP DO WHILE (DTEST.NE.0) DTEST = DSEC21 ( TIME , TOUT ) IF ( DTEST .GT. 0. ) THEN - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) IF ( IOTEST .EQ. -1 ) THEN IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,949) GOTO 888 @@ -1070,7 +1072,7 @@ PROGRAM W3OUNP DTEST = DSEC21 ( TIME , TOUT ) IF ( DTEST .GT. 0. ) THEN ! reads TIME from out_pnt.ww3 - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) IF ( IOTEST .EQ. -1 ) THEN IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,949) GOTO 700 @@ -1215,7 +1217,7 @@ PROGRAM W3OUNP ! 7.3 Reinitiazes TIME (close open out_pnt.ww3) and TOUT to process a new bunch of stations CLOSE(NDSOP) ! closes binary file out_pnt* IPASS = 0 ! resets time counter for binary file out_pnt* - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) #ifdef W3_T WRITE(NDSE,*) 'out_pnt* closed and reopened' #endif @@ -1228,7 +1230,7 @@ PROGRAM W3OUNP DO WHILE (DTEST.NE.0) DTEST = DSEC21 ( TIME , TOUT ) IF ( DTEST .GT. 0. ) THEN - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) IF ( IOTEST .EQ. -1 ) THEN IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,949) GOTO 700 diff --git a/model/src/ww3_outp.F90 b/model/src/ww3_outp.F90 index 6d750687a..8313f3516 100644 --- a/model/src/ww3_outp.F90 +++ b/model/src/ww3_outp.F90 @@ -208,7 +208,11 @@ PROGRAM W3OUTP #endif USE W3ODATMD, ONLY: W3SETO, W3NOUT USE W3IOGRMD, ONLY: W3IOGR - USE W3IOPOMD, ONLY: W3IOPO + !!!MTM + !!! USE W3IOPOMD, ONLY: W3IOPO + USE W3IOPOMD, ONLY: W3IOPO, W3IOPON, W3IOPON_READ, W3IOPON_WRITE + USE netcdf + !!!MTM USE W3SERVMD, ONLY : ITRACE, NEXTLN, EXTCDE #ifdef W3_S USE W3SERVMD, ONLY : STRACE @@ -359,7 +363,9 @@ PROGRAM W3OUTP !--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! 3. Read general data and first fields from file ! - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + !!!MTM + !!!CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) ! WRITE (NDSO,930) DO I=1, NOPTS @@ -457,7 +463,9 @@ PROGRAM W3OUTP DO CALL STME21 ( TIME , IDTIME ) WRITE (NDSO,948) IDTIME - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + !!!MTM + !!! CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) IF ( IOTEST .EQ. -1 ) THEN WRITE (NDSO,949) GOTO 888 @@ -777,7 +785,9 @@ PROGRAM W3OUTP DO DTEST = DSEC21 ( TIME , TOUT ) IF ( DTEST .GT. 0. ) THEN - CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + !!!MTM + !!! CALL W3IOPO ( 'READ', NDSOP, IOTEST ) + CALL W3IOPON ( 'READ', NDSOP, IOTEST ) IF ( IOTEST .EQ. -1 ) THEN WRITE (NDSO,949) EXIT diff --git a/regtests/unittests/CMakeLists.txt b/regtests/unittests/CMakeLists.txt index 69445bfb7..8a11d2ad8 100644 --- a/regtests/unittests/CMakeLists.txt +++ b/regtests/unittests/CMakeLists.txt @@ -24,16 +24,23 @@ endfunction() # Function to build and run a test. function(unit_test name) - add_executable(${name} ${name}.F90) + add_executable(${name} ${name}.F90 ww3_unittest_util.F90) target_link_libraries(${name} PRIVATE ww3_lib) add_test(NAME ${name} COMMAND ${name}) endfunction() +# The binary file mod_def.ww3 is needed for testing. It's created by +# the ww3_grid utility. +#add_custom_target(create_mod_def TEST ../../bin/ww3_grid +# COMMENT "Creating mod_def.ww3 file for testing") + # Copy test data files that are in the repo to the build directory. copy_test_data(switch.io) copy_test_data_2(ww3_grid.inp ww3_grid.inp) # Build and run the tests. unit_test(test_io_points_bin) +unit_test(test_io) +unit_test(test_io_restart_bin) diff --git a/regtests/unittests/test_io.F90 b/regtests/unittests/test_io.F90 new file mode 100644 index 000000000..e94e1a5d3 --- /dev/null +++ b/regtests/unittests/test_io.F90 @@ -0,0 +1,116 @@ +! This is a test for model IO for WW3. +! +! Ed Hartnett 10/14/23 +program test_io + use w3iopomd + use w3gdatmd + use w3wdatmd + use w3odatmd + use w3iogrmd + use w3adatmd + implicit none + + integer, target :: i, j, k, l + integer :: ndsop, iotest, imod, ndstst, ierr, ndsbul, ndsm + integer :: ndstrc, ntrace + real :: m2km + character*7 expected_ptnme + character*6 my_fmt + real :: expected_loc_1 + integer :: write_test_file + + print *, 'Testing WW3 netCDF point file code.' + + ! These are mysterious but have to be called or else the IPASS + ! variable does not exist and w3iopo() crashes. + call w3nmod(1, 6, 6) + call w3setg(1, 6, 6) + call w3ndat(6, 6) + call w3setw(1, 6, 6) + call w3nout(6, 6) + call w3seto(1, 6, 6) + + ndsm = 20 + ndsop = 20 + ndsbul = 0 + ndstrc = 6 + ntrace = 10 + + write (ndso,900) +900 FORMAT (/15X,' *** WAVEWATCH III Point output post.*** '/ & + 15X,'==============================================='/) + + ! Open the file with the output settings for WW3. It is not needed actually. + ! open(ndsi, file = 'ww3_outp.inp', status='old', iostat = ierr) + ! if (ierr .ne. 0) stop 10 + + ! Create a point output file needed for this test. + print *, 'Creating point output test file for this test...' + if (write_test_file() .ne. 0) stop 1 + + ! 2. Read model definition file. + CALL W3IOGR('READ', NDSM) + WRITE (NDSO,920) GNAME +920 FORMAT (' Grid name : ',A/) + + ! IF (FLAGLL) THEN + ! M2KM = 1. + ! ELSE + ! M2KM = 1.E-3 + ! END IF + + ! Read the file out_pnt.ww3 from the model/tests/data directory. + print *, 'OK!' + print *, 'Reading the point output test file for this test...' + call w3iopo('READ', ndsop, iotest) + if (iotest .ne. 0) stop 10 + close(ndsop) + + ! Make sure we got the values we expected. + if (nopts .ne. 11) stop 11 + expected_loc_1 = 0.0 + do i = 1, nopts + ! Check ptnme and ptloc arrays. + print *, ptnme(i), ptloc(1, i), ptloc(2, i) + if (i .lt. 10) then + my_fmt = '(a,i1)' + else + my_fmt = '(a,i2)' + endif + write(fmt = my_fmt, unit=expected_ptnme) 'Point', i + if (ptnme(i) .ne. expected_ptnme) stop 20 + print *, expected_loc_1 + if (ptloc(1, i) .ne. expected_loc_1) stop 21 + expected_loc_1 = expected_loc_1 + 5000.0 + if (ptloc(2, i) .ne. 0) stop 22 + end do + + print *, 'OK!' + print *, 'initializing some data...' + ipass2 = 0 + do i = 1, nopts + do j = 1, nspec + spco(j, i) = 0.0 + end do + end do + + print *, 'OK!' + print *, 'testing writing the WW3 binary point file in netCDF...' + + ! Write in netCDF. + call w3iopon('WRITE', ndsop, iotest) + if (iotest .ne. 0) stop 100 + print *, 'OK!' + + print *, 'testing reading the WW3 binary point file in netCDF...' + ipass2 = 0 + call w3iopon('READ', ndsop, iotest) + print *, iotest + if (iotest .ne. 0) stop 100 + print *, 'OK!' + + print *, 'OK!' + + print *, 'SUCCESS!' +end program test_io + diff --git a/regtests/unittests/test_io_points_bin.F90 b/regtests/unittests/test_io_points_bin.F90 index 69c197bce..4093b24ba 100644 --- a/regtests/unittests/test_io_points_bin.F90 +++ b/regtests/unittests/test_io_points_bin.F90 @@ -79,74 +79,3 @@ program test_io_points_bin print *, 'OK!' print *, 'SUCCESS!' end program test_io_points_bin - -integer function write_test_file() - implicit none - - integer :: ntlu, nk, nth, nopts - character(len=10), parameter :: veropt = '2021-04-06' - character(len=31), parameter :: idstr = 'WAVEWATCH III POINT OUTPUT FILE' - real :: ptloc(2,11) = reshape((/ 0., 0., 5000., 0., 10000., 0., 15000., 0., & - 20000., 0., 25000., 0., 30000., 0., 35000., 0., 40000., 0., 45000., 0., 50000., 0. /), & - (/ 2, 11 /)) - character*40 ptnme(11) - integer :: time(2) = (/ 19680606, 0 /) - integer :: nspec = 72 - integer :: iw(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /) - integer :: ii(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /) - integer :: il(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /) - real :: iceo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) - real :: iceho(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) - real :: icefo(11) = (/ 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000. /) - real :: dpo(11) = (/ 50., 50., 45., 40., 35., 30., 25., 20., 15., 10., 5. /) - real :: wao(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) - real :: wdo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) - real :: aso(11) = (/ -999.900024, -999.900024, -999.900024, -999.900024, -999.900024, & - -999.900024, -999.900024, -999.900024, -999.900024, -999.900024, -999.900024 /) - real :: cao(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) - real :: cdo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) - character*13 :: grdid(11) - real :: spco(72, 11) - integer :: i, j - integer :: ierr - - ! Initialize some values. - ntlu = 21 - nk = 3 - nth = 24 - nopts = 11 - do i = 1, nopts - if (i .le. 9) then - write(ptnme(i), '(a,i1)') 'Point', i - else - write(ptnme(i), '(a,i2)') 'Point', i - endif - grdid(i) = 'ww3 ' - end do - - ! Open the file. - open(ntlu, file="out_pnt.ww3", form="unformatted", status="replace", & - action="write", convert="big_endian", iostat=ierr) - if (ierr .ne. 0) stop 111 - - ! Write our values. - write (ntlu, iostat=ierr) idstr, veropt, nk, nth, nopts - if (ierr .ne. 0) stop 112 - write (ntlu, iostat=ierr) ((ptloc(j,i),j=1,2),i=1,nopts), (ptnme(i),i=1,nopts) - if (ierr .ne. 0) stop 113 - write (ntlu, iostat=ierr) time - if (ierr .ne. 0) stop 114 - do i=1, nopts - write (ntlu, iostat=ierr) iw(i), ii(i), il(i), dpo(i), wao(i), wdo(i), & - aso(i), cao(i), cdo(i), iceo(i), iceho(i), & - icefo(i), grdid(i), (spco(j,i),j=1,nspec) - if (ierr .ne. 0) stop 115 - enddo - - ! Close the file. - close(ntlu) - - ! We're done! - write_test_file = 0 -end function write_test_file - diff --git a/regtests/unittests/test_io_restart_bin.F90 b/regtests/unittests/test_io_restart_bin.F90 new file mode 100644 index 000000000..026e8d3d2 --- /dev/null +++ b/regtests/unittests/test_io_restart_bin.F90 @@ -0,0 +1,59 @@ +! This is a test for model IO for WW3. This tests the legacy (binary) +! output of restart data, done by function W3IORS(). +! +! Ed Hartnett 1/13/24 +program test_io_restart_bin + use w3iorsmd + use w3iopomd + use w3gdatmd + use w3wdatmd + use w3odatmd + use w3iogrmd + use w3adatmd + implicit none + +! integer, target :: i +! integer :: ndsop, iotest, ndsbul, ndsm +! integer :: ndstrc, ntrace +! character*7 expected_ptnme +! character*6 my_fmt +! real :: expected_loc_1 +! integer :: ndsr = 11 +! real :: dumfpi = 99.9 + +! print *, 'Testing WW3 binary restart file code.' + +! ! These are mysterious but have to be called or else the IPASS +! ! variable does not exist and w3iopo() crashes. +! call w3nmod(1, 6, 6) +! call w3setg(1, 6, 6) +! call w3ndat(6, 6) +! call w3setw(1, 6, 6) +! call w3nout(6, 6) +! call w3seto(1, 6, 6) + +! ndsm = 20 +! ndsop = 20 +! ndsbul = 0 +! ndstrc = 6 +! ntrace = 10 + +! write (ndso,900) +! 900 FORMAT (/15X,' *** WAVEWATCH III Point output post.*** '/ & +! 15X,'==============================================='/) + +! ! 2. Read model definition file. +! CALL W3IOGR('READ', NDSM) +! WRITE (NDSO,920) GNAME +! 920 FORMAT (' Grid name : ',A/) + +! ! Read the file out_pnt.ww3 from the model/tests/data directory. +! call w3iors('HOT', ndsr, dumfpi) +! if (iotest .ne. 0) stop 10 +! close(ndsop) + + + print *, 'OK!' + print *, 'SUCCESS!' +end program test_io_restart_bin + diff --git a/regtests/unittests/ww3_unittest_util.F90 b/regtests/unittests/ww3_unittest_util.F90 new file mode 100644 index 000000000..fe20ddb30 --- /dev/null +++ b/regtests/unittests/ww3_unittest_util.F90 @@ -0,0 +1,75 @@ +! This is test code for the WW3 I/O unit tests. +! +! This file holds a function used by multiple tests. +! +! Ed Hartnett, 1/11/24 +integer function write_test_file() + implicit none + + integer :: ntlu, nk, nth, nopts + character(len=10), parameter :: veropt = '2021-04-06' + character(len=31), parameter :: idstr = 'WAVEWATCH III POINT OUTPUT FILE' + real :: ptloc(2,11) = reshape((/ 0., 0., 5000., 0., 10000., 0., 15000., 0., & + 20000., 0., 25000., 0., 30000., 0., 35000., 0., 40000., 0., 45000., 0., 50000., 0. /), & + (/ 2, 11 /)) + character*40 ptnme(11) + integer :: time(2) = (/ 19680606, 0 /) + integer :: nspec = 72 + integer :: iw(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /) + integer :: ii(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /) + integer :: il(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /) + real :: iceo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) + real :: iceho(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) + real :: icefo(11) = (/ 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000. /) + real :: dpo(11) = (/ 50., 50., 45., 40., 35., 30., 25., 20., 15., 10., 5. /) + real :: wao(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) + real :: wdo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) + real :: aso(11) = (/ -999.900024, -999.900024, -999.900024, -999.900024, -999.900024, & + -999.900024, -999.900024, -999.900024, -999.900024, -999.900024, -999.900024 /) + real :: cao(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) + real :: cdo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /) + character*13 :: grdid(11) + real :: spco(72, 11) + integer :: i, j + integer :: ierr + + ! Initialize some values. + ntlu = 21 + nk = 3 + nth = 24 + nopts = 11 + do i = 1, nopts + if (i .le. 9) then + write(ptnme(i), '(a,i1)') 'Point', i + else + write(ptnme(i), '(a,i2)') 'Point', i + endif + grdid(i) = 'ww3 ' + end do + + ! Open the file. + open(ntlu, file="out_pnt.ww3", form="unformatted", status="replace", & + action="write", convert="big_endian", iostat=ierr) + if (ierr .ne. 0) stop 111 + + ! Write our values. + write (ntlu, iostat=ierr) idstr, veropt, nk, nth, nopts + if (ierr .ne. 0) stop 112 + write (ntlu, iostat=ierr) ((ptloc(j,i),j=1,2),i=1,nopts), (ptnme(i),i=1,nopts) + if (ierr .ne. 0) stop 113 + write (ntlu, iostat=ierr) time + if (ierr .ne. 0) stop 114 + do i=1, nopts + write (ntlu, iostat=ierr) iw(i), ii(i), il(i), dpo(i), wao(i), wdo(i), & + aso(i), cao(i), cdo(i), iceo(i), iceho(i), & + icefo(i), grdid(i), (spco(j,i),j=1,nspec) + if (ierr .ne. 0) stop 115 + enddo + + ! Close the file. + close(ntlu) + + ! We're done! + write_test_file = 0 +end function write_test_file + diff --git a/regtests/ww3_tp2.5/out_pnt_ncdump.txt b/regtests/ww3_tp2.5/out_pnt_ncdump.txt new file mode 100644 index 000000000..3747eb8e4 --- /dev/null +++ b/regtests/ww3_tp2.5/out_pnt_ncdump.txt @@ -0,0 +1,33 @@ +netcdf out_pnt.ww3 { +dimensions: + NOPTS = 1 ; + NSPEC = 36 ; + VSIZE = 2 ; + NAMELEN = 40 ; + GRDIDLEN = 13 ; + TIME = UNLIMITED ; // (13 currently) +variables: + int NK ; + int NTH ; + float PTLOC(NOPTS, VSIZE) ; + char PTNME(NOPTS, NAMELEN) ; + int TIME(TIME, VSIZE) ; + int IW(TIME, NOPTS) ; + int II(TIME, NOPTS) ; + int IL(TIME, NOPTS) ; + float DPO(TIME, NOPTS) ; + float WAO(TIME, NOPTS) ; + float WDO(TIME, NOPTS) ; + float ASO(TIME, NOPTS) ; + float CAO(TIME, NOPTS) ; + float CDO(TIME, NOPTS) ; + float ICEO(TIME, NOPTS) ; + float ICEHO(TIME, NOPTS) ; + float ICEFO(TIME, NOPTS) ; + char GRDID(TIME, NOPTS, GRDIDLEN) ; + float SPCO(TIME, NOPTS, NSPEC) ; + +// global attributes: + :title = "WAVEWATCH III POINT OUTPUT FILE" ; + :version = "2021-04-06" ; +}