diff --git a/tutorials/fortran/t2.f90 b/tutorials/fortran/t2.f90
index d898ca260da0be8989979a6665ef5d5195ea58a4..34d65911e54ffce38abb627d2f7ff35b5e9b9654 100644
--- a/tutorials/fortran/t2.f90
+++ b/tutorials/fortran/t2.f90
@@ -12,40 +12,14 @@ program main
     use gmsh
 
     implicit none
-    integer(c_int) :: ierr, argc, itmp, i, ps, len
-    integer(c_int) :: recombine
     integer(c_size_t) :: ov_n, xyz_n, numElements_n, heights_n, ov2_n
-    real(c_double) :: lc
-
-    integer(c_int) :: cl1(4) = [4, 1, -2, 3]
-    integer(c_int) :: cl2(4) = [5, -8, -7, 3]
-    integer(c_int) :: cl3(4) = [115, -111, 3, 110]
-    integer(c_int) :: cl4(4) = [111, 116, -112, -7]
-    integer(c_int) :: cl5(4) = [112, 117, -113, -8]
-    integer(c_int) :: cl6(4) = [114, -110, 5, 113]
-    integer(c_int) :: cl7(4) = [115, 116, 117, 114]
-    integer(c_int) :: s1(1) = [1]
-    integer(c_int) :: s2(1) = [10]
-    integer(c_int) :: s3(1) = [118]
-    integer(c_int) :: s4(1) = [120]
-    integer(c_int) :: s5(1) = [122]
-    integer(c_int) :: s6(1) = [124]
-    integer(c_int) :: s7(1) = [126]
-    integer(c_int) :: g5(3) = [1, 2, 4]
-    integer(c_int) :: g6(1) = [1]
-    integer(c_int) :: g7(2) = [129, 130]
-    integer(c_int) :: t(2) = [0, 5]
-    integer(c_int) :: iv(2) = [0, 3]
-    integer(c_int) :: iv2(4) = [2, 1, 2, 11]
-    integer(c_int) :: numElements(0)
-    real (c_double) :: iv0(0)
-    real(c_double) :: heights(0)
-    integer(c_int) :: sl1(6) = [127, 119, 121, 123, 125, 11]
-    integer(c_int) :: v1(1) = [128]
-    integer(c_int) :: ss(16) = [0, 103, 0, 105, 0, 109, 0, 102, 0, 28, 0, 24, 0, 6, 0, 5]
-
+    integer(c_int) :: cl1(4), cl2(4), cl3(4), cl4(4), cl5(4), cl6(4), cl7(4), &
+                      s1(1), s2(1), s3(1), s4(1), s5(1), s6(1), s7(1), g5(3), &
+                      g6(1), g7(2), t(2), iv(2), iv2(4), numElements(0),      &
+                      sl1(6), v1(1), ss(16), recombine, ierr, argc, itmp, i, len
+    real (c_double) :: lc, iv0(0), heights(0)
+    type(c_ptr) :: ov, xyz, ov2
     type(c_ptr), allocatable :: argv(:)
-    type(c_ptr) :: ov, xyz, ov2, ov_3
 
     type string
         character(len = :, kind = c_char), allocatable :: item
@@ -57,60 +31,75 @@ program main
     integer(c_int), pointer :: pf_ov(:), pf_ov3(:)
     real(c_double), pointer :: pf_xyz(:)
 
-    lc = 0.01
-
     argc = command_argument_count()
     allocate(argv(argc + 2))
     allocate(tmp(argc + 1))
 
     do i = 0, argc
         call get_command_argument(i, buf, len)
-        tmp(i + 1) % item = buf(1 : len) // c_null_char
+        tmp(i + 1) % item = buf(1 : len)//c_null_char
         argv(i + 1) = c_loc(tmp(i + 1) % item)
-    enddo
+    end do
     argv(argc + 2) = c_null_ptr
 
     call gmshInitialize(argc + 1, argv, 1, 0, ierr)
 
-    call gmshModelAdd("t2" // c_null_char, ierr)
+    call gmshModelAdd("t2"//c_null_char, ierr)
 
-    itmp = gmshModelGeoAddPoint(0d0, 0d0, 0d0, lc, 1, ierr)
-    itmp = gmshModelGeoAddPoint(0.1d0, 0d0, 0d0, lc, 2, ierr)
-    itmp = gmshModelGeoAddPoint(0.1d0, 0.3d0, 0d0, lc, 3, ierr)
-    itmp = gmshModelGeoAddPoint(0d0, 0.3d0, 0d0, lc, 4, ierr)
+    ! Copied from `t1.f90'...
+    lc = 0.01
+    itmp = gmshModelGeoAddPoint(0.0d0, 0.0d0, 0.0d0, lc, 1, ierr)
+    itmp = gmshModelGeoAddPoint(0.1d0, 0.0d0, 0.0d0, lc, 2, ierr)
+    itmp = gmshModelGeoAddPoint(0.1d0, 0.3d0, 0.0d0, lc, 3, ierr)
+    itmp = gmshModelGeoAddPoint(0.0d0, 0.3d0, 0.0d0, lc, 4, ierr)
 
     itmp = gmshModelGeoAddLine(1, 2, 1, ierr)
     itmp = gmshModelGeoAddLine(3, 2, 2, ierr)
     itmp = gmshModelGeoAddLine(3, 4, 3, ierr)
     itmp = gmshModelGeoAddLine(4, 1, 4, ierr)
 
-    itmp = gmshModelGeoAddCurveLoop(cl1, 4_8, 1, 0, ierr)
-    itmp = gmshModelGeoAddPlaneSurface(s1, 1_8, 1, ierr)
+    cl1 = [4, 1, -2, 3]; s1 = [1]
+    itmp = gmshModelGeoAddCurveLoop(cl1, size(cl1, kind=c_size_t), 1, 0, ierr)
+    itmp = gmshModelGeoAddPlaneSurface(s1, size(s1, kind=c_size_t), 1, ierr)
 
     call gmshModelGeoSynchronize(ierr)
-    itmp = gmshModelAddPhysicalGroup(1, g5, 3_8, 5, "", ierr)
-    ps = gmshModelAddPhysicalGroup(2, g6, 1_8, -1, "", ierr)
-    call gmshModelSetPhysicalName(2, ps, "My surface" // c_null_char, ierr)
 
-    itmp = gmshModelGeoAddPoint(0d0, 0.4d0, 0d0, lc, 5, ierr)
+    g5 = [1, 2, 4]; g6 = [1]
+    itmp = gmshModelAddPhysicalGroup(1, g5, size(g5, kind=c_size_t), 5, ""//c_null_char, ierr)
+    itmp = gmshModelAddPhysicalGroup(2, g6, size(g6, kind=c_size_t), -1, "My surface"//c_null_char, ierr)
+    call gmshModelSetPhysicalName(2, itmp, "My surface"//c_null_char, ierr)
 
+    itmp = gmshModelGeoAddPoint(0.0d0, 0.4d0, 0.0d0, lc, 5, ierr)
     itmp = gmshModelGeoAddLine(4, 5, 5, ierr)
 
-    call gmshModelGeoTranslate(t, 2_8, -0.02d0, 0d0, 0d0, ierr)
+    t = [0, 5]
+    call gmshModelGeoTranslate(t, size(t, kind=c_size_t), -0.02d0, 0.0d0, 0.0d0, ierr)
+    call gmshModelGeoRotate(t, size(t, kind=c_size_t), 0.0d0, 0.3d0, 0.0d0, &
+                            0.0d0, 0.0d0, 1.0d0, -acos(1.0d0) / 4.0d0, ierr)
 
-    call gmshModelGeoRotate(t, 2_8, 0d0, 0.3d0, 0d0, 0d0, 0d0, 1d0, -acos(1.0) / 4d0, ierr)
-
-    call gmshModelGeoCopy(iv, 2_8, ov, ov_n, ierr)
+    ! Note that there are no units in Gmsh: coordinates are just numbers - it's
+    ! up to the user to associate a meaning to them.
 
+    ! Point 3 can be duplicated and translated by 0.05 along the y axis by using
+    ! the `copy()' function, which takes a vector of (dim, tag) pairs as input,
+    ! and returns another vector of (dim, tag) pairs:
+    iv = [0, 3]
+    call gmshModelGeoCopy(iv, size(iv, kind=c_size_t), ov, ov_n, ierr)
     call c_f_pointer(ov, pf_ov, [ov_n])
-    call gmshModelGeoTranslate(pf_ov, ov_n, 0d0, 0.05d0, 0d0, ierr)
+    call gmshModelGeoTranslate(pf_ov, ov_n, 0.0d0, 0.05d0, 0.0d0, ierr)
 
+    ! The new point tag is available in ov[0].second, and can be used to create
+    ! new lines:
     itmp = gmshModelGeoAddLine(3, pf_ov(2), 7, ierr)
     itmp = gmshModelGeoAddLine(pf_ov(2), 5, 8, ierr)
 
-    itmp = gmshModelGeoAddCurveLoop(cl2, 4_8, 10, 0, ierr)
-    itmp = gmshModelGeoAddPlaneSurface(s2, 1_8, 11, ierr)
+    cl2 = [5, -8, -7, 3]; s2 = [10]
+    itmp = gmshModelGeoAddCurveLoop(cl2, size(cl2, kind=c_size_t), 10, 0, ierr)
+    itmp = gmshModelGeoAddPlaneSurface(s2, size(s2, kind=c_size_t), 11, ierr)
 
+    ! In the same way, we can translate copies of the two surfaces 1 and 11 to
+    ! the right with the following command:
+    iv2 = [2, 1, 2, 11]
     call gmshModelGeoCopy(iv2, 4_8, ov, ov_n, ierr)
 
     call c_f_pointer(ov, pf_ov, [ov_n])
@@ -118,17 +107,21 @@ program main
 
     print *, "New surfaces ", pf_ov(2), " and ", pf_ov(4)
 
-    itmp = gmshModelGeoAddPoint(0d0, 0.3d0, 0.12d0, lc, 100, ierr)
-    itmp = gmshModelGeoAddPoint(0.1d0, 0.3d0, 0.12d0, lc, 101, ierr)
+    ! Volumes are the fourth type of elementary entities in Gmsh. In the same way
+    ! one defines curve loops to build surfaces, one has to define surface loops
+    ! (i.e. `shells') to build volumes. The following volume does not have holes
+    ! and thus consists of a single surface loop:
+    itmp = gmshModelGeoAddPoint(0.0d0, 0.30d0, 0.12d0, lc, 100, ierr)
+    itmp = gmshModelGeoAddPoint(0.1d0, 0.30d0, 0.12d0, lc, 101, ierr)
     itmp = gmshModelGeoAddPoint(0.1d0, 0.35d0, 0.12d0, lc, 102, ierr)
 
+    ! We would like to retrieve the coordinates of point 5 to create point 103,
+    ! so we synchronize the model, and use `getValue()'
     call gmshModelGeoSynchronize(ierr)
 
-    call gmshModelGetValue(0, 5, iv0, 0_8, xyz, xyz_n, ierr)
-
+    call gmshModelGetValue(0, 5, iv0, size(iv0, kind=c_size_t), xyz, xyz_n, ierr)
     call c_f_pointer(xyz, pf_xyz, [xyz_n])
     itmp = gmshModelGeoAddPoint(pf_xyz(1), pf_xyz(2), 0.12d0, lc, 103, ierr)
-
     itmp = gmshModelGeoAddLine(4, 100, 110, ierr)
     itmp = gmshModelGeoAddLine(3, 101, 111, ierr)
     itmp = gmshModelGeoAddLine(6, 102, 112, ierr);
@@ -138,42 +131,63 @@ program main
     itmp = gmshModelGeoAddLine(101, 102, 116, ierr)
     itmp = gmshModelGeoAddLine(102, 103, 117, ierr)
 
+    cl3 = [115, -111, 3, 110]; s3 = [118]
     itmp = gmshModelGeoAddCurveLoop(cl3, 4_8, 118, 0, ierr)
     itmp = gmshModelGeoAddPlaneSurface(s3, 1_8, 119, ierr)
 
+    cl4 = [111, 116, -112, -7]; s4 = [120]
     itmp = gmshModelGeoAddCurveLoop(cl4, 4_8, 120, 0, ierr)
     itmp = gmshModelGeoAddPlaneSurface(s4, 1_8, 121, ierr)
 
+    cl5 = [112, 117, -113, -8]; s5 = [122]
     itmp = gmshModelGeoAddCurveLoop(cl5, 4_8, 122, 0, ierr)
     itmp = gmshModelGeoAddPlaneSurface(s5, 1_8, 123, ierr)
 
+    cl6 = [114, -110, 5, 113]; s6 = [124]
     itmp = gmshModelGeoAddCurveLoop(cl6, 4_8, 124, 0, ierr)
     itmp = gmshModelGeoAddPlaneSurface(s6, 1_8, 125, ierr)
 
+    cl7 = [115, 116, 117, 114]; s7 = [126]
     itmp = gmshModelGeoAddCurveLoop(cl7, 4_8, 126, 0, ierr)
     itmp = gmshModelGeoAddPlaneSurface(s7, 1_8, 127, ierr)
 
+    sl1 = [127, 119, 121, 123, 125, 11]; v1 = [128]
     itmp = gmshModelGeoAddSurfaceLoop(sl1, 6_8, 128, ierr)
     itmp = gmshModelGeoAddVolume(v1, 1_8, 129, ierr)
 
+    ! When a volume can be extruded from a surface, it is usually easier to use
+    ! the `extrude()' function directly instead of creating all the points,
+    ! curves and surfaces by hand. For example, the following command extrudes
+    ! the surface 11 along the z axis and automatically creates a new volume (as
+    ! well as all the needed points, curves and surfaces). As expected, the
+    ! function takes a vector of (dim, tag) pairs as input as well as the
+    ! translation vector, and returns a vector of (dim, tag) pairs as output:
     numElements_n = 0
     heights_n = 0
     recombine=0
-    ov_3 = c_loc(pf_ov(3))
-    call c_f_pointer(ov_3, pf_ov3, [ov_n - 2])
-    call gmshModelGeoExtrude(pf_ov3, 2_8, 0d0, 0d0, 0.12d0, ov2, ov2_n, &
+    call c_f_pointer(c_loc(pf_ov(3)), pf_ov3, [ov_n - 2])
+    call gmshModelGeoExtrude(pf_ov3, 2_8, 0.0d0, 0.0d0, 0.12d0, ov2, ov2_n, &
                              numElements, numElements_n, heights, heights_n, recombine, ierr)
 
+    ! Mesh sizes associated to geometrical points can be set by passing a vector
+    ! of (dim, tag) pairs for the corresponding points:
+    ss = [0, 103, 0, 105, 0, 109, 0, 102, 0, 28, 0, 24, 0, 6, 0, 5]
     call gmshModelGeoMeshSetSize(ss, 16_8, lc * 3, ierr)
 
+    ! We finish by synchronizing the data from the built-in CAD kernel with the
+    ! Gmsh model:
     call gmshModelGeoSynchronize(ierr)
 
-    itmp = gmshModelAddPhysicalGroup(3, g7, 2_8, 1, "", ierr)
+    ! We group volumes 129 and 130 in a single physical group with tag `1' and
+    ! name "The volume":
+    g7 = [129, 130]
+    itmp = gmshModelAddPhysicalGroup(3, g7, size(g7, kind=c_size_t), 1, ""//c_null_char, ierr)
 
-    call gmshModelSetPhysicalName(3, 1, "The volume" // c_null_char, ierr)
+    call gmshModelSetPhysicalName(3, 1, "The volume"//c_null_char, ierr)
 
+    ! We finally generate and save the mesh:
     call gmshModelMeshGenerate(3, ierr)
-    call gmshWrite("t2.msh" // c_null_char, ierr)
+    call gmshWrite("t2.msh"//c_null_char, ierr)
 
     ! call gmshFltkRun(ierr)