我想重载一个运算符(*)来执行以下类中的向量标量乘法:
module vectorField_mod
use constants_mod
implicit none
private
public :: vectorField
public :: allocateVectorField
public :: delete
type vectorField
real(dpn),dimension(:,:,:),allocatable :: x,y,z
end type
interface operator (*)
module procedure scalarMultiply
end interface
contains
function scalarMultiply(f,g) result(q)
implicit none
type(vectorField),intent(in) :: f
real(dpn),intent(in) :: g
type(vectorField) :: q
q%x = f%x * g
q%y = f%y * g
q%z = f%z * g
q%sx = f%sx; q%sy = f%sy; q%sz = f%sz
end function
...
end module
但我收到以下错误:
Error: Operands of binary numeric operator '*' at (1) are REAL(8)/TYPE(vectorfield)
我试图实现这个:
type(vectorField) :: a
real(8) :: dt = 0.001
call allocateVectorField(a,..)
a = a*dt
这不是二元操作吗?还有办法吗?非常感谢任何帮助!
要点:
1)@francescalus的回答是必要的,但不足以成功编译。
2)另外,事实证明乘法的顺序很重要。这是a = a dt有效,但a = dt a不起作用(这是我遇到的问题)
这是一个说明性的样本:
module constants_mod
integer,parameter :: dpn = selected_real_kind(14)
end module
module vectorField_mod
use constants_mod
implicit none
private
public :: vectorField
public :: allocateX,allocateY,allocateZ
public :: delete
public :: operator(*)
type vectorField
integer,dimension(3) :: sx,sy,sz
real(dpn),dimension(:,:,:),allocatable :: x,y,z
end type
interface delete
module procedure deallocateVectorField
end interface
interface operator (*)
module procedure scalarMultiply
end interface
contains
function scalarMultiply(f,g) result(q)
implicit none
type(vectorField),intent(in) :: f
real(dpn),intent(in) :: g
type(vectorField) :: q
q%x = f%x * g; q%y = f%y * g; q%z = f%z * g
q%sx = f%sx; q%sy = f%sy; q%sz = f%sz
end function
subroutine allocateX(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%x)) deallocate(field%x)
allocate(field%x(Nx,Ny,Nz))
field%sx = shape(field%x)
end subroutine
subroutine allocateY(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%y)) deallocate(field%y)
allocate(field%y(Nx,Ny,Nz))
field%sy = shape(field%y)
end subroutine
subroutine allocateZ(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%z)) deallocate(field%z)
allocate(field%z(Nx,Ny,Nz))
field%sz = shape(field%z)
end subroutine
subroutine deallocateVectorField(field)
implicit none
type(vectorField),intent(inout) :: field
deallocate(field%x,field%y,field%z)
field%sx = 0; field%sy = 0; field%sz = 0
end subroutine
end module
program test
use constants_mod
use vectorField_mod
implicit none
type(vectorField) :: a,b
integer :: N = 1
real(dpn) :: dt = 0.1
call allocateX(a,N,N,N)
call allocateY(a,N,N,N)
call allocateZ(a,N,N,N)
call allocateX(b,N,N,N)
call allocateY(b,N,N,N)
call allocateZ(b,N,N,N)
a%x = dble(1.0); a%y = dble(1.0); a%z = dble(1.0)
b%x = dble(1.0); b%y = dble(1.0); b%z = dble(1.0)
a = b
a = a*dt ! compiles fine
a = dt*a ! does not compile
call delete(a)
call delete(b)
end program
答案 0 :(得分:1)
模块的默认可访问性为private
。此默认值也适用于已定义的运算符。
要使操作员标识符公开(以便可以在模块外部使用),请使用public
语句,如:
public :: operator(*)