FVCOM 4.4.2 のインストールと Estuary テストケースの MPI 実行

FVCOM 4.4.1 から **FVCOM 4.4.2** に更新しました．
[FVCOM](http://fvcom.smast.umassd.edu/) は非構造格子有限体積法海洋コミュニティモデルです．WindowsのWSL2のUbuntu 20.04LTS および 九州大学スパコンITO-A において **Intel oneAPI** を用いて，FVCOM 4.4.2 をインストールします．**Examples/Estuary** のテストケースの **MPI** 実行を想定します．
**ユーザー登録者限定コードのため示せませんが，一部コードの修正が必要でした**

## コンパイラの準備
Intel oneAPI を用意します．WSL2 の Ubuntu 20.04LTS は [こちら](https://estuarine.jp/2021/03/install-oneapi/) を参照ください．
ITO-A では以下の通りです．

```bash
 module load oneapi/2021.3
```

## NetCDF ライブラリのインストール

NetCDF-4 をリンクしたFVCOM実行形式は実行時にsegmentation faultとなりました．対処法不明です．そこで，NetCDF-3.6.3 をインストールします．
[**netcdf-3.6.3.tar.gz**](https://www.gfd-dennou.org/library/netcdf/unidata-mirror/netcdf-3.6.3.tar.gz) がソースコードです．

ビルドスクリプト build_netcdf363.sh を用意します．

```bash
#!/bin/bash
# build_netcdf363.sh
export CC=icc
export CXX=icpc
export CFLAGS=-O3
export CXXFLAGS=-O3
export F77=ifort
export FC=ifort
export F90=ifort
export FFLAGS=-O3
export CPP='icc -E'
export CXXCPP='icpc -E'

tar xf netcdf-3.6.3.tar.gz
cd netcdf-3.6.3
./configure --prefix=${HOME}/local/netcdf-3.6.3-one-api-2021.3
make
make check
make install
```

スクリプトに実行権限を付与し，実行します．

```bash
chmod a+x build_netcdf363.sh
./build_netcdf363.sh
```

## FVCOM同梱のライブラリのインストール

### make.inc の編集
**fvcom442/FVCOM_source/make.inc** を以下のように編集します．**make.inc_example** が存在するので，これをコピーして使いましょう．
ホームディレクトリは `$(HOME)` のように丸括弧（中括弧ではありません）で囲みます．
ライブラリのインストールのため，コンパイラの設定は **Serial** 用の **Intel Compiler Definitions** 関連の編集が必要です． **Intel/MPI Compiler Definitions** 関連はすべてコメントアウトしておきます．

```bash
# Set the FVCOM_source directory
TOPDIR =  $(HOME)/Github/fvcom442/FVCOM_source

# Comment out all lines for MEDM Environment and specify the Local Install
####################### MEDM ENVIRONMENT #####################################
# Use the environmental variables, LIBPATH and INCLUDEPATH, set by MODULE 
# to find the packages used by this build.
#colon=:
#empty=
#dashI= $(empty) -I
#dashL= $(empty) -L
# ### UNCOMMENT HERE!
#             LIBDIR       =  -L$(subst $(colon),$(dashL),$(LIBPATH))
#             INCDIR       =  -I$(subst $(colon),$(dashI),$(INCLUDEPATH))

###########################################################################
# LOCAL INSTALL
             LIBDIR       =  -L$(INSTALLDIR)/lib
             INCDIR       =  -I$(INSTALLDIR)/include

# Specify NetCDF Library
#--------------------------------------------------------------------------
#        NETCDF OUTPUT      NETCDF IS NOW REQUIRED TO COMPILE FVCOM
#                           DUMP OUTPUT INTO NETCDF FILES (yes/no)
#                           REQUIRES SYSTEM DEPENDENT NETCDF LIBRARIES
#                           COMPILED WITH SAME F90 COMPILER
#                           SET PATH TO LIBRARIES WITH IOLIBS      
#                           SET PATH TO INCLUDE FILES (netcdf.mod) WITH IOINCS
#--------------------------------------------------------------------------
#            FLAG_USE_NETCDF4     = -DUSE_NETCDF4
#            FLAG_USE_COMPRESSION = -DUSE_COMPRESSION
#
#             IOLIBS       =  -lnetcdff -lnetcdf #-lhdf5_hl -lhdf5 -lz -lcurl -lm
#             IOLIBS       =  -lnetcdf #-L/hosts/mao/usr/medm/install/netcdf/3.6.3/em64t/lib -lnetcdf

#             IOINCS       =  #-I/hosts/mao/usr/medm/install/netcdf/3.6.3/em64t/include
#             IOLIBS       =  -L/usr/local/install/netcdf/gcc_ifort/3.6.2/lib  -lnetcdf
#             IOINCS       =  -I/usr/local/install/netcdf/gcc_ifort/3.6.2/include
#
##             IOLIBS       = -L/usr/local/install/netcdf-4.4.1.1-with-fortran/lib -lnetcdff -lnetcdf
##             IOINCS       = -I/usr/local/install/netcdf-4.4.1.1-with-fortran/include
#             IOLIBS       = -L/home/teem/local/netcdf4-intel-fortran/4.5.3/lib -lnetcdff -lnetcdf
#             IOINCS       = -I/home/teem/local/netcdf4-intel-fortran/4.5.3/include
#             IOLIBS       = -L/home/teem/local/netcdf-3.6.3-intel/lib -lnetcdf
#             IOINCS       = -I/home/teem/local/netcdf-3.6.3-intel/include
             IOLIBS       = -L$(HOME)/local/netcdf-3.6.3-one-api-2021.3/lib -lnetcdf
             IOINCS       = -I$(HOME)/local/netcdf-3.6.3-one-api-2021.3/include

#--------------------------------------------------------------------------

            FLAG_1 = -DDOUBLE_PRECISION
            FLAG_3 = -DWET_DRY
#            FLAG_9 = -DSEMI_IMPLICIT
#            include ${PETSC_DIR}/bmake/common/variables
            FLAG_14 = -DRIVER_FLOAT
#            FLAG_28 = -DAIR_PRESSURE  

#--------------------------------------------------------------------------
#  Intel Compiler Definitions (ITO-A, Ubuntu 20.04LTS on WSL2)
#--------------------------------------------------------------------------
#
         CPP      = /usr/bin/cpp
         COMPILER = -DIFORT
         FC       = ifort
         CC       = icc
         CXX      = icpc
         CFLAGS   = -O3
# Activate DEBFLGS when debuging
#         DEBFLGS  = -check all -warn -std -fpe0 -ftrapuv -traceback
#         OPT      = -O0 -g  
          OPT      = -O3

# Do not set static for use with visit!
#         VISOPT   = -Wl,--export-dynamic
#         LDFLAGS  = $(VISITLIBPATH)
```

### ライブラリのインストール

ライブラリのルート（**fvcom442/FVCOM_source/libs/**）に移動します．`chmod a+x untar.sh` で実行権限を付与しておきます．
**makefile** を開き，インストール済みのnetcdf関連行をコメントアウトします．

```makefile
# PACKAGES =	proj	fproj	julian	metis	netcdf	
PACKAGES =	proj	fproj	julian	metis	
#	cd netcdf && ./configure CC=$(CC) CFLAGS=-O3 CXX=$(CC) CXXFLAGS=-O3 F77=$(FC) F90=$(FC) FFLAGS=-O3 --prefix=$(MYINSTALLDIR) --build=$(MACHTYPE)
#	cd netcdf && make install
```

**make** を実行すると，ライブラリが **fvcom442/FVCOM_source/libs/install/** にインストールされます．

```bash
make
```

## FVCOM の MPI 用のビルド

**fvcom442/FVCOM_source/** に戻って **make.inc** を開き，**Intel/MPI Compiler Definitions** 関連を以下の通り編集します．Serial 用の設定はMPI用の設定で上書きされますので，そのままで大丈夫です．

```bash
#--------------------------------------------------------------------------
#  Intel/MPI Compiler Definitions (ITO-A, Ubuntu 20.04LTS on WSL2)
#--------------------------------------------------------------------------
         CPP      = /usr/bin/cpp
         COMPILER = -DIFORT  
         CC       = mpiicc
         CXX      = mpiicpc
         CFLAGS   = -O3
         FC       = mpiifort
#        DEBFLGS  = -check all -warn -std -fpe0 -ftrapuv -traceback
#        OPT      = -O0 -g
         OPT      = -O3

# Do not set static for use with visit!
#         VISOPT   = -Wl,--export-dynamic
#         LDFLAGS  =  $(VISITLIBPATH)
```

以上で準備が整いましたので，**make** します．

```bash
make
```

以下を実行して，リストの最後に **fvcom** と **libfvcom.a** が生成されていれば成功です．

```bash
ls -ltr
```

コンパイルをやり直すときはクリーンしてから実行します．

```bash
make clean
make
```

### 共有ライブラリパスの設定

これをしないと実行時に共有ライブラリ **libproj.so.0** がロードできないエラーとなります．

```bash
export LD_LIBRARY_PATH="${HOME}/Github/fvcom442/FVCOM_source/libs/install/lib:$LD_LIBRARY_PATH"
```

**.bashrc** に追記しておくとよいでしょう．

## Estuary テストケースの実行

**fvcom442/Examples/Estuary/run/** に移動します．

### tst_run.nml の修正

計算条件が書かれた，**tst_run.nml** は以下のように修正が必要です．

**NML_CASE** の最後に **DATE_REFERENCE** を追記します．

```fortran
  DATE_REFERENCE  = '1858-11-17 00:00:00'
 ```

**NML_NETCDF_SURFACE** を **NML_NETCDF** の後に追記します．

```fortran
&NML_NETCDF_SURFACE
 NCSF_ON = F,
 NCSF_FIRST_OUT = 'none' ,
 NCSF_OUT_INTERVAL = 'none' ,
 NCSF_OUTPUT_STACK = 0,
 NCSF_SUBDOMAIN_FILES= ,
 NCSF_GRID_METRICS = F,
 NCSF_FILE_DATE    = F,
 NCSF_VELOCITY     = F,
 NCSF_SALT_TEMP    = F,
 NCSF_TURBULENCE   = F,
 NCSF_WIND_VEL     = F,
! NCSF_ATM_PRESS   = F,
 NCSF_WIND_STRESS  = F,
! NCSF_WAVE_PARA    = F,
! NCSF_ICE          = F,
 NCSF_EVAP_PRECIP  = F,
 NCSF_SURFACE_HEAT = F
/
```

最後に **NML_MLD** を追記します．

```fortran
 &NML_MLD
 NC_MLD          = F,
 GAMMA_MIN       = 0.04e-3,
 MLD_DEFAULT     = 5.0,
 DEEPWATER_DEPTH = 100.0,
 DEEPWATER_GAMMA = 0.03e-3
 /
```

### 実行

実行形式 **fvcom** をカレントディレクトリにコピーします．または以下の様にリンクを張ると，コピー不要で，再ビルド後も有効です．

実行時は先頭の **tst** のみを **--casename** の引数として与えます．**-n** の引数にはプロセス数を与えます．例えば 4 core マシンで4プロセスによる計算は 4 とします．1 （serialと同じ）も指定できます．

```bash
# リンクを張る場合
ln -s ${HOME}/Github/fvcom442/FVCOM_source/fvcom fvcom

# Ubuntu 20.04LTS で 4プロセス実行の例
mpirun -n 4 ./fvcom --casename tst
# ITO の FRONTEND基本ベアメタルで 36プロセス実行の例
mpiexec.hydra -n 36 ./fvcom --casename tst
```