!> author: Sam Hatfield, Fred Kucharski, Franco Molteni ! date: 29/04/2019 ! ! contributor: Andres Perez Hortal ! ! This module initialize the land-sea mask, the surface geopotential ! (i.e. the orography), the filtered surface geopotential (i.e. the smoothed orography) ! and the bare-land annual-mean albedo. module boundaries use types, only: p use params implicit none private public initialize_boundaries, fill_missing_values, check_surface_fields contains !> Initialize boundary conditions (land-sea mask, surface geopotential ! and surface albedo). subroutine initialize_boundaries(state) use physical_constants, only: grav use model_state, only: ModelState_t type(ModelState_t), intent(inout) :: state state%phi0 = grav*state%orog ! IMPORTANT: The following variables show be initilized in the model state ! before calling this function. ! - Annual-mean surface albedo (state%alb0) ! - Land-sea mask (state%fmask_orig) ! - Annual-mean surface albedo (state%alb0) ! Initialize the spectrally truncated surface geopotential call state%mod_spectral%grid_filter(state%phi0, state%phis0) end subroutine !> Check consistency of surface fields with land-sea mask and set undefined ! values to a constant (to avoid over/underflow). subroutine check_surface_fields(fmask, nf, fmin, fmax, fset, field) real(p), intent(in) :: fmask(ix,il) !! The fractional land-sea mask integer, intent(in) :: nf !! The number of input 2D fields real(p), intent(in) :: fmin !! The minimum allowable value real(p), intent(in) :: fmax !! The maximum allowable value real(p), intent(in) :: fset !! Replacement for undefined values real(p), intent(inout) :: field(ix,il,nf) !! The output field integer :: i, j, jf, nfault do jf = 1, nf nfault = 0 do i = 1, ix do j = 1, il if (fmask(i,j) > 0.0) then if (field(i,j,jf) < fmin .or. field(i,j,jf) > fmax) then nfault = nfault + 1 end if else field(i,j,jf) = fset end if end do end do end do end subroutine !> Replace missing values in surface fields. ! @note It is assumed that non-missing values exist near the Equator. subroutine fill_missing_values(sf, fmis) real(p), intent(inout) :: sf(ix,il) !! Field to replace missing values in real(p), intent(in) :: fmis !! Replacement for missing values real(p) :: sf2(0:ix+1) integer :: hemisphere, j, j1, j2, j3, i, nmis real(p) :: fmean = 0 do hemisphere = 1, 2 if (hemisphere == 1) then j1 = il/2 j2 = 1 j3 = -1 else j1 = j1+1 j2 = il j3 = 1 end if do j = j1, j2, j3 sf2(1:ix) = sf(:,j) nmis = 0 do i = 1, ix if (sf(i,j) < fmis) then nmis = nmis + 1 sf2(i) = 0.0 end if end do if (nmis < ix) fmean = sum(sf2(1:ix))/float(ix - nmis) do i = 1, ix if (sf(i,j) < fmis) sf2(i) = fmean end do sf2(0) = sf2(ix) sf2(ix+1) = sf2(1) do i = 1, ix if (sf(i,j) < fmis) sf(i,j) = 0.5*(sf2(i-1) + sf2(i+1)) end do end do end do end subroutine end module