Creating an array of derived types that share parent type

type person
logical infected
end type

type, extends(person) :: v
! Irrelevant members
end type

type r
type(p), allocatable :: stuck
end room

subroutine infect(visiting, room)
    type(r), INTENT(INOUT) :: room
    class(Person), ALLOCATABLE :: tmp(:)
    integer, INTENT(IN) :: visiting(:)
    real, ALLOCATABLE :: vals(:)
    integer, ALLOCATABLE :: indices_healthy(:)
    integer boundary, i, j, ninfected

    boundary = size(visiting)
    ALLOCATE(tmp(boundary+size(room%stuck)), source=tmp)
    !ALLOCATE(tmp(boundary+1:), source=room%stuck)
    tmp = [visitor(visiting), room%stuck]
    ninfected = count(tmp%infected .eqv..true.)
    indices_healthy = PACK([(i, i = 1, size(tmp))], tmp%infected .eqv..false.)

    ! Assumption: for each infected person in a room, the person
    ! will interact with every healthy person in the same room.
    do i = 1, ninfected
        call RANDOM_NUMBER(vals(size(indices_healthy)))
        do j = 1, SIZE(indices_healthy)
            if (vals(j) < .5) tmp(indices_healthy(j))%infected = .true.
        end do
    end do
    visiting = tmp(:boundary)
    room%stuck = tmp(boundary + 1:)
end subroutine

Trying to compile yielded this:


  160 |     tmp = [visitor(visiting), room%stuck]
      |                             1
Error: Element in TYPE(v) array constructor at (1) is TYPE(person)

  172 |     visiting = tmp(:boundary)
      |    1
Error: Dummy argument ‘visiting’ with INTENT(IN) in variable definition context (assignment) at (1)
1 Like

Hi rugta,

Welcome to the Fortran Discourse.

Your first mistake is that visitor has not been declared. Fixing that error should get you headed back in the right direction. However, there is also an important point about polymorphic arrays in Fortran; all of the elements stored in the array must still be of the same type. If you want an array of elements that may be of different types, you need an extra type for some indirection. I have an example that demonstrates it: Files · implement_area_filter · Brad Richardson / heterogeneous_list · GitLab

Good luck, and feel free to come back with more questions.


what is type r and what is type p?

In code posted you declare person and extend it with a type v