# 津波コードの使用方法 ## 概要 研究室で受け継がれている津波コードですが,以下の課題があります. - `implicit none`が行われていないこと - `main`や`subroutine` が1つのファイルにまとめられておりこと - 並列化されていないこと - 接続領域を変更するたびに`main`コードを書き換える必要があること 研究で津波計算を行うたびに,これらの問題点で結構苦しめられたので,コードを書き直しました. 書き直す際にやったことは様々あるんですけど,説明すると長くなるのでやりません. 今回は新しくしたコードの使い方を示します.一応デバッグはしましたが,不具合が生じた場合はお知らせください. ## 目次 1. ファイル構成 2. パラメータ設定 3. コンパイル・実行 4. あとがき ## 1.ファイル構成 1つにまとめられていたコードを,以下のような複数ファイルに分けました. |ファイル名|説明| | ---| ---| |MakeFile|コンパイルするときに必要なファイル| |tnm_main.f90|mainコード,基本的に触らない| |tnm_sub.f90|subroutineコード,基本的に触らない| |tnm_input_file.f90|ファイル名設定コード,入出力ファイルの場所をここで指定する| |tnm_input_vals.f90|パラメータ設定コード,計算に必要な変数の設定を行う| 基本的にはinputの2つだけをいじると計算が回るようになっています. mainとsubコードは機能を増やす時に書き換える必要がありますが,勉強をしてからにしましょう. ## 2.パラメータ設定 2つのinputファイルの設定方法を記します. - tnm_input_file.f90 コードの中身をさらっと見せると以下の通りです.(第一領域のみ) ```fortran= module input_file ! implicit none ! character*64,parameter :: F_OP1 = 'outpoint/outpoint1.dat' ! character*64,parameter :: F_DF1 = 'deform/deform1.dat' ! character*64,parameter :: F_BT1 = 'bathymetry/region1.dat' ! character*64,parameter :: F_POUT1 = 'result/point1.dat' ! character*64,parameter :: F_ZMAX1 = 'result/max1.dat' ! character*64,parameter :: F_VMAX1 = 'result/vmax1.dat' ! character*64,parameter :: F_IND1 = 'result/inund1.dat' ! character*64,parameter :: F_AT1 = 'result/atime1.dat' ! end module input_file ``` 各変数の説明は以下の通りです.(第1領域) |変数|説明|status| |---|---|---| |F_OP|波形出力点|old| |F_DF|初期水位(deformコードにより作成)|old| |F_BT|地形データ|old| |F_POUT|出力波形|unknown| |F_ZMAX|最大水位分布|unknown| |F_VMAX|最大流速分布|unknown| |F_IND|最大浸水深分布|unknown| |F_AT|到達時間分布|unknown| 文字数は見ての通り64文字に設定しているので,それ以内に抑えるようにしてください. また不要なoutputがある場合でも(流速や浸水深),コメントアウトせずに使用してください. - tnm_input_vals.f90 同じく,第一領域を見せると以下の通りです.(大分見づらいと思うので, ```fortran= module input_vals ! implicit none ! integer,parameter :: K6 = 100, KP = 60 real,parameter :: FM = 0.025, GG = 9.8, SH = -50.0 ! --- SH = 0.0:MNTK, -50.0:NLMNT ! integer,parameter :: KL = 3600 real,parameter :: DT = 0.1 ! ! <-- Boundary Condition ---> ! BC = 0.0 : vertical wall B.C. ! = -30.0 : uphill B.C. real,parameter :: BC = -30.0 ! integer,parameter :: RN = 6 integer,parameter :: P_FORM = 0 !--- 0 : ASCII, 1 : BINARY(little endian) --- integer,parameter :: FL_MNT = 0 !--- 0 : NLMNT, 1 : MNT , 2 : LNMNT ! integer,parameter :: NRU(6) = (/0,0,0,0,1,1/) ! <--inund--- 0:NO, 1:yes --- ! ! - * - * - * - * - region1 - * - * - * - * - integer,parameter :: IF1 = 691, JF1 = 1018 integer,parameter :: NP1 = 101 integer,parameter :: KSNZ1 = 100, KSTRT1 = 0, KEND1 = 54000 integer,parameter :: IZS1 = 1, IZE1 = 691, JZS1 = 1, JZE1 = 1018 real,parameter :: DX1 = 1215.0, DY1 = 1215.0 integer,parameter :: ISNV1 = 0, KSNV1 = 3000 integer,parameter :: IVS1 = 1, IVE1 = 691, JVS1 = 1, JVE1 = 1018 ! integer :: NC1 real,parameter :: RX1 = DT/DX1, RY1 = DT/DY1 character*40,dimension(NP1) :: PNAME1 real,dimension(IF1,JF1) :: HZ1, HM1, HN1, ZM1 real,dimension(IF1,JF1,2) :: Z1, M1, N1, DZ1, DM1, DN1 integer,dimension(NP1) :: IP1, JP1 real,dimension(IF1,JF1) :: VM1, ZI1 real,dimension(IF1,JF1,2) :: VEL1 real,dimension(IF1,JF1) :: AT1 integer,parameter :: I_PT1 = NP1+1, J_PT1 = KL/KP real,dimension(I_PT1,J_PT1) :: WP1 ! end module input_vals ``` 各変数の説明は,変更するもののみ行います. |行数|変数|説明| |---|---|---| |5|KP|波形出力間隔,波形出力点の時間間隔のステップ数<br>(上例だと`DT=0.1`の`KP=60`なので,6秒間隔)| |6|SH|モーメントの計算上限水深,<br>`FL_MNT=0`のとき`SH=-50.0`, `FL_MNT=1 or 2`の時,`SH=0.0` |8|KL|再現時間のステップ数(上例では,360秒) |9|DT|計算時間間隔,ある程度の細かさが必要 |14|BC|境界条件,遡上境界の場合`-30.0`,<br>完全反射境界の場合`0.0`(`FL_MNT=1 or 2`の場合も) |16|RN|計算領域数,`1~6`で指定,ここを間違えると計算が回らない可能性大| |17|P_FORM|出力形式(波形出力データのみ,snapについては今後追加予定)| |18|FL_MNT|支配方程式の指定,<br>非線形長波:`0`,線形長波(摩擦あり):`1`,線形長波(摩擦なし):`2`| |20|NRU|浸水深の出力指定,各領域毎に指定| |23|IF,JF|領域の格子数(x,y)| |24|NP|波形出力点数| |25|KSNZ|水位スナップの出力間隔ステップ数| |25|KSTRT<br>KEND|スナップの出力開始,終了ステップ数| |26|I(J)ZS<br>I(J)ZE|水位スナップの出力範囲,<br>無駄を減らすときは範囲を絞ると楽になる| |27|DX,DY|格子サイズ(m)| |28|ISNV|流速出力指定,`0`:出力なし,`1`:出力あり| |28|KSNV|流速出力間隔ステップ数,基本的にはKSNZと同じくする| |29|I(J)VS<br>I(J)VE|流速スナップの出力範囲,<br>I(J)ZS,I(J)ZEと同じくする| これらを計算する領域分指定するだけです.簡単ですね. 計算は第6領域までしかしない想定で作成したので,それ以上の計算が必要な場合は(そんな計算しないと思いますが),書き換える必要がありますので気をつけてください. ## 3.コンパイル・実行 - コンパイル 1で示したファイルを1つのディレクトリにまとめてください. 私は`module`というディレクトリにまとめています. パラメータの設定が終わったら,以下を実行します. ``` $ make ``` 問題がなければ以下のファイルが生成されます. - tunami - input_file.mod - input_vals.mod - routines.mod このうち,実行ファイルはtunamiです. これを実行する場所に移動して,実行します. - 実行 実行ファイルtunamiを実行する場所に移動しましょう. 実行する場所とは,地形データや初期水位データがある場所です. 例としては,以下のような配置を示します. - bathymetry - region1~6.dat - outpoint - outpoint1~6.dat - deform - deform1~6.dat - result - elr - vxr - vyr - tunami - run_tunami.sh - module 同じ場所でコンパイルしてもいいですが,ファイルが多くなりすぎて困るので,別のディレクトリにしましょう. 実行ですが,普通に以下のように行ってもできます. ``` $ ./tunami ``` しかし,せっかくなのでshellファイルを使用して実行しましょう. shellファイル`run_tunami.sh`は以下のようになります. ```sh= #usr/bin/bash ulimit -s unlimited ./a.out ``` これを以下のように実行します. ``` $ sh run_tunami.sh <バックグラウンドの場合> $ nohup sh run_tunami.sh -& ``` これでファイルの指定がちゃんとできていれば,計算できます. <発展> 上で示したshellファイルは単純すぎるため,shellを使う意味があまりありません.(shellの使い方の練習にはいいかも) なので,コンパイル・実行ファイル移動・実行 を一気にやりましょう. `run_tsunami.sh`を以下のように書き換えます. ```sh= #usr/bin/bash rm tunami cd module make mv tunami ../ cd ../ ulimit -s unlimited ./tunami ``` これを以下のように回せば,割とスマートにできると思います. ``` $ nohup sh run_tunami.sh -& ``` ## 4.あとがき この記事では,簡便化したtunamiコードの使い方を示しました. 基本的には,この通りに回せば簡単に回るかと思います. このコードを作成するにあたり,作るべきか少し迷いました. 理由は,簡単になりすぎると,構造などを理解せずとも計算ができてしまうからです. しかし,tunamiコードはとても長いコードであり,理解するにはとても長い時間を要します. 人によって差はあると思いますが,私はM1のときに1ヶ月以上,それだけをやることで多少理解できました. まあ,何が言いたいかというと,できれば理解を深めてから使用してほしいですが,時間的な制約があると思うのでこのコードを有効に活用して欲しいということです.(できれば感謝しながら 笑 ) 計算モデルの研究を主に行う人の場合は,是非main,subコードを読んでください. そして,不適切な部分や改良の余地がある場合は,どんどん書き換えていってください. 断層の破壊時間を考慮したコードやsnapのバイナリ出力コードは,時間があれば追加していきたいと思います. これらが急ぎで必要な場合は連絡ください.努力します笑. ###### tags: `tunami`, `Fortran`