WAVEWATCH III  beta 0.0.1
w3partmd Module Reference

Spectral partitioning according to the watershed method. More...

Functions/Subroutines

subroutine w3part (SPEC, UABS, UDIR, DEPTH, WN, NP, XP, DIMXP)
 Interface to watershed partitioning routines. More...
 
subroutine ptsort (IMI, IND, IHMAX)
 Sorts the image data in ascending order. More...
 
subroutine ptnghb
 Nearest neighbour calculation. More...
 
subroutine pt_fld (IMI, IND, IMO, ZP, NPART)
 Image watersheding. More...
 
subroutine ptmean (NPI, IMO, ZP, DEPTH, UABS, UDIR, WN, NPO, XP, DIMXP, PMAP)
 Compute mean parameters per partition. More...
 

Detailed Description

Spectral partitioning according to the watershed method.

Multiple partitioning methods are provided in this module that can be selected via the PTMETH namelist variable. Please see the w3part() subroutine for details

Author
Barbara Tracey, H. L. Tolman, M. Szyszka, Chris Bunney
Date
23 Jul 2018

Function/Subroutine Documentation

◆ pt_fld()

subroutine w3partmd::pt_fld ( integer, dimension(nspec), intent(in)  IMI,
integer, dimension(nspec), intent(in)  IND,
integer, dimension(nspec), intent(out)  IMO,
real, dimension(nspec), intent(in)  ZP,
integer, intent(out)  NPART 
)

Image watersheding.

This subroutine does incremental flooding of the image to determine the watershed image.

Parameters
[in]IMIInput discretized spectrum
[in]INDSorted addresses
[out]IMOOutput partitioned spectrum
[in]ZPSpectral array
[out]NPARTNumber of partitions found
Author
H.L. Tolman
Date
01 Nov 2006

Definition at line 841 of file w3partmd.F90.

841  !/
842  !/ +-----------------------------------+
843  !/ | WAVEWATCH III NOAA/NCEP |
844  !/ | H. L. Tolman |
845  !/ | FORTRAN 90 |
846  !/ | Last update : 01-Nov-2006 !
847  !/ +-----------------------------------+
848  !/
849  !/ 01-Nov-2006 : Origination. ( version 3.10 )
850  !/
851  ! 1. Purpose :
852  !
853  ! This subroutine does incremental flooding of the image to
854  ! determine the watershed image.
855  !
856  ! 3. Parameters :
857  !
858  ! Parameter list
859  ! ----------------------------------------------------------------
860  ! IMI I.A. I Input discretized spectrum.
861  ! IND I.A. I Sorted addresses.
862  ! IMO I.A. O Output partitioned spectrum.
863  ! ZP R.A. I Spectral array.
864  ! NPART Int. O Number of partitions found.
865  ! ----------------------------------------------------------------
866  !
867  ! 4. Subroutines used :
868  !
869  ! Name Type Module Description
870  ! ----------------------------------------------------------------
871  ! STRACE Sur. W3SERVMD Subroutine tracing.
872  ! ----------------------------------------------------------------
873  !
874  ! 10. Source code :
875  !
876  !/ ------------------------------------------------------------------- /
877  !
878 #ifdef W3_S
879  USE w3servmd, ONLY: strace
880 #endif
881  !
882  USE w3gdatmd, ONLY: nspec
883  !
884  IMPLICIT NONE
885  !/
886  !/ ------------------------------------------------------------------- /
887  !/ Parameter list
888  !/
889  INTEGER, INTENT(IN) :: IMI(NSPEC), IND(NSPEC)
890  INTEGER, INTENT(OUT) :: IMO(NSPEC), NPART
891  REAL, INTENT(IN) :: ZP(NSPEC)
892  !/
893  !/ ------------------------------------------------------------------- /
894  !/ Local parameters
895  !/
896  INTEGER :: MASK, INIT, IWSHED, IMD(NSPEC), &
897  IC_LABEL, IFICT_PIXEL, M, IH, MSAVE, &
898  IP, I, IPP, IC_DIST, IEMPTY, IPPP, &
899  JL, JN, IPT, J
900  INTEGER :: IQ(NSPEC), IQ_START, IQ_END
901 #ifdef W3_S
902  INTEGER, SAVE :: IENT = 0
903 #endif
904  REAL :: ZPMAX, EP1, DIFF
905  !/
906 #ifdef W3_S
907  CALL strace (ient, 'PT_FLD')
908 #endif
909  !
910  ! -------------------------------------------------------------------- /
911  ! 0. Initializations
912  !
913  mask = -2
914  init = -1
915  iwshed = 0
916  imo = init
917  ic_label = 0
918  imd = 0
919  ifict_pixel = -100
920  !
921  iq_start = 1
922  iq_end = 1
923  !
924  zpmax = maxval( zp )
925  !
926  ! -------------------------------------------------------------------- /
927  ! 1. Loop over levels
928  !
929  m = 1
930  !
931  DO ih=1, ihmax
932  msave = m
933  !
934  ! 1.a Pixels at level IH
935  !
936  DO
937  ip = ind(m)
938  IF ( imi(ip) .NE. ih ) EXIT
939  !
940  ! Flag the point, if it stays flagge, it is a separate minimum.
941  !
942  imo(ip) = mask
943  !
944  ! Consider neighbors. If there is neighbor, set distance and add
945  ! to queue.
946  !
947  DO i=1, neigh(9,ip)
948  ipp = neigh(i,ip)
949  IF ( (imo(ipp).GT.0) .OR. (imo(ipp).EQ.iwshed) ) THEN
950  imd(ip) = 1
951  CALL fifo_add (ip)
952  EXIT
953  END IF
954  END DO
955  !
956  IF ( m+1 .GT. nspec ) THEN
957  EXIT
958  ELSE
959  m = m + 1
960  END IF
961  !
962  END DO
963  !
964  ! 1.b Process the queue
965  !
966  ic_dist = 1
967  CALL fifo_add (ifict_pixel)
968  !
969  DO
970  CALL fifo_first (ip)
971  !
972  ! Check for end of processing
973  !
974  IF ( ip .EQ. ifict_pixel ) THEN
975  CALL fifo_empty (iempty)
976  IF ( iempty .EQ. 1 ) THEN
977  EXIT
978  ELSE
979  CALL fifo_add (ifict_pixel)
980  ic_dist = ic_dist + 1
981  CALL fifo_first (ip)
982  END IF
983  END IF
984  !
985  ! Process queue
986  !
987  DO i=1, neigh(9,ip)
988  ipp = neigh(i,ip)
989  !
990  ! Check for labeled watersheds or basins
991  !
992  IF ( (imd(ipp).LT.ic_dist) .AND. ( (imo(ipp).GT.0) .OR. &
993  (imo(ipp).EQ.iwshed))) THEN
994  !
995  IF ( imo(ipp) .GT. 0 ) THEN
996  !
997  IF ((imo(ip) .EQ. mask) .OR. (imo(ip) .EQ. &
998  iwshed)) THEN
999  imo(ip) = imo(ipp)
1000  ELSE IF (imo(ip) .NE. imo(ipp)) THEN
1001  imo(ip) = iwshed
1002  END IF
1003  !
1004  ELSE IF (imo(ip) .EQ. mask) THEN
1005  !
1006  imo(ip) = iwshed
1007  !
1008  END IF
1009  !
1010  ELSE IF ( (imo(ipp).EQ.mask) .AND. (imd(ipp).EQ.0) ) THEN
1011  !
1012  imd(ipp) = ic_dist + 1
1013  CALL fifo_add (ipp)
1014  !
1015  END IF
1016  !
1017  END DO
1018  !
1019  END DO
1020  !
1021  ! 1.c Check for mask values in IMO to identify new basins
1022  !
1023  m = msave
1024  !
1025  DO
1026  ip = ind(m)
1027  IF ( imi(ip) .NE. ih ) EXIT
1028  imd(ip) = 0
1029  !
1030  IF (imo(ip) .EQ. mask) THEN
1031  !
1032  ! ... New label for pixel
1033  !
1034  ic_label = ic_label + 1
1035  CALL fifo_add (ip)
1036  imo(ip) = ic_label
1037  !
1038  ! ... and all connected to it ...
1039  !
1040  DO
1041  CALL fifo_empty (iempty)
1042  IF ( iempty .EQ. 1 ) EXIT
1043  CALL fifo_first (ipp)
1044  !
1045  DO i=1, neigh(9,ipp)
1046  ippp = neigh(i,ipp)
1047  IF ( imo(ippp) .EQ. mask ) THEN
1048  CALL fifo_add (ippp)
1049  imo(ippp) = ic_label
1050  END IF
1051  END DO
1052  !
1053  END DO
1054  !
1055  END IF
1056  !
1057  IF ( m + 1 .GT. nspec ) THEN
1058  EXIT
1059  ELSE
1060  m = m + 1
1061  END IF
1062  !
1063  END DO
1064  !
1065  END DO
1066  !
1067  ! -------------------------------------------------------------------- /
1068  ! 2. Find nearest neighbor of 0 watershed points and replace
1069  ! use original input to check which group to affiliate with 0
1070  ! Soring changes first in IMD to assure symetry in adjustment.
1071  !
1072  DO j=1, 5
1073  imd = imo
1074  DO jl=1 , nspec
1075  ipt = -1
1076  IF ( imo(jl) .EQ. 0 ) THEN
1077  ep1 = zpmax
1078  DO jn=1, neigh(9,jl)
1079  diff = abs( zp(jl) - zp(neigh(jn,jl)))
1080  IF ( (diff.LE.ep1) .AND. (imo(neigh(jn,jl)).NE.0) ) THEN
1081  ep1 = diff
1082  ipt = jn
1083  END IF
1084  END DO
1085  IF ( ipt .GT. 0 ) imd(jl) = imo(neigh(ipt,jl))
1086  END IF
1087  END DO
1088  imo = imd
1089  IF ( minval(imo) .GT. 0 ) EXIT
1090  END DO
1091  !
1092  npart = ic_label
1093  !
1094  RETURN
1095  !
1096  CONTAINS
1097  !/ ------------------------------------------------------------------- /
1104  SUBROUTINE fifo_add ( IV )
1105 
1106  INTEGER, INTENT(IN) :: IV
1107  !
1108  iq(iq_end) = iv
1109  !
1110  iq_end = iq_end + 1
1111  IF ( iq_end .GT. nspec ) iq_end = 1
1112  !
1113  RETURN
1114  END SUBROUTINE fifo_add
1115  !/ ------------------------------------------------------------------- /
1123  SUBROUTINE fifo_empty ( IEMPTY )
1124 
1125  INTEGER, INTENT(OUT) :: IEMPTY
1126  !
1127  IF ( iq_start .NE. iq_end ) THEN
1128  iempty = 0
1129  ELSE
1130  iempty = 1
1131  END IF
1132  !
1133  RETURN
1134  END SUBROUTINE fifo_empty
1135  !/ ------------------------------------------------------------------- /
1143  SUBROUTINE fifo_first ( IV )
1144 
1145  INTEGER, INTENT(OUT) :: IV
1146  !
1147  iv = iq(iq_start)
1148  !
1149  iq_start = iq_start + 1
1150  IF ( iq_start .GT. nspec ) iq_start = 1
1151  !
1152  RETURN
1153  END SUBROUTINE fifo_first
1154  !/
1155  !/ End of PT_FLD ----------------------------------------------------- /
1156  !/

References fifo_add(), fifo_empty(), fifo_first(), w3odatmd::ihmax, w3gdatmd::nspec, and w3servmd::strace().

Referenced by w3part().

◆ ptmean()

subroutine w3partmd::ptmean ( integer, intent(in)  NPI,
integer, dimension(nspec), intent(in)  IMO,
real, dimension(nspec), intent(in)  ZP,
real, intent(in)  DEPTH,
real, intent(in)  UABS,
real, intent(in)  UDIR,
real, dimension(nk), intent(in)  WN,
integer, intent(out)  NPO,
real, dimension(dimp,0:dimxp), intent(out)  XP,
integer, intent(in)  DIMXP,
integer, dimension(dimxp), intent(out)  PMAP 
)

Compute mean parameters per partition.

Parameters
[in]NPINumber of partitions found.
[in]IMOPartition map.
[in]ZPInput spectrum.
[in]DEPTHWater depth.
[in]UABSWind speed.
[in]UDIRWind direction.
[in]WNWavenumebers for each frequency.
[out]NPONumber of partitions with mean parameters.
[out]XPArray with output parameters.
[in]DIMXPSecond dimension of XP.
[out]PMAPMapping between orig. and combined partitions
Author
Barbara Tracy, H. L. Tolman, M. Szyszka, C. Bunney
Date
02 Dec 2010

Definition at line 1178 of file w3partmd.F90.

1178  !/
1179  !/ +-----------------------------------+
1180  !/ | WAVEWATCH III USACE/NOAA |
1181  !/ | Barbara Tracy |
1182  !/ | H. L. Tolman |
1183  !/ | FORTRAN 90 |
1184  !/ | Last update : 02-Dec-2010 !
1185  !/ +-----------------------------------+
1186  !/
1187  !/ 28-Oct-2006 : Origination. ( version 3.10 )
1188  !/ 02-Nov-2006 : Adding tail to integration. ( version 3.10 )
1189  !/ 24-Mar-2007 : Adding overall field. ( version 3.11 )
1190  !/ 02-Dec-2010 : Adding a mapping PMAP between ( version 3.14 )
1191  !/ original and combined partitions
1192  !/ ( M. Szyszka )
1193  !/
1194  ! 1. Purpose :
1195  !
1196  ! Compute mean parameters per partition.
1197  !
1198  ! 3. Parameters :
1199  !
1200  ! Parameter list
1201  ! ----------------------------------------------------------------
1202  ! NPI Int. I Number of partitions found.
1203  ! IMO I.A. I Partition map.
1204  ! ZP R.A. I Input spectrum.
1205  ! DEPTH Real I Water depth.
1206  ! UABS Real I Wind speed.
1207  ! UDIR Real I Wind direction.
1208  ! WN R.A. I Wavenumebers for each frequency.
1209  ! NPO Int. O Number of partitions with mean parameters.
1210  ! XP R.A. O Array with output parameters.
1211  ! DIMXP int. I Second dimension of XP.
1212  ! PMAP I.A. O Mapping between orig. and combined partitions
1213  ! ----------------------------------------------------------------
1214  !
1215  ! 4. Subroutines used :
1216  !
1217  ! Name Type Module Description
1218  ! ----------------------------------------------------------------
1219  ! STRACE Sur. W3SERVMD Subroutine tracing.
1220  ! WAVNU1 Subr. W3DISPMD Wavenumber computation.
1221  ! ----------------------------------------------------------------
1222  !
1223  ! 10. Source code :
1224  !
1225  !/ ------------------------------------------------------------------- /
1226  !
1227  USE constants
1228 #ifdef W3_S
1229  USE w3servmd, ONLY: strace
1230 #endif
1231  USE w3dispmd, ONLY: wavnu1
1232  !
1233  USE w3gdatmd, ONLY: nk, nth, nspec, dth, sig, dsii, dsip, &
1234  ecos, esin, xfr, fachfe, th, fte
1235  USE w3odatmd, ONLY: iaproc, naperr, ndse, ndst
1236  !
1237  IMPLICIT NONE
1238  !/
1239  !/ ------------------------------------------------------------------- /
1240  !/ Parameter list
1241  !/
1242  INTEGER, INTENT(IN) :: NPI, IMO(NSPEC), DIMXP
1243  INTEGER, INTENT(OUT) :: NPO, PMAP(DIMXP)
1244  REAL, INTENT(IN) :: ZP(NSPEC), DEPTH, UABS, UDIR, WN(NK)
1245  REAL, INTENT(OUT) :: XP(DIMP,0:DIMXP)
1246  !/
1247  !/ ------------------------------------------------------------------- /
1248  !/ Local parameters
1249  !/
1250  INTEGER :: IK, ITH, ISP, IP, IFPMAX(0:NPI)
1251 #ifdef W3_S
1252  INTEGER, SAVE :: IENT = 0
1253 #endif
1254  REAL :: SUMF(0:NK+1,0:NPI), SUMFW(NK,0:NPI), &
1255  SUMFX(NK,0:NPI), SUMFY(NK,0:NPI), &
1256  SUME(0:NPI), SUMEW(0:NPI), &
1257  SUMEX(0:NPI), SUMEY(0:NPI), &
1258  EFPMAX(0:NPI), FCDIR(NTH)
1259  REAL,DIMENSION(0:NPI) :: SUME1, SUME2, SUMEM1, SUMQP
1260  REAL :: HS, XL, XH, XL2, XH2, EL, EH, DENOM, &
1261  SIGP, WNP, CGP, UPAR, C(NK), RD, FACT
1262  REAL :: QP, M0, M1, M2, MM1, FSPRD, EPM_FP, ALP_PM
1263  REAL :: Y, YHAT, XHAT, SUMXY, SUMYLOGY, NUMER,&
1264  SUMY, SUMXXY, SUMXYLOGY, SUMEXP, SUMEYP
1265  REAL :: FTEII
1266  !/
1267 #ifdef W3_S
1268  CALL strace (ient, 'PTMEAN')
1269 #endif
1270  !
1271  ! -------------------------------------------------------------------- /
1272  ! 1. Check on need of processing
1273  !
1274  npo = 0
1275  xp = 0.
1276  !
1277  IF ( npi .EQ. 0 ) RETURN
1278  !
1279  ! -------------------------------------------------------------------- /
1280  ! 2. Initialize arrays
1281  !
1282  sumf = 0.
1283  sumfw = 0.
1284  sumfx = 0.
1285  sumfy = 0.
1286  sume = 0.
1287  !
1288  sume1 = 0. !/ first spectral moment
1289  sume2 = 0. !/ second spectral moment
1290  sumem1 = 0. !/ inverse spectral moment
1291  sumqp = 0. !/ peakedness parameter
1292  !
1293  sumew = 0.
1294  sumex = 0.
1295  sumey = 0.
1296  ifpmax = 0
1297  efpmax = 0.
1298  !
1299  DO ik=1, nk
1300  c(ik) = sig(ik) / wn(ik)
1301  END DO
1302  !
1303  DO ith=1, nth
1304  upar = wsmult * uabs * max(0.,cos(th(ith)-dera*udir))
1305  IF ( upar .LT. c(nk) ) THEN
1306  fcdir(ith) = sig(nk+1)
1307  ELSE
1308  DO ik=nk-1, 2, -1
1309  IF ( upar .LT. c(ik) ) EXIT
1310  END DO
1311  rd = (c(ik)-upar) / (c(ik)-c(ik+1))
1312  IF ( rd .LT. 0 ) THEN
1313  ik = 0
1314  rd = max( 0., rd+1. )
1315  END IF
1316  fcdir(ith) = rd*sig(ik+1) + (1.-rd)*sig(ik)
1317  END IF
1318  END DO
1319  !
1320  ! -------------------------------------------------------------------- /
1321  ! 3. Spectral integrals and preps
1322  ! 3.a Integrals
1323  ! NOTE: Factor DTH only used in Hs computation.
1324  !
1325  DO ik=1, nk
1326  DO ith=1, nth
1327  isp = ik + (ith-1)*nk
1328  ip = imo(isp)
1329  fact = max( 0. , min( 1. , &
1330  1. - ( fcdir(ith) - 0.5*(sig(ik-1)+sig(ik)) ) / dsip(ik) ) )
1331  sumf(ik, 0) = sumf(ik, 0) + zp(isp)
1332  sumfw(ik, 0) = sumfw(ik, 0) + zp(isp) * fact
1333  sumfx(ik, 0) = sumfx(ik, 0) + zp(isp) * ecos(ith)
1334  sumfy(ik, 0) = sumfy(ik, 0) + zp(isp) * esin(ith)
1335  IF ( ip .EQ. 0 ) cycle
1336  sumf(ik,ip) = sumf(ik,ip) + zp(isp)
1337  sumfw(ik,ip) = sumfw(ik,ip) + zp(isp) * fact
1338  sumfx(ik,ip) = sumfx(ik,ip) + zp(isp) * ecos(ith)
1339  sumfy(ik,ip) = sumfy(ik,ip) + zp(isp) * esin(ith)
1340  END DO
1341  END DO
1342  sumf(nk+1,:) = sumf(nk,:) * fachfe
1343  !
1344  DO ip=0, npi
1345  DO ik=1, nk
1346  sume(ip) = sume(ip) + sumf(ik,ip) * dsii(ik)
1347  sumqp(ip) = sumqp(ip) + sumf(ik,ip)**2 * dsii(ik) * sig(ik)
1348  sume1(ip) = sume1(ip) + sumf(ik,ip) * dsii(ik) * sig(ik)
1349  sume2(ip) = sume2(ip) + sumf(ik,ip) * dsii(ik) * sig(ik)**2
1350  sumem1(ip) = sumem1(ip) + sumf(ik,ip) * dsii(ik) / sig(ik)
1351 
1352  sumew(ip) = sumew(ip) + sumfw(ik,ip) * dsii(ik)
1353  sumex(ip) = sumex(ip) + sumfx(ik,ip) * dsii(ik)
1354  sumey(ip) = sumey(ip) + sumfy(ik,ip) * dsii(ik)
1355  IF ( sumf(ik,ip) .GT. efpmax(ip) ) THEN
1356  ifpmax(ip) = ik
1357  efpmax(ip) = sumf(ik,ip)
1358  END IF
1359  END DO
1360 
1361  !SUME (IP) = SUME (IP) + SUMF (NK,IP) * FTE
1362  !SUME1(IP) = SUME1(IP) + SUMF (NK,IP) * FTE
1363  !SUME2(IP) = SUME2(IP) + SUMF (NK,IP) * FTE
1364  !SUMEM1(IP) = SUMEM1(IP) + SUMF (NK,IP) * FTE
1365  !SUMQP(IP) = SUMQP(IP) + SUMF (NK,IP) * FTE
1366  !SUMEW(IP) = SUMEW(IP) + SUMFW(NK,IP) * FTE
1367  !SUMEX(IP) = SUMEX(IP) + SUMFX(NK,IP) * FTE
1368  !SUMEY(IP) = SUMEY(IP) + SUMFY(NK,IP) * FTE
1369  ! Met Office: Proposed bugfix for tail calculations, previously
1370  ! PT1 and PT2 values were found to be too low when using the
1371  ! FTE scaling factor for the tail. I think there are two issues:
1372  ! 1. energy spectrum is scaled in radian frequency space above by DSII.
1373  ! This needs to be consistent and FTE contains a DTH*SIG(NK)
1374  ! factor that is not used in the DSII scaled calcs above
1375  ! 2. the tail fit calcs for period parameters needs to follow
1376  ! the form used in w3iogomd and scaling should be
1377  ! based on the relationship between FTE and FT1, FTTR etc.
1378  ! as per w3iogomd and ww3_grid
1379  fteii = fte / (dth * sig(nk))
1380  sume(ip) = sume(ip) + sumf(nk,ip) * fteii
1381  sume1(ip) = sume1(ip) + sumf(nk,ip) * sig(nk) * fteii * (0.3333 / 0.25)
1382  sume2(ip) = sume2(ip) + sumf(nk,ip) * sig(nk)**2 * fteii * (0.5 / 0.25)
1383  sumem1(ip) = sumem1(ip) + sumf(nk,ip) / sig(nk) * fteii * (0.2 / 0.25)
1384  sumqp(ip) = sumqp(ip) + sumf(nk,ip) * fteii
1385  sumew(ip) = sumew(ip) + sumfw(nk,ip) * fteii
1386  sumex(ip) = sumex(ip) + sumfx(nk,ip) * fteii
1387  sumey(ip) = sumey(ip) + sumfy(nk,ip) * fteii
1388 
1389  END DO
1390  !
1391  ! -------------------------------------------------------------------- /
1392  ! 4. Compute pars
1393  !
1394  npo = -1
1395  !
1396  DO ip=0, npi
1397  !
1398  sumexp = 0.
1399  sumeyp = 0.
1400  !
1401  m0 = sume(ip) * dth * tpiinv
1402  hs = 4. * sqrt( max( m0 , 0. ) )
1403  IF ( hs .LT. hspmin ) THEN
1404  ! For wind cutoff and 2-band partitioning methods, keep the
1405  ! partition, but set the integrated parameters to UNDEF
1406  ! for Hs values less that HSPMIN:
1407  IF( ptmeth .EQ. 4 .OR. ptmeth .EQ. 5 ) THEN
1408  npo = npo + 1
1409  xp(:,npo) = undef
1410  xp(6,npo) = 0.0 ! Set wind sea frac to zero
1411  ENDIF
1412  cycle
1413  ENDIF
1414  !
1415  IF ( npo .GE. dimxp ) GOTO 2000
1416  npo = npo + 1
1417  IF (ip.GT.0)THEN
1418  IF(npo.LT.1)cycle
1419  pmap(npo) = ip
1420  ENDIF
1421  !
1422  m1 = sume1(ip) * dth * tpiinv**2
1423  m2 = sume2(ip) * dth * tpiinv**3
1424  mm1 = sumem1(ip) * dth
1425  qp = sumqp(ip) *(dth * tpiinv)**2
1426  ! M1 = MAX( M1, 1.E-7 )
1427  ! M2 = MAX( M2, 1.E-7 )
1428  !
1429  xl = 1. / xfr - 1.
1430  xh = xfr - 1.
1431  xl2 = xl**2
1432  xh2 = xh**2
1433  el = sumf(ifpmax(ip)-1,ip) - sumf(ifpmax(ip),ip)
1434  eh = sumf(ifpmax(ip)+1,ip) - sumf(ifpmax(ip),ip)
1435  denom = xl*eh - xh*el
1436  sigp = sig(ifpmax(ip))
1437  IF (denom.NE.0.) THEN
1438  sigp = sigp *( 1. + 0.5 * ( xl2*eh - xh2*el ) &
1439  / sign( abs(denom) , denom ) )
1440  END IF
1441  CALL wavnu1 ( sigp, depth, wnp, cgp )
1442  !
1443  !/ --- Parabolic fit around the spectral peak ---
1444  ik = ifpmax(ip)
1445  efpmax(ip) = sumf(ik,ip) * dth
1446  IF (ik.GT.1 .AND. ik.LT.nk) THEN
1447  el = sumf(ik-1,ip) * dth
1448  eh = sumf(ik+1,ip) * dth
1449  numer = 0.125 * ( el - eh )**2
1450  denom = el - 2. * efpmax(ip) + eh
1451  IF (denom.NE.0.) efpmax(ip) = efpmax(ip) &
1452  - numer / sign( abs(denom),denom )
1453  END IF
1454  !
1455  !/ --- Weighted least-squares regression to estimate frequency
1456  !/ spread (FSPRD) to an exponential function:
1457  !/ E(f) = A * exp(-1/2*(f-fp)/B)**2 ,
1458  !/ where B is frequency spread and E(f) is used for
1459  !/ weighting to avoid greater weights to smalll values
1460  !/ in ordinary least-square fit. ---
1461  fsprd = undef
1462  sumy = 0.
1463  sumxy = 0.
1464  sumxxy = 0.
1465  sumylogy = 0.
1466  sumxylogy = 0.
1467  !
1468  DO ik=1, nk
1469  y = sumf(ik,ip)*dth
1470  ! --- sums for weighted least-squares ---
1471  IF (y.GE.1.e-15) THEN
1472  yhat = log(y)
1473  xhat = -0.5 * ( (sig(ik)-sigp)*tpiinv )**2
1474  sumy = sumy + y
1475  sumxy = sumxy + xhat * yhat
1476  sumxxy = sumxxy + xhat * xhat * y
1477  sumylogy = sumylogy + y * yhat
1478  sumxylogy = sumxylogy + sumxy * yhat
1479  END IF
1480  END DO
1481  !
1482  numer = sumy * sumxxy - sumxy**2
1483  denom = sumy * sumxylogy - sumxy * sumylogy
1484  IF (denom.NE.0.) fsprd = sqrt( numer / sign(abs(denom),numer) )
1485  !
1486  sumexp = sumfx(ifpmax(ip),ip) * dsii(ifpmax(ip))
1487  sumeyp = sumfy(ifpmax(ip),ip) * dsii(ifpmax(ip))
1488  !
1489  !/ --- Significant wave height ---
1490  xp(1,npo) = hs
1491  !/ --- Peak wave period ---
1492  xp(2,npo) = tpi / sigp
1493  !/ --- Peak wave length ---
1494  xp(3,npo) = tpi / wnp
1495  !/ --- Mean wave direction ---
1496  xp(4,npo) = mod( 630.-atan2(sumey(ip),sumex(ip))*rade , 360. )
1497  !/ --- Mean directional spread ---
1498  xp(5,npo) = rade * sqrt( max( 0. , 2. * ( 1. - sqrt( &
1499  max(0.,(sumex(ip)**2+sumey(ip)**2)/sume(ip)**2) ) ) ) )
1500  !/ --- Wind sea fraction ---
1501  xp(6,npo) = sumew(ip) / sume(ip)
1502  !/ --- Peak wave direction ---
1503  xp(7,npo) = mod(630.-atan2(sumeyp,sumexp)*rade , 360.)
1504  !/ --- Spectral width (Longuet-Higgins 1975) ---
1505  xp(8,npo) = sqrt( max( 1. , m2*m0 / m1**2 ) - 1. )
1506  !/ --- JONSWAP peak enhancement parameter (E(fp)/EPM(fp))---
1507  ! EPM_FMX = ALPHA_PM_FMX * GRAV**2 * TPI * SIGP**-5 * EXP(-5/4)
1508  alp_pm = 0.3125 * hs**2 * (sigp)**4
1509  epm_fp = alp_pm * tpi * (sigp**(-5)) * 2.865048e-1
1510  xp(9,npo) = max( efpmax(ip) / epm_fp , 1.0 )
1511  !/ --- peakedness parameter (Goda 1970) ---
1512  xp(10,npo) = 2. * qp / m0**2
1513  !/ --- gaussian frequency width ---
1514  xp(11,npo) = fsprd
1515  !/ --- wave energy period (inverse moment) ---
1516  xp(12,npo) = mm1 / m0
1517  !/ --- mean wave period (first moment) ---
1518  xp(13,npo) = m0 / m1
1519  !/ --- zero-upcrossing period (second moment) ---
1520  xp(14,npo) = sqrt( m0 / m2 )
1521  !/ --- peak spectral density (one-dimensional) ---
1522  xp(15,npo) = efpmax(ip)
1523  !
1524  END DO
1525  !
1526  RETURN
1527  !
1528  ! Escape locations read errors --------------------------------------- *
1529  !
1530 2000 CONTINUE
1531  IF ( iaproc .EQ. naperr ) WRITE (ndse,1000) npo+1
1532  RETURN
1533  !
1534  ! Formats
1535  !
1536 1000 FORMAT (/' *** WAVEWATCH III ERROR IN PTMEAN :'/ &
1537  ' XP ARRAY TOO SMALL AT PARTITION',i6/)
1538  !/
1539  !/ End of PTMEAN ----------------------------------------------------- /
1540  !/

References constants::dera, w3gdatmd::dsii, w3gdatmd::dsip, w3gdatmd::dth, w3gdatmd::ecos, w3gdatmd::esin, w3gdatmd::fachfe, w3gdatmd::fte, w3odatmd::iaproc, w3odatmd::naperr, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nk, w3gdatmd::nspec, w3gdatmd::nth, constants::rade, w3gdatmd::sig, w3servmd::strace(), w3gdatmd::th, constants::tpi, constants::tpiinv, constants::undef, w3dispmd::wavnu1(), and w3gdatmd::xfr.

Referenced by w3part().

◆ ptnghb()

subroutine w3partmd::ptnghb

Nearest neighbour calculation.

Computes the nearest neighbors for each grid point. Wrapping of directional distribution (0 to 360) is taken care of using the nearest neighbor system

Parameters
[in]IMIInput discretized spectrum
[out]IMDSorted data
[in]IHMAXNumber of integer levels
Author
Barbara Tracy
Date
20 Oct 2006

Definition at line 632 of file w3partmd.F90.

632  !/
633  !/ +-----------------------------------+
634  !/ | WAVEWATCH III USACE/NOAA |
635  !/ | Barbara Tracy |
636  !/ | H. L. Tolman |
637  !/ | FORTRAN 90 |
638  !/ | Last update : 20-Oct-2006 !
639  !/ +-----------------------------------+
640  !/
641  !/ 20-Oct-2006 : Origination. ( version 3.10 )
642  !/
643  ! 1. Purpose :
644  !
645  ! This subroutine computes the nearest neighbors for each grid
646  ! point. Wrapping of directional distribution (0 to 360)is taken
647  ! care of using the nearest neighbor system
648  !
649  ! 3. Parameters :
650  !
651  ! Parameter list
652  ! ----------------------------------------------------------------
653  ! IMI I.A. I Input discretized spectrum.
654  ! IMD I.A. O Sorted data.
655  ! IHMAX Int. I Number of integer levels.
656  ! ----------------------------------------------------------------
657  !
658  ! 4. Subroutines used :
659  !
660  ! Name Type Module Description
661  ! ----------------------------------------------------------------
662  ! STRACE Sur. W3SERVMD Subroutine tracing.
663  ! ----------------------------------------------------------------
664  !
665  ! 10. Source code :
666  !
667  !/ ------------------------------------------------------------------- /
668  !
669 #ifdef W3_S
670  USE w3servmd, ONLY: strace
671 #endif
672  !
673  USE w3gdatmd, ONLY: nk, nth, nspec
674  !
675  IMPLICIT NONE
676  !/
677  !/ ------------------------------------------------------------------- /
678  !/ Parameter list
679  !/
680  ! INTEGER, INTENT(IN) :: IHMAX, IMI(NSPEC)
681  ! INTEGER, INTENT(IN) :: IMD(NSPEC)
682  !/
683  !/ ------------------------------------------------------------------- /
684  !/ Local parameters
685  !/
686  INTEGER :: N, J, I, K
687 #ifdef W3_S
688  INTEGER, SAVE :: IENT = 0
689  CALL strace (ient, 'PTNGHB')
690 #endif
691  !
692  ! -------------------------------------------------------------------- /
693  ! 1. Check on need of processing
694  !
695  IF ( mk.EQ.nk .AND. mth.EQ.nth ) RETURN
696  !
697  IF ( mk.GT.0 ) DEALLOCATE ( neigh )
698  ALLOCATE ( neigh(9,nspec) )
699  mk = nk
700  mth = nth
701  !
702  ! -------------------------------------------------------------------- /
703  ! 2. Build map
704  !
705  neigh = 0
706  !
707  ! ... Base loop
708  !
709  DO n = 1, nspec
710  !
711  j = (n-1) / nk + 1
712  i = n - (j-1) * nk
713  k = 0
714  !
715  ! ... Point at the left(1)
716  !
717  IF ( i .NE. 1 ) THEN
718  k = k + 1
719  neigh(k, n) = n - 1
720  END IF
721  !
722  ! ... Point at the right (2)
723  !
724  IF ( i .NE. nk ) THEN
725  k = k + 1
726  neigh(k, n) = n + 1
727  END IF
728  !
729  ! ... Point at the bottom(3)
730  !
731  IF ( j .NE. 1 ) THEN
732  k = k + 1
733  neigh(k, n) = n - nk
734  END IF
735  !
736  ! ... ADD Point at bottom_wrap to top
737  !
738  IF ( j .EQ. 1 ) THEN
739  k = k + 1
740  neigh(k,n) = nspec - (nk-i)
741  END IF
742  !
743  ! ... Point at the top(4)
744  !
745  IF ( j .NE. nth ) THEN
746  k = k + 1
747  neigh(k, n) = n + nk
748  END IF
749  !
750  ! ... ADD Point to top_wrap to bottom
751  !
752  IF ( j .EQ. nth ) THEN
753  k = k + 1
754  neigh(k,n) = n - (nth-1) * nk
755  END IF
756  !
757  ! ... Point at the bottom, left(5)
758  !
759  IF ( (i.NE.1) .AND. (j.NE.1) ) THEN
760  k = k + 1
761  neigh(k, n) = n - nk - 1
762  END IF
763  !
764  ! ... Point at the bottom, left with wrap.
765  !
766  IF ( (i.NE.1) .AND. (j.EQ.1) ) THEN
767  k = k + 1
768  neigh(k,n) = n - 1 + nk * (nth-1)
769  END IF
770  !
771  ! ... Point at the bottom, right(6)
772  !
773  IF ( (i.NE.nk) .AND. (j.NE.1) ) THEN
774  k = k + 1
775  neigh(k, n) = n - nk + 1
776  END IF
777  !
778  ! ... Point at the bottom, right with wrap
779  !
780  IF ( (i.NE.nk) .AND. (j.EQ.1) ) THEN
781  k = k + 1
782  neigh(k,n) = n + 1 + nk * (nth - 1)
783  END IF
784  !
785  ! ... Point at the top, left(7)
786  !
787  IF ( (i.NE.1) .AND. (j.NE.nth) ) THEN
788  k = k + 1
789  neigh(k, n) = n + nk - 1
790  END IF
791  !
792  ! ... Point at the top, left with wrap
793  !
794  IF ( (i.NE.1) .AND. (j.EQ.nth) ) THEN
795  k = k + 1
796  neigh(k,n) = n - 1 - (nk) * (nth-1)
797  END IF
798  !
799  ! ... Point at the top, right(8)
800  !
801  IF ( (i.NE.nk) .AND. (j.NE.nth) ) THEN
802  k = k + 1
803  neigh(k, n) = n + nk + 1
804  END IF
805  !
806  ! ... Point at top, right with wrap
807  !
808  !
809  IF ( (i.NE.nk) .AND. (j.EQ.nth) ) THEN
810  k = k + 1
811  neigh(k,n) = n + 1 - (nk) * (nth-1)
812  END IF
813  !
814  neigh(9,n) = k
815  !
816  END DO
817  !
818  RETURN
819  !/
820  !/ End of PTNGHB ----------------------------------------------------- /
821  !/

References w3gdatmd::nk, w3gdatmd::nspec, w3gdatmd::nth, and w3servmd::strace().

Referenced by w3part().

◆ ptsort()

subroutine w3partmd::ptsort ( integer, dimension(nspec), intent(in)  IMI,
integer, dimension(nspec), intent(out)  IND,
integer, intent(in)  IHMAX 
)

Sorts the image data in ascending order.

This sort original to F. T. Tracy (2006)

Parameters
[in]IMIInput discretized spectrum
[out]INDSorted data
[in]IHMAXNumber of integer levels
Author
Barbara Tracy
Date
19 Oct 2006

Definition at line 513 of file w3partmd.F90.

513  !/
514  !/ +-----------------------------------+
515  !/ | WAVEWATCH III USACE/NOAA |
516  !/ | Barbara Tracy |
517  !/ | H. L. Tolman |
518  !/ | FORTRAN 90 |
519  !/ | Last update : 19-Oct-2006 !
520  !/ +-----------------------------------+
521  !/
522  !/ 19-Oct-2006 : Origination. ( version 3.10 )
523  !/
524  ! 1. Purpose :
525  !
526  ! This subroutine sorts the image data in ascending order.
527  ! This sort original to F.T.Tracy (2006)
528  !
529  ! 3. Parameters :
530  !
531  ! Parameter list
532  ! ----------------------------------------------------------------
533  ! IMI I.A. I Input discretized spectrum.
534  ! IND I.A. O Sorted data.
535  ! IHMAX Int. I Number of integer levels.
536  ! ----------------------------------------------------------------
537  !
538  ! 4. Subroutines used :
539  !
540  ! Name Type Module Description
541  ! ----------------------------------------------------------------
542  ! STRACE Sur. W3SERVMD Subroutine tracing.
543  ! ----------------------------------------------------------------
544  !
545  ! 10. Source code :
546  !
547  !/ ------------------------------------------------------------------- /
548  !
549 #ifdef W3_S
550  USE w3servmd, ONLY: strace
551 #endif
552  !
553  USE w3gdatmd, ONLY: nspec
554  !
555  IMPLICIT NONE
556  !/
557  !/ ------------------------------------------------------------------- /
558  !/ Parameter list
559  !/
560  INTEGER, INTENT(IN) :: IHMAX, IMI(NSPEC)
561  INTEGER, INTENT(OUT) :: IND(NSPEC)
562  !/
563  !/ ------------------------------------------------------------------- /
564  !/ Local parameters
565  !/
566  INTEGER :: I, IN, IV
567 #ifdef W3_S
568  INTEGER, SAVE :: IENT = 0
569 #endif
570  INTEGER :: NUMV(IHMAX), IADDR(IHMAX), &
571  IORDER(NSPEC)
572  !/
573 #ifdef W3_S
574  CALL strace (ient, 'PTSORT')
575 #endif
576  !
577  ! -------------------------------------------------------------------- /
578  ! 1. Occurences per height
579  !
580  numv = 0
581  DO i=1, nspec
582  numv(imi(i)) = numv(imi(i)) + 1
583  END DO
584  !
585  ! -------------------------------------------------------------------- /
586  ! 2. Starting address per height
587  !
588  iaddr(1) = 1
589  DO i=1, ihmax-1
590  iaddr(i+1) = iaddr(i) + numv(i)
591  END DO
592  !
593  ! -------------------------------------------------------------------- /
594  ! 3. Order points
595  !
596  DO i=1, nspec
597  iv = imi(i)
598  in = iaddr(iv)
599  iorder(i) = in
600  iaddr(iv) = in + 1
601  END DO
602  !
603  ! -------------------------------------------------------------------- /
604  ! 4. Sort points
605  !
606  DO i=1, nspec
607  ind(iorder(i)) = i
608  END DO
609  !
610  RETURN
611  !/
612  !/ End of PTSORT ----------------------------------------------------- /
613  !/

References w3gdatmd::nspec, and w3servmd::strace().

Referenced by w3part().

◆ w3part()

subroutine w3partmd::w3part ( real, dimension(nk,nth), intent(in)  SPEC,
real, intent(in)  UABS,
real, intent(in)  UDIR,
real, intent(in)  DEPTH,
real, dimension(nk), intent(in)  WN,
integer, intent(out)  NP,
real, dimension(dimp,0:dimxp), intent(out)  XP,
integer, intent(in)  DIMXP 
)

Interface to watershed partitioning routines.

Watershed Algorithm of Vincent and Soille, 1991, implemented by Barbara Tracy (USACE/ERDC) for NOAA/NCEP.

This version of W3PART contains alternate Met Office partitioning methods, selected at runtime using the PTMETH namlist variable:

  1. Standard WW3 partitioning, as per original method described by Barbary Tracy.
  2. Met Office extended partitioning using split-partitions (removes the wind sea part of any swell partiton and combines with total wind sea partition).
  3. Met Office "wave systems" - no classification or combining of wind sea partitions. All partitions output and ordered simply by wave height.
  4. Classic, simple wave age based partitioning generating a single wind sea and swell partition.
  5. 2-band partitioning; produces hi and low freqency band partitions using a user-defined cutoff frequency (PTFCUT).
Remarks
  • DIMXP will always be of size 2 when using PTMETH 4 or 5.
  • To achieve minimum storage but guaranteed storage of all partitions DIMXP = ((NK+1)/2) * ((NTH-1)/2) unless specified otherwise below.
Parameters
[in]SPEC2-D spectrum E(f,theta)
[in]UABSWind speed
[in]UDIRWind direction
[in]DEPTHWater depth
[in]WNWavenumebers for each frequency
[out]NPNumber of partitions found (-1=Spectrum without minumum energy; 0=Spectrum with minumum energy but no partitions)
[out]XPParameters describing partitions. Entry '0' contains entire spectrum
[in]DIMXPSecond dimension of XP
Author
Barbara Tracey, H. L. Tolman, M. Szyszka, Chris Bunney
Date
23 Jul 2018

Definition at line 139 of file w3partmd.F90.

139  !/
140  !/ +-----------------------------------+
141  !/ | WAVEWATCH III USACE/NOAA |
142  !/ | Barbara Tracy |
143  !/ | H. L. Tolman |
144  !/ | FORTRAN 90 |
145  !/ | Last update : 02-Dec-2010 !
146  !/ +-----------------------------------+
147  !/
148  !/ 28-Oct-2006 : Origination. ( version 3.10 )
149  !/ 02-Dec-2010 : Adding a mapping PMAP between ( version 3.14 )
150  !/ original and combined partitions
151  !/ ( M. Szyszka )
152  !/
153  ! 1. Purpose :
154  !
155  ! Interface to watershed partitioning routines.
156  !
157  ! 2. Method :
158  !
159  ! Watershed Algorithm of Vincent and Soille, 1991, implemented by
160  ! Barbara Tracy (USACE/ERDC) for NOAA/NCEP.
161  !
162  ! 3. Parameters :
163  !
164  ! Parameter list
165  ! ----------------------------------------------------------------
166  ! SPEC R.A. I 2-D spectrum E(f,theta).
167  ! UABS Real I Wind speed.
168  ! UDIR Real I Wind direction.
169  ! DEPTH Real I Water depth.
170  ! WN R.A. I Wavenumebers for each frequency.
171  ! NP Int. O Number of partitions.
172  ! -1 : Spectrum without minumum energy.
173  ! 0 : Spectrum with minumum energy.
174  ! but no partitions.
175  ! XP R.A. O Parameters describing partitions.
176  ! Entry '0' contains entire spectrum.
177  ! DIMXP Int. I Second dimension of XP.
178  ! ----------------------------------------------------------------
179  !
180  ! 4. Subroutines used :
181  !
182  ! Name Type Module Description
183  ! ----------------------------------------------------------------
184  ! STRACE Sur. W3SERVMD Subroutine tracing.
185  ! ----------------------------------------------------------------
186  !
187  ! 5. Called by :
188  !
189  ! 6. Error messages :
190  !
191  ! 7. Remarks :
192  !
193  ! - To achieve minimum storage but guaranteed storage of all
194  ! partitions DIMXP = ((NK+1)/2) * ((NTH-1)/2) unless specified
195  ! otherwise below.
196  !
197  ! This version of W3PART contains alternate Met Office partitioning
198  ! methods, selected at runtime using the PTMETH namlist variable:
199  ! 1) Standard WW3 partitioning
200  ! 2) Met Office extended partitioning using split-partitions
201  ! (removes the wind sea part of any swell partiton and combines
202  ! with total wind sea partition).
203  ! 3) Met Office "wave systems" - no classification or combining of
204  ! wind sea partitions. All partitions output and ordered simply
205  ! by wave height.
206  ! 4) Classic, simple wave age based partitioning generating
207  ! a single wind sea and swell partition. [DIMXP = 2]
208  ! 5) 2-band partitioning; produces hi and low freqency band partitions
209  ! using a user-defined cutoff frequency (PTFCUT). [DIMXP = 2]
210  !
211  ! (Chris Bunney, UK Met Office, Jul 2018)
212  !
213  ! 8. Structure :
214  !
215  ! 9. Switches :
216  !
217  ! !/S Enable subroutine tracing.
218  ! !/T Enable test output
219  !
220  ! 10. Source code :
221  !
222  !/ ------------------------------------------------------------------- /
223  !/
224  USE constants
225 #ifdef W3_S
226  USE w3servmd, ONLY: strace
227 #endif
228  !
229  USE w3gdatmd, ONLY: nk, nth, nspec, sig, th
230  USE w3odatmd, ONLY: wscut, flcomb
231  !
232  IMPLICIT NONE
233  !/
234  !/ ------------------------------------------------------------------- /
235  !/ Parameter list
236  !/
237  INTEGER, INTENT(OUT) :: NP
238  INTEGER, INTENT(IN) :: DIMXP
239  REAL, INTENT(IN) :: SPEC(NK,NTH), WN(NK), UABS, &
240  UDIR, DEPTH
241  REAL, INTENT(OUT) :: XP(DIMP,0:DIMXP)
242  !/
243  !/ ------------------------------------------------------------------- /
244  !/ Local parameters
245  !/
246  INTEGER :: ITH, IMI(NSPEC), IMD(NSPEC), &
247  IMO(NSPEC), IND(NSPEC), NP_MAX, &
248  IP, IT(1), INDEX(DIMXP), NWS, &
249  IPW, IPT, ISP
250  INTEGER :: PMAP(DIMXP)
251 #ifdef W3_S
252  INTEGER, SAVE :: IENT = 0
253 #endif
254  REAL :: ZP(NSPEC), ZMIN, ZMAX, Z(NSPEC), &
255  FACT, WSMAX, HSMAX
256  REAL :: TP(DIMP,DIMXP)
257  INTEGER :: IK, WIND_PART ! ChrisB; added for new
258  REAL :: C, UPAR, SIGCUT ! UKMO partioning methods
259  !/
260  !/ ------------------------------------------------------------------- /
261  ! 0. Initializations
262  !
263 #ifdef W3_S
264  CALL strace (ient, 'W3PART')
265 #endif
266  !
267  np = 0
268  xp = 0.
269  !
270  ! -------------------------------------------------------------------- /
271  ! 1. Process input spectrum
272  ! 1.a 2-D to 1-D spectrum
273  !
274  DO ith=1, nth
275  zp(1+(ith-1)*nk:ith*nk) = spec(:,ith)
276  END DO
277 
278  !
279  ! PTMETH == 4 : Do simple partitioning based solely on the
280  ! wave age criterion (produces one swell and one wind sea only):
281  !
282  IF( ptmeth .EQ. 4 ) THEN
283  DO ik=1, nk
284  DO ith=1, nth
285  isp = ik + (ith-1) * nk ! index into partition array IMO
286 
287  upar = wsmult * uabs * max(0.0, cos(th(ith)-dera*udir))
288  c = sig(ik) / wn(ik)
289 
290  IF( upar .LE. c ) THEN
291  ! Is swell:
292  imo(isp) = 2
293  ELSE
294  ! Is wind sea:
295  imo(isp) = 1
296  ENDIF
297  ENDDO
298  ENDDO
299 
300  ! We have a max of up to two partitions:
301  np_max=2
302 
303  ! Calculate mean parameters:
304  CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
305  np, xp, dimxp, pmap )
306 
307  ! No more processing required, return:
308  RETURN
309  ENDIF ! PTMETH == 4
310  !
311  ! PTMETH == 5 : produce "high" and "low" band partitions
312  ! using a frequency cutoff:
313  !
314  IF( ptmeth .EQ. 5 ) THEN
315  sigcut = tpi * ptfcut
316  DO ik = 1, nk
317  ! If bin center <= freq cutoff then mark as "low band".
318  IF(sig(ik) .LE. sigcut) THEN
319  ip = 2
320  ELSE
321  ip = 1
322  ENDIF
323 
324  DO ith=1, nth
325  isp = ik + (ith-1) * nk ! index into partition array IMO
326  imo(isp) = ip
327  ENDDO
328  ENDDO
329 
330  ! We only ever have 2 partitions:
331  np_max=2
332 
333  ! Calculate mean parameters:
334  CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
335  np, xp, dimxp, pmap )
336 
337  ! No more processing required, return:
338  RETURN
339  ENDIF ! PTMETH == 5
340  !
341  ! 1.b Invert spectrum and 'digitize'
342  !
343  zmin = minval( zp )
344  zmax = maxval( zp )
345  IF ( zmax-zmin .LT. 1.e-9 ) RETURN
346  !
347  z = zmax - zp
348  !
349  fact = real(ihmax-1) / ( zmax - zmin )
350  imi = max( 1 , min( ihmax , nint( 1. + z*fact ) ) )
351  !
352  ! 1.c Sort digitized image
353  !
354  CALL ptsort ( imi, ind, ihmax )
355  !
356  ! -------------------------------------------------------------------- /
357  ! 2. Perform partitioning
358  ! 2.a Update nearest neighbor info as needed.
359  !
360  CALL ptnghb
361  !
362  ! 2.b Incremental flooding
363  !
364  CALL pt_fld ( imi, ind, imo, zp, np_max )
365  !
366  ! 2.c Compute parameters per partition
367  ! NP and NX initialized inside routine.
368  !
369  CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
370  np, xp, dimxp, pmap )
371  !
372  ! 2.d PTMETH == 2: move the wind sea part of the partitions into a
373  ! seperate partition and recalculate the mean parameters.
374  !
375  IF ( np .GT. 0 .AND. ptmeth .EQ. 2 ) THEN
376  wind_part = np_max
377 
378  DO ik=1, nk
379  DO ith=1, nth
380  isp = ik + (ith-1) * nk ! index into partition array IMO
381  upar = wsmult * uabs * max(0.0, cos(th(ith)-dera*udir))
382  c = sig(ik) / wn(ik)
383 
384  IF( c .LT. upar ) THEN
385  ! Bin is wind forced - mark as new wind partition:
386  wind_part = np_max + 1
387 
388  ! Update status map to show new wind partition
389  imo(isp) = wind_part
390  ENDIF
391  ENDDO
392  ENDDO
393 
394  IF( wind_part .NE. np_max ) THEN
395  ! Some bins were marked as wind sea - recalculate
396  ! integrated parameters:
397  np_max = wind_part
398  CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
399  np, xp, dimxp, pmap )
400  ENDIF
401  ENDIF
402  !
403  ! -------------------------------------------------------------------- /
404  ! 3. Sort and recombine wind seas as needed
405  ! 3.a Sort by wind sea fraction
406  !
407  IF ( np .LE. 1 ) RETURN
408 
409  ! -----------------------------------------------------------------
410  ! PTMETH == 3: Don't classify or combine any partitions as wind sea.
411  ! Simply sort by HS and return.
412  ! -----------------------------------------------------------------
413  IF( ptmeth .EQ. 3 ) THEN
414  tp(:,1:np) = xp(:,1:np)
415  xp(:,1:np) = 0.
416 
417  DO ip=1, np
418  it = maxloc(tp(1,1:np))
419  xp(:,ip) = tp(:,it(1))
420  tp(1,it(1)) = -1.
421  END DO
422 
423  RETURN ! Don't process any further
424  ENDIF ! PTMETH == 3
425 
426  ! -----------------------------------------------------------------
427  ! PTMETH == 1: Default WW3 partitioning.
428  ! -----------------------------------------------------------------
429  tp(:,1:np) = xp(:,1:np)
430  xp(:,1:np) = 0.
431  index(1:np) = 0
432  nws = 0
433  !
434  DO ip=1, np
435  it = maxloc(tp(6,1:np))
436  index(ip) = it(1)
437  xp(:,ip) = tp(:,index(ip))
438  IF ( tp(6,it(1)) .GE. wscut ) nws = nws + 1
439  tp(6,it(1)) = -1.
440  END DO
441  !
442  ! 3.b Combine wind seas as needed and resort
443  !
444  IF ( nws.GT.1 .AND. flcomb ) THEN
445  ipw = pmap(index(1))
446  DO ip=2, nws
447  ipt = pmap(index(ip))
448  DO isp=1, nspec
449  IF ( imo(isp) .EQ. ipt ) imo(isp) = ipw
450  END DO
451  END DO
452  !
453  CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
454  np, xp, dimxp, pmap )
455  IF ( np .LE. 1 ) RETURN
456  !
457  tp(:,1:np) = xp(:,1:np)
458  xp(:,1:np) = 0.
459  index(1:np) = 0
460  nws = 0
461  !
462  DO ip=1, np
463  it = maxloc(tp(6,1:np))
464  index(ip) = it(1)
465  xp(:,ip) = tp(:,index(ip))
466  IF ( tp(6,it(1)) .GE. wscut ) nws = nws + 1
467  tp(6,it(1)) = -1.
468  END DO
469  !
470  END IF
471  !
472  ! 3.c Sort remaining fields by wave height
473  !
474  nws = min( 1 , nws )
475  !
476  tp(:,1:np) = xp(:,1:np)
477  xp(:,1:np) = 0.
478  !
479  IF ( nws .GT. 0 ) THEN
480  xp(:,1) = tp(:,1)
481  tp(1,1) = -1.
482  nws = 1
483  END IF
484  !
485  DO ip=nws+1, np
486  it = maxloc(tp(1,1:np))
487  xp(:,ip) = tp(:,it(1))
488  tp(1,it(1)) = -1.
489  END DO
490  !
491  ! -------------------------------------------------------------------- /
492  ! 4. End of routine
493  !
494  RETURN
495  !/
496  !/ End of W3PART ----------------------------------------------------- /
497  !/

References constants::dera, w3odatmd::flcomb, w3gdatmd::nk, w3gdatmd::nspec, w3gdatmd::nth, pt_fld(), ptmean(), ptnghb(), ptsort(), w3gdatmd::sig, w3servmd::strace(), w3gdatmd::th, constants::tpi, and w3odatmd::wscut.

Referenced by w3iosfmd::w3cprt(), w3exnc(), and w3expo().

w3gdatmd::dth
real, pointer dth
Definition: w3gdatmd.F90:1232
constants::dera
real, parameter dera
DERA Conversion factor from degrees to radians.
Definition: constants.F90:77
fifo_add
subroutine fifo_add(IV)
Add point to FIFO queue.
Definition: w3partmd.F90:1105
fifo_empty
subroutine fifo_empty(IEMPTY)
Check if queue is empty.
Definition: w3partmd.F90:1124
w3gdatmd::sig
real, dimension(:), pointer sig
Definition: w3gdatmd.F90:1234
w3odatmd::iaproc
integer, pointer iaproc
Definition: w3odatmd.F90:457
w3gdatmd::fachfe
real, pointer fachfe
Definition: w3gdatmd.F90:1232
w3gdatmd::ecos
real, dimension(:), pointer ecos
Definition: w3gdatmd.F90:1234
constants::rade
real, parameter rade
RADE Conversion factor from radians to degrees.
Definition: constants.F90:76
w3gdatmd::dsip
real, dimension(:), pointer dsip
Definition: w3gdatmd.F90:1234
w3gdatmd::th
real, dimension(:), pointer th
Definition: w3gdatmd.F90:1234
w3odatmd::ndse
integer, pointer ndse
Definition: w3odatmd.F90:456
fifo_first
subroutine fifo_first(IV)
Get point out of queue.
Definition: w3partmd.F90:1144
w3gdatmd::esin
real, dimension(:), pointer esin
Definition: w3gdatmd.F90:1234
w3odatmd::naperr
integer, pointer naperr
Definition: w3odatmd.F90:457
w3servmd
Definition: w3servmd.F90:3
w3gdatmd::dsii
real, dimension(:), pointer dsii
Definition: w3gdatmd.F90:1234
w3odatmd::flcomb
logical, pointer flcomb
Definition: w3odatmd.F90:554
constants::tpiinv
real, parameter tpiinv
TPIINV Inverse of 2*Pi.
Definition: constants.F90:74
w3odatmd
Definition: w3odatmd.F90:3
constants::tpi
real, parameter tpi
TPI 2*Pi.
Definition: constants.F90:72
w3servmd::strace
subroutine strace(IENT, SNAME)
Definition: w3servmd.F90:148
w3gdatmd::xfr
real, pointer xfr
Definition: w3gdatmd.F90:1232
w3gdatmd::fte
real, pointer fte
Definition: w3gdatmd.F90:1232
w3odatmd::ndst
integer, pointer ndst
Definition: w3odatmd.F90:456
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
w3gdatmd
Definition: w3gdatmd.F90:16
w3dispmd::wavnu1
subroutine wavnu1(SI, H, K, CG)
Definition: w3dispmd.F90:85
constants::undef
real undef
UNDEF Value for undefined variable in output.
Definition: constants.F90:84
w3dispmd
Definition: w3dispmd.F90:3
w3odatmd::wscut
real, pointer wscut
Definition: w3odatmd.F90:553