title: Fortran Modules and Global Variables
body: <p>I'm trying to create a data structure accessible globally to the main program and all subroutines. The data structure is built from reading some .dat files. </p>
  
  <p>This kind of global accessibility seems appropriate for a module. So far my module solution includes: 1) define the data type globally; 2) include (contain) a bunch of subroutines in the module to open/read the .dat files; and 3) construct the data type from the .dat files.</p>
  
  <p>Ideally, I would like to construct this data structure ONCE within the module, and then have this single data structure globally accessible. I do NOT want to open/read the .dat files every time I call the module procedures.</p>
  
  <p>For example. Is there a way to declare the data structure as a global variable from the main program, and then call the module procedures to build the data structure once?</p>
  
  <p>@Ross. Source code:</p>
  
  <pre><code>module DataTypeModule
  
    implicit none
  
    type :: DatCube
        integer :: NGrid(4)
        double precision, allocatable :: tgrid(:)
    end type DatCube
  
    contains
  
    subroutine DataArraySizes(NGrd)
      implicit none
      integer, intent(out) :: NGrd(4)
      open(unit=15, file='./Data/DataHeader.txt', status='old')
      read(15,*) NGrd(1)
      read(15,*) NGrd(2)
      read(15,*) NGrd(3)
      read(15,*) NGrd(4)
      close(15)
    end subroutine DataArraySizes
  
    subroutine DataTGrd(NGrd,tgrd)
      implicit none
      integer, intent(in) :: NGrd(4)
      double precision, intent(out) :: tgrd(NGrd(1))
      open(unit=16, file='./Data/tgrid.dat', status='old')
      read(16,*) tgrd
      close(16)
    end subroutine DataTGrd
  
    subroutine ConstructDataCube(DataCube)
      implicit none
      type(DatCube), Intent(out) :: DataCube
  
      integer, allocatable :: NGrd(:)
      double precision, allocatable :: tgrd(:)
  
      allocate( NGrd(4) )
      call DataArraySizes(NGrd)
      DataCube%NGrid = NGrd
  
      allocate( tgrd(NGrd(1)),DataCube%tgrid(NGrd(1)) )
      call DataTGrd(NGrd,tgrd)
      DataCube%tgrid = tgrd
  
      deallocate( NGrd,tgrd )
  
      return
    end
  
  end module DataTypeModule
  
  program main
    use DatatypeModule
    implicit none
    double precision :: arg1,out1(4)
    type(DatCube) :: DataCube
  
    call ConstructDataCube(DataCube)
  
    call subrtn1(arg1,out1)
  
    stop
  end
  
  
  subroutine subrtn1(arg1,out1)
    use DataTypeModule
    implicit none
    double precision, Intent(in)  :: arg1
    double precision, Intent(out) :: out1(4)
    type(DatCube) :: DataCube
  
    out1 = DataCube%NGrid
  
    return
  end
  </code></pre>