forked from NOAA-PSL/stochastic_physics
-
Notifications
You must be signed in to change notification settings - Fork 1
/
glats_stochy.f
115 lines (109 loc) · 3.4 KB
/
glats_stochy.f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
!>@brief The module 'glats_stochy_mod' contains the subroute glats_stochy
module glats_stochy_mod
implicit none
contains
!>@brief The subroutine 'glats_stochy' calculate the latitudes for the gaussian grid
!>@details This code is taken from the legacy spectral GFS
subroutine glats_stochy(lgghaf,colrad,wgt,wgtcs,rcs2,iprint)
!
! Jan 2013 Henry Juang increase precision by kind_qdt_prec=16
! to help wgt (Gaussian weighting)
use kinddef
implicit none
integer iter,k,k1,l2,lgghaf,iprint
!
! increase precision for more significant digit to help wgt
real(kind=kind_qdt_prec) drad,dradz,p1,p2,phi,pi,rad,rc
! real(kind=kind_qdt_prec) drad,dradz,eps,p1,p2,phi,pi,rad,rc
real(kind=kind_qdt_prec) rl2,scale,si,sn,w,x
!
real(kind=kind_dbl_prec), dimension(lgghaf) :: colrad, wgt,
& wgtcs, rcs2
!
real(kind=kind_dbl_prec), parameter :: cons0 = 0.d0, cons1 = 1.d0,
& cons2 = 2.d0, cons4 = 4.d0,
& cons180 = 180.d0,
& cons360 = 360.d0,
& cons0p25 = 0.25d0
real(kind=kind_qdt_prec), parameter :: eps = 1.d-20
!
! for better accuracy to select smaller number
! eps = 1.d-12
! eps = 1.d-20
!
if(iprint == 1) print 101
101 format (' i colat colrad wgt', 12x, 'wgtcs',
& 10x, 'iter res')
si = cons1
l2 = 2*lgghaf
rl2 = l2
scale = cons2/(rl2*rl2)
k1 = l2-1
pi = atan(si)*cons4
! dradz = pi / cons360 / 10.0
! for better accuracy to start iteration
dradz = pi / float(lgghaf) / 200.0
rad = cons0
do k=1,lgghaf
iter = 0
drad = dradz
1 call poly(l2,rad,p2)
2 p1 = p2
iter = iter + 1
rad = rad + drad
call poly(l2,rad,p2)
if(sign(si,p1) == sign(si,p2)) go to 2
if(drad < eps)go to 3
rad = rad-drad
drad = drad * cons0p25
go to 1
3 continue
colrad(k) = rad
phi = rad * cons180 / pi
call poly(k1,rad,p1)
x = cos(rad)
w = scale * (cons1 - x*x)/ (p1*p1)
wgt(k) = w
sn = sin(rad)
w = w/(sn*sn)
wgtcs(k) = w
rc = cons1/(sn*sn)
rcs2(k) = rc
call poly(l2,rad,p1)
if(iprint == 1)
& print 102,k,phi,colrad(k),wgt(k),wgtcs(k),iter,p1
102 format(1x,i3,2x,f6.2,2x,f10.7,2x,e14.7,2x,e14.7,2x,i4,2x,e14.7)
enddo
if(iprint == 1) print 100,lgghaf
100 format(1h ,'shalom from 0.0e0 glats for ',i3)
!
return
end
!>@brief The subroutine 'poly' does something with latitudes
!>@details This code is taken from the legacy spectral GFS
subroutine poly(n,rad,p)
use kinddef
!
implicit none
!
integer i,n
!
! increase precision for more significant digit to help wgt
real(kind=kind_qdt_prec) floati,g,p,rad,x,y1,y2,y3
!
real(kind=kind_dbl_prec), parameter :: cons1 = 1.d0
!
x = cos(rad)
y1 = cons1
y2 = x
do i=2,n
g = x*y2
floati = i
y3 = g - y1 + g - (g-y1)/floati
y1 = y2
y2 = y3
enddo
p = y3
return
end
end module glats_stochy_mod