OutputInfo.F90 Source File


This file depends on

sourcefile~~outputinfo.f90~~EfferentGraph sourcefile~outputinfo.f90 OutputInfo.F90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~outputinfo.f90->sourcefile~errorhandling.f90 sourcefile~mapl_esmf_infokeys.f90 MAPL_ESMF_InfoKeys.F90 sourcefile~outputinfo.f90->sourcefile~mapl_esmf_infokeys.f90 sourcefile~ungriddeddim.f90 UngriddedDim.F90 sourcefile~outputinfo.f90->sourcefile~ungriddeddim.f90 sourcefile~ungriddeddims.f90 UngriddedDims.F90 sourcefile~outputinfo.f90->sourcefile~ungriddeddims.f90 sourcefile~ungriddeddimvector.f90 UngriddedDimVector.F90 sourcefile~outputinfo.f90->sourcefile~ungriddeddimvector.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~mapl_esmf_infokeys.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddim.f90->sourcefile~errorhandling.f90 sourcefile~lu_bound.f90 LU_Bound.F90 sourcefile~ungriddeddim.f90->sourcefile~lu_bound.f90 sourcefile~ungriddeddims.f90->sourcefile~errorhandling.f90 sourcefile~ungriddeddims.f90->sourcefile~ungriddeddim.f90 sourcefile~ungriddeddims.f90->sourcefile~ungriddeddimvector.f90 sourcefile~ungriddeddims.f90->sourcefile~lu_bound.f90 sourcefile~ungriddeddimvector.f90->sourcefile~ungriddeddim.f90

Files dependent on this one

sourcefile~~outputinfo.f90~~AfferentGraph sourcefile~outputinfo.f90 OutputInfo.F90 sourcefile~generic3g.f90 Generic3g.F90 sourcefile~generic3g.f90->sourcefile~outputinfo.f90 sourcefile~historycollectiongridcomp_private.f90 HistoryCollectionGridComp_private.F90 sourcefile~historycollectiongridcomp_private.f90->sourcefile~outputinfo.f90 sourcefile~historycollectiongridcomp_private.f90->sourcefile~generic3g.f90 sourcefile~sharedio.f90 SharedIO.F90 sourcefile~sharedio.f90->sourcefile~outputinfo.f90 sourcefile~test_outputinfo.pf Test_OutputInfo.pf sourcefile~test_outputinfo.pf->sourcefile~outputinfo.f90 sourcefile~cap.f90 Cap.F90 sourcefile~cap.f90->sourcefile~generic3g.f90 sourcefile~capgridcomp.f90 CapGridComp.F90 sourcefile~cap.f90->sourcefile~capgridcomp.f90 sourcefile~capgridcomp.f90->sourcefile~generic3g.f90 sourcefile~configurableleafgridcomp.f90 ConfigurableLeafGridComp.F90 sourcefile~configurableleafgridcomp.f90->sourcefile~generic3g.f90 sourcefile~configurableparentgridcomp.f90 ConfigurableParentGridComp.F90 sourcefile~configurableparentgridcomp.f90->sourcefile~generic3g.f90 sourcefile~extdatagridcomp.f90 ExtDataGridComp.F90 sourcefile~extdatagridcomp.f90->sourcefile~generic3g.f90 sourcefile~geom_pfio.f90 Geom_PFIO.F90 sourcefile~geom_pfio.f90->sourcefile~sharedio.f90 sourcefile~geomio.f90 GeomIO.F90 sourcefile~geomio.f90->sourcefile~sharedio.f90 sourcefile~geomio.f90->sourcefile~geom_pfio.f90 sourcefile~geomcatagorizer.f90 GeomCatagorizer.F90 sourcefile~geomio.f90->sourcefile~geomcatagorizer.f90 sourcefile~grid_pfio.f90 Grid_PFIO.F90 sourcefile~grid_pfio.f90->sourcefile~sharedio.f90 sourcefile~grid_pfio.f90->sourcefile~geom_pfio.f90 sourcefile~historycollectiongridcomp.f90 HistoryCollectionGridComp.F90 sourcefile~historycollectiongridcomp.f90->sourcefile~generic3g.f90 sourcefile~historycollectiongridcomp.f90->sourcefile~historycollectiongridcomp_private.f90 sourcefile~historycollectiongridcomp.f90->sourcefile~geomio.f90 sourcefile~historygridcomp.f90 HistoryGridComp.F90 sourcefile~historygridcomp.f90->sourcefile~generic3g.f90 sourcefile~historygridcomp.f90->sourcefile~historycollectiongridcomp.f90 sourcefile~mapl3g.f90 mapl3g.F90 sourcefile~mapl3g.f90->sourcefile~generic3g.f90 sourcefile~mapl3g.f90->sourcefile~cap.f90 sourcefile~restarthandler.f90 RestartHandler.F90 sourcefile~restarthandler.f90->sourcefile~sharedio.f90 sourcefile~restarthandler.f90->sourcefile~geomio.f90 sourcefile~test_extdatagridcomp.pf Test_ExtDataGridComp.pf sourcefile~test_extdatagridcomp.pf->sourcefile~generic3g.f90 sourcefile~test_historycollectiongridcomp.pf Test_HistoryCollectionGridComp.pf sourcefile~test_historycollectiongridcomp.pf->sourcefile~historycollectiongridcomp_private.f90 sourcefile~test_historygridcomp.pf Test_HistoryGridComp.pf sourcefile~test_historygridcomp.pf->sourcefile~generic3g.f90 sourcefile~test_sharedio.pf Test_SharedIO.pf sourcefile~test_sharedio.pf->sourcefile~sharedio.f90 sourcefile~geomcatagorizer.f90->sourcefile~geom_pfio.f90 sourcefile~geomcatagorizer.f90->sourcefile~grid_pfio.f90 sourcefile~geos.f90 GEOS.F90 sourcefile~geos.f90->sourcefile~mapl3g.f90 sourcefile~read_restart.f90~2 read_restart.F90 sourcefile~read_restart.f90~2->sourcefile~restarthandler.f90 sourcefile~write_restart.f90~2 write_restart.F90 sourcefile~write_restart.f90~2->sourcefile~restarthandler.f90

Source Code

#include "MAPL_Generic.h"
module mapl3g_output_info

   use mapl3g_UngriddedDim
   use mapl3g_UngriddedDimVector
   use mapl3g_UngriddedDims
   use mapl3g_esmf_info_keys
   use gFTL2_StringVector
   use esmf, only: ESMF_Field, ESMF_FieldBundle, ESMF_FieldBundleGet
   use esmf, only: ESMF_Info, ESMF_InfoIsPresent
   use esmf, only: ESMF_InfoDestroy, ESMF_InfoCreate
   use esmf, only: ESMF_InfoGet, ESMF_InfoGetFromHost
   use esmf, only: ESMF_InfoGetAlloc, ESMF_InfoGetCharAlloc
   use esmf, only: ESMF_InfoPrint
   use Mapl_ErrorHandling

   implicit none

   private

   public :: get_num_levels
   public :: get_vertical_dim_spec_names
   public :: get_vertical_dim_spec_name
   public :: get_ungridded_dims
   public :: get_num_levels_bundle_info
   public :: get_vertical_dim_spec_names_bundle_info
   public :: get_ungridded_dims_bundle_info

   interface get_num_levels
      module procedure :: get_num_levels_bundle
      module procedure :: get_num_levels_field
   end interface get_num_levels

   interface get_vertical_dim_spec_names
      module procedure :: get_vertical_dim_spec_names_bundle
   end interface get_vertical_dim_spec_names

   interface get_vertical_dim_spec_name
      module procedure :: get_vertical_dim_spec_name_field
   end interface get_vertical_dim_spec_name

   interface get_ungridded_dims
      module procedure :: get_ungridded_dims_bundle
      module procedure :: get_ungridded_dims_field
   end interface get_ungridded_dims

   character(len=*), parameter :: VERT_DIM_NONE = 'VERTICAL_DIM_NONE'

contains

   integer function get_num_levels_bundle(bundle, rc) result(num)
      type(ESMF_FieldBundle), intent(in) :: bundle
      integer, optional, intent(out) :: rc
      integer :: status
      type(ESMF_Info), allocatable :: info(:)

      info = create_bundle_info(bundle, _RC)
      num = get_num_levels_bundle_info(info, _RC)
      _RETURN(_SUCCESS)

   end function get_num_levels_bundle

   integer function get_num_levels_bundle_info(info, rc) result(num)
      type(ESMF_Info), intent(in) :: info(:)
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: i, n

      num = 0
      do i=1, size(info)
         n = get_num_levels_info(info(i), _RC)
         num = max(num, n)
         if(n == 0) cycle
         _ASSERT(n == num, 'Fields with vertical levels must have the same number of levels.')
      end do
      _RETURN(_SUCCESS)

   end function get_num_levels_bundle_info

   integer function get_num_levels_field(field, rc) result(num)
      type(ESMF_Field), intent(in) :: field
      integer, optional, intent(out) :: rc
      integer :: status
      type(ESMF_Info) :: info

      call ESMF_InfoGetFromHost(field, info, _RC)
      num = get_num_levels_info(info, _RC)
      _RETURN(_SUCCESS)

   end function get_num_levels_field

   integer function get_num_levels_info(info, rc) result(num)
      type(ESMF_Info), intent(in) :: info
      integer, optional, intent(out) :: rc
      integer :: status
      logical :: is_none

      num = 0
      is_none = VERT_DIM_NONE == get_vertical_dim_spec_info(info, _RC)
      _RETURN_IF(is_none)

      call ESMF_InfoGet(info, key=KEY_NUM_LEVELS, value=num, _RC)
      _RETURN(_SUCCESS)

   end function get_num_levels_info

   function get_vertical_dim_spec_names_bundle(bundle, rc) result(names)
      type(StringVector) :: names
      type(ESMF_FieldBundle), intent(in) :: bundle
      integer, optional, intent(out) :: rc
      integer :: status
      type(ESMF_Info), allocatable :: info(:)

      info = create_bundle_info(bundle, _RC)
      names = get_vertical_dim_spec_names_bundle_info(info, _RC)
      _RETURN(_SUCCESS)

   end function get_vertical_dim_spec_names_bundle

   function get_vertical_dim_spec_names_bundle_info(info, rc) result(names)
      type(StringVector) :: names
      type(ESMF_Info), intent(in) :: info(:)
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: i
      character(len=:), allocatable :: name

      names = StringVector()
      do i=1, size(info)
         name = get_vertical_dim_spec_info(info(i), _RC)
         if(find_index(names, name) == 0) call names%push_back(name)
      end do
      _RETURN(_SUCCESS)

   end function get_vertical_dim_spec_names_bundle_info

   function get_vertical_dim_spec_name_field(field, rc) result(spec_name)
      character(len=:), allocatable :: spec_name
      type(ESMF_Field), intent(in) :: field
      integer, optional, intent(out) :: rc
      integer :: status
      type(ESMF_Info) :: info

      call ESMF_InfoGetFromHost(field, info, _RC)
      spec_name = get_vertical_dim_spec_info(info, _RC)
      _RETURN(_SUCCESS)

   end function get_vertical_dim_spec_name_field

   function get_vertical_dim_spec_info(info, rc) result(spec_name)
      character(len=:), allocatable :: spec_name
      type(ESMF_Info), intent(in) :: info
      integer, optional, intent(out) :: rc
      integer :: status

      call ESMF_InfoGetCharAlloc(info, key=KEY_VLOC, value=spec_name, _RC)
      _RETURN(_SUCCESS)

   end function get_vertical_dim_spec_info

   function get_ungridded_dims_bundle(bundle, rc) result(dims)
      type(UngriddedDims) :: dims
      type(ESMF_FieldBundle), intent(in) :: bundle
      integer, optional, intent(out) :: rc
      integer :: status
      type(ESMF_Info), allocatable :: info(:)
      type(UngriddedDimVector) :: vec

      info = create_bundle_info(bundle, _RC)
      vec = get_ungridded_dims_bundle_info(info, _RC)
      dims = UngriddedDims(vec)
      _RETURN(_SUCCESS)

   end function get_ungridded_dims_bundle

   function get_ungridded_dims_bundle_info(info, rc) result(vec)
      type(UngriddedDimVector) :: vec
      type(ESMF_Info), intent(in) :: info(:)
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: i
      type(UngriddedDims) :: dims

      do i=1, size(info)
         dims = make_ungridded_dims(info(i), _RC)
         call push_ungridded_dims(vec, dims, rc)
      end do
      _RETURN(_SUCCESS)

   end function get_ungridded_dims_bundle_info

   function get_ungridded_dims_field(field, rc) result(ungridded)
      type(UngriddedDims) :: ungridded
      type(ESMF_Field), intent(in) :: field
      integer, optional, intent(out) :: rc
      integer :: status
      type(ESMF_Info) :: info

      call ESMF_InfoGetFromHost(field, info, _RC)
      ungridded = make_ungridded_dims(info, _RC)
      _RETURN(_SUCCESS)

   end function get_ungridded_dims_field

   function make_ungridded_dims(info, rc) result(dims)
      type(UngriddedDims) :: dims
      type(ESMF_Info), intent(in) :: info
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: num_dims, i
      type(UngriddedDim) :: ungridded

      call ESMF_InfoGet(info, key=KEY_NUM_UNGRID_DIMS, value=num_dims, _RC)
      do i=1, num_dims
         ungridded = make_ungridded_dim(info, i, _RC)
         call dims%add_dim(ungridded, _RC)
      end do
      _RETURN(_SUCCESS)

   end function make_ungridded_dims

   function make_ungridded_dim(info, n, rc) result(ungridded_dim)
      type(UngriddedDim) :: ungridded_dim
      integer, intent(in) :: n
      type(ESMF_Info), intent(in) :: info
      integer, optional, intent(out) :: rc
      integer :: status
      character(len=:), allocatable :: key
      type(ESMF_Info) :: dim_info
      character(len=:), allocatable :: name
      character(len=:), allocatable :: units
      real, allocatable :: coordinates(:)
      logical :: is_present
      character(len=1024) :: json_repr

      key = make_dim_key(n, _RC)
      call ESMF_InfoGet(info, key=key, isPresent=is_present, _RC)
      if(.not. is_present) then
         call ESMF_InfoPrint(info, unit=json_repr, _RC)
      end if
      _ASSERT(is_present, 'Key ' // key // ' not found in ' // trim(json_repr))
      dim_info = ESMF_InfoCreate(info, key=key, _RC)
      call ESMF_InfoGetCharAlloc(dim_info, key=KEY_UNGRIDDED_NAME, value=name, _RC)
      call ESMF_InfoGetCharAlloc(dim_info, key=KEY_UNGRIDDED_UNITS, value=units, _RC)
      call ESMF_InfoGetAlloc(dim_info, key=KEY_UNGRIDDED_COORD, values=coordinates, _RC)
      call ESMF_InfoDestroy(dim_info, _RC)
      ungridded_dim = UngriddedDim(coordinates, name=name, units=units)
      _RETURN(_SUCCESS)

   end function make_ungridded_dim

   subroutine push_ungridded_dims(vec, dims, rc)
      class(UngriddedDimVector), intent(inout) :: vec
      class(UngriddedDims), intent(in) :: dims
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: i

      do i = 1, dims%get_num_ungridded()
         call check_duplicate(vec, dims%get_ith_dim_spec(i), _RC)
         call vec%push_back(dims%get_ith_dim_spec(i), _RC)
      end do
      _RETURN(_SUCCESS)

   end subroutine push_ungridded_dims

   integer function find_index(v, name) result(i)
      class(StringVector), intent(in) :: v
      character(len=*), intent(in) :: name
      type(StringVectorIterator) :: iter

      i = 0
      iter = v%begin()
      do while (iter /= v%end())
         i = i+1
         if(iter%of() == name) return
         call iter%next()
      end do
      i = 0

   end function find_index

   subroutine check_duplicate(vec, udim, rc)
      class(UngriddedDimVector), intent(in) :: vec
      class(UngriddedDim), intent(in) :: udim
      integer, optional, intent(out) :: rc
      integer :: status
      type(UngriddedDimVectorIterator) :: iter
      type(UngriddedDim) :: vdim

      iter = vec%ftn_begin()
      do while(iter < vec%ftn_end())
         call iter%next()
         vdim = iter%of()
         if(udim%get_name() /= vdim%get_name()) cycle
         _ASSERT(udim == vdim, 'UngriddedDim mismatch.')
      end do

      _RETURN(_SUCCESS)

   end subroutine check_duplicate

   logical function is_vertical_dim_none(s)
      character(len=*), intent(in) :: s

      is_vertical_dim_none = s == 'VERTICAL_DIM_NONE'

   end function is_vertical_dim_none

   function create_bundle_info(bundle, rc) result(bundle_info)
      type(ESMF_Info), allocatable :: bundle_info(:)
      type(ESMF_FieldBundle), intent(in) :: bundle
      integer, optional, intent(out) :: rc
      integer :: status
      integer :: field_count, i
      type(ESMF_Field) :: field
      type(ESMF_Field), allocatable :: fields(:)
      type(ESMF_Info) :: info

      status = 0
      call ESMF_FieldBundleGet(bundle, fieldCount=field_count, _RC)
      _ASSERT(field_count > 0, 'Empty bundle')
      allocate(fields(field_count))
      call ESMF_FieldBundleGet(bundle, fieldList=fields, _RC)
      allocate(bundle_info(field_count))
      do i=1, field_count
         call ESMF_InfoGetFromHost(fields(i), info, _RC)
         bundle_info(i) = info
      end do
      _RETURN(_SUCCESS)

   end function create_bundle_info

   subroutine destroy_bundle_info(bundle_info, rc)
      type(ESMF_Info), intent(inout) :: bundle_info(:)
      integer, optional, intent(out) :: rc
      integer :: status, i

      do i=1, size(bundle_info)
         call ESMF_InfoDestroy(bundle_info(i), _RC)
      end do
      _RETURN(_SUCCESS)

   end subroutine destroy_bundle_info

end module mapl3g_output_info