10 |
--------------------------------------------------------------------------------
/exercises/03-more-on-pointers/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | implicit none
4 |
5 |
6 | ! print pointer lower bound lbound()
7 | ! print pointer upper bound ubound()
8 | ! check size and elements
9 |
10 | end program example1
11 |
--------------------------------------------------------------------------------
/bin/knit_lessons.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Only try running R to translate files if there are some files present.
4 | # The Makefile passes in the names of files.
5 |
6 | if [ $# -eq 2 ] ; then
7 | Rscript -e "source('bin/generate_md_episodes.R')" "$@"
8 | fi
9 |
--------------------------------------------------------------------------------
/exercises/05-interfaces-overloading/my_vector_type.f90:
--------------------------------------------------------------------------------
1 | module my_vector_type
2 |
3 | implicit none
4 | public
5 |
6 | type, public :: my_vector_t
7 | integer :: x, y, z
8 | end type my_vector_t
9 |
10 | contains
11 |
12 | end module my_vector_type
13 |
--------------------------------------------------------------------------------
/exercises/01-arrays/problem2.f90:
--------------------------------------------------------------------------------
1 | program problem2
2 |
3 | implicit none
4 |
5 | ! Initialise t(1:3) to the initial values 10, 20, 40
6 |
7 | real :: t(3) = [ (2.0*(i**2 + 1), i = 1,3) ]
8 |
9 | print *, "Initial values ", t(1:3)
10 |
11 | end program problem2
12 |
--------------------------------------------------------------------------------
/_includes/dc/who.html:
--------------------------------------------------------------------------------
1 |
2 | Who:
3 | The course is aimed at graduate students and other researchers.
4 |
5 | You don't need to have any previous knowledge of the tools
6 | that will be presented at the workshop.
7 |
8 |
2 | Who:
3 | The course is aimed at graduate students and other researchers.
4 |
5 | You don't need to have any previous knowledge of the tools
6 | that will be presented at the workshop.
7 |
8 |
9 |
--------------------------------------------------------------------------------
/_includes/main_title.html:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | Main title for lesson pages.
3 | {% endcomment %}
4 |
5 | {% include base_path.html %}
6 |
7 |
2 | Who:
3 | The course is for people working in library- and information-related roles.
4 |
5 | You don't need to have any previous knowledge of the tools that
6 | will be presented at the workshop.
7 |
8 |
9 |
--------------------------------------------------------------------------------
/_layouts/break.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | ---
4 | {% include episode_navbar.html episode_navbar_title=true %}
5 |
6 | {% include episode_title.html %}
7 | {% include episode_break.html %}
8 | {{content}}
9 |
10 | {% include episode_navbar.html episode_navbar_title=false %}
11 |
--------------------------------------------------------------------------------
/bin/markdown_ast.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # Use Kramdown parser to produce AST for Markdown document.
4 |
5 | require "kramdown"
6 | require "json"
7 |
8 | markdown = STDIN.read()
9 | doc = Kramdown::Document.new(markdown)
10 | tree = doc.to_hash_a_s_t
11 | puts JSON.pretty_generate(tree)
12 |
--------------------------------------------------------------------------------
/exercises/04-derived-types/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | use my_semi_opaque_type
4 | implicit none
5 |
6 | type (my_semi_opaque_t) :: a
7 | type (my_semi_opaque_t) :: b
8 |
9 | b = my_semi_opaque(2, 3)
10 | a = b
11 |
12 | call my_semi_opaque_print("a", a)
13 |
14 | end program example1
15 |
--------------------------------------------------------------------------------
/_includes/episode_keypoints.html:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | Display key points for an episode.
3 | {% endcomment %}
4 |
5 |
Key Points
6 |
7 | {% for keypoint in page.keypoints %}
8 |
{{ keypoint|markdownify }}
9 | {% endfor %}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/exercises/04-derived-types/solutions/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | use my_semi_opaque_type
4 | implicit none
5 |
6 | type (my_semi_opaque_t) :: a
7 | type (my_semi_opaque_t) :: b
8 |
9 | b = my_semi_opaque(2, 3)
10 | a = b
11 |
12 | call my_semi_opaque_print("a", a)
13 |
14 | end program example1
15 |
--------------------------------------------------------------------------------
/exercises/01-arrays/problem3.f90:
--------------------------------------------------------------------------------
1 | program problem1
2 |
3 | implicit none
4 |
5 | ! Use an array constructor to assign elements to values 1.0, 2.0, 3.0
6 |
7 | real, allocatable :: a(:)
8 |
9 | a(:) = [ 1.0, 2.0, 3.0 ]
10 |
11 | print *, "Status ", allocated(a)
12 | print *, "Values ", a(:)
13 |
14 | end program problem1
15 |
--------------------------------------------------------------------------------
/_layouts/episode.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base
3 | ---
4 | {% include episode_navbar.html episode_navbar_title=true %}
5 |
6 | {% include episode_title.html %}
7 | {% include episode_overview.html %}
8 | {{content}}
9 | {% include episode_keypoints.html %}
10 |
11 | {% include episode_navbar.html episode_navbar_title=false %}
12 |
--------------------------------------------------------------------------------
/exercises/01-arrays/bounds-run-time.f90:
--------------------------------------------------------------------------------
1 | program bounds_check1
2 |
3 | ! Run time error
4 | implicit none
5 |
6 | real :: array(3)
7 | integer :: i
8 |
9 | write (*, '(a)', advance = 'no') "Input an array index "
10 | read (*, *) i
11 |
12 | print *, "Selected array element ", array(i)
13 |
14 | end program bounds_check1
15 |
--------------------------------------------------------------------------------
/exercises/14-interoperability-with-c/c_array.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 |
4 | void c_array(int mlen, int nlen, int idata[][mlen]) {
5 |
6 | for (int n = 0; n < nlen; n++) {
7 | for (int m = 0; m < mlen; m++) {
8 | printf("Element [%1d][%1d] %2d %2d\n", n, m, n*mlen + m, idata[n][m]);
9 | }
10 | }
11 | return;
12 | }
13 |
--------------------------------------------------------------------------------
/bin/boilerplate/_episodes/01-introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction"
3 | teaching: 0
4 | exercises: 0
5 | questions:
6 | - "Key question (FIXME)"
7 | objectives:
8 | - "First learning objective. (FIXME)"
9 | keypoints:
10 | - "First key point. Brief Answer to questions. (FIXME)"
11 | ---
12 | FIXME
13 |
14 | {% include links.md %}
15 |
16 |
--------------------------------------------------------------------------------
/exercises/14-interoperability-with-c/c_snprintf.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 |
4 | int c_snprintf_float(char * str, size_t size, const char * format, float x) {
5 |
6 | return snprintf(str, size, format, x);
7 | }
8 |
9 | int c_snprintf_double(char * str, size_t size, const char * format, double x) {
10 |
11 | return snprintf(str, size, format, x);
12 | }
13 |
--------------------------------------------------------------------------------
/exercises/10-modules-again/example_submodule.f90:
--------------------------------------------------------------------------------
1 | submodule (example_module) example_submodule
2 |
3 | implicit none
4 |
5 | contains
6 |
7 | function example_int_t(ival) result(e)
8 |
9 | integer, intent(in) :: ival
10 | type (example_t) :: e
11 |
12 | e%data = ival
13 |
14 | end function example_int_t
15 |
16 | end submodule example_submodule
17 |
--------------------------------------------------------------------------------
/_includes/figure.html:
--------------------------------------------------------------------------------
1 |
2 | {% if include.url != "" %}
3 |
4 | {% endif %}
5 |
7 | {% if include.url != "" %}
8 |
9 | {% endif %}
10 | {{ include.caption }}
11 |
12 |
--------------------------------------------------------------------------------
/_includes/episode_break.html:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | Display a break's timings in a box similar to a learning episode's.
3 | {% endcomment %}
4 |
5 |
Overview
6 |
7 |
8 |
9 | Break: {{ page.break }} min
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/exercises/06-type-extension-polypmorphism/object_type.f90:
--------------------------------------------------------------------------------
1 | module object_type
2 |
3 | implicit none
4 | public
5 |
6 | type, public :: object_t
7 | real :: rho = 1.0 ! density
8 | real :: x(3) = 0.0 ! position of centre of mass
9 | end type object_t
10 |
11 | type, extends(object_t), public :: sphere_t
12 | real :: a = 1.0 ! radius
13 | end type sphere_t
14 |
15 | end module object_type
16 |
--------------------------------------------------------------------------------
/bin/boilerplate/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: lesson
3 | root: . # Is the only page that doesn't follow the pattern /:path/index.html
4 | permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html
5 | ---
6 | FIXME: home page introduction
7 |
8 |
9 |
10 | {% comment %} This is a comment in Liquid {% endcomment %}
11 |
12 | > ## Prerequisites
13 | >
14 | > FIXME
15 | {: .prereq}
16 |
17 | {% include links.md %}
18 |
--------------------------------------------------------------------------------
/exercises/10-modules-again/example_module.f90:
--------------------------------------------------------------------------------
1 | module example_module
2 |
3 | implicit none
4 | public
5 |
6 | type, public :: example_t
7 | private
8 | integer :: data = 0
9 | end type example_t
10 |
11 | interface example_t
12 | module function example_int_t(ival) result(e)
13 | integer, intent(in) :: ival
14 | type (example_t) :: e
15 | end function example_int_t
16 | end interface example_t
17 |
18 | end module example_module
19 |
--------------------------------------------------------------------------------
/exercises/08-generic-io-for-derived-types/date_program.f90:
--------------------------------------------------------------------------------
1 | program date_program
2 |
3 | use date_module
4 | implicit none
5 |
6 | type (my_type) :: date
7 |
8 | date%day = 21
9 | date%month = 4
10 | date%year = 2022
11 |
12 | ! Some valid date examples ...
13 |
14 | print *, "List directed date output: ", date
15 | ! print "(a,dt)", "Default dt format: ", date
16 | ! print "(a,dt(2,4,5))", "vlist dt format: ", date
17 |
18 | end program date_program
19 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: "Contributor Code of Conduct"
4 | ---
5 | As contributors and maintainers of this project,
6 | we pledge to follow the [Carpentry Code of Conduct][coc].
7 |
8 | Instances of abusive, harassing, or otherwise unacceptable behavior
9 | may be reported by following our [reporting guidelines][coc-reporting].
10 |
11 | Participants are required to abide by the [ARCHER2 Training Code of Conduct][archer2-tcoc].
12 |
13 | {% include links.md %}
14 |
--------------------------------------------------------------------------------
/exercises/08-generic-io-for-derived-types/solutions/date_program.f90:
--------------------------------------------------------------------------------
1 | program date_program
2 |
3 | use date_module
4 | implicit none
5 |
6 | type (my_type) :: date
7 |
8 | date%day = 21
9 | date%month = 4
10 | date%year = 2022
11 |
12 | ! Some valid date examples ...
13 |
14 | print *, "List directed date output: ", date
15 | print "(a,dt)", "Default dt format: ", date
16 | print "(a,dt(2,4,5))", "vlist dt format: ", date
17 |
18 | end program date_program
19 |
--------------------------------------------------------------------------------
/exercises/09-abstract-types/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | ! Write a file using the concrete class for formatted output.
4 | ! Compile with: ftn file_module.f90 example1.f90
5 |
6 | use file_module
7 | implicit none
8 |
9 | type (file_formatted_writer_t) :: f
10 | integer :: data(4) = [ 3.0, 5.0, 7.0, 9.0 ]
11 | integer :: ierr
12 |
13 | ! Open a file, say "file_formatted.dat"
14 | ! Write `data` to the file
15 | ! Close the file
16 |
17 | end program example1
18 |
--------------------------------------------------------------------------------
/exercises/09-abstract-types/solutions/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | ! Write a file using the concrete class for formatted output.
4 | ! Compile with: ftn file_module.f90 example1.f90
5 |
6 | use file_module
7 | implicit none
8 |
9 | type (file_formatted_writer_t) :: f
10 | integer :: data(4) = [ 3.0, 5.0, 7.0, 9.0 ]
11 | integer :: ierr
12 |
13 | ierr = f%open("file_formatted.dat")
14 | ierr = f%write(data)
15 | ierr = f%close()
16 |
17 | end program example1
18 |
--------------------------------------------------------------------------------
/exercises/01-arrays/problem1.f90:
--------------------------------------------------------------------------------
1 | program array_sections
2 |
3 | implicit none
4 |
5 | ! Given the following arrays ...
6 |
7 | integer :: a(10) = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
8 | integer :: b(2, 3) = reshape( [1,2,3,4,5,6], shape = [2,3])
9 |
10 | ! Write an array section to print ...
11 |
12 | ! a. elements 1, 2 and 7 of a
13 |
14 | ! b. all elements of a with odd index
15 |
16 | ! c. elements b(1, 1), b(2, 1), b(1, 3) and b(2, 3)
17 |
18 | end program array_sections
19 |
--------------------------------------------------------------------------------
/exercises/02-arrays-as-arguments/example2.f90:
--------------------------------------------------------------------------------
1 | program example2
2 |
3 | implicit none
4 |
5 | real :: a(5) = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]
6 |
7 | call my_array_operation(a(1:5:2))
8 | print "(a,5(1x,f5.2))", "Final values ", a(1:5)
9 |
10 | contains
11 |
12 | subroutine my_array_operation(b)
13 |
14 | real, intent(inout) :: b(:)
15 |
16 | print *, "shape(b): ", shape(b)
17 |
18 | b(:) = 0.0
19 |
20 | end subroutine my_array_operation
21 |
22 | end program example2
23 |
--------------------------------------------------------------------------------
/exercises/04-derived-types/example2.f90:
--------------------------------------------------------------------------------
1 | program example2
2 |
3 | use my_array_type
4 | implicit none
5 |
6 | type (my_array_t), target :: a
7 | type (my_array_t) :: b
8 | type (my_array_pointer_t) :: c
9 |
10 | b = my_array_allocate(3)
11 | a = b
12 |
13 | print *, "State of a ", a%nlen, allocated(a%values)
14 |
15 | c%nlen = a%nlen
16 | c%values => a%values
17 |
18 | print *, "State of c ", c%nlen, associated(c%values), c%values
19 |
20 | end program example2
21 |
--------------------------------------------------------------------------------
/exercises/03-more-on-pointers/solutions/example2.f90:
--------------------------------------------------------------------------------
1 | program example2
2 |
3 | implicit none
4 |
5 | interface
6 | function array_size(a) result(isize)
7 | real, dimension(:), intent(in) :: a
8 | integer :: isize
9 | end function array_size
10 | end interface
11 |
12 | procedure (array_size), pointer :: f => array_size
13 | real :: a(13)
14 |
15 | print *, "size of a is: ", array_size(a)
16 | print *, "size of a is: ", f(a)
17 |
18 | end program example2
19 |
--------------------------------------------------------------------------------
/exercises/03-more-on-pointers/solutions/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | implicit none
4 |
5 | integer, target :: a(10)
6 | integer, pointer :: p(:)
7 | integer :: i
8 |
9 | p => a(2:10:2)
10 | a = [ (i, i = 1, 10) ]
11 |
12 | ! print pointer lower bound lbound()
13 | print *, "Lower bound: ", lbound(p) ! => 1
14 |
15 | ! print pointer upper bound ubound()
16 | print *, "Upper bound: ", ubound(p) ! => 5
17 |
18 | ! check size and elements
19 | print *, "Size: ", size(p) ! => 5
20 | print *, "p(4) = ", p(4) ! => 8
21 |
22 | end program example1
23 |
--------------------------------------------------------------------------------
/exercises/07-type-bound-procedures/object_type.f90:
--------------------------------------------------------------------------------
1 | module object_type
2 |
3 | implicit none
4 | public
5 |
6 | type, public :: object_t
7 | real :: rho = 1.0 ! density
8 | real :: x(3) = 0.0 ! position of centre of mass
9 | end type object_t
10 |
11 | type, extends(object_t), public :: sphere_t
12 | real :: a = 1.0 ! radius
13 | end type sphere_t
14 |
15 | type, extends(sphere_t), public :: charged_sphere_t
16 | real :: q = -1.0 ! charge
17 | end type charged_sphere_t
18 |
19 | contains
20 |
21 | end module object_type
22 |
--------------------------------------------------------------------------------
/exercises/11-unlimited-polymorphic-entities/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | use iso_fortran_env
4 | implicit none
5 |
6 | real (real32), target :: r32 = 32.0
7 | real (real64), target :: r64 = 64.0
8 | real (real32), pointer :: p32 => null()
9 | real (real64), pointer :: p64 => null()
10 |
11 | class (*), pointer :: p => null()
12 |
13 | p32 => r32
14 | p32 => r64
15 | p => r32
16 | p => r64
17 |
18 | p32 = 0.0
19 | p = 0.0
20 |
21 | p32 => p
22 |
23 | print *, "Result ", p32, p64
24 | print *, "Result ", p
25 |
26 | end program example1
27 |
--------------------------------------------------------------------------------
/_includes/workshop_calendar.html:
--------------------------------------------------------------------------------
1 | Add to your Google Calendar.
2 |
--------------------------------------------------------------------------------
/exercises/04-derived-types/solutions/example2.f90:
--------------------------------------------------------------------------------
1 | program example2
2 |
3 | use my_array_type
4 | implicit none
5 |
6 | type (my_array_t), target :: a
7 | type (my_array_t) :: b
8 | type (my_array_pointer_t) :: c
9 |
10 | b = my_array_allocate(3)
11 | a = b
12 |
13 | print *, "State of a ", a%nlen, allocated(a%values)
14 |
15 | c%nlen = a%nlen
16 | c%values => a%values
17 |
18 | print *, "State of c ", c%nlen, associated(c%values), c%values
19 |
20 | call my_array_destroy(a)
21 |
22 | print *, "State of c ", c%nlen, associated(c%values), c%values
23 |
24 | end program example2
25 |
--------------------------------------------------------------------------------
/exercises/10-modules-again/solutions/example2.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | use file_module
4 | implicit none
5 |
6 | class (file_writer_t), pointer :: f => null()
7 | integer :: data(4) = [ 2, 4, 6, 8 ]
8 | integer :: ierr
9 |
10 | f => file_writer_from_string("formatted")
11 |
12 | ierr = f%open("data_formatted.dat")
13 | ierr = f%write(data)
14 | ierr = f%close()
15 |
16 | deallocate(f)
17 |
18 | f => file_writer_from_string("unformatted")
19 |
20 | ierr = f%open("data_unformatted.dat")
21 | ierr = f%write(data)
22 | ierr = f%close()
23 |
24 | deallocate(f)
25 |
26 | end program example1
27 |
--------------------------------------------------------------------------------
/exercises/02-arrays-as-arguments/example1.f90:
--------------------------------------------------------------------------------
1 | program assumed_shape
2 |
3 | implicit none
4 |
5 | ! The program should print out the values 0.0, 1.0, ..., 3.0
6 |
7 | real :: a(0:3)
8 |
9 | call initialise(a)
10 |
11 | print *, "Values are: ", a(:)
12 |
13 | contains
14 |
15 | subroutine initialise(array)
16 |
17 | real, intent(inout) :: array(:)
18 |
19 | ! Initialise the values to the corresponding index
20 |
21 | integer :: i
22 |
23 | do i = lbound(array, dim = 1), ubound(array, dim = 1)
24 | array(i) = 1.0*i
25 | end do
26 |
27 | end subroutine initialise
28 |
29 | end program assumed_shape
30 |
--------------------------------------------------------------------------------
/exercises/04-derived-types/my_semi_opaque_type.f90:
--------------------------------------------------------------------------------
1 | module my_semi_opaque_type
2 |
3 | ! An example dervided type
4 |
5 | implicit none
6 | public
7 |
8 | type, public :: my_semi_opaque_t
9 | private
10 | integer :: idata
11 | integer, public :: ndata
12 | end type my_semi_opaque_t
13 |
14 | contains
15 |
16 | function my_semi_opaque(idata, ndata) result(res)
17 |
18 | integer, intent(in) :: idata
19 | integer, intent(in) :: ndata
20 | type (my_semi_opaque_t) :: res
21 |
22 | res%idata = idata
23 | res%ndata = ndata
24 |
25 | end function my_semi_opaque
26 |
27 | end module my_semi_opaque_type
28 |
--------------------------------------------------------------------------------
/exercises/05-interfaces-overloading/example3.f90:
--------------------------------------------------------------------------------
1 | program example3
2 |
3 | use my_vector_type
4 | implicit none
5 |
6 | type (my_vector_t) :: i = my_vector_t(1, 0, 0)
7 | type (my_vector_t) :: j = my_vector_t(0, 1, 0)
8 | type (my_vector_t) :: k = my_vector_t(0, 0, 1)
9 |
10 | ! scalar products
11 | ! i .dot. i should be 1
12 | ! i .dot. j should be 0
13 |
14 | ! vector products
15 | ! i .x. j should be k
16 | ! j .x. k should be i
17 | ! k .x. j should be -i
18 |
19 | ! scalar triple product
20 | ! i .dot. j .x. k should be 1
21 |
22 | ! vector triple product
23 | ! j .x. (i .x. j) should be (1, 0, 0)
24 |
25 | end program example3
26 |
--------------------------------------------------------------------------------
/exercises/08-generic-io-for-derived-types/date_module.f90:
--------------------------------------------------------------------------------
1 | module date_module
2 |
3 | ! A module which defines a simple date type, and overrides the
4 | ! default formatted write.
5 |
6 | implicit none
7 |
8 | type :: my_type
9 | integer :: day = 0
10 | integer :: month = 0
11 | integer :: year = 0
12 | end type my_type
13 |
14 | ! Define some months, so we can produce formats like "12 Dec 2022"
15 | character (len = 3), dimension(12), parameter :: months = &
16 | [character (len = 3) :: "Jan", "Feb", "Mar", "Apr", "May", "Jun", &
17 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]
18 |
19 | end module date_module
20 |
--------------------------------------------------------------------------------
/exercises/11-unlimited-polymorphic-entities/key_value_program.f90:
--------------------------------------------------------------------------------
1 | program key_value_program
2 |
3 | ! Generate three key value pairs of different types.
4 | ! If the list is implemented they could be added to
5 | ! a list.
6 |
7 | use key_value_module
8 | implicit none
9 |
10 | type (key_value_t) :: kv1 = key_value_t()
11 | type (key_value_t) :: kv2 = key_value_t()
12 | type (key_value_t) :: kv3 = key_value_t()
13 |
14 |
15 | kv1 = key_value_t("kv1", 2)
16 | kv2 = key_value_t("kv2", 3.141)
17 | kv3 = key_value_t("kv3", "foo")
18 |
19 | call key_value_print(kv1)
20 | call key_value_print(kv2)
21 | call key_value_print(kv3)
22 |
23 | end program key_value_program
24 |
--------------------------------------------------------------------------------
/exercises/05-interfaces-overloading/example1.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | ! Exercise (see also my_array_type.f90) to
4 | !
5 | ! 1. replace my_array_allocate(3) to a call with the overloaded
6 | ! my_array_t(3)
7 | !
8 | ! 2. write an additional generic procedure to allow, e.g.,
9 | ! a = my_array_t(nlen, iconstant) which allocates a%values(nlen)
10 | ! and initialises all values to scalar integer iconstant
11 |
12 | use my_array_type
13 | implicit none
14 |
15 | type (my_array_t) :: a
16 |
17 | a = my_array_allocate(3)
18 |
19 | print *, "State of a ", a%nlen, allocated(a%values), a%values(:)
20 |
21 | call my_array_destroy(a)
22 |
23 | end program example1
24 |
--------------------------------------------------------------------------------
/setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: Setup
4 | ---
5 |
6 | Please try to complete the following setup tasks ahead of the lesson.
7 |
8 | ## Create appropriate SAFE accounts
9 |
10 | Course attendees should have received instructions on how to set up an Archer SAFE account.
11 | Details are available in the [ARCHER2 documentation][archer2-quickstart].
12 |
13 | This will allow you to obtain a machine account which will be used for the course.
14 | (If you already have a machine account, it is possible to use that, although you may not have access to the course queue reservation.)
15 |
16 | Any problems encountered will be addressed as the first part of the course.
17 |
18 |
19 | {% include links.md %}
20 |
--------------------------------------------------------------------------------
/_includes/all_keypoints.html:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | Display key points of all episodes for reference.
3 | {% endcomment %}
4 |
5 | {% include base_path.html %}
6 |
7 |
Key Points
8 |
9 | {% for episode in site.episodes %}
10 | {% unless episode.break %}
11 |
26 |
--------------------------------------------------------------------------------
/exercises/09-abstract-types/solutions/example2.f90:
--------------------------------------------------------------------------------
1 | program example1
2 |
3 | ! Write two files via abstract mechanism.
4 | ! Compile: ftn file_module.f90 example2.f90
5 |
6 | use file_module
7 | implicit none
8 |
9 | class (file_writer_t), pointer :: f => null()
10 | integer :: data(4) = [ 2, 4, 6, 8 ]
11 | integer :: ierr
12 |
13 | f => file_writer_from_string("formatted")
14 |
15 | ierr = f%open("data_formatted.dat")
16 | ierr = f%write(data)
17 | ierr = f%close()
18 |
19 | deallocate(f)
20 |
21 | f => file_write_from_string("unformatted")
22 |
23 | ierr = f%open("data_unformatted.dat")
24 | ierr = f%write(data)
25 | ierr = f%close()
26 |
27 | deallocate(f)
28 |
29 | end program example1
30 |
--------------------------------------------------------------------------------
/bin/test_lesson_check.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import unittest
4 |
5 | import lesson_check
6 | import util
7 |
8 |
9 | class TestFileList(unittest.TestCase):
10 | def setUp(self):
11 | self.reporter = util.Reporter() # TODO: refactor reporter class.
12 |
13 | def test_file_list_has_expected_entries(self):
14 | # For first pass, simply assume that all required files are present
15 | all_filenames = [filename.replace('%', '')
16 | for filename in lesson_check.REQUIRED_FILES]
17 |
18 | lesson_check.check_fileset('', self.reporter, all_filenames)
19 | self.assertEqual(len(self.reporter.messages), 0)
20 |
21 |
22 | if __name__ == "__main__":
23 | unittest.main()
24 |
--------------------------------------------------------------------------------
/exercises/05-interfaces-overloading/example2.f90:
--------------------------------------------------------------------------------
1 | module example2
2 |
3 | ! An example of an ambiguous interface. (Compile only required. No link.)
4 | ! How can the situation be resolved?
5 | public
6 |
7 | interface my_print
8 | module procedure my_print_a, my_print_b
9 | end interface my_print
10 |
11 | contains
12 |
13 | subroutine my_print_a(a, i)
14 |
15 | real, intent(in) :: a
16 | integer, intent(in) :: i
17 |
18 | print *, "real32 integer ", a, i
19 |
20 | end subroutine my_print_a
21 |
22 | subroutine my_print_b(i, a)
23 |
24 | integer, intent(in) :: i
25 | real, intent(in) :: a
26 |
27 | print *, "integer real32 ", i, a
28 |
29 | end subroutine my_print_b
30 |
31 | end module example2
32 |
--------------------------------------------------------------------------------
/_includes/javascript.html:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | JavaScript used in lesson and workshop pages.
3 | {% endcomment %}
4 |
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/_includes/dc/intro.html:
--------------------------------------------------------------------------------
1 |
2 | Data Carpentry
3 | aims to help researchers get their work done
4 | in less time and with less pain
5 | by teaching them basic research computing skills.
6 | This hands-on workshop will cover basic concepts and tools,
7 | including program design, version control, data management,
8 | and task automation.
9 | Participants will be encouraged to help one another
10 | and to apply what they have learned to their own research problems.
11 |
19 |
--------------------------------------------------------------------------------
/exercises/14-interoperability-with-c/solutions/c_struct_to_fortran.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | typedef struct array_s {
5 | int nlen;
6 | float * data;
7 | } array_t;
8 |
9 | extern void f_subroutine(const array_t * a);
10 |
11 | int main() {
12 | // Allocate and fill the array
13 | array_t a;
14 | a.nlen = 10;
15 | a.data = (float *)malloc(a.nlen * sizeof(float));
16 | printf("C array of size %2d:\n", a.nlen);
17 | for (int i = 0; i < a.nlen; ++i) {
18 | a.data[i] = 2 * i + 1.0f;
19 | printf("Element [%1d] %2.1f\n", i, a.data[i]);
20 | }
21 |
22 | // Call the Fortran subroutine, passing a by reference.
23 | f_subroutine(&a);
24 |
25 | // Free the allocated memory in a.
26 | free(a.data);
27 | a.data = NULL;
28 |
29 | return 0;
30 | }
--------------------------------------------------------------------------------
/_includes/sc/intro.html:
--------------------------------------------------------------------------------
1 |
2 | Software Carpentry
3 | aims to help researchers get their work done
4 | in less time and with less pain
5 | by teaching them basic research computing skills.
6 | This hands-on workshop will cover basic concepts and tools,
7 | including program design, version control, data management,
8 | and task automation.
9 | Participants will be encouraged to help one another
10 | and to apply what they have learned to their own research problems.
11 |
19 |
--------------------------------------------------------------------------------
/_includes/workshop_footer.html:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | Footer for a standard workshop.
3 | {% endcomment %}
4 |
27 |
--------------------------------------------------------------------------------
/exercises/02-arrays-as-arguments/solutions/exercise1.f90:
--------------------------------------------------------------------------------
1 | program exercise1
2 |
3 | implicit none
4 |
5 | real, allocatable :: a(:)
6 |
7 | a = [ 1.0, 2.0, 3.0, 4.0, 5.0 ]
8 | print *, "Initial values ", a
9 |
10 | call my_array_operation(a)
11 | ! call my_array_operation(a(1:5:2))
12 | ! a = alloc_arr()
13 |
14 | print *, "Final values ", a
15 |
16 | contains
17 |
18 | subroutine my_array_operation(b)
19 |
20 | real, allocatable, intent(out) :: b(:)
21 |
22 | if (.not. allocated(b)) then
23 | print *, "The argument b is unallocated"
24 | return
25 | end if
26 |
27 | print *, "shape(b): ", shape(b)
28 |
29 | b(:) = 0.0
30 |
31 | end subroutine my_array_operation
32 |
33 | function alloc_arr() result(arr)
34 |
35 | integer, allocatable :: arr(:)
36 |
37 | end function alloc_arr
38 |
39 | end program exercise1
40 |
--------------------------------------------------------------------------------
/exercises/06-type-extension-polypmorphism/example2.f90:
--------------------------------------------------------------------------------
1 | program example2
2 |
3 | use object_type
4 | implicit none
5 |
6 | type (object_t), target :: obj = object_t()
7 | type (sphere_t), target :: s = sphere_t()
8 | type (charged_sphere_t), target :: cs
9 |
10 | class (object_t), pointer :: p => null()
11 |
12 | obj = object_t(rho = 1.0, x = [1.0, 2.0, 3.0])
13 | s = sphere_t(object_t = obj, a = 2.5)
14 | cs = charged_sphere_t(sphere_t = s, q = -1.0)
15 |
16 | p => obj
17 |
18 | print *, "object density ", p%rho
19 | print *, "object position ", p%x(:)
20 | print *, "object radius ", p%a
21 |
22 | p => s
23 |
24 | print *, "sphere density ", p%rho
25 | print *, "sphere position ", p%x(:)
26 | print *, "sphere radius ", p%a
27 |
28 | p => cs
29 | print *, "sphere charge ", p%q
30 |
31 | end program example2
32 |
--------------------------------------------------------------------------------
/exercises/05-interfaces-overloading/my_array_type.f90:
--------------------------------------------------------------------------------
1 | module my_array_type
2 |
3 | implicit none
4 | public
5 |
6 | type, public :: my_array_t
7 | integer :: nlen = 0
8 | real, allocatable :: values(:)
9 | end type my_array_t
10 |
11 | contains
12 |
13 | function my_array_allocate(nlen) result(a)
14 |
15 | integer, intent(in) :: nlen
16 | type (my_array_t) :: a
17 | integer :: i
18 |
19 | a%nlen = nlen
20 | a%values = [ (1.0*i, i = 1, nlen) ]
21 |
22 | end function my_array_allocate
23 |
24 | !----------------------------------------------------------------------------
25 |
26 | subroutine my_array_destroy(a)
27 |
28 | type (my_array_t), intent(inout) :: a
29 |
30 | a%nlen = 0
31 | if (allocated(a%values)) deallocate(a%values)
32 |
33 | end subroutine my_array_destroy
34 |
35 | end module my_array_type
36 |
--------------------------------------------------------------------------------
/_includes/lc/intro.html:
--------------------------------------------------------------------------------
1 |
2 | Library Carpentry
3 | is made by people working in library- and information-related roles to help you:
4 |
5 |
6 |
automate repetitive, boring, error-prone tasks
7 |
create, maintain and analyze sustainable and reusable data
8 |
work effectively with IT and systems colleagues
9 |
better understand the use of software in research
10 |
and much more...
11 |
12 |
13 |
14 | Library Carpentry introduces you to the fundamentals of computing
15 | and provides you with a platform for further self-directed learning.
16 | For more information on what we teach and why, please see our paper
17 | "Library Carpentry: software skills training for library professionals".
18 |
19 |
20 |
--------------------------------------------------------------------------------
/exercises/06-type-extension-polypmorphism/example1.f90:
--------------------------------------------------------------------------------
1 | program test1
2 |
3 | use object_type
4 | implicit none
5 |
6 | type (object_t) :: obj
7 | type (sphere_t) :: s
8 | real :: rho = 1.0
9 | real :: x(3) = [ 2.0, 3.0, 4.0 ]
10 | real :: radius = 1.5
11 |
12 | s = sphere_t(rho, x, radius)
13 |
14 | print *, "Sphere density ", s%object_t%rho
15 | print *, "Sphere density ", s%rho
16 | print *, "Sphere radius ", s%a
17 |
18 | s = sphere_t(a = radius, rho = rho , x = x)
19 |
20 | print *, "Sphere density ", s%object_t%rho
21 | print *, "Sphere density ", s%rho
22 | print *, "Sphere radius ", s%a
23 |
24 | obj = object_t(2.5, [1.0, 1.0, 1.0])
25 | s = sphere_t(obj, radius)
26 |
27 | print *, "Sphere density ", s%rho
28 | print *, "Sphere position: ", s%x
29 | print *, "Sphere radius ", s%a
30 |
31 | end program test1
32 |
--------------------------------------------------------------------------------
/exercises/06-type-extension-polypmorphism/solutions/example1.f90:
--------------------------------------------------------------------------------
1 | program test1
2 |
3 | use object_type
4 | implicit none
5 |
6 | type (object_t) :: obj
7 | type (sphere_t) :: s
8 | real :: rho = 1.0
9 | real :: x(3) = [ 2.0, 3.0, 4.0 ]
10 | real :: radius = 1.5
11 |
12 | s = sphere_t(rho, x, radius)
13 |
14 | print *, "Sphere density ", s%object_t%rho
15 | print *, "Sphere density ", s%rho
16 | print *, "Sphere radius ", s%a
17 |
18 | s = sphere_t(a = radius, rho = rho , x = x)
19 |
20 | print *, "Sphere density ", s%object_t%rho
21 | print *, "Sphere density ", s%rho
22 | print *, "Sphere radius ", s%a
23 |
24 | obj = object_t(2.5, [1.0, 1.0, 1.0])
25 | s = sphere_t(obj, radius)
26 |
27 | print *, "Sphere density ", s%rho
28 | print *, "Sphere position: ", s%x
29 | print *, "Sphere radius ", s%a
30 |
31 | end program test1
32 |
--------------------------------------------------------------------------------
/_includes/life_cycle.html:
--------------------------------------------------------------------------------
1 |
2 | {% if site.life_cycle == "pre-alpha" %}
3 |
4 |
5 |
6 | This lesson is still being designed and assembled (Pre-Alpha version)
7 |
25 | {% for episode in site.episodes %}
26 | {% if episode.start %} {% comment %} Starting a new day? {% endcomment %}
27 | {% assign day = day | plus: 1 %}
28 | {% if day > 1 %} {% comment %} If about to start day 2 or later, show finishing time for previous day {% endcomment %}
29 | {% assign hours = current | divided_by: 60 %}
30 | {% assign minutes = current | modulo: 60 %}
31 |
32 | {% if multiday %}
{% endif %}
33 |
{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }}
34 |
Finish
35 |
36 |
37 | {% endif %}
38 | {% assign current = site.start_time %} {% comment %}Re-set start time of this episode to general daily start time {% endcomment %}
39 | {% endif %}
40 | {% assign hours = current | divided_by: 60 %}
41 | {% assign minutes = current | modulo: 60 %}
42 |
43 | {% if multiday %}
{% if episode.start %}Day {{ day }}{% endif %}
{% endif %}
44 |
{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }}
The Carpentries comprises
13 | Software Carpentry, Data Carpentry, and Library Carpentry communities of Instructors, Trainers,
14 | Maintainers, helpers, and supporters who share a mission to teach
15 | foundational coding and data science skills to researchers and people
16 | working in library- and information-related roles. In January,
17 | 2018, The Carpentries was formed by the merger of Software Carpentry and
18 | Data Carpentry. Library Carpentry became an official Carpentries Lesson Program in November 2018.
19 |
20 |
While individual lessons and workshops continue to be run under each
21 | lesson project, The Carpentries provide overall staffing and governance, as
22 | well as support for assessment, instructor training and mentoring.
23 | Memberships are joint, and the Carpentries project maintains a shared Code
24 | of Conduct. The Carpentries is a fiscally sponsored project of Community
25 | Initiatives, a registered 501(c)3 non-profit based in California, USA.
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Since 1998, Software Carpentry has
34 | been teaching researchers across all disciplines the foundational coding
35 | skills they need to get more done in less time and with less pain. Its
36 | volunteer instructors have run hundreds of events for thousands of learners
37 | around the world. Now that all research involves some degree of
38 | computational work, whether with big data, cloud computing, or simple task
39 | automation, these skills are needed more than ever.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
Data Carpentry develops and teaches
49 | workshops on the fundamental data skills needed to conduct research. Its
50 | target audience is researchers who have little to no prior computational
51 | experience, and its lessons are domain specific, building on learners'
52 | existing knowledge to enable them to quickly apply skills learned to their
53 | own research. Data Carpentry workshops take researchers through the entire
54 | data life cycle.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
Library Carpentry develops lessons and
64 | teaches workshops for and with people working in library- and
65 | information-related roles. Its goal is to create an on-ramp to empower this
66 | community to use software and data in their own work, as well as be
67 | advocates for and train others in efficient, effective and reproducible data
68 | and software practices.
69 |
70 |
71 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | #------------------------------------------------------------
2 | # Values for this lesson.
3 | #------------------------------------------------------------
4 |
5 | # Which carpentry is this ("swc", "dc", "lc", or "cp")?
6 | # swc: Software Carpentry
7 | # dc: Data Carpentry
8 | # lc: Library Carpentry
9 | # cp: Carpentries (to use for instructor training for instance)
10 | carpentry: "swc"
11 |
12 | # Overall title for pages.
13 | title: "Intermediate Modern Fortran"
14 |
15 | # Life cycle stage of the lesson
16 | # possible values: "pre-alpha", "alpha", "beta", "stable"
17 | life_cycle: "stable"
18 |
19 | #------------------------------------------------------------
20 | # Generic settings (should not need to change).
21 | #------------------------------------------------------------
22 |
23 | # What kind of thing is this ("workshop" or "lesson")?
24 | kind: "lesson"
25 |
26 | # Magic to make URLs resolve both locally and on GitHub.
27 | # See https://help.github.com/articles/repository-metadata-on-github-pages/.
28 | # Please don't change it: / is correct.
29 | repository: /
30 |
31 | # Email address, no mailto:
32 | email: "support@archer2.ac.uk"
33 |
34 | # Sites.
35 | amy_site: "https://amy.software-carpentry.org/workshops"
36 | carpentries_github: "https://github.com/carpentries"
37 | carpentries_pages: "https://carpentries.github.io"
38 | carpentries_site: "https://carpentries.org/"
39 | dc_site: "http://datacarpentry.org"
40 | example_repo: "https://github.com/carpentries/lesson-example"
41 | example_site: "https://carpentries.github.io/lesson-example"
42 | lc_site: "https://librarycarpentry.org/"
43 | swc_github: "https://github.com/swcarpentry"
44 | swc_pages: "https://swcarpentry.github.io"
45 | swc_site: "https://software-carpentry.org"
46 | template_repo: "https://github.com/carpentries/styles"
47 | training_site: "https://carpentries.github.io/instructor-training"
48 | workshop_repo: "https://github.com/carpentries/workshop-template"
49 | workshop_site: "https://carpentries.github.io/workshop-template"
50 | cc_by_human: "https://creativecommons.org/licenses/by/4.0/"
51 |
52 | # Surveys.
53 | swc_pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id="
54 | swc_post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id="
55 | training_post_survey: "https://www.surveymonkey.com/r/post-instructor-training"
56 | dc_pre_survey: "https://www.surveymonkey.com/r/dcpreworkshopassessment?workshop_id="
57 | dc_post_survey: "https://www.surveymonkey.com/r/dcpostworkshopassessment?workshop_id="
58 | lc_pre_survey: "https://www.surveymonkey.com/r/lcpreworkshopsurvey?workshop_id="
59 | lc_post_survey: "https://www.surveymonkey.com/r/lcpostworkshopsurvey?workshop_id="
60 | instructor_pre_survey: "https://www.surveymonkey.com/r/instructor_training_pre_survey?workshop_id="
61 | instructor_post_survey: "https://www.surveymonkey.com/r/instructor_training_post_survey?workshop_id="
62 |
63 |
64 | # Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am).
65 | start_time: 600
66 |
67 | # Specify that things in the episodes collection should be output.
68 | collections:
69 | episodes:
70 | output: true
71 | permalink: /:path/index.html
72 | extras:
73 | output: true
74 | permalink: /:path/index.html
75 |
76 | # Set the default layout for things in the episodes collection.
77 | defaults:
78 | - values:
79 | root: .
80 | layout: page
81 | - scope:
82 | path: ""
83 | type: episodes
84 | values:
85 | root: ..
86 | layout: episode
87 | - scope:
88 | path: ""
89 | type: extras
90 | values:
91 | root: ..
92 | layout: page
93 |
94 | # Files and directories that are not to be copied.
95 | exclude:
96 | - Makefile
97 | - bin/
98 | - .Rproj.user/
99 |
100 | # Turn on built-in syntax highlighting.
101 | highlighter: rouge
102 |
--------------------------------------------------------------------------------
/bin/boilerplate/_config.yml:
--------------------------------------------------------------------------------
1 | #------------------------------------------------------------
2 | # Values for this lesson.
3 | #------------------------------------------------------------
4 |
5 | # Which carpentry is this ("swc", "dc", "lc", or "cp")?
6 | # swc: Software Carpentry
7 | # dc: Data Carpentry
8 | # lc: Library Carpentry
9 | # cp: Carpentries (to use for instructor traning for instance)
10 | carpentry: "swc"
11 |
12 | # Overall title for pages.
13 | title: "Lesson Title"
14 |
15 | # Life cycle stage of the lesson
16 | # possible values: "pre-alpha", "alpha", "beta", "stable"
17 | life_cycle: "pre-alpha"
18 |
19 | #------------------------------------------------------------
20 | # Generic settings (should not need to change).
21 | #------------------------------------------------------------
22 |
23 | # What kind of thing is this ("workshop" or "lesson")?
24 | kind: "lesson"
25 |
26 | # Magic to make URLs resolve both locally and on GitHub.
27 | # See https://help.github.com/articles/repository-metadata-on-github-pages/.
28 | # Please don't change it: / is correct.
29 | repository: /
30 |
31 | # Email address, no mailto:
32 | email: "team@carpentries.org"
33 |
34 | # Sites.
35 | amy_site: "https://amy.software-carpentry.org/workshops"
36 | carpentries_github: "https://github.com/carpentries"
37 | carpentries_pages: "https://carpentries.github.io"
38 | carpentries_site: "https://carpentries.org/"
39 | dc_site: "http://datacarpentry.org"
40 | example_repo: "https://github.com/carpentries/lesson-example"
41 | example_site: "https://carpentries.github.io/lesson-example"
42 | lc_site: "https://librarycarpentry.org/"
43 | swc_github: "https://github.com/swcarpentry"
44 | swc_pages: "https://swcarpentry.github.io"
45 | swc_site: "https://software-carpentry.org"
46 | template_repo: "https://github.com/carpentries/styles"
47 | training_site: "https://carpentries.github.io/instructor-training"
48 | workshop_repo: "https://github.com/carpentries/workshop-template"
49 | workshop_site: "https://carpentries.github.io/workshop-template"
50 | cc_by_human: "https://creativecommons.org/licenses/by/4.0/"
51 |
52 | # Surveys.
53 | swc_pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id="
54 | swc_post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id="
55 | training_post_survey: "https://www.surveymonkey.com/r/post-instructor-training"
56 | dc_pre_survey: "https://www.surveymonkey.com/r/dcpreworkshopassessment?workshop_id="
57 | dc_post_survey: "https://www.surveymonkey.com/r/dcpostworkshopassessment?workshop_id="
58 | lc_pre_survey: "https://www.surveymonkey.com/r/lcpreworkshopsurvey?workshop_id="
59 | lc_post_survey: "https://www.surveymonkey.com/r/lcpostworkshopsurvey?workshop_id="
60 | instructor_pre_survey: "https://www.surveymonkey.com/r/instructor_training_pre_survey?workshop_id="
61 | instructor_post_survey: "https://www.surveymonkey.com/r/instructor_training_post_survey?workshop_id="
62 |
63 |
64 | # Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am).
65 | start_time: 0
66 |
67 | # Specify that things in the episodes collection should be output.
68 | collections:
69 | episodes:
70 | output: true
71 | permalink: /:path/index.html
72 | extras:
73 | output: true
74 | permalink: /:path/index.html
75 |
76 | # Set the default layout for things in the episodes collection.
77 | defaults:
78 | - values:
79 | root: .
80 | layout: page
81 | - scope:
82 | path: ""
83 | type: episodes
84 | values:
85 | root: ..
86 | layout: episode
87 | - scope:
88 | path: ""
89 | type: extras
90 | values:
91 | root: ..
92 | layout: page
93 |
94 | # Files and directories that are not to be copied.
95 | exclude:
96 | - Makefile
97 | - bin/
98 | - .Rproj.user/
99 |
100 | # Turn on built-in syntax highlighting.
101 | highlighter: rouge
102 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | ## ========================================
2 | ## Commands for both workshop and lesson websites.
3 |
4 | # Settings
5 | MAKEFILES=Makefile $(wildcard *.mk)
6 | JEKYLL=jekyll
7 | JEKYLL_VERSION=3.7.3
8 | PARSER=bin/markdown_ast.rb
9 | DST=_site
10 |
11 | # Controls
12 | .PHONY : commands clean files
13 | .NOTPARALLEL:
14 | all : commands
15 |
16 | ## commands : show all commands.
17 | commands :
18 | @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g'
19 |
20 | ## docker-serve : use docker to build the site
21 | docker-serve :
22 | docker run --rm -it -v ${PWD}:/srv/jekyll -p 127.0.0.1:4000:4000 jekyll/jekyll:${JEKYLL_VERSION} make serve
23 |
24 | ## serve : run a local server.
25 | serve : lesson-md
26 | ${JEKYLL} serve
27 |
28 | ## site : build files but do not run a server.
29 | site : lesson-md
30 | ${JEKYLL} build
31 |
32 | # repo-check : check repository settings.
33 | repo-check :
34 | @bin/repo_check.py -s .
35 |
36 | ## clean : clean up junk files.
37 | clean :
38 | @rm -rf ${DST}
39 | @rm -rf .sass-cache
40 | @rm -rf bin/__pycache__
41 | @find . -name .DS_Store -exec rm {} \;
42 | @find . -name '*~' -exec rm {} \;
43 | @find . -name '*.pyc' -exec rm {} \;
44 |
45 | ## clean-rmd : clean intermediate R files (that need to be committed to the repo).
46 | clean-rmd :
47 | @rm -rf ${RMD_DST}
48 | @rm -rf fig/rmd-*
49 |
50 | ## ----------------------------------------
51 | ## Commands specific to workshop websites.
52 |
53 | .PHONY : workshop-check
54 |
55 | ## workshop-check : check workshop homepage.
56 | workshop-check :
57 | @bin/workshop_check.py .
58 |
59 | ## ----------------------------------------
60 | ## Commands specific to lesson websites.
61 |
62 | .PHONY : lesson-check lesson-md lesson-files lesson-fixme
63 |
64 | # RMarkdown files
65 | RMD_SRC = $(wildcard _episodes_rmd/??-*.Rmd)
66 | RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC))
67 |
68 | # Lesson source files in the order they appear in the navigation menu.
69 | MARKDOWN_SRC = \
70 | index.md \
71 | CODE_OF_CONDUCT.md \
72 | setup.md \
73 | $(sort $(wildcard _episodes/*.md)) \
74 | reference.md \
75 | $(sort $(wildcard _extras/*.md)) \
76 | LICENSE.md
77 |
78 | # Generated lesson files in the order they appear in the navigation menu.
79 | HTML_DST = \
80 | ${DST}/index.html \
81 | ${DST}/conduct/index.html \
82 | ${DST}/setup/index.html \
83 | $(patsubst _episodes/%.md,${DST}/%/index.html,$(sort $(wildcard _episodes/*.md))) \
84 | ${DST}/reference/index.html \
85 | $(patsubst _extras/%.md,${DST}/%/index.html,$(sort $(wildcard _extras/*.md))) \
86 | ${DST}/license/index.html
87 |
88 | ## lesson-md : convert Rmarkdown files to markdown
89 | lesson-md : ${RMD_DST}
90 |
91 | _episodes/%.md: _episodes_rmd/%.Rmd
92 | @bin/knit_lessons.sh $< $@
93 |
94 | ## lesson-check : validate lesson Markdown.
95 | lesson-check : lesson-fixme
96 | @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md
97 |
98 | ## lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace.
99 | lesson-check-all :
100 | @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive
101 |
102 | ## unittest : run unit tests on checking tools.
103 | unittest :
104 | @bin/test_lesson_check.py
105 |
106 | ## lesson-files : show expected names of generated files for debugging.
107 | lesson-files :
108 | @echo 'RMD_SRC:' ${RMD_SRC}
109 | @echo 'RMD_DST:' ${RMD_DST}
110 | @echo 'MARKDOWN_SRC:' ${MARKDOWN_SRC}
111 | @echo 'HTML_DST:' ${HTML_DST}
112 |
113 | ## lesson-fixme : show FIXME markers embedded in source files.
114 | lesson-fixme :
115 | @fgrep -i -n FIXME ${MARKDOWN_SRC} || true
116 |
117 | #-------------------------------------------------------------------------------
118 | # Include extra commands if available.
119 | #-------------------------------------------------------------------------------
120 |
121 | -include commands.mk
122 |
--------------------------------------------------------------------------------
/_episodes/12-type-parameters.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Type parameters"
3 | teaching: 15
4 | exercises: 15
5 | questions:
6 | - "How to implement user-defined types with `kind`s, like intrinsic types?"
7 | objectives:
8 | - "Understand the use of type parameters in user-defined types."
9 | keypoints:
10 | - "The `kind` of a user-defined type must be known at compile time (as for intrinsic types)"
11 | ---
12 |
13 | ## Type parameters for intrinsic types
14 |
15 | We have seen type parameters (kind type parameters) for intrinsic types:
16 | ```
17 | use iso_fortran_env
18 | ...
19 | integer (int32) :: i32
20 | ```
21 | This provides a way to control, parametrically, the actual data type
22 | associated with the variable. Such parameters must be known at compile
23 | time.
24 |
25 | There are all so-called deferred parameters, such as the length of a
26 | deferred length string
27 | ```
28 | character (len = :), allocatable :: string
29 | ```
30 | The colon indicates the length is deferred.
31 |
32 |
33 | ## Parameterised derived types
34 |
35 | These features may be combined in a parameterised type definition, e.g.:
36 | ```
37 | type, public :: my_array_t(kr, nlen)
38 | integer, kind :: kr ! kind parameter
39 | integer, len :: nlen ! len parameter
40 | real (kr) :: data(nlen)
41 | end type my_array_t
42 | ```
43 | The type parameters must be integers and take one of two roles: a `kind`
44 | parameter, which is used in the place of kind type parameters, and a
45 | `len` parameter, which can be used in array bound declaration or a length
46 | specificaition. A `kind` parameter must be a compile-time constant, but a
47 | length parameter may be deferred until run time.
48 |
49 | The extra components act as normal components in that they may have a
50 | default value specified in the declaration, and may be accessed at run
51 | time via the component selector `%` in the usual way.
52 |
53 | For example declaration of a variable of such a type might look like:
54 | ```
55 | ! ... establish len_input ...
56 |
57 | type (my_array_t(real32, len_input)) :: a
58 | ```
59 |
60 | Such a parameterised type may have a dummy argument associated with an
61 | actual argument via a dummy argument declaration, e.g.,
62 | ```
63 | type (my_array_t(real32, nlen = *)), intent(in) :: a
64 | ```
65 | cf.
66 | ```
67 | character (len = *), intent(in) :: str
68 | ```
69 | A pointer declaration of this type would use the deferred notation
70 | with the colon:
71 | ```
72 | type (my_array_t(real32, nlen = :)), pointer p => null()
73 | ```
74 | Here, an (optional) keyword has been used in the parameter list.
75 |
76 | > ## Example
77 | >
78 | > The example code `example1` illustrates how a parameterised type can be defined and used
79 | > ```
80 | > program exmaple1
81 | >
82 | > use iso_fortran_env
83 | > implicit none
84 | >
85 | > type :: my_array_t(kr, nlen)
86 | > integer, kind :: kr
87 | > integer, len :: nlen
88 | > real (kr) :: data(nlen)
89 | > end type my_array_t
90 | >
91 | > integer :: kr
92 | > integer :: nlen
93 | > type (my_array_t(kr = real64, nlen = 1000)) :: a
94 | >
95 | > print *, "kind a", a%kr
96 | > print *, "nlen a", a%nlen
97 | >
98 | > write (*, "(a)", advance = "no") "nlen: "
99 | > read (*, *) nlen
100 | >
101 | > call defer_me(nlen)
102 | >
103 | > contains
104 | >
105 | > subroutine defer_me(nlen)
106 | >
107 | > integer, intent(in) :: nlen
108 | > type (my_array_t(kr = real32, nlen=nlen)) :: b
109 | >
110 | > print *, "Length ", b%nlen
111 | > print *, "Shape ", shape(b%data)
112 | >
113 | > end subroutine defer_me
114 | >
115 | > end program exmaple1
116 | > ```
117 | > The `kind` of the data held by `my_array_t%data` must be known at compile time, but the `len` of
118 | > the array can be set dynamically as shown by `defer_me()`.
119 | > You can convince yourself of this by compiling and running `example1.f90` which will allow you to
120 | > pass the array length at runtime.
121 | {: .challenge}
122 |
123 | {% include links.md %}
124 |
--------------------------------------------------------------------------------
/_includes/links.md:
--------------------------------------------------------------------------------
1 | {% include base_path.html %}
2 | [archer2-connecting]: https://docs.archer2.ac.uk/user-guide/connecting/
3 | [archer2-data]: https://docs.archer2.ac.uk/user-guide/data/
4 | [archer2-docs]: https://docs.archer2.ac.uk/
5 | [archer2-password]: https://www.archer2.ac.uk/about/policies/passwords_usernames.html
6 | [archer2-quickstart]: https://docs.archer2.ac.uk/quick-start/quickstart-users/
7 | [archer2-tcoc]: https://www.archer2.ac.uk/about/policies/code-of-conduct.html
8 | [archer2-training]: https://www.archer2.ac.uk/training/
9 | [archer2-training-materials]: https://www.archer2.ac.uk/training/materials/
10 | [archer2-website]: https://www.archer2.ac.uk/
11 | [c-site]: https://carpentries.org/
12 | [cc-by-human]: https://creativecommons.org/licenses/by/4.0/
13 | [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode
14 | [ci]: http://communityin.org/
15 | [coc-reporting]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html#incident-reporting-guidelines
16 | [coc]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html
17 | [concept-maps]: https://carpentries.github.io/instructor-training/05-memory/
18 | [contrib-covenant]: https://contributor-covenant.org/
19 | [contributing]: {{ repo_url }}/blob/{{ source_branch }}/CONTRIBUTING.md
20 | [cran-checkpoint]: https://cran.r-project.org/package=checkpoint
21 | [cran-knitr]: https://cran.r-project.org/package=knitr
22 | [cran-stringr]: https://cran.r-project.org/package=stringr
23 | [dc-issues]: https://github.com/issues?q=user%3Adatacarpentry
24 | [dc-lessons]: http://www.datacarpentry.org/lessons/
25 | [dc-site]: http://datacarpentry.org/
26 | [discuss-list]: http://lists.software-carpentry.org/listinfo/discuss
27 | [email]: mailto:team@carpentries.org
28 | [github-flow]: https://guides.github.com/introduction/flow/
29 | [github-importer]: https://import.github.com/
30 | [github-join]: https://github.com/join
31 | [github]: https://github.com
32 | [how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
33 | [importer]: https://github.com/new/import
34 | [issues]: https://guides.github.com/features/issues/
35 | [jekyll-collection]: https://jekyllrb.com/docs/collections/
36 | [jekyll-install]: https://jekyllrb.com/docs/installation/
37 | [jekyll-windows]: http://jekyll-windows.juthilo.com/
38 | [jekyll]: https://jekyllrb.com/
39 | [jupyter]: https://jupyter.org/
40 | [kramdown]: https://kramdown.gettalong.org/
41 | [lammps-docs]: https://lammps.sandia.gov/doc/Manual.html
42 | [lammps-download]: https://lammps.sandia.gov/download.html
43 | [lc-issues]: https://github.com/issues?q=user%3Alibrarycarpentry
44 | [lc-lessons]: https://librarycarpentry.org/lessons/
45 | [lc-site]: https://librarycarpentry.org/
46 | [lesson-aio]: {{ relative_root_path }}{% link aio.md %}
47 | [lesson-coc]: {{ relative_root_path }}{% link CODE_OF_CONDUCT.md %}
48 | [lesson-example]: https://carpentries.github.io/lesson-example/
49 | [lesson-license]: {{ relative_root_path }}{% link LICENSE.md %}
50 | [lesson-mainpage]: {{ relative_root_path }}{% link index.md %}
51 | [lesson-reference]: {{ relative_root_path }}{% link reference.md %}
52 | [lesson-setup]: {{ relative_page_root }}{% link setup.md %}
53 | [mit-license]: https://opensource.org/licenses/mit-license.html
54 | [morea]: https://morea-framework.github.io/
55 | [numfocus]: https://numfocus.org/
56 | [osi]: https://opensource.org
57 | [pandoc]: https://pandoc.org/
58 | [paper-now]: https://github.com/PeerJ/paper-now
59 | [python-gapminder]: https://swcarpentry.github.io/python-novice-gapminder/
60 | [pyyaml]: https://pypi.python.org/pypi/PyYAML
61 | [r-markdown]: https://rmarkdown.rstudio.com/
62 | [rstudio]: https://www.rstudio.com/
63 | [ruby-install-guide]: https://www.ruby-lang.org/en/downloads/
64 | [ruby-installer]: https://rubyinstaller.org/
65 | [rubygems]: https://rubygems.org/pages/download/
66 | [safe-machine-mfa]: https://epcced.github.io/safe-docs/safe-for-users/#how-to-turn-on-mfa-on-your-machine-account
67 | [styles]: https://github.com/carpentries/styles/
68 | [swc-issues]: https://github.com/issues?q=user%3Aswcarpentry
69 | [swc-lessons]: https://software-carpentry.org/lessons/
70 | [swc-releases]: https://github.com/swcarpentry/swc-releases
71 | [swc-site]: https://software-carpentry.org/
72 | [training]: https://carpentries.github.io/instructor-training/
73 | [workshop-repo]: {{ site.workshop_repo }}
74 | [yaml]: http://yaml.org/
75 |
--------------------------------------------------------------------------------
/assets/css/syntax.css:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffffcc }
2 | .highlight { background: #f8f8f8; }
3 | .highlight .c { color: #408080; font-style: italic } /* Comment */
4 | .highlight .err { border: 1px solid #FF0000 } /* Error */
5 | .highlight .k { color: #008000; font-weight: bold } /* Keyword */
6 | .highlight .o { color: #666666 } /* Operator */
7 | .highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
8 | .highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
9 | .highlight .cp { color: #BC7A00 } /* Comment.Preproc */
10 | .highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
11 | .highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
12 | .highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
14 | .highlight .ge { font-style: italic } /* Generic.Emph */
15 | .highlight .gr { color: #FF0000 } /* Generic.Error */
16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
18 | .highlight .go { color: #888888 } /* Generic.Output */
19 | .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
20 | .highlight .gs { font-weight: bold } /* Generic.Strong */
21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
23 | .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
24 | .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
25 | .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
26 | .highlight .kp { color: #008000 } /* Keyword.Pseudo */
27 | .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
28 | .highlight .kt { color: #B00040 } /* Keyword.Type */
29 | .highlight .m { color: #666666 } /* Literal.Number */
30 | .highlight .s { color: #BA2121 } /* Literal.String */
31 | .highlight .na { color: #7D9029 } /* Name.Attribute */
32 | .highlight .nb { color: #008000 } /* Name.Builtin */
33 | .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
34 | .highlight .no { color: #880000 } /* Name.Constant */
35 | .highlight .nd { color: #AA22FF } /* Name.Decorator */
36 | .highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
37 | .highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
38 | .highlight .nf { color: #0000FF } /* Name.Function */
39 | .highlight .nl { color: #A0A000 } /* Name.Label */
40 | .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
41 | .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
42 | .highlight .nv { color: #19177C } /* Name.Variable */
43 | .highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
45 | .highlight .mb { color: #666666 } /* Literal.Number.Bin */
46 | .highlight .mf { color: #666666 } /* Literal.Number.Float */
47 | .highlight .mh { color: #666666 } /* Literal.Number.Hex */
48 | .highlight .mi { color: #666666 } /* Literal.Number.Integer */
49 | .highlight .mo { color: #666666 } /* Literal.Number.Oct */
50 | .highlight .sa { color: #BA2121 } /* Literal.String.Affix */
51 | .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
52 | .highlight .sc { color: #BA2121 } /* Literal.String.Char */
53 | .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
54 | .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
55 | .highlight .s2 { color: #BA2121 } /* Literal.String.Double */
56 | .highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
57 | .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
58 | .highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
59 | .highlight .sx { color: #008000 } /* Literal.String.Other */
60 | .highlight .sr { color: #BB6688 } /* Literal.String.Regex */
61 | .highlight .s1 { color: #BA2121 } /* Literal.String.Single */
62 | .highlight .ss { color: #19177C } /* Literal.String.Symbol */
63 | .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
64 | .highlight .fm { color: #0000FF } /* Name.Function.Magic */
65 | .highlight .vc { color: #19177C } /* Name.Variable.Class */
66 | .highlight .vg { color: #19177C } /* Name.Variable.Global */
67 | .highlight .vi { color: #19177C } /* Name.Variable.Instance */
68 | .highlight .vm { color: #19177C } /* Name.Variable.Magic */
69 | .highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
70 |
--------------------------------------------------------------------------------
/_episodes/13-intrinsic-modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Intrinsic modules"
3 | teaching: 15
4 | exercises: 5
5 | questions:
6 | - "What intrinsic modules does Fortran provide?"
7 | - "How can intrinsic modules aid writing portable code?"
8 | objectives:
9 | - "Be aware of the intrinsic modules in Fortran and their uses"
10 | keypoints:
11 | - "The `iso_fortran_env` intrinsic module provides constants and functions that enable code portability"
12 | - "The IEEE intrinsic modules allow programs to check the conformance with IEEE features"
13 | ---
14 |
15 | ## Intrisic and non-intrinsic modules
16 |
17 | Five intrinsic modules are provided by the implementation: we
18 | have seen `iso_fortran_env`.
19 |
20 | Three are related to IEEE arithmetic: `ieee_arithmetic`, `ieee_exceptions`
21 | and `ieee_features`.
22 | The last is `iso_c_binding` which concerns C/Fortran interoperability.
23 |
24 | A use statement may include, optionally, an `intrinsic` or `non_intrinsic`
25 | attribute, e.g.,
26 | ```
27 | use, intrinsic :: iso_fortran_env
28 | ```
29 | This true intrinsic `iso_fortran_env` will then be used in preference to
30 | any other module with the same name.
31 |
32 | Likewise a non-intrinsic module can be used:
33 | ```
34 | use, non_intrinsic :: iso_fortran_env
35 | ```
36 | This would generate an error if a user-provided `iso_fortran_env` were
37 | unavailable to the compiler.
38 |
39 | Best practice is to always use an `only` clause with intrinsic modules,
40 | which enumerates the names required in the current scope. This is a
41 | general rule which limits "namespace pollution", and can be applied to
42 | your own modules too.
43 |
44 |
45 | ## Intrinsic module `iso_fortran_env`
46 |
47 | This module provides a number of symbolic constants and functions to
48 | provide information about the local Fortran implementation.
49 |
50 | These include:
51 | 1. `error_unit`, `input_unit` and `output_unit`: the unit numbers
52 | associated with standard error, standard input, and standard output.
53 | 2. `iostat_end` and `iostat_eor`: error codes for end-fo-file and
54 | end-of-record.
55 | 3. `character_storage_size`, `file_storage_size`, and `numeric_storage_size`
56 | related to i/o
57 |
58 |
59 | F2008 included kind type parameters for frequently used intrinsic data
60 | types:
61 | 1. `int8`, `int16`, `int32`, `int64`: integer kind type parameter for
62 | intrinsic integers (in bits);
63 | 2. `real32`, `real64`, `real128`: integer kind type parameters for
64 | intrinsic real data types.
65 |
66 | Lists of the kind types available for each intrinsic data type are also
67 | available: `integer_kinds`, `logical_kinds`, `real_kinds`, `character_kinds`.
68 |
69 |
70 | ### Functions
71 |
72 | Information on the compiler and the options at compile time can be accessed
73 | via the functions: `compiler_version()` and `compiler_options()`. Both
74 | return a string fixed at compile time.
75 |
76 | E.g.,
77 | ```
78 | character (len = *), parameter :: compiler = compiler_version()
79 | ```
80 |
81 | ### Example (3 minutes)
82 |
83 | > ## `iso_fortran_env` values
84 | >
85 | > An example program is provided which prints out the values of the various
86 | > symbols available from `iso_fortran_env`.
87 | > ```
88 | > $ ftn print_iso_fortran_env.f90
89 | > ```
90 | > To see the actual values in the kind arrays (`integer_kinds` and so on)
91 | > some extra statements would be required.
92 | {: .challenge}
93 |
94 |
95 | ## IEEE arithmetic support
96 |
97 | Fortran provides support for programmers to inquire about support for various
98 | aspects of the IEEE standard for floating point arithmetic. This information
99 | is separated into three modules.
100 |
101 | 1. `ieee_exceptions` provides handling for IEEE exception types enumerated
102 | by the values: `ieee_overflow`, `ieee_divide_by_zero`, `ieee_invalid`,
103 | `ieee_underflow` and `ieee_inexact`.
104 | 2. `ieee_arithmetic` contains functionality for identifying different classes
105 | of floating point values (e.g., `ieee_negative_inf`), rounding modes, and
106 | so on. The `ieee_arithmetic` module include `ieee_exceptions`.
107 | 3. `ieee_features` does not provide names a such by may affect compilation if
108 | present. E.g., if
109 | ```
110 | use, intrinsic :: ieee_features, only : ieee_subnormal
111 | ```
112 | is present, then the program unit must provide support for subnormal floating
113 | point numbers (aka denormalised numbers, with a leading zero in the mantissa).
114 |
115 | A full description of the IEEE features will not be attempted here.
116 |
117 |
118 | {% include links.md %}
119 |
--------------------------------------------------------------------------------
/exercises/11-unlimited-polymorphic-entities/key_value_module.f90:
--------------------------------------------------------------------------------
1 | module key_value_module
2 |
3 | ! Two types are defined:
4 |
5 | ! key_value_t to hold key value pairs, where the key is a string,
6 | ! and the value is an unlimited polymporphic type
7 | !
8 | ! The following interface is wanted:
9 | !
10 | ! A generic function to return a new key_value_t for
11 | ! kv = key_value_t(key, int32) key-value pair for int32 value
12 | ! kv = key_value_t(key, real32) ditto for real32 value
13 | ! kv = key_value_t(key, string) ditto for string value
14 | !
15 | ! subroutine key_value_release(kv) to release/destroy resources
16 | ! subroutine key_value_print(kv) utility to print key/value pair
17 |
18 | ! key_value_list_t an exapndable list of key_value_t pairs
19 |
20 | use iso_fortran_env
21 |
22 | implicit none
23 | public
24 |
25 | type, public :: key_value_t
26 | character (len = :), allocatable :: key ! The key ...
27 | class (*), pointer :: val => null() ! ... value
28 | end type key_value_t
29 |
30 | type, public :: key_value_list_t
31 | integer :: npair = 0 ! Current number of pairs
32 | type (key_value_t), allocatable :: kv(:) ! Expandable list
33 | end type key_value_list_t
34 |
35 | ! We will make the specific versions private; one must use the generic
36 | ! name.
37 | private :: key_value_create_i32
38 | private :: key_value_create_r32
39 | private :: key_value_create_str
40 |
41 | contains
42 |
43 | !---------------------------------------------------------------------------
44 | !---------------------------------------------------------------------------
45 |
46 | function key_value_create_str(key, str) result(kv)
47 |
48 | ! Return aggregated key / value pair - note with trim(str)
49 |
50 | character (len = *), intent(in) :: key
51 | character (len = *), intent(in) :: str
52 | type (key_value_t) :: kv
53 |
54 | kv%key = trim(key)
55 | allocate(kv%val, source = trim(str))
56 |
57 | end function key_value_create_str
58 |
59 | !---------------------------------------------------------------------------
60 | !---------------------------------------------------------------------------
61 |
62 | !----------------------------------------------------------------------------
63 | !----------------------------------------------------------------------------
64 |
65 | function key_value_list_empty_t() result(kvlist)
66 |
67 | ! Return a newly created empty list; allocate size zero pairs.
68 |
69 | type (key_value_list_t) :: kvlist
70 |
71 | kvlist%npair = 0
72 | allocate(kvlist%kv(0))
73 |
74 | end function key_value_list_empty_t
75 |
76 | !---------------------------------------------------------------------------
77 | !---------------------------------------------------------------------------
78 |
79 | subroutine key_value_list_release(kvlist)
80 |
81 | ! Release list storage (assume allocated).
82 |
83 | type (key_value_list_t), intent(inout) :: kvlist
84 |
85 | integer :: ikv
86 |
87 | do ikv = 1, kvlist%npair
88 | call key_value_release(kvlist%kv(ikv))
89 | end do
90 |
91 | deallocate(kvlist%kv)
92 | kvlist%npair = 0
93 |
94 | end subroutine key_value_list_release
95 |
96 | !---------------------------------------------------------------------------
97 | !---------------------------------------------------------------------------
98 |
99 | subroutine key_value_list_add_kv(kvlist, kv)
100 |
101 | ! Add attribute to list
102 |
103 | type (key_value_list_t), intent(inout) :: kvlist
104 | type (key_value_t), intent(in) :: kv
105 |
106 | integer :: nnew
107 |
108 | nnew = kvlist%npair + 1
109 | if (nnew > size(kvlist%kv)) call key_value_list_reallocate(kvlist)
110 |
111 | kvlist%npair = nnew
112 | kvlist%kv(nnew)%key = kv%key
113 | allocate(kvlist%kv(nnew)%val, source = kv%val)
114 |
115 | end subroutine key_value_list_add_kv
116 |
117 | !---------------------------------------------------------------------------
118 | !---------------------------------------------------------------------------
119 |
120 | subroutine key_value_list_print(kvlist)
121 |
122 | ! List items
123 |
124 | type (key_value_list_t), intent(in) :: kvlist
125 |
126 | integer :: ib
127 |
128 | print *, "List has (size, current pairs): ", size(kvlist%kv), kvlist%npair
129 | do ib = 1, kvlist%npair
130 | call key_value_print(kvlist%kv(ib))
131 | end do
132 |
133 | end subroutine key_value_list_print
134 |
135 | !---------------------------------------------------------------------------
136 | !---------------------------------------------------------------------------
137 |
138 | subroutine key_value_list_reallocate(kvlist)
139 |
140 | ! Expand list storage (by a factor of 2)
141 |
142 | type (key_value_list_t), intent(inout) :: kvlist
143 |
144 | ! .. implementation required
145 |
146 | end subroutine key_value_list_reallocate
147 |
148 | end module key_value_module
149 |
--------------------------------------------------------------------------------
/assets/img/swc-icon-blue.svg:
--------------------------------------------------------------------------------
1 |
2 |
71 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Context
2 |
3 | This contribution guide is derived directly that of [The Carpentries' ][c-site].
4 |
5 | ## Contributing
6 |
7 | This is an open source project,
8 | and we welcome contributions of all kinds:
9 | new lessons,
10 | fixes to existing material,
11 | bug reports,
12 | and reviews of proposed changes.
13 |
14 | ## Contributor Agreement
15 |
16 | By contributing,
17 | you agree that we may redistribute your work under [our license](LICENSE.md).
18 | In exchange,
19 | we will address your issues and/or assess your change proposal as promptly as we can.
20 | Everyone involved should
21 | agree to abide by our [code of conduct](CODE_OF_CONDUCT.md).
22 |
23 | ## How to Contribute
24 |
25 | The easiest way to get started is to file an issue
26 | to tell us about a spelling mistake,
27 | some awkward wording,
28 | or a factual error.
29 | This is a good way to introduce yourself
30 | and to meet some of our community members.
31 |
32 | 1. If you do not have a [GitHub][github] account,
33 | you can [send us comments by email][email].
34 | However,
35 | we will be able to respond more quickly if you use one of the other methods described below.
36 |
37 | 2. If you have a [GitHub][github] account,
38 | or are willing to [create one][github-join],
39 | but do not know how to use Git,
40 | you can report problems or suggest improvements by [creating an issue][issues].
41 | This allows us to assign the item to someone
42 | and to respond to it in a threaded discussion.
43 |
44 | 3. If you are comfortable with Git,
45 | and would like to add or change material,
46 | you can submit a pull request (PR).
47 | Instructions for doing this are [included below](#using-github).
48 |
49 | ## Where to Contribute
50 |
51 | 1. If you wish to change this lesson,
52 | please work in ,
53 | which can be viewed at .
54 |
55 | 2. If you wish to change the example lesson,
56 | please work in ,
57 | which documents the format of our lessons
58 | and can be viewed [here][lesson-example].
59 |
60 | 3. If you wish to change the template used for workshop websites,
61 | please work in .
62 | The home page of that repository explains how to set up workshop websites,
63 | while the extra pages in
64 | provide more background on our design choices.
65 |
66 | 4. If you wish to change CSS style files, tools,
67 | or HTML boilerplate for lessons or workshops stored in `_includes` or `_layouts`,
68 | please work in [styles][styles].
69 |
70 | ## What to Contribute
71 |
72 | There are many ways to contribute,
73 | from writing new exercises and improving existing ones
74 | to updating or filling in the documentation
75 | and submitting [bug reports][issues]
76 | about things that don't work, aren't clear, or are missing.
77 |
78 | Comments on issues and reviews of pull requests are just as welcome:
79 | we are smarter together than we are on our own.
80 | Reviews from novices and newcomers are particularly valuable:
81 | it's easy for people who have been using these lessons for a while
82 | to forget how impenetrable some of this material can be,
83 | so fresh eyes are always welcome.
84 |
85 | ## What *Not* to Contribute
86 |
87 | Our lessons already contain more material than we can cover in a typical workshop,
88 | so we are usually *not* looking for more concepts or tools to add to them.
89 | As a rule,
90 | if you want to introduce a new idea,
91 | you must (a) estimate how long it will take to teach
92 | and (b) explain what you would take out to make room for it.
93 | The first encourages contributors to be honest about requirements;
94 | the second, to think hard about priorities.
95 |
96 | ## Using GitHub
97 |
98 | If you choose to contribute via GitHub, you may want to look at
99 | [How to Contribute to an Open Source Project on GitHub][how-contribute].
100 | To manage changes, we follow [GitHub flow][github-flow].
101 | Each lesson has two maintainers who review issues and pull requests or encourage others to do so.
102 | The maintainers are community volunteers and have final say over what gets merged into the lesson.
103 | To use the web interface for contributing to a lesson:
104 |
105 | 1. Fork the originating repository to your GitHub profile.
106 | 2. Within your version of the forked repository, move to the `gh-pages` branch and
107 | create a new branch for each significant change being made.
108 | 3. Navigate to the file(s) you wish to change within the new branches and make revisions as required.
109 | 4. Commit all changed files within the appropriate branches.
110 | 5. Create individual pull requests from each of your changed branches
111 | to the `gh-pages` branch within the originating repository.
112 | 6. If you receive feedback, make changes using your issue-specific branches of the forked
113 | repository and the pull requests will update automatically.
114 | 7. Repeat as needed until all feedback has been addressed.
115 |
116 | When starting work, please make sure your clone of the originating `gh-pages` branch is up-to-date
117 | before creating your own revision-specific branch(es) from there.
118 | Additionally, please only work from your newly-created branch(es) and *not*
119 | your clone of the originating `gh-pages` branch.
120 | Lastly, published copies of all the lessons are available in the `gh-pages` branch of the originating
121 | repository for reference while revising.
122 |
123 | {% include links.md %}
124 |
--------------------------------------------------------------------------------
/exercises/09-abstract-types/solutions/file_module.f90:
--------------------------------------------------------------------------------
1 | module file_module
2 |
3 | implicit none
4 |
5 | type, abstract, public :: file_writer_t
6 | contains
7 | procedure (if_open), pass, deferred :: open
8 | procedure (if_write), pass, deferred :: write
9 | procedure (if_close), pass, deferred :: close
10 | end type file_writer_t
11 |
12 | abstract interface
13 | function if_open(self, filename) result(ierr)
14 | import file_writer_t
15 | class (file_writer_t), intent(inout) :: self
16 | character (len = *), intent(in) :: filename
17 | integer :: ierr
18 | end function if_open
19 |
20 | function if_write(self, data) result(ierr)
21 | import file_writer_t
22 | class (file_writer_t), intent(inout) :: self
23 | integer, intent(in) :: data(:)
24 | integer :: ierr
25 | end function if_write
26 |
27 | function if_close(self) result(ierr)
28 | import file_writer_t
29 | class (file_writer_t), intent(inout) :: self
30 | integer :: ierr
31 | end function if_close
32 | end interface
33 |
34 | !----------------------------------------------------------------------------
35 |
36 | type, extends(file_writer_t), public :: file_formatted_writer_t
37 | private
38 | integer :: myunit
39 | contains
40 | procedure, pass :: open => open_formatted
41 | procedure, pass :: write => write_formatted
42 | procedure, pass :: close => close_formatted
43 | end type file_formatted_writer_t
44 |
45 | !-----------------------------------------------------------------------------
46 |
47 | type, extends(file_writer_t), public :: file_unformatted_writer_t
48 | private
49 | integer :: myunit
50 | contains
51 | procedure, pass :: open => open_unformatted
52 | procedure, pass :: write => write_unformatted
53 | procedure, pass :: close => close_unformatted
54 | end type file_unformatted_writer_t
55 |
56 |
57 | contains
58 |
59 | !----------------------------------------------------------------------------
60 |
61 | function open_formatted(self, filename) result(ierr)
62 |
63 | class (file_formatted_writer_t), intent(inout) :: self
64 | character (len = *), intent(in) :: filename
65 | integer :: ierr
66 |
67 | open (newunit = self%myunit, file = filename, form = 'formatted', &
68 | status = "replace", action = 'write', iostat = ierr)
69 |
70 | end function open_formatted
71 |
72 | function write_formatted(self, data) result(ierr)
73 |
74 | class (file_formatted_writer_t), intent(inout) :: self
75 | integer, intent(in) :: data(:)
76 | integer :: ierr
77 |
78 | write (unit = self%myunit, fmt = *, iostat = ierr) data(:)
79 |
80 | end function write_formatted
81 |
82 | function close_formatted(self) result(ierr)
83 |
84 | class (file_formatted_writer_t), intent(inout) :: self
85 | integer :: ierr
86 |
87 | close (unit = self%myunit, status = 'keep', iostat = ierr)
88 |
89 | end function close_formatted
90 |
91 | !----------------------------------------------------------------------------
92 |
93 | function open_unformatted(self, filename) result(ierr)
94 |
95 | class (file_unformatted_writer_t), intent(inout) :: self
96 | character (len = *), intent(in) :: filename
97 | integer :: ierr
98 |
99 | open (newunit = self%myunit, file = filename, form = 'unformatted', &
100 | status = "replace", action = 'write', iostat = ierr)
101 |
102 | end function open_unformatted
103 |
104 | function write_unformatted(self, data) result(ierr)
105 |
106 | class (file_unformatted_writer_t), intent(inout) :: self
107 | integer, intent(in) :: data(:)
108 | integer :: ierr
109 |
110 | write (unit = self%myunit, iostat = ierr) data(:)
111 |
112 | end function write_unformatted
113 |
114 | function close_unformatted(self) result(ierr)
115 |
116 | class (file_unformatted_writer_t), intent(inout) :: self
117 | integer :: ierr
118 |
119 | close (unit = self%myunit, status = 'keep', iostat = ierr)
120 |
121 | end function close_unformatted
122 |
123 | !----------------------------------------------------------------------------
124 |
125 | function create_file_formatted_writer_t() result(fp)
126 |
127 | class (file_formatted_writer_t), pointer :: fp
128 | allocate(fp)
129 |
130 | end function create_file_formatted_writer_t
131 |
132 | function create_file_unformatted_writer_t() result(fp)
133 |
134 | class (file_unformatted_writer_t), pointer :: fp
135 | allocate(fp)
136 |
137 | end function create_file_unformatted_writer_t
138 |
139 | function file_writer_from_string(str) result(fp)
140 |
141 | character (len = *), intent(in) :: str
142 | class (file_writer_t), pointer :: fp
143 |
144 | ! We haven't reached typed allocation yet, hence the extra
145 | ! routines to return a pointer of the right type.
146 | fp => null()
147 | select case (str)
148 | case ("formatted")
149 | fp => create_file_formatted_writer_t()
150 | case ("unformatted")
151 | fp => create_file_unformatted_writer_t()
152 | case default
153 | print *, "Not recognised ", str
154 | end select
155 |
156 | end function file_writer_from_string
157 |
158 | end module file_module
159 |
--------------------------------------------------------------------------------