Fortranの拡張をいろいろ盛り込んだオレオレIO

更新ログ:2021/05/01 ご指摘いただいた事項を修正しました！
ありがとうございました。

# Frotranを拡張していろいろ盛り込んだIOを作りました。


↓こちらの```src/IOClass/IOClass.f90```にコード等があります。

https://github.com/kazulagi/plantFEM.git



私は物覚えが悪くコーディングが苦手なので、そんな私でも気軽にコードを書けるライブラリを目指しています。
しばらく運用してきて、今では当たり前になっている程ちょっと便利なあれこれをメモします。

# ファイルOpen, write, close

ファイルを書き込み専用で開き、文字を書き、閉じます。

```Fortran
program main
    use IOClass
    implicit none

    type(IO_) :: f

    call f%open("hello.txt",'w')
    call f%write("Hello, world!")
    call f%close()
    
end program main

```

もちろん、pythonを真似ています。
IOクラスのインスタンスに面倒なことを全部押し込めて、制約はあるものの最小限のことはストレスなしにできます。

なお、読み込み専用で開いて書き込もうとした場合、エラーが出ます。

```Fortran
program main
    use IOClass
    implicit none

    type(IO_) :: f

    call f%open("hello.txt",'r') ! 読み込み専用
    call f%write("Hello, world!")!書き込もうとする
    call f%close()
    
end program main

```

実行結果：


```shell
IOClass >> Error >> This file is readonly.
Nothing is written.
```
# 配列の書き出し

配列も書き出せます。疑似乱数の入った配列を書き出します。

```Fortran
program main
    use IOClass
    use RandomClass
    implicit none

    type(IO_) :: f
    
    ! ランダム配列を作成
    type(Random_) :: random
    real(real64),allocatable :: matrix(:,:)
    matrix = random%randn(5,3) 

    ! ファイルへ出力
    call f%open("hello.txt",'w')
    call f%write(matrix)
    call f%close()
    
end program main
```

実行結果：

```
  0.67536126921419082       0.69757660370274011       0.60094521743857499     
  0.59806235391600904       0.74967556553758152       0.90754945224994465     
  0.75558385131066363       0.12390139489396934       0.79041193308025293     
   8.6508975968684232E-002  0.22201368894750784       0.51021838491468208     
  0.26723752139363488       0.90740198182976362       0.11228899238368861     

```

# 一行ずつ最終行まで読み込む

全部文字列型として読み込まれます。

```Fortran
program main
    use IOClass
    use RandomClass
    implicit none

    type(IO_) :: f
    
    ! 1行ずつ読み込み
    call f%open("hello.txt",'r')
    do 
        if(f%EOF) exit !End of Fileを検出
        call print( f%readline() )
    enddo
    call f%close()
    

end program main
```

出力

```shell
0.67536126921419082       0.69757660370274011       0.60094521743857499
0.59806235391600904       0.74967556553758152       0.90754945224994465
0.75558385131066363       0.12390139489396934       0.79041193308025293
8.6508975968684232E-002  0.22201368894750784       0.51021838491468208
0.26723752139363488       0.90740198182976362       0.11228899238368861
```

ベクトルを読み込む例：

```Fortran
program main
    use IOClass
    use ArrayClass

    implicit none
    
    type(IO_) :: f
    real(real64),allocatable :: a(:)
    integer(int32) :: vector_size,k
    
    ! 1行ずつ読み込み
    call f%open("hello.txt",'r')
    call f%read(vector_size)
    
    ! vector_sizeの大きさのベクトルを、成分すべてゼロで埋めて初期化
    a = zeros(vector_size) 

    k=0
    do k=1,vector_size
        call f%read(a(k) )
    enddo
    call f%close()

end program main
```
今後、追加したい機能ができたり、リクエストを頂いたら機能を充実させようと思います。

2021/04/30 13:00追記

このままだとpythonの劣化版コピーになりそうなので、少し変な例を追記します。
MPIを使って無駄に複数プロセスから連番ファイルを作成します。

```Fortran
program main
    use IOClass
    use RandomClass
    use MPIClass
    implicit none

    type(IO_) :: f
    type(MPI_) :: mpid
    type(Random_) :: random
    real(real64),allocatable :: matrix(:,:)

    ! MPIプロセスを起動
    call mpid%start()

    ! プロセスごとに乱数配列生成
    matrix = random%randn(5,2)

    ! RandomArray+[各プロセスのID:0~n]+.txt　のファイル名で書き込み
    call f%open("RandomArray"//str(mpid%myrank)//".txt",'w')
    call f%write(matrix)
    call f%close()

    ! MPIプロセスを終了
    call mpid%end()

end program main
```

実行結果（ファイルの中身をtailで表示しています）：

```実行結果

==> RandomArray0.txt <==
  0.13358124007489824       0.30942756280821027     
  0.91429368767347441        3.6723915916362371E-003
  0.79563657553889677        7.5968026161326585E-002
  0.52397486475551402       0.10411972865166408     
  0.98648440745513211       0.34160400739322294     

==> RandomArray1.txt <==
  0.58591290030779586       0.27005717525812956     
  0.74099504929005300       0.27308210837237179     
  0.24246487752131585       0.52686351576746970     
   1.7073996870589081E-002  0.77873768203914484     
  0.70074166638753155       0.90150905063838749     

==> RandomArray2.txt <==
  0.18961760714972586       0.24390471147059178     
  0.14709164649379058       0.17226645744811075     
  0.57021241598938266       0.24058007257742742     
   5.0949403785039871E-002  0.81951667425579844     
  0.73324091042227757       0.78762545339124646     

==> RandomArray3.txt <==
  0.74468275167468678       0.59067804940089152     
  0.97496026030280525       0.29655465505147727     
  0.42163374300476952       0.13652505186054953     
  0.22036072578754673       0.61955516343189088     
  0.37554403953208015       0.17710431989767361     
```


乱文失礼いたしました。