source: codes/icosagcm/trunk/src/spherical_geom.f90 @ 15

Last change on this file since 15 was 15, checked in by ymipsl, 12 years ago

Update on 3D dynamic

YM

File size: 4.0 KB
Line 
1MODULE spherical_geom_mod
2USE genmod
3
4
5
6CONTAINS
7
8
9
10
11SUBROUTINE lonlat2xyz(lon,lat,xyz)
12IMPLICIT NONE
13  REAL(rstd),INTENT(IN) :: lon
14  REAL(rstd),INTENT(IN) :: lat
15  REAL(rstd),INTENT(OUT) :: xyz(3)
16 
17  xyz(1)=cos(lon)*cos(lat)
18  xyz(2)=sin(lon)*cos(lat)
19  xyz(3)=sin(lat)
20
21END SUBROUTINE lonlat2xyz
22
23
24SUBROUTINE xyz2lonlat(xyz,lon,lat)
25IMPLICIT NONE
26  REAL(rstd),INTENT(IN) :: xyz(3)
27  REAL(rstd),INTENT(OUT) :: lon
28  REAL(rstd),INTENT(OUT) :: lat
29 
30  REAL(rstd) :: coslat
31  REAL(rstd) :: xyzn(3)
32 
33  xyzn(:)=xyz(:)/sqrt(sum(xyz(:)**2))
34 
35  lat=asin(xyzn(3))
36  coslat=cos(lat)
37  IF (abs(coslat)<1e-15) THEN
38    lon=0.
39  ELSE
40    lon=acos(MAX(MIN((xyzn(1)/coslat),1.),-1.))
41    IF (xyzn(2)/coslat<0) lon=-lon
42  ENDIF
43   
44END SUBROUTINE xyz2lonlat
45
46
47SUBROUTINE dist_cart(A,B,d)
48USE vector
49IMPLICIT NONE
50  REAL(rstd),INTENT(IN)  :: A(3)
51  REAL(rstd),INTENT(IN)  :: B(3)
52  REAL(rstd),INTENT(OUT) :: d
53 
54   REAL(rstd)  :: n(3)
55   CALL cross_product2(A,B,n)
56   d=asin(sqrt(sum(n**2)))
57
58END SUBROUTINE dist_cart
59
60
61SUBROUTINE dist_lonlat(lonA,latA,lonB,latB,d)
62IMPLICIT NONE
63  REAL(rstd),INTENT(IN)  :: lonA
64  REAL(rstd),INTENT(IN)  :: latA
65  REAL(rstd),INTENT(IN)  :: lonB
66  REAL(rstd),INTENT(IN)  :: latB
67  REAL(rstd),INTENT(OUT) :: d
68 
69  d=acos(MAX(MIN(sin(latA)*sin(latB)+cos(latA)*cos(latB)*cos(lonA-lonB),1.),-1.))
70 
71END SUBROUTINE dist_lonlat
72
73SUBROUTINE surf_triangle(A,B,C,surf)
74  REAL(rstd),INTENT(IN)  :: A(3)
75  REAL(rstd),INTENT(IN)  :: B(3)
76  REAL(rstd),INTENT(IN)  :: C(3)
77  REAL(rstd),INTENT(OUT) :: Surf
78
79  REAL(rstd)  :: AB,AC,BC
80  REAL(rstd)  :: s,x
81 
82  CALL dist_cart(A,B,AB)
83  CALL dist_cart(A,C,AC)
84  CALL dist_cart(B,C,BC)
85 
86  s=(AB+AC+BC)/2
87  x=tan(s/2) * tan((s-AB)/2)  * tan((s-AC)/2) * tan((s-BC)/2)
88  IF (x<0) x=0.
89  surf=4*atan(sqrt( x))
90 
91END SUBROUTINE surf_triangle 
92
93
94SUBROUTINE div_arc(A,B,frac,C)
95IMPLICIT NONE
96  REAL(rstd),INTENT(IN)  :: A(3)
97  REAL(rstd),INTENT(IN)  :: B(3)
98  REAL(rstd),INTENT(IN)  :: frac
99  REAL(rstd),INTENT(OUT)  :: C(3)
100 
101  REAL(rstd) :: d
102  REAL(rstd) :: M(3,3)
103  REAL(rstd) :: alpha(3,3)
104  INTEGER    :: IPIV(3)
105  INTEGER    :: info
106  REAL(rstd) :: xa,xb,xc
107  REAL(rstd) :: ya,yb,yc
108  REAL(rstd) :: za,zb,zc
109  REAL(rstd) :: alpha_A,alpha_B,alpha_C
110  REAL(rstd) :: x,y,z
111  REAL(rstd) :: a1,a2,a3
112  REAL(rstd) :: b1,b2,b3
113 
114 
115  xa=A(1) ; ya=A(2) ; za=A(3)
116  xb=B(1) ; yb=B(2) ; zb=B(3)
117
118  CALL dist_cart(A,B,d)
119
120  C(1)=cos(frac*d) 
121  C(2)=cos((1-frac)*d)
122  C(3)=0.
123
124  xc=ya*zb-yb*za ; yc=-(xa*zb-xb*za) ; zc=xa*yb-xb*ya
125 
126  M(1,1)=xa ; M(1,2)=ya ; M(1,3)=za
127  M(2,1)=xb ; M(2,2)=yb ; M(2,3)=zb
128  M(3,1)=xc ; M(3,2)=yc ; M(3,3)=zc
129  stop 'STOP'
130!  CALL DGESV(3,1,M,3,IPIV,C,3,info)
131 
132END SUBROUTINE div_arc
133
134SUBROUTINE div_arc_bis(A,B,frac,C)
135IMPLICIT NONE
136  REAL(rstd),INTENT(IN)  :: A(3)
137  REAL(rstd),INTENT(IN)  :: B(3)
138  REAL(rstd),INTENT(IN)  :: frac
139  REAL(rstd),INTENT(OUT)  :: C(3)
140 
141   C=A*(1-frac)+B*frac 
142   C=C/sqrt(sum(C**2))
143END SUBROUTINE div_arc_bis
144
145
146  SUBROUTINE circumcenter(A0,B0,C0,Center)
147  USE vector
148  IMPLICIT NONE
149    REAL(rstd), INTENT(IN)  :: A0(3),B0(3),C0(3)
150    REAL(rstd), INTENT(OUT) :: Center(3)
151   
152    REAL(rstd)  :: a(3),b(3),c(3)
153   
154    a=A0/sqrt(sum(A0**2))
155    b=B0/sqrt(sum(B0**2))
156    c=C0/sqrt(sum(C0**2))
157   
158    CALL Cross_product2(b-a,c-b,center)
159    center=center/sqrt(sum(center**2))
160   
161  END SUBROUTINE circumcenter
162   
163
164  SUBROUTINE compute_centroid(points,n,centr)
165  USE vector
166  IMPLICIT NONE
167    INTEGER :: n
168    REAL(rstd), INTENT(IN)  :: points(3,n)
169    REAL(rstd), INTENT(OUT) :: Centr(3)
170   
171    REAL(rstd) :: p1(3),p2(3),cross(3)
172    REAL(rstd) :: norm_cross
173    INTEGER :: i,j
174     
175      Centr(:)=0
176      DO i=1,n
177        j=MOD(i,n)+1
178        p1=points(:,i)/norm(points(:,i))
179        p2=points(:,j)/norm(points(:,j))
180        CALL cross_product2(p1,p2,cross)
181        norm_cross=norm(cross)
182        if (norm_cross<1e-10) CYCLE
183       
184        Centr(:)=centr(:)+asin(norm_cross)*cross(:)/norm_cross
185      ENDDO
186     
187      Centr(:)=centr(:)/norm(centr(:))
188 
189  END SUBROUTINE compute_centroid
190
191END MODULE spherical_geom_mod
192
193
Note: See TracBrowser for help on using the repository browser.