/WPS/geogrid/src/smooth_module.F
FORTRAN Legacy | 587 lines | 369 code | 118 blank | 100 comment | 36 complexity | ff2d7589f6ce247a17e013d503336c7d MD5 | raw file
Possible License(s): AGPL-1.0
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! MODULE SMOOTH_MODULE
- !
- ! This module provides routines for smoothing.
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- module smooth_module
- use parallel_module
- contains
-
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Name: one_two_one
- !
- ! Purpose: Apply the 1-2-1 smoother from the MM5 program TERRAIN
- ! (found in smth121.F) to array.
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- subroutine one_two_one(array, start_dom_x, end_dom_x, start_dom_y, end_dom_y, &
- start_x, end_x, start_y, end_y, start_z, end_z, npass, msgval)
-
- implicit none
-
- ! Arguments
- integer, intent(in) :: start_dom_x, start_dom_y, start_x, start_y, start_z
- integer, intent(in) :: end_dom_x, end_dom_y, end_x, end_y, end_z
- integer, intent(in) :: npass
- real, intent(in) :: msgval
- real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(inout) :: array
-
- ! Local variables
- integer :: ix, iy, iz, ipass
- real, pointer, dimension(:,:,:) :: scratch
-
- allocate(scratch(start_x+1:end_x-1, start_y:end_y, start_z:end_z))
-
- do ipass=1,npass
- do iy=start_y,end_y
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- scratch(ix,iy,iz) = 0.50*array(ix,iy,iz)+0.25*(array(ix-1,iy,iz)+array(ix+1,iy,iz))
- end do
- end do
- end do
-
- do iy=start_y+1,end_y-1
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- array(ix,iy,iz) = 0.50*scratch(ix,iy,iz)+0.25*(scratch(ix,iy-1,iz)+scratch(ix,iy+1,iz))
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- end do
-
- deallocate(scratch)
-
- end subroutine one_two_one
-
-
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Name: smth_desmth
- !
- ! Purpose: Apply the smoother-desmoother from the MM5 program TERRAIN
- ! (found in smther.F) to array.
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- subroutine smth_desmth(array, start_dom_x, end_dom_x, start_dom_y, end_dom_y, &
- start_x, end_x, start_y, end_y, start_z, end_z, npass, msgval)
-
- implicit none
-
- ! Arguments
- integer, intent(in) :: start_dom_x, start_dom_y, start_x, start_y, start_z
- integer, intent(in) :: end_dom_x, end_dom_y, end_x, end_y, end_z
- integer, intent(in) :: npass
- real, intent(in) :: msgval
- real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(inout) :: array
-
- ! Local variables
- integer :: ix, iy, iz, ipass
- real, pointer, dimension(:,:,:) :: scratch
-
- allocate(scratch(start_x+1:end_x-1, start_y:end_y, start_z:end_z))
-
- do ipass=1,npass
- !
- ! Smoothing pass
- !
- do iy=start_y,end_y
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- scratch(ix,iy,iz) = 0.5*array(ix,iy,iz) + 0.25*(array(ix-1,iy,iz)+array(ix+1,iy,iz))
- end do
- end do
- end do
-
- do iy=start_y+1,end_y-1
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- array(ix,iy,iz) = 0.5*scratch(ix,iy,iz) + 0.25*(scratch(ix,iy-1,iz)+scratch(ix,iy+1,iz))
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
-
- !
- ! Desmoothing pass
- !
- do iy=start_y,end_y
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- scratch(ix,iy,iz) = 1.52*array(ix,iy,iz) - 0.26*(array(ix-1,iy,iz)+array(ix+1,iy,iz))
- end do
- end do
- end do
-
- do iy=start_y+1,end_y-1
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- array(ix,iy,iz) = 1.52*scratch(ix,iy,iz) - 0.26*(scratch(ix,iy-1,iz)+scratch(ix,iy+1,iz))
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- end do
-
- deallocate(scratch)
-
- end subroutine smth_desmth
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Name: smth_desmth_special
- !
- ! Purpose: Apply the smoother-desmoother from the MM5 program TERRAIN
- ! (found in smther.F) to array; however, any grid points that were not
- ! originally negative but which have been smoothed to a negative value
- ! will be restored to their original values.
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- subroutine smth_desmth_special(array, start_dom_x, end_dom_x, start_dom_y, end_dom_y, &
- start_x, end_x, start_y, end_y, start_z, end_z, npass, msgval)
- implicit none
- ! Arguments
- integer, intent(in) :: start_dom_x, start_dom_y, start_x, start_y, start_z
- integer, intent(in) :: end_dom_x, end_dom_y, end_x, end_y, end_z
- integer, intent(in) :: npass
- real, intent(in) :: msgval
- real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(inout) :: array
- ! Local variables
- integer :: ix, iy, iz, ipass
- real, pointer, dimension(:,:,:) :: scratch, orig_array
- allocate(scratch(start_x+1:end_x-1, start_y:end_y, start_z:end_z))
- allocate(orig_array(start_x:end_x, start_y:end_y, start_z:end_z))
- orig_array = array
- do ipass=1,npass
- !
- ! Smoothing pass
- !
- do iy=start_y,end_y
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- scratch(ix,iy,iz) = 0.5*array(ix,iy,iz) + 0.25*(array(ix-1,iy,iz)+array(ix+1,iy,iz))
- end do
- end do
- end do
- do iy=start_y+1,end_y-1
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- array(ix,iy,iz) = 0.5*scratch(ix,iy,iz) + 0.25*(scratch(ix,iy-1,iz)+scratch(ix,iy+1,iz))
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- !
- ! Desmoothing pass
- !
- do iy=start_y,end_y
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- scratch(ix,iy,iz) = 1.52*array(ix,iy,iz) - 0.26*(array(ix-1,iy,iz)+array(ix+1,iy,iz))
- end do
- end do
- end do
- do iy=start_y+1,end_y-1
- do ix=start_x+1,end_x-1
- do iz=start_z,end_z
- array(ix,iy,iz) = 1.52*scratch(ix,iy,iz) - 0.26*(scratch(ix,iy-1,iz)+scratch(ix,iy+1,iz))
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- end do
- ! Remove artificially negative values
- do iy=start_y,end_y
- do ix=start_x,end_x
- do iz=start_z,end_z
- if (array(ix,iy,iz) < 0. .and. orig_array(ix,iy,iz) >= 0.) then
- array(ix,iy,iz) = orig_array(ix,iy,iz)
- end if
- end do
- end do
- end do
- deallocate(scratch)
- deallocate(orig_array)
- end subroutine smth_desmth_special
- !
- ! Smoothing routines for E-grid, contributed by Matthew Pyle
- !
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Name: one_two_one_egrid
- !
- ! Purpose: Apply the 1-2-1 smoother from the MM5 program TERRAIN
- ! (found in smth121.F) to array.
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- subroutine one_two_one_egrid(array, start_dom_x, end_dom_x, start_dom_y, end_dom_y, &
- start_x, end_x, start_y, end_y, start_z, end_z, npass, msgval, hflag)
- implicit none
- ! Arguments
- integer, intent(in) :: start_dom_x, start_dom_y, start_x, start_y, start_z
- integer, intent(in) :: end_dom_x, end_dom_y, end_x, end_y, end_z
- integer, intent(in) :: npass
- real, intent(in) :: msgval, hflag
- real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), intent(inout) :: array
- ! Local variables
- integer :: ix, iy, iz, ipass
- real, pointer, dimension(:,:,:) :: scratch
- integer, dimension(start_y:end_y) :: ihe, ihw, istart
- allocate(scratch(start_x:end_x, start_y:end_y, start_z:end_z))
- do iy=start_y,end_y
- if (hflag == 1.0) then
- ihe(iy) = abs(mod(iy+1,2))
- ihw(iy) = ihe(iy)-1
- else
- ! assign ive,ivw equivs to ihe,ihw
- ihe(iy) = abs(mod(iy,2))
- ihw(iy) = ihe(iy)-1
- end if
- end do
- do iy=start_y,end_y
- if (hflag == 1.0) then
- if (mod(iy,2) == 0) then
- istart(iy) = start_x
- else
- istart(iy) = start_x+1
- end if
- else ! v points
- if (abs(mod(iy,2)) == 1) then
- istart(iy) = start_x
- else
- istart(iy) = start_x+1
- end if
- end if
- end do
- do ipass=1,npass
- do iy=start_y,end_y
- do ix=start_x,end_x
- scratch(ix,iy,1) = array(ix,iy,1) ! for points used in 2nd computation but not defined in 1st computation
- end do
- end do
- ! SW-NE direction
- do iy=start_y+1,end_y-1
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval == 1.0 .and. array(ix,iy,iz) /= 0.) .or. msgval /= 1.0) then
- scratch(ix,iy,iz) = 0.50*array(ix,iy,iz)+ &
- 0.25*(array(ix+ihw(iy),iy-1,iz)+array(ix+ihe(iy),iy+1,iz))
- end if
- end do
- end do
- end do
- ! NW-SE direction
- do iy=start_y+1,end_y-1
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval == 1.0 .and. array(ix,iy,iz) /= 0.) .or. msgval /= 1.0) then
- array(ix,iy,iz) = 0.50*scratch(ix,iy,iz)+ &
- 0.25*(scratch(ix+ihe(iy),iy-1,iz)+scratch(ix+ihw(iy),iy+1,iz))
- end if
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- end do
- deallocate(scratch)
- end subroutine one_two_one_egrid
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Name: smth_desmth_egrid_old
- !
- ! Purpose: Apply the smoother-desmoother for E grid
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- subroutine smth_desmth_egrid_old(array, start_dom_x, end_dom_x, start_dom_y, end_dom_y, &
- start_x, end_x, start_y, end_y, start_z, end_z, npass, msgval, hflag)
- implicit none
- ! Arguments
- integer, intent(in) :: start_dom_x, start_dom_y, start_x, start_y, start_z
- integer, intent(in) :: end_dom_x, end_dom_y, end_x, end_y, end_z
- integer, intent(in) :: npass
- real, intent(in) :: msgval, hflag
- real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
- intent(inout) :: array
- ! Local variables
- integer :: ix, iy, iz, ipass
- real, pointer, dimension(:,:,:) :: scratch
- integer, dimension(start_y:end_y) :: ihe, ihw, istart
- real, parameter:: cenwgt = 1.52
- real, parameter:: endwgt = 0.13
- allocate(scratch(start_x:end_x, start_y:end_y, start_z:end_z))
- do iy=start_y,end_y
- if (hflag == 1.0) then
- ihe(iy) = abs(mod(iy+1,2))
- ihw(iy) = ihe(iy)-1
- else
- ! assign ive,ivw equivs to ihe,ihw
- ihe(iy) = abs(mod(iy,2))
- ihw(iy) = ihe(iy)-1
- end if
- end do
- do iy=start_y,end_y
- if (hflag == 1.0) then
- if (mod(iy,2) == 0) then
- istart(iy) = start_x
- else
- istart(iy) = start_x+1
- endif
- else ! v points
- if (abs(mod(iy,2)) == 1) then
- istart(iy) = start_x
- else
- istart(iy) = start_x+1
- endif
- endif
- end do
- do ipass=1,npass
- !
- ! Smoothing pass
- !
- do iy=start_y,end_y
- do ix=start_x,end_x
- scratch(ix,iy,1) = array(ix,iy,1)
- end do
- end do
- do iy=start_y+1,end_y-1
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval == 1.0 .and. array(ix,iy,iz) /= 0.) .or. msgval /= 1.0) then
- scratch(ix,iy,iz) = 0.50*array(ix,iy,iz)+ &
- 0.125*(array(ix+ihw(iy),iy-1,iz)+array(ix+ihe(iy),iy+1,iz)+ &
- array(ix+ihw(iy),iy+1,iz)+array(ix+ihe(iy),iy-1,iz))
- end if
- end do
- end do
- end do
- !
- ! Desmoothing pass
- !
- do iy=start_y+2,end_y-2
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval == 1.0 .and. scratch(ix,iy,iz) /= 0.) .or. msgval /= 1.0) then
- array(ix,iy,iz) = cenwgt*scratch(ix,iy,iz) - &
- endwgt*(scratch(ix+ihw(iy),iy-1,iz)+scratch(ix+ihe(iy),iy+1,iz) + &
- scratch(ix+ihw(iy),iy+1,iz)+scratch(ix+ihe(iy),iy-1,iz))
- end if
- end do
- end do
- end do
- end do
- deallocate(scratch)
- end subroutine smth_desmth_egrid_old
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Name: smth_desmth_egrid
- !
- ! Purpose: Apply the smoother-desmoother for E grid
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- subroutine smth_desmth_egrid(array, start_dom_x, end_dom_x, start_dom_y, end_dom_y, &
- start_x, end_x, start_y, end_y, start_z, end_z, npass, msgval, hflag)
- implicit none
- ! Arguments
- integer, intent(in) :: start_dom_x, start_dom_y, start_x, start_y, start_z
- integer, intent(in) :: end_dom_x, end_dom_y, end_x, end_y, end_z
- integer, intent(in) :: npass
- real, intent(in) :: msgval, hflag
- real, dimension(start_x:end_x, start_y:end_y, start_z:end_z), &
- intent(inout) :: array
- ! Local variables
- integer :: ix, iy, iz, ipass
- real, pointer, dimension(:,:,:) :: scratch
- integer, dimension(start_y:end_y) :: ihe, ihw, istart
- real, parameter :: cenwgt = 1.52
- real, parameter :: endwgt = 0.26
- allocate(scratch(start_x:end_x, start_y:end_y, start_z:end_z))
- do iy=start_y,end_y
- if (hflag .eq. 1.0) then
- ihe(iy)=abs(mod(iy+1,2))
- ihw(iy)=ihe(iy)-1
- ! assign ive,ivw equivs to ihe,ihw
- else
- ihe(iy)=abs(mod(iy,2))
- ihw(iy)=ihe(iy)-1
- end if
- end do
- do iy=start_y,end_y
- if (hflag .eq. 1.0) then
- if (mod(iy,2) .eq. 0) then
- istart(iy)=start_x
- else
- istart(iy)=start_x+1
- endif
- else ! v points
- if (abs(mod(iy,2)) .eq. 1) then
- istart(iy)=start_x
- else
- istart(iy)=start_x+1
- end if
- end if
- end do
- do ipass=1,npass
- !
- ! Smoothing pass
- !
- do iy=start_y,end_y
- do ix=start_x,end_x
- scratch(ix,iy,1)=array(ix,iy,1) ! for points used in 2nd computation but
- ! not defined in 1st
- end do
- end do
- ! SW-NE direction
- do iy=start_y+1,end_y-1
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval .eq. 1.0 .and. array(ix,iy,iz) .ne. 0.) .or. msgval .ne. 1.0) then
- scratch(ix,iy,iz) = 0.50*array(ix,iy,iz)+ &
- 0.25*(array(ix+ihw(iy),iy-1,iz)+array(ix+ihe(iy),iy+1,iz))
- end if
- end do
- end do
- end do
- ! NW-SE direction
- do iy=start_y+1,end_y-1
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval .eq. 1.0 .and. array(ix,iy,iz) .ne. 0.) .or. msgval .ne. 1.0) then
- array(ix,iy,iz) = 0.50*scratch(ix,iy,iz)+ &
- 0.25*(scratch(ix+ihe(iy),iy-1,iz)+scratch(ix+ihw(iy),iy+1,iz))
- end if
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- !
- ! Desmoothing pass
- !
- ! SW-NE direction
- do iy=start_y+2,end_y-2
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval .eq. 1.0 .and. array(ix,iy,iz) .ne. 0.) .or. msgval .ne. 1.0) then
- scratch(ix,iy,iz) = cenwgt*array(ix,iy,iz) - &
- endwgt*(array(ix+ihw(iy),iy-1,iz)+array(ix+ihe(iy),iy+1,iz))
- end if
- end do
- end do
- end do
- ! NW-SE direction
- do iy=start_y+2,end_y-2
- do ix=istart(iy),end_x-1
- do iz=start_z,end_z
- if ( (msgval .eq. 1.0 .and. array(ix,iy,iz) .ne. 0.) .or. msgval .ne. 1.0) then
- array(ix,iy,iz) = cenwgt*scratch(ix,iy,iz) - &
- endwgt*(scratch(ix+ihe(iy),iy-1,iz)+scratch(ix+ihw(iy),iy+1,iz))
- end if
- end do
- end do
- end do
- call exchange_halo_r(array, &
- start_x, end_x, start_y, end_y, start_z, end_z, &
- start_dom_x, end_dom_x, start_dom_y, end_dom_y, start_z, end_z)
- end do
- deallocate(scratch)
- end subroutine smth_desmth_egrid
- end module smooth_module