88 INTEGER,
PRIVATE :: MK = -1
90 INTEGER,
PRIVATE :: MTH = -1
92 INTEGER,
ALLOCATABLE,
PRIVATE :: NEIGH(:,:)
138 SUBROUTINE w3part ( SPEC, UABS, UDIR, DEPTH, WN, NP, XP, DIMXP )
237 INTEGER,
INTENT(OUT) :: NP
238 INTEGER,
INTENT(IN) :: DIMXP
239 REAL,
INTENT(IN) :: SPEC(NK,NTH), WN(NK), UABS, &
241 REAL,
INTENT(OUT) :: XP(DIMP,0:DIMXP)
246 INTEGER :: ITH, IMI(NSPEC), IMD(NSPEC), &
247 IMO(NSPEC), IND(NSPEC), NP_MAX, &
248 IP, IT(1), INDEX(DIMXP), NWS, &
250 INTEGER :: PMAP(DIMXP)
252 INTEGER,
SAVE :: IENT = 0
254 REAL :: ZP(NSPEC), ZMIN, ZMAX, Z(NSPEC), &
256 REAL :: TP(DIMP,DIMXP)
257 INTEGER :: IK, WIND_PART
258 REAL :: C, UPAR, SIGCUT
264 CALL strace (ient,
'W3PART')
275 zp(1+(ith-1)*nk:ith*nk) = spec(:,ith)
282 IF( ptmeth .EQ. 4 )
THEN
285 isp = ik + (ith-1) * nk
287 upar = wsmult * uabs * max(0.0, cos(
th(ith)-
dera*udir))
290 IF( upar .LE. c )
THEN
304 CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
305 np, xp, dimxp, pmap )
314 IF( ptmeth .EQ. 5 )
THEN
315 sigcut =
tpi * ptfcut
318 IF(
sig(ik) .LE. sigcut)
THEN
325 isp = ik + (ith-1) * nk
334 CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
335 np, xp, dimxp, pmap )
345 IF ( zmax-zmin .LT. 1.e-9 )
RETURN
349 fact = real(ihmax-1) / ( zmax - zmin )
350 imi = max( 1 , min( ihmax , nint( 1. + z*fact ) ) )
354 CALL ptsort ( imi, ind, ihmax )
364 CALL pt_fld ( imi, ind, imo, zp, np_max )
369 CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
370 np, xp, dimxp, pmap )
375 IF ( np .GT. 0 .AND. ptmeth .EQ. 2 )
THEN
380 isp = ik + (ith-1) * nk
381 upar = wsmult * uabs * max(0.0, cos(
th(ith)-
dera*udir))
384 IF( c .LT. upar )
THEN
386 wind_part = np_max + 1
394 IF( wind_part .NE. np_max )
THEN
398 CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
399 np, xp, dimxp, pmap )
407 IF ( np .LE. 1 )
RETURN
413 IF( ptmeth .EQ. 3 )
THEN
414 tp(:,1:np) = xp(:,1:np)
418 it = maxloc(tp(1,1:np))
419 xp(:,ip) = tp(:,it(1))
429 tp(:,1:np) = xp(:,1:np)
435 it = maxloc(tp(6,1:np))
437 xp(:,ip) = tp(:,index(ip))
438 IF ( tp(6,it(1)) .GE.
wscut ) nws = nws + 1
444 IF ( nws.GT.1 .AND.
flcomb )
THEN
447 ipt = pmap(index(ip))
449 IF ( imo(isp) .EQ. ipt ) imo(isp) = ipw
453 CALL ptmean ( np_max, imo, zp, depth, uabs, udir, wn, &
454 np, xp, dimxp, pmap )
455 IF ( np .LE. 1 )
RETURN
457 tp(:,1:np) = xp(:,1:np)
463 it = maxloc(tp(6,1:np))
465 xp(:,ip) = tp(:,index(ip))
466 IF ( tp(6,it(1)) .GE.
wscut ) nws = nws + 1
476 tp(:,1:np) = xp(:,1:np)
479 IF ( nws .GT. 0 )
THEN
486 it = maxloc(tp(1,1:np))
487 xp(:,ip) = tp(:,it(1))
512 SUBROUTINE ptsort ( IMI, IND, IHMAX )
560 INTEGER,
INTENT(IN) :: IHMAX, IMI(NSPEC)
561 INTEGER,
INTENT(OUT) :: IND(NSPEC)
568 INTEGER,
SAVE :: IENT = 0
570 INTEGER :: NUMV(IHMAX), IADDR(IHMAX), &
574 CALL strace (ient,
'PTSORT')
582 numv(imi(i)) = numv(imi(i)) + 1
590 iaddr(i+1) = iaddr(i) + numv(i)
686 INTEGER :: N, J, I, K
688 INTEGER,
SAVE :: IENT = 0
689 CALL strace (ient,
'PTNGHB')
695 IF ( mk.EQ.
nk .AND. mth.EQ.
nth )
RETURN
697 IF ( mk.GT.0 )
DEALLOCATE ( neigh )
698 ALLOCATE ( neigh(9,
nspec) )
724 IF ( i .NE.
nk )
THEN
745 IF ( j .NE.
nth )
THEN
752 IF ( j .EQ.
nth )
THEN
754 neigh(k,n) = n - (
nth-1) *
nk
759 IF ( (i.NE.1) .AND. (j.NE.1) )
THEN
761 neigh(k, n) = n -
nk - 1
766 IF ( (i.NE.1) .AND. (j.EQ.1) )
THEN
768 neigh(k,n) = n - 1 +
nk * (
nth-1)
773 IF ( (i.NE.
nk) .AND. (j.NE.1) )
THEN
775 neigh(k, n) = n -
nk + 1
780 IF ( (i.NE.
nk) .AND. (j.EQ.1) )
THEN
782 neigh(k,n) = n + 1 +
nk * (
nth - 1)
787 IF ( (i.NE.1) .AND. (j.NE.
nth) )
THEN
789 neigh(k, n) = n +
nk - 1
794 IF ( (i.NE.1) .AND. (j.EQ.
nth) )
THEN
796 neigh(k,n) = n - 1 - (
nk) * (
nth-1)
801 IF ( (i.NE.
nk) .AND. (j.NE.
nth) )
THEN
803 neigh(k, n) = n +
nk + 1
809 IF ( (i.NE.
nk) .AND. (j.EQ.
nth) )
THEN
811 neigh(k,n) = n + 1 - (
nk) * (
nth-1)
840 SUBROUTINE pt_fld ( IMI, IND, IMO, ZP, NPART )
889 INTEGER,
INTENT(IN) :: IMI(NSPEC), IND(NSPEC)
890 INTEGER,
INTENT(OUT) :: IMO(NSPEC), NPART
891 REAL,
INTENT(IN) :: ZP(NSPEC)
896 INTEGER :: MASK, INIT, IWSHED, IMD(NSPEC), &
897 IC_LABEL, IFICT_PIXEL, M, IH, MSAVE, &
898 IP, I, IPP, IC_DIST, IEMPTY, IPPP, &
900 INTEGER :: IQ(NSPEC), IQ_START, IQ_END
902 INTEGER,
SAVE :: IENT = 0
904 REAL :: ZPMAX, EP1, DIFF
907 CALL strace (ient,
'PT_FLD')
938 IF ( imi(ip) .NE. ih )
EXIT
949 IF ( (imo(ipp).GT.0) .OR. (imo(ipp).EQ.iwshed) )
THEN
956 IF ( m+1 .GT. nspec )
THEN
974 IF ( ip .EQ. ifict_pixel )
THEN
976 IF ( iempty .EQ. 1 )
THEN
980 ic_dist = ic_dist + 1
992 IF ( (imd(ipp).LT.ic_dist) .AND. ( (imo(ipp).GT.0) .OR. &
993 (imo(ipp).EQ.iwshed)))
THEN
995 IF ( imo(ipp) .GT. 0 )
THEN
997 IF ((imo(ip) .EQ. mask) .OR. (imo(ip) .EQ. &
1000 ELSE IF (imo(ip) .NE. imo(ipp))
THEN
1004 ELSE IF (imo(ip) .EQ. mask)
THEN
1010 ELSE IF ( (imo(ipp).EQ.mask) .AND. (imd(ipp).EQ.0) )
THEN
1012 imd(ipp) = ic_dist + 1
1027 IF ( imi(ip) .NE. ih )
EXIT
1030 IF (imo(ip) .EQ. mask)
THEN
1034 ic_label = ic_label + 1
1042 IF ( iempty .EQ. 1 )
EXIT
1045 DO i=1, neigh(9,ipp)
1047 IF ( imo(ippp) .EQ. mask )
THEN
1049 imo(ippp) = ic_label
1057 IF ( m + 1 .GT. nspec )
THEN
1076 IF ( imo(jl) .EQ. 0 )
THEN
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
1085 IF ( ipt .GT. 0 ) imd(jl) = imo(neigh(ipt,jl))
1089 IF ( minval(imo) .GT. 0 )
EXIT
1106 INTEGER,
INTENT(IN) :: IV
1111 IF ( iq_end .GT. nspec ) iq_end = 1
1125 INTEGER,
INTENT(OUT) :: IEMPTY
1127 IF ( iq_start .NE. iq_end )
THEN
1145 INTEGER,
INTENT(OUT) :: IV
1149 iq_start = iq_start + 1
1150 IF ( iq_start .GT. nspec ) iq_start = 1
1176 SUBROUTINE ptmean ( NPI, IMO, ZP, DEPTH, UABS, UDIR, WN, &
1177 NPO, XP, DIMXP, PMAP )
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)
1250 INTEGER :: IK, ITH, ISP, IP, IFPMAX(0:NPI)
1252 INTEGER,
SAVE :: IENT = 0
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
1268 CALL strace (ient,
'PTMEAN')
1277 IF ( npi .EQ. 0 )
RETURN
1300 c(ik) =
sig(ik) / wn(ik)
1304 upar = wsmult * uabs * max(0.,cos(
th(ith)-
dera*udir))
1305 IF ( upar .LT. c(nk) )
THEN
1306 fcdir(ith) =
sig(nk+1)
1309 IF ( upar .LT. c(ik) )
EXIT
1311 rd = (c(ik)-upar) / (c(ik)-c(ik+1))
1312 IF ( rd .LT. 0 )
THEN
1314 rd = max( 0., rd+1. )
1316 fcdir(ith) = rd*
sig(ik+1) + (1.-rd)*
sig(ik)
1327 isp = ik + (ith-1)*nk
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)
1342 sumf(nk+1,:) = sumf(nk,:) *
fachfe
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)
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
1357 efpmax(ip) = sumf(ik,ip)
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
1402 hs = 4. * sqrt( max( m0 , 0. ) )
1403 IF ( hs .LT. hspmin )
THEN
1407 IF( ptmeth .EQ. 4 .OR. ptmeth .EQ. 5 )
THEN
1415 IF ( npo .GE. dimxp )
GOTO 2000
1424 mm1 = sumem1(ip) *
dth
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 ) )
1441 CALL wavnu1 ( sigp, depth, wnp, cgp )
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 )
1471 IF (y.GE.1.e-15)
THEN
1473 xhat = -0.5 * ( (
sig(ik)-sigp)*
tpiinv )**2
1475 sumxy = sumxy + xhat * yhat
1476 sumxxy = sumxxy + xhat * xhat * y
1477 sumylogy = sumylogy + y * yhat
1478 sumxylogy = sumxylogy + sumxy * yhat
1482 numer = sumy * sumxxy - sumxy**2
1483 denom = sumy * sumxylogy - sumxy * sumylogy
1484 IF (denom.NE.0.) fsprd = sqrt( numer / sign(abs(denom),numer) )
1486 sumexp = sumfx(ifpmax(ip),ip) *
dsii(ifpmax(ip))
1487 sumeyp = sumfy(ifpmax(ip),ip) *
dsii(ifpmax(ip))
1492 xp(2,npo) =
tpi / sigp
1494 xp(3,npo) =
tpi / wnp
1496 xp(4,npo) = mod( 630.-atan2(sumey(ip),sumex(ip))*
rade , 360. )
1498 xp(5,npo) =
rade * sqrt( max( 0. , 2. * ( 1. - sqrt( &
1499 max(0.,(sumex(ip)**2+sumey(ip)**2)/sume(ip)**2) ) ) ) )
1501 xp(6,npo) = sumew(ip) / sume(ip)
1503 xp(7,npo) = mod(630.-atan2(sumeyp,sumexp)*
rade , 360.)
1505 xp(8,npo) = sqrt( max( 1. , m2*m0 / m1**2 ) - 1. )
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 )
1512 xp(10,npo) = 2. * qp / m0**2
1516 xp(12,npo) = mm1 / m0
1518 xp(13,npo) = m0 / m1
1520 xp(14,npo) = sqrt( m0 / m2 )
1522 xp(15,npo) = efpmax(ip)
1536 1000
FORMAT (/
' *** WAVEWATCH III ERROR IN PTMEAN :'/ &
1537 ' XP ARRAY TOO SMALL AT PARTITION',i6/)