diff --git a/fortran90.html.markdown b/fortran90.html.markdown index 4209d374..2f2cfdfd 100644 --- a/fortran90.html.markdown +++ b/fortran90.html.markdown @@ -5,8 +5,8 @@ contributors: filename: learnfortran.f90 --- -Fortran is one of the oldest computer languages. It was developed in the 1950s -by IBM for numeric calculations (Fortran is an abbreviation of "Formula +Fortran is one of the oldest computer languages. It was developed in the 1950s +by IBM for numeric calculations (Fortran is an abbreviation of "Formula Translation"). Despite its age, it is still used for high-performance computing such as weather prediction. However, the language has changed considerably over the years, although mostly maintaining backwards compatibility; well known @@ -30,29 +30,29 @@ program example !declare a program called example. ! Declaring Variables ! =================== - + ! All declarations must come before statements and expressions. - + implicit none !prevents dynamic declaration of variables (recommended!) ! Implicit none must be redeclared in every function/program/module... - + ! IMPORTANT - Fortran is case insensitive. real z REAL Z2 - real :: v,x ! WARNING: default initial values are compiler dependent! + real :: v,x ! WARNING: default initial values are compiler dependent! real :: a = 3, b=2E12, c = 0.01 integer :: i, j, k=1, m real, parameter :: PI = 3.1415926535897931 !declare a constant. logical :: y = .TRUE. , n = .FALSE. !boolean type. complex :: w = (0,1) !sqrt(-1) character (len=3) :: month !string of 3 characters. - + real :: array(6) !declare an array of 6 reals. real, dimension(4) :: arrayb !another way to declare an array. integer :: arrayc(-10:10) !an array with a custom index. real :: array2d(3,2) !multidimensional array. - + ! The '::' separators are not always necessary but are recommended. ! many other variable attributes also exist: @@ -65,8 +65,8 @@ program example !declare a program called example. ! in functions since this automatically implies the 'save' attribute ! whereby values are saved between function calls. In general, separate ! declaration and initialisation code except for constants! - - + + ! Strings ! ======= @@ -75,7 +75,7 @@ program example !declare a program called example. character (len = 30) :: str_b character (len = *), parameter :: a_long_str = "This is a long string." !can have automatic counting of length using (len=*) but only for constants. - + str_b = a_str // " keyboard" !concatenate strings using // operator. @@ -98,7 +98,7 @@ program example !declare a program called example. ! Other symbolic comparisons are < > <= >= == /= b = 4 else if (z .GT. a) then !z greater than a - ! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE. + ! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE. b = 6 else if (z < a) then !'then' must be on this line. b = 5 !execution block must be on a new line. @@ -145,32 +145,32 @@ program example !declare a program called example. cycle !jump to next loop iteration. enddo - + ! Goto statement exists but it is heavily discouraged though. - goto 10 + goto 10 stop 1 !stops code immediately (returning specified condition code). 10 j = 201 !this line is labeled as line 10 - - + + ! Arrays ! ====== array = (/1,2,3,4,5,6/) array = [1,2,3,4,5,6] !using Fortran 2003 notation. arrayb = [10.2,3e3,0.41,4e-5] array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2]) - + ! Fortran array indexing starts from 1. ! (by default but can be defined differently for specific arrays). v = array(1) !take first element of array. v = array2d(2,2) - + print *, array(3:5) !print all elements from 3rd to 5th (inclusive). print *, array2d(1,:) !print first column of 2d array. - + array = array*3 + 2 !can apply mathematical expressions to arrays. array = array*array !array operations occur element-wise. !array = array*array2d !these arrays would not be compatible. - + ! There are many built-in functions that operate on arrays. c = dot_product(array,array) !this is the dot product. ! Use matmul() for matrix maths. @@ -180,13 +180,13 @@ program example !declare a program called example. c = size(array) print *, shape(array) m = count(array > 0) - + ! Loop over an array (could have used Product() function normally). v = 1 do i = 1, size(array) v = v*array(i) end do - + ! Conditionally execute element-wise assignments. array = [1,2,3,4,5,6] where (array > 3) @@ -196,30 +196,30 @@ program example !declare a program called example. elsewhere array = 0 end where - + ! Implied-DO loops are a compact way to create arrays. array = [ (i, i = 1,6) ] !creates an array of [1,2,3,4,5,6] array = [ (i, i = 1,12,2) ] !creates an array of [1,3,5,7,9,11] array = [ (i**2, i = 1,6) ] !creates an array of [1,4,9,16,25,36] array = [ (4,5, i = 1,3) ] !creates an array of [4,5,4,5,4,5] - + ! Input/Output ! ============ - + print *, b !print the variable 'b' to the command line ! We can format our printed output. print "(I6)", 320 !prints ' 320' - print "(I6.4)", 3 !prints ' 0003' + print "(I6.4)", 3 !prints ' 0003' print "(F6.3)", 4.32 !prints ' 4.320' - - ! The letter indicates the expected type and the number afterwards gives + + ! The letter indicates the expected type and the number afterwards gives ! the number of characters to use for printing the value. - ! Letters can be I (integer), F (real), E (engineering format), + ! Letters can be I (integer), F (real), E (engineering format), ! L (logical), A (characters) ... print "(I3)", 3200 !print '***' since the number doesn't fit. - + ! we can have multiple format specifications. print "(I5,F6.2,E6.2)", 120, 43.41, 43.41 print "(3I5)", 10, 20, 30 !3 repeats of integers (field width = 5). @@ -230,7 +230,7 @@ program example !declare a program called example. read "(2F6.2)", v, x !read two numbers ! To read a file. - open(unit=11, file="records.txt", status="old") + open(unit=11, file="records.txt", status="old") ! The file is referred to by a 'unit number', an integer that you pick in ! the range 9:99. Status can be one of {'old','replace','new'}. read(unit=11, fmt="(3F10.2)") a, b, c @@ -241,39 +241,39 @@ program example !declare a program called example. write(12, "(F10.2,F10.2,F10.2)") c, b, a close(12) - ! There are more features available than discussed here and alternative + ! There are more features available than discussed here and alternative ! variants due to backwards compatibility with older Fortran versions. - - + + ! Built-in Functions ! ================== ! Fortran has around 200 functions/subroutines intrinsic to the language. - ! Examples - + ! Examples - call cpu_time(v) !sets 'v' to a time in seconds. k = ior(i,j) !bitwise OR of 2 integers. v = log10(x) !log base 10. i = floor(b) !returns the closest integer less than or equal to x. v = aimag(w) !imaginary part of a complex number. - + ! Functions & Subroutines ! ======================= - + ! A subroutine runs some code on some input values and can cause ! side-effects or modify the input values. - + call routine(a,c,v) !subroutine call. - + ! A function takes a list of input parameters and returns a single value. - ! However the input parameters may still be modified and side effects + ! However the input parameters may still be modified and side effects ! executed. - + m = func(3,2,k) !function call. - + ! Function calls can also be evoked within expressions. - Print *, func2(3,2,k) - + Print *, func2(3,2,k) + ! A pure function is a function that doesn't modify its input parameters ! or cause any side-effects. m = func3(3,2,k) @@ -297,7 +297,7 @@ contains ! Zone for defining sub-programs internal to the program. function func2(a,b,c) result(f) !return variable declared to be 'f'. implicit none - integer, intent(in) :: a,b !can declare and enforce that variables + integer, intent(in) :: a,b !can declare and enforce that variables !are not modified by the function. integer, intent(inout) :: c integer :: f !function return type declared inside the function. @@ -328,14 +328,14 @@ contains ! Zone for defining sub-programs internal to the program. end program example ! End of Program Definition ----------------------- -! Functions and Subroutines declared externally to the program listing need +! Functions and Subroutines declared externally to the program listing need ! to be declared to the program using an Interface declaration (even if they ! are in the same source file!) (see below). It is easier to define them within ! the 'contains' section of a module or program. elemental real function func4(a) result(res) ! An elemental function is a Pure function that takes a scalar input variable -! but can also be used on an array where it will be separately applied to all +! but can also be used on an array where it will be separately applied to all ! of the elements of an array and return a new array. real, intent(in) :: a res = a**2 + 1.0 @@ -345,7 +345,7 @@ end function func4 ! Modules ! ======= -! A module is a useful way to collect related declarations, functions and +! A module is a useful way to collect related declarations, functions and ! subroutines together for reusability. module fruit @@ -358,7 +358,7 @@ end module fruit module fruity ! Declarations must be in the order: modules, interfaces, variables. ! (can declare modules and interfaces in programs too). - + use fruit, only: apple, pear ! use apple and pear from fruit module. implicit none !comes after module imports. @@ -367,7 +367,7 @@ module fruity public :: apple,mycar,create_mycar ! Declare some variables/functions private to the module (redundant here). private :: func4 - + ! Interfaces ! ========== ! Explicitly declare an external function/procedure within the module @@ -377,14 +377,14 @@ module fruity real, intent(in) :: a end function func4 end interface - + ! Overloaded functions can be defined using named interfaces. interface myabs ! Can use 'module procedure' keyword to include functions already ! defined within the module. module procedure real_abs, complex_abs - end interface - + end interface + ! Derived Data Types ! ================== ! Can create custom structured data collections. @@ -394,19 +394,19 @@ module fruity real :: dimensions(3) !i.e. length-width-height (metres). character :: colour end type car - + type(car) :: mycar !declare a variable of your custom type. ! See create_mycar() routine for usage. - + ! Note: There are no executable statements in modules. - + contains subroutine create_mycar(mycar) ! Demonstrates usage of a derived data type. implicit none type(car),intent(out) :: mycar - + ! Access type elements using '%' operator. mycar%model = "Ford Prefect" mycar%colour = 'r' @@ -414,7 +414,7 @@ contains mycar%dimensions(1) = 5.0 !default indexing starts from 1! mycar%dimensions(2) = 3.0 mycar%dimensions(3) = 1.5 - + end subroutine real function real_abs(x) @@ -425,7 +425,7 @@ contains real_abs = x end if end function real_abs - + real function complex_abs(z) complex :: z ! long lines can be continued using the continuation character '&'