Silverfrost Forums

Welcome to our forums

Initialising data for derived types

22 Aug 2015 5:49 #16754

I have recently started using derived types and found this quite useful. I am however finding it difficult to understand how to initialise the variables within a derived type within a parameter construction.

Consider the following code:-

winapp
module conductor_lib
implicit none
  
  type acsr                        !Standard acsr conductor parameters
    character(len=10) name         !Name
    integer           al_st        !No of Al strands          [-]
    real              al_st_dia    !Al strand diameter        [mm]
    integer           fe_st        !No of Fe strands          [-]
    real              fe_st_dia    !Fr strand diameter        [mm]
    real              csa_al       !Area of Al                [mm^2]
    real              csa_fe       !Area of Fe                [mm^2]
    real              csa_tot      !Area in total             [mm^2]
    real              over_dia     !Overall diameter          [mm]
    real              rdc_20       !DC resistance at 20 deg C [ohm/km]
  end type acsr

  integer rows_acsr_lib
  type(acsr), dimension(1:14) :: acsr_lib

  contains

    subroutine load_acsr_lib
    integer i
    
      open (unit=10, file = 'acsr_lib.txt')
      rewind 10
      read (10,*) rows_acsr_lib
      do i = 1, rows_acsr_lib
        read(10,*) acsr_lib(i)%name, acsr_lib(i)%al_st, acsr_lib(i)%al_st_dia, acsr_lib(i)%fe_st, &
                   acsr_lib(i)%fe_st_dia, acsr_lib(i)%csa_al, acsr_lib(i)%csa_fe,                 & 
                   acsr_lib(i)%csa_tot, acsr_lib(i)%over_dia, acsr_lib(i)%rdc_20
      end do
      rewind 10
      close (unit=10, status = 'keep')
      
    end subroutine load_acsr_lib
  
end module conductor_lib

program test
use conductor_lib
implicit none
integer i

  call load_acsr_lib
  do i = 1, rows_acsr_lib
    write(6,*)acsr_lib(i)%name, acsr_lib(i)%al_st, acsr_lib(i)%al_st_dia, acsr_lib(i)%fe_st, &
              acsr_lib(i)%fe_st_dia, acsr_lib(i)%csa_al, acsr_lib(i)%csa_fe,               &
              acsr_lib(i)%csa_tot, acsr_lib(i)%over_dia, acsr_lib(i)%rdc_20
  end do
  
end program test

Here the routine load_acsr_lib opens the file 'acsr_lib.txt' and reads the data describing each of the 14 data sets. The contents of the file is a mixture of character, integer, and reals:-

14
'Gopher', 6,  2.36, 1, 2.40,  26.20,  4.40,  30.60, 7.08,  1.093 
'Weasel', 6,  2.59, 1, 2.60,  31.60,  5.30,  36.90, 7.77,  0.908
'Ferret', 6,  3.00, 1, 3.00,  42.40,  7.10,  49.50, 9.00,  0.676
'Rabbit', 6,  3.35, 1, 3.40,  52.90,  8.80,  61.70, 10.05, 0.542
'Horse',  12, 2.79, 7, 2.80,  73.40, 42.80, 116.20, 13.95, 0.393
'Dog',    6,  4.72, 7, 1.60, 105.00, 13.60, 118.50, 14.15, 0.273
'Tiger',  30, 2.36, 7, 2.40, 131.20, 30.60, 161.90, 16.52, 0.220
'Wolf',   30, 2.59, 7, 2.60, 158.10, 36.90, 194.90, 18.13, 0.182
'Dingo',  18, 3.35, 1, 3.40, 158.70,  8.80, 167.50, 16.75, 0.181
'Lynx',   30, 2.79, 7, 2.80, 183.40, 42.80, 226.20, 19.53, 0.157
'Caracal',18, 3.61, 1, 3.60, 184.20, 10.20, 194.50, 18.05, 0.156
'Jaguar', 18, 3.86, 1, 3.90, 210.60, 11.70, 222.30, 19.30, 0.137
'Panther',30, 3.00, 7, 3.00, 212.10, 49.50, 261.50, 21.00, 0.136
'Zebra',  54, 3.18, 7, 3.20, 428.90, 55.60, 484.50, 28.62, 0.067  

How do I initialise this data, within the module conductor_lib with a parameter (or data ?) statement, rather than using the subroutine load_acsr_lib to read the file 'acsr_lib.txt'. All my attempts to do this, have failed. Can somebody point me in the correct direction?

Thanks

Ken

22 Aug 2015 8:39 #16755

One way is to add the following lines just before the line with CONTAINS in your module, as a replacement for the two preceding lines of code:

  integer, parameter :: rows_acsr_lib   = 14
  type(acsr), dimension(1:rows_acsr_lib) :: acsr_lib = (/ &
    acsr('Gopher', 6,  2.36, 1, 2.40,  26.20,  4.40,  30.60, 7.08,  1.093), &
    acsr('Weasel', 6,  2.59, 1, 2.60,  31.60,  5.30,  36.90, 7.77,  0.908), &
    acsr('Ferret', 6,  3.00, 1, 3.00,  42.40,  7.10,  49.50, 9.00,  0.676), &
    acsr('Rabbit', 6,  3.35, 1, 3.40,  52.90,  8.80,  61.70, 10.05, 0.542), &
    acsr('Horse',  12, 2.79, 7, 2.80,  73.40, 42.80, 116.20, 13.95, 0.393), &
    acsr('Dog',    6,  4.72, 7, 1.60, 105.00, 13.60, 118.50, 14.15, 0.273), &
    acsr('Tiger',  30, 2.36, 7, 2.40, 131.20, 30.60, 161.90, 16.52, 0.220), &
    acsr('Wolf',   30, 2.59, 7, 2.60, 158.10, 36.90, 194.90, 18.13, 0.182), &
    acsr('Dingo',  18, 3.35, 1, 3.40, 158.70,  8.80, 167.50, 16.75, 0.181), &
    acsr('Lynx',   30, 2.79, 7, 2.80, 183.40, 42.80, 226.20, 19.53, 0.157), &
    acsr('Caracal',18, 3.61, 1, 3.60, 184.20, 10.20, 194.50, 18.05, 0.156), &
    acsr('Jaguar', 18, 3.86, 1, 3.90, 210.60, 11.70, 222.30, 19.30, 0.137), &
    acsr('Panther',30, 3.00, 7, 3.00, 212.10, 49.50, 261.50, 21.00, 0.136), &
    acsr('Zebra',  54, 3.18, 7, 3.20, 428.90, 55.60, 484.50, 28.62, 0.067) /)

I have chosen to make rows_acsr_lib a parameter and acsr_lib an array variable, but you can change these as you please.

22 Aug 2015 9:18 #16756

Excellent mecej4 - thank you.

Ken

Please login to reply.