LCOV - code coverage report
Current view: top level - ionosphere/waccmx - amie_module.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 430 0.0 %
Date: 2025-03-14 01:26:08 Functions: 0 7 0.0 %

          Line data    Source code
       1             : module amie_module
       2             :   !
       3             :   ! Module used to read data from the AMIE outputs (POT,mean energy,
       4             :   !   and energy flux).
       5             :   !
       6             : 
       7             :   use shr_kind_mod,   only: r8 => shr_kind_r8, cl => shr_kind_cl
       8             :   use cam_logfile,    only: iulog
       9             :   use spmd_utils,     only: masterproc
      10             :   use edyn_maggrid,   only: nmlat, nmlonp1
      11             :   use edyn_maggrid,   only: ylonm     ! magnetic latitudes (nmlat) (radians)
      12             :   use edyn_maggrid,   only: ylatm     ! magnetic longtitudes (nmlonp1) (radians)
      13             :   use cam_pio_utils,  only: cam_pio_openfile, cam_pio_closefile
      14             :   use pio,            only: pio_inq_dimid, pio_inquire_dimension
      15             :   use pio,            only: pio_inquire, pio_inq_varid
      16             :   use pio,            only: file_desc_t, pio_noerr, pio_nowrite, pio_get_var
      17             :   use utils_mod,      only: check_ncerr, check_alloc, boxcar_ave
      18             :   use edyn_mpi,       only: ntask, mytid
      19             :   use edyn_params,    only: pi, dtr, rtd
      20             :   use input_data_utils, only: time_coordinate
      21             : 
      22             :   implicit none
      23             : 
      24             :   private
      25             :   public :: init_amie
      26             :   public :: getamie
      27             : 
      28             :   ! Define parameters for AMIE input data file:
      29             :   integer, parameter ::  &
      30             :        ithmx = 55,       & ! maximum number of latitudes of AMIE data
      31             :        jmxm = 2*ithmx-1, & ! maximum number of global latitudes
      32             :        lonmx = 36          ! maximum number of longitudes of AMIE data
      33             :   integer :: lonp1,latp1
      34             :   !
      35             :   ! Define fields for AMIE input data file:
      36             :   ! electric potential in Volt
      37             :   ! mean energy in KeV
      38             :   ! energy flux in W/m^2
      39             :   ! cusplat_nh_input(sh) and cuspmlt_nh_input(sh) are
      40             :   !   AMIE cusp latitude and MLT in NH and SH
      41             :   ! hpi_nh(sh) are AMIE hemi-integrated power
      42             :   ! pcp_nh(sh) are AMIE polar-cap potential drop
      43             :   ! Time interpolated AMIE outputs with suffix _amie
      44             :   !
      45             :   real(r8), allocatable, dimension(:,:,:), save :: & ! (lonp1,latp1,ntimes)
      46             :        pot_nh_input, pot_sh_input,                   &
      47             :        ekv_nh_input, ekv_sh_input,                   &
      48             :        efx_nh_input, efx_sh_input
      49             :   real(r8), allocatable, dimension(:,:), save ::           &  ! (lonp1,latp1)
      50             :        pot_nh_amie, pot_sh_amie, ekv_nh_amie, ekv_sh_amie, &
      51             :        efx_nh_amie, efx_sh_amie
      52             :   integer,  allocatable, dimension(:), save ::                 & ! (ntimes)
      53             :        year, month, day, jday
      54             :   real(r8), allocatable, dimension(:), save ::                 & ! (ntimes)
      55             :        cusplat_nh_input, cuspmlt_nh_input, hpi_nh_input,          &
      56             :        pcp_nh_input, amie_nh_ut,                                &
      57             :        cusplat_sh_input, cuspmlt_sh_input, hpi_sh_input,          &
      58             :        pcp_sh_input, amie_sh_ut
      59             :   real(r8) ::                                                  &
      60             :        cusplat_nh_amie, cuspmlt_nh_amie, cusplat_sh_amie,      &
      61             :        cuspmlt_sh_amie, hpi_sh_amie, hpi_nh_amie, pcp_sh_amie, &
      62             :        pcp_nh_amie
      63             :   !
      64             :   type(file_desc_t) :: ncid_nh
      65             :   type(file_desc_t) :: ncid_sh
      66             : 
      67             :   character(len=cl), allocatable :: amienh_files(:)
      68             :   character(len=cl), allocatable :: amiesh_files(:)
      69             :   integer :: num_files, file_ndx
      70             : 
      71             :   type(time_coordinate) :: time_coord_nh
      72             :   type(time_coordinate) :: time_coord_sh
      73             : 
      74             : contains
      75             : 
      76             :   !-----------------------------------------------------------------------
      77           0 :   subroutine init_amie(amienh_list,amiesh_list)
      78             : 
      79             :     character(len=*),intent(in) :: amienh_list(:)
      80             :     character(len=*),intent(in) :: amiesh_list(:)
      81             : 
      82             :     integer :: n, nfiles
      83             : 
      84           0 :     nfiles = min( size(amienh_list), size(amiesh_list) )
      85           0 :     num_files = 0
      86             : 
      87           0 :     count_files: do n = 1,nfiles
      88           0 :        if (len_trim(amienh_list(n))<1 .or. len_trim(amiesh_list(n))<1 .or. &
      89           0 :            trim(amienh_list(n))=='NONE' .or. trim(amiesh_list(n))=='NONE') then
      90             :           exit count_files
      91             :        else
      92           0 :           num_files = num_files + 1
      93             :        end if
      94             :     end do count_files
      95             : 
      96           0 :     allocate(amienh_files(num_files), amiesh_files(num_files))
      97           0 :     amienh_files(:num_files) = amienh_list(:num_files)
      98           0 :     amiesh_files(:num_files) = amiesh_list(:num_files)
      99           0 :     file_ndx = 1
     100           0 :     call open_files()
     101             : 
     102           0 :   end subroutine init_amie
     103             : 
     104             :   !-----------------------------------------------------------------------
     105           0 :   subroutine rdamie_nh(amienh)
     106             :     !
     107             :     ! Read AMIE data for the northern hemisphere from amienh
     108             :     !
     109             : 
     110             :     ! Dummy argument
     111             :     character(len=*), intent(in) :: amienh
     112             :     ! Local variables:
     113             :     integer                      :: istat, ntimes, ndims, nvars, ngatts
     114             :     integer                      :: idunlim, ier
     115             :     integer                      :: id_lon, id_lat, id_time
     116             :     integer                      :: idv_year, idv_mon, idv_day, idv_jday
     117             :     integer                      :: idv_ut, idv_cusplat, idv_cuspmlt
     118             :     integer                      :: idv_hpi, idv_pcp
     119             :     character(len=*), parameter  :: subname = 'rdamie_nh'
     120             :     !
     121           0 :     if (masterproc) then
     122           0 :        write(iulog, "(/,72('-'))")
     123           0 :        write(iulog, "(a,': read AMIE data for northern hemisphere:')") subname
     124             :     end if
     125             :     !
     126             :     ! Open netcdf file:
     127           0 :     call cam_pio_openfile(ncid_nh, amienh, pio_nowrite)
     128             :     !
     129             :     ! Get AMIE grid dimension:
     130           0 :     istat = pio_inq_dimid(ncid_nh, 'lon', id_lon)
     131           0 :     istat = pio_inquire_dimension(ncid_nh, id_lon, len=lonp1)
     132           0 :     call check_ncerr(istat, subname, 'AMIE longitude dimension')
     133             : 
     134           0 :     istat = pio_inq_dimid(ncid_nh, 'lat', id_lat)
     135           0 :     istat = pio_inquire_dimension(ncid_nh, id_lat, len=latp1)
     136           0 :     call check_ncerr(istat, subname, 'AMIE latitude dimension')
     137             : 
     138           0 :     call time_coord_nh%initialize( amienh, set_weights=.false. )
     139             : 
     140             :     !
     141             :     ! Get time dimension:
     142           0 :     istat = pio_inquire(ncid_nh, unlimiteddimid=id_time)
     143           0 :     istat = pio_inquire_dimension(ncid_nh, id_time, len=ntimes)
     144           0 :     call check_ncerr(istat, subname, 'AMIE time dimension')
     145             :     !
     146             :     ! Search for requested AMIE output fields
     147           0 :     istat = pio_inquire(ncid_nh, ndims, nvars, ngatts, idunlim)
     148             :     !
     149             :     ! Get 1-D AMIE fields (ntimes)
     150           0 :     if (.not. allocated(year)) then
     151           0 :        allocate(year(ntimes), stat=ier)
     152           0 :        call check_alloc(ier, subname, 'year', ntimes=ntimes)
     153             :     end if
     154           0 :     istat = pio_inq_varid(ncid_nh, 'year', idv_year)
     155           0 :     call check_ncerr(istat, subname, 'AMIE year id')
     156           0 :     istat = pio_get_var(ncid_nh, idv_year, year)
     157           0 :     call check_ncerr(istat, subname, 'AMIE year')
     158             : 
     159           0 :     if (.not. allocated(month)) then
     160           0 :        allocate(month(ntimes), stat=ier)
     161           0 :        call check_alloc(ier, subname, 'month', ntimes=ntimes)
     162             :     end if
     163           0 :     istat = pio_inq_varid(ncid_nh, 'month', idv_mon)
     164           0 :     call check_ncerr(istat, subname, 'AMIE month id')
     165           0 :     istat = pio_get_var(ncid_nh, idv_mon, month)
     166           0 :     call check_ncerr(istat, subname, 'AMIE month')
     167           0 :     if (.not. allocated(day)) then
     168           0 :        allocate(day(ntimes), stat=ier)
     169           0 :        call check_alloc(ier, subname, 'day', ntimes=ntimes)
     170             :     end if
     171           0 :     istat = pio_inq_varid(ncid_nh, 'day', idv_day)
     172           0 :     call check_ncerr(istat, subname, 'AMIE day id')
     173           0 :     istat = pio_get_var(ncid_nh, idv_day, day)
     174           0 :     call check_ncerr(istat, subname, 'AMIE day')
     175             : 
     176           0 :     if (.not. allocated(jday)) then
     177           0 :        allocate(jday(ntimes), stat=ier)
     178           0 :        call check_alloc(ier, subname, 'jday', ntimes=ntimes)
     179             :     end if
     180           0 :     istat = pio_inq_varid(ncid_nh, 'jday', idv_jday)
     181           0 :     call check_ncerr(istat, subname, 'AMIE jday id')
     182           0 :     istat = pio_get_var(ncid_nh, idv_jday, jday)
     183           0 :     call check_ncerr(istat, subname, 'AMIE jday')
     184             :     !
     185             :     ! Allocate 1-d fields:
     186           0 :     if (.not. allocated(amie_nh_ut)) then
     187           0 :        allocate(amie_nh_ut(ntimes), stat=ier)
     188           0 :        call check_alloc(ier, subname, 'amie_nh_ut', ntimes=ntimes)
     189             :     end if
     190           0 :     if (.not. allocated(cusplat_nh_input)) then
     191           0 :        allocate(cusplat_nh_input(ntimes), stat=ier)
     192           0 :        call check_alloc(ier, subname, 'cusplat_nh_input', ntimes=ntimes)
     193             :     end if
     194           0 :     if (.not. allocated(cuspmlt_nh_input)) then
     195           0 :        allocate(cuspmlt_nh_input(ntimes), stat=ier)
     196           0 :        call check_alloc(ier, subname, 'cuspmlt_nh_input', ntimes=ntimes)
     197             :     end if
     198           0 :     if (.not. allocated(hpi_nh_input)) then
     199           0 :        allocate(hpi_nh_input(ntimes), stat=ier)
     200           0 :        call check_alloc(ier, subname, 'hpi_nh_input', ntimes=ntimes)
     201             :     end if
     202           0 :     if (.not. allocated(pcp_nh_input)) then
     203           0 :        allocate(pcp_nh_input(ntimes), stat=ier)
     204           0 :        call check_alloc(ier, subname, 'pcp_nh_input', ntimes=ntimes)
     205             :     end if
     206             :     !
     207             :     ! Get ut
     208           0 :     istat = pio_inq_varid(ncid_nh, 'ut', idv_ut)
     209           0 :     call check_ncerr(istat, subname, 'AMIE ut id')
     210           0 :     istat = pio_get_var(ncid_nh, idv_ut, amie_nh_ut)
     211           0 :     call check_ncerr(istat, subname, 'AMIE ut')
     212             :     !
     213             :     ! Get HPI
     214           0 :     istat = pio_inq_varid(ncid_nh, 'hpi', idv_hpi)
     215           0 :     call check_ncerr(istat, subname, 'AMIE hpi id')
     216           0 :     istat = pio_get_var(ncid_nh, idv_hpi, hpi_nh_input)
     217           0 :     call check_ncerr(istat, subname, 'AMIE hpi')
     218             :     !
     219             :     ! Get PCP
     220           0 :     istat = pio_inq_varid(ncid_nh, 'pcp', idv_pcp)
     221           0 :     call check_ncerr(istat, subname, 'AMIE pcp id')
     222           0 :     istat = pio_get_var(ncid_nh, idv_pcp, pcp_nh_input)
     223           0 :     call check_ncerr(istat, subname, 'AMIE pcp')
     224             :     !
     225             :     ! Get cusplat
     226           0 :     istat = pio_inq_varid(ncid_nh, 'cusplat', idv_cusplat)
     227           0 :     call check_ncerr(istat, subname, 'AMIE cusplat id')
     228           0 :     istat = pio_get_var(ncid_nh, idv_cusplat, cusplat_nh_input)
     229           0 :     call check_ncerr(istat, subname, 'AMIE cusplat')
     230             :     !
     231             :     ! Get cuspmlt
     232           0 :     istat = pio_inq_varid(ncid_nh, 'cuspmlt', idv_cuspmlt)
     233           0 :     call check_ncerr(istat, subname, 'AMIE cuspmlt id')
     234           0 :     istat = pio_get_var(ncid_nh, idv_cuspmlt, cuspmlt_nh_input)
     235           0 :     call check_ncerr(istat, subname, 'AMIE cuspmlt')
     236             :     !
     237             :     ! Allocate 2-d fields:
     238           0 :     if (.not. allocated(pot_nh_amie)) then
     239           0 :        allocate(pot_nh_amie(lonp1, latp1), stat=ier)
     240           0 :        call check_alloc(ier, subname, 'pot_nh_amie', lonp1=lonp1, latp1=latp1)
     241             :     end if
     242           0 :     if (.not. allocated(ekv_nh_amie)) then
     243           0 :        allocate(ekv_nh_amie(lonp1, latp1), stat=ier)
     244           0 :        call check_alloc(ier, subname, 'ekv_nh_amie', lonp1=lonp1, latp1=latp1)
     245             :     end if
     246           0 :     if (.not. allocated(efx_nh_amie)) then
     247           0 :        allocate(efx_nh_amie(lonp1, latp1), stat=ier)
     248           0 :        call check_alloc(ier, subname, 'efx_nh_amie', lonp1=lonp1, latp1=latp1)
     249             :     end if
     250             :     !
     251             :     ! Allocate 3-d fields:
     252           0 :     if (.not. allocated(pot_nh_input)) then
     253           0 :        allocate(pot_nh_input(lonp1, latp1, 2), stat=ier)
     254             :        call check_alloc(ier, subname, 'pot_nh_input', &
     255           0 :             lonp1=lonp1, latp1=latp1, ntimes=ntimes)
     256             :     end if
     257           0 :     if (.not. allocated(ekv_nh_input)) then
     258           0 :        allocate(ekv_nh_input(lonp1, latp1, 2), stat=ier)
     259             :        call check_alloc(ier, subname, 'ekv_nh_input', &
     260           0 :             lonp1=lonp1, latp1=latp1, ntimes=ntimes)
     261             :     end if
     262           0 :     if (.not. allocated(efx_nh_input)) then
     263           0 :        allocate(efx_nh_input(lonp1, latp1, 2), stat=ier)
     264             :        call check_alloc(ier, subname, 'efx_nh_input', &
     265           0 :             lonp1=lonp1, latp1=latp1, ntimes=ntimes)
     266             :     end if
     267           0 :   end subroutine rdamie_nh
     268             : 
     269             :   !-----------------------------------------------------------------------
     270           0 :   subroutine rdamie_sh(amiesh)
     271             :     !
     272             :     ! Read AMIE data for the southern hemisphere from amiesh
     273             :     !
     274             : 
     275             :     ! Dummy argument
     276             :     character(len=*), intent(in) :: amiesh
     277             :     ! Local variables:
     278             :     integer                      :: istat, ntimes, ndims, nvars, ngatts, ier
     279             :     integer                      :: idunlim
     280             :     integer                      :: id_lon, id_lat, id_time
     281             :     integer                      :: idv_year, idv_mon, idv_day, idv_jday
     282             :     integer                      :: idv_ut
     283             :     integer                      :: idv_cusplat, idv_cuspmlt, idv_hpi, idv_pcp
     284             :     character(len=*), parameter  :: subname = 'rdamie_sh'
     285             :     !
     286           0 :     if (masterproc) then
     287           0 :        write(iulog, "(/, 72('-'))")
     288           0 :        write(iulog, "(a, ': read AMIE data for southern hemisphere:')") subname
     289             :     end if
     290             :     !
     291             :     ! Open netcdf file:
     292           0 :     call cam_pio_openfile(ncid_sh, amiesh, pio_nowrite)
     293             :     !
     294             :     ! Get AMIE grid dimension:
     295           0 :     istat = pio_inq_dimid(ncid_sh, 'lon', id_lon)
     296           0 :     istat = pio_inquire_dimension(ncid_sh, id_lon, len=lonp1)
     297           0 :     call check_ncerr(istat, subname, 'AMIE longitude dimension')
     298             : 
     299           0 :     istat = pio_inq_dimid(ncid_sh, 'lat', id_lat)
     300           0 :     istat = pio_inquire_dimension(ncid_sh, id_lat, len=latp1)
     301           0 :     call check_ncerr(istat, subname, 'AMIE latitude dimension')
     302             : 
     303           0 :     call time_coord_sh%initialize( amiesh, set_weights=.false. )
     304             : 
     305             :     !
     306             :     ! Get time dimension:
     307           0 :     istat = pio_inquire(ncid_sh, unlimiteddimid=id_time)
     308           0 :     istat = pio_inquire_dimension(ncid_sh, id_time, len=ntimes)
     309           0 :     call check_ncerr(istat, subname, 'AMIE time dimension')
     310             :     !
     311             :     ! Search for requested AMIE output fields
     312           0 :     istat = pio_inquire(ncid_sh, ndims, nvars, ngatts, idunlim)
     313             :     !
     314             :     ! Get 1-D AMIE fields (ntimes)
     315           0 :     if (.not. allocated(year)) then
     316           0 :        allocate(year(ntimes), stat=ier)
     317           0 :        call check_alloc(ier, subname, 'year', ntimes=ntimes)
     318             :     end if
     319           0 :     istat = pio_inq_varid(ncid_sh, 'year', idv_year)
     320           0 :     call check_ncerr(istat, subname, 'AMIE year id')
     321           0 :     istat = pio_get_var(ncid_sh, idv_year, year)
     322           0 :     call check_ncerr(istat, subname, 'AMIE year')
     323             : 
     324           0 :     if (.not. allocated(month)) then
     325           0 :        allocate(month(ntimes), stat=ier)
     326           0 :        call check_alloc(ier, subname, 'month', ntimes=ntimes)
     327             :     end if
     328           0 :     istat = pio_inq_varid(ncid_sh, 'month', idv_mon)
     329           0 :     call check_ncerr(istat, subname, 'AMIE month id')
     330           0 :     istat = pio_get_var(ncid_sh, idv_mon, month)
     331           0 :     call check_ncerr(istat, subname, 'AMIE month')
     332           0 :     if (.not. allocated(day)) then
     333           0 :        allocate(day(ntimes), stat=ier)
     334           0 :        call check_alloc(ier, subname, 'day', ntimes=ntimes)
     335             :     end if
     336           0 :     istat = pio_inq_varid(ncid_sh, 'day', idv_day)
     337           0 :     call check_ncerr(istat, subname, 'AMIE day id')
     338           0 :     istat = pio_get_var(ncid_sh, idv_day, day)
     339           0 :     call check_ncerr(istat, subname, 'AMIE day')
     340             : 
     341           0 :     if (.not. allocated(jday)) then
     342           0 :        allocate(jday(ntimes), stat=ier)
     343           0 :        call check_alloc(ier, subname, 'jday', ntimes=ntimes)
     344             :     end if
     345           0 :     istat = pio_inq_varid(ncid_sh, 'jday', idv_jday)
     346           0 :     call check_ncerr(istat, subname, 'AMIE jday id')
     347           0 :     istat = pio_get_var(ncid_sh, idv_jday, jday)
     348           0 :     call check_ncerr(istat, subname, 'AMIE jday')
     349             :     !
     350             :     ! Allocate 1-d fields:
     351           0 :     if (.not. allocated(amie_sh_ut)) then
     352           0 :        allocate(amie_sh_ut(ntimes), stat=ier)
     353           0 :        call check_alloc(ier, subname, 'amie_sh_ut', ntimes=ntimes)
     354             :     end if
     355           0 :     if (.not. allocated(cusplat_sh_input)) then
     356           0 :        allocate(cusplat_sh_input(ntimes), stat=ier)
     357           0 :        call check_alloc(ier, subname, 'cusplat_sh_input', ntimes=ntimes)
     358             :     end if
     359           0 :     if (.not. allocated(cuspmlt_sh_input)) then
     360           0 :        allocate(cuspmlt_sh_input(ntimes), stat=ier)
     361           0 :        call check_alloc(ier, subname, 'cuspmlt_sh_input', ntimes=ntimes)
     362             :     end if
     363           0 :     if (.not. allocated(hpi_sh_input)) then
     364           0 :        allocate(hpi_sh_input(ntimes), stat=ier)
     365           0 :        call check_alloc(ier, subname, 'hpi_sh_input', ntimes=ntimes)
     366             :     end if
     367           0 :     if (.not. allocated(pcp_sh_input)) then
     368           0 :        allocate(pcp_sh_input(ntimes), stat=ier)
     369           0 :        call check_alloc(ier, subname, 'pcp_sh_input', ntimes=ntimes)
     370             :     end if
     371             :     !
     372             :     ! Get ut
     373           0 :     istat = pio_inq_varid(ncid_sh, 'ut', idv_ut)
     374           0 :     call check_ncerr(istat, subname, 'AMIE ut id')
     375           0 :     istat = pio_get_var(ncid_sh, idv_ut, amie_sh_ut)
     376           0 :     call check_ncerr(istat, subname, 'AMIE ut')
     377             :     !
     378             :     ! Get HPI
     379           0 :     istat = pio_inq_varid(ncid_sh, 'hpi', idv_hpi)
     380           0 :     call check_ncerr(istat, subname, 'AMIE hpi id')
     381           0 :     istat = pio_get_var(ncid_sh, idv_hpi, hpi_sh_input)
     382           0 :     call check_ncerr(istat, subname, 'AMIE hpi')
     383             :     !
     384             :     ! Get PCP
     385           0 :     istat = pio_inq_varid(ncid_sh, 'pcp', idv_pcp)
     386           0 :     call check_ncerr(istat, subname, 'AMIE pcp id')
     387           0 :     istat = pio_get_var(ncid_sh, idv_pcp, pcp_sh_input)
     388           0 :     call check_ncerr(istat, subname, 'AMIE pcp')
     389             :     !
     390             :     ! Get cusplat
     391           0 :     istat = pio_inq_varid(ncid_sh, 'cusplat', idv_cusplat)
     392           0 :     call check_ncerr(istat, subname, 'AMIE cusplat id')
     393           0 :     istat = pio_get_var(ncid_sh, idv_cusplat, cusplat_sh_input)
     394           0 :     call check_ncerr(istat, subname, 'AMIE cusplat')
     395             :     !
     396             :     ! Get cuspmlt
     397           0 :     istat = pio_inq_varid(ncid_sh, 'cuspmlt', idv_cuspmlt)
     398           0 :     call check_ncerr(istat, subname, 'AMIE cuspmlt id')
     399           0 :     istat = pio_get_var(ncid_sh, idv_cuspmlt, cuspmlt_sh_input)
     400           0 :     call check_ncerr(istat, subname, 'AMIE cuspmlt')
     401             :     !
     402             :     ! Allocate 2-d fields:
     403           0 :     if (.not. allocated(pot_sh_amie)) then
     404           0 :        allocate(pot_sh_amie(lonp1, latp1), stat=ier)
     405           0 :        call check_alloc(ier, subname, 'pot_sh_amie', lonp1=lonp1, latp1=latp1)
     406             :     end if
     407           0 :     if (.not. allocated(ekv_sh_amie)) then
     408           0 :        allocate(ekv_sh_amie(lonp1, latp1), stat=ier)
     409           0 :        call check_alloc(ier, subname, 'ekv_sh_amie', lonp1=lonp1, latp1=latp1)
     410             :     end if
     411           0 :     if (.not. allocated(efx_sh_amie)) then
     412           0 :        allocate(efx_sh_amie(lonp1, latp1), stat=ier)
     413           0 :        call check_alloc(ier, subname, 'efx_sh_amie', lonp1=lonp1, latp1=latp1)
     414             :     end if
     415             :     !
     416             :     ! Allocate 3-d fields:
     417           0 :     if (.not. allocated(pot_sh_input)) then
     418           0 :        allocate(pot_sh_input(lonp1, latp1, 2), stat=ier)
     419             :        call check_alloc(ier, subname, 'pot_sh_input', &
     420           0 :             lonp1=lonp1, latp1=latp1, ntimes=ntimes)
     421             :     end if
     422           0 :     if (.not. allocated(ekv_sh_input)) then
     423           0 :        allocate(ekv_sh_input(lonp1, latp1, 2), stat=ier)
     424             :        call check_alloc(ier, subname, 'ekv_sh_input', &
     425           0 :             lonp1=lonp1, latp1=latp1, ntimes=ntimes)
     426             :     end if
     427           0 :     if (.not. allocated(efx_sh_input)) then
     428           0 :        allocate(efx_sh_input(lonp1, latp1, 2), stat=ier)
     429             :        call check_alloc(ier, subname, 'efx_sh_input', &
     430           0 :             lonp1=lonp1, latp1=latp1, ntimes=ntimes)
     431             :     end if
     432           0 :   end subroutine rdamie_sh
     433             : 
     434             :   !-----------------------------------------------------------------------
     435           0 :   subroutine update_3d_fields( ncid, offset, kount, pot_3d,ekv_3d,efx_3d )
     436             : 
     437             :     type(file_desc_t), intent(in) :: ncid
     438             :     integer, intent(in)  :: offset(:)
     439             :     integer, intent(in)  :: kount(:)
     440             :     real(r8),intent(out) :: pot_3d(:,:,:)
     441             :     real(r8),intent(out) :: ekv_3d(:,:,:)
     442             :     real(r8),intent(out) :: efx_3d(:,:,:)
     443             : 
     444             : 
     445             :     integer :: istat
     446             :     integer :: idv_pot, idv_ekv, idv_efx
     447             :     character(len=*), parameter :: subname = 'update_3d_fields'
     448             : 
     449             :     !
     450             :     ! Get 3-D fields (lon,lat,ntimes)
     451             :     !
     452             :     ! electric potential
     453           0 :     istat = pio_inq_varid(ncid, 'pot', idv_pot)
     454           0 :     call check_ncerr(istat, subname, 'AMIE pot id')
     455           0 :     istat = pio_get_var(ncid, idv_pot, offset, kount, pot_3d)
     456           0 :     call check_ncerr(istat, subname, 'AMIE pot')
     457             :     !
     458             :     ! mean energy
     459           0 :     istat = pio_inq_varid(ncid, 'ekv', idv_ekv)
     460           0 :     call check_ncerr(istat, subname, 'AMIE ekv id')
     461           0 :     istat = pio_get_var(ncid, idv_ekv, offset, kount, ekv_3d)
     462           0 :     call check_ncerr(istat, subname, 'AMIE ekv')
     463             :     !
     464             :     ! energy flux
     465           0 :     istat = pio_inq_varid(ncid, 'efx', idv_efx)
     466           0 :     call check_ncerr(istat, subname, 'AMIE efx id')
     467           0 :     istat = pio_get_var(ncid, idv_efx, offset, kount, efx_3d)
     468           0 :     call check_ncerr(istat, subname, 'AMIE efx')
     469             : 
     470           0 :   end subroutine update_3d_fields
     471             : 
     472             :   !-----------------------------------------------------------------------
     473           0 :   subroutine getamie(iyear, imo, iday, iutsec, sunlon, iprint,  &
     474           0 :                      iamie, phihm, amie_efxm, amie_kevm, crad)
     475             :     use cam_history_support, only: fillvalue
     476             :     use rgrd_mod,            only: rgrd2
     477             : 
     478             :     !
     479             :     !    Read AMIE outputs from amie_ncfile file, returning electric potential,
     480             :     !    auroral mean energy and energy flux at current date and time,
     481             :     !    and the data is linearly interpolated to the model time
     482             :     !    gl - 12/07/2002
     483             :     !
     484             :     !
     485             :     !    Args:
     486             : 
     487             :     integer,  intent(in)    :: iyear
     488             :     integer,  intent(in)    :: imo
     489             :     integer,  intent(in)    :: iday
     490             :     real(r8), intent(in)    :: sunlon
     491             :     integer,  intent(in)    :: iutsec
     492             :     integer,  intent(in)    :: iprint
     493             :     integer,  intent(out)   :: iamie
     494             :     real(r8), intent(out)   :: phihm(nmlonp1,nmlat)
     495             :     real(r8), intent(out)   :: amie_efxm(nmlonp1,nmlat) ! on geomag grid
     496             :     real(r8), intent(out)   :: amie_kevm(nmlonp1,nmlat) ! on geomag grid
     497             :     real(r8), intent(out)   :: crad(2)
     498             :     !
     499             :     !
     500             :     !     Local:
     501           0 :     real(r8)                    :: potm(lonp1,jmxm)
     502           0 :     real(r8)                    :: efxm(lonp1,jmxm), ekvm(lonp1,jmxm)
     503           0 :     real(r8)                    :: alat(jmxm), alon(lonp1)
     504           0 :     real(r8)                    :: alatm(jmxm), alonm(lonp1)
     505             :     integer                     :: ier, lw, liw, intpol(2)
     506           0 :     integer,  allocatable       :: iw(:)
     507           0 :     real(r8), allocatable       :: w(:)
     508             :     integer                     :: i, j
     509             :     integer                     :: nn, iset1, iset2, m, mp1, n
     510             :     integer                     :: iboxcar
     511             :     real(r8)                    :: f1, f2
     512             :     real(r8)                    :: del, xmlt, dmlat, dlatm, dlonm, dmltm, rot
     513             :     integer                     :: offset(3), kount(3)
     514             :     character(len=*), parameter :: subname = 'getamie'
     515             : 
     516           0 :     phihm = fillvalue
     517           0 :     amie_efxm = fillvalue
     518           0 :     amie_kevm = fillvalue
     519           0 :     crad = fillvalue
     520             : 
     521           0 :     if (iprint > 0 .and. masterproc) then
     522           0 :        write(iulog,"(/,72('-'))")
     523           0 :        write(iulog,"(a,':')") subname
     524             :        write(iulog,"(a,i4,', iday = ',i3,', iutsec = ',i10)")                &
     525           0 :             'Initial requested iyear= ', iyear, iday, iutsec
     526             :     end if
     527             : 
     528           0 :     nn = size(amie_sh_ut)
     529             :     !
     530             :     !     Check times:
     531             :     !
     532             : 
     533           0 :     iamie = 1 - time_coord_sh%times_check()
     534           0 :     check_loop: do while( iamie/=1 )
     535           0 :        if (iamie==2) then
     536           0 :           if (masterproc) then
     537             :              write(iulog, "(a,': Model date prior to AMIE first date:',3I5)")   &
     538           0 :                   subname, year(1), month(1), day(1)
     539             :           end if
     540           0 :           return
     541             :        end if
     542             : 
     543           0 :        if (iamie==0) then
     544           0 :           if (masterproc) then
     545             :              write(iulog, "(a,': Model date beyond the AMIE last Data:',3I5)")  &
     546           0 :                   subname, year(nn), month(nn), day(nn)
     547             :           end if
     548             : 
     549           0 :           if (file_ndx<num_files) then
     550           0 :              file_ndx = file_ndx+1
     551           0 :              call close_files()
     552           0 :              call open_files()
     553           0 :              iamie = 1 - time_coord_sh%times_check()
     554             :           else
     555             :              return
     556             :           end if
     557             :        end if
     558             :     end do check_loop
     559             : 
     560             : !     get SH AMIE data
     561           0 :     pot_sh_amie(:,:) = 0._r8
     562           0 :     ekv_sh_amie(:,:) = 0._r8
     563           0 :     efx_sh_amie(:,:) = 0._r8
     564           0 :     cusplat_sh_amie = 0._r8
     565           0 :     cuspmlt_sh_amie = 0._r8
     566           0 :     hpi_sh_amie = 0._r8
     567           0 :     pcp_sh_amie = 0._r8
     568             :     !
     569             : 
     570           0 :     iboxcar = 0
     571             : 
     572           0 :     call time_coord_sh%advance()
     573             : 
     574           0 :     iset1 = time_coord_sh%indxs(1)
     575           0 :     iset2 = time_coord_sh%indxs(2)
     576             : 
     577           0 :     f1 = time_coord_sh%wghts(1)
     578           0 :     f2 = time_coord_sh%wghts(2)
     579             : 
     580           0 :     cusplat_sh_amie = (f1*cusplat_sh_input(iset1) + &
     581           0 :                        f2*cusplat_sh_input(iset2))
     582           0 :     cuspmlt_sh_amie = (f1*cuspmlt_sh_input(iset1) + &
     583           0 :                        f2*cuspmlt_sh_input(iset2))
     584           0 :     hpi_sh_amie = (f1*hpi_sh_input(iset1) + f2*hpi_sh_input(iset2))
     585           0 :     pcp_sh_amie = (f1*pcp_sh_input(iset1) + f2*pcp_sh_input(iset2))
     586             : 
     587           0 :     offset = (/1,1,iset1/)
     588           0 :     kount = (/lonp1,latp1,2/)
     589             : 
     590           0 :     call update_3d_fields( ncid_sh, offset, kount, pot_sh_input,ekv_sh_input,efx_sh_input )
     591           0 :     if (iboxcar == 0) then
     592           0 :        pot_sh_amie(:,:) = (f1*pot_sh_input(:,:,1) + &
     593           0 :                            f2*pot_sh_input(:,:,2))
     594           0 :        ekv_sh_amie(:,:) = (f1*ekv_sh_input(:,:,1) + &
     595           0 :                            f2*ekv_sh_input(:,:,2))
     596           0 :        efx_sh_amie(:,:) = (f1*efx_sh_input(:,:,1) + &
     597           0 :                            f2*efx_sh_input(:,:,2))
     598             :     else
     599             :        call boxcar_ave(pot_sh_input,pot_sh_amie,lonp1,latp1, &
     600           0 :             nn,iset1,iboxcar)
     601             :        call boxcar_ave(efx_sh_input,efx_sh_amie,lonp1,latp1, &
     602           0 :             nn,iset1,iboxcar)
     603             :        call boxcar_ave(ekv_sh_input,ekv_sh_amie,lonp1,latp1, &
     604           0 :             nn,iset1,iboxcar)
     605             :     end if
     606             : !
     607             : !     get NH AMIE data
     608           0 :     pot_nh_amie(:,:) = 0._r8
     609           0 :     ekv_nh_amie(:,:) = 0._r8
     610           0 :     efx_nh_amie(:,:) = 0._r8
     611           0 :     cusplat_nh_amie = 0._r8
     612           0 :     cuspmlt_nh_amie = 0._r8
     613           0 :     hpi_nh_amie = 0._r8
     614           0 :     pcp_nh_amie = 0._r8
     615             : 
     616           0 :     iboxcar = 0
     617             : 
     618           0 :     call time_coord_nh%advance()
     619             : 
     620           0 :     iset1 = time_coord_nh%indxs(1)
     621           0 :     iset2 = time_coord_nh%indxs(2)
     622             : 
     623           0 :     f1 = time_coord_nh%wghts(1)
     624           0 :     f2 = time_coord_nh%wghts(2)
     625             : 
     626           0 :     cusplat_nh_amie = (f1*cusplat_nh_input(iset1) + &
     627           0 :                        f2*cusplat_nh_input(iset2))
     628           0 :     cuspmlt_nh_amie = (f1*cuspmlt_nh_input(iset1) + &
     629           0 :                        f2*cuspmlt_nh_input(iset2))
     630           0 :     hpi_nh_amie = (f1*hpi_nh_input(iset1) + f2*hpi_nh_input(iset2))
     631           0 :     pcp_nh_amie = (f1*pcp_nh_input(iset1) + f2*pcp_nh_input(iset2))
     632             : 
     633           0 :     offset = (/1,1,iset1/)
     634           0 :     kount = (/lonp1,latp1,2/)
     635             : 
     636           0 :     call update_3d_fields( ncid_nh, offset, kount, pot_nh_input,ekv_nh_input,efx_nh_input )
     637             : 
     638           0 :     if (iboxcar == 0) then
     639           0 :        pot_nh_amie(:,:) = (f1*pot_nh_input(:,:,1) + &
     640           0 :                            f2*pot_nh_input(:,:,2))
     641           0 :        ekv_nh_amie(:,:) = (f1*ekv_nh_input(:,:,1) + &
     642           0 :                            f2*ekv_nh_input(:,:,2))
     643           0 :        efx_nh_amie(:,:) = (f1*efx_nh_input(:,:,1) + &
     644           0 :                            f2*efx_nh_input(:,:,2))
     645             :     else
     646             :        call boxcar_ave(pot_nh_input,pot_nh_amie,lonp1,latp1, &
     647           0 :             nn,iset1,iboxcar)
     648             :        call boxcar_ave(efx_nh_input,efx_nh_amie,lonp1,latp1, &
     649           0 :             nn,iset1,iboxcar)
     650             :        call boxcar_ave(ekv_nh_input,ekv_nh_amie,lonp1,latp1, &
     651           0 :             nn,iset1,iboxcar)
     652             :     end if
     653             :     !
     654             :     !     The OLTMAX latitude also defines the co-latitude theta0, which in
     655             :     !     turn determines crit1(+2.5deg) and crit2(-12.5deg) which are used
     656             :     !     in TIE-GCM as the boundaries of the polar cap and the region of
     657             :     !     influence of the high-lat potential versus the low-lat dynamo potential
     658             :     !     Define this latitude to be between 70 and 77.5 degrees
     659             :     !
     660           0 :     if (cusplat_sh_amie > 75.0_r8) then
     661           0 :        cusplat_sh_amie = 75.0_r8
     662           0 :        cuspmlt_sh_amie = 11._r8
     663             :     end if
     664           0 :     if (cusplat_sh_amie < 60.0_r8) then
     665           0 :        cusplat_sh_amie = 60.0_r8
     666           0 :        cuspmlt_sh_amie = 11._r8
     667             :     end if
     668           0 :     if (cusplat_nh_amie > 75.0_r8) then
     669           0 :        cusplat_nh_amie = 75.0_r8
     670           0 :        cuspmlt_nh_amie = 11._r8
     671             :     end if
     672           0 :     if (cusplat_nh_amie < 60.0_r8) then
     673           0 :        cusplat_nh_amie = 60.0_r8
     674           0 :        cuspmlt_nh_amie = 11._r8
     675             :     end if
     676             :     !     cusplat_nh_amie = amin1(65.0,cusplat_nh_amie)
     677           0 :     if (cuspmlt_sh_amie > 12.5_r8) cuspmlt_sh_amie = 12.5_r8
     678           0 :     if (cuspmlt_sh_amie < 11.0_r8) cuspmlt_sh_amie = 11.0_r8
     679           0 :     if (cuspmlt_nh_amie > 12.5_r8) cuspmlt_nh_amie = 12.5_r8
     680           0 :     if (cuspmlt_nh_amie < 11.0_r8) cuspmlt_nh_amie = 11.0_r8
     681           0 :     crad(1) = (90._r8-cusplat_sh_amie)*pi/180._r8
     682           0 :     crad(2) = (90._r8-cusplat_nh_amie)*pi/180._r8
     683             : 
     684           0 :     active_task: if ( mytid<ntask ) then
     685             : 
     686             :        !     mlongitude starts from 180 degree
     687           0 :        rot = sunlon*rtd
     688           0 :        if(rot < 0) then
     689           0 :           rot = rot + 360._r8    !  0 to 360 degrees
     690             :        end if
     691           0 :        rot = rot / 15._r8        !  convert from degree to hrs
     692             : 
     693           0 :        dmltm = 24._r8 / real(lonmx, kind=r8)
     694           0 :        do i = 1, lonp1
     695           0 :           xmlt = (real(i-1, kind=r8) * dmltm) - rot + 24._r8
     696           0 :           xmlt = MOD(xmlt, 24._r8)
     697           0 :           m = int(xmlt/dmltm + 1.01_r8)
     698           0 :           mp1 = m + 1
     699           0 :           if (mp1 > lonp1) mp1 = 2
     700           0 :           del = xmlt - (m-1)*dmltm
     701             :           !     Initialize arrays around equator
     702           0 :           do j = latp1+1, ithmx
     703           0 :              potm(i,j) = 0._r8
     704           0 :              potm(i,jmxm+1-j) = 0._r8
     705           0 :              ekvm(i,j) = (1._r8-del)*ekv_sh_amie(m,latp1) + &
     706           0 :                   del*ekv_sh_amie(mp1,latp1)
     707           0 :              ekvm(i,jmxm+1-j) = (1._r8-del)*ekv_nh_amie(m,latp1) +  &
     708           0 :                   del*ekv_nh_amie(mp1,latp1)
     709           0 :              efxm(i,j) = 0._r8
     710           0 :              efxm(i,jmxm+1-j) = 0._r8
     711             :           end do
     712             :           !     Put in AMIE arrays from pole to latp1
     713           0 :           do j = 1, latp1
     714           0 :              potm(i,j) = (1._r8-del)*pot_sh_amie(m,j) + &
     715           0 :                   del*pot_sh_amie(mp1,j)
     716           0 :              potm(i,jmxm+1-j) = (1._r8-del)*pot_nh_amie(m,j) + &
     717           0 :                   del*pot_nh_amie(mp1,j)
     718           0 :              ekvm(i,j) = (1._r8-del)*ekv_sh_amie(m,j) + &
     719           0 :                   del*ekv_sh_amie(mp1,j)
     720           0 :              ekvm(i,jmxm+1-j) = (1._r8-del)*ekv_nh_amie(m,j) + &
     721           0 :                   del*ekv_nh_amie(mp1,j)
     722           0 :              efxm(i,j) = (1._r8-del)*efx_sh_amie(m,j) + &
     723           0 :                   del*efx_sh_amie(mp1,j)
     724           0 :              efxm(i,jmxm+1-j) = (1._r8-del)*efx_nh_amie(m,j) + &
     725           0 :                   del*efx_nh_amie(mp1,j)
     726             :           end do
     727             : 
     728             :        end do
     729             : 
     730             :        !     Set up coeffs to go between EPOTM(IMXMP,JMNH) and TIEPOT(IMAXM,JMAXMH)
     731             : 
     732             :        !     ****     SET GRID SPACING DLATM, DLONM
     733             :        !     DMLAT=lat spacing in degrees of AMIE apex grid
     734           0 :        dmlat = 180._r8 / real(jmxm-1, kind=r8)
     735           0 :        dlatm = dmlat * dtr
     736           0 :        dlonm = 2._r8 * pi / real(lonmx, kind=r8)
     737           0 :        dmltm = 24._r8 / real(lonmx, kind=r8)
     738             :        !     ****
     739             :        !     ****     SET ARRAY YLATM (LATITUDE VALUES FOR GEOMAGNETIC GRID
     740             :        !     ****
     741           0 :        alatm(1) = -pi / 2._r8
     742           0 :        alat(1) = -90._r8
     743           0 :        alatm(jmxm) = pi / 2._r8
     744           0 :        alat(jmxm) = 90._r8
     745           0 :        do i = 2, ithmx
     746           0 :           alat(i) = alat(i-1)+dlatm*rtd
     747           0 :           alat(jmxm+1-i) = alat(jmxm+2-i)-dlatm*rtd
     748           0 :           alatm(i) = alatm(i-1)+dlatm
     749           0 :           alatm(jmxm+1-i) = alatm(jmxm+2-i)-dlatm
     750             :        end do
     751           0 :        alon(1) = -pi*rtd
     752           0 :        alonm(1) = -pi
     753           0 :        do i = 2, lonp1
     754           0 :           alon(i) = alon(i-1) + dlonm*rtd
     755           0 :           alonm(i) = alonm(i-1) + dlonm
     756             :        end do
     757             : 
     758             :        !     ylatm and ylonm are arrays of latitudes and longitudes of the
     759             :        !     distorted magnetic grids in radian - from consdyn.h
     760             :        !     Convert from apex magnetic grid to distorted magnetic grid
     761             :        !
     762             :        !     Allocate workspace for regrid routine rgrd_mod:
     763           0 :        lw = nmlonp1+nmlat+2*nmlonp1
     764             :        if (.not. allocated(w)) then
     765           0 :           allocate(w(lw), stat=ier)
     766           0 :           call check_alloc(ier, 'getamie', 'w', lw=lw)
     767             :        end if
     768           0 :        liw = nmlonp1 + nmlat
     769             :        if (.not. allocated(iw)) then
     770           0 :           allocate(iw(liw), stat=ier)
     771           0 :           call check_alloc(ier, 'getamie', 'iw', lw=liw)
     772             :        end if
     773           0 :        intpol(:) = 1             ! linear (not cubic) interp in both dimensions
     774           0 :        if (alatm(1) > ylatm(1)) then
     775           0 :           alatm(1) = ylatm(1)
     776             :        end if
     777           0 :        if (alatm(jmxm) < ylatm(nmlat)) then
     778           0 :           alatm(jmxm) = ylatm(nmlat)
     779             :        end if
     780           0 :        if (alonm(1) > ylonm(1)) then
     781           0 :           alonm(1) = ylonm(1)
     782             :        end if
     783           0 :        if (alonm(lonp1) < ylonm(nmlonp1)) then
     784           0 :           alonm(lonp1) = ylonm(nmlonp1)
     785             :        end if
     786             : 
     787             :        !     ylatm from -pi/2 to pi/2, and ylonm from -pi to pi
     788             :        call rgrd2(lonp1, jmxm, alonm, alatm, potm, nmlonp1, nmlat,  &
     789           0 :             ylonm, ylatm, phihm, intpol, w, lw, iw, liw, ier)
     790             :        call rgrd2(lonp1, jmxm, alonm, alatm, ekvm, nmlonp1, nmlat,  &
     791           0 :             ylonm, ylatm, amie_kevm, intpol, w, lw, iw, liw, ier)
     792             :        call rgrd2(lonp1, jmxm, alonm, alatm, efxm, nmlonp1, nmlat,  &
     793           0 :             ylonm, ylatm, amie_efxm, intpol, w, lw, iw, liw, ier)
     794             : 
     795           0 :        if (iprint > 0 .and. masterproc) then
     796           0 :           write(iulog, *) subname, ': Max, min amie_efxm = ', &
     797           0 :                maxval(amie_efxm), minval(amie_efxm)
     798           0 :           write(iulog, "(a,': AMIE data interpolated to date and time')") subname
     799           0 :           write(iulog,"(a,': iyear,imo,iday,iutsec = ',3i6,i10)") subname,       &
     800           0 :                iyear, imo, iday, iutsec
     801             :           write(iulog,"(2a,i6,2F9.5,3I6,f10.4)")                                 &
     802           0 :                subname, ': AMIE iset1 f1,f2,year,mon,day,ut = ', iset1,          &
     803           0 :                f1, f2, year(iset1), month(iset1), day(iset1), amie_nh_ut(iset1)
     804           0 :           write(iulog,*) subname, ': max,min phihm= ', maxval(phihm), minval(phihm)
     805             :        end if
     806             :     end if active_task
     807             : 
     808           0 :   end subroutine getamie
     809             : 
     810             :   !-----------------------------------------------------------------------
     811           0 :   subroutine close_files
     812             : 
     813           0 :     deallocate( year,month,day )
     814           0 :     deallocate( cusplat_nh_input, cuspmlt_nh_input, hpi_nh_input, &
     815           0 :                 pcp_nh_input, amie_nh_ut, &
     816           0 :                 cusplat_sh_input, cuspmlt_sh_input, hpi_sh_input, &
     817           0 :                 pcp_sh_input, amie_sh_ut )
     818             : 
     819           0 :     call cam_pio_closefile(ncid_nh)
     820           0 :     call cam_pio_closefile(ncid_sh)
     821             : 
     822             : 
     823           0 :   end subroutine close_files
     824             :   !-----------------------------------------------------------------------
     825           0 :   subroutine open_files()
     826             : 
     827           0 :     call rdamie_nh(amienh_files(file_ndx))
     828           0 :     call rdamie_sh(amiesh_files(file_ndx))
     829             : 
     830           0 :   end subroutine open_files
     831             : 
     832             : end module amie_module

Generated by: LCOV version 1.14