Handling AoS & Default ValuesΒΆ

This example focuses on handling arrays of structures and default values.

See also

API documentation for:
subroutine default_values_and_aos_operations()

    use ids_routines
    implicit none

    ! create empty edge_profiles
    type(ids_edge_profiles) :: edge_profiles
    type(ids_edge_profiles) :: edge_profiles2
    type(ids_generic_grid_aos3_root), pointer :: tmp_grid_ggd(:)
    integer :: copy_starting_index, i

    ! set mandatory field
    edge_profiles%ids_properties%homogeneous_time = IDS_TIME_MODE_HOMOGENEOUS

    ! edge_profiles/grid_ggd is array of structures and must be resized before accessing any of it's elements
    allocate(edge_profiles%grid_ggd(1))
    ! NOTE: for historic reason IDS STR_0D fields are in fact character(len=132), pointer (:)
    allocate(edge_profiles%grid_ggd(1)%identifier%name(1))
    edge_profiles%grid_ggd(1)%identifier%name(1) = 'First test struct'

    ! AoS can be resized with deallocate(node); allocate(node(n)). After calling this, the array of structures will have n elements.
    ! Resizing an array of structures will clear all data inside the array of structures!
    ! Use a temporary variable (as in below example) to keep existing data.
    allocate(tmp_grid_ggd(1))
    call ids_copy(edge_profiles%grid_ggd(1), tmp_grid_ggd(1)) 

    ! first, deallocate structure contents and AoS itself
    call ids_deallocate_struct(edge_profiles%grid_ggd(1), .false.)
    deallocate(edge_profiles%grid_ggd)

    ! actual resize and AoS repopulation
    allocate(edge_profiles%grid_ggd(3))
    call ids_copy(tmp_grid_ggd(1), edge_profiles%grid_ggd(1))

    ! single element can be added to AoS the following way
    ! tmp_grid_ggd will be reused in this example
    tmp_grid_ggd(1)%identifier%name(1) = 'Second test struct'

    ! append aos_element to edge_profiles.grid_ggd AoS
    call ids_copy(tmp_grid_ggd(1), edge_profiles%grid_ggd(2))

    ! common action would be merging two different AoS
    ! edge_profiles2/grid_ggd will be merged with edge_profiles/grid_ggd
    ! first, we have to create new AoS and fill it with data
    allocate(edge_profiles2%grid_ggd(1))
    allocate(edge_profiles2%grid_ggd(1)%identifier%name(1))
    edge_profiles2%grid_ggd(1)%identifier%name(1) = 'Third test struct'

    ! once data are in place, we can merge two AoS objects
    ! Note: in real-life situation user has to extract starting index from target array.
    ! since this IDS is created and deleted in this function, we know starting index is 2 (copying starts from starting_index+1)
    copy_starting_index = 2
    do i = 1, size(edge_profiles2%grid_ggd)
        call ids_copy(edge_profiles2%grid_ggd(i), edge_profiles%grid_ggd(copy_starting_index+i))
    end do

    do i = 1, size(edge_profiles%grid_ggd)
        write(*,*) 'Value of edge_profiles%grid_ggd(', i , ')%identifier%name: ', edge_profiles%grid_ggd(i)%identifier%name(1)
    end do

    ! ids fields have default values different for every data type
    write(*,*) 'Default value for INT     data  (edge_profiles/midplane/index)                                 :', &
        edge_profiles%midplane%index
    write(*,*) 'Default value for FLOAT   data  (edge_profiles/vacuum_toroidal_field/vacuum_toroidal_field/r0) :', &
        edge_profiles%vacuum_toroidal_field%r0
    write(*,*) 'Default value for COMPLEX data                                                                 :', &
        IDS_COMPLEX_INVALID
    write(*,*) 'Default value for 1+ dimensional data is unassociated.'
    write(*,*) 'Is edge_profiles/vacuum_toroidal_field/b0 associated?: ', &
        associated(edge_profiles%vacuum_toroidal_field%b0)

    ! clear memory
    call ids_deallocate(edge_profiles)
    call ids_deallocate(edge_profiles2)
    ! second argument in ids_deallocate_struct() indicates if struct was retrieved from entry (.true.),
    ! or defined in Fortran code (.false.)
    call ids_deallocate_struct(tmp_grid_ggd(1), .false.)
    deallocate(tmp_grid_ggd)

end subroutine default_values_and_aos_operations