Is there a way to overload the = operator so that you can write an assignment like in this example:
  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 vectorAssign
  ! end interface
  contains
    ! function vectorAssign(f) result(q)
    !   implicit none
    !   real(dpn),intent(in) :: f
    !   type(vectorField) :: q
    !   q%x = f; q%y = f; q%z = f
    ! end function
    ! subroutine vectorAssign(f,g)
    !   implicit none
    !   type(vectorField),intent(inout) :: f
    !   real(dpn),intent(in) :: g
    !   f%x = g; f%y = g; f%z = g
    ! end subroutine
    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
  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)
  a%x = dble(1.0) ! want to avoid this
  a%y = dble(1.0) ! want to avoid this
  a%z = dble(1.0) ! want to avoid this
  a = real(1.0,dpn) ! want this instead (does not compile)
  call delete(a)
  end program
I've tried two different ways (shown in comments) but I get errors saying that there is a syntax error in generic specification (for publicizing the = operator).
= is not an operator, it is an assignment in Fortran and they are very different beasts.
To the classical possibility found in Fortran 90 and explained well in other answers, Fortran 2003 added a better possibility to bind the overloaded operators and assignments with the derived type.
This way you are sure you will not import the type without the assignment (beware of public and private statement in this case!). It can have very unpleasant consequences and can be hard to debug:
type vectorField
  integer,dimension(3) :: sx,sy,sz
  real(dpn),dimension(:,:,:),allocatable :: x,y,z
contains
  procedure :: assignVector
  generic :: assignment(=) => assignVector
end type
This way you do not have to be that careful to not forget the public :: assignment (=)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With