1.はじめに
有限体積法を用いた海洋モデルfvcomのインストール記録です。
開発者の環境と異なる設定のため、多少の手直しが必要でした。
ここでは例題として用意されているEstuary caseを動かすまでの過程を示します。
通常とは異なる点
1) gfortranを使ってコンパイル
fvcom作成に通常用いられるintel fortranは、netcdfの作成・管理が面倒
websiteではgfortran対応を謳っているものの、対応しきれていない
2) os標準のnetcdf4を使用
ただし、netcdf4の圧縮機能は導入できなかった
3) mpiにopenmpiを使用
単にインストール済みだったため利用。特に問題は生じなかった
2.前提条件
- fvcom v5.0.1 (2023/02/25)
- ubuntu v22.04LTS
- gfortran v11.4.0
- fproj/proj4/julian/metisはfvcomのものを利用
- petsc (semi-implicit) は使用せず(インストール方法がわからなかった)
- ディレクトリ~/fvcomを作成、その下にインストール
3. 準備
1) ライブラリの用意
1. fortran用netcdf
$ sudo apt install libnetcdff-dev
2. openmpi
$ sudo apt install libopenmpi-dev
2) 修正ファイル(2つ、~/fvcomに置いておく)
1. cfortran.h (fprojで使用)
fvcom同梱のものはgfortran未対応
cfortran-20110621.tar.gz2から、cfortran.hのみを抜き出す
下記urlから入手したが、他にあるものでも恐らく流用可能
https://sourceforge.net/projects/cfortran/files/
2. metis-4.0.patch (metisに使用)
~/fvcom$ wget http://www.math-linux.com/IMG/patch/metis-4.0.patch
※~/fvcom$は、実行時のディレクトリを表すプロンプト(wget... のみを実行する)
※別途metis v5をダウンロードして、作成する場合は不要
3. テスト用ファイル
FVCOM_Package.zip (146MB)はgithub main pageの末尾に記載のリンクからダウンロードした後、~/fvcomに展開しておく
https://drive.google.com/file/d/1xwcFjzkSNT26FBu83pq2I8oIGzPqnjUn/view
~/fvcom$ unzip ./FVCOM_Package.zip
4. ファイルの取得
ファイル入手・展開後は、srcディレクトリへ移動しておく
方法1: githubから (v5.0.1) (今回はこちらを使用)
~/fvcom$ git clone https://github.com/FVCOM-GitHub/FVCOM.git
~/fvcom$ cd FVCOM/src
~/fvcom/FVCOM/src$
※$で終わる文字列は、ディレクトリ位置(実行時に入力する必要なし)
方法2: tarファイルをダウンロード (v4.4.5)
~/fvcom$ wget https://github.com/FVCOM-GitHub/FVCOM/archive/refs/tags/release-$ v4.4.5.tar.gz
~/fvcom$ tar xvfz release-v4.4.5.tar.gz
~/fvcom$ cd FVCOM-release-4.4.5/src
~/fvcom/FVCOM-release-4.4.5/src$
5. make.incの編集
このファイルは、モデルのコンパイル時の設定(FLAGなど)を指定するほか、次項で行うライブラリ作成の際にも参照するので、一番最初に修正する
※行頭に#をつけると、コメント行となり、実行されなくなる
1) 環境変数TOPDIR, INSTALLDIRの設定
TOPDIRは、make.incがある場所の絶対パス
INSTALLDIRは、関連ライブラリ(fprojなど)のインストール先
TOPDIR = $(HOME)/fvcom/FVCOM/src
INSTALLDIR = $(TOPDIR)/libs/install
通常、$(HOME)はコンパイル時に環境変数HOME(ホームディレクトリの位置)の中身で置き換えられるが、上手く展開されず、エラーが出ることがある。
その場合は、
TOPDIR=/home/(user名)/fvcom/FVCOM/src
のようにすべて書き出して記載する。
2) 環境変数LIBDIR, INCDIRの修正
#LOCAL INSTALL(L79-80)を利用する
(#UNCOMMENT HEREと書かれた方は使用しない)
LIBDIRはL79行頭のコメントを外す
INCDIRは-I.../includeの後に、-I(ファイルmpi.modの場所)を追加
(mpi.modの場所は"find /usr -name mpi.mod"で探索可能)
# LOCAL INSTALL
LIBDIR = -L(INSTALLDIR)/lib
INCDIR = -I(INSTALLDIR)/include -I/usr/lib/x86_64-linux-gnu/fortran/gfortran-mod-15/openmpi
3) netcdf関連
L97 FLAG_USE_NETCDF4 : 行頭のコメントを外す
L98 FLAG_USE_COMPRESSION : エラーが出るので指定しない
L99 IOLIBS : -L(libnetcdff.aの場所)を-lnetcdffの前に追加
L101 IOINCS : -I(netcdf.hの場所)を指定
FLAG_USE_NETCDF4 = -DUSE_NETCDF4
#FLAG_USE_COMPRESSION = -DUSE_COMPRESSION # 使用しない
IOLIBS = -L/usr/lib/x86_64-linux-gnu -lnetcdff -lnetcdf #
#IOLIBS = ...
IOINCS = -I/usr/include #-l/hosts ...
4) Estuary caseに合わせた設定
make.inc.exampleを参考にFLAGの指定を修正する
FLAG_3, FLAG_4, FLAG_8, FLAG_10, FLAG_14 をON(行頭の#を外す)
インストール直後の設定であれば、変更する箇所は
#FLAG_1 = -DDOUBLE_PRECISION-SINGLE_OUTPUT # L128 コメントにする
#FLAG_2 = -DSPHERICAL # L136 コメントにする
FLAG_14 = -DRIVER_FLOAT # L286 コメントを外す
#FLAG_15 = -DMPDATA # L304 コメントにする
※後述の実験条件を記載するnamelistファイルと整合しない設定は、エラーとなることがある
5) コンパイラ設定
intel fortranの設定を無効にして、代わりにgfortran用の設定を記載する
※1行の文字数が132を超える場合に対応するため--ffree-line-length-noneオプションを加える
# Intel/MPI Compiler Definitions (SMAST) (L579-591)
# CPP/COMPILER/CC/CXX/CFLAGS/FC/OPTの定義をコメントにするか後で再定義
...
# gfortran defs
CPP = /usr/bin/cpp # L600 コメントを外す
COMPILER = -DGFORTRAN # L601 コメントを外す
CC = mpicc # 追加
CXX= mpicxx # 追加
FC = mpif90 # L603 コメントを外し、修正
OPT = -O3 -ffree-line-length-none # L605 コメントを外し、修正
並列計算を行わないときは
# gfortran defs
CPP = /usr/bin/cpp # L600 コメントを外す
COMPILER = -DGFORTRAN # L601 コメントを外す
CC = gcc # 追加
CXX= g++
FC = gfortran # 追加
OPT = -O3 -ffree-line-length-none # L605 コメントを外し、修正
6. fvcomコンパイルに必要なライブラリを作成
※fvcom本体の再コンパイル時には、行わなくて良い(項目7へ)
- $TOPDIR/libs (~/fvcom/FVCOM/src/libs)に5つのライブラリのソースがある
(proj, fproj, julian, metis, netcdf) - (os標準のものを利用する)netcdf以外の4つのライブラリを作成
- コンパイルは、$TOPDIR/libs/makefileを用いて$TOPDIR/libsにて実施
- 結果は$INSTALLDIR (~/fvcom/FVCOM/src/libs/install)にインストール
- 手順は../make.incの修正 → ./makefileの修正 → make
※一度作成してしまえば、fvcom本体の再コンパイル時の作り直しは不要
~/fvcom/FVCOM/src$ cd libs
~/fvcom/FVCOM/src/libs$
1) makefileを編集
- PACKAGESは、tar形式のソースファイルのうち、展開するものを指定
netcdfを消去
PACKAGES = proj fproj julian metis
- L14以降にて、各ライブラリのコンパイル、インストールを行う
今回は、proj, fproj, metis, julianを作成する(netcdfは作成しない)
netcdfに関する行(L18-19)をコメントにする (行頭に#をつける)
metisに関する行(L20)のコメントを外す
all:
for item in $(PACKAGES); do (./untar.sh $$item ) || exit 1; done
cd proj && ./configure CC=$(CC) CFLAGS=-O3 CXX=$(CC) CXXFLAGS=-O3 F77=$(FC) FFLAGS=-O3 --prefix=$(MYINSTALLDIR)
cd proj && make install
cd fproj && ./configure CPPFLAGS='$(COMPILER)' CC=$(CC) CFLAGS=-O3 CXX=$(CXX) CXXFLAGS=-O3 FC=$(FC) FFLAGS=-O3 --with-proj4=$(MYINSTALLDIR) --prefix=$(MYINSTALLDIR)
cd fproj && make install
# 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
cd metis && make install # 行頭コメントを外す
cd julian && make install
2) 修正ファイルの適用
makefileがあるディレクトリ(~/fvcom/FVCOM/src/libs)にて作業する
修正ファイルは~/fvcomにあると仮定
1. fproj用cfortran.hの置き換え
fprojのソースファイルは、元々 fproj.tgzの形で存在
tarコマンドにて解凍してできる./fprojディレクトリの中のファイルを置換
~/fvcom/FVCOM/src/libs$ tar xvfz fproj.tgz
~/fvcom/FVCOM/src/libs$ cp ~/fvcom/cfortran.h ./fproj
2. metis用修正パッチの適用
~/fvcom/FVCOM/src/libs$ tar xvfz metis.tgz
~/fvcom/FVCOM/src/libs$ cd metis
~/fvcom/FVCOM/src/libs/metis$ patch < ~/fvcom/metis-4.0.patch
~/fvcom/FVCOM/src/libs/metis$ cd ..
~/fvcom/FVCOM/src/libs$
3) ライブラリのコンパイル
~/fvcom/FVCOM/src/libs$ make
(コンパイル結果の確認:4つのライブラリファイルができていれば成功)
~/fvcom/FVCOM/src/libs$ ls install/lib/*.a
install/lib/libfproj4.a install/lib/libjulian.a install/lib/libmetis.a install/lib/libproj.a
(fvcom本体のコンパイル場所へ移動)
~/fvcom/FVCOM/src/libs$ cd ..
~/fvcom/FVCOM/src$
7. fvcom本体の作成
※FLAG設定変更などに伴う再コンパイルの際には、項目5のmake.inc修正と本項2)のコンパイルだけ行えば良い
1) ファイル修正
gfortran独自の仕様に合わせるため、(xx.f90ではなく) xx.Fを修正する
(拡張子f90のファイルを修正しても、コンパイル時に上書きされ、変更が反映されないので注意)
※この項の内容は、バージョン更新に伴い、不要になる可能性がある
1. mod_station_timeseries.F (L1438)
修正前
WRITE(10,'(2I10,<MX_NBR_ELEM_GL+1>I10)') I,NTVEGL(I),(NBVEGL(I,J),J=1,NTVEGL(I))
修正後 ( WRITE( )の中の <MX_NBR_ELEM_GL+1> を10000に変更 )
WRITE(10,'(2I10,10000I10)') I,NTVEGL(I),(NBVEGL(I,J),J=1,NTVEGL(I))
2. mod_action_ex.F (L688-689)
SIGN( )の中のREAL(1.0,SP)を1.0に置き換える(各行2カ所ずつ)
修正前 修正後
SIGN(REAL(1.0,SP),UNA) -> SIGN(1.0,UNA) # L688の2カ所
SIGN(REAL(1.0,SP),UNBB) -> SIGN(1.0,UNBB) # L689の2カ所
※L564のSIGN(REAL(1.0,SP),UN)は変更不要
3. ocpcre.F (L2217)
KEYWISの後の==を.eqv.に書き換え(eqvのあとは"."が2つ並ぶ)
修正前
IF(ELTYPE == 'KEY' .AND. KEYWIS==.TRUE.) ELTYPE = 'USED'
修正後
IF(ELTYPE == 'KEY' .AND. KEYWIS.eqv..TRUE.) ELTYPE = 'USED'
4. swancom5.F (L133)
SPCSIGLをSPCSIG(IS)に書き換える
修正前
CALL KSCIP1(1,SPCSIGL,DEPLOC,KWAVEL,CGOL,NN,ND)
修正後
CALL KSCIP1(1,SPCSIG(IS),DEPLOC,KWAVEL,CGOL,NN,ND)
2) コンパイル
※事前にmake cleanを行うこと
~/fvcom/FVCOM/src$ make
しばらく後に ./fvcomと./libfvcom.aができていれば成功
3) 動作確認
1. 環境変数を設定
~/fvcom/FVCOM/src$ export LD_LIBRARY_PATH=~/fvcom/FVCOM/src/libs/install/lib:$LD_LIBRARY_PATH
※ここで指定したディレクトリはmake.incのINSTALLDIRと同じ
※LD_LIBRARY_PATHがそれ以前に設定されていなければ、":"以降の記載は不要
2. 実行
コンパイル時の設定に応じて、どちらか一方を入力する
(parallel modeでコンパイルした場合 - mpi使用)
~/fvcom/FVCOM/src$ mpiexec -n 2 ./fvcom
(serial modeでコンパイルした場合 - mpi不使用)
~/fvcom/FVCOM/src$ ./fvcom
※-nの後の数字はcpuコア数(またはそれ以下)を指定する
コア数は cat /proc/cpuinfo にて確認可能
成功すれば、下記画面が現れる
You must specify a case name:
Need to put something here!
This is not a very helpful help message!
LONG INPUT OPTIONS
--HELP => PRINT THIS MESSAGE
--CASENAME=<YOUR_CASE> (REQUIRED)
--CREATE_NAMELIST => PRINT BLANK NAMELIST AND RETURN
--LOGFILE=<FILENAME> => TO OUTPUT TO A LOG FILE
--CRASHRESTART => RUN FROM CURRENT TIME IN RESTART FILE
SHORT INPUT OPTIONS
-V => PRINT FVCOM VERSION INFO AND RETURN
-H => PRINT THIS MESSAGE AND RETURN
DEBUG LEVELS
--dbg=0 => DBG LOG (DEFAULT
--dbg=1 => DBG IO FILENAMES
--dbg=2 => DBG SCALARS
--dbg=4 => DBG SUBROUTINE NAMES
--dbg=5 => DBG SUBROUTINE IO
--dbg=6 => DBG VECTORS
--dbg=7 => DBG EVERYTHING
--dbg_par => WRITE LOG FOR EACH PROCESSOR
環境変数LD_LIBRARY_PATHが設定しないと、下記エラーがでることがある
./fvcom: error while loading shared libraries: libproj.so.0: cannot open shared object file: No such file or directory
8. Estuary caseの実行
fvcomのテストケース(testsuite)のうち、Estuary caseを試す
設定の詳細は、pdfマニュアルの19章冒頭にも記載がある
おおまかな手順
- 入力ファイルの準備
testsuiteの場合、すべて用意されている - make.incの修正(FLAGの設定) → 実行ファイル (fvcom, libfvcom.a)の作成
FLAGの変更などがなければ、一度作成したfvcomファイルの再生成は不要
fvcomファイルは単独で動くので、移動やコピー、リンクが可能 - namelistファイル(tst_run.nml)の修正
- casename(ここではtst)を指定して、fvcomを実行
※本来、設定を変えずにそのまま動かせるはずだが、namelistファイルに誤りがあるのと、新バージョンに対応していない箇所があることから、namelistファイルの修正が必要
1) FVCOM Package
~/fvcomにて、FVCOM_Package.zipを展開されているとする
$ cd ~/fvcom/FVCOM_Package/Examples/Estuary
~/fvcom/FVCOM_Package/Examples/Estuary$ ls
make.inc_example run/ tstinp/
~/fvcom/FVCOM_Package/Examples/Estuary$ ls tstinp/
RIVERS_NAMELIST.nml River_data.nc sigma.dat
tst_cor.dat tst_dep.dat tst_grd.dat tst_obc.dat
tst_spg.dat m2_only_1m.nc
~/fvcom/FVCOM_Package/Examples/Estuary$ ls run/
tst_run.nml
ファイル構成
- make.inc_example : fvcomコンパイル時に使うmake.incの設定例
- tstinp/ : 入力ファイル(境界条件や地形など)
- run/ : 実行ディレクトリ
- run/tst_run.nml : namelistファイル。実験設定を定義
_runの前の文字列がcasenameと呼ばれる識別子(tst)
前項まででは、上記make.inc_exampleの記述に沿った設定でfvcomをコンパイル・作成しているので、再コンパイルの必要はない。
実行ディレクトリに移動し、fvcom実行の準備を進める
~/fvcom/FVCOM_Package/Examples/Estuary$ cd run
~/fvcom/FVCOM_Package/Examples/Estuary/run$
1. namelistファイル (tst_run.nml) の修正
※&から/までの間が一つのブロックなので、最後の"/"を忘れないこと
a) 誤植の修正
&NML_GRID_COORDINATES 2行目 : 文字列tst_grd.datの前後に' 'を追加
&NML_GRID_COORDINATES
GRID_FILE = 'tst_grd.dat',
GRID_FILE_UNITS = 'meters',
PROJECTION_REFERENCE = 'proj=tmerc +datum=NAD83 +lon_0=-70d10 lat_0=42d50 k=.9999666666666667 x_0=900000 y_0=0',
SIGMA_LEVELS_FILE = 'sigma.dat',
DEPTH_FILE = 'tst_dep.dat',
CORIOLIS_FILE = 'tst_cor.dat',
SPONGE_FILE = 'tst_spg.dat'
/
b) namelist追加(ファイル末尾)
新バージョンで必要となった下記を追記
(&NML_NETCDF_SURFACE, &NML_MLD, &NML_HEATFLUX_SEDIMENT)
&NML_NETCDF_SURFACE
NCSF_ON=F,
NCSF_FIRST_OUT="Date to start NETCDF OUTPUT: Format the same as START_DATE ",
NCSF_OUT_INTERVAL="A length of time: 'seconds= ','days= ', or 'cycles= ' ",
NCSF_OUTPUT_STACK=0 ,
NCSF_SUBDOMAIN_FILES="FVCOM
",
NCSF_GRID_METRICS=F,
NCSF_FILE_DATE=F,
NCSF_VELOCITY=F,
NCSF_SALT_TEMP=F,
NCSF_TURBULENCE=F,
NCSF_WIND_VEL=F,
NCSF_WIND_STRESS=F,
NCSF_EVAP_PRECIP=F,
NCSF_SURFACE_HEAT=F,
/
&NML_MLD
NC_MLD=F,
GAMMA_MIN= 3.99999990E-05,
MLD_DEFAULT= 5.00000000 ,
DEEPWATER_DEPTH= 100.000000 ,
DEEPWATER_GAMMA= 2.99999992E-05,
/
&NML_HEATFLUX_SEDIMENT
HEATFLUX_SEDIMENT_ON=F,
MUD_INITIAL_TEMP_FILE="none ",
VOLUMETRIC_HEAT_CAPACITY= 3.65000010 ,
THERMAL_DIFFUSIVITY= 0.379999995 ,
EFFECTIVE_THICKNESS= 9.99999978E-03,
CRITICAL_DEPTH= 1.00000000 ,
SEDIMENT_TEMPERATURE= 10.0000000 ,
/
2. fvcomのリンク作成
tst_run.nmlのあるディレクトリにfvcomをリンク
~/fvcom/FVCOM_Package/Examples/Estuary/run$ ln -s ~/fvcom/FVCOM/src/fvcom .
~/fvcom/FVCOM_Package/Examples/Estuary/run$ ls
fvcom tst_run.nml
3. プログラム実行
casename (namelistファイル冒頭の文字列)を指定して、fvcomを実行
-nの後の数字は、cpuコア数
--casenameオプションでは"-"を2つ並べる点に注意
~/fvcom/FVCOM_Package/Examples/Estuary/run$ mpiexec -n 2 ./fvcom --casename=tst
最後にtada! と出たら成功
tst_0001.ncというファイルができる
ncviewでは、非構造格子の表示には対応していないので、結果は線状に表示
9. エラー対応
1) Can Not Read NameList xxx from file: xxx
&NML_NETCDF_SURFACE
NCSF_ON=F,
NCSF_FIRST_OUT="Date to start NETCDF OUTPUT: Format the same as START_DATE ",
NCSF_OUT_INTERVAL="A length of time: 'seconds= ','days= ', or 'cycles= ' ",
NCSF_OUTPUT_STACK=0
...
/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FVCOM Fatal Error!
Can Not Read NameList NML_NETCDF_SURFACE from file: ./tst_run.nml
Stopping FVCOM
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
内容:新バージョンにて必要になったnamelistが無い
対処法:表示されたnamelist blockをそのままnamelistファイルの末尾に追記
2) Can Not Read NameList from file: xxx
&NML_GRID_COORDINATES
GRID_FILE="tst_grd.dat ",
GRID_FILE_UNITS="Can be 'degrees' or 'meters'; certain make options required ",
PROJECTION_REFERENCE="none: A recognized reference coordinate for projtion for PROJ4
...
/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FVCOM Fatal Error!
Can Not Read NameList NML_GRID_COORDINATES from file: ./tst_run.nml
Stopping FVCOM
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
内容:&NML_GRID_COORDINATESが正しく読み込めない(文法エラー)
対処法:そのブロックの内容を確認する
→ "tst_grd.dat の引用符が片方しかなかったので追加
3) その他
- make.incにて指定したFLAGとtst_run.nmlの設定が整合しない
(例えば、FLAG_3=-DWET_DRYを指定したら、nmlファイルでも必要な設定を加える) - 古い設定が残ったままコンパイル
コンパイル前のmake cleanを徹底(それでも上手くいかないことがある) - &NML_RIVER_TYPE (tst_run.nml)
下記の情報によれば、RIVER_NUMBER=0 (元々3)に修正する必要がある
(3のままでもとりあえず動いていたが、正しいのかは不明)
https://estuarine.jp/2018/04/build-fvcom4-1-series/ - &NML_CASE (tst_run.nml)
下記によれば、&NML_CASEの最後にDATE_REFERENCEを追記した方が良い
(無くても計算は可能だが、日付の情報が入らない)
DATE_REFERENCE = '1858-11-17 00:00:00'
謝辞
以下2つのサイトの情報が特に参考になりました。謝意を表します。
https://estuarine.jp/2018/04/build-fvcom4-1-series/
https://qiita.com/jsasaki/items/a4817acdff52c52623fd