SICOPOLIS V3.0
 All Classes Files Functions Variables Macros
geo_coord.F90
Go to the documentation of this file.
1 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 !
3 ! Subroutine : g e o _ c o o r d
4 !
5 !> @file
6 !!
7 !! Computation of longitude lambda and latitude phi for position (x,y) in the
8 !! numerical domain.
9 !!
10 !! @section Copyright
11 !!
12 !! Copyright 2009-2013 Ralf Greve, Reinhard Calov, Alex Robinson
13 !!
14 !! @section License
15 !!
16 !! This file is part of SICOPOLIS.
17 !!
18 !! SICOPOLIS is free software: you can redistribute it and/or modify
19 !! it under the terms of the GNU General Public License as published by
20 !! the Free Software Foundation, either version 3 of the License, or
21 !! (at your option) any later version.
22 !!
23 !! SICOPOLIS is distributed in the hope that it will be useful,
24 !! but WITHOUT ANY WARRANTY; without even the implied warranty of
25 !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 !! GNU General Public License for more details.
27 !!
28 !! You should have received a copy of the GNU General Public License
29 !! along with SICOPOLIS. If not, see <http://www.gnu.org/licenses/>.
30 !<
31 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32 
33 !-------------------------------------------------------------------------------
34 !> Computation of longitude lambda and latitude phi for position (x,y) in the
35 !! numerical domain.
36 !<------------------------------------------------------------------------------
37 subroutine geo_coord(phi_val, lambda_val, x_val, y_val)
38 
39 use sico_types
41 
42 implicit none
43 
44 real(dp), intent(in) :: x_val, y_val
45 
46 real(dp), intent(out) :: lambda_val, phi_val
47 
48 real(dp) :: k
49 
50 #if (GRID==0 || GRID==1)
51 
52 !-------- Inverse stereographic projection --------
53 
54 call stereo_inv_ellipsoid(x_val, y_val, a, b, &
55  lambda0, phi0, lambda_val, phi_val)
56 
57 #elif GRID==2
58 
59 !-------- Identity --------
60 
61 lambda_val = x_val
62 phi_val = y_val
63 
64 #endif
65 
66 end subroutine geo_coord
67 
68 !-------------------------------------------------------------------------------
69 !> Inverse stereographic projection for an ellipsoidal planet.
70 !<------------------------------------------------------------------------------
71 subroutine stereo_inv_ellipsoid(x_val, y_val, A, B, &
72  lambda0, phi0, lambda_val, phi_val)
73 
74 use sico_types
75 
76 implicit none
77 real(dp), intent(in) :: x_val, y_val, a, b, lambda0, phi0
78 real(dp), intent(out) :: lambda_val, phi_val
79 
80 integer(i4b) :: l
81 integer(i4b) :: sign_phi0
82 real(dp) :: phi_aux, phi0_aux
83 real(dp) :: e, mc, t, tc, kp, rho, phi_p, residual
84 real(dp) :: sinphi0, sinlambda0, cosphi0, coslambda0
85 
86 real(dp), parameter :: pi = 3.141592653589793_dp, &
87  eps = 1.0e-05_dp, &
88  eps_residual = 1.0e-09_dp
89 
90 if (phi0 > eps) then ! for northern hemisphere
91  sign_phi0 = 1
92 else if (phi0 < (-eps)) then ! for southern hemisphere
93  sign_phi0 = -1
94 else
95  stop ' geo_coord: phi0 must be different from zero!'
96 end if
97 
98 phi0_aux = phi0 * sign_phi0
99 
100 e=sqrt((a**2-b**2)/(a**2))
101 
102 sinphi0 = sin(phi0_aux)
103 sinlambda0 = sin(lambda0)
104 cosphi0 = cos(phi0_aux)
105 coslambda0 = cos(lambda0)
106 
107 tc=sqrt(((1.0_dp-sinphi0)/(1.0_dp+sinphi0))* &
108  ((1.0_dp+e*sinphi0)/(1.0_dp-e*sinphi0))**e)
109 mc=cosphi0/sqrt(1.0_dp-e*e*sinphi0*sinphi0)
110 rho=sqrt(x_val*x_val+y_val*y_val)
111 t=rho*tc/(a*mc)
112 
113 lambda_val = lambda0 + sign_phi0*atan2(y_val,x_val) + 0.5_dp*pi
114 
115 ! fix point iteration
116 
117 phi_p=0.5_dp*pi-2.0_dp*atan(t)
118 l=0
119 residual=3600.0_dp
120 do while(residual >= eps_residual)
121  l=l+1
122  phi_aux=0.5_dp*pi-2.0_dp*atan(t*((1.0_dp-e*sin(phi_p))/ &
123  (1.0_dp+e*sin(phi_p)))**(0.5_dp*e))
124  residual=abs(phi_aux-phi_p)
125  phi_p=phi_aux
126 end do
127 
128 phi_val = phi_aux * sign_phi0
129 
130 if (lambda_val < 0.0_dp) then
131  lambda_val = lambda_val + 2.0_dp*pi
132 else if (lambda_val >= (2.0_dp*pi)) then
133  lambda_val = lambda_val - 2.0_dp*pi
134 end if
135 
136 end subroutine stereo_inv_ellipsoid
137 !