ground.F90 Source File


This file depends on

sourcefile~~ground.f90~~EfferentGraph sourcefile~ground.f90 ground.F90 sourcefile~basal_surface.f90 basal_surface.F90 sourcefile~ground.f90->sourcefile~basal_surface.f90 sourcefile~nitsol.f90 nitsol.f90 sourcefile~basal_surface.f90->sourcefile~nitsol.f90

Contents

Source Code


Source Code

!
!  ground.f90
!  This file is part of ISOFT.
!  
!  Copyright 2016 Chris MacMackin <cmacmackin@gmail.com>
!  
!  This program is free software; you can redistribute it and/or modify
!  it under the terms of the GNU General Public License as published by
!  the Free Software Foundation; either version 2 of the License, or
!  (at your option) any later version.
!  
!  This program is distributed in the hope that it will be useful,
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!  GNU General Public License for more details.
!  
!  You should have received a copy of the GNU General Public License
!  along with this program; if not, write to the Free Software
!  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
!  MA 02110-1301, USA.
!  

#ifdef DEBUG
#define pure 
#define elemental 
#endif

module ground_mod
  !* Author: Christopher MacMackin
  !  Date: April 2016
  !  License: GPLv3
  !
  ! Provides a concrete implementation of the [[basal_surface]] data type,
  ! representing solid ground.
  !
  use iso_fortran_env, only: r8 => real64
  use basal_surface_mod, only: basal_surface
  use factual_mod, only: scalar_field
  use hdf5
  implicit none
  private

  type, extends(basal_surface), public :: ground
    !* Author: Christopher MacMackin
    !  Date: April 2016
    !
    ! A concrete implementation of the [[basal_surface]] abstract data type,
    ! representing the ground beneath an ice sheet. At the moment this
    ! doesn't actually do anything.
    !
  contains
    procedure :: basal_melt => ground_melt
    procedure :: basal_drag_parameter => ground_drag_parameter
    procedure :: water_density => ground_water_density
    procedure :: update => ground_update
    procedure :: data_size => ground_data_size
    procedure :: state_vector => ground_state_vector
    procedure :: read_data => ground_read_data
    procedure :: write_data => ground_write_data
    procedure :: solve => ground_solve
  end type ground

  interface ground
    module procedure constructor
  end interface ground

contains

  function constructor() result(this)
    !* Author: Christopher MacMackin
    !  Date: April 2016
    ! 
    ! Instantiates a [[ground]] object.
    !
    type(ground) :: this
  end function constructor


  function ground_melt(this) result(melt)
    !* Author: Christopher MacMackin
    !  Date: April 2016
    !
    ! Computes and returns the melt rate at the bottom of the ice
    ! sheet due to interaction with the ground.
    !
    class(ground), intent(in)    :: this
    class(scalar_field), pointer :: melt
      !! The melt rate at the base of the ice sheet.
  end function ground_melt


  function ground_drag_parameter(this) result(drag)
    !* Author: Christopher MacMackin
    !  Date: April 2016
    !
    ! Computes and returns a quantity which may be necessary to determine
    ! the frictional drag the ground exerts on the bottom of the ice
    ! sheet. An example would be the coefficient of friction. The 
    ! description of this method is left deliberately vague so that as not
    ! to constrain how the drag is parameterized.
    !
    class(ground), intent(in)    :: this
    class(scalar_field), pointer :: drag
      !! The value of a paramter describing the drag of the ground on the
      !! ice sheet.
  end function ground_drag_parameter


  function ground_water_density(this) result(density)
    !* Author: Christopher MacMackin
    !  Date: April 2016
    !
    ! Computes and returns the density of the water beneath the ice sheet.
    ! This water would be subglacial discharge and would tend to lubricate
    ! the motion of the ice sheet. The density probably won't be important
    ! in the case of an ice sheet, but is included so that the ground data
    ! type can have the same interface as the [[plume]] data type.
    !
    class(ground), intent(in) :: this
    real(r8)                  :: density
      !! The density of any water at the base of the ice sheet.
  end function ground_water_density


  subroutine ground_update(this, state_vector, ice_thickness)
    !* Author: Christopher MacMackin
    !  Date: April 2016
    !
    ! Updates the state of the ground from its state vector. The state
    ! vector is a real array containing the value of each of the ground's
    ! properties at each of the locations on the grid used in discretization.
    !
    class(ground), intent(inout)       :: this
    real(r8), dimension(:), intent(in) :: state_vector
      !! A real array containing the data describing the state of the
      !! ground.
    class(scalar_field), optional, intent(in) :: ice_thickness
      !! The ice thickness which, if present, will be used to update
      !! the calculation of the melt rate and/or drag parameter.
  end subroutine ground_update


  pure function ground_data_size(this)
    !* Author: Christopher MacMackin
    !  Date: August 2016
    !
    ! Returns the number of elements in the ground's state vector.
    ! This is the size of the vector returned by
    ! [[ground(type):state_vector]] and taken as an argument by
    ! [[ground(type):update]].
    !
    class(ground), intent(in) :: this
    integer                   :: ground_data_size
      !! The number of elements in the ground's state vector.
  end function ground_data_size


  pure function ground_state_vector(this) result(state_vector) 
    !* Author: Christopher MacMackin
    !  Date: April 2016
    !
    ! Returns the state vector for the current state of the ground. 
    ! This takes the form of a 1D array.
    !
    class(ground), intent(in)           :: this
    real(r8), dimension(:), allocatable :: state_vector
      !! The state vector describing the ground.
  end function ground_state_vector


  subroutine ground_read_data(this,file_id,group_name,error)
    !* Author: Chris MacMackin
    !  Date: April 2017
    !
    ! Reads the state of the ground object from the specified group in
    ! an HDF file.
    !
    class(ground), intent(inout) :: this
    integer(hid_t), intent(in)   :: file_id
      !! The identifier for the HDF5 file/group from which this data is
      !! meant to be read.
    character(len=*), intent(in) :: group_name
      !! The name of the group in the HDF5 file storing the
      !! ground's data.
    integer, intent(out)         :: error
      !! Flag indicating whether routine ran without error. If no
      !! error occurs then has value 0.
    integer(hid_t) :: group_id
    error = 0
  end subroutine ground_read_data


  subroutine ground_write_data(this,file_id,group_name,error)
    !* Author: Chris MacMackin
    !  Date: November 2016
    !
    ! Writes the state of the ground object to an HDF file in the
    ! specified group.
    !
    class(ground), intent(in)    :: this
    integer(hid_t), intent(in)   :: file_id
      !! The identifier for the HDF5 file/group in which this data is
      !! meant to be written.
    character(len=*), intent(in) :: group_name
      !! The name to give the group in the HDF5 file storing the
      !! ground's data.
    integer, intent(out)         :: error
      !! Flag indicating whether routine ran without error. If no
      !! error occurs then has value 0.
    integer(hid_t) :: group_id
    call h5gcreate_f(file_id, group_name, group_id, error)
    if (error /= 0) then
      write(*,*) 'WARNING: Error code',error,' returned when creating HDF '// &
                 'group', group_name
      write(*,*) '         Data IO not performed for ice shelf'
      return
    end if

    call h5gclose_f(group_id, error)
    if (error /= 0) then
      write(*,*) 'WARNING: Error code',error,' returned when closing HDF '// &
                 'group', group_name
      write(*,*) '         Possible bad IO'
    end if
  end subroutine ground_write_data


  subroutine ground_solve(this, ice_thickness, ice_density, &
                         ice_temperature, time, success)
    !* Author: Chris MacMackin
    !  Date: April 2017
    !
    ! Solves the state of the ground for the specified ice properties,
    ! at the specified time.
    !
    class(ground), intent(inout)    :: this
    class(scalar_field), intent(in) :: ice_thickness
      !! Thickness of the ice above the basal surface
    real(r8), intent(in)            :: ice_density
      !! The density of the ice above the basal surface, assumed uniform
    real(r8), intent(in)            :: ice_temperature
      !! The temperature of the ice above the basal surface, assumed uniform
    real(r8), intent(in)            :: time
      !! The time to which the basal surface should be solved
    logical, intent(out)            :: success
      !! True if the solver is successful, false otherwise
  end subroutine ground_solve

end module ground_mod