76 REAL,
ALLOCATABLE :: COSTH(:), SINTH(:)
78 REAL :: GAMMADOWN = 20
80 TYPE(GRID),
POINTER :: GRD
81 TYPE(SGRD),
POINTER :: SGD
88 PROCEDURE, PASS,
PRIVATE :: COMPUTE_SE => uost_sourceterm_compute_se
90 PROCEDURE, PASS :: COMPUTE => uost_sourceterm_compute
92 PROCEDURE, PASS :: SETGRID => uost_sourceterm_setgrid
93 END TYPE uost_sourceterm
96 CLASS(UOST_SOURCETERM),
ALLOCATABLE :: SRCTRM
98 INTEGER,
PARAMETER :: UNIT_AB = 110
122 SUBROUTINE uost_initgrid(IGRID, FILELOCAL, FILESHADOW, LOCALFACTOR, SHADOWFACTOR)
162 INTEGER,
INTENT(IN) :: igrid
163 CHARACTER(LEN=*),
INTENT(IN) :: filelocal, fileshadow
164 REAL,
INTENT(IN) :: localfactor, shadowfactor
165 TYPE(
grid),
POINTER :: grd
166 TYPE(
sgrd),
POINTER :: sgd
167 REAL :: cgmax, minsize
169 INTEGER,
SAVE :: ient = 0
173 CALL strace (ient,
'UOST_INITGRID')
176 IF ( (igrid .LE. 0) .OR. (.NOT.
ALLOCATED(
grids)) )
THEN
182 grd%UOSTFILELOCAL = filelocal
183 grd%UOSTFILESHADOW = fileshadow
184 grd%UOSTLOCALFACTOR = localfactor
185 grd%UOSTSHADOWFACTOR = shadowfactor
187 ALLOCATE( grd%UOST_LCL_OBSTRUCTED(grd%NX, grd%NY) )
188 grd%UOST_LCL_OBSTRUCTED = .false.
189 ALLOCATE( grd%UOST_SHD_OBSTRUCTED(grd%NX, grd%NY) )
190 grd%UOST_SHD_OBSTRUCTED = .false.
191 ALLOCATE( grd%UOSTCELLSIZE(grd%NX, grd%NY, sgd%NTH) )
193 ALLOCATE( grd%UOSTLOCALALPHA(grd%NX, grd%NY, sgd%NK, sgd%NTH) )
194 grd%UOSTLOCALALPHA = 100
195 ALLOCATE( grd%UOSTLOCALBETA(grd%NX, grd%NY, sgd%NK, sgd%NTH) )
196 grd%UOSTLOCALBETA = 100
197 ALLOCATE( grd%UOSTSHADOWALPHA(grd%NX, grd%NY, sgd%NK, sgd%NTH) )
198 grd%UOSTSHADOWALPHA = 100
199 ALLOCATE( grd%UOSTSHADOWBETA(grd%NX, grd%NY, sgd%NK, sgd%NTH) )
200 grd%UOSTSHADOWBETA = 100
203 IF ( (igrid .GT. 0) .AND. (
ALLOCATED(srctrm)) )
THEN
205 CALL load_alphabeta(grd, sgd, unit_ab)
209 minsize = cgmax*grd%DTMAX/1000
210 WRITE(
ndso,*)
'*** WAVEWATCH-III WARNING IN W3UOST/UOST_INITGRID'
211 WRITE(
ndso,*)
'UOST: grid ',trim(grd%GNAME),
':'
212 WRITE(
ndso,*)
' global time step == ', grd%DTMAX,
' s'
213 WRITE(
ndso,*)
' FOR CELLS SMALLER THAN ABOUT ', minsize, &
214 ' KM UOST MAY UNDERESTIMATE THE DISSIPATION'
264 INTEGER,
INTENT(IN) :: igrid
266 INTEGER,
SAVE :: ient = 0
270 CALL strace (ient,
'UOST_SETGRID')
273 IF ( .NOT.
ALLOCATED(srctrm) )
THEN
277 CALL srctrm%SETGRID(
grids(igrid),
sgrds(igrid))
329 INTEGER,
INTENT(IN) :: ix, iy
330 REAL,
INTENT(IN) :: dt
331 REAL,
INTENT(IN) :: spec(srctrm%sgd%nspec), cg(srctrm%sgd%nk)
332 REAL,
INTENT(IN) :: u10abs, u10dir
333 REAL,
INTENT(OUT) :: s(srctrm%sgd%nspec), d(srctrm%sgd%nspec)
335 INTEGER,
SAVE :: ient = 0
339 CALL strace (ient,
'UOST_SRCTRMCOMPUTE')
342 CALL srctrm%COMPUTE(ix, iy, spec, cg, dt, u10abs, u10dir, s, d)
357 SUBROUTINE load_alphabeta(GRD, SGD, FILEUNIT)
391 TYPE(
grid),
INTENT(INOUT) :: grd
392 TYPE(
sgrd),
INTENT(IN) :: sgd
393 INTEGER,
INTENT(IN) :: fileunit
394 CHARACTER(256) :: filename
395 LOGICAL :: fileexists
396 INTEGER :: jg, j, l, i, ix, iy
398 INTEGER,
SAVE :: ient = 0
402 CALL strace (ient,
'LOAD_ALPHABETA')
407 filename = grd%UOSTFILELOCAL
408 INQUIRE(
file=filename, exist=fileexists)
410 j = len_trim(filename)
411 IF (.NOT. fileexists)
THEN
412 WRITE(
ndse,*)
'*** WAVEWATCH III ERROR IN W3UOST: '// &
413 'FILE '//filename(:j)//
' NOT FOUND. QUITTING'
416 WRITE(
ndso,*)
'FILE '//filename(:j)//
' FOUND.'// &
417 'LOADING UOST SETTINGS FOR GRID '//grd%GNAME
419 CALL load_alphabeta_fromfile(fileunit, filename(:j), grd%NX, grd%NY, sgd%NK, sgd%NTH,&
420 grd%UOSTABMULTFACTOR, grd%UOSTLOCALALPHA, grd%UOSTLOCALBETA,&
421 grd%UOSTCELLSIZE, grd%UOST_LCL_OBSTRUCTED)
425 filename = grd%UOSTFILESHADOW
426 INQUIRE(
file=filename, exist=fileexists)
428 j = len_trim(filename)
429 IF (.NOT. fileexists)
THEN
430 WRITE(
ndse,*)
'*** WAVEWATCH III ERROR IN W3UOST: '// &
431 'FILE '//filename(:j)//
' NOT FOUND. QUITTING'
434 WRITE(
ndso,*)
'FILE '//filename(:j)//
' FOUND.'//&
435 'LOADING UOST SETTINGS FOR GRID '//grd%GNAME
437 CALL load_alphabeta_fromfile(fileunit, filename(:j), grd%NX, grd%NY, sgd%NK, sgd%NTH,&
438 grd%UOSTABMULTFACTOR, grd%UOSTSHADOWALPHA, grd%UOSTSHADOWBETA,&
439 grd%UOSTCELLSIZE, grd%UOST_SHD_OBSTRUCTED)
442 END SUBROUTINE load_alphabeta
466 SUBROUTINE load_alphabeta_fromfile(FILEUNIT, FILENAME, NX, NY, NK, NTH,&
467 MULTFACTOR, ALPHAMTX, BETAMTX, CELLSIZE, ISOBSTRUCTED)
508 CHARACTER(*),
INTENT(IN) :: filename
509 REAL,
INTENT(IN) :: multfactor
510 INTEGER,
INTENT(IN) :: fileunit, nx, ny, nk, nth
511 INTEGER*1,
INTENT(INOUT) :: alphamtx(:,:,:,:), betamtx(:,:,:,:)
512 real*4,
INTENT(INOUT) :: cellsize(:,:,:)
513 LOGICAL,
INTENT(INOUT) :: isobstructed(:,:)
514 CHARACTER(LEN=600) :: line
516 LOGICAL :: header, filestart, readingcellsize, readingalpha
517 INTEGER :: ix, iy, spgrds_size, ik
518 REAL,
ALLOCATABLE :: trans(:)
520 INTEGER,
SAVE :: ient = 0
524 CALL strace (ient,
'LOAD_ALPHABETA_FROMFILE')
530 readingcellsize = .false.
531 readingalpha = .false.
536 OPEN(fileunit,
file=filename, status=
'OLD', action=
'READ')
538 READ(fileunit,
'(A)', iostat=fiostat) line
540 IF (fiostat .NE. 0)
EXIT read_loop
542 IF (line(1:1) .EQ.
'$') cycle
546 READ(line,
'(I5)') spgrds_size
551 isobstructed(ix, iy) = .true.
552 IF ((ix .GT. nx) .OR. (iy .GT. ny))
THEN
553 WRITE(
ndse,*)
'*** WAVEWATCH III ERROR IN W3UOST: '// &
554 'GRID INDICES OUT OF RANGE.'// &
555 'CHECK FILE '//filename
561 readingcellsize = .true.
562 ELSEIF (readingcellsize)
THEN
564 READ(line, *) cellsize(ix, iy, :)
565 readingcellsize = .false.
566 readingalpha = .true.
569 IF (readingalpha)
THEN
571 alphamtx(ix, iy, ik, :) = nint(trans*multfactor)
574 betamtx(ix, iy, ik, :) = nint(trans*multfactor)
578 ELSE IF (readingalpha)
THEN
580 readingalpha = .false.
592 END SUBROUTINE load_alphabeta_fromfile
606 SUBROUTINE uost_sourceterm_setgrid(THIS, GRD, SGD)
640 CLASS(uost_sourceterm),
INTENT(INOUT) :: this
641 TYPE(
grid),
TARGET,
INTENT(IN) :: grd
642 TYPE(
sgrd),
TARGET,
INTENT(IN) :: sgd
645 INTEGER,
SAVE :: ient = 0
649 CALL strace (ient,
'UOST_SOURCETERM_SETGRID')
655 IF (
ALLOCATED(this%COSTH))
THEN
656 DEALLOCATE(this%COSTH)
657 DEALLOCATE(this%SINTH)
661 ALLOCATE(this%COSTH(nth))
662 ALLOCATE(this%SINTH(nth))
664 this%COSTH(ith) = cos(sgd%TH(ith))
665 this%SINTH(ith) = sin(sgd%TH(ith))
667 END SUBROUTINE uost_sourceterm_setgrid
688 SUBROUTINE compute_reduction_psi(U10ABS, U10DIR, CGABS, CGDIR, DT, PSI)
730 REAL,
PARAMETER :: tolerance = 0.000001
731 REAL,
PARAMETER :: whthr1 = .5, whthr2 = 1.5
733 REAL,
INTENT(IN) :: u10abs, u10dir, cgabs, cgdir, dt
734 REAL,
INTENT(OUT) :: psi
735 REAL :: thdelta, cp, wa
737 INTEGER,
SAVE :: ient = 0
741 CALL strace (ient,
'COMPUTE_REDUCTION_PSI')
745 thdelta = abs(u10dir - cgdir)
746 DO WHILE (thdelta .GT.
pi)
747 thdelta = thdelta - 2*
pi
749 thdelta = abs(thdelta)
750 IF (
pi/2 - thdelta .GT. tolerance)
THEN
752 wa = cp/u10abs/cos(thdelta)
757 IF (wa .LE. whthr1)
THEN
761 ELSEIF ((wa .GT. whthr1) .AND. (wa .LT. whthr2))
THEN
764 psi = (wa - whthr1)/(whthr2 - whthr1)
770 END SUBROUTINE compute_reduction_psi
834 CLASS(uost_sourceterm),
INTENT(INOUT) :: THIS
835 INTEGER,
INTENT(IN) :: IX, IY
836 REAL,
INTENT(IN) :: SPEC(THIS%SGD%NSPEC), CG(THIS%SGD%NK)
837 REAL,
INTENT(OUT) :: S(THIS%SGD%NSPEC), D(THIS%SGD%NSPEC)
838 REAL,
INTENT(IN) :: U10ABS, U10DIR
839 REAL,
INTENT(IN) :: DT
841 INTEGER :: IK, ITH, ISP, NK, NTH
842 REAL :: ALPHA, BETA, CGI, CELLSIZE, SPECI, SFC
843 LOGICAL :: CELLOBSTRUCTED
846 INTEGER,
SAVE :: IENT = 0
850 CALL strace (ient,
'UOST_SOURCETERM_COMPUTE_LD')
856 cellobstructed = this%GRD%UOST_LCL_OBSTRUCTED(ix, iy)
857 IF (.NOT. cellobstructed)
RETURN
867 alpha = this%GRD%UOSTLOCALALPHA(ix, iy, ik, ith)/this%GRD%UOSTABMULTFACTOR
868 alpha = max(min(alpha*this%GRD%UOSTLOCALFACTOR, 1.), 0.)
869 beta = this%GRD%UOSTLOCALBETA(ix, iy, ik, ith)/this%GRD%UOSTABMULTFACTOR
870 beta = max(min(beta*this%GRD%UOSTLOCALFACTOR, 1.), 0.)
873 IF (alpha .EQ. 1) cycle
876 cellsize = this%GRD%UOSTCELLSIZE(ix, iy, ith)*this%GRD%UOSTCELLSIZEFACTOR
878 isp = ith + (ik-1)*nth
881 th = this%SGD%TH(ith)
882 CALL compute_reduction_psi(u10abs, u10dir, cg(ik), th, dt, psi)
884 IF (beta > 0.09)
THEN
886 sfc = - cgi/cellsize * (1 - beta)/beta
890 sfc = - cgi/cellsize * this%GAMMAUP
893 s(isp) = sfc * speci * psi
920 SUBROUTINE uost_sourceterm_compute_se(THIS, IX, IY, SPEC, CG, DT, U10ABS, U10DIR, S, D)
961 CLASS(uost_sourceterm),
INTENT(INOUT),
TARGET :: THIS
962 INTEGER,
INTENT(IN) :: IX, IY
963 REAL,
INTENT(IN) :: SPEC(THIS%SGD%NSPEC), CG(THIS%SGD%NK)
964 REAL,
INTENT(OUT) :: S(THIS%SGD%NSPEC), D(THIS%SGD%NSPEC)
965 REAL,
INTENT(IN) :: U10ABS, U10DIR
966 REAL,
INTENT(IN) :: DT
968 INTEGER :: IK, ITH, IS
969 REAL :: CGI, SPECI, SFC, CELLSIZE, &
970 SFCLEFT, SFCRIGHT, SFCCENTER, THDIAG, CGDIAG, &
971 ALPHASH, BETASH, GAMMMA, GG
972 INTEGER :: N = 8, ithdiag, isp, nk, nth, nx, ny
973 LOGICAL :: CELLOBSTRUCTED
976 INTEGER,
SAVE :: IENT = 0
980 CALL strace (ient,
'UOST_SOURCETERM_COMPUTE_SE')
991 IF ((ix .EQ. 1) .OR. (ix .EQ. nx) .OR. (iy .EQ. 1) .OR. (iy .EQ. ny))
RETURN
993 cellobstructed = this%GRD%UOST_SHD_OBSTRUCTED(ix, iy)
994 IF (.NOT. cellobstructed)
RETURN
1000 alphash = this%GRD%UOSTSHADOWALPHA(ix, iy, ik, ith)/this%GRD%UOSTABMULTFACTOR
1001 alphash = max(min(alphash*this%GRD%UOSTSHADOWFACTOR, 1.), 0.)
1002 betash = this%GRD%UOSTSHADOWBETA(ix, iy, ik, ith)/this%GRD%UOSTABMULTFACTOR
1003 betash = max(min(betash*this%GRD%UOSTSHADOWFACTOR, 1.), 0.)
1005 IF (alphash .EQ. 1) cycle
1008 cellsize = this%GRD%UOSTCELLSIZE(ix, iy, ith)*this%GRD%UOSTCELLSIZEFACTOR
1014 IF (alphash > 0.2)
THEN
1016 gammma = (betash/alphash - 1)
1019 gammma = this%GAMMADOWN
1022 th = this%SGD%TH(ith)
1024 CALL compute_reduction_psi(u10abs, u10dir, cg(ik), th, dt, psi)
1028 isp = ith + (ik-1)*nth
1030 s(isp) = sfc * speci * psi
1034 END SUBROUTINE uost_sourceterm_compute_se
1056 SUBROUTINE uost_sourceterm_compute(THIS, IX, IY, SPEC, CG, DT, U10ABS, U10DIR, S, D)
1097 CLASS(uost_sourceterm),
INTENT(INOUT) :: THIS
1098 INTEGER,
INTENT(IN) :: IX, IY
1099 REAL,
INTENT(IN) :: SPEC(THIS%SGD%NSPEC), CG(THIS%SGD%NK)
1100 REAL,
INTENT(IN) :: DT
1101 REAL,
INTENT(IN) :: U10ABS, U10DIR
1102 REAL,
INTENT(OUT) :: S(THIS%SGD%NSPEC), D(THIS%SGD%NSPEC)
1104 REAL :: S_LD(THIS%SGD%NSPEC), S_SE(THIS%SGD%NSPEC)
1105 REAL :: D_LD(THIS%SGD%NSPEC), D_SE(THIS%SGD%NSPEC)
1107 INTEGER,
SAVE :: IENT = 0
1111 CALL strace (ient,
'UOST_SOURCETERM_COMPUTE')
1114 IF (.NOT. this%GRD%UOSTENABLED)
THEN
1123 CALL this%COMPUTE_LD(ix, iy, spec, cg, dt, u10abs, u10dir, s_ld, d_ld)
1125 CALL this%COMPUTE_SE(ix, iy, spec, cg, dt, u10abs, u10dir, s_se, d_se)
1128 END SUBROUTINE uost_sourceterm_compute