WAVEWATCH III  beta 0.0.1
w3smcomd Module Reference

Service module for support of SMC regridding and interpolation. More...

Functions/Subroutines

subroutine smc_interp ()
 Generate SMC interpolation/output information. More...
 
subroutine w3s2xy_smcrg (S, XY)
 Regrid SMC data onto a regular grid. More...
 
subroutine w3s2xy_smcrg_dir (S, XY)
 Regrid directional SMC data onto a regular grid. More...
 
subroutine mapsta_smc ()
 Calculates a new MAPSTA using SMC grid cell averaging. More...
 
subroutine read_smcint ()
 Read interpolation information from smcint.ww3. More...
 
subroutine calc_interp ()
 Calculates weights for SMC to arbitrary grid intepolation. More...
 
subroutine w3s2xy_smcnn (S, XY, DIRN)
 Fill regular grid using nearest SMC point data. More...
 
subroutine w3s2xy_smcnn_int (S, XY, DIRN)
 Nearest neighbour interpolation. More...
 
subroutine w3s2xy_smc (S, XY, DIR)
 Entry point for SMC version of W3S2XY. More...
 

Variables

double precision sxo
 Output grid longitude origin. More...
 
double precision syo
 Output grid latitude origin. More...
 
double precision exo
 Output grid final longitude. More...
 
double precision eyo
 Output grid final latitude. More...
 
double precision dxo
 Output grid cell longitude size. More...
 
double precision dyo
 Output grid cell latitude size. More...
 
integer nxo
 Output grid number of longitude cells. More...
 
integer nyo
 Output grid number of latitude cells. More...
 
integer smcotype
 Type of SMC output: 1=seapoint grid of SMC cells; 2=regridding to regular grid; 3=interpolation to arbtrary grid; 4=nearest neighbour interpolation to arbitrary grid. More...
 
integer celfac
 Output grid cell scaling factor; should be an integer power of 2. More...
 
integer, dimension(:), allocatable xidx
 X-indices of SMC cells in regular grid. More...
 
integer, dimension(:), allocatable yidx
 Y-Indices of SMC cells in regular grid. More...
 
integer, dimension(:), allocatable xspan
 Number of longitude cells SMC cell spans. More...
 
integer, dimension(:), allocatable yspan
 Number of longitude cells SMC cell spans. More...
 
real, dimension(:), allocatable wts
 Regridding weights. More...
 
real, dimension(:,:), allocatable cov
 Wet fraction (coverage) of cell. More...
 
integer, dimension(:,:), allocatable mapsmc
 Regridded MAPSTA. More...
 
logical, dimension(:), allocatable smcmask
 Mask for type 1 output (flat array) More...
 
integer, dimension(:), allocatable smcidx
 Indices of SMC cells within output grid domain. More...
 
integer, dimension(:), allocatable smccx
 SMC grid definition. More...
 
integer, dimension(:), allocatable smccy
 Latitude cell size factors. More...
 
real dlat
 Base longitude cell size. More...
 
real dlon
 Base latitude cell size. More...
 
integer cfac
 SMC scaling factor (number of levels) More...
 
real noval
 Fill value for seapoints with no value. More...
 
integer, dimension(:,:), allocatable nnidx
 Nearest neighbour SMC point to regular grid. More...
 
real, dimension(:,:), allocatable xdist
 Lng. More...
 
real, dimension(:,:), allocatable ydist
 Lat. More...
 
integer ndsmc
 ww3_smcint file unit number More...
 
integer smcnout
 Number of SMC output cells. More...
 
integer nsmc
 Number of SMC cells used in regridding. More...
 

Detailed Description

Service module for support of SMC regridding and interpolation.

For SMC grids, four types of output are possible:

  1. Flat grid (seapoint) output of SMC cells with associated cell size variables (cx and cy). Requires extra effort to plot as grid is not regular.
  2. Regular, uniformly gridded output to a specified output grid. This is achieved by area averaging of the SMC cells. The output grid will be aligned with the SMC grid cell edges which may result in the actual output grid being slightly different to the original user request. A land/sea mask is created by keeping track of the cell coverage and setting cells with total coverage of <50% UNDEF.
  3. [Experimental] Arbitrary regualar grid re-gridding using indices and weights generated from WW3_SMCINT*. Uses the local gradient within the grid cell and distance between cell centres to interpolate.
  4. [Experimental] As type 3, but with no interpolation - value from surrounding SMC cell only.

* The ww3_smcint program is experimental and not yet included in the official WW3 distribution; it is currently part of the UK Met Office's suite of internal tools.

Remarks
Note - directional fields are expected to be passed to routines with units of radians (cartesian convention). They will be OUTPUT in units of degrees (nautical convention).
Author
Chris Bunney
Date
21-Jul-2021

Change log

Date Ver Comments
18-Jan-2016 4.18 Initial version
28-Sep-2016 4.18 Bug fix EXO/EYO calcs for whole domain output
05-Oct-2016 4.18 Bug fix regular grid indicies for type 2 output
29-Sep-2017 4.18 Revise calculation of indicies to ensure selected cells fall inside user selected areas.
18-Apr-2018 4.18 Added Type 3 and 4 SMC output
20-Jun-2018 4.18 Directional fields output as nautical convention (deg)
27-Jun-2018 6.05 Ported to V6
06-Jan-2021 7.12 Use ARCTC option for SMC grid.
20-Jul-2021 7.12 Fix bug where edge cells in design grid may not be matched due where SMC cell > base grid size.
21-Jul-2021 7.12 Elevated some grid variables to DOUBLE PRECISION, fixed EXO/EYO bug

Function/Subroutine Documentation

◆ calc_interp()

subroutine w3smcomd::calc_interp

Calculates weights for SMC to arbitrary grid intepolation.

Calculates the interpolation indices and weights for regridding an SMC grid to an arbitrary regular grid. Calculated index is that of the SMC cell that contains output cell centre. Weights are the distance in metres between the output and SMC cell centres.

A future version may allow for output grids to be on a rotated pole.

Author
Chris Bunney
Date
18-Apr-2018

Definition at line 623 of file w3smcomd.F90.

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 

References w3gdatmd::clats, constants::dera, dlat, dlon, dxo, dyo, nnidx, w3gdatmd::polat, w3gdatmd::polon, constants::radius, sxo, syo, w3servmd::w3lltoeq(), xdist, and ydist.

◆ mapsta_smc()

subroutine w3smcomd::mapsta_smc

Calculates a new MAPSTA using SMC grid cell averaging.

Author
Chris Bunney
Date
02-Jul-2013

Definition at line 519 of file w3smcomd.F90.

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 

References cov, w3gdatmd::mapsf, mapsmc, w3gdatmd::mapsta, w3gdatmd::nsea, nxo, nyo, wts, xidx, xspan, yidx, and yspan.

◆ read_smcint()

subroutine w3smcomd::read_smcint

Read interpolation information from smcint.ww3.

Reads the interpolation indices and distance weights from the smcint.ww3 file generated by ww3_smcint program.

Author
Chris Bunney
Date
18-Apr-2018

Definition at line 580 of file w3smcomd.F90.

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 

References dxo, dyo, w3servmd::extcde(), file(), constants::file_endian, ndsmc, nnidx, nxo, nyo, sxo, syo, xdist, and ydist.

◆ smc_interp()

subroutine w3smcomd::smc_interp

Generate SMC interpolation/output information.

This subroutine generates index or mask values for extraction of SMC data to either a flat grid or regular lat/lon grid, depending on the type of SMC output grid selected:

Type 1: Generates a mask for extracting only points from the user requested region.

Type 2: Calculate interpolation indices and weights for regridding the irregular SMC grid onto a regular, uniformly spaced lat/lon grid.

Author
Chris Bunney
Date
22-Oct-2015

Definition at line 143 of file w3smcomd.F90.

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 

References w3gdatmd::arctc, celfac, cfac, dlat, dlon, dxo, dyo, exo, eyo, w3gdatmd::ijkcel, w3gdatmd::narc, w3gdatmd::nbac, w3gdatmd::nglo, w3gdatmd::nrlv, w3gdatmd::nsea, nsmc, w3gdatmd::nx, nxo, w3gdatmd::ny, nyo, smcidx, smcmask, smcotype, w3gdatmd::sx, sxo, w3gdatmd::sy, syo, wts, w3gdatmd::x0, xidx, xspan, w3gdatmd::y0, yidx, and yspan.

◆ w3s2xy_smc()

subroutine w3smcomd::w3s2xy_smc ( real, dimension(:), intent(in)  S,
real, dimension(nxo,nyo), intent(out)  XY,
logical, optional  DIR 
)

Entry point for SMC version of W3S2XY.

Dispatches to regridding subroutine based on SMCOTYPE. Optional DIR logical specifies whether field is a directional value; in which case it will be decomposed into u/v components prior to any interpolation.

Parameters
[in]SInput array on SMC grid
[out]XYOutput array to store interpolated 2D field
[in]DIR(Optional) Set to .TRUE. if S is a directional field
Author
Chris Bunney
Date
18-Apr-2018

Definition at line 817 of file w3smcomd.F90.

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 

References constants::rade, smcmask, smcotype, constants::undef, w3s2xy_smcnn(), w3s2xy_smcnn_int(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ w3s2xy_smcnn()

subroutine w3smcomd::w3s2xy_smcnn ( real, dimension(:), intent(in)  S,
real, dimension(nxo,nyo), intent(out)  XY,
logical, intent(in)  DIRN 
)

Fill regular grid using nearest SMC point data.

Directional fields (DIRN=True) will be assumed to be in radians and will be converted to degrees in nautical convention.

Parameters
[in]SInput array on SMC grid
[out]XYOutput array to store interpolated 2D field
[in]DIRNSet to .TRUE. if S is a directional field
Author
Chris Bunney
Date
18-Apr-2018

Definition at line 712 of file w3smcomd.F90.

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 

References nnidx, noval, constants::rade, and constants::undef.

Referenced by w3s2xy_smc().

◆ w3s2xy_smcnn_int()

subroutine w3smcomd::w3s2xy_smcnn_int ( real, dimension(:), intent(in)  S,
real, dimension(nxo,nyo), intent(out)  XY,
logical, intent(in)  DIRN 
)

Nearest neighbour interpolation.

Fill regular grid using nearest SMC point data and interpolate output value based on local gradient and distance between grid cell centres.

Directional fields (DIRN=True) will be assumed to be in radians and will be converted to degrees in nautical convention.

Parameters
[in]SInput array on SMC grid
[out]XYOutput array to store interpolated 2D field
[in]DIRNSet to .TRUE. if S is a directional field
Author
Chris Bunney
Date
18-Apr-2018

Definition at line 763 of file w3smcomd.F90.

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 

References nnidx, constants::rade, w3psmcmd::smcgradn(), constants::undef, xdist, and ydist.

Referenced by w3s2xy_smc().

◆ w3s2xy_smcrg()

subroutine w3smcomd::w3s2xy_smcrg ( real, dimension(:), intent(in)  S,
real, dimension(nxo,nyo), intent(out)  XY 
)

Regrid SMC data onto a regular grid.

Regrids scalar data from the SMC grid onto a regular grid. Uses pre-calculated grid indices and weights generated from the smc_interp() subroutine.

Remarks
If source field is directional data, use the w3s2xy_smcrg_dir() subroutine instead.
Parameters
[in]SSource field, on SMC grid.
[out]XYStorage for regridded field; must be 2D array with dimensions of (NXO,NYO).
Author
Chris Bunney
Date
02-Jul-2013

Definition at line 360 of file w3smcomd.F90.

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 

References cov, mapsmc, noval, nsmc, smcidx, constants::undef, wts, xidx, xspan, yidx, and yspan.

Referenced by w3s2xy_smc().

◆ w3s2xy_smcrg_dir()

subroutine w3smcomd::w3s2xy_smcrg_dir ( real, dimension(:), intent(in)  S,
real, dimension(nxo,nyo), intent(out)  XY 
)

Regrid directional SMC data onto a regular grid.

Regrids directioanl scalar data from the SMC grid onto a regular grid. Uses pre-calculated grid indices and weights generated from the smc_interp() subroutine.

Remarks
Functionality as per w3s2xy_smc(), but decomposes the field into u/v components first to ensure proper area averaging of directional data (handles cyclic transition between 359 -> 0 degrees).
Parameters
[in]SDirectional source field, on SMC grid.
[out]XYStorage for regridded field; must be 2D array with dimensions of (NXO,NYO).
Author
Chris Bunney
Date
02-Jul-2013

Definition at line 439 of file w3smcomd.F90.

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 

References cov, mapsmc, noval, nsmc, constants::rade, smcidx, constants::undef, wts, xidx, xspan, yidx, and yspan.

Referenced by w3s2xy_smc().

Variable Documentation

◆ celfac

integer w3smcomd::celfac

Output grid cell scaling factor; should be an integer power of 2.

Definition at line 92 of file w3smcomd.F90.

92  INTEGER :: CELFAC

Referenced by smc_interp(), and w3ounf().

◆ cfac

integer w3smcomd::cfac

SMC scaling factor (number of levels)

Definition at line 108 of file w3smcomd.F90.

108  INTEGER :: CFAC

Referenced by smc_interp().

◆ cov

real, dimension(:,:), allocatable w3smcomd::cov

Wet fraction (coverage) of cell.

Definition at line 98 of file w3smcomd.F90.

98  REAL, ALLOCATABLE :: COV(:,:)

Referenced by mapsta_smc(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ dlat

real w3smcomd::dlat

Base longitude cell size.

Definition at line 106 of file w3smcomd.F90.

106  REAL :: DLAT

Referenced by calc_interp(), and smc_interp().

◆ dlon

real w3smcomd::dlon

Base latitude cell size.

Definition at line 107 of file w3smcomd.F90.

107  REAL :: DLON

Referenced by calc_interp(), and smc_interp().

◆ dxo

double precision w3smcomd::dxo

Output grid cell longitude size.

Definition at line 81 of file w3smcomd.F90.

81  DOUBLE PRECISION :: DXO

Referenced by calc_interp(), read_smcint(), and smc_interp().

◆ dyo

double precision w3smcomd::dyo

Output grid cell latitude size.

Definition at line 82 of file w3smcomd.F90.

82  DOUBLE PRECISION :: DYO

Referenced by calc_interp(), read_smcint(), and smc_interp().

◆ exo

double precision w3smcomd::exo

Output grid final longitude.

Definition at line 79 of file w3smcomd.F90.

79  DOUBLE PRECISION :: EXO

Referenced by smc_interp(), and w3ounf().

◆ eyo

double precision w3smcomd::eyo

Output grid final latitude.

Definition at line 80 of file w3smcomd.F90.

80  DOUBLE PRECISION :: EYO

Referenced by smc_interp(), and w3ounf().

◆ mapsmc

integer, dimension(:,:), allocatable w3smcomd::mapsmc

Regridded MAPSTA.

Definition at line 99 of file w3smcomd.F90.

99  INTEGER, ALLOCATABLE :: MAPSMC(:,:)

Referenced by mapsta_smc(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ ndsmc

integer w3smcomd::ndsmc

ww3_smcint file unit number

Definition at line 116 of file w3smcomd.F90.

116  INTEGER :: NDSMC

Referenced by read_smcint().

◆ nnidx

integer, dimension(:,:), allocatable w3smcomd::nnidx

Nearest neighbour SMC point to regular grid.

Definition at line 113 of file w3smcomd.F90.

113  INTEGER, ALLOCATABLE :: NNIDX(:,:)

Referenced by calc_interp(), read_smcint(), w3s2xy_smcnn(), and w3s2xy_smcnn_int().

◆ noval

real w3smcomd::noval

Fill value for seapoints with no value.

Definition at line 110 of file w3smcomd.F90.

110  REAL :: NOVAL

Referenced by w3ounf(), w3s2xy_smcnn(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ nsmc

integer w3smcomd::nsmc

Number of SMC cells used in regridding.

Definition at line 120 of file w3smcomd.F90.

120  INTEGER :: NSMC

Referenced by smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ nxo

integer w3smcomd::nxo

Output grid number of longitude cells.

Definition at line 83 of file w3smcomd.F90.

83  INTEGER :: NXO

Referenced by mapsta_smc(), read_smcint(), and smc_interp().

◆ nyo

integer w3smcomd::nyo

Output grid number of latitude cells.

Definition at line 84 of file w3smcomd.F90.

84  INTEGER :: NYO

Referenced by mapsta_smc(), read_smcint(), and smc_interp().

◆ smccx

integer, dimension(:), allocatable w3smcomd::smccx

SMC grid definition.

Longitude cell size factors

Definition at line 104 of file w3smcomd.F90.

104  INTEGER, ALLOCATABLE :: SMCCX(:)

◆ smccy

integer, dimension(:), allocatable w3smcomd::smccy

Latitude cell size factors.

Definition at line 105 of file w3smcomd.F90.

105  INTEGER, ALLOCATABLE :: SMCCY(:)

◆ smcidx

integer, dimension(:), allocatable w3smcomd::smcidx

Indices of SMC cells within output grid domain.

Definition at line 101 of file w3smcomd.F90.

101  INTEGER, ALLOCATABLE :: SMCIDX(:)

Referenced by smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ smcmask

logical, dimension(:), allocatable w3smcomd::smcmask

Mask for type 1 output (flat array)

Definition at line 100 of file w3smcomd.F90.

100  LOGICAL, ALLOCATABLE :: SMCMASK(:)

Referenced by smc_interp(), and w3s2xy_smc().

◆ smcnout

integer w3smcomd::smcnout

Number of SMC output cells.

Definition at line 119 of file w3smcomd.F90.

119  INTEGER :: SMCNOUT

◆ smcotype

integer w3smcomd::smcotype

Type of SMC output: 1=seapoint grid of SMC cells; 2=regridding to regular grid; 3=interpolation to arbtrary grid; 4=nearest neighbour interpolation to arbitrary grid.

Definition at line 90 of file w3smcomd.F90.

90  INTEGER :: SMCOTYPE

Referenced by w3ounfmetamd::init_meta(), smc_interp(), w3ounf(), and w3s2xy_smc().

◆ sxo

double precision w3smcomd::sxo

Output grid longitude origin.

Definition at line 77 of file w3smcomd.F90.

77  DOUBLE PRECISION :: SXO

Referenced by calc_interp(), read_smcint(), smc_interp(), and w3ounf().

◆ syo

double precision w3smcomd::syo

Output grid latitude origin.

Definition at line 78 of file w3smcomd.F90.

78  DOUBLE PRECISION :: SYO

Referenced by calc_interp(), read_smcint(), smc_interp(), and w3ounf().

◆ wts

real, dimension(:), allocatable w3smcomd::wts

Regridding weights.

Definition at line 97 of file w3smcomd.F90.

97  REAL, ALLOCATABLE :: WTS(:)

Referenced by mapsta_smc(), smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ xdist

real, dimension(:,:), allocatable w3smcomd::xdist

Lng.

distance to nearest neighbour

Definition at line 114 of file w3smcomd.F90.

114  REAL, ALLOCATABLE :: XDIST(:,:)

Referenced by calc_interp(), read_smcint(), and w3s2xy_smcnn_int().

◆ xidx

integer, dimension(:), allocatable w3smcomd::xidx

X-indices of SMC cells in regular grid.

Definition at line 93 of file w3smcomd.F90.

93  INTEGER, ALLOCATABLE :: XIDX(:)

Referenced by mapsta_smc(), smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ xspan

integer, dimension(:), allocatable w3smcomd::xspan

Number of longitude cells SMC cell spans.

Definition at line 95 of file w3smcomd.F90.

95  INTEGER, ALLOCATABLE :: XSPAN(:)

Referenced by mapsta_smc(), smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ ydist

real, dimension(:,:), allocatable w3smcomd::ydist

Lat.

distance to nearest neighbour

Definition at line 115 of file w3smcomd.F90.

115  REAL, ALLOCATABLE :: YDIST(:,:)

Referenced by calc_interp(), read_smcint(), and w3s2xy_smcnn_int().

◆ yidx

integer, dimension(:), allocatable w3smcomd::yidx

Y-Indices of SMC cells in regular grid.

Definition at line 94 of file w3smcomd.F90.

94  INTEGER, ALLOCATABLE :: YIDX(:)

Referenced by mapsta_smc(), smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

◆ yspan

integer, dimension(:), allocatable w3smcomd::yspan

Number of longitude cells SMC cell spans.

Definition at line 96 of file w3smcomd.F90.

96  INTEGER, ALLOCATABLE :: YSPAN(:)

Referenced by mapsta_smc(), smc_interp(), w3s2xy_smcrg(), and w3s2xy_smcrg_dir().

constants::dera
real, parameter dera
DERA Conversion factor from degrees to radians.
Definition: constants.F90:77
m_constants::rade
real rade
conversion from radians to degrees
Definition: mod_constants.f90:33
scrip_timers::status
character(len=8), dimension(max_timers), save status
Definition: scrip_timers.f:63
w3gdatmd::polat
real, pointer polat
Definition: w3gdatmd.F90:1191
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::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
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
w3psmcmd
Spherical Multiple-Cell (SMC) grid routines.
Definition: w3psmcmd.F90:18
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
w3gdatmd
Definition: w3gdatmd.F90:16
w3servmd::extcde
subroutine extcde(IEXIT, UNIT, MSG, FILE, LINE, COMM)
Definition: w3servmd.F90:736
w3gdatmd::polon
real, pointer polon
Definition: w3gdatmd.F90:1191