I have now set the gfortran compiler to the following version:
GNU Fortran (Ubuntu 11.1.0-1ubuntu1~18.04.1) 11.1.0
My module looks now like this:
module coords
use iso_fortran_env
implicit none
private
public :: point
type ::point!(k)
!integer, kind :: k = kind(0.)
!real(kind=k) :: x,y,z
real :: x,y,z
contains
procedure,private,pass(this) :: pointplus, pointminus, pointseparation
procedure,private,pass(this) :: vecotr_dot, vecotr_cros
procedure,private,pass(this) :: point_multiply_vct_scalar_32, point_multiply_vct_scalar_64
procedure,private,pass(this) :: point_multiply_scalar_vct_32, point_multiply_scalar_vct_64
procedure,private,pass(this) :: absvec_real32, absvec_real64
procedure,private,pass(this) :: pointdivide_32, pointdivide_64
generic,public :: operator(+) => pointplus
generic,public :: operator(-) => pointminus
generic,public :: operator(*) => point_multiply_vct_scalar_32, point_multiply_vct_scalar_64
generic,public :: operator(*) => point_multiply_scalar_vct_32, point_multiply_scalar_vct_64
generic,public :: operator(/) => pointdivide_32, pointdivide_64
generic,public :: operator(.distance.) => pointseparation
generic,public :: assignment(=) => absvec_real32, absvec_real64
generic,public :: operator(.dot.) => vecotr_dot
generic,public :: operator(.cros.) => vecotr_cros
end type point
type, extends(point), public :: pointT
real, PUBLIC :: T
contains
procedure,PUBLIC :: Tplus,Tminus
end type pointT
type, extends(point) :: point_64
real(real64),PUBLIC :: x_64, y_64, z_64
end type point_64
interface absvec
module procedure absvec_real32, absvec_real64
end interface absvec
contains
type(pointT) function Tplus(this) ! for +
class(pointT),intent(in) :: this
Tplus%T = this%T + Tplus%x
end function Tplus
type(pointT) function Tminus(this) ! for +
class(pointT),intent(in) :: this
Tminus%T = Tminus%T - this%T
end function Tminus
type(point) function pointplus(this,b) ! for +
class(point),intent(in) :: this, b
pointplus%x = this%x + b%x
pointplus%y = this%y + b%y
pointplus%z = this%z + b%z
end function pointplus
type(point) function pointdivide_32(this,scalar) ! for +
class(point),intent(in) :: this
real(real32), INTENT(IN) :: scalar
pointdivide_32%x = this%x / scalar
pointdivide_32%y = this%y / scalar
pointdivide_32%z = this%z / scalar
end function pointdivide_32
type(point) function pointdivide_64(this,scalar) ! for +
class(point),intent(in) :: this
real(real64), INTENT(IN) :: scalar
pointdivide_64%x = this%x / scalar
pointdivide_64%y = this%y / scalar
pointdivide_64%z = this%z / scalar
end function pointdivide_64
type(point) function point_multiply_vct_scalar_32(this,scalar) ! for +
class(point),intent(in) :: this
real(real32), INTENT(IN) :: scalar
point_multiply_vct_scalar_32%x = this%x * scalar
point_multiply_vct_scalar_32%y = this%y * scalar
point_multiply_vct_scalar_32%z = this%z * scalar
end function point_multiply_vct_scalar_32
type(point) function point_multiply_scalar_vct_32(scalar,this) ! for +
class(point),intent(in) :: this
real(real32), INTENT(IN) :: scalar
point_multiply_scalar_vct_32%x = this%x * scalar
point_multiply_scalar_vct_32%y = this%y * scalar
point_multiply_scalar_vct_32%z = this%z * scalar
end function point_multiply_scalar_vct_32
type(point) function point_multiply_vct_scalar_64(this,scalar) ! for +
class(point),intent(in) :: this
real(real64), INTENT(IN) :: scalar
select type (this)
class is (point_64)
point_multiply_vct_scalar_64%x = this%x_64 * scalar
point_multiply_vct_scalar_64%y = this%y_64 * scalar
point_multiply_vct_scalar_64%z = this%z_64 * scalar
end select
end function point_multiply_vct_scalar_64
type(point) function point_multiply_scalar_vct_64(scalar,this) ! for +
class(point),intent(in) :: this
real(real64), INTENT(IN) :: scalar
select type (this)
class is (point_64)
point_multiply_scalar_vct_64%x = this%x_64 * scalar
point_multiply_scalar_vct_64%y = this%y_64 * scalar
point_multiply_scalar_vct_64%z = this%z_64 * scalar
end select
end function point_multiply_scalar_vct_64
type(point) function pointminus(this,b) ! for -
class(point),intent(in):: this, b
pointminus%x = this%x - b%x
pointminus%y = this%y - b%y
pointminus%z = this%z - b%z
end function pointminus
real function pointseparation(this,b) ! for .distance.
class(point),intent(in) :: this,b
pointseparation = sqrt( &
(this%x-b%x)**2+(this%y-b%y)**2+(this%z-b%z)**2)
end function pointseparation
subroutine absvec_real64(a,this) ! for = (distance
real(real64),intent(out) :: a ! from origin)
class(point),intent(in) :: this
a = sqrt(this%x**2+this%y**2+this%z**2)
end subroutine absvec_real64
subroutine absvec_real32(a,this) ! for = (distance
real(real32),intent(out) :: a ! from origin)
class(point),intent(in) :: this
a = sqrt(this%x**2 + this%y**2 + this%z**2)
end subroutine absvec_real32
real function vecotr_dot(this,b) ! for .distance.
class(point),intent(in) :: this,b
vecotr_dot = (this%x*b%x)+(this%y*b%y)+(this%z*b%z)
end function vecotr_dot
type(point) function vecotr_cros(this,b) ! for -
class(point),intent(in):: this, b
vecotr_cros%x = this%y * b%z - this%z * b%y
vecotr_cros%y = this%z * b%x - this%x * b%z
vecotr_cros%z = this%x * b%y - this%y * b%x
end function vecotr_cros
end module coords
and my file to run like:
program test
use coords
use iso_fortran_env
implicit none
real(real32) :: r4
real(real64) :: r8
type(point) :: p1, p2, p3
type(pointT) :: pT1, pT2
!test
r4 = p1
r8 = p1
r4 = p1.dot.p2
p3 = p1.cros.p2
p3 = p1 * r4
p3 = p1 * r8
p3 = r4 * p1
p3 = r8 * p1
p3 = p1 / r4
p3 = p1 / r8
r4 = pT1%Tplus(pT2)
r4 = pT1%Tminus(pT2)
end program test
My understanding is that the functions are now the required operations. However, I have a problem with the type extension pointT. I get the following error:
exercise_10_1.f90:24:10:
24 | r4 = pT1%Tplus(pT2)
| 1
Error: More actual than formal arguments in procedure call at (1)
exercise_10_1.f90:25:10:
25 | r4 = pT1%Tminus(pT2)
| 1
Error: More actual than formal arguments in procedure call at (1)
./run: line 4: ./a.out: No such file or directory
How can I interpret this? In my search on the web I only found that I can use Makefiles. But why do I need to do that? I am currently compiling my code as:
gfortran -fbacktrace -g -fcheck=all -fbounds-check -finit-real=snan -ffpe-trap=invalid,zero,overflow -O0 -O -Wall -g module_cords.f90 exercise_10_1.f90
Do I really need to use makefiles to solve this error? Or is there something else I did wrong?