CurvatureMicroMet Subroutine

public subroutine CurvatureMicroMet(dem, curve_len_scale, curvature)

Calculate curvature according to method implemented in MICROMET

References:

Liston, G.E., Elder, K., A Meteorological Distribution System for High-Resolution Terrestrial Modeling, JOURNAL OF HYDROMETEOROLOGY, 7, 217-234, 2006.

Arguments

Type IntentOptional Attributes Name
type(grid_real), intent(in) :: dem
real(kind=float), intent(in) :: curve_len_scale
type(grid_real), intent(out) :: curvature

Variables

Type Visibility Attributes Name Initial
real(kind=float), public :: curve_max
real(kind=float), public :: deltaxy
integer(kind=short), public :: i
integer(kind=short), public :: inc
integer(kind=short), public :: j
real(kind=float), public :: z
real(kind=float), public :: ze
real(kind=float), public :: zn
real(kind=float), public :: zne
real(kind=float), public :: znw
real(kind=float), public :: zs
real(kind=float), public :: zse
real(kind=float), public :: zsw
real(kind=float), public :: zw

Source Code

SUBROUTINE CurvatureMicroMet &
!
(dem, curve_len_scale, curvature)

IMPLICIT NONE

!arguments with intent in
TYPE(grid_real),    INTENT(in) :: dem
REAL (KIND = float), INTENT(in) :: curve_len_scale

!arguments with intent out
TYPE (grid_real), INTENT (out) :: curvature

!local declarations:
 REAL (KIND = float) :: deltaxy
 REAL (KIND = float) :: z, zw, ze, zs, zn, zsw, zne, znw, zse
 REAL (KIND = float) :: curve_max
 INTEGER (KIND = short) :: inc
 INTEGER (KIND = short) :: i, j


!-----------------------------end of declarations------------------------------
!allocate grid
CALL NewGrid (curvature, dem)


!compute curvature
DO i = 1, dem % idim
  DO j = 1, dem % jdim
   IF (dem % mat (i,j) /= dem % nodata) THEN
   
     !average grid increment
     deltaxy = CellArea (dem,i,j) ** 0.5

     !Convert the length scale to an appropriate grid increment.
     inc = max(1,nint(curve_len_scale/deltaxy))
     
     !srt z
     z = dem % mat(i,j)
     
     !set zn
     IF ( .NOT. IsOutOfGrid (i-inc,j,dem) ) THEN
        IF ( dem % mat (i-inc,j) /= dem % nodata) THEN
           zn = dem % mat (i-inc,j)
        ELSE
           zn = dem % mat (i,j)
        END IF  
      ELSE 
           zn = dem % mat (i,j)
      END IF
      
      !set zne
      IF ( .NOT. IsOutOfGrid (i-inc,j+inc,dem) ) THEN
         IF ( dem % mat (i-inc,j+inc) /= dem % nodata) THEN
            zne = dem % mat (i-inc,j+inc)
         ELSE
            zne = dem % mat (i,j)
         END IF  
       ELSE 
            zne = dem % mat (i,j)
       END IF
       
       !set ze
       IF ( .NOT. IsOutOfGrid (i,j+inc,dem) ) THEN
          IF ( dem % mat (i,j+inc) /= dem % nodata) THEN
             ze = dem % mat (i,j+inc)
          ELSE
             ze = dem % mat (i,j)
          END IF  
        ELSE 
             ze = dem % mat (i,j)
        END IF
        
        !set zse
        IF ( .NOT. IsOutOfGrid (i+inc,j+inc,dem) ) THEN
           IF ( dem % mat (i+inc,j+inc) /= dem % nodata) THEN
              zse = dem % mat (i+inc,j+inc)
           ELSE
              zse = dem % mat (i,j)
           END IF  
         ELSE 
              zse = dem % mat (i,j)
         END IF
         
         !set zs
         IF ( .NOT. IsOutOfGrid (i+inc,j,dem) ) THEN
            IF ( dem % mat (i+inc,j) /= dem % nodata) THEN
               zs = dem % mat (i+inc,j)
            ELSE
               zs = dem % mat (i,j)
            END IF  
          ELSE 
               zs = dem % mat (i,j)
          END IF
          
          !set zsw
          IF ( .NOT. IsOutOfGrid (i+inc,j-inc,dem) ) THEN
             IF ( dem % mat (i+inc,j-inc) /= dem % nodata) THEN
                zsw = dem % mat (i+inc,j-inc)
             ELSE
                zsw = dem % mat (i,j)
             END IF  
           ELSE 
                zsw = dem % mat (i,j)
           END IF
           
           !set zw
           IF ( .NOT. IsOutOfGrid (i,j-inc,dem) ) THEN
              IF ( dem % mat (i,j-inc) /= dem % nodata) THEN
                 zw = dem % mat (i,j-inc)
              ELSE
                 zw = dem % mat (i,j)
              END IF  
            ELSE 
                 zw = dem % mat (i,j)
            END IF
            
            !set znw
            IF ( .NOT. IsOutOfGrid (i-inc,j-inc,dem) ) THEN
               IF ( dem % mat (i-inc,j-inc) /= dem % nodata) THEN
                  znw = dem % mat (i-inc,j-inc)
               ELSE
                  znw = dem % mat (i,j)
               END IF  
             ELSE 
                  znw = dem % mat (i,j)
             END IF
             
             
             !curvature
              curvature % mat(i,j) = (4.0 * z - znw - zse - zsw - zne ) / &
                   (sqrt(2.0) * 16.0 * real(inc) * deltaxy) + &
                   (4.0 * z - zs - zn - ze - zw) / &
                   (16.0 * real(inc) * deltaxy)
      
   END IF
  END DO
END DO


! Scale the curvature such that the max abs(curvature) has a value
!   of abs(0.5).  Include a 1 mm curvature in curve_max to prevent
!   divisions by zero in flat terrain where the curvature is zero.

curve_max = 0.0 + 0.001

DO i = 1, dem % idim
  DO j = 1, dem % jdim
    IF (dem % mat (i,j) /= dem % nodata) THEN 
       curve_max = MAX(curve_max,ABS(curvature%mat(i,j)))
    END IF
  END DO
END DO

DO i = 1, dem % idim
  DO j = 1, dem % jdim
    IF (dem % mat (i,j) /= dem % nodata) THEN 
       curvature%mat(i,j) = curvature%mat(i,j) / (2.0 * curve_max)
    END IF
  END DO
END DO
       

RETURN

END SUBROUTINE CurvatureMicroMet