# Fortran
## Fortran Basic
* ### Variables
Cases do not matter in Fortran. i.e., `a` is identical to `A`.
* ### Built-in functions
* `SQRT`
* `ABS`
* `EXP`
* `LOG` (natural log) & `LOG10`
* `SIN`, `COS`, `TAN`; `ASIN`, `ACOS` & `ATAN`
## Loops
* ### IF
```fortran
IF ((c>a) .AND. (a>b)) THEN
WRITE(*,*) '1'
ELSEIF (a<0) THEN
WRITE(*,*) '2'
ELSE
WRITE(*,*) '3'
ENDIF
```
A logical expression must be wrapped with `()`.
* #### Logical expressions
| Code | Algorithm |
|:---- |:--------- |
| `==` | $=$ |
| `/=` | $\neq$ |
* #### Boolean algebra
| Code | Algorithm |
|:------- |:--------- |
| `.AND.` | and |
| `.OR.` | or |
| `.NOT.` | not |
* ### DO
**e.g.,** calculating $\displaystyle S=\sum^{100}_{r=1}r!$:
```Fortran
S = 0
s = 1
DO r = 1,100,1
s = s*r
S = S+s
END DO
```
#### Variation: `DO WHILE`
**e.g.,**
```Fortran
DO WHILE (k>0)
WRITE(*,*) ‘Please input next number (>0):’
READ(*,*) k
IF (k>0) THEN
S = S+k
WRITE(*,*) ‘Sum =’, S
ENDIF
END DO
WRITE(*,*) ‘Do not input 0 or negative number!’
```
#### Special commands:
* `CYCLE`: forces to go back to top and continue. e.g.,
```Fortran
DO I=1,5
IF (I==3) THEN
CYCLE ! go back to top and continue
END IF
WRITE(*,*) I
END DO
```
* `EXIT`: forces to exit loop.
* ### WHERE
e.g.,
```Fortran
REAL,DIMENSION(5) :: A, B, C
A = 0.0
B = 1.0
C = [0.0, 4.0, 5.0, 10.0, 0.0]
! Simple where construct use
WHERE (C/=0)
A=B/C
ELSEWHERE
A=0.0
END WHERE
```
## File I/O
* ### Opening a file
```Fortran
OPEN(100, FILE='file1.txt', FORM='formatted', STATUS='replace')
OPEN(200, FILE='file2.dat', FORM='unformatted', STATUS='old')
```
* `FORM` can be:
1. `formatted` (default), for .txt files
2. `unformatted`, for .dat files
* `STSTUS` can be:
1. `unknown` (default)
2. `old`
3. `new`
4. `replace`
* ### Reading data
```FORTRAN
READ(100,*) var
```
When the file is `formatted`, one line is read in at a time.
* ### Writing data
```Fortran
WRITE(100,*) var
```
* ### Closing a file
```Fortran
CLOSE(100)
```
* ### Formmated text
```Fortran
WRITE (*,001) a
101 FORMAT (F5.2)
```
#### Formats
* Float: `Fw.d`, e.g.,
```
F7.2
-> __-0.01
```
* Scientific notation: `Ew.dek` or `ESw.dek`, e.g.,
```
E11.3e3
-> _0.123E+003
ES11.3e3
-> _1.230E+002
```
* Integer: `Iw` or Iw.d`, e.g.,
```
I5
-> __123
```
* String: `Aw`, e.g.,
```
A9
-> __Fortran
A4
-> Fort
```
* Space: `wX`, e.g.,
```
3X
-> ___
```
**Strings can be included in format code**, e.g.,
```Fortran
WRITE(*,001) A, B, C
001 FORMAT (1X,'A=',I3,1X,'B=',F5.2,1X,'C=',A8)
```
**Format codes can be "repeated"**, e.g.,
```Fortran
FORMAT(A9, 3F6.1, I4.2)
FORMAT(A9, 3(2X, F4.1), 2X, I2)
```
* ### Direct access
```Fortran
OPEN(100, FILE='file1.txt', FORM='formatted', STATUS='replace', ACCESS='direct', RECL=Lrec)
READ(100,*,REC=6)
```
* **The** `FORM` **term only needs to be filled when the file is formatted.**
```Fortran
INQUIRE(IOLENGTH=Lrec) var
```
* `Lrec` is the length of var when trying to write a .dat file.
## Array
The size must be declared:
```Fortran
REAL,DIMENSION(-180:180,-90:90,12) :: A
INTEGER,DIMENSION(12) :: B = (/1,2,3,4,5,6,6,8,9,10,11,12/)
```
Subscripts do not necessarily start at `1`.
* ### Indexing
```Fortran
A(1,1,1) = 1013.
```
* ### Implict loop
An implict loop is regarded as a whole.
**e.g.,** Reading data from the following file alternatively to two separate arrays:
```
1.1, 1.2, 1.3, 1.4, 1.5, 1.6
2.1, 2.2, 2.3, 2.4, 2.5, 2.6
3.1, 3.2, 3.3, 3.4, 3.5, 3.6
```
we can use the following code:
```Fortran
DO i = 1,3
READ(100,*) (A(i,j),B(i,j), j=1,3)
END DO
```
* ### Array operation
* Summation
```Fortran
s = SUM(A(:,:),[1],[A>0.])
```
The `dim` and `mask` terms are optional and brackets shall not be added.
* Count
```Fortran
c = COUNT(A>0.,[1])
```
The `dim` term is optional.
* Finding max and min values
```Fortran
MxVl = MAXVAL(A,[dim],[mask])
MnLc = MINLOC(A,[dim],[mask])
MxVl = MAXVAL(A,[dim],[mask])
MnLc = MINLOC(A,[dim],[mask])
```
## Function and subroutine
* ### Function
**e.g.,** $\cot(x)$
```Fortran
PROGRAM calc_cot ! main program
IMPLICIT NONE
REAL :: x, COT
WRITE(*,*) 'input:'
READ (*,*) x
WRITE(*,*) COT(x)
END PROGRAM calc_cot
FUNCTION COT(x) ! custom function
IMPLICIT NONE
REAL,intent(in) :: x
REAL :: COT
COT = 1./TAN(x)
RETURN
END FUNCTION COT
```
* The output of the function is its name, i.e., `COT` in this case. **It must also be declared in the main program.**
* ### Subroutine
**e.g.,** $\cot(x)$
```Fortran
PROGRAM test ! main program
IMPLICIT NONE
REAL :: x, COT
WRITE(*,*) 'input:'
READ (*,*) x
CALL calc_cot(x,COT)
WRITE(*,*) COT
END PROGRAM test
SUBROUTINE calc_cot(x,COT) ! custom function
REAL,intent(in) :: x
REAL,intent(out) :: COT
COT = 1./TAN(x)
RETURN
END SUBROUTINE calc_cot
```
* The name of variables cannot be the same as that of the subroutine's.
## Examples
* ### Integration
\begin{align}
\int^b_af(x)dx\fallingdotseq
\frac{\Delta x}2[f(a)+2f(a+\Delta x) +2f(a+2\Delta x) +\cdots+f(b)]
\end{align}