grid_tools.F90 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. !
  2. ! Grid tools.
  3. !
  4. ! may 2002, Arjo Segers
  5. !
  6. module grid_tools
  7. use Binas, only : deg2rad, pi, ae
  8. implicit none
  9. ! --- in/out --------------------------------------
  10. private
  11. public :: deg2rad, pi, ae
  12. public :: ll_area
  13. public :: ll_area_frac
  14. contains
  15. ! ===================================================================
  16. ! given rectangle [west,east]x[south,north] in radians,
  17. ! compute area in rad^2
  18. real function ll_area( west, east, south, north )
  19. ! --- in/out -------------------------------------
  20. real, intent(in) :: west, east, south, north ! rad
  21. ! --- begin ------------------------------------
  22. ll_area = ( sin(max(north,south)) - sin(min(north,south)) ) * abs(east-west)
  23. end function ll_area
  24. ! ===
  25. ! Compute fraction of rectangle 1 that covers rectangle 2,
  26. ! both defined in radians.
  27. ! Fraction is equal to ratio of shaded area and area 1.
  28. !
  29. ! +-----------------+ |
  30. ! | +-----+---------+--
  31. ! | 1 |/////| |
  32. ! +-----------------+ 2 |
  33. ! | |
  34. ! --+---------------+--
  35. ! | |
  36. !
  37. real function ll_area_frac( west1, east1, south1, north1, &
  38. west2, east2, south2, north2 )
  39. ! --- in/out ----------------------------
  40. real, intent(in) :: west1, east1, south1, north1 ! rad
  41. real, intent(in) :: west2, east2, south2, north2 ! rad
  42. ! --- local ---------------------------
  43. real :: xwest2, xeast2
  44. ! --- begin -----------------------------
  45. ! check ..
  46. if ( east1 < west1 .or. east2 < west2 .or. &
  47. north1 < south1 .or. north2 < south2 ) then
  48. print *, 'found strange area:'
  49. print *, ' 1:', west1, east1, south1, north1
  50. print *, ' 2:', west2, east2, south2, north2
  51. stop 'FATAL ERROR IN ll_area_frac'
  52. end if
  53. ! shift rect 2 over 360 deg if it does not cover rect 1 at all;
  54. ! if they still not cover, the fraction will be set to zero later on:
  55. if ( west2 > east1 ) then
  56. ! cell 2 is east of cell 1; try to shift 360.0 westwards
  57. xwest2 = west2 - 2*pi
  58. xeast2 = east2 - 2*pi
  59. else if ( east2 < west1 ) then
  60. ! cell 2 is west of cell 1; try to shift 360.0 eastwards
  61. xwest2 = west2 + 2*pi
  62. xeast2 = east2 + 2*pi
  63. else
  64. ! just copy ...
  65. xwest2 = west2
  66. xeast2 = east2
  67. end if
  68. ! compute fraction; zero if rectangles do not cover:
  69. if ( (xeast2 <= west1 ) .or. (xwest2 >= east1 ) .or. &
  70. (north2 <= south1) .or. (south2 >= north1) ) then
  71. ll_area_frac = 0.0
  72. else
  73. ll_area_frac = &
  74. ll_area( max(west1 ,xwest2), min(east1 ,xeast2), &
  75. max(south1,south2), min(north1,north2) ) &
  76. / ll_area( west1, east1, south1, north1 )
  77. end if
  78. end function ll_area_frac
  79. end module grid_tools