{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "10d0e3c5",
   "metadata": {},
   "source": [
    "## Introduction to structured programming with Fortran\n",
    "\n",
    "### Why to learn Fortran ?\n",
    "\n",
    "* Because of the execution speed of a program\n",
    "* Well suited for numerical computations : more than **45% of scientific applications** are in Fortran\n",
    "\n",
    "### Getting started\n",
    "\n",
    "#### Hello World"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00ec1776",
   "metadata": {},
   "outputs": [],
   "source": [
    "program hello_world\n",
    "\n",
    "  implicit none ! important\n",
    "\n",
    "  print *, \"Hello World!\"\n",
    "\n",
    "end program hello_world"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4b788f0",
   "metadata": {},
   "source": [
    "#### Data Type Declarations and Assignments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffd3f0c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "program data_type\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real x, y\n",
    "  integer i, j\n",
    "  logical flag\n",
    "  \n",
    "  integer matrix(2,2) \n",
    "  character(80) month\n",
    "  character(len=80) months(12)\n",
    "  \n",
    "  character family*16\n",
    "  \n",
    "  real, dimension(12) :: small_array\n",
    "  character(len=80), dimension(24) :: screen\n",
    "  \n",
    "  integer, parameter :: it = 100\n",
    "  \n",
    "  i = 1\n",
    "  j = i+2\n",
    "  x = 85.8\n",
    "  y = 3.5*cos(x)\n",
    "\n",
    "  month=\"december\"\n",
    "  \n",
    "  months(:)=\"empty\"\n",
    "  \n",
    "  months(12)=month\n",
    "  \n",
    "  flag = .TRUE.\n",
    "  \n",
    "  family = \"GEORGE P. BURDELL\"\n",
    "  print*,family(:6)\n",
    "  print*,family(8:9)\n",
    "  print*,family(11:)\n",
    "  print*,family(:6)//FAMILY(10:)\n",
    "  \n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "133046ed",
   "metadata": {},
   "source": [
    "#### Arithmetic Assignments\n",
    "\n",
    "The result of any integer divide is truncated to the integer value less than the correct decimal answer for the division. The result of this is that changing the order of operations can make a big difference in the answers.  Notice how parentheses force more expected results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13343800",
   "metadata": {},
   "outputs": [],
   "source": [
    "program arith\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real r2,r3,r4,r5,r6,ans1,ans2,ans3\n",
    "  integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4\n",
    "  \n",
    "  data r2/2./,r3/3./,r4/4.0/,r5/5.0/\n",
    "  data i2,i3,i4,i5/2,3,4,5/\n",
    "  \n",
    "  ians1=i2*i3/i5\n",
    "  ians2=i3/i5*i2\n",
    "  ians3=i2*(i3/i5)\n",
    "  ians4=(i3/i5)*i2\n",
    "  print *, '2*3/5 =', ians1, ', 3/5*2 =',ians2,', 2*(3/5) =',ians3 ,', (3/5)*2 =',ians4\n",
    "  \n",
    "end program arith"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cabea667",
   "metadata": {},
   "source": [
    "Real arithmetic behaves more uniformly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e1de5730",
   "metadata": {},
   "outputs": [],
   "source": [
    "program arith\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real r2,r3,r4,r5,r6,ans1,ans2,ans3\n",
    "  integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4\n",
    "  \n",
    "  data r2/2./,r3/3./,r4/4.0/,r5/5.0/\n",
    "  data i2,i3,i4,i5/2,3,4,5/\n",
    "  \n",
    "  ans1=r2*r3/r5\n",
    "  ans2=r3/r5*r2\n",
    "  ans3=(r3/r5)*r2\n",
    "  print *, '2.0*3.0/5.0 =', ans1, ', 3.0/5.0*2.0 =',ans2,', (3.0/5.0)*2.0 =',ans3\n",
    "      \n",
    "end program arith      "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f18b85ec",
   "metadata": {},
   "source": [
    "Watch how precedence of operations effects the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a362858",
   "metadata": {},
   "outputs": [],
   "source": [
    "program arith\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real r2,r3,r4,r5,r6,ans1,ans2,ans3\n",
    "  integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4\n",
    "  \n",
    "  data r2/2./,r3/3./,r4/4.0/,r5/5.0/\n",
    "  data i2,i3,i4,i5/2,3,4,5/\n",
    "\n",
    "  ians1=i2+i5*i3**i2\n",
    "  ians2=i5*i3**i2+i2\n",
    "  ians3=i3**i2*i5+i2\n",
    "  print *, '2+5*3**2 =',ians1,', 5*3**2+2 =',ians2, ', 3**2*5+2 =',ians3\n",
    "      \n",
    "end program arith      "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5297b017",
   "metadata": {},
   "source": [
    "You can mix real and integers, but watch what happens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7d50669e",
   "metadata": {},
   "outputs": [],
   "source": [
    "program arith\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real r2,r3,r4,r5,r6,ans1,ans2,ans3\n",
    "  integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4\n",
    "  \n",
    "  data r2/2./,r3/3./,r4/4.0/,r5/5.0/\n",
    "  data i2,i3,i4,i5/2,3,4,5/\n",
    "\n",
    "  ans1=r5+i3/i2\n",
    "  ans2=5.0+3/2\n",
    "  print *, '5.0+3/2 =',ans1\n",
    "  print *, '5.0+3/2 =',ans2\n",
    "      \n",
    "end program arith      "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "222cabbc",
   "metadata": {},
   "source": [
    "Look at what happens when I put a real in either the numerator or denominator of the division term"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "78929c6e",
   "metadata": {},
   "outputs": [],
   "source": [
    "program arith\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real r2,r3,r4,r5,r6,ans1,ans2,ans3\n",
    "  integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4\n",
    "  \n",
    "  data r2/2./,r3/3./,r4/4.0/,r5/5.0/\n",
    "  data i2,i3,i4,i5/2,3,4,5/\n",
    "\n",
    "  ans1=r5+i3/r2\n",
    "  ans2=r5+r3/i2\n",
    "  print *, '5.0+3/2.0 =',ans1, ', 5.0+3.0/2 =', ans2\n",
    "      \n",
    "end program arith           "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7d37bc2",
   "metadata": {},
   "source": [
    "Although Fortran normally works from left to right at a given level of precedence (does all multiply and divide from left to right before moving on to adds and subtracts). It works exponentiation from right to left when it hits 2 or more sequential exponentiation operations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c2da1a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "program arith\n",
    "\n",
    "  implicit none\n",
    "  \n",
    "  real r2,r3,r4,r5,r6,ans1,ans2,ans3\n",
    "  integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4\n",
    "  \n",
    "  data r2/2./,r3/3./,r4/4.0/,r5/5.0/\n",
    "  data i2,i3,i4,i5/2,3,4,5/\n",
    "\n",
    "  ians1= i5**i3**i2\n",
    "  ians2= (i5**i3)**i2\n",
    "  ians3= i5**(i3**i2)\n",
    "  print *, '5**3**2 =',ians1, ', (5**3)**2 =',ians2,  ', 5**(3**2) =',ians3\n",
    "      \n",
    "end program arith           "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8387be7a",
   "metadata": {},
   "source": [
    "When in doubt use parentheses to get the answer that you really want.\n",
    "\n",
    "#### Assignments exercise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14f6e7e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "program sphere  \n",
    "\n",
    "  implicit none\n",
    "      \n",
    "      real pi,radius,volume,area  \n",
    "          \n",
    "      radius = 1.0\n",
    "      pi = 0.0\n",
    "      \n",
    "      write(*,*) 'The value of pi is ', pi\n",
    "      write(*,*) \n",
    "\n",
    "      area = 0.0\n",
    "      volume = 0.0\n",
    "      \n",
    "      write(*,*) 'For a radius ', radius \n",
    "      write(*,*) 'the area of a sphere is ', area\n",
    "      write(*,*) 'and the volume is ', volume\n",
    "      \n",
    "end "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a1702f7",
   "metadata": {},
   "source": [
    "#### Execution Control"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41f9a8f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "PROGRAM gcd\n",
    "  ! Computes the greatest common divisor, Euclidean algorithm\n",
    "  IMPLICIT NONE\n",
    "  INTEGER :: m, n, t\n",
    "  WRITE(*,*) \"Give positive integers m and n :\"\n",
    "  m=5464\n",
    "  n=484682\n",
    "  WRITE(*,*) 'm:', m,' n:', n\n",
    "  positive_check: IF (m > 0 .AND. n > 0) THEN\n",
    "    main_algorithm: DO WHILE (n /= 0)\n",
    "      t = MOD(m,n)\n",
    "      m = n\n",
    "      n = t\n",
    "    END DO main_algorithm\n",
    "    WRITE(*,*) \"Greatest common divisor: \",m\n",
    "  ELSE\n",
    "    WRITE(*,*) 'Negative value entered'\n",
    "  END IF positive_check\n",
    "END PROGRAM gcd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cef2ad42",
   "metadata": {},
   "source": [
    "#### File-Directed Input and Output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8fd042c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "program plot\n",
    "\n",
    "  ! Program to provide plots of Sin(x)\n",
    "\n",
    "  implicit none\n",
    "  character label*150\n",
    "  real x\n",
    "  integer i\n",
    "  character xlabel*32,ylabel*32,title*32\n",
    "  real fx\n",
    "  !\n",
    "  ! label   -   Character string \n",
    "  ! xlabel  -   Contains a label for the x-axis\n",
    "  ! ylabel  -   Contains a label for the y-axis\n",
    "  ! title   -   Contains a title for the plot\n",
    "  !\n",
    "  ! Drive a separate true graphics program (gnuplot)\n",
    "  !\n",
    "  ! First set up the command file for gnuplot\n",
    "  !\n",
    "  xlabel=\"'x'\"\n",
    "  ylabel=\"'y'\"\n",
    "  title=\"'sin(x)'\"\n",
    "  open (112,file='03_gnuxy')\n",
    "  !\n",
    "  label='set xlabel '//xlabel\n",
    "  write(112,*)label\n",
    "  write(112,*)'set xrange [0:6]'\n",
    "  label='set ylabel '//ylabel\n",
    "  write(112,*)label\n",
    "  write(112,*)'set yrange [-1.2:1.2]'\n",
    "  label='plot \"03_dataxy\" using 1:2 title '//title\n",
    "  label=trim(label)//' with lines lt rgb \"red\"'\n",
    "  write(112,*) label\n",
    "  write (112,*) 'pause -1'\n",
    "  close(112)\n",
    "  !\n",
    "  !   Generate x-y pairs for the graph\n",
    "  !\n",
    "  open (112,file='03_dataxy')\n",
    "  do i=0,60\n",
    "    x=.1*i\n",
    "    fx=sin(x)\n",
    "    write(112,*) x,fx\n",
    "  enddo\n",
    "  close(112)\n",
    "  !\n",
    "end program"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "558d962e",
   "metadata": {},
   "source": [
    "This code is going to create 2 files: \"03_dataxy\" and \"03_gnuxy\".\n",
    "\n",
    "The idea is to use a linux plotting tool called \"GNUplot\" to make a graph: the first file is the data for the graph, the second one is the gnuplot script using these data.\n",
    "\n",
    "```bash\n",
    "gnuplot 03_gnuxy\n",
    "```\n",
    "\n",
    "<img src=\"../assets/sin.png\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b517d6b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Fortran",
   "language": "Fortran",
   "name": "fortran_spec"
  },
  "language_info": {
   "file_extension": "f90",
   "mimetype": "text/plain",
   "name": "fortran"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
