LoginSignup
0
0

fvcom v5.0.1 をgfortranにてインストール

Posted at

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など)のインストール先

make.inc
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"で探索可能)

make.inc (L78-80)
# 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の場所)を指定

make.inc (L97-101)
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(行頭の#を外す)
インストール直後の設定であれば、変更する箇所は

make.inc (Estuary case対応 FLAG修正箇所)
#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オプションを加える

make.inc (parallel mode - MPI使用)
# 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 コメントを外し、修正

並列計算を行わないときは

make.inc (serial mode - MPI未使用)
# 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を消去
makefile (L9)
PACKAGES =      proj    fproj   julian  metis
  • L14以降にて、各ライブラリのコンパイル、インストールを行う
    今回は、proj, fproj, metis, julianを作成する(netcdfは作成しない)
    netcdfに関する行(L18-19)をコメントにする (行頭に#をつける)
    metisに関する行(L20)のコメントを外す
makefile (L12-21)
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)
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カ所ずつ)

mod_action_ex.F (L688-689)
修正前                     修正後
SIGN(REAL(1.0,SP),UNA)  -> SIGN(1.0,UNA)  # L6882カ所
SIGN(REAL(1.0,SP),UNBB) -> SIGN(1.0,UNBB) # L6892カ所

※L564のSIGN(REAL(1.0,SP),UN)は変更不要

3. ocpcre.F (L2217)

KEYWISの後の==を.eqv.に書き換え(eqvのあとは"."が2つ並ぶ)

ocpcre.F (L2217)
修正前
IF(ELTYPE == 'KEY' .AND. KEYWIS==.TRUE.) ELTYPE = 'USED'
修正後
IF(ELTYPE == 'KEY' .AND. KEYWIS.eqv..TRUE.) ELTYPE = 'USED'
4. swancom5.F (L133)

SPCSIGLをSPCSIG(IS)に書き換える

swancom5.F (L133)
修正前
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章冒頭にも記載がある

おおまかな手順

  1. 入力ファイルの準備
    testsuiteの場合、すべて用意されている
  2. make.incの修正(FLAGの設定) → 実行ファイル (fvcom, libfvcom.a)の作成
    FLAGの変更などがなければ、一度作成したfvcomファイルの再生成は不要
    fvcomファイルは単独で動くので、移動やコピー、リンクが可能
  3. namelistファイル(tst_run.nml)の修正
  4. 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の前後に' 'を追加

tst_run.nml (L187-195)
&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)

tst_run.nml (末尾に追加)
&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を追記した方が良い
    (無くても計算は可能だが、日付の情報が入らない)
&NML_CASE (tst_run.nml)
DATE_REFERENCE  = '1858-11-17 00:00:00'

謝辞

以下2つのサイトの情報が特に参考になりました。謝意を表します。
https://estuarine.jp/2018/04/build-fvcom4-1-series/
https://qiita.com/jsasaki/items/a4817acdff52c52623fd

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0