base.F90 Source File


This file depends on

sourcefile~~base.f90~~EfferentGraph sourcefile~base.f90 base.F90 sourcefile~field_manager.f90 field_manager.F90 sourcefile~base.f90->sourcefile~field_manager.f90 sourcefile~output_manager_core.f90 output_manager_core.F90 sourcefile~base.f90->sourcefile~output_manager_core.f90 sourcefile~output_manager_core.f90->sourcefile~field_manager.f90

Files dependent on this one

sourcefile~~base.f90~~AfferentGraph sourcefile~base.f90 base.F90 sourcefile~library.f90 library.F90 sourcefile~library.f90->sourcefile~base.f90 sourcefile~time_average.f90 time_average.F90 sourcefile~library.f90->sourcefile~time_average.f90 sourcefile~interp.f90 interp.F90 sourcefile~library.f90->sourcefile~interp.f90 sourcefile~slice.f90 slice.F90 sourcefile~library.f90->sourcefile~slice.f90 sourcefile~time_average.f90->sourcefile~base.f90 sourcefile~interp.f90->sourcefile~base.f90 sourcefile~slice.f90->sourcefile~base.f90 sourcefile~output_manager.f90 output_manager.F90 sourcefile~output_manager.f90->sourcefile~library.f90 sourcefile~output_manager.f90->sourcefile~time_average.f90 sourcefile~output_manager.f90->sourcefile~slice.f90

Contents

Source Code


Source Code

module output_operators_base

   use output_manager_core
   use field_manager
   use yaml_types

   implicit none

   private

   public type_operator_result, type_universal_operator_result

   type, extends(type_base_output_field) :: type_operator_result
      class (type_base_operator), pointer :: operator => null()
      class (type_base_output_field), pointer :: source => null()
      real(rk)              :: result_0d
      real(rk), allocatable :: result_1d(:)
      real(rk), allocatable :: result_2d(:,:)
      real(rk), allocatable :: result_3d(:,:,:)
      type (type_dimension_pointer), allocatable :: dimensions(:)
   contains
      procedure :: new_data
      procedure :: before_save
      procedure :: get_metadata
      procedure :: flag_as_required
      procedure :: fill
      procedure :: get_field
   end type

   type, extends(type_operator_result) :: type_universal_operator_result
   contains
      procedure :: get_field => universal_get_field
   end type

   contains

   recursive subroutine new_data(self)
      class (type_operator_result), intent(inout) :: self
      call self%source%new_data()
   end subroutine

   recursive subroutine before_save(self)
      class (type_operator_result), intent(inout) :: self
      call self%source%before_save()
   end subroutine

   recursive subroutine get_metadata(self, long_name, units, dimensions, minimum, maximum, fill_value, standard_name, path, attributes)
      class (type_operator_result), intent(in) :: self
      character(len=:), allocatable, intent(out), optional :: long_name, units, standard_name, path
      type (type_dimension_pointer), allocatable, intent(out), optional :: dimensions(:)
      real(rk), intent(out), optional :: minimum, maximum, fill_value
      type (type_attributes), intent(out), optional :: attributes

      ! Workaround for gfortran BUG 88511 - passing optional allocatable deferred length character arguments to the next routine causes memory corruption
      character(len=:), allocatable :: long_name2, units2, standard_name2, path2

      call self%source%get_metadata(long_name2, units2, dimensions, minimum, maximum, fill_value, standard_name2, path2, attributes)

      ! Workaround for gfortran
      if (present(long_name) .and. allocated(long_name2)) long_name = long_name2
      if (present(units) .and. allocated(units2)) units = units2
      if (present(standard_name) .and. allocated(standard_name2)) standard_name = standard_name2
      if (present(path) .and. allocated(path2)) path = path2

      if (present(dimensions) .and. allocated(self%dimensions)) dimensions(:) = self%dimensions(:)
   end subroutine

   recursive subroutine flag_as_required(self, required)
      class (type_operator_result), intent(inout) :: self
      logical,                      intent(in)    :: required

      call self%source%flag_as_required(required)
   end subroutine

   subroutine fill(self, value)
      class (type_operator_result), intent(inout) :: self
      real(rk),                     intent(in)    :: value

      if (allocated(self%result_3d)) then
         self%result_3d(:,:,:) = value
      elseif (allocated(self%result_2d)) then
         self%result_2d(:,:) = value
      elseif (allocated(self%result_1d)) then
         self%result_1d(:) = value
      else
         self%result_0d = value
      end if
   end subroutine

   recursive function get_field(self, field) result(output_field)
      class (type_operator_result), intent(in) :: self
      type (type_field), target                :: field
      class (type_base_output_field), pointer  :: output_field
      output_field => self%source%get_field(field)
   end function

   recursive function universal_get_field(self, field) result(output_field)
      class (type_universal_operator_result), intent(in) :: self
      type (type_field), target                          :: field
      class (type_base_output_field), pointer            :: output_field
      output_field => self%type_operator_result%get_field(field)
      if (associated(output_field)) output_field => self%operator%apply(output_field)
   end function

end module