PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/WPS/ungrib/src/rd_grib1.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 612 lines | 412 code | 49 blank | 151 comment | 59 complexity | dd01f9d61a4cb5889e327ee78ce0115c MD5 | raw file
Possible License(s): AGPL-1.0
  1. !*****************************************************************************!
  2. ! Subroutine RD_GRIB1 !
  3. ! !
  4. ! Purpose: !
  5. ! Read one record from the input GRIB file. Based on the information in !
  6. ! the GRIB header and the user-defined Vtable, decide whether the field in !
  7. ! the GRIB record is one to process or to skip. If the field is one we !
  8. ! want to keep, extract the data from the GRIB record, and pass the data !
  9. ! back to the calling routine. !
  10. ! !
  11. ! Argument list: !
  12. ! Input: !
  13. ! IUNIT : "Unit Number" to open and read from. Not really a Fortran !
  14. ! unit number, since we do not do Fortran I/O for the GRIB !
  15. ! files. Nor is it a UNIX File Descriptor returned from a C !
  16. ! OPEN statement. It is really just an array index to the !
  17. ! array (IUARR) where the UNIX File Descriptor values are !
  18. ! stored. !
  19. ! GRIBFLNM: File name to open, if it is not already open. !
  20. ! IUARR : Array to hold UNIX File descriptors retured from a C open !
  21. ! statement. If the value of IUARR(IUNIT) is zero, then the !
  22. ! file GRIBFLNM must be opened, and the value of IUARR(IUNIT) !
  23. ! becomes the UNIX File descriptor to read from. !
  24. ! DEBUG_LEVEL Integer for various amounts of printout. !
  25. ! !
  26. ! Output: !
  27. ! LEVEL : The pressure-level (Pa) of the field to process. !
  28. ! FIELD : The field name of the field to process. NULL is returned !
  29. ! if we do not want to process the field we read. !
  30. ! HDATE : The 19-character date of the field to process. !
  31. ! IERR : Error flag: 0 - no error on read from GRIB file. !
  32. ! 1 - Hit the end of the GRIB file. !
  33. ! 2 - The file GRIBFLNM we tried to open does !
  34. ! not exist. !
  35. ! Externals !
  36. ! Module TABLE !
  37. ! Module GRIDINFO !
  38. ! Subroutine C_OPEN !
  39. ! Subroutine DEALLOGRIB !
  40. ! Subroutine GRIBGET !
  41. ! Subroutine GRIBHEADER !
  42. ! Subroutine GET_SEC1 !
  43. ! Subroutine GET_SEC2 !
  44. ! Subroutine GET_GRIDINFO !
  45. ! Subroutine BUILD_HDATE !
  46. ! Subroutine GETH_NEWDATE !
  47. ! Subroutine GRIBDATA !
  48. ! !
  49. ! Side Effects !
  50. ! File GRIBFLNM is opened, as necessary !
  51. ! !
  52. ! Variable MAP from module GRIDINFO is filled in. !
  53. ! !
  54. ! Numerous side effects from the GRIB-processing routines. !
  55. ! !
  56. ! Kevin W. Manning !
  57. ! NCAR/MMM !
  58. ! Summer, 1998, and continuing !
  59. ! SDG !
  60. ! !
  61. !*****************************************************************************!
  62. SUBROUTINE rd_grib1(IUNIT, gribflnm, level, field, hdate, &
  63. ierr, iuarr, debug_level)
  64. use table
  65. use gridinfo
  66. use datarray
  67. use module_debug
  68. implicit none
  69. integer :: debug_level
  70. integer :: iunit ! Array number in IUARR assigned to the C read pointer.
  71. integer, dimension(100) :: KSEC1
  72. integer, dimension(10) :: KSEC2
  73. integer, dimension(40) :: infogrid
  74. real, dimension(40) :: ginfo
  75. !
  76. !-----------------------------------------------------------------------
  77. integer :: iparm, ktype
  78. logical :: lopen
  79. integer :: icenter, iprocess, iscan, ii, isb
  80. integer year, month, day, hour, minute, second, icc, iyy
  81. integer :: fcst
  82. real :: level
  83. character(LEN=*) :: field
  84. character(LEN=132) :: gribflnm
  85. character(LEN=8) :: tmp8
  86. integer, dimension(255) :: iuarr
  87. integer :: ierr, iostat, nunit
  88. integer :: i, lvl2, lvl1
  89. character(LEN=19) :: hdate
  90. integer :: igherr
  91. ! Variables for thinned grids:
  92. logical :: lthinned = .FALSE.
  93. real, allocatable, dimension(:) :: thinnedDataArray
  94. integer, dimension(74) :: npoints_acc
  95. real :: mj, xmj
  96. integer :: np, ny, nx
  97. real :: Va, Vb, Vc, Vd
  98. real, external :: oned
  99. ierr = 0
  100. ! If the file GRIBFLNM has not been opened, then IUARR(IUNIT) should be Zero.
  101. ! In this case, open the file GRIBFLNM, and store the UNIX File descriptor
  102. ! in to IUARR(IUNIT). This way, we will know what UNIX File descriptor to use
  103. ! next time we call this RD_GRIB subroutine.
  104. !
  105. if (iuarr(iunit).eq.0) then
  106. if (debug_level.gt.0) then
  107. call c_open(iunit, nunit, gribflnm, 1, ierr, 1)
  108. else
  109. call c_open(iunit, nunit, gribflnm, 1, ierr, -1)
  110. endif
  111. if (ierr.ne.0) then
  112. call deallogrib
  113. ierr = 2
  114. return
  115. endif
  116. iuarr(iunit) = nunit
  117. endif
  118. ! Read a single GRIB record, but do no unpacking now:
  119. call gribget(iuarr(iunit), ierr)
  120. if (ierr.ne.0) then
  121. call mprintf(.true.,DEBUG,"RD_GRIB1 gribget read error, ierr = %i",i1=ierr)
  122. call deallogrib
  123. return
  124. endif
  125. !
  126. ! Unpack the header information:
  127. !
  128. call gribheader(debug_level,igherr)
  129. if (igherr /= 0) then
  130. field = "NULL"
  131. call deallogrib
  132. return
  133. endif
  134. !
  135. ! Copy header information to arrays KSEC1, KSEC2, INFOGRID, and GRIDINFO
  136. !
  137. call get_sec1(ksec1)
  138. call get_sec2(ksec2)
  139. call get_gridinfo(infogrid, ginfo)
  140. icenter = KSEC1(3) ! Indicator of the source (center) of the data.
  141. iprocess = KSEC1(4) ! Indicator of model (or whatever) which generated the data.
  142. if (icenter.eq.7) then
  143. if (iprocess.eq.83 .or. iprocess.eq.84) then
  144. map%source = 'NCEP MESO NAM Model'
  145. elseif (iprocess.eq.81) then
  146. map%source = 'NCEP GFS Analysis'
  147. elseif (iprocess.eq.82) then
  148. map%source = 'NCEP GFS GDAS/FNL'
  149. elseif (iprocess.eq.89) then
  150. map%source = 'NCEP NMM '
  151. elseif (iprocess.eq.96) then
  152. map%source = 'NCEP GFS Model'
  153. elseif (iprocess.eq.107) then
  154. map%source = 'NCEP GEFS'
  155. elseif (iprocess.eq.109) then
  156. map%source = 'NCEP RTMA'
  157. elseif (iprocess.eq.86 .or. iprocess.eq.100) then
  158. map%source = 'NCEP RUC Model' ! 60 km
  159. elseif (iprocess.eq.101) then
  160. map%source = 'NCEP RUC Model' ! 40 km
  161. elseif (iprocess.eq.105) then
  162. map%source = 'NCEP RUC Model' ! 20 km
  163. elseif (iprocess.eq.140) then
  164. map%source = 'NCEP NARR'
  165. elseif (iprocess.eq.195) then
  166. map%source = 'NCEP CDAS2'
  167. elseif (iprocess.eq.44) then
  168. map%source = 'NCEP SST Analysis'
  169. elseif (iprocess.eq.70) then
  170. map%source = 'GFDL Hurricane Model'
  171. elseif (iprocess.eq.129) then
  172. map%source = 'NCEP GODAS'
  173. elseif (iprocess.eq.25) then
  174. map%source = 'NCEP SNOW COVER ANALYSIS'
  175. else
  176. map%source = 'unknown model from NCEP'
  177. end if
  178. ! grid numbers only set for NCEP and AFWA models
  179. write(tmp8,'("GRID ",i3)') KSEC1(5)
  180. map%source(25:32) = tmp8
  181. else if (icenter .eq. 57) then
  182. if (iprocess .eq. 87) then
  183. map%source = 'AFWA AGRMET'
  184. else
  185. map%source = 'AFWA'
  186. endif
  187. write(tmp8,'("GRID ",i3)') KSEC1(5)
  188. map%source(25:32) = tmp8
  189. else if (icenter .eq. 58) then
  190. map%source = 'US Navy FNOC'
  191. else if (icenter .eq. 59) then
  192. if (iprocess .eq. 120) then
  193. map%source = 'NOAA GSD Rapid Refresh'
  194. else
  195. map%source = 'NOAA GSD'
  196. endif
  197. else if (icenter .eq. 60) then
  198. map%source = 'NCAR'
  199. else if (icenter .eq. 98) then
  200. map%source = 'ECMWF'
  201. else if (icenter .eq. 74 .or. icenter .eq. 75 ) then
  202. map%source = 'UKMO'
  203. else
  204. map%source = 'unknown model and orig center'
  205. end if
  206. IPARM=KSEC1(7) ! Indicator of parameter
  207. KTYPE=KSEC1(8) ! Indicator of type of level
  208. ! print *,' IPARM, KTYPE, KSEC1(9)', iparm,ktype,ksec1(9)
  209. IF(KTYPE.EQ.1) THEN
  210. LVL1=KSEC1(9)
  211. LVL2=-99
  212. ELSEIF(KTYPE.EQ.100) THEN
  213. LVL1=FLOAT(KSEC1(9)) * 100.
  214. LVL2=-99
  215. ELSEIF(KTYPE.EQ.101) THEN
  216. LVL1=KSEC1(9)
  217. LVL2=KSEC1(10)
  218. ELSEIF(KTYPE.EQ.102) THEN
  219. LVL1=KSEC1(9)
  220. LVL2=-99
  221. ELSEIF(KTYPE.EQ.103) THEN
  222. LVL1=KSEC1(9)
  223. LVL2=-99
  224. ELSEIF(KTYPE.EQ.105) THEN
  225. LVL1=KSEC1(9)
  226. LVL2=-99
  227. ELSEIF(KTYPE.EQ.107) THEN
  228. LVL1=KSEC1(9)
  229. LVL2=-99
  230. ELSEIF(KTYPE.EQ.109) THEN
  231. LVL1=KSEC1(9)
  232. LVL2=-99
  233. ELSEIF(KTYPE.EQ.111) THEN
  234. LVL1=KSEC1(9)
  235. LVL2=-99
  236. ELSEIF(KTYPE.EQ.112) THEN ! Layer between two depths below surface
  237. LVL1=KSEC1(9)
  238. LVL2=KSEC1(10)
  239. ELSEIF(KTYPE.EQ.113) THEN
  240. LVL1=KSEC1(9)
  241. LVL2=-99
  242. ELSEIF(KTYPE.EQ.115) THEN
  243. LVL1=KSEC1(9)
  244. LVL2=-99
  245. ELSEIF(KTYPE.EQ.117) THEN
  246. LVL1=KSEC1(9)
  247. LVL2=-99
  248. ELSEIF(KTYPE.EQ.119) THEN
  249. LVL1=KSEC1(9)
  250. LVL2=-99
  251. ELSEIF(KTYPE.EQ.125) THEN
  252. LVL1=KSEC1(9)
  253. LVL2=-99
  254. ELSEIF(KTYPE.EQ.160) THEN
  255. LVL1=KSEC1(9)
  256. LVL2=-99
  257. ELSEIF(KTYPE.EQ.200) THEN
  258. LVL1=0
  259. LVL2=-99
  260. ELSEIF(KTYPE.EQ.201) THEN
  261. LVL1=0
  262. LVL2=-99
  263. ELSE
  264. LVL1=KSEC1(9)
  265. LVL2=KSEC1(10)
  266. ENDIF
  267. ! Check to see that the combination of iparm, ktype, lvl1, and lvl2
  268. ! match what has been requested in the Vtable. If not, set the field
  269. ! name to NULL, meaning that we do not want to process this one.
  270. field = 'NULL'
  271. do i = 1, maxvar
  272. if (gcode(i).eq.iparm) then
  273. if (lcode(i).eq.ktype) then
  274. if ((level1(i).eq.lvl1) .or. (level1(i) == splatcode) ) then
  275. if (level2(i).eq.lvl2) then
  276. field=namvar(i)
  277. level = -999.
  278. if (ktype.eq.100) then ! Pressure-level
  279. level=lvl1
  280. elseif (ktype.eq.102) then
  281. level=201300.
  282. elseif ((ktype.eq.116.and.lvl1.le.50.and.lvl2.eq.0) .or. &
  283. (ktype.eq.105).or.(ktype.eq.1) .or. &
  284. (ktype.eq.111).or.(ktype.eq.112) ) then
  285. ! level=200100.
  286. level = float(200000+iprty(i))
  287. elseif (ktype.eq.109 .or. ktype.eq.107) then ! hybrid or sigma levels
  288. level = lvl1
  289. elseif (ktype.eq. 6 ) then ! max wind
  290. level = 6.
  291. elseif (ktype.eq. 7 ) then ! trop
  292. level = 7.
  293. elseif (ktype .eq. 160 ) then ! depth below sea-surface (m)
  294. level = 201500.
  295. elseif (ktype .eq. 237 .or. ktype .eq. 238 ) then ! depth of ocean layer
  296. level = 201600.
  297. endif
  298. if (level .lt. -998. ) then
  299. write(6,*) 'Could not find a level for this Vtable entry'
  300. write(6,*) 'iparm = ',iparm,' ktype = ',ktype,' lvl1 = ',lvl1,' lvl2 = ',lvl2
  301. write(6,*) 'Fix the Vtable or modify rd_grib1.F'
  302. stop 'rd_grib1'
  303. endif
  304. endif
  305. endif
  306. endif
  307. endif
  308. enddo
  309. if (field .eq. 'NULL') then
  310. call deallogrib
  311. return
  312. endif
  313. if ((field.eq.'WEASD').or.(field.eq.'SNOW')) then
  314. level = level + ksec1(19)+1
  315. endif
  316. ! Build the 19-character date string, based on GRIB header date and time
  317. ! information, including forecast time information:
  318. ICC=KSEC1(22) ! CENTURY OF THE DATA
  319. IYY=KSEC1(11) ! (TWO-DIGIT) YEAR OF THE DATA
  320. MONTH=KSEC1(12) ! MONTH OF THE DATA
  321. DAY=KSEC1(13) ! DAY OF THE DATA
  322. HOUR=KSEC1(14) ! HOUR OF THE DATA
  323. MINUTE=KSEC1(15) ! MINUTE OF THE DATA
  324. SECOND=0
  325. if (ksec1(19) == 3) then
  326. FCST = (KSEC1(17) + KSEC1(18))/2
  327. ! TEMPORARY AFWA FIX
  328. ! elseif (ksec1(19) == 4 .or. ksec1(19) == 5) then
  329. elseif (ksec1(19) == 4 .or. ksec1(19) == 5 .or. ksec1(19) == 7) then
  330. FCST = KSEC1(18)
  331. else
  332. FCST = KSEC1(17)
  333. endif
  334. if (IYY.EQ.00) then
  335. YEAR = ICC*100
  336. else
  337. YEAR = (ICC-1)*100 + IYY
  338. endif
  339. hdate(1:19) = ' '
  340. call build_hdate(hdate,year,month,day,hour,minute,second)
  341. call geth_newdate(hdate,hdate,3600*fcst)
  342. ! Store information about the grid on which the data is.
  343. ! This stuff gets stored in the MAP variable, as defined in module GRIDINFO
  344. map%startloc = 'SWCORNER'
  345. map%grid_wind = .true.
  346. ! NCEP's grib1 messages (in GDS Octet 17, the Resolution and Component Flags)
  347. ! all have '0' for the earth radius flag which the documentation (written by NCEP)
  348. ! says is 6367.47, but they really use 6371.229. Hardcode it.
  349. ! It's not clear what ECMWF uses. One place says 6367.47 and another 6371.229.
  350. if ( index(map%source,'NCEP') .ne. 0 ) then
  351. map%r_earth = 6371.229
  352. else
  353. map%r_earth = 6367.47
  354. endif
  355. if (ksec2(4).eq.0) then ! Lat/Lon grid
  356. map%igrid = 0
  357. map%nx = infogrid(1)
  358. map%ny = infogrid(2)
  359. map%dx = ginfo(8)
  360. map%dy = ginfo(9)
  361. map%lat1 = ginfo(3)
  362. map%lon1 = ginfo(4)
  363. ! If this is global data, then the dx and dy are more accurately
  364. ! computed by the number of points than the 3 digits grib permits.
  365. if ( ABS(map%nx * map%dx - 360.) .lt. 1 ) then
  366. if ( ABS ( map%dx - (360./real(map%nx)) ) .gt. 0.00001 ) then
  367. !print *,'old dx = ',ginfo(8)
  368. map%dx = 360./real(map%nx)
  369. !print *,'new dx = ',map%dx
  370. endif
  371. endif
  372. if ( ABS((map%ny-1) * map%dy - 2.*abs(map%lat1)) .lt. 1 ) then
  373. if ( ABS ( map%dy - (2.*abs(map%lat1)/real(map%ny-1)) ) .gt. 0.00001 ) then
  374. !print *,'old dy = ',ginfo(9)
  375. map%dy = 2.*abs(map%lat1)/real(map%ny-1)
  376. !print *,'new dy = ',map%dy
  377. endif
  378. endif
  379. write(tmp8,'(b8.8)') infogrid(5)
  380. if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
  381. if (icenter .eq. 7 .and. KSEC1(5) .eq. 173 ) then ! correction for ncep grid 173
  382. map%lat1 = 89.958333
  383. map%lon1 = 0.041667
  384. map%dx = 0.083333333 * sign(1.0,map%dx)
  385. map%dy = 0.083333333 * sign(1.0,map%dy)
  386. endif
  387. ! correction for ncep grid 229 added 5/3/07 JFB
  388. if (icenter .eq. 7 .and. KSEC1(5) .eq. 229 ) then
  389. if (ginfo(3) .gt. 89. .and. ginfo(9) .gt. 0.) then
  390. map%dy = -1. * map%dy
  391. endif
  392. endif
  393. ! print *, "CE map stuff", map%igrid, map%nx, map%ny, map%dx, &
  394. ! map%dy, map%lat1, map%lon1
  395. elseif (ksec2(4).eq.3) then ! Lambert Conformal Grid
  396. map%igrid = 3
  397. map%nx = infogrid(1)
  398. map%ny = infogrid(2)
  399. map%lov = ginfo(6)
  400. map%truelat1 = ginfo(11)
  401. map%truelat2 = ginfo(12)
  402. map%dx = ginfo(7)
  403. map%dy = ginfo(8)
  404. map%lat1 = ginfo(3)
  405. map%lon1 = ginfo(4)
  406. write(tmp8,'(b8.8)') infogrid(5)
  407. if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
  408. ! if (tmp8(2:2) .eq. '0') map%r_earth = 6367.47
  409. elseif(ksec2(4).eq.4) then ! Gaussian Grid
  410. map%igrid = 4
  411. map%nx = infogrid(1)
  412. map%ny = infogrid(2)
  413. map%dx = ginfo(8)
  414. ! map%dy = ginfo(19)
  415. map%dy = real (infogrid(9))
  416. map%lon1 = ginfo(4)
  417. map%lat1 = ginfo(3)
  418. write(tmp8,'(b8.8)') infogrid(5)
  419. if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
  420. elseif (ksec2(4).eq.5) then ! Polar-Stereographic Grid.
  421. map%igrid = 5
  422. map%nx = infogrid(1)
  423. map%ny = infogrid(2)
  424. map%lov = ginfo(6)
  425. map%truelat1 = 60.
  426. map%truelat2 = 91.
  427. map%dx = ginfo(7)
  428. map%dy = ginfo(8)
  429. map%lat1 = ginfo(3)
  430. map%lon1 = ginfo(4)
  431. write(tmp8,'(b8.8)') infogrid(5)
  432. if (tmp8(5:5) .eq. '0') map%grid_wind = .false.
  433. else
  434. print*, 'Unknown Data Representation Type, ksec2(4)= ', ksec2(4)
  435. stop 'rd_grib1'
  436. endif
  437. 111 format(' igrid : ', i3, /, &
  438. ' nx, ny : ', 2I4, /, &
  439. ' truelat1, 2: ', 2F10.4, /, &
  440. ' Center Lon : ', F10.4, /, &
  441. ' LatLon(1,1): ', 2F10.4, /, &
  442. ' DX, DY : ', F10.4, F10.4)
  443. ! Special for NCEP/NCAR Reanalysis Project:
  444. ! Throw out PSFC on lat/lon grid (save gaussian version)
  445. if ((icenter.eq.7).and.(iprocess.eq.80)) then ! Careful! This combination may refer
  446. ! to other products as well.
  447. if ((field.eq.'PSFC').and.(ksec2(4).eq.0)) then
  448. field='NULL'
  449. call deallogrib
  450. return
  451. endif
  452. endif
  453. if (allocated(rdatarray)) deallocate(rdatarray)
  454. allocate(rdatarray(map%nx * map%ny))
  455. ! If nx=65535, assume the grid is a thinned grid.
  456. ! Process only the NCEP grid IDs is 37 to 44.
  457. if (map%nx.eq.65535) then
  458. if ( (icenter .ne. 7) .or. (KSEC1(5).lt.37) .or. (KSEC1(5).gt.44) ) then
  459. write(*,*) 'Originating center is ',icenter
  460. write(*,*) 'Grid ID is ',KSEC1(5),' Only WAFS grids 37-44 are supported'
  461. write(*,'(" ***** STOP in Subroutine RD_GRIB1.",//)')
  462. stop
  463. endif
  464. lthinned = .TRUE.
  465. map%nx = 73
  466. map%dx = 1.25
  467. else
  468. lthinned = .FALSE.
  469. endif
  470. ! Unpack the 2D slab from the GRIB record, and put it in array rdatarray
  471. if (lthinned) then
  472. if (allocated(thinnedDataArray)) deallocate(thinnedDataArray)
  473. allocate(thinnedDataArray(map%nx * map%ny))
  474. call gribdata(thinnedDataArray,3447)
  475. ! Calculate how many points for each latitude, and accumulate into array
  476. if ((KSEC1(5).ge.37).and.(KSEC1(5).le.40)) then
  477. ! Northern hemisphere:
  478. npoints_acc(1)=0
  479. npoints_acc(2)=73
  480. do i=1,72
  481. np = int(2.0+(90.0/1.25)*cos(i*1.25*3.1415926/180.0))
  482. npoints_acc(i+2)=npoints_acc(i+1)+np
  483. enddo
  484. else
  485. ! Southern Hemisphere:
  486. npoints_acc(1)=0
  487. npoints_acc(2)=2
  488. do i=1,71
  489. ii = 72-i
  490. np = int(2.0+(90.0/1.25)*cos(ii*1.25*3.1415926/180.0))
  491. npoints_acc(i+2)=npoints_acc(i+1)+np
  492. enddo
  493. npoints_acc(74) = npoints_acc(73) + 73
  494. endif
  495. ! for row number i (where i=1 is the southern edge of the grid)
  496. ! npoints_acc(i+1)-npoints_acc(i) = number of points in this line
  497. ! npoints_acc(i)+1 = index into thinned array for first point of line
  498. do ny=1,73
  499. np = npoints_acc(ny+1)-npoints_acc(ny) ! Number of points in this line.
  500. do nx=1,73
  501. ! Calulate the x index (mj) of thinned array (real value)
  502. mj = (nx-1.0)*(np-1.0)/(72.0)
  503. if (abs(mj - int(mj)) < 1.E-10) then
  504. rdatarray((ny-1)*73+nx) = thinnedDataArray(npoints_acc(ny)+1+int(mj))
  505. else
  506. ! Get the 2 closest values from thinned array
  507. Vb = thinnedDataArray(npoints_acc(ny)+1+int(mj))
  508. Vc = thinnedDataArray(npoints_acc(ny)+1+int(mj)+1)
  509. ! Get the next two closest, if available:
  510. Va = -999999.
  511. Vd = -999999.
  512. if (mj > 1.0) then
  513. Va = thinnedDataArray(npoints_acc(ny)+1+int(mj)-1)
  514. endif
  515. if (mj < np-2) then
  516. Vd = thinnedDataArray(npoints_acc(ny)+1+int(mj)+2)
  517. endif
  518. if ((Va < -999998.) .or. (Vd < -999998.)) then
  519. ! Use 2-point linear interpolation.
  520. rdatarray((ny-1)*73+nx) = Vb*(int(mj)+1.0-mj) + Vc*(mj-int(mj))
  521. else
  522. ! Use 4-point overlapping parabolic interpolation.
  523. xmj = mj - float(int(mj))
  524. rdatarray((ny-1)*73+nx) = oned(xmj,Va,Vb,Vc,Vd)
  525. endif
  526. endif
  527. enddo
  528. enddo
  529. else
  530. call gribdata(rdatarray,map%nx*map%ny)
  531. endif
  532. ! Some grids are broken and need to be reordered (e.g. NCEP-II in 1997).
  533. ! WPS assumes that the grids are ordered consistently with the start location.
  534. call mprintf(.true.,DEBUG, &
  535. "RD_GRIB1 icenter = %i , iprocess = %i , grid = %i",i1=icenter,i2=iprocess,i3=KSEC1(5))
  536. if (icenter .eq. 7 .and. iprocess .eq. 0 .and. KSEC1(5) .eq. 2 ) then
  537. call mprintf(.true.,DEBUG, &
  538. "resetting NCEP2 dx and dy. If this is not NCEP2 data you must modify rd_grib1.f90")
  539. call mprintf(.true.,DEBUG, &
  540. "field = %s , dx = %f , dy = %f , i10 = %i",s1=field,f1=map%dx,f2=map%dy,i1=infogrid(10))
  541. map%dx = 2.5
  542. map%dy = -2.5
  543. ! call reorder_it (rdatarray, map%nx, map%ny, map%dx, map%dy, infogrid(10))
  544. endif
  545. ! Deallocate a couple of arrays that may have been allocated by the
  546. ! GRIB decoding routines.
  547. call deallogrib
  548. END subroutine rd_grib1
  549. real function oned(x, a, b, c, d) Result (Answer)
  550. implicit none
  551. real :: x ! Proportion of the way between B and C. Between 0.0 and 1.0
  552. real :: a, b, c, d
  553. if (abs(x) < 1.E-10) then
  554. Answer = B
  555. return
  556. endif
  557. IF(abs(x-1.) < 1.E-10) then
  558. Answer = C
  559. return
  560. endif
  561. Answer = (1.0-X)*(B+X*(0.5*(C-A)+X*(0.5*(C+A)-B)))+X*(C+(1.0-X)*(0.5 &
  562. *(B-D)+(1.0-X)*(0.5*(B+D)-C)))
  563. end function oned