NCEPLIBS-g2 4.0.0
Loading...
Searching...
No Matches
g2spec.F90
Go to the documentation of this file.
1
7
24subroutine specpack(fld,ndpts,JJ,KK,MM,idrstmpl,cpack,lcpack)
25
26 real,intent(in) :: fld(ndpts)
27 integer,intent(in) :: ndpts,JJ,KK,MM
28 integer,intent(inout) :: idrstmpl(*)
29 character(len=1),intent(out) :: cpack(*)
30 integer,intent(out) :: lcpack
31
32 integer :: Ts,tmplsim(5)
33 real :: bscale,dscale,unpk(ndpts),tfld(ndpts)
34 real,allocatable :: pscale(:)
35
36 bscale = 2.0**real(-idrstmpl(2))
37 dscale = 10.0**real(idrstmpl(3))
38 nbits = idrstmpl(4)
39 js=idrstmpl(6)
40 ks=idrstmpl(7)
41 ms=idrstmpl(8)
42 ts=idrstmpl(9)
43
44 ! Calculate Laplacian scaling factors for each possible wave number.
45 allocate(pscale(jj+mm))
46 tscale=real(idrstmpl(5))*1e-6
47 do n=js,jj+mm
48 pscale(n)=real(n*(n+1))**(tscale)
49 enddo
50
51 ! Separate spectral coeffs into two lists; one to contain unpacked
52 ! values within the sub-spectrum Js, Ks, Ms, and the other with
53 ! values outside of the sub-spectrum to be packed.
54 inc=1
55 incu=1
56 incp=1
57 do m=0,mm
58 nm=jj ! triangular or trapezoidal
59 if (kk .eq. jj+mm) nm=jj+m ! rhombodial
60 ns=js ! triangular or trapezoidal
61 if (ks .eq. js+ms) ns=js+m ! rhombodial
62 do n=m,nm
63 if (n.le.ns .AND. m.le.ms) then ! save unpacked value
64 unpk(incu)=fld(inc) ! real part
65 unpk(incu+1)=fld(inc+1) ! imaginary part
66 inc=inc+2
67 incu=incu+2
68 else
69 ! Save value to be packed and scale Laplacian scale factor.
70 tfld(incp)=fld(inc)*pscale(n) ! real part
71 tfld(incp+1)=fld(inc+1)*pscale(n) ! imaginary part
72 inc=inc+2
73 incp=incp+2
74 endif
75 enddo
76 enddo
77
78 deallocate(pscale)
79
80 incu=incu-1
81 if (incu .ne. ts) then
82 print *,'specpack: Incorrect number of unpacked values ', 'given:',ts
83 print *,'specpack: Resetting idrstmpl(9) to ',incu
84 ts=incu
85 endif
86
87 ! Add unpacked values to the packed data array in 32-bit IEEE format.
88 call mkieee(unpk,cpack,ts)
89 ipos=4*ts
90
91 ! Scale and pack the rest of the coefficients.
92 tmplsim(2)=idrstmpl(2)
93 tmplsim(3)=idrstmpl(3)
94 tmplsim(4)=idrstmpl(4)
95 call simpack(tfld,ndpts-ts,tmplsim,cpack(ipos+1),lcpack)
96 lcpack=lcpack+ipos
97
98 ! Fill in Template 5.51.
99 idrstmpl(1)=tmplsim(1)
100 idrstmpl(2)=tmplsim(2)
101 idrstmpl(3)=tmplsim(3)
102 idrstmpl(4)=tmplsim(4)
103 idrstmpl(9)=ts
104 idrstmpl(10)=1 ! Unpacked spectral data is 32-bit IEEE
105
106end subroutine specpack
107
123subroutine specunpack(cpack, len, idrstmpl, ndpts, JJ, KK, MM, fld)
124
125 character(len = 1), intent(in) :: cpack(len)
126 integer, intent(in) :: ndpts, len, JJ, KK, MM
127 integer, intent(in) :: idrstmpl(*)
128 real, intent(out) :: fld(ndpts)
129
130 integer :: ifld(ndpts), Ts
131 integer(4) :: ieee
132 real :: ref, bscale, dscale, unpk(ndpts)
133 real, allocatable :: pscale(:)
134
135 ieee = idrstmpl(1)
136 call rdieee(ieee, ref, 1)
137 bscale = 2.0**real(idrstmpl(2))
138 dscale = 10.0**real(-idrstmpl(3))
139 nbits = idrstmpl(4)
140 js = idrstmpl(6)
141 ks = idrstmpl(7)
142 ms = idrstmpl(8)
143 ts = idrstmpl(9)
144
145 if (idrstmpl(10) .eq. 1) then ! unpacked floats are 32-bit IEEE
146 call rdieeec(cpack, unpk, ts) ! read IEEE unpacked floats
147 iofst = 32 * ts
148 call g2_gbytesc(cpack, ifld, iofst, nbits, 0, ndpts - ts) ! unpack scaled data
149
150 ! Calculate Laplacian scaling factors for each possible wave number.
151 allocate(pscale(jj + mm))
152 tscale = real(idrstmpl(5)) * 1e-6
153 do n = js, jj + mm
154 pscale(n) = real(n * (n + 1))**(-tscale)
155 enddo
156
157 ! Assemble spectral coeffs back to original order.
158 inc = 1
159 incu = 1
160 incp = 1
161 do m = 0, mm
162 nm = jj ! triangular or trapezoidal
163 if (kk .eq. jj + mm) nm = jj + m ! rhombodial
164 ns = js ! triangular or trapezoidal
165 if (ks .eq. js + ms) ns = js + m ! rhombodial
166 do n = m, nm
167 if (n .le. ns .AND. m .le. ms) then ! grab unpacked value
168 fld(inc) = unpk(incu) ! real part
169 fld(inc + 1) = unpk(incu + 1) ! imaginary part
170 inc = inc + 2
171 incu = incu + 2
172 else ! Calc coeff from packed value
173 fld(inc) = ((real(ifld(incp))*bscale) + ref)*dscale*pscale(n) ! real part
174 fld(inc + 1) = ((real(ifld(incp + 1)) * bscale) + ref) * dscale * pscale(n) ! imaginary part
175 inc = inc + 2
176 incp = incp + 2
177 endif
178 enddo
179 enddo
180 deallocate(pscale)
181 else
182 print *, 'specunpack: Cannot handle 64 or 128-bit floats.'
183 fld = 0.0
184 endif
185end subroutine specunpack
subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n)
Extract arbitrary size big-endian integer values (up to 32 bits each) from a packed bit string.
Definition g2bytes.F90:120
subroutine rdieee(rieee, a, num)
Copy array of 32-bit IEEE floating point values to local floating point representation.
Definition g2bytes.F90:637
subroutine mkieee(a, rieee, num)
Copy an array of real to an array of 32-bit IEEE floating points.
Definition g2bytes.F90:685
subroutine rdieeec(cieee, a, num)
Copy array of 32-bit IEEE floating point values stored in char array to local floating point represen...
Definition g2bytes.F90:607
subroutine simpack(fld, ndpts, idrstmpl, cpack, lcpack)
Pack a data field using a simple packing algorithm.
Definition g2sim.F90:27
subroutine specunpack(cpack, len, idrstmpl, ndpts, jj, kk, mm, fld)
Unpack a spectral data field using the complex packing algorithm for spherical harmonic data,...
Definition g2spec.F90:124
subroutine specpack(fld, ndpts, jj, kk, mm, idrstmpl, cpack, lcpack)
Pack a spectral data field using the complex packing algorithm for spherical harmonic data as defined...
Definition g2spec.F90:25