Ticket #428: occ_point.f90

File occ_point.f90, 4.7 KB (added by Ian Culverwell, 10 years ago)

occ_point.f90

Line 
1! $Id: occ_point.f90 2019 2009-01-14 10:20:26Z frhl $
2
3!****f* Coordinates/occ_point
4!
5! NAME
6! occ_point - Determine the occultation point
7!
8! SYNOPSIS
9! call occ_point(r_leo, r_gns, lat, lon, r_coc, roc, azimuth, undulation,
10! cfile, efile)
11!
12! DESCRIPTION
13! This subroutine calculates the lowest occultation perigree point projected
14! to the Earth's surface
15!
16! INPUTS
17! r_leo cartesian LEO position vector (relative to ECF frame)
18! r_gns cartesian GPS position vector (relative to ECF frame)
19! cfile path to geoid potential coefficients file (optional)
20! efile path to geoid potential corrections file (optional)
21!
22! OUTPUT
23! lat Occultation point latitude
24! lon Occultation point longitude
25! r_coc Cartesian centre of curvature vector for occ point (ECF)
26! roc Radius of curvature value for occultation point
27! azimuth GPS to LEO azimuth direction wrt true North (deg)
28! undulation Difference between ellipsoid (WGS-84) and EGM-96 geoid (m)
29!
30! SEE ALSO
31!
32! REFERENCES
33!
34! AUTHOR
35! Met Office, Exeter, UK.
36! Any comments on this software should be given via the ROM SAF
37! Helpdesk at http://www.romsaf.org
38!
39! COPYRIGHT
40! (c) EUMETSAT. All rights reserved.
41! For further details please refer to the file COPYRIGHT
42! which you should have received as part of this distribution.
43!
44!****
45
46subroutine occ_point(r_leo, r_gns, lat, lon, r_coc, roc, azimuth, &
47 undulation, cfile,efile)
48
49! 1.1 Declarations
50! ----------------
51
52 use typesizes, only: wp => EightByteReal
53 use coordinates, not_this => occ_point
54 use EarthMod, only: datum_hmsl
55
56 implicit none
57
58 real(wp), dimension(:,:), intent(in) :: r_leo ! LEO position vector (ECF)
59 real(wp), dimension(:,:), intent(in) :: r_gns ! GPS position vector (ECF)
60 real(wp), intent(out) :: lat ! Occultation point latitude
61 real(wp), intent(out) :: lon ! Occultation point longitude
62 real(wp), dimension(size(r_leo,2)), intent(out) :: r_coc ! Centre curvature
63 real(wp), intent(out) :: roc ! Radius curvature
64 real(wp), intent(out) :: azimuth ! Azimuth (deg)
65 real(wp), intent(out) :: undulation ! Undulation
66 character(len=*), optional, intent(in) :: cfile ! Coefficient file path
67 character(len=*), optional, intent(in) :: efile ! Corrections file path
68
69 real(wp), dimension(size(r_leo,1),size(r_leo,2)) :: perigee
70 real(wp) :: slta ! Straight line tangent ht
71 real(wp) :: ro ! Length of r_leo
72 real(wp) :: alpha ! Angle r_leo and perigee
73 real(wp) :: theta ! Cross section azimuth
74 real(wp), dimension(size(r_leo,1)) :: height_per
75 real(wp), dimension(size(r_leo,1)) :: lat_per
76 real(wp), dimension(size(r_leo,1)) :: lon_per
77 real(wp), dimension(3), parameter :: pa = (/0,0,1/) ! Polar axis
78
79 integer:: i, iocc
80
81 do i=1,size(r_leo,1)
82
83! 1.2 Determine ray tangent points
84! --------------------------------
85
86 slta = impact_parameter(r_leo(i,:), r_gns(i,:))
87 ro = Sqrt(Dot_Product(r_leo(i,:), r_leo(i,:)))
88 alpha = acos(slta/ro)
89
90 perigee(i,:) = rotate(r_leo(i,:), vector_product(r_leo(i,:), r_gns(i,:)), alpha) * (slta/ro)
91
92 enddo
93
94! 1.3 Convert cartesian to geodetic points
95! ----------------------------------------
96
97 call cart2geod(perigee, lat_per, lon_per, height_per)
98
99! 1.4 Find the lowest perigee
100! ---------------------------
101
102 iocc = Sum(MinLoc(Abs(height_per)))
103
104! 1.5 Define occultation point latitude and longitude
105! ---------------------------------------------------
106
107 lat = lat_per(iocc)
108 lon = lon_per(iocc)
109
110! 1.6 Determine occultation point centre of curvature and radius
111! --------------------------------------------------------------
112
113 ! 1.6.1 Cross-section azimuth
114
115 theta = vector_angle( vector_product(perigee(iocc,:), pa), &
116 vector_product(r_gns(iocc,:), r_leo(iocc,:)), &
117 -perigee(iocc,:) )
118
119 azimuth = theta * rad2deg
120
121 if ( azimuth < 0.0_wp ) azimuth = azimuth + 360.0_wp
122
123 ! 1.6.2 Compute curvature
124
125 call curvature(lat, lon, theta, r_coc, roc)
126
127! 1.7 Find undulation - height difference between local ellipsoid and geoid
128! -------------------------------------------------------------------------
129
130 if (present(cfile) .and. present(efile)) then
131 call datum_hmsl("WGS84", (/lat, lon, 0.0_wp/), undulation, cfile, efile)
132 else
133 call datum_hmsl("WGS84", (/lat, lon, 0.0_wp/), undulation)
134 endif
135 if (undulation > -999999.000) undulation = -1.0_wp * undulation
136
137end subroutine occ_point
138
139
140