SURFEX v8.1
General documentation of Surfex
fitspectrum_mod.F90
Go to the documentation of this file.
2 
3 USE parkind1 ,ONLY : jpim ,jprb
4 USE yomhook ,ONLY : lhook, dr_hook
5 
6 IMPLICIT NONE
7 
8 PRIVATE
9 PUBLIC fitspectrum
10 
11 CONTAINS
12 
13 SUBROUTINE fitspectrum(KSMAX,KSPEC2G,PSPEC,KSTRUNK,PBETA0,PBETA1)
14 
15 
16 
17 !**** *FITSPECTRUM* - linear fit of spectrum to (n*(n+1))**P
18 
19 ! Purpose. GRIB allows for "complex packing" of spectral
20 ! -------- coeficients. This means that a sub-spectrum
21 ! is not packed and for the rest a multiplying
22 ! factor of (n*(n+1))**p, where n is the total
23 ! wave-number, is applied before packing. This routine
24 ! produces an optimal P (-PBETA1) based on the field
25 ! itself.
26 
27 !** Interface.
28 ! ----------
29 ! *CALL* *FITSPECTRUM(...)
30 
31 ! Explicit arguments : KSMAX - spectral field truncation
32 ! -------------------- KSPEC2G - size of spectral field array
33 ! PSPEC - spectral field
34 ! KSTRUNK - truncation of "non-packed"
35 ! part of spectrum
36 ! PBETA0 - linear fit par. (output)
37 ! PBETA1 - linear fit par. (output)
38 
39 ! Implicit arguments :
40 ! --------------------
41 
42 ! Method.
43 ! -------
44 ! If F(n,m) = (n*(n+1))**(-P) * G(n,m) where F(n,m) is the
45 ! original spectral field and n the total wavenumber the aim
46 ! is to minimize G in a 1 norm with respect to P.This can only
47 ! partially be achieved. What we do is to to compute H(n) where
48 ! H(n)=max(F(n,m)) with respect to m. We then perform a least
49 ! square fit for the equation log(H(n))=beta0+beta1*log(n*(n+1)).
50 ! To ensure a better fit for the lower end of the spectrum we
51 ! apply an (arbitrary) weighting funtion W(n)=1./(n-kstrunk+1)
52 ! before fitting.
53 
54 ! Externals.
55 ! ----------
56 
57 ! Reference.
58 ! ----------
59 ! Seber, G.A.F. (1979). Linear Regression Analyses.
60 ! John Wiley and Sons
61 
62 ! ECMWF Research Department documentation of the IFS
63 
64 ! Author.
65 ! -------
66 ! Mats Hamrud *ECMWF*
67 
68 ! Modifications.
69 ! --------------
70 ! Original : 94-05-05
71 ! Modified 95-06-06 by L.Isaksen : Reordering of spectral arrays
72 ! Modified 02-04-03 Y. Tremolet : Resolution different from NSMAX
73 ! M.Hamrud 01-Oct-2003 CY28 Cleaning
74 ! ------------------------------------------------------------------
75 
76 
77 INTEGER(KIND=JPIM),INTENT(IN) :: KSPEC2G
78 INTEGER(KIND=JPIM),INTENT(IN) :: KSMAX
79 REAL(KIND=JPRB) ,INTENT(IN) :: PSPEC(kspec2g)
80 INTEGER(KIND=JPIM),INTENT(IN) :: KSTRUNK
81 REAL(KIND=JPRB) ,INTENT(OUT) :: PBETA0
82 REAL(KIND=JPRB) ,INTENT(OUT) :: PBETA1
83 REAL(KIND=JPRB) :: ZW(0:ksmax),ZNORM(0:ksmax)
84 
85 INTEGER(KIND=JPIM) :: INM, ISMIN, JIR, JM, JN
86 INTEGER(KIND=JPIM) :: IASM0G(0:ksmax)
87 
88 REAL(KIND=JPRB) :: Z, ZEPS, ZSUM1, ZSUM2, ZWSUM, ZX, ZXMW, ZY, ZYMW, ZZ
89 REAL(KIND=JPRB) :: ZHOOK_HANDLE
90 
91 ! ------------------------------------------------------------------
92 
93 IF (lhook) CALL dr_hook('FITSPECTRUM',0,zhook_handle)
94 inm=1
95 DO jm=0,ksmax
96  iasm0g(jm)=inm
97  inm=inm+(ksmax+1-jm)*2
98 ENDDO
99 
100 !* 1. BEST FIT.
101 ! ---------
102 
103 !* 1.1 INITIAL COMPUTATIONS
104 
105 ismin = kstrunk+1
106 zeps = epsilon(z)
107 
108 !* 1.2 SET UP WEIGHTS
109 
110 zz=REAL(ksmax-ismin+1,jprb)
111 DO jn=ismin,ksmax
112  zw(jn) = zz/REAL(jn-ismin+1,jprb)
113 ENDDO
114 
115 !* 1.3 COMPUTE NORMS
116 
117 DO jn=ismin,ksmax
118  znorm(jn) = 0.0_jprb
119 ENDDO
120 DO jm=0,ksmax
121  DO jir=0,min(1,jm)
122  DO jn=max(ismin,jm),ksmax
123  inm=iasm0g(jm)+(jn-jm)*2+jir
124  znorm(jn) = max(znorm(jn),abs(pspec(inm)))
125  ENDDO
126  ENDDO
127 ENDDO
128 DO jn=ismin,ksmax
129  znorm(jn)=max(znorm(jn),zeps)
130  IF(znorm(jn) == zeps) THEN
131  zw(jn) = 100._jprb*zeps
132  ENDIF
133 ENDDO
134 
135 !* 1.4 LINEAR FIT
136 
137 zxmw = 0.0_jprb
138 zymw = 0.0_jprb
139 zwsum = 0.0_jprb
140 DO jn=ismin,ksmax
141  zx = log(REAL(JN*(JN+1),JPRB))
142  zy = log(znorm(jn))
143  zxmw = zxmw+zx*zw(jn)
144  zymw = zymw+zy*zw(jn)
145  zwsum = zwsum+zw(jn)
146 ENDDO
147 zxmw = zxmw/zwsum
148 zymw = zymw/zwsum
149 zsum1 = 0.0_jprb
150 zsum2 = 0.0_jprb
151 DO jn=ismin,ksmax
152  zx = log(REAL(JN*(JN+1),JPRB))
153  zy = log(znorm(jn))
154  zsum1 = zsum1+zw(jn)*(zy-zymw)*(zx-zxmw)
155  zsum2 = zsum2+zw(jn)*(zx-zxmw)**2
156 ENDDO
157 
158 pbeta1 = zsum1/zsum2
159 pbeta0 = zymw-pbeta1*zxmw
160 
161 ! ------------------------------------------------------------------
162 
163 IF (lhook) CALL dr_hook('FITSPECTRUM',1,zhook_handle)
164 END SUBROUTINE fitspectrum
165 
166 END MODULE fitspectrum_mod
integer, parameter jpim
Definition: parkind1.F90:13
integer, parameter jprb
Definition: parkind1.F90:32
subroutine, public fitspectrum(KSMAX, KSPEC2G, PSPEC, KSTRUNK, PBETA0, PBETA1)
logical lhook
Definition: yomhook.F90:15