Strange result with polymorphic variables

Arjen Markus arjen.markus895@gmail.com
Mon Aug 29 12:04:00 GMT 2011


Hi Janus,

the reduced program below (I removed the scaling and the 3D version)
seems to work properly
with the exception of the need for deallocating the result variable in
add_vector_2d.

It is down to 92 lines of code. I can perhaps reduce it even further.

Regards,

Arjen

----------
! random_walk.f90 --
!     Simulate a random walk in two and three dimensions
!
module points2d3d

    implicit none

    type point2d
        real :: x, y
    contains
        procedure               :: print           => print_2d
        procedure               :: random_vector   => random_vector_2d
        procedure               :: add_vector      => add_vector_2d
        procedure               :: assign          => assign_2d
        generic                 :: operator(+)     => add_vector
        generic                 :: assignment(=)   => assign
    end type point2d

contains

subroutine assign_2d( point1, point2 )
    class(point2d), intent(inout) :: point1
    class(point2d), intent(in)    :: point2

    point1%x = point2%x
    point1%y = point2%y

end subroutine assign_2d

subroutine print_2d( point )
    class(point2d) :: point

    write(*,'(2f10.4)') point%x, point%y
end subroutine print_2d

subroutine random_vector_2d( point )
    class(point2d) :: point

    call random_number( point%x )
    call random_number( point%y )

    point%x = 2.0 * (point%x - 0.5)
    point%y = 2.0 * (point%y - 0.5)

end subroutine random_vector_2d

function add_vector_2d( point, vector )
    class(point2d), intent(in)  :: point, vector
    class(point2d), allocatable :: add_vector_2d

    ! Workaround for gfortran 4.6
!    if ( allocated( add_vector_2d ) ) then
!        deallocate( add_vector_2d )
!    endif

    allocate( add_vector_2d )
    add_vector_2d%x = point%x + vector%x
    add_vector_2d%y = point%y + vector%y

end function add_vector_2d

end module points2d3d

program random_walk

    use points2d3d   ! Both 2D and 3D points available

    type(point2d), target   :: point_2d
    type(point2d), target   :: vector_2d

    class(point2d), pointer :: point
    class(point2d), pointer :: vector

    integer        :: nsteps = 10
    integer        :: i
    integer        :: trial
    real           :: deltt  = 0.1

    point  => point_2d
    vector => vector_2d
    write(*,*) 'Two-dimensional walk:'

    call point%random_vector

     do i = 1,nsteps
        call vector%random_vector

        point = point + vector

        call point%print
    enddo
end program random_walk



More information about the Fortran mailing list