diff --git a/slides.md b/slides.md index 258fb855a4ea238feb3b6ba911152e79459a76d9..313831aedbaa3d29d56fd5e64fd66ec2b4d17f97 100644 --- a/slides.md +++ b/slides.md @@ -2,7 +2,6 @@ marp: true title: Introduction to structured programming with Fortran author: P.Y. Barriat -description: https://dev.to/nikolab/complete-list-of-github-markdown-emoji-markup-5aia backgroundImage: url('assets/back.png') _backgroundImage: url('assets/garde.png') footer: 09/11/2023 | Introduction to structured programming with Fortran @@ -28,11 +27,11 @@ https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran # Fortran : shall we start ? -- You know already one computer language ? +- You already know one computer language ? - You understand the very basic programming concepts : - - What is a variable, an assignment, function call, etc.? - - Why do I have to compile my code? - - What is an executable? + - What is a variable, an assignment, function call, etc. ? + - Why do I have to compile my code ? + - What is an executable ? - You (may) already know some Fortran ? - How to proceed from old Fortran, to much more modern languages like Fortran 90/2003 ? @@ -40,22 +39,23 @@ https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran # Why to learn Fortran ? -- Because of the execution `speed` of a program -- Well suited for numerical computations : +* Because of the execution `speed` of a program +* Well suited for numerical computations : more than 45% of scientific applications are in Fortran -- `Fast` code : compilers can optimize well -- Optimized `numerical libraries` available -- Fortran is a `simple` langage and it is (kind-of) `easy to learn` +* `Fast` code : compilers can optimize well +* Optimized `numerical libraries` available +* Fortran is a `simple` langage and it is (kind-of) `easy to learn` --- # Fortran is simple - **We want to get our science done! Not learn languages!** -- How easy/difficult is it really to learn Fortran ? -- The concept is easy: +* How easy/difficult is it really to learn Fortran ? +* The concept is easy: *variables, operators, controls, loops, subroutines/functions* -- **Invest some time now, gain big later!** + +* **Invest some time now, gain big later!** --- @@ -76,23 +76,23 @@ more than 45% of scientific applications are in Fortran # Starting with Fortran 77 -- Old Fortran provides only the absolute minimum! -- Basic features : -data containers (integer, float, ...), arrays, basic operators, loops, I/O, subroutines and functions -- But this version has flaws: -no dynamic memory allocation, old & obsolete constructs, “spaghetti†code, etc. +- Old Fortran provides only the absolute minimum ! +- Basic features + > data containers (integer, float, ...), arrays, basic operators, loops, I/O, subroutines and functions +- But this version has flaws + > no dynamic memory allocation, old & obsolete constructs, "spaghetti" code, etc. - Is that enough to write code ? --- # Fortran 77 → Fortran >90 -- If Fortran 77 is so simple, why is it then so difficult to write good code? -- Is simple really better? -⇒ Using a language allows us to express our thoughts (on a computer) +- If Fortran 77 is so simple, why is it then so difficult to write good code ? +- Is simple really better ? + > ⇒ Using a language allows us to express our thoughts (on a computer) - A more sophisticated language allows for more complex thoughts - More language elements to get organized -⇒ Fortran 90/95/2003 (recursive, OOP, etc) + > ⇒ Fortran 90/95/2003 (recursive, OOP, etc) --- @@ -122,19 +122,19 @@ This version requires a fixed format for programs Versions >90 relaxe these requirements: -- comments following statements (! delimiter) +- comments following statements (`!` delimiter) - long variable names (31 characters) - containing only letters, digits or underscore - max row length is 132 characters - can be max 39 continuation lines -- if a line is ended with ampersand (&), the line continues onto the next line -- semicolon (;) as a separator between statements on a single line +- if a line is ended with ampersand (`&`), the line continues onto the next line +- semicolon (`;`) as a separator between statements on a single line --- # Program Organization -Most FORTRAN programs consist of a main program and one or more subprograms +Most `FORTRAN` programs consist of a main program and one or more subprograms There is a fixed order: @@ -259,8 +259,8 @@ and smaller byte size *(low)* to larger byte size *(high)* ## Examples: -> Fortran 77 source code [arith.f](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/01_arith.f) -> Fortran 77 source code [sphere.f](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/02_sphere.f) +> Fortran 77 source code [01_arith.f](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/01_arith.f) +> Fortran 77 source code [02_sphere.f](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/02_sphere.f) --- @@ -481,22 +481,23 @@ END DO # Comments on Loop Statements -In old versions: +### To exit a loop + +- in old versions: use a `GO TO` statement -- to transfer out (exit loop), use a `GO TO` -- to skip to next loop, use `GO TO` terminating statement (this is a good reason to always make this a `CONTINUE` statement) +- in new versions: use an `EXIT` statement + > you cannot transfer out of multiple nested loops with a single `EXIT` + > use named loops if needed : `myloop : do i=1,n` and then `EXIT myloop` -In new versions: +### To skip to next loop cycle -- to transfer out (exit loop), use `EXIT` statement and control is transferred to statement following loop end. This means you cannot transfer out of multiple nested loops with a single `EXIT` statement (use named loops if needed - `myloop : do i=1,n`). This is much like a `BREAK` statement in other languages. -- to skip to next loop cycle, use `CYCLE` statement in loop. +- in new versions **only** : use a `CYCLE` statement --- # File-Directed Input and Output -Much of early FORTRAN was devoted to reading input data -from "cards" and writing to a line printer +Much of early FORTRAN was devoted to reading input data from "cards" and writing to a line printer Today, most I/O is to and from a file: it requires more extensive I/O capabilities standardized until FORTRAN 77 @@ -506,14 +507,11 @@ Today, most I/O is to and from a file: it requires more extensive I/O capabiliti - data reading & writing with `READ` & `WRITE` - can use **unformatted** `READ` & `WRITE` if no human readable data are involved (much faster access, smaller files) -> Fortran 77 source code [plot.f](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/03_plot.f) - --- # `READ` Statement -- syntax: `READ(dev_no, format_label) variable_list` -- read a record from `dev_no` using `format_label` and assign results to variables in `variable_list` +Syntax: `READ(dev_no, format_label) variable_list` ```fortran READ(105,1000) A,B,C @@ -522,8 +520,11 @@ Today, most I/O is to and from a file: it requires more extensive I/O capabiliti > device numbers 1-7 are defined as standard I/O devices -- each `READ` reads one or more lines of data and any remaining data in a line that is read is dropped if not translated to one of the variables in the `variable_list` -- `variable_list` can include implied `DO` such as: `READ(105,1000)(A(I),I=1,10)` +- each `READ` reads one line of data + > any remaining data in a line is dropped if not translated in `variable_list` + +- `variable_list` can include implied `DO` such as : + `READ(105,1000)(A(I),I=1,10)` --- @@ -538,18 +539,16 @@ Today, most I/O is to and from a file: it requires more extensive I/O capabiliti ```fortran INTEGER K REAL(8) A,B +! reads one line and look for floating point values for A & B and an integer for K OPEN(105,FILE='path_to_existing_file') READ(105,*) A,B,K ``` -> read one line and look for floating point values for A and B and an integer for K - --- # `WRITE` Statement -- syntax: `WRITE(dev_no, format_label) variable_list` -- write variables in `variable_list` to output `dev_no` using format specified in format statement with `format_label` +Syntax: `WRITE(dev_no, format_label) variable_list` ```fortran WRITE(*,1000) A,B,KEY @@ -563,9 +562,7 @@ READ(105,*) A,B,K - device number `*` is by default the screen (or *standard output* - also 6) - each `WRITE` produces one or more output lines as needed to write out `variable_list` using `format` statement -- `variable_list` can include implied `DO` such as: `WRITE(*,2000)(A(I),I=1,10)` - -<!-- _footer: "" --> +- `variable_list` can include implied `DO` --- @@ -609,6 +606,16 @@ endif --- +# Examples + +Fortran 77 source code [03_histogram.f](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/03_histogram.f) + +Fortran 90 source code [03_histogram.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/03_histogram.f90) + +Fortran 90 source code [04_plot.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/04_plot.f90) + +--- + # `NAMELIST` It is possible to pre-define the structure of input and output data using `NAMELIST` in order to make it easier to process with `READ` and `WRITE` statements @@ -633,16 +640,14 @@ On input, the `NAMELIST` data must be structured as follows: / ``` -> Fortran 90 source code [namelist.f90](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/04_namelist.f90) -> Namelist file [namelist.def](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/04_namelist.def) +> Fortran 90 source code [05_namelist.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/05_namelist.f90) +> Namelist file [05_namelist.def](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/05_namelist.def) --- # Internal `WRITE` Statement Internal `WRITE` does same as `ENCODE` in F77 : **a cast to string** -> `WRITE (dev_no, format_label) var_list` -> write variables in `var_list` to internal storage defined by character variable used as `dev_no` = default character variable (not an array) ```fortran INTEGER*4 J,K @@ -663,8 +668,6 @@ CHAR50=' 1 2' # Internal `READ` Statement Internal `READ` does same as `DECODE` in F77 : **a cast from string** -> `READ (dev_no, format_label) var_list` -> read variables from internal storage specified by character variable used as `dev_no` = default character variable (not an array) ```fortran INTEGER K @@ -681,8 +684,6 @@ Results: A=1.2, B=2.3, K=-5 ``` -<!-- _footer: "" --> - --- # Structured programming @@ -699,25 +700,25 @@ It is a **programming paradigm** aimed at improving the quality, clarity, and ac # Functions and Subroutines -`FUNCTION` & `SUBROUTINE` are subprograms that allow structured coding +Subprograms allow **structured coding** -- `FUNCTION`: returns a single explicit function value for given function arguments - It’s also a variable → so must be declared ! -- `SUBROUTINE`: any values returned must be returned through the arguments (no explicit subroutine value is returned) -- functions and subroutines are **not recursive in F77** + `FUNCTION`: returns single explicit function value for given function arguments + > it's also a variable → so must be declared ! -Subprograms use a separate namespace for each subprogram so that variables are local to the subprogram + `SUBROUTINE`: any values returned must be returned through the arguments + > no explicit subroutine value is returned ! -- variables are passed to subprogram through argument list and returned in function value or through arguments -- variables stored in `COMMON` may be shared between namespaces +* Subprograms are not recursive in F77 -<!-- _footer: "" --> +* Subprograms use a separate namespace (variables are local) + +* Variables stored in `COMMON` may be shared between namespaces --- # Functions and Subroutines - cont'd -Subprograms must (should) include at least one `RETURN` (can have more) and be terminated by an `END` statement +Subprograms must (should) include at least one `RETURN` `FUNCTION` example: @@ -758,40 +759,35 @@ RESULT = WEIGHT*AVR Any returned values must be returned through argument list -> Fortran 90 source code [newton.f90](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/05_newton.f90) - --- # Arguments -Arguments in subprogram are `dummy` arguments used in place of the real arguments +Arguments in subprogram are `dummy` arguments +> arguments used in invocation are called "actual" or "real" -- arguments are passed by **reference** (memory address) if given as *symbolic* - >the subprogram can then alter the actual argument value since it can access it by reference -- arguments are passed by **value** if given as *literal* (so cannot be modified) +- passed by **reference** (memory address) if given as *symbolic* + > the subprogram can then alter the actual argument value since it can access it by reference + +- passed by **value** if given as *literal* (so cannot be modified) ```fortran CALL AVG3S(A1,3.4,C1,QAV) ``` -> 2nd argument is passed by value - QAV contains result - -```fortran -CALL AVG3S(A,C,B,4.1) -``` +> 2nd argument is passed by value and others by reference -> no return value is available since "4.1" is a value and not a reference to a variable! --- # Arguments - cont'd -- `dummy` arguments appearing in a subprogram declaration cannot be an individual array element reference, e.g., `A(2)`, or a *literal*, for obvious reasons! -- arguments used in invocation (by calling program) may be *variables*, *subscripted variables*, *array names*, *literals*, *expressions* or *function names* -- using symbolic arguments (variables or array names) is the **only way** to return a value (result) from a `SUBROUTINE` +Arguments used in invocation (by calling program) may be *variables*, *array names*, *literals*, *expressions* or *function names* -> It is considered **BAD coding practice**, but functions can return values by changing the value of arguments - This type of use should be strictly **avoided**! +Using symbolic arguments (variables or array names) is the **only way** to return a value (result) from a `SUBROUTINE` + +It is considered **BAD coding practice**, but functions can return values by changing the value of arguments +> this type of use should be strictly **avoided** ! --- @@ -812,7 +808,7 @@ SUBROUTINE AVG3S(A,B,C,AVERAGE) END ``` -> Compiler uses `INTENT` for error checking and optimization +> compiler uses `INTENT` for error checking and optimization --- @@ -843,22 +839,19 @@ END # Arrays with Subprograms -Arrays present special problems in subprograms - -- must pass by reference to subprogram since there is no way to list array values explicitly as literals -- how do you tell subprogram how large the array is ? +Arrays must be passed by reference to subprogram -> Answer varies with FORTRAN version and vendor (dialect)... +How do you tell subprogram how large the array is ? +> answer varies with FORTRAN version and vendor (dialect)... -When an array element, e.g. `A(1)`, is used in a subprogram invocation (in calling program), it is passed as a reference (address), just like a simple variable +- when an array element, e.g. `A(1)`, is used in a subprogram invocation , it is passed as a reference (address), just like a simple variable -When an array is used by name in a subprogram invocation (in calling program), it is passed as a reference to the entire array. In this case the array must be appropriately dimensioned in the subroutine (and this can be tricky...) +- when an array is used by name in a subprogram invocation, it is passed as a reference to the entire array. + > the array must be appropriately dimensioned (and this can be tricky...) --- -# Arrays - cont'd - -### Data layout in multi-dimensional arrays +# Data layout in multi-dimensional arrays - always increment the left-most index of multi-dimensional arrays in the innermost loop (i.e. fastest) - **column major** ordering in Fortran vs. **row major** ordering in C @@ -874,10 +867,9 @@ end do --- -# Arrays - cont'd +# Arrays - dynamic allocation -- dynamically allocate memory for arrays using `ALLOCATABLE` on declaration -- memory is allocated through `ALLOCATE` statement in the code and is deallocated through `DEALLOCATE` statement +Using `ALLOCATABLE` on declaration, and using `ALLOCATE` and `DEALLOCATE` later ```fortran integer :: m, n @@ -890,22 +882,33 @@ allocate( mat(m, n)) deallocate(idx , mat) ``` -> It exists many array intrinsic functions: SIZE, SHAPE, SUM, ANY, MINVAL, MAXLOC, RESHAPE, DOT_PRODUCT, TRANSPOSE, WHERE, FORALL, etc +It exists many array intrinsic functions +> SIZE, SHAPE, SUM, ANY, MINVAL, MAXLOC, RESHAPE, DOT_PRODUCT, TRANSPOSE, WHERE, FORALL, etc --- # `COMMON` & `MODULE` Statement -The `COMMON` statement allows variables to have a more extensive scope than otherwise +A variable declared in a `Main` program can be made accessible to subprograms + +- `COMMON` statement allows variables to have a more extensive scope + > can group into **labeled** `COMMON` + +- with > F90, it's better to use a `MODULE` subprogram + > this can be selective (don't have to share all everywhere) with `ONLY` + +> Fortran 77 source code [06_common.f](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/06_common.f) +> Fortran 90 source code [06_module.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/06_module.f90) + +--- + +# Hands-on -- a variable declared in a `Main Program` can be made accessible to subprograms (without appearing in argument lists of a calling statement) -- this can be selective (don't have to share all everywhere) with `ONLY` -- **placement**: among type declarations, after `IMPLICIT` or `EXPLICIT`, before `DATA` statements -- can group into **labeled** `COMMON` +Fortran 90 source code [07_plot_newton.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/07_plot_newton.f90) -With > F90, it's better to use the `MODULE` subprogram instead of the `COMMON` statement +Fortran 90 source code [07_newton.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/07_newton.f90) -> Fortran 77 source code [common.f](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/06_common.f) - Fortran 90 source code [module.f90](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/06_module.f90) +Text file [08_ChristmasTree.txt](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/08_ChristmasTree.txt) --- @@ -1124,7 +1127,7 @@ ifort -O3 \ -I${EBROOTNETCDFMINFORTRAN}/include -L${EBROOTNETCDFMINFORTRAN}/lib -lnetcdff ``` -> Fortran 90 source code [OceanGrideChange.f90](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/07_OceanGrideChange.f90) with the input file [input.nc](https://gogs.elic.ucl.ac.be/pbarriat/learning-fortran/src/master/src/07_input.nc) +> Fortran 90 source code [09_OceanGrideChange.f90](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/09_OceanGrideChange.f90) with the input file [09_input.nc](https://forge.uclouvain.be/barriat/learning-fortran/-/blob/master/src/09_input.nc) --- diff --git a/slides.pdf b/slides.pdf index 1ced077d3a59720207acfa6e17ce3b9820974916..91c1ea31e4f88989bde4be42084d488f76354e0a 100644 Binary files a/slides.pdf and b/slides.pdf differ diff --git a/src/03_histogram.data b/src/03_histogram.data new file mode 100644 index 0000000000000000000000000000000000000000..34f90c8aa0996f060fe00394414a75489de52133 --- /dev/null +++ b/src/03_histogram.data @@ -0,0 +1,10 @@ +1 +2 +3 +10.0 +0.1 +-1 +4 +10000 +900 +4.1 \ No newline at end of file diff --git a/src/03_histogram.f b/src/03_histogram.f new file mode 100644 index 0000000000000000000000000000000000000000..83b5bd9db92f88c05f1e7104bd8eeae153705e6c --- /dev/null +++ b/src/03_histogram.f @@ -0,0 +1,60 @@ +C +C histogram.f +C + PROGRAM HIST + + INTEGER MAXDATA + PARAMETER (MAXDATA = 1000) + + INTEGER NOBND + PARAMETER (NOBND = 9) + REAL BOUND(NOBND) + + REAL HISTO_DATA(MAXDATA) + INTEGER I, NODATA + + DATA BOUND /0.1, 0.3, 1.0, 3.0, 10.0, 30.0, 100.0, 300.0, 1000.0/ + + OPEN( 10, FILE = '03_histogram.data', STATUS = 'OLD', ERR = 900 ) + OPEN( 20, FILE = '03_histogram.out' ) + + DO 110 I = 1,MAXDATA + READ( 10, *, END = 120, ERR = 900 ) HISTO_DATA(I) + 110 CONTINUE + + 120 CONTINUE + CLOSE( 10 ) + NODATA = I - 1 + + CALL PRHIST( HISTO_DATA, NODATA, BOUND, NOBND ) + STOP + +C File not found, and other errors + + 900 CONTINUE + WRITE( *, * ) 'File histogram.data could not be opened or some rea + &ding error' + + END + +C +C Subroutine to print the histogram +C + SUBROUTINE PRHIST( HISTO_DATA, NODATA, BOUND, NOBND ) + REAL HISTO_DATA(*), BOUND(*) + INTEGER NODATA, NOBND + + INTEGER I, J, NOHIST + + DO 120 I = 1,NOBND + NOHIST = 0 + DO 110 J = 1,NODATA + IF ( HISTO_DATA(J) .LE. BOUND(I) ) THEN + NOHIST = NOHIST + 1 + ENDIF + 110 CONTINUE + + WRITE( 20, '(F10.2,I10)' ) BOUND(I), NOHIST + 120 CONTINUE + + END diff --git a/src/03_histogram.f90 b/src/03_histogram.f90 new file mode 100644 index 0000000000000000000000000000000000000000..1e4b301411240838d4b47b3b2057ac74e4d81029 --- /dev/null +++ b/src/03_histogram.f90 @@ -0,0 +1,54 @@ +! +! histogram.f90 +! +program hist + implicit none + + integer, parameter :: maxdata = 1000 + integer, parameter :: nobnd = 9 + + real, dimension(maxdata) :: histo_data + real, dimension(nobnd) :: bound = (/0.1, 0.3, 1.0, 3.0, 10.0, 30.0, 100.0, 300.0, 1000.0/) + + integer :: i, nodata, ierr + + open( 10, file = '03_histogram.data', status = 'old', iostat = ierr ) + + if ( ierr /= 0 ) then + write( *, * ) 'file histogram.data could not be opened' + stop + endif + + open( 20, file = '03_histogram.out' ) + + do i = 1,size(histo_data) + read( 10, *, iostat = ierr ) histo_data(i) + + if ( ierr > 0 ) then + write( *, * ) 'Error reading the data!' + stop + elseif ( ierr < 0 ) then + exit ! Reached the end of the file + endif + enddo + + close( 10 ) + nodata = i - 1 + + call print_history( histo_data(1:nodata), bound ) + +contains + + ! subroutine to print the histogram + ! + subroutine print_history( histo_data, bound ) + real, dimension(:), intent(in) :: histo_data, bound + + integer :: i + + do i = 1,size(bound) + write( 20, '(f10.2,i10)' ) bound(i), count( histo_data <= bound(i) ) + enddo + end subroutine print_history + +end program hist diff --git a/src/03_plot.f b/src/03_plot.f deleted file mode 100644 index ef637ee7cd29027ecae3218aaab826be05f64235..0000000000000000000000000000000000000000 --- a/src/03_plot.f +++ /dev/null @@ -1,59 +0,0 @@ - program plot -c -c Program to provide plots of Sin(x) -c - implicit none - character label*150 - real x - integer i - character xlabel*32,ylabel*32,title*32 - real fx -c -c label - Character string -c xlabel - Contains a label for the x-axis -c ylabel - Contains a label for the y-axis -c title - Contains a title for the plot -c -c Drive a separate true graphics program (gnuplot) -c -c First set up the command file for gnuplot -c - xlabel='''x''' - ylabel='''y''' - title="'sin(x)'" - open (112,file='03_gnuxy') -c -c write(112,*) 'set term wxt size 800, 800' -c - label='set xlabel '//xlabel - write(112,*)label - write(112,*)'set xrange [0:6]' - label='set ylabel '//ylabel - write(112,*)label - write(112,*)'set yrange [-1.2:1.2]' - label='plot "03_dataxy" using 1:2 title '//title - label=trim(label)//' with lines lt rgb "red"' - write(112,*) label - write (112,*) 'pause -1' - close(112) -c -c Generate x-y pairs for the graph -c - open (112,file='03_dataxy') - do 100 i=0,60 - x=.1*i - fx=sin(x) - write(112,*) x,fx - 100 continue - close(112) -c - print *, ' Hit the Return (Enter) key to continue' -c -c Tell the system to run the program gnuplot -c This call works on either IBM RS6000 or Sun, but is not part of -c the Fortran standard. -c Comment out the line if you aren't at a terminal with graphics -c - call system ('gnuplot 03_gnuxy') - stop - end diff --git a/src/04_plot.f90 b/src/04_plot.f90 new file mode 100644 index 0000000000000000000000000000000000000000..f82ff015ff3dd915e54d384467b40410b111a83a --- /dev/null +++ b/src/04_plot.f90 @@ -0,0 +1,58 @@ +! +! Program to provide plots of Sin(x) +! +program plot + implicit none + + real(8) x, fx + integer i + character label*150 + character xlabel*32,ylabel*32,title*32 + ! + ! label - Character string + ! xlabel - Contains a label for the x-axis + ! ylabel - Contains a label for the y-axis + ! title - Contains a title for the plot + ! + ! Drive a separate true graphics program (gnuplot) + ! + ! First set up the command file for gnuplot + ! + xlabel="'x'" + ylabel="'y'" + title="'sin(x)'" + open (112,file='04_gnuxy.plt') + ! + label='set xlabel '//xlabel + write(112,*)label + write(112,*)'set xrange [0:6]' + label='set ylabel '//ylabel + write(112,*)label + write(112,*)'set yrange [-1.2:1.2]' + label='plot "04_dataxy.data" using 1:2 title '//title + label=trim(label)//' with lines lt rgb "red"' + write(112,*) label + write (112,*) 'pause -1' + close(112) + ! + ! Generate x-y pairs for the graph + ! + open (112,file='04_dataxy.data') + do i=0,60 + x=.1d0*i + fx=dsin(x) + write(112,*) x,fx + end do + close(112) + ! + print *, ' Hit the Return (Enter) key to continue' + ! + ! Tell the system to run the program gnuplot + ! This call works on either IBM RS6000 or Sun, but is not part of + ! the Fortran standard. + ! Comment out the line if you aren't at a terminal with graphics + ! + call system ('gnuplot 04_gnuxy.plt') + stop + +end program diff --git a/src/04_namelist.def b/src/05_namelist.def similarity index 100% rename from src/04_namelist.def rename to src/05_namelist.def diff --git a/src/04_namelist.f90 b/src/05_namelist.f90 similarity index 91% rename from src/04_namelist.f90 rename to src/05_namelist.f90 index 12b384ca72cc8a68519de672dca0ae276f96e48d..d7fe7c41e9bc9872599b4b3d48b4a487a4b215b6 100644 --- a/src/04_namelist.f90 +++ b/src/05_namelist.f90 @@ -10,7 +10,7 @@ PROGRAM test_namelist write(*,*) 'Before:' call print_res(lon_min, lon_max, lat_min, lat_max) - open(161,file='04_namelist.def',status='old',form='formatted') + open(161,file='05_namelist.def',status='old',form='formatted') read(161,NML=namlon) write(*,*) 'Between:' diff --git a/src/05_newton.f90 b/src/05_newton.f90 deleted file mode 100644 index da7528529617df8f43bfa1325b65468520bd4b43..0000000000000000000000000000000000000000 --- a/src/05_newton.f90 +++ /dev/null @@ -1,54 +0,0 @@ -program newton - - implicit none - -! Use a Newton iteration to solve the equation --> x**3+x-10 -! -! x - current approximation to the solution -! f(x) - polynomial function -! df - derivative of f with respect to x -! xo - previous guess for solution -! eps - convergence criterion -! dx - change in solution approximation -! it - number of iterations -! itmax - maximum number of iterations - - integer, parameter :: itmax = 1000 - real(8), parameter :: eps = 1.e-6 - - integer :: it - real(8) :: x,f,df,xo - - it = 0 - f = 1d0 - - write(*,*) 'Try to solve "x**3+x-10=0"' - write(*,*) 'What is your initial guess for the solution?' - read(*,*) x - - do while( dabs(f)>eps .and. it<=itmax ) - it=it+1 - xo=x - call derivate(xo,f,df) - x = xo -f/df - write(*,*) 'it = ',it,', x = ',x,', f(x) = ',f - end do - -end program - -! ****************************************************************************************** - -subroutine derivate(x,f,d) - -! Evaluate the function f(x)=x**3+x-10 -! also return the derivative of the function - - implicit none - - real(8), intent(in) :: x - real(8), intent(out) :: f, d - - d = 3*x**2 + 1d0 - f = x**3 + x - 10d0 - -end subroutine diff --git a/src/06_module.f90 b/src/06_module.f90 index 8e138ad7d4537a4f03566c1429600cc67c7a388d..41b9514bc91e85881b7560107131d63607a406e0 100644 --- a/src/06_module.f90 +++ b/src/06_module.f90 @@ -1,35 +1,53 @@ MODULE arg - implicit none - integer :: a,b,c - real(8) :: x + implicit none + + integer :: a,b,c + real(8) :: x + +CONTAINS + + SUBROUTINE sub + implicit none + + b = a + c + c = c + 1 + END SUBROUTINE sub + END MODULE arg ! * * * * * * * PROGRAM test_arg - USE arg - implicit none + USE arg + implicit none - a = 2 - c = 1 + a = 2 + c = 1 - write(*,*) 'Before the call:' - write(*,'(3(A5,I3))') ' a = ',a,', b = ',b,', c = ',c + write(*,*) 'Before the sub call:' + write(*,'(3(A5,I3))') ' a = ',a,', b = ',b,', c = ',c - call sub + call sub - write(*,*) 'After the call:' - write(*,'(3(A5,I3))') 'a = ',a,', b = ',b,', c = ',c + write(*,*) 'After the sub call:' + write(*,'(3(A5,I3))') 'a = ',a,', b = ',b,', c = ',c -END PROGRAM test_arg -! * * * * * * * + write(*,*) + write(*,*) 'Before the pi call:' + write(*,'(A4,F10.7)') 'x = ',x + + call pi + + write(*,*) 'After the pi call:' + write(*,'(A4,F10.7)') 'x = ',x + +END PROGRAM test_arg -SUBROUTINE sub - USE arg, only : a,b,c ! seuls a b et c sont utiles - implicit none +SUBROUTINE pi + USE arg, ONLY : x + implicit none - b = a + c - c = c + 1 + x = 2d0*dacos(0d0) -END SUBROUTINE sub +END SUBROUTINE pi diff --git a/src/07_newton.f90 b/src/07_newton.f90 new file mode 100644 index 0000000000000000000000000000000000000000..c6e7d0f4dca891d1da2ea5d759ebda1b4fb70dd4 --- /dev/null +++ b/src/07_newton.f90 @@ -0,0 +1,40 @@ +! +! Use a Newton iteration to solve the equation --> x**3+x-10 +! +program newton + implicit none + + ! declare here + ! ... + ! + + ! initialize here + ! ... + ! + + write(*,*) 'Try to solve "x**3+x-10=0"' + write(*,*) 'What is your initial guess for the solution?' + read(*,*) !!!! + + do while( ) + + !!! + !!! + + end do + +end program + +! *************************************************************** ! + +subroutine !!!!!! + +! Evaluate the function f(x)=x**3+x-10 +! also return the derivative of the function + + implicit none + + !!! + !!! + +end subroutine diff --git a/src/05_newton_plot.f90 b/src/07_plot_newton.f90 similarity index 82% rename from src/05_newton_plot.f90 rename to src/07_plot_newton.f90 index 563016e293b8544b03e54cb051e03aa1b6c35003..0bac36dc959cf14782ddc3bfbe2f340c7fc7b27a 100644 --- a/src/05_newton_plot.f90 +++ b/src/07_plot_newton.f90 @@ -1,11 +1,11 @@ -program plot +program plot_newton implicit none - real(4) :: fx, x + real(8) :: fx, x integer :: i - open (112,file='05_gnuxy.gpl') + open (112,file='07_plot_newton.plt') write(112,*) 'set grid' write(112,*) 'set xzeroaxis' @@ -27,24 +27,24 @@ program plot write(112,*) '' write(112,*) 'set nokey' write(112,*) 'set xrange [-4:4]' - write(112,*) 'plot "04_dataxy_1" using 1:2 with lines lt rgb "blue"' + write(112,*) 'plot "07_plot_newton.data" using 1:2 with lines lt rgb "blue"' write(112,*) 'pause -1' close(112) ! Generate x-y pairs for the graph - open (112,file='05_dataxy.dat') + open (112,file='07_plot_newton.data') do i=-40,40 - x = .1*i - fx = x**3+x-10.0 + x = .1d0*i + fx = x**3+x-10d0 write(112,*) x, fx end do close(112) print *, ' Hit the Return (Enter) key to continue' - call system ('gnuplot 05_gnuxy.gpl') + call system ('gnuplot 07_plot_newton.plt') stop end diff --git a/src/07_OceanGrideChange.f90 b/src/09_OceanGrideChange.f90 similarity index 100% rename from src/07_OceanGrideChange.f90 rename to src/09_OceanGrideChange.f90 diff --git a/src/07_input.nc b/src/09_input.nc similarity index 100% rename from src/07_input.nc rename to src/09_input.nc