WAVEWATCH III  beta 0.0.1
w3dispmd.F90
Go to the documentation of this file.
1 #include "w3macros.h"
2 !/ ------------------------------------------------------------------- /
3 MODULE w3dispmd
4  !/
5  !/ +-----------------------------------+
6  !/ | WAVEWATCH III NOAA/NCEP |
7  !/ | H. L. Tolman |
8  !/ | FORTRAN 90 |
9  !/ | Last update : 29-May-2009 |
10  !/ +-----------------------------------+
11  !/
12  !/ 30-Nov-1999 : Fortran 90 version. ( version 2.00 )
13  !/ 29-May-2009 : Preparing distribution version. ( version 3.14 )
14  !/ 10-Mar-2016 : Added Liu & Mollo-Christensen
15  !/ dispersion with ice (E. Rogers) ( version 5.10 )
16  !/
17  !/ Copyright 2009 National Weather Service (NWS),
18  !/ National Oceanic and Atmospheric Administration. All rights
19  !/ reserved. WAVEWATCH III is a trademark of the NWS.
20  !/ No unauthorized use without permission.
21  !/
22  ! 1. Purpose :
23  !
24  ! A set of routines for solving the dispersion relation.
25  !
26  ! 2. Variables and types :
27  !
28  ! All variables are retated to the interpolation tables. See
29  ! DISTAB for a more comprehensive description.
30  !
31  ! Name Type Scope Description
32  ! ----------------------------------------------------------------
33  ! NAR1D I.P. Public Nmmer of elements in interpolation
34  ! array.
35  ! DFAC R.P. Public Value of KH at deep boundary.
36  ! EWN1 R.A. Public Wavenumber array.
37  ! ECG1 R.A. Public Group velocity array.
38  ! N1MAX Int. Public Actual maximum position in array.
39  ! DSIE Real Public SI step.
40  ! ----------------------------------------------------------------
41  !
42  ! 3. Subroutines and functions :
43  !
44  ! Name Type Scope Description
45  ! ----------------------------------------------------------------
46  ! WAVNU1 Subr. Public Solve dispersion using lookup table.
47  ! WAVNU2 Subr. Public Solve dispersion relation itteratively.
48  ! DISTAB Subr. Public Fill interpolation tables.
49  ! LIU_FORWARD_DISPERSION Subr. Public Dispersion with ice
50  ! LIU_REVERSE_DISPERSION Subr. Public Dispersion with ice
51  ! ----------------------------------------------------------------
52  !
53  ! 4. Subroutines and functions used :
54  !
55  ! Name Type Module Description
56  ! ----------------------------------------------------------------
57  ! STRACE Subr. W3SERVMD Subroutine tracing ( !/S )
58  ! ----------------------------------------------------------------
59  !
60  ! 5. Remarks :
61  !
62  ! 6. Switches :
63  !
64  ! !/S Enable subroutine tracing.
65  !
66  ! 7. Source code :
67  !
68  !/ ------------------------------------------------------------------- /
69  !/
70  PUBLIC
71  !/
72  !/ Set up of public interpolation table ------------------------------ /
73  !/
74  INTEGER, PARAMETER :: nar1d = 121
75  REAL, PARAMETER :: dfac = 6.
76  !/
77  INTEGER :: n1max
78  REAL :: ecg1(0:nar1d), ewn1(0:nar1d), dsie
79  !/
80  !/ Set up of public subroutines -------------------------------------- /
81  !/
82 CONTAINS
83  !/ ------------------------------------------------------------------- /
84  SUBROUTINE wavnu1 (SI,H,K,CG)
85  !/
86  !/ +-----------------------------------+
87  !/ | WAVEWATCH III NOAA/NCEP |
88  !/ | H. L. Tolman |
89  !/ | FORTRAN 90 |
90  !/ | Last update : 30-Nov-1999 |
91  !/ +-----------------------------------+
92  !/
93  !/ 04-Nov-1990 : Final FORTRAN 77 ( version 1.18 )
94  !/ 30-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
95  !/
96  ! 1. Purpose :
97  !
98  ! Calculate wavenumber and group velocity from the interpolation
99  ! array filled by DISTAB from a given intrinsic frequency and the
100  ! waterdepth.
101  !
102  ! 2. Method :
103  !
104  ! Linear interpolation from one-dimensional array.
105  !
106  ! 3. Parameters used :
107  !
108  ! Parameter list
109  ! ----------------------------------------------------------------
110  ! SI Real I Intrinsic frequency (moving frame) (rad/s)
111  ! H Real I Waterdepth (m)
112  ! K Real O Wavenumber (rad/m)
113  ! CG Real O Group velocity (m/s)
114  ! ----------------------------------------------------------------
115  !
116  ! 4. Error messages :
117  !
118  ! - None.
119  !
120  ! 5. Called by :
121  !
122  ! - Any main program
123  !
124  ! 6. Subroutines used :
125  !
126  ! - None
127  !
128  ! 7. Remarks :
129  !
130  ! - Calculated si* is always made positive without checks : check in
131  ! main program assumed !
132  ! - Depth is unlimited.
133  !
134  ! 8. Structure :
135  !
136  ! +---------------------------------------------+
137  ! | calculate non-dimensional frequency |
138  ! |---------------------------------------------|
139  ! | T si* in range ? F |
140  ! |----------------------|----------------------|
141  ! | calculate k* and cg* | deep water approx. |
142  ! | calculate output | |
143  ! | parameters | |
144  ! +---------------------------------------------+
145  !
146  ! 9. Switches :
147  !
148  ! !/S Enable subroutine tracing.
149  !
150  ! 10. Source code :
151  !
152  !/ ------------------------------------------------------------------- /
153  !/
154  USE constants, ONLY : grav
155 #ifdef W3_S
156  USE w3servmd, ONLY: strace
157 #endif
158  !
159  IMPLICIT NONE
160  !/
161  !/ ------------------------------------------------------------------- /
162  !/ Parameter list
163  !/
164  REAL, INTENT(IN) :: SI, H
165  REAL, INTENT(OUT) :: K, CG
166  !/
167  !/ ------------------------------------------------------------------- /
168  !/ Local parameters
169  !/
170  INTEGER :: I1, I2
171 #ifdef W3_S
172  INTEGER, SAVE :: IENT = 0
173 #endif
174  REAL :: SQRTH, SIX, R1, R2
175  !/
176  !/ ------------------------------------------------------------------- /
177  !/
178 #ifdef W3_S
179  CALL strace (ient, 'WAVNU1')
180 #endif
181  !
182  sqrth = sqrt(h)
183  six = si * sqrth
184  i1 = int(six/dsie)
185  !
186  IF (i1.LE.n1max.AND.i1.GE.1) THEN
187  i2 = i1 + 1
188  r1 = six/dsie - real(i1)
189  r2 = 1. - r1
190  k = ( r2*ewn1(i1) + r1*ewn1(i2) ) / h
191  cg = ( r2*ecg1(i1) + r1*ecg1(i2) ) * sqrth
192  ELSE
193  k = si*si/grav
194  cg = 0.5 * grav / si
195  END IF
196  !
197  RETURN
198  !/
199  !/ End of WAVNU1 ----------------------------------------------------- /
200  !/
201  END SUBROUTINE wavnu1
202  !/ ------------------------------------------------------------------- /
203  SUBROUTINE wavnu2 (W,H,K,CG,EPS,NMAX,ICON)
204  !/
205  !/ +-----------------------------------+
206  !/ | WAVEWATCH III NOAA/NCEP |
207  !/ | H. L. Tolman |
208  !/ | FORTRAN 90 |
209  !/ | Last update : 30-Nov-1999 |
210  !/ +-----------------------------------+
211  !/
212  !/ 17-Jul-1990 : Final FORTRAN 77 ( version 1.18 )
213  !/ 30-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
214  !/
215  ! 1. Purpose :
216  !
217  ! Calculation of wavenumber K from a given angular
218  ! frequency W and waterdepth H.
219  !
220  ! 2. Method :
221  !
222  ! Used equation :
223  ! 2
224  ! W = G*K*TANH(K*H)
225  !
226  ! Because of the nature of the equation, K is calculated
227  ! with an itterative procedure.
228  !
229  ! 3. Parameters :
230  !
231  ! Parameter list
232  ! ----------------------------------------------------------------
233  ! W Real I Angular frequency
234  ! H Real I Waterdepth
235  ! K Real O Wavenumber ( same sign as W )
236  ! CG Real O Group velocity (same sign as W)
237  ! EPS Real I Wanted max. difference between K and Kold
238  ! NMAX Int. I Max number of repetitions in calculation
239  ! ICON Int. O Contol counter ( See error messages )
240  ! ----------------------------------------------------------------
241  !
242  ! 9. Switches :
243  !
244  ! !/S Enable subroutine tracing.
245  !
246  ! 10. Source code :
247  !
248  !/ ------------------------------------------------------------------- /
249  !/
250  USE constants, ONLY : grav
251 #ifdef W3_S
252  USE w3servmd, ONLY: strace
253 #endif
254  !
255  IMPLICIT NONE
256  !/
257  !/ ------------------------------------------------------------------- /
258  !/ Parameter list
259  !/
260  INTEGER, INTENT(IN) :: NMAX
261  INTEGER, INTENT(OUT) :: ICON
262  REAL, INTENT(IN) :: W, H, EPS
263  REAL, INTENT(OUT) :: CG, K
264  !/
265  !/ ------------------------------------------------------------------- /
266  !/ Local parameters
267  !/
268  INTEGER :: I
269 #ifdef W3_S
270  INTEGER, SAVE :: IENT = 0
271 #endif
272  REAL :: F, W0, FD, DIF, RDIF, KOLD
273  !REAL :: KTEST1, CGTEST1, KTEST2, CGTEST2
274  !/
275  !/ ------------------------------------------------------------------- /
276  !/
277 #ifdef W3_S
278  CALL strace (ient, 'WAVNU2')
279 #endif
280  !
281  ! Initialisations :
282  !
283  !CALL WAVNU1(ABS(W),H,KTEST1,CGTEST1)
284  !CALL WAVNU3(ABS(W),H,KTEST2,CGTEST2)
285 
286  cg = 0
287  kold = 0
288  icon = 0
289  w0 = abs(w)
290 
291  !
292  ! 1st approach :
293  !
294  IF (w0.LT.sqrt(grav/h)) THEN
295  k = w0/sqrt(grav*h)
296  ELSE
297  k = w0*w0/grav
298  END IF
299  !
300  ! Refinement :
301  !
302  DO i=1, nmax
303  dif = abs(k-kold)
304  IF (k.NE.0) THEN
305  rdif = dif/k
306  ELSE
307  rdif = 0
308  END IF
309  IF (dif .LT. eps .AND. rdif .LT. eps) THEN
310  icon = 1
311  GOTO 100
312  ELSE
313  kold = k
314  f = grav*kold*tanh(kold*h)-w0**2
315  IF (kold*h.GT.25) THEN
316  fd = grav*tanh(kold*h)
317  ELSE
318  fd = grav*tanh(kold*h) + grav*kold*h/((cosh(kold*h))**2)
319  END IF
320  k = kold - f/fd
321  END IF
322  END DO
323  !
324  dif = abs(k-kold)
325  rdif = dif/k
326  IF (dif .LT. eps .AND. rdif .LT. eps) icon = 1
327 100 CONTINUE
328  IF (2*k*h.GT.25) THEN
329  cg = w0/k * 0.5
330  ELSE
331  cg = w0/k * 0.5*(1+(2*k*h/sinh(2*k*h)))
332  END IF
333  IF (w.LT.0.0) THEN
334  k = (-1)*k
335  cg = cg*(-1)
336  END IF
337 
338  !WRITE(*,'(20F20.10)') W, H, (K-KTEST2)/K*100., (CG-CGTEST2)/CG*100.
339  !
340  RETURN
341  !/
342  !/ End of WAVNU2 ----------------------------------------------------- /
343  !/
344  END SUBROUTINE wavnu2
345  !/
346  PURE SUBROUTINE wavnu3 (SI,H,K,CG)
347  !/
348  !/ +-----------------------------------+
349  !/ | WAVEWATCH III NOAA/NCEP |
350  !/ | Aron Roland |
351  !/ | FORTRAN 90 |
352  !/ | Last update : 20-05-17 |
353  !/ +-----------------------------------+
354  !/
355  !/ 20.05.17 : Initial Version, Aron Roland based on WAVNU1
356  !/
357  ! 1. Purpose :
358  !
359  ! Calculate wavenumber and group velocity from the improved
360  ! Eckard's formula by Beji (2003)
361  !
362  ! 2. Method :
363  !
364  ! Direct computation by approximation
365  !
366  ! 3. Parameters used :
367  !
368  ! Parameter list
369  ! ----------------------------------------------------------------
370  ! SI Real I Intrinsic frequency (moving frame) (rad/s)
371  ! H Real I Waterdepth (m)
372  ! K Real O Wavenumber (rad/m)
373  ! CG Real O Group velocity (m/s)
374  ! ----------------------------------------------------------------
375  !
376  ! 4. Error messages :
377  !
378  ! - None.
379  !
380  ! 5. Called by :
381  !
382  ! - Any main program
383  !
384  ! 6. Subroutines used :
385  !
386  ! - None
387  !
388  ! 7. Remarks :
389  !
390  ! - Calculated si* is always made positive without checks : check in
391  ! main program assumed !
392  ! - Depth is unlimited.
393  !
394  ! 8. Structure :
395  !
396  ! +---------------------------------------------+
397  ! | calculate non-dimensional frequency |
398  ! |---------------------------------------------|
399  ! | T si* in range ? F |
400  ! |----------------------|----------------------|
401  ! | calculate k* and cg* | deep water approx. |
402  ! | calculate output | |
403  ! | parameters | |
404  ! +---------------------------------------------+
405  !
406  ! 9. Switches :
407  !
408  ! !/S Enable subroutine tracing.
409  !
410  ! 10. Source code :
411  !
412  !/ ------------------------------------------------------------------- /
413  !/
414  USE constants, ONLY : grav, pi
415  !!/S USE W3SERVMD, ONLY: STRACE
416  !
417  IMPLICIT NONE
418  !/
419  !/ ------------------------------------------------------------------- /
420  !/ Parameter list
421  !/
422  REAL, INTENT(IN) :: si, h
423  REAL, INTENT(OUT) :: k, cg
424  !/
425  !/ ------------------------------------------------------------------- /
426  !/ Local parameters
427  !/
428  INTEGER :: i1, i2
429  !!/S INTEGER, SAVE :: IENT = 0
430  REAL :: kh0, kh, tmp, tp, cp, l
431  REAL, PARAMETER :: beta1 = 1.55
432  REAL, PARAMETER :: beta2 = 1.3
433  REAL, PARAMETER :: beta3 = 0.216
434  REAL, PARAMETER :: zpi = 2 * pi
435  REAL, PARAMETER :: kdmax = 20.
436  !/
437  !/ ------------------------------------------------------------------- /
438  !/
439  ! IENT does not work with PURE subroutines
440  !!/S CALL STRACE (IENT, 'WAVNU1')
441  !
442  tp = si/zpi
443  kh0 = zpi*zpi*h/grav*tp*tp
444  tmp = 1.55 + 1.3*kh0 + 0.216*kh0*kh0
445  kh = kh0 * (1 + kh0**1.09 * 1./exp(min(kdmax,tmp))) / sqrt(tanh(min(kdmax,kh0)))
446  k = kh/h
447  cg = 0.5*(1+(2*kh/sinh(min(kdmax,2*kh))))*si/k
448  !
449  RETURN
450  !/
451  !/ End of WAVNU3 ----------------------------------------------------- /
452  !/
453  END SUBROUTINE wavnu3
454 
455  PURE SUBROUTINE wavnu_local (SIG,DW,WNL,CGL)
456  !/
457  !/ +-----------------------------------+
458  !/ | WAVEWATCH III NOAA/NCEP |
459  !/ | Aron Roland |
460  !/ | FORTRAN 90 |
461  !/ | Last update : 20-05-17 |
462  !/ +-----------------------------------+
463  !/
464  !/ 20.05.17 : Initial Version, Aron Roland based on WAVNU1
465  !/
466  ! 1. Purpose :
467  !
468  ! Calculate wavenumber and group velocity from the improved
469  ! Eckard's formula by Beji (2003)
470  !
471  ! 2. Method :
472  !
473  ! Linear interpolation from one-dimensional array.
474  !
475  ! 3. Parameters used :
476  !
477  ! Parameter list
478  ! ----------------------------------------------------------------
479  ! SI Real I Intrinsic frequency (moving frame) (rad/s)
480  ! H Real I Waterdepth (m)
481  ! K Real O Wavenumber (rad/m)
482  ! CG Real O Group velocity (m/s)
483  ! ----------------------------------------------------------------
484  !
485  ! 4. Error messages :
486  !
487  ! - None.
488  !
489  ! 5. Called by :
490  !
491  ! - Any main program
492  !
493  ! 6. Subroutines used :
494  !
495  ! - None
496  !
497  ! 7. Remarks :
498  !
499  ! - Calculated si* is always made positive without checks : check in
500  ! main program assumed !
501  ! - Depth is unlimited.
502  !
503  ! 8. Structure :
504  !
505  ! +---------------------------------------------+
506  ! | calculate non-dimensional frequency |
507  ! |---------------------------------------------|
508  ! | T si* in range ? F |
509  ! |----------------------|----------------------|
510  ! | calculate k* and cg* | deep water approx. |
511  ! | calculate output | |
512  ! | parameters | |
513  ! +---------------------------------------------+
514  !
515  ! 9. Switches :
516  !
517  ! !/S Enable subroutine tracing.
518  !
519  ! 10. Source code :
520 
521  USE w3gdatmd, ONLY: dmin
522  !
523  !/ ------------------------------------------------------------------- /
524  !/
525  IMPLICIT NONE
526 
527  !/
528  !/ ------------------------------------------------------------------- /
529  !/ Parameter list
530  !/
531  REAL, INTENT(IN) :: sig, dw
532  REAL, INTENT(OUT) :: wnl, cgl
533  !/
534  !/ ------------------------------------------------------------------- /
535  !/ Local parameters
536  REAL :: depth
537  !
538  !/
539  !/ End of WAVNU_LOCAL------------------------------------------------- /
540  !/
541 
542  depth = max( dmin , dw)
543  !
544  CALL wavnu3(sig,depth,wnl,cgl)
545 
546  END SUBROUTINE wavnu_local
547  !/
548  !/ ------------------------------------------------------------------- /
549 
550  !/ ------------------------------------------------------------------- /
551  SUBROUTINE distab
552  !/
553  !/ +-----------------------------------+
554  !/ | WAVEWATCH III NOAA/NCEP |
555  !/ | H. L. Tolman |
556  !/ | FORTRAN 90 |
557  !/ | Last update : 30-Nov-1990 |
558  !/ +-----------------------------------+
559  !/
560  !/ 04-Nov-1990 : Final FORTRAN 77 ( version 1.18 )
561  !/ 30-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
562  !/
563  ! 1. Purpose :
564  !
565  ! Fill interpolation arrays for the calculation of wave parameters
566  ! according to the linear (Airy) wave theory given the intrinsic
567  ! frequency.
568  !
569  ! 2. Method :
570  !
571  ! For a given set of non-dimensional frequencies the interpolation
572  ! arrays with non-dimensional depths and group velocity are filled.
573  ! The following non-dimensional parameters are used :
574  !
575  ! frequency f*SQRT(h/g) = f*
576  ! depth kh = k*
577  ! group vel. c/SQRT(gh) = c*
578  !
579  ! Where k is the wavenumber, h the depth f the intrinsic frequency,
580  ! g the acceleration of gravity and c the group velocity.
581  !
582  ! 3. Parameters :
583  !
584  ! See module documentation.
585  !
586  ! 4. Error messages :
587  !
588  ! - None.
589  !
590  ! 5. Called by :
591  !
592  ! - W3GRID
593  ! - Any main program.
594  !
595  ! 6. Subroutines used :
596  !
597  ! - WAVNU2 (solve dispersion relation)
598  !
599  ! 7. Remarks :
600  !
601  ! - In the filling of the arrays H = 1. is assumed and the factor
602  ! SQRT (g) is moved from the interpolation to the filling
603  ! procedure thus :
604  !
605  ! k* = k
606  !
607  ! c* = cg/SQRT(g)
608  !
609  ! 8. Structure
610  !
611  ! -----------------------------------
612  ! include common block
613  ! calculate parameters
614  ! fill zero-th position of arrays
615  ! fill middle positions of arrays
616  ! fill last positions of arrays
617  ! -----------------------------------
618  !
619  ! 9. Switches :
620  !
621  ! !/S Enable subroutine tracing.
622  !
623  ! 10. Source code :
624  !
625  !/ ------------------------------------------------------------------- /
626  !/
627  USE constants, ONLY : grav
628 #ifdef W3_S
629  USE w3servmd, ONLY: strace
630 #endif
631  !
632  IMPLICIT NONE
633  !/
634  !/ ------------------------------------------------------------------- /
635  !/ Local parameters
636  !/
637  INTEGER :: I, ICON
638 #ifdef W3_S
639  INTEGER, SAVE :: IENT = 0
640 #endif
641  REAL :: DEPTH, CG, SIMAX, SI, K
642  !/
643  !/ ------------------------------------------------------------------- /
644  !/
645 #ifdef W3_S
646  CALL strace (ient, 'DISTAB')
647 #endif
648  !
649  ! Calculate parameters ----------------------------------------------- *
650  !
651  n1max = nar1d - 1
652  depth = 1.
653  simax = sqrt(grav * dfac)
654  dsie = simax / real(n1max)
655  !
656  ! Fill zero-th position of arrays ------------------------------------ *
657  !
658  ewn1(0) = 0.
659  ecg1(0) = sqrt(grav)
660  !
661  ! Fill middle positions of arrays ------------------------------------ *
662  !
663  DO i=1, n1max
664  si = real(i)*dsie
665  CALL wavnu2 (si,depth,k,cg,1e-7,15,icon)
666  ewn1(i) = k
667  ecg1(i) = cg
668  END DO
669  !
670  ! Fill last positions of arrays -------------------------------------- *
671  !
672  i = n1max+1
673  si = real(i)*dsie
674  CALL wavnu2 (si,depth,k,cg,1e-7,15,icon)
675  ewn1(i) = k
676  ecg1(i) = cg
677  !
678  RETURN
679  !/
680  !/ End of DISTAB ----------------------------------------------------- /
681  !/
682  END SUBROUTINE distab
683 
684  !/ ------------------------------------------------------------------- /
685  !/
686  SUBROUTINE liu_forward_dispersion (H_ICE,VISC,H_WDEPTH,SIGMA &
687  ,K_SOLUTION,CG,ALPHA)
688  !/
689  !/ +-----------------------------------+
690  !/ | WAVEWATCH III NOAA/NCEP |
691  !/ | W. E. Rogers (NRL-SSC) |
692  !/ | FORTRAN 90 |
693  !/ | Last update : 11-Oct-2013 |
694  !/ +-----------------------------------+
695  !/
696  !/ 16-Oct-2012 : Origination. ( version 4.04 )
697  !/ (E. Rogers)
698  !/
699  ! 1. Purpose :
700  !
701  ! Dispersion relation calculation: given frequency, find k
702  ! This is for dispersion in ice, so it requires the ice thickness
703  ! and viscosity also. (the latter is the "eddy viscosity in the
704  ! turbulent boundary layer beneath the ice.").
705  ! Please note that this is for a continuous ice cover (not broken in floes)
706  !
707  ! This subroutine also calculates Cg and alpha.
708  ! alpha is the exponential decay rate of *energy* (not to be
709  ! confused with k_i which is the exponential decay rate of
710  ! amplitude)
711  !
712  ! Both alpha and k_i are for spatial decay rate, units (1/m)
713  ! Neither is for temporal decay rate.
714  !
715  ! References:
716  ! N/A here, but see subroutine "Liu_reverse_dispersion"
717  !
718  ! 2. Method :
719  !
720  ! Newton-Raphson.
721  ! For actual dispersion relation, see documentation of subroutine
722  ! "Liu_reverse_dispersion"
723  !
724  ! 3. Parameters :
725  !
726  ! Parameter list
727  ! ----------------------------------------------------------------
728  ! H_ICE Real I Ice thickness
729  ! VISC Real I Eddy viscosity (m2/sec)
730  ! H_WDEPTH Real I Water depth
731  ! SIGMA R.A. I Radian Wave frequency
732  ! K_SOLUTION R.A. O Wave number
733  ! CG R.A. O Group velocity
734  ! ALPHA R.A. O Exponential decay rate of energy
735  ! NK Int. I Number of frequencies
736  ! ----------------------------------------------------------------
737  !
738  ! 4. Subroutines used :
739  !
740  ! Name | Type | Module | Description
741  ! ----------------------------------------------------------------
742  ! Liu_reverse_dispersion | Subr.| W3SIC2MD| As name implies.
743  ! STRACE | Subr.| W3SERVMD| Subroutine tracing.
744  ! WAVNU1 | Subr.| W3DISPMD| Wavenumber for waves
745  ! in open water.
746  ! ----------------------------------------------------------------
747  !
748  ! 5. Called by :
749  !
750  ! Name | Type | Module | Description
751  ! ----------------------------------------------------------------
752  ! W3SIC2 | Subr.| W3SIC2MD| S_ice source term
753  ! ----------------------------------------------------------------
754  !
755  ! 6. Error messages :
756  !
757  ! Fails if solution is not found in a given number of iterations
758  !
759  ! 7. Remarks :
760  !
761  ! Eventually, k and Cg should be used for propagation. This is not
762  ! implemented yet. For now, it is only used to calculate the source
763  ! term.
764  !
765  ! For discussion of the eddy viscosity term, see documentation of
766  ! subroutine "Liu_reverse_dispersion"
767  !
768  ! This subroutine expects eddy viscosity in units of m2/sec even
769  ! though values are given in units of cm2/sec in the Liu paper.
770  !
771  ! 8. Structure :
772  !
773  ! See source code.
774  !
775  ! 9. Switches :
776  !
777  ! !/S Enable subroutine tracing.
778  !
779  ! 10. Source code :
780  !
781  !/ ------------------------------------------------------------------- /
782  USE constants, ONLY: tpi
783  USE w3odatmd, ONLY: ndse
784  USE w3servmd, ONLY: extcde
786  ! USE W3DISPMD, ONLY: WAVNU1
787 #ifdef W3_S
788  USE w3servmd, ONLY: strace
789 #endif
790  !/
791  IMPLICIT NONE
792  !/
793  !/ ------------------------------------------------------------------- /
794  !/ Parameter list
795 
796  REAL , INTENT(IN) :: H_ICE, H_WDEPTH, SIGMA(NK)
797  REAL , INTENT(IN) :: VISC ! in m2/sec
798  REAL , INTENT(OUT) :: K_SOLUTION(NK) ,CG(NK) ,ALPHA(NK)
799 
800  !/
801  !/ ------------------------------------------------------------------- /
802  !/ Local parameters
803 #ifdef W3_S
804  INTEGER, SAVE :: IENT = 0
805 #endif
806  INTEGER :: IK
807  REAL, PARAMETER :: FERRORMAX=1.0e-5 ! maximum acceptable error
808  INTEGER, PARAMETER :: N_ITER=20 ! number of iterations prior to
809  ! failure
810  LOGICAL :: GET_CG ! indicates whether to get Cg
811  ! and alpha
812  ! from "Liu_reverse_dispersion"
813  REAL :: FREQ(20) ! wave frequency at current
814  ! iteration
815  REAL :: KWN(20) ! wavenumber at current
816  ! iteration
817  INTEGER :: ITER ! iteration number
818  REAL :: DK,DF,DFDK ! as name implies
819  REAL :: FDUMMY ! as name implies
820  !REAL :: SIGMA ! 2*pi/T
821  REAL :: K_OPEN ! open-water value of k
822  REAL :: CG_OPEN ! open-water value of Cg
823  REAL :: FWANTED ! Freq. corresponding to sigma
824  REAL :: FERROR ! Max acceptable error after test to avoid crash
825 
826  !/
827  !/ ------------------------------------------------------------------- /
828  !/
829 #ifdef W3_S
830  CALL strace (ient, 'LIU_FORWARD_DISPERSION')
831 #endif
832  !
833  !/ 0) --- Initialize/allocate variables ------------------------------ /
834 
835 
836 
837 
838  DO ik = 1, nk
839 
840  get_cg = .false.
841  !/T38 WRITE(*,*)'FORWARD IN: H_ICE,VISC,H_WDEPTH,FWANTED = ', &
842  !/T38 H_ICE,VISC,H_WDEPTH,FWANTED
843  fwanted=sigma(ik)/tpi
844  ! First guess for k :
845 
846  CALL wavnu1(sigma(ik),h_wdepth,k_open,cg_open)
847  ! KWN(1) = 0.2 ! (old method)
848  kwn(1) =k_open ! new method, Mar 10 2014
849  !
850  !/ 1) ----- Iteration loop to find k --------------------------------- /
851  iter = 0
852  df = 999.
853 
854  IF ( (h_ice.LT.iicehdisp).OR.(h_wdepth.LT.iiceddisp) ) THEN
855  ferror=iicefdisp*ferrormax
856  ELSE
857  ferror=ferrormax
858  ENDIF
859 
860  DO WHILE ( abs(df).GE.ferror .AND. iter.LE.n_iter )
861  iter = iter + 1
862  ! compute freq for this iteration
863  CALL liu_reverse_dispersion(h_ice,visc,h_wdepth,kwn(iter), &
864  get_cg,freq(iter),cg(ik),alpha(ik))
865 
866  ! calculate dk
867  IF (iter == 1)THEN
868  ! We do not have slope yet, so pick a number...
869  dk = 0.01
870  ELSEIF (iter.EQ.n_iter+1) THEN
871  WRITE(ndse,800) n_iter
872  CALL extcde(2)
873  ELSE
874  ! use slope
875  dfdk = (freq(iter)-freq(iter-1)) / (kwn(iter)-kwn(iter-1))
876  df = fwanted - freq(iter)
877  !/T38 WRITE(*,*)'ITER = ',ITER,' ; K = ',KWN(ITER),' ; F = ', &
878  !/T38 FREQ(ITER),' ; DF = ',DF
879  dk = df / dfdk
880  ENDIF
881 
882  ! Decide on next k to try
883  kwn(iter+1) = kwn(iter) + dk
884  ! If we end up with a negative k for the next iteration, don't
885  ! allow this.
886  IF(kwn(iter+1) < 0.0)THEN
887  kwn(iter+1) = tpi / 1000.0
888  ENDIF
889 
890  END DO
891 
892  !/ 2) -------- Finish up. -------------------------------------------- /
893  ! Success, so return K_SOLUTION, and call LIU_REVERSE_DISPERSION one
894  ! last time, to get CG and ALPHA
895 
896  k_solution(ik) = kwn(iter)
897 
898  get_cg = .true.
899  CALL liu_reverse_dispersion(h_ice,visc,h_wdepth,k_solution(ik), &
900  get_cg,fdummy,cg(ik),alpha(ik))
901  END DO
902  !
903 #ifdef W3_T38
904  WRITE(*,*)'FORWARD OUT: K_SOLUTION,CG,ALPHA = ', &
905  k_solution,cg,alpha
906  IF (h_ice==1.0)THEN
907  WRITE(*,*)fwanted,alpha
908  ENDIF
909 #endif
910  !
911 800 FORMAT (/' *** WAVEWATCH III ERROR IN ' &
912  'W3SIC2_LIU_FORWARD_DISPERSION : ' / &
913  ' NO SOLUTION FOUND AFTER ',i4,' ITERATIONS.')
914  !/
915  !/ End of LIU_FORWARD_DISPERSION ------------------------------------- /
916  !/
917  END SUBROUTINE liu_forward_dispersion
918  !/ ------------------------------------------------------------------- /
919  !/
920  SUBROUTINE liu_reverse_dispersion (H_ICE,VISC,H_WDEPTH,KWN &
921  ,GET_CG,FREQ,CG,ALPHA)
922  !/
923  !/ +-----------------------------------+
924  !/ | WAVEWATCH III NOAA/NCEP |
925  !/ | W. E. Rogers (NRL-SSC) |
926  !/ | FORTRAN 90 |
927  !/ | Last update : 11-Oct-2013 |
928  !/ +-----------------------------------+
929  !/
930  !/ 12-Oct-2012 : Origination. ( version 4.04 )
931  !/ (E. Rogers)
932  !/
933  ! 1. Purpose :
934  !
935  ! Dispersion relation calculation: given k, find frequency.
936  ! This is for dispersion in ice, so it requires the ice thickness
937  ! and viscosity also. (the latter is the "eddy viscosity in the
938  ! turbulent boundary layer beneath the ice.").
939  !
940  ! This subroutine also (optionally) calculates Cg and alpha.
941  ! alpha is the exponential decay rate of *energy* (not to be
942  ! confused with k_i which is the exponential decay rate of
943  ! amplitude)
944  !
945  ! Both alpha and k_i are for spatial decay rate, units (1/m)
946  ! Neither is for temporal decay rate.
947 
948  ! This calculation is optional for reasons of computational
949  ! efficiency (don't calculate if it will not be used). Note that
950  ! if Cg and alpha are not calculated, the value of input viscosity
951  ! is irrelevant.
952  !
953  ! References:
954  ! Liu et al. 1991: JGR 96 (C3), 4605-4621
955  ! Liu and Mollo 1988: JPO 18 1720-1712
956  !
957  ! 2. Method :
958  !
959  ! In 1991 paper, see equations on page 4606. The key equations are:
960  ! sigma2=(grav*k+B*k^5)/((coth(k*H_wdepth))+k*M);
961  ! Cg=(grav+(5+4*k*M)*(B*k^4))/((2*sigma)*((1+k*M)^2));
962  ! alpha=(sqrt(visc)*k*sqrt(sigma))/(Cg*sqrt(2)*(1+k*M));
963  !
964  ! 3. Parameters :
965  !
966  ! Parameter list
967  ! ----------------------------------------------------------------
968  ! H_ICE REAL I Ice thickness
969  ! VISC REAL I Eddy viscosity (if GET_CG) (m2/sec)
970  ! H_WDEPTH REAL I Water depth
971  ! KWN REAL I Wavenumber
972  ! GET_CG LOGICAL I Indicates whether to calculate Cg and alpha
973  ! FREQ REAL O Frequency
974  ! CG REAL O Group velocity (if GET_CG)
975  ! ALPHA REAL O Exponential decay rate of energy (if GET_CG)
976  ! ----------------------------------------------------------------
977  !
978  ! 4. Subroutines used :
979  !
980  ! Name Type Module Description
981  ! ----------------------------------------------------------------
982  ! STRACE Subr. W3SERVMD Subroutine tracing.
983  ! ----------------------------------------------------------------
984  !
985  ! 5. Called by :
986  !
987  ! Name | Type | Module | Description
988  ! ----------------------------------------------------------------
989  ! Liu_forward_dispersion| Subr.| W3SIC2MD| As name implies.
990  ! ----------------------------------------------------------------
991  !
992  ! 6. Error messages :
993  !
994  ! None.
995  !
996  ! 7. Remarks :
997  !
998  ! Eventually, k and Cg should be used for propagation. This is not
999  ! implemented yet. For now, it is only used to calculate the source
1000  ! term.
1001  !
1002  ! The eddy viscosity term given by Liu is unfortunately highly
1003  ! variable, and "not a physical parameter", which suggests that it
1004  ! is difficult to specify in practice. In this paper, we see values
1005  ! of:
1006  ! nu= 160.0e-4 m2/sec (Brennecke (1921)
1007  ! nu= 24.0e-4 m2/sec (Hunkins 1966)
1008  ! nu=3450.0e-4 m2/sec (Fig 11)
1009  ! nu= 4.0e-4 m2/sec (Fig 12)
1010  ! nu= 150.0e-4 m2/sec (Fig 13)
1011  ! nu= 54.0e-4 m2/sec (Fig 14)
1012  ! nu= 384.0e-4 m2/sec (Fig 15)
1013  ! nu=1536.0e-4 m2/sec (Fig 16)
1014  !
1015  ! The paper states: "The only tuning parameter is the turbulent eddy
1016  ! viscosity, and it is a function of the flow conditions in the
1017  ! turbulent boundary layer which are determined by the ice
1018  ! thickness, floe sizes, ice concentration, and wavelength."
1019  !
1020  ! Another criticism of this source term is that it does not use the
1021  ! ice concentration in actual calculations. The method appears to
1022  ! simply rely on concentration being high, "When the ice is highly
1023  ! compact with high concentration, the flexural waves obey the
1024  ! dispersion relation (1) as similar waves in a continuous ice
1025  ! sheet." Later, "Five of these cases with high ice conentration
1026  ! (larger than 60%) in the MIZ have been selected"
1027  !
1028  ! This subroutine expects eddy viscosity in units of m2/sec even
1029  ! though values are given in units of cm2/sec in the Liu paper.
1030  !
1031  ! Cg used here is correct only for deep water. It is taken from
1032  ! Liu et al. (1991) equation 2. If we want to calculate for finite
1033  ! depths accurately, we need to use d_sigma/d_k. However, be warned
1034  ! that this calculation is sensitive to numerical error and so the
1035  ! (potentially too coarse) computational grid for sigma and k should
1036  ! *not* be used.
1037  !
1038  ! 8. Structure :
1039  !
1040  ! See source code.
1041  !
1042  ! 9. Switches :
1043  !
1044  ! !/S Enable subroutine tracing.
1045  !
1046  ! 10. Source code :
1047  !
1048  !/ ------------------------------------------------------------------- /
1049  USE constants, ONLY: dwat, tpi, grav
1050  USE w3gdatmd, ONLY: nk
1051 #ifdef W3_S
1052  USE w3servmd, ONLY: strace
1053 #endif
1054  !/
1055  IMPLICIT NONE
1056  !/
1057  !/ ------------------------------------------------------------------- /
1058  !/ Parameter list
1059  REAL , INTENT(IN) :: H_ICE,H_WDEPTH,KWN
1060  REAL , INTENT(IN) :: VISC ! in m2/sec
1061  LOGICAL, INTENT(IN) :: GET_CG
1062  REAL , INTENT(OUT) :: FREQ,CG,ALPHA
1063  !/
1064  !/ ------------------------------------------------------------------- /
1065  !/ Local parameters
1066 #ifdef W3_S
1067  INTEGER, SAVE :: IENT = 0
1068 #endif
1069  REAL, PARAMETER :: E = 6.0e+9 ! Young's modulus of elasticity
1070  REAL, PARAMETER :: S = 0.3 ! "s", Poisson's ratio
1071  REAL :: DICE ! "dice", density of ice
1072  REAL :: B ! quantifies effect of bending
1073  ! of ice
1074  REAL :: M ! quantifies effect of inertia
1075  ! of ice
1076  REAL :: COTHTERM ! temporary variable
1077  REAL :: SIGMA ! 2*pi/T
1078  REAL :: KH ! k*h
1079  !/
1080  !/ ------------------------------------------------------------------- /
1081  !/
1082 #ifdef W3_S
1083  CALL strace (ient, 'LIU_REVERSE_DISPERSION')
1084 #endif
1085  !
1086  !/ 0) --- Initialize essential parameters ---------------------------- /
1087  cg = 0.
1088  alpha = 0.
1089  freq = 0.
1090  dice = dwat * 0.9 ! from Liu 1991 pg 4606
1091 
1092 #ifdef W3_T38
1093  WRITE(*,*)'REVERSE IN: H_ICE,VISC,H_WDEPTH,KWN,GET_CG = ', &
1094  h_ice,visc,h_wdepth,kwn,get_cg
1095 #endif
1096 
1097  !
1098  !/ 1) --- Calculate frequency ---------------------------------------- /
1099 
1100  ! Note: Liu et al 1991 have "kwn*h_ice" in COTH(_) but I believe they
1101  ! meant to write "kwn*H_wdepth"
1102 
1103  b = (e * h_ice**3) / (12. * (1. - s**2) * dwat)
1104  m = dice * h_ice / dwat
1105  kh = kwn * h_wdepth
1106  IF ( kh>5.0 ) THEN
1107  cothterm = 1.0
1108  ELSEIF ( kh<1.0e-4 ) THEN
1109  cothterm = 1.0 / kh
1110  ELSE
1111  cothterm = cosh(kh) / sinh(kh)
1112  ENDIF
1113  sigma = sqrt((grav * kwn + b * kwn**5) / (cothterm + kwn * m))
1114  freq = sigma/(tpi)
1115 
1116  !/ 2) --- Calculate Cg and alpha if requested ------------------------ /
1117  ! Note: Cg is correct only for deep water
1118  IF (get_cg) THEN
1119  cg = (grav + (5.0+4.0 * kwn * m) * (b * kwn**4)) &
1120  / (2.0 * sigma * ((1.0 + kwn * m)**2))
1121  alpha = (sqrt(visc) * kwn * sqrt(sigma)) &
1122  / (cg * sqrt(2.0) * (1 + kwn * m))
1123  ENDIF
1124 
1125 #ifdef W3_T38
1126  WRITE(*,*)'REVERSE OUT: FREQ,CG,ALPHA = ',freq,cg,alpha
1127 #endif
1128 
1129  !/
1130  !/ End of LIU_REVERSE_DISPERSION ------------------------------------- /
1131  !/
1132  END SUBROUTINE liu_reverse_dispersion
1133  !/ ------------------------------------------------------------------- /
1134  !/
1135  !/ End of module W3DISPMD -------------------------------------------- /
1136  !/
1137 END MODULE w3dispmd
w3dispmd::dfac
real, parameter dfac
Definition: w3dispmd.F90:75
w3gdatmd::nk
integer, pointer nk
Definition: w3gdatmd.F90:1230
w3gdatmd::iiceddisp
real, pointer iiceddisp
Definition: w3gdatmd.F90:1183
constants::pi
real, parameter pi
PI Value of Pi.
Definition: constants.F90:71
w3dispmd::wavnu_local
pure subroutine wavnu_local(SIG, DW, WNL, CGL)
Definition: w3dispmd.F90:456
w3gdatmd::dmin
real, pointer dmin
Definition: w3gdatmd.F90:1183
w3dispmd::wavnu3
pure subroutine wavnu3(SI, H, K, CG)
Definition: w3dispmd.F90:347
w3gdatmd::iicehdisp
real, pointer iicehdisp
Definition: w3gdatmd.F90:1183
w3odatmd::ndse
integer, pointer ndse
Definition: w3odatmd.F90:456
w3dispmd::ewn1
real, dimension(0:nar1d) ewn1
Definition: w3dispmd.F90:78
w3dispmd::wavnu2
subroutine wavnu2(W, H, K, CG, EPS, NMAX, ICON)
Definition: w3dispmd.F90:204
w3servmd
Definition: w3servmd.F90:3
w3gdatmd::iicehmin
real, pointer iicehmin
Definition: w3gdatmd.F90:1183
w3dispmd::liu_forward_dispersion
subroutine liu_forward_dispersion(H_ICE, VISC, H_WDEPTH, SIGMA, K_SOLUTION, CG, ALPHA)
Definition: w3dispmd.F90:688
w3odatmd
Definition: w3odatmd.F90:3
w3dispmd::ecg1
real, dimension(0:nar1d) ecg1
Definition: w3dispmd.F90:78
constants::dwat
real, parameter dwat
DWAT Density of water (kg/m3).
Definition: constants.F90:62
w3dispmd::distab
subroutine distab
Definition: w3dispmd.F90:552
constants::tpi
real, parameter tpi
TPI 2*Pi.
Definition: constants.F90:72
w3servmd::strace
subroutine strace(IENT, SNAME)
Definition: w3servmd.F90:148
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
w3gdatmd
Definition: w3gdatmd.F90:16
w3dispmd::nar1d
integer, parameter nar1d
Definition: w3dispmd.F90:74
w3dispmd::wavnu1
subroutine wavnu1(SI, H, K, CG)
Definition: w3dispmd.F90:85
w3servmd::extcde
subroutine extcde(IEXIT, UNIT, MSG, FILE, LINE, COMM)
Definition: w3servmd.F90:736
w3dispmd::liu_reverse_dispersion
subroutine liu_reverse_dispersion(H_ICE, VISC, H_WDEPTH, KWN, GET_CG, FREQ, CG, ALPHA)
Definition: w3dispmd.F90:922
w3dispmd
Definition: w3dispmd.F90:3
w3dispmd::n1max
integer n1max
Definition: w3dispmd.F90:77
w3gdatmd::iicefdisp
real, pointer iicefdisp
Definition: w3gdatmd.F90:1183
constants::grav
real, parameter grav
GRAV Acc.
Definition: constants.F90:61
w3dispmd::dsie
real dsie
Definition: w3dispmd.F90:78