WAVEWATCH III  beta 0.0.1
w3smcomd.F90
Go to the documentation of this file.
1 
6 !/
56 MODULE w3smcomd
57  !/
58  !/ +-----------------------------------+
59  !/ | WAVEWATCH III NOAA/NCEP |
60  !/ | Chris Bunney, UKMO |
61  !/ | FORTRAN 90 |
62  !/ | Last update : 21-Jul-2021 |
63  !/ +-----------------------------------+
64  !/
65  !/ Copyright 2009-2012 National Weather Service (NWS),
66  !/ National Oceanic and Atmospheric Administration. All rights
67  !/ reserved. WAVEWATCH III is a trademark of the NWS.
68  !/ No unauthorized use without permission.
69  !/
70  USE w3gdatmd
71  USE constants
72  USE w3odatmd, ONLY: undef
73 
74  PUBLIC
75 
76  ! Output grid definition
77  DOUBLE PRECISION :: sxo
78  DOUBLE PRECISION :: syo
79  DOUBLE PRECISION :: exo
80  DOUBLE PRECISION :: eyo
81  DOUBLE PRECISION :: dxo
82  DOUBLE PRECISION :: dyo
83  INTEGER :: nxo
84  INTEGER :: nyo
85 
86  ! Variables for SMC regridding (type 2 output):
90  INTEGER :: smcotype
92  INTEGER :: celfac
93  INTEGER, ALLOCATABLE :: xidx(:)
94  INTEGER, ALLOCATABLE :: yidx(:)
95  INTEGER, ALLOCATABLE :: xspan(:)
96  INTEGER, ALLOCATABLE :: yspan(:)
97  REAL, ALLOCATABLE :: wts(:)
98  REAL, ALLOCATABLE :: cov(:,:)
99  INTEGER, ALLOCATABLE :: mapsmc(:,:)
100  LOGICAL, ALLOCATABLE :: smcmask(:)
101  INTEGER, ALLOCATABLE :: smcidx(:)
102 
104  INTEGER, ALLOCATABLE :: smccx(:)
105  INTEGER, ALLOCATABLE :: smccy(:)
106  REAL :: dlat
107  REAL :: dlon
108  INTEGER :: cfac
109 
110  REAL :: noval
111 
112  ! Variables for SMC nearest neighbour interpolation (type 3/4 output)
113  INTEGER, ALLOCATABLE :: nnidx(:,:)
114  REAL, ALLOCATABLE :: xdist(:,:)
115  REAL, ALLOCATABLE :: ydist(:,:)
116  INTEGER :: ndsmc
117 
118  ! Counters:
119  INTEGER :: smcnout
120  INTEGER :: nsmc
121 
122 CONTAINS
123 
124  !--------------------------------------------------------------------------
142  SUBROUTINE smc_interp()
143 
144  IMPLICIT NONE
145 
146  ! Locals
147  REAL :: CX0, CY0 ! SW corner of origin of grid
148  REAL :: S0CHK, XSNAP, YSNAP
149 
150  INTEGER :: ISEA, mx, my, ixx, iyy, J
151  REAL :: lat, lon
152 
153  j = 1
154  nsmc = 0
155 
156  ! Determine smallest cell size factor:
157  cfac = 2**(nrlv - 1)
158 
159  ! Get smallest SMC grid cells step size:
160  dlat = sy / cfac
161  dlon = sx / cfac
162  ! SW Corner of grid origin cell:
163  cx0 = x0 - sx / 2.
164  cy0 = y0 - sy / 2.
165 
166  ! Grid cell size to snap design grid to. Will be regular grid
167  ! resolution for cellsize <= cfac, or cellsize for cellsize > cfac
168  xsnap = sx
169  ysnap = sy
170  IF(celfac .gt. cfac) xsnap = celfac * dlon
171  IF(celfac .gt. cfac) ysnap = celfac * dlat
172 
173  ! Get start lat,lon (must be aligned with SMC grid edges). Use
174  ! regular grid origins if SXO or SYO is -999.9 (use full grid):
175  IF(abs(sxo + 999.9) .LT. 1e-4) THEN
176  sxo = cx0
177  ELSE
178  s0chk = cx0 + floor((sxo - cx0) / xsnap) * xsnap
179  ! Ensure first grid value falls within specified range
180  IF (s0chk .LT. sxo) THEN
181  sxo = s0chk + xsnap
182  ELSE
183  sxo = s0chk
184  ENDIF
185  ENDIF
186  IF(abs(syo + 999.9) .LT. 1e-4) THEN
187  syo = cy0
188  ELSE
189  s0chk = cy0 + floor((syo - cy0) / ysnap) * ysnap
190  ! Ensure first grid value falls within specified range
191  IF (s0chk .LT. syo) THEN
192  syo = s0chk + ysnap
193  ELSE
194  syo = s0chk
195  ENDIF
196  ENDIF
197 
198  ! Use regular grid extents for last lat/lon if user
199  ! specifies -999.9 for EXO/EYO (use full grid):
200  IF(abs(exo + 999.9) .LT. 1e-4) THEN
201  exo = cx0 + sx * nx ! TRHC of last cell
202  ENDIF
203  IF(abs(eyo + 999.9) .LT. 1e-4) THEN
204  eyo = cy0 + sy * ny ! TRHC of last cell
205  ENDIF
206 
207  ! Ouput grid cell dx/dy will be integer factor of smallest
208  ! SMC grid cell size:
209  dxo = dlon * celfac
210  dyo = dlat * celfac
211 
212  ! Determine number of cells in grid:
213  nxo = nint((exo - sxo) / dxo)
214  nyo = nint((eyo - syo) / dyo)
215 
216  IF(smcotype .EQ. 2) THEN
217  ! Initialise all indices to "missing":
218  xidx(:) = -1
219  yidx(:) = -1
220  ENDIF
221 
222  ! Loop over cell array and calculate regidding factors:
223  DO isea=1, nsea
224  ! ! For grids with Arctic region: make sure we don't double count
225  ! ! the overlapping boundary cells. Also, don't process the arctic
226  ! ! cell (which is always the last cell).
227  ! ! Note: NARC contains ALL the boundary cells (global + arctic).
228  ! ! whereas NGLO contains only the global boundary cells.
229  ! IF(ISEA .GT. NGLO-NBAC .AND. ISEA .LT. NSEA-NARC+1) CYCLE
230  IF( arctc .AND. &
231  isea .GT. nglo-nbac .AND. isea .LT. nsea-narc+1) cycle
232 
233  ! Get grid cell size:
234  mx = ijkcel(3,isea)
235  my = ijkcel(4,isea)
236 
237  ! Determine cell lat/lon (bottom left corner of cell)
238  lon = cx0 + ijkcel(1,isea) * dlon
239  lat = cy0 + ijkcel(2,isea) * dlat
240 
241  ! For output type 1 (seapoint array), just check whether
242  ! cell centre is within specified domain range, and update
243  ! output mask accordingly:
244  IF( smcotype .EQ. 1 ) THEN
245  ! Ensure longitude ranges are aligned
246  lon = lon + 0.5 * mx * dlon
247  lat = lat + 0.5 * my * dlat
248  IF(lon .LT. sxo) lon = lon + 360.0
249  IF(lon .GT. exo) lon = lon - 360.0
250 
251  ! Now check if it is within range of requested domain:
252  IF(lon .GE. sxo .AND. lon .LE. exo .AND. &
253  lat .GE. syo .AND. lat .LE. eyo ) THEN
254  smcmask(isea) = .true.
255  smcidx(j) = isea
256  j = j + 1
257  ENDIF
258  cycle
259  ENDIF ! SMCOTYPE == 1
260 
261  ! For output type 2 (area averaged regular grid), determine
262  ! SMC grid cell location and coverage in output grid:
263 
264  ! Align lons
265  IF(lon .LT. sxo) THEN
266  lon = lon + 360.
267  ENDIF
268  IF(lon .GT. exo) THEN
269  lon = lon - 360.
270  ENDIF
271 
272  ! Find first SW cell in design grid:
273  ! We add on 1/2 of the smallest SMC cell dlon/dlat values to ensure
274  ! source grid cell ends up in the correct target grid cell (after
275  ! integer trunction):
276  ixx = floor((lon + 0.5*dlon - sxo) / dxo) + 1
277  iyy = floor((lat + 0.5*dlat - syo) / dyo) + 1
278 
279  ! If we fall outside the left/bottom edge of the design grid,
280  ! check for cases where the SMC cell has a lon or lat
281  ! scaling factor > cfac (design grid is assumed to align
282  ! its origin with cells of size cfac). For such cells,
283  ! keep moving the left/bottom edge up by cfac until
284  ! the SW corner (possibly) matches a design grid cell.
285  IF(ixx .LE. 0 .AND. ixx + mx / celfac .GT. 0) THEN
286  DO WHILE(mx .GT. cfac)
287  mx = mx - cfac
288  lon = lon + dlon * cfac
289  ixx = floor((lon + 0.5*dlon - sxo) / dxo) + 1
290  IF(ixx .GT. 0) EXIT ! Found cell lon-edge in design grid
291  ENDDO
292  ENDIF
293  IF(iyy .LE. 0 .AND. iyy + my / celfac .GT. 0) THEN
294  DO WHILE(my .GT. cfac)
295  my = my - cfac
296  lat = lat + dlat * cfac
297  iyy = floor((lat + 0.5*dlat - syo) / dyo) + 1
298  IF(iyy .GT. 0) EXIT ! Found cell lat-edge in design grid
299  ENDDO
300  ENDIF
301 
302  ! If SMC cell definitely out of design grid domain, then cycle.
303  IF(ixx .LE. 0 .OR. ixx .GT. nxo .OR. &
304  iyy .LE. 0 .OR. iyy .GT. nyo) THEN
305  xidx(isea) = -1
306  yidx(isea) = -1
307  cycle
308  ENDIF
309 
310  xidx(isea) = ixx
311  yidx(isea) = iyy
312  nsmc = nsmc + 1
313  smcidx(nsmc) = isea
314 
315  ! find out how many cells it covers in the x/y directions:
316  xspan(isea) = max(1, int(mx / celfac))
317  yspan(isea) = max(1, int(my / celfac))
318 
319  ! Do a bit of error checking (non fatal - just produced warning):
320  IF(xspan(isea) .GT. 1) THEN
321  IF(abs((sxo+(ixx-1)*dxo) - lon) .GT. dxo/100.0) THEN
322  print*, 'Potential problem with SMC grid cell span:'
323  print*, xspan(isea), float(mx) / celfac
324  print*, lon,lat
325  print*, sxo+(ixx-1)*dxo,syo+iyy*dyo,dxo,dyo
326  print*, "diff:", (sxo+(ixx-1)*dxo) - lon
327  ENDIF
328  ENDIF
329 
330  ! calc cell weight in relation to output grid:
331  wts(isea) = min(1., dble(min(celfac, mx) * min(celfac, my)) / &
332  (celfac**2))
333 
334  ENDDO
335 
336  ! Reset SXO and SYO to be the cell-centre (currently cell SW edge):
337  sxo = sxo + 0.5 * dxo
338  syo = syo + 0.5 * dyo
339 
340  END SUBROUTINE smc_interp
341 
342  !--------------------------------------------------------------------------
359  SUBROUTINE w3s2xy_smcrg(S, XY)
360 
361  IMPLICIT NONE
362 
363  ! Input parameters:
364  REAL, INTENT(IN) :: S(:)
365  REAL, INTENT(OUT) :: XY(NXO,NYO)
366 
367  ! Local parameters
368  INTEGER :: I, J, IX, IY, ISEA, ISMC
369 
370  ! Initialise coverage and output arrays:
371  cov(:,:) = 0.0
372  xy(:,:) = 0.0
373 
374  DO ismc=1,nsmc
375  isea = smcidx(ismc)
376 
377  IF(s(isea) .EQ. undef) cycle ! MDI
378 
379  ! Loop over number of spanned cells:
380  DO i=0, xspan(isea) - 1
381  DO j=0, yspan(isea) - 1
382  ix = xidx(isea) + i
383  iy = yidx(isea) + j
384 
385  ! Spans outside of grid?
386  IF(ix .GT. nxo .OR. iy .GT. nyo) cycle
387 
388  ! Interpolate:
389  xy(ix, iy) = xy(ix, iy) + s(isea) * wts(isea)
390 
391  ! Keep track of how much of cell is (wet) covered:
392  cov(ix, iy) = cov(ix, iy) + wts(isea)
393  ENDDO
394  ENDDO
395 
396  ENDDO
397 
398  ! Create coastline by masking out areas with < 50% coverage:
399  DO ix=1,nxo
400  DO iy=1,nyo
401  IF(mapsmc(ix,iy) .EQ. 0) THEN
402  ! Make land point
403  xy(ix,iy) = undef
404  ELSE IF(cov(ix,iy) .LT. 0.5) THEN
405  ! More than half of cell has UNDEF values - set to NOVAL:
406  xy(ix,iy) = noval
407  ELSE IF(cov(ix,iy) .LT. 1.0) THEN
408  ! If coverage < 1.0, scale values back to full cell coverage.
409  ! Without this step, points around coast could end up with lower
410  ! waveheights due to weights not summing to 1.0:
411  xy(ix,iy) = xy(ix,iy) * ( 1.0 / cov(ix,iy) )
412  ENDIF
413  ENDDO
414  ENDDO
415 
416  RETURN
417 
418  END SUBROUTINE w3s2xy_smcrg
419 
420  !--------------------------------------------------------------------------
438  SUBROUTINE w3s2xy_smcrg_dir(S, XY)
439 
440  IMPLICIT NONE
441 
442  ! Input parameters:
443  REAL, INTENT(IN) :: S(:)
444  REAL, INTENT(OUT) :: XY(NXO,NYO)
445 
446  ! Local parameters
447  INTEGER :: I, J, IX, IY, ISEA, ISMC
448  REAL, ALLOCATABLE :: AUX1(:,:), AUX2(:,:)
449  REAL :: COSS, SINS
450 
451  ! Initialise coverage and output arrays:
452  ALLOCATE(aux1(nxo,nyo),aux2(nxo,nyo))
453  cov(:,:) = 0.0
454  xy(:,:) = 0.0
455  aux1(:,:) = 0.0
456  aux2(:,:) = 0.0
457 
458  DO ismc=1,nsmc
459  isea = smcidx(ismc)
460 
461  IF(s(isea) .EQ. undef) cycle ! MDI
462  coss = cos(s(isea))
463  sins = sin(s(isea))
464 
465  ! Loop over number of spanned cells:
466  DO i=0, xspan(isea) - 1
467  DO j=0, yspan(isea) - 1
468  ix = xidx(isea) + i
469  iy = yidx(isea) + j
470 
471  ! Spans outside of grid?
472  IF(ix .GT. nxo .OR. iy .GT. nyo) cycle
473 
474  ! Interpolate:
475  !XY(IX, IY) = XY(IX, IY) + S(ISEA) * WTS(ISEA)
476  aux1(ix, iy) = aux1(ix, iy) + coss * wts(isea)
477  aux2(ix, iy) = aux2(ix, iy) + sins * wts(isea)
478 
479  ! Keep track of how much of cell is (wet) covered:
480  cov(ix, iy) = cov(ix, iy) + wts(isea)
481  ENDDO
482  ENDDO
483 
484  ENDDO
485 
486  ! Create coastline by masking out areas with < 50% coverage:
487  DO ix=1,nxo
488  DO iy=1,nyo
489  IF(mapsmc(ix,iy) .EQ. 0) THEN
490  ! Make land point
491  xy(ix,iy) = undef
492  ELSE IF(cov(ix,iy) .LT. 0.5) THEN
493  ! More than half of cell has UNDEF values - set to NOVAL
494  xy(ix,iy) = noval
495  ELSE IF(cov(ix,iy) .LT. 1.0) THEN
496  ! If coverage < 1.0, scale values back to full cell coverage.
497  ! Without this step, points around coast could end up with lower
498  ! waveheights due to weights not summing to 1.0:
499  xy(ix,iy) = atan2(aux2(ix,iy), aux1(ix,iy))
500  xy(ix,iy) = mod(630. - rade * xy(ix,iy), 360. )
501  ELSE
502  xy(ix,iy) = atan2(aux2(ix,iy), aux1(ix,iy))
503  xy(ix,iy) = mod(630. - rade * xy(ix,iy), 360. )
504  ENDIF
505  ENDDO
506  ENDDO
507 
508  RETURN
509 
510  END SUBROUTINE w3s2xy_smcrg_dir
511 
512  !--------------------------------------------------------------------------
518  SUBROUTINE mapsta_smc()
519 
520  IMPLICIT NONE
521 
522  ! Local parameters
523  INTEGER :: I, J, IX, IY, IMX, IMY, ISEA
524 
525  ! Initialise coverage and output arrays:
526  cov(:,:) = 0.0
527  mapsmc(:,:) = 0
528 
529  DO isea=1,nsea
530  imx = mapsf(isea,1)
531  imy = mapsf(isea,2)
532 
533  IF(xidx(isea) .EQ. -1) cycle ! Out of grid
534 
535  ! Loop over number of spanned cells:
536  DO i=0, xspan(isea) - 1
537  DO j=0, yspan(isea) - 1
538  ix = xidx(isea) + i
539  iy = yidx(isea) + j
540 
541  ! Spans outside of grid?
542  IF(ix .GT. nxo .OR. iy .GT. nyo) cycle
543 
544  ! MAPSTA values: 0=Excluded, (+-)1=Sea, (+-2)=Input boundary
545  ! We will just keep track of sea and non-sea points:
546  IF(mapsta(imy, imx) .NE. 0) THEN
547  ! Keep track of how much of cell is (wet) covered:
548  cov(ix, iy) = cov(ix, iy) + wts(isea)
549  ENDIF
550  ENDDO
551  ENDDO
552 
553  ENDDO
554 
555  ! Create coastline by masking out areas with < 50% coverage:
556  DO ix=1,nxo
557  DO iy=1,nyo
558  IF(cov(ix,iy) .LT. 0.5) THEN
559  mapsmc(ix, iy) = 0
560  ELSE
561  mapsmc(ix, iy) = 1
562  ENDIF
563  ENDDO
564  ENDDO
565 
566  RETURN
567 
568  END SUBROUTINE mapsta_smc
569 
570  !--------------------------------------------------------------------------
579  SUBROUTINE read_smcint()
580 
581  USE w3servmd, ONLY: extcde
582  IMPLICIT NONE
583 
584  ! Locals
585  INTEGER :: IERR, I, J
586  REAL :: PLATO, PLONO ! Not used yet....future version might allow
587  ! output to a rotated pole grid...
588 
589  ndsmc = 50
590  OPEN(ndsmc, file='smcint.ww3', status='old', form='unformatted', convert=file_endian, iostat=ierr)
591  IF(ierr .NE. 0) THEN
592  WRITE(*,*) "ERROR! Failed to open smcint.ww3 for reading"
593  CALL extcde(1)
594  ENDIF
595 
596  ! Header
597  READ(ndsmc) nxo, nyo, sxo, syo, dxo, dyo, plono, plato
598  ALLOCATE(nnidx(nxo,nyo), xdist(nxo,nyo), ydist(nxo,nyo))
599 
600  ! Indices and weights:
601  READ(ndsmc)((nnidx(i,j), xdist(i,j), ydist(i,j),i=1,nxo),j=1,nyo)
602 
603  CLOSE(ndsmc)
604 
605  END SUBROUTINE read_smcint
606 
607  !--------------------------------------------------------------------------
622  SUBROUTINE calc_interp()
623 
624  USE w3gdatmd, ONLY: clats
625  USE constants, ONLY : dera, radius
626 #ifdef W3_RTD
627  USE w3servmd, ONLY: w3lltoeq
628  USE w3gdatmd, ONLY: polon, polat
629 #endif
630 
631  IMPLICIT NONE
632  INTEGER :: IERR, I, J, ISEA, N, CFAC
633  REAL :: mlon(NSEA), mlat(NSEA), olon(nxo,nyo), olat(nxo,nyo), &
634  ang(nxo,nyo), lon, lat
635 #ifdef W3_RTD
636  REAL :: tmplon(nxo,nyo), tmplat(nxo,nyo)
637 #endif
638 
639  ! Determine smallest cell size factor:
640  cfac = 2**(nrlv - 1)
641 
642  ! Get smallest SMC grid cells step size:
643  dlat = sy / cfac
644  dlon = sx / cfac
645 
646  ALLOCATE(xdist(nx,ny), ydist(ny,nx))
647 
648  ! Model lat/lons:
649  DO isea = 1,nsea
650  mlon(isea) = (x0-0.5*sx) + (ijkcel(1,isea) + 0.5 * ijkcel(3,isea)) * dlon
651  mlat(isea) = (y0-0.5*sy) + (ijkcel(2,isea) + 0.5 * ijkcel(4,isea)) * dlat
652  ENDDO
653 
654  ! Generate output grid cell centres:
655  DO i=1,nxo
656  DO j=1,nyo
657  olon(i,j) = sxo + (i-1) * dxo
658  olat(i,j) = syo + (j-1) * dyo
659  ENDDO
660  ENDDO
661 
662 #ifdef W3_RTD
663  tmplat = olat
664  tmplon = olon
665  print*,'Rotating coordinates'
666  CALL w3lltoeq ( tmplat, tmplon, olat, olon, &
667  ang, polat, polon, nxo*nyo )
668  print*,'Rotating coordinates complete'
669 #endif
670 
671  ! Cycle over output grid points and find containing SMC cell:
672  ! NOTE : BRUTE FORCE!
673  nnidx(:,:) = -1
674  DO i=1,nxo
675  print*,i,' of ',nxo
676  DO j=1,nyo
677  lon = olon(i,j)
678  lat = olat(i,j)
679  IF(lon .LT. x0 - sx / 2) lon = lon + 360.0
680  IF(lon .GT. (x0 + (nx-1) * sx) + 0.5 * sx) lon = lon - 360.0
681  DO isea=1,nsea
682  IF(mlon(isea) - 0.5 * ijkcel(3,isea) * dlon .LE. lon .AND. &
683  mlon(isea) + 0.5 * ijkcel(3,isea) * dlon .GE. lon .AND. &
684  mlat(isea) - 0.5 * ijkcel(4,isea) * dlat .LE. lat .AND. &
685  mlat(isea) + 0.5 * ijkcel(4,isea) * dlat .GE. lat ) THEN
686  ! Match!
687  nnidx(i,j) = isea
688  xdist(i,j) = (lon - mlon(isea)) * dera * radius * clats(isea)
689  ydist(i,j) = (lat - mlat(isea)) * dera * radius
690  EXIT
691  ENDIF
692  ENDDO
693  ENDDO
694  ENDDO
695 
696  END SUBROUTINE calc_interp
697 
698  !--------------------------------------------------------------------------
711  SUBROUTINE w3s2xy_smcnn(S, XY, DIRN)
712 
713  IMPLICIT NONE
714 
715  ! Input parameters:
716  REAL, INTENT(IN) :: S(:) ! Inupt array
717  REAL, INTENT(OUT) :: XY(NXO,NYO) ! Output data
718  LOGICAL, INTENT(IN) :: DIRN ! Directional field?
719 
720  ! Local parameters
721  INTEGER :: I, J, IX, IY, ISEA, ISMC
722  DO ix = 1,nxo
723  DO iy = 1,nyo
724  isea = nnidx(ix,iy) ! Nearest neighbour SMC point
725  IF(isea .EQ. -1) THEN
726  ! Land
727  xy(ix,iy) = undef
728  ELSE
729  IF(s(isea) .EQ. undef) THEN
730  ! Set undefined sea points to NOVAL
731  xy(ix,iy) = noval
732  ELSE
733  xy(ix,iy) = s(isea)
734  IF(dirn) THEN
735  ! Convert direction fields to degrees nautical
736  xy(ix,iy) = mod(630. - rade * xy(ix,iy), 360.0)
737  ENDIF
738  ENDIF
739  ENDIF
740  ENDDO
741  ENDDO
742 
743  END SUBROUTINE w3s2xy_smcnn
744 
745  !--------------------------------------------------------------------------
762  SUBROUTINE w3s2xy_smcnn_int(S, XY, DIRN)
763 
764  USE w3psmcmd, ONLY: smcgradn
765  IMPLICIT NONE
766 
767  ! Input parameters:
768  REAL, INTENT(IN) :: S(:) ! Input array
769  REAL, INTENT(OUT) :: XY(NXO,NYO) ! Output array
770  LOGICAL, INTENT(IN) :: DIRN ! Directional field?
771 
772  ! Locals
773  INTEGER :: I, J, IX, IY, ISEA, ISMC
774  REAL :: CVQ(-9:NSEA)
775  REAL :: GrdX(NSEA), GrdY(NSEA)
776 
777  ! Calculate local gradients:
778  cvq(1:nsea) = s ! Need to copy S into array with bounds starting at -9
779  CALL smcgradn(cvq, grdx, grdy, 0)
780 
781  ! Interpolate:
782  DO ix = 1,nxo
783  DO iy = 1,nyo
784  isea = nnidx(ix,iy) ! Nearest neighbour SMC point
785  IF(isea .EQ. -1) THEN
786  xy(ix,iy) = undef
787  ELSE
788  ! Interpolate using local gradient and distance from cell centre:
789  xy(ix,iy) = s(isea) + grdx(isea) * xdist(ix,iy) + grdy(isea) * ydist(ix,iy)
790  IF(dirn) THEN
791  ! Convert direction fields to degrees nautical
792  xy(ix,iy) = mod(630. - rade * xy(ix,iy), 360.0)
793  ENDIF
794  ENDIF
795  ENDDO
796  ENDDO
797 
798  END SUBROUTINE w3s2xy_smcnn_int
799  !--------------------------------------------------------------------------
800 
801  !--------------------------------------------------------------------------
816  SUBROUTINE w3s2xy_smc(S, XY, DIR)
817 
818  IMPLICIT NONE
819 
820  REAL, INTENT(IN) :: S(:)
821  REAL, INTENT(OUT) :: XY(NXO,NYO)
822  LOGICAL, OPTIONAL :: DIR
823 
824  LOGICAL :: DIRN
825  INTEGER :: ISEA
826 
827  IF(PRESENT(dir)) THEN
828  dirn = dir
829  ELSE
830  dirn = .false.
831  ENDIF
832 
833  IF(smcotype .EQ. 1) THEN
834  ! Flat sea point array
835  xy(:,1) = pack(s, smcmask)
836  IF(dirn) THEN
837  ! Convert to nautical convention in degrees
838  DO isea=1,nxo
839  IF(xy(isea,1) .NE. undef) THEN
840  xy(isea,1) = mod(630. - rade * xy(isea,1), 360.)
841  ENDIF
842  ENDDO
843  ENDIF
844  ELSEIF(smcotype .EQ. 2) THEN
845  ! Regular gridded SMC cells
846  IF(dirn) THEN
847  CALL w3s2xy_smcrg_dir(s, xy)
848  ELSE
849  CALL w3s2xy_smcrg(s, xy)
850  ENDIF
851  ELSEIF(smcotype .EQ. 3) THEN
852  ! Regridded to arbitrary regular grid with interpolation
853  CALL w3s2xy_smcnn_int(s, xy, dirn)
854  ELSEIF(smcotype .EQ. 4) THEN
855  ! Regridded to arbitrary regular grid - no interpolation
856  CALL w3s2xy_smcnn(s, xy, dirn)
857  ELSE
858  WRITE(*,*) "Uknonwn SMC type!", smcotype
859  ! Unknown SMC type!
860  stop
861  ENDIF
862 
863  END SUBROUTINE w3s2xy_smc
864  !--------------------------------------------------------------------------
865 
866 END MODULE w3smcomd
w3smcomd::nxo
integer nxo
Output grid number of longitude cells.
Definition: w3smcomd.F90:83
w3smcomd::smccy
integer, dimension(:), allocatable smccy
Latitude cell size factors.
Definition: w3smcomd.F90:105
w3smcomd::nsmc
integer nsmc
Number of SMC cells used in regridding.
Definition: w3smcomd.F90:120
constants::dera
real, parameter dera
DERA Conversion factor from degrees to radians.
Definition: constants.F90:77
w3smcomd::celfac
integer celfac
Output grid cell scaling factor; should be an integer power of 2.
Definition: w3smcomd.F90:92
w3smcomd::mapsmc
integer, dimension(:,:), allocatable mapsmc
Regridded MAPSTA.
Definition: w3smcomd.F90:99
w3smcomd::nyo
integer nyo
Output grid number of latitude cells.
Definition: w3smcomd.F90:84
w3smcomd::w3s2xy_smcnn
subroutine w3s2xy_smcnn(S, XY, DIRN)
Fill regular grid using nearest SMC point data.
Definition: w3smcomd.F90:712
w3smcomd::xdist
real, dimension(:,:), allocatable xdist
Lng.
Definition: w3smcomd.F90:114
w3smcomd::dlat
real dlat
Base longitude cell size.
Definition: w3smcomd.F90:106
w3smcomd::calc_interp
subroutine calc_interp()
Calculates weights for SMC to arbitrary grid intepolation.
Definition: w3smcomd.F90:623
w3smcomd::w3s2xy_smc
subroutine w3s2xy_smc(S, XY, DIR)
Entry point for SMC version of W3S2XY.
Definition: w3smcomd.F90:817
w3smcomd::dlon
real dlon
Base latitude cell size.
Definition: w3smcomd.F90:107
w3gdatmd::sy
real, pointer sy
Definition: w3gdatmd.F90:1183
constants::rade
real, parameter rade
RADE Conversion factor from radians to degrees.
Definition: constants.F90:76
w3smcomd::w3s2xy_smcrg_dir
subroutine w3s2xy_smcrg_dir(S, XY)
Regrid directional SMC data onto a regular grid.
Definition: w3smcomd.F90:439
w3gdatmd::ny
integer, pointer ny
Definition: w3gdatmd.F90:1097
w3smcomd::smcmask
logical, dimension(:), allocatable smcmask
Mask for type 1 output (flat array)
Definition: w3smcomd.F90:100
w3smcomd::smcidx
integer, dimension(:), allocatable smcidx
Indices of SMC cells within output grid domain.
Definition: w3smcomd.F90:101
w3smcomd::exo
double precision exo
Output grid final longitude.
Definition: w3smcomd.F90:79
w3gdatmd::nglo
integer, pointer nglo
Definition: w3gdatmd.F90:1168
w3smcomd::mapsta_smc
subroutine mapsta_smc()
Calculates a new MAPSTA using SMC grid cell averaging.
Definition: w3smcomd.F90:519
w3gdatmd::polat
real, pointer polat
Definition: w3gdatmd.F90:1191
w3gdatmd::x0
real, pointer x0
Definition: w3gdatmd.F90:1183
w3smcomd::w3s2xy_smcrg
subroutine w3s2xy_smcrg(S, XY)
Regrid SMC data onto a regular grid.
Definition: w3smcomd.F90:360
w3gdatmd::nsea
integer, pointer nsea
Definition: w3gdatmd.F90:1097
w3smcomd::xidx
integer, dimension(:), allocatable xidx
X-indices of SMC cells in regular grid.
Definition: w3smcomd.F90:93
w3servmd
Definition: w3servmd.F90:3
w3servmd::w3lltoeq
subroutine w3lltoeq(PHI, LAMBDA, PHI_EQ, LAMBDA_EQ, ANGLED, PHI_POLE, LAMBDA_POLE, POINTS)
Definition: w3servmd.F90:1084
w3gdatmd::nbac
integer, pointer nbac
Definition: w3gdatmd.F90:1168
w3smcomd::eyo
double precision eyo
Output grid final latitude.
Definition: w3smcomd.F90:80
w3smcomd::ndsmc
integer ndsmc
ww3_smcint file unit number
Definition: w3smcomd.F90:116
w3smcomd::nnidx
integer, dimension(:,:), allocatable nnidx
Nearest neighbour SMC point to regular grid.
Definition: w3smcomd.F90:113
w3odatmd
Definition: w3odatmd.F90:3
w3gdatmd::clats
real, dimension(:), pointer clats
Definition: w3gdatmd.F90:1196
w3psmcmd::smcgradn
subroutine smcgradn(CVQ, GrdX, GrdY, L0r1)
Evaluate local gradient for sea points.
Definition: w3psmcmd.F90:2335
w3smcomd::sxo
double precision sxo
Output grid longitude origin.
Definition: w3smcomd.F90:77
w3smcomd::smccx
integer, dimension(:), allocatable smccx
SMC grid definition.
Definition: w3smcomd.F90:104
w3gdatmd::mapsf
integer, dimension(:,:), pointer mapsf
Definition: w3gdatmd.F90:1163
w3smcomd::dxo
double precision dxo
Output grid cell longitude size.
Definition: w3smcomd.F90:81
file
file(STRINGS ${CMAKE_BINARY_DIR}/switch switch_strings) separate_arguments(switches UNIX_COMMAND $
Definition: CMakeLists.txt:3
constants::radius
real, parameter radius
RADIUS Radius of the earth (m).
Definition: constants.F90:79
w3smcomd::smcnout
integer smcnout
Number of SMC output cells.
Definition: w3smcomd.F90:119
w3smcomd
Service module for support of SMC regridding and interpolation.
Definition: w3smcomd.F90:56
w3gdatmd::ijkcel
integer, dimension(:,:), pointer ijkcel
Definition: w3gdatmd.F90:1170
w3gdatmd::y0
real, pointer y0
Definition: w3gdatmd.F90:1183
w3smcomd::xspan
integer, dimension(:), allocatable xspan
Number of longitude cells SMC cell spans.
Definition: w3smcomd.F90:95
w3psmcmd
Spherical Multiple-Cell (SMC) grid routines.
Definition: w3psmcmd.F90:18
w3gdatmd::sx
real, pointer sx
Definition: w3gdatmd.F90:1183
w3smcomd::w3s2xy_smcnn_int
subroutine w3s2xy_smcnn_int(S, XY, DIRN)
Nearest neighbour interpolation.
Definition: w3smcomd.F90:763
w3gdatmd::narc
integer, pointer narc
Definition: w3gdatmd.F90:1168
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
w3gdatmd
Definition: w3gdatmd.F90:16
w3gdatmd::arctc
logical, pointer arctc
Definition: w3gdatmd.F90:1264
constants::file_endian
character(*), parameter file_endian
FILE_ENDIAN Filled by preprocessor with 'big_endian', 'little_endian', or 'native'.
Definition: constants.F90:86
w3servmd::extcde
subroutine extcde(IEXIT, UNIT, MSG, FILE, LINE, COMM)
Definition: w3servmd.F90:736
w3smcomd::read_smcint
subroutine read_smcint()
Read interpolation information from smcint.ww3.
Definition: w3smcomd.F90:580
w3smcomd::smc_interp
subroutine smc_interp()
Generate SMC interpolation/output information.
Definition: w3smcomd.F90:143
w3smcomd::yspan
integer, dimension(:), allocatable yspan
Number of longitude cells SMC cell spans.
Definition: w3smcomd.F90:96
w3smcomd::noval
real noval
Fill value for seapoints with no value.
Definition: w3smcomd.F90:110
w3gdatmd::nrlv
integer, pointer nrlv
Definition: w3gdatmd.F90:1167
w3smcomd::yidx
integer, dimension(:), allocatable yidx
Y-Indices of SMC cells in regular grid.
Definition: w3smcomd.F90:94
w3gdatmd::nx
integer, pointer nx
Definition: w3gdatmd.F90:1097
w3smcomd::syo
double precision syo
Output grid latitude origin.
Definition: w3smcomd.F90:78
constants::undef
real undef
UNDEF Value for undefined variable in output.
Definition: constants.F90:84
w3smcomd::smcotype
integer smcotype
Type of SMC output: 1=seapoint grid of SMC cells; 2=regridding to regular grid; 3=interpolation to ar...
Definition: w3smcomd.F90:90
w3smcomd::dyo
double precision dyo
Output grid cell latitude size.
Definition: w3smcomd.F90:82
w3smcomd::wts
real, dimension(:), allocatable wts
Regridding weights.
Definition: w3smcomd.F90:97
w3smcomd::ydist
real, dimension(:,:), allocatable ydist
Lat.
Definition: w3smcomd.F90:115
w3smcomd::cov
real, dimension(:,:), allocatable cov
Wet fraction (coverage) of cell.
Definition: w3smcomd.F90:98
w3gdatmd::mapsta
integer, dimension(:,:), pointer mapsta
Definition: w3gdatmd.F90:1163
w3gdatmd::polon
real, pointer polon
Definition: w3gdatmd.F90:1191
w3smcomd::cfac
integer cfac
SMC scaling factor (number of levels)
Definition: w3smcomd.F90:108