WAVEWATCH III  beta 0.0.1
w3sic3md.F90
Go to the documentation of this file.
1 #include "w3macros.h"
2 !/ ------------------------------------------------------------------- /
3 MODULE w3sic3md
4  !/
5  !/ +-----------------------------------+
6  !/ | WAVEWATCH III NOAA/NCEP |
7  !/ | E. Rogers |
8  !/ | S. Zieger |
9  !/ | X. Zhao |
10  !/ | S. Cheng |
11  !/ | FORTRAN 90 |
12  !/ | Last update : 04-Jan-2016 |
13  !/ +-----------------------------------+
14  !/
15  !/ Updates:
16  !/ 29-May-2014 : Generalization with turbulent BL
17  !/ (F.A. method imported from IC2 by E.R.) ( version 5.01 )
18  !/ 04-Jan-2016 : Importing code provided by S. Cheng
19  !/ (improved solution methods for Wang and Shen model)
20  !/
21  ! 1. Purpose :
22  !
23  ! Calculate ice source term S_{ice} according to a viscoelastic sea
24  ! ice model (Wang and Shen 2010).
25  !
26  ! Reference: Wang, R., and H. H. Shen (2010), Gravity waves
27  ! propagating into an ice‐covered ocean: A viscoelastic model, J.
28  ! Geophys. Res., 115, C06024, doi:10.1029/2009JC005591 .
29  !
30  ! 2. Variables and types :
31  ! Name Type Scope Description
32  ! ------------------------------------------------------------------
33  ! IC3TABLE_CHENG Int. Public Table of wave number k_r,
34  ! attenuation k_i and group
35  ! velocity cg
36  ! IC3_DITK R.A. Private Ice thickness increment
37  ! IC3_MAXITK R.A. Private Maximum ice thickness, the code
38  ! may fail for situation with ice
39  ! thickness larger than this value
40  !
41  ! 3. Subroutines and functions :
42  !
43  ! Name Type Scope Description
44  ! ------------------------------------------------------------------
45  ! W3SIC3 Subr. Public Ice source term.
46  ! BSDET Func. Private Calculate the determinant for
47  ! the dispersion relation.
48  ! WN_CMPLX_V1 Func. Private Calculate complex wavenumber in
49  ! ice
50  ! WN_PRECALC_CHENG Subr. Private Calculate complex wavenumber in
51  ! ice
52  ! WN_CMPLX_HF Func. Private Like above, but for h-f waves
53  ! CMPLX_ROOT_MULLER_CHENG Func. Private Find root for complex
54  ! numbers
55  ! FUN_ZHAO Func. Private Wrapper function for FUNC0/FUNC1
56  ! FUNC0_ZHAO Func. Private
57  ! FUNC1_ZHAO Func. Private
58  ! W3IC3WNCG Subr. Public Calculate kr,ki and cg for all
59  ! frequency at each grid point
60  ! IC3PRECALC_CHENG Subr. Private Calculate kr,ki and cg table for
61  ! all frequencies and ice
62  ! thickness from 0~IC3_MAXITK
63  ! CGinIC3_CHENG func. Private Calculate group velocity
64  ! related to IC3 model
65  ! F_ZHAO Func. Private Wrapper function for double/
66  ! quadruple precision
67  ! ------------------------------------------------------------------
68  !
69  ! 4. Subroutines and functions used :
70  !
71  ! See subroutine documentation.
72  !
73  ! 5. Remarks :
74  !
75  ! 6. Switches :
76  !
77  ! See subroutine documentation.
78  !
79  ! 7. Source code :
80  !/
81  !/ ------------------------------------------------------------------- /
82  !/
84  PRIVATE :: wn_cmplx_v1, wn_cmplx_hf
85  PRIVATE :: cmplx_root_muller_v1, cmplx_root_muller_cheng
86  PRIVATE :: f_zhao_v1, f_zhao_cheng
87  PRIVATE :: func1_zhao, func0_zhao, bsdet
88  INTEGER,SAVE :: calledic3table = 0
89  REAL,PRIVATE,PARAMETER :: ic3_ditk = 0.01, ic3_maxitk = 3.
90  PUBLIC :: ic3table_cheng
91  PRIVATE :: ic3precalc_cheng, cginic3_cheng
92 
93 CONTAINS
94  !/ ------------------------------------------------------------------- /
95  !/
96  SUBROUTINE w3sic3 (A, DEPTH, CG, WN, IX, IY, S, D)
97  !/
98  !/ +-----------------------------------+
99  !/ | WAVEWATCH III NOAA/NCEP |
100  !/ | E. Rogers |
101  !/ | S. Zieger |
102  !/ | FORTRAN 90 |
103  !/ | Last update : 11-Oct-2013 |
104  !/ +-----------------------------------+
105  !/
106  !/ 06-May-2013 : Origination (copied from SICE1) ( version 4.10 )
107  !/ (E. Rogers)
108  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
109  !/
110  !/ FIXME : Move field input to W3SRCE and provide
111  !/ (S.Zieger) input parameter to W3SIC1 to make the subroutine
112  !/ : versatile for point output processors ww3_outp
113  !/ and ww3_ounp.
114  !/
115  !/ Copyright 2009 National Weather Service (NWS),
116  !/ National Oceanic and Atmospheric Administration. All rights
117  !/ reserved. WAVEWATCH III is a trademark of the NWS.
118  !/ No unauthorized use without permission.
119  !/
120  ! 1. Purpose :
121  !
122  ! Calculate ice source term S_{ice} according to a viscoelastic sea
123  ! ice model (Wang and Shen 2010).
124  !
125  ! Reference: Wang, R., and H. H. Shen (2010), Gravity waves
126  ! propagating into an ice‐covered ocean: A viscoelastic model, J.
127  ! Geophys. Res., 115, C06024, doi:10.1029/2009JC005591 .
128  !
129  !/ ------------------------------------------------------------------- /
130  !
131  ! 2. Method :
132  !
133  ! Regarding i/o (general to all Sice modules): S_{ice} source term
134  ! is calculated using up to 5 parameters read from input files.
135  ! These parameters are allowed to vary in space and time.
136  ! The parameters control the exponential decay rate k_i
137  ! Since there are 5 parameters, this permits description of
138  ! dependence of k_i on frequency or wavenumber.
139  !
140  ! Sea ice affects the wavenumber k of wind-generated ocean waves.
141  ! The ice-modified wavenumber can be expressed as a complex number
142  ! k = k_r + i*k_i, with the real part k_r representing impact of
143  ! the sea ice on the physical wavelength and propagation speeds,
144  ! producing something analogous to shoaling and refraction by
145  ! bathymetry, whereas the imaginary part of the complex
146  ! wavenumber, k_i, is an exponential decay coefficient
147  ! k_i(x,y,t,sigma) (depending on location, time and frequency,
148  ! respectively), representing wave attenuation, and can be
149  ! introduced in a wave model such as WW3 as S_ice/E=-2*Cg*k_i,
150  ! where S_ice is one of several dissipation mechanisms, along
151  ! with whitecapping, for example, S_ds=S_wc+S_ice+⋯. The k_r -
152  ! modified by ice would enter the model via the C calculations
153  ! on the left-hand side of the governing equation.The fundamentals
154  ! are straightforward, e.g. Rogers and Holland (2009 and
155  ! subsequent unpublished work) modified a similar model, SWAN
156  ! (Booij et al. 1999) to include the effects of a viscous mud
157  ! layer using the same approach (k = k_r + i*k_i) previously.
158  !
159  ! General approach is analogous to Rogers and Holland (2009)
160  ! approach for mud.
161  ! See text near their eq. 1 :
162  ! k = k_r + i * k_i
163  ! eta(x,t) = Real( a * exp( i * ( k * x - sigma * t ) ) )
164  ! a = a0 * exp( -k_i * x )
165  ! S / E = -2 * Cg * k_i (see also Komen et al. (1994, pg. 170)
166  !
167  ! Following W3SBT1 as a guide, equation 1 of W3SBT1 says:
168  ! S = D * E
169  ! However, the code of W3SBT1 has
170  ! S = D * A
171  ! This leads me to believe that the calling routine is
172  ! expecting "S/sigma" not "S"
173  ! Thus we will use D = S/E = -2 * Cg * k_i
174  !
175  ! The calling routine is expecting "S/sigma" not "S"
176  ! Thus we will use D = S/E = -2 * Cg * k_i
177  ! (see also documentation of W3SIC1)
178  !
179  ! Notes regarding numerics:
180  !
181  ! Experiments with constant k_i values suggest that results may be
182  ! dependent on resolution if insufficient resolution is used.
183  ! For detailed information, see documentation of W3SIC1.
184  !
185  ! Note regarding applicability/validity:
186  !
187  ! The Wang and Shen model is intended as a generalized model for
188  ! various types of ice cover. It is a "continuum" model for
189  ! which the same model is used from the ice edge to the ice
190  ! interior. Though the ice types are expected to be very different
191  ! from the edge to the interior, this is accomodated by the relative
192  ! importance of the "effective viscosity" and the "modulus of
193  ! elasticity". At the ice edge, where one finds frazil ice, pancake
194  ! ice, or ice floes much smaller than the wave length, the "viscous"
195  ! component of the model is believed to be most appropriate. At the
196  ! interior, where one finds a continuous ice sheet, the "elastic
197  ! model" component of the generalized visco-elastic model is
198  ! expected to be appropriate. In addition to the case of continuous
199  ! ice, Wang and Shen argue that the elastic model is also applicable
200  ! to ice floes when the floe sizes are large relative to the
201  ! wavelength. So to summarize,
202  ! * frazil ice, pancake ice, and floes smaller than wavelength :
203  ! viscosity dominates
204  ! * continuous ice, and floes larger than wavelength :
205  ! elasticity dominates
206  ! * intermediate conditions: neither dominates
207  ! All this is accomodated in WW3 by using non-uniform specification
208  ! of viscosity and elasticity.
209  !
210  ! In the case where a user wishes to utilize only the "viscous
211  ! model" aspect of Wang and Shen, and use an alternative scheme for
212  ! continous ice and large ice floes, we allow this through the use
213  ! of a user-defined namelist parameter "IC3MAXTHK". Floe size is
214  ! not (at time of writing) an output available from ice model CICE,
215  ! so we use the ice thickness as a way to anticipate the floe size.
216  ! When ice thickness exceeds IC3MAXTHK, WW3 will use another model
217  ! in place of the Wang and Shen formulation :
218  !
219  ! S_ice by F.A., an estimation of dissipation by turbulence
220  ! at the ice-water interface. It uses only namelists for input, and
221  ! no space/time varying input (though of course ice concentration is
222  ! space/time varying). Unlike Liu et al. (IC2), it does not use
223  ! ice thickness and does not yield a new C|Cg|k (i.e. it is non-
224  ! dispersive), but it has the very nice feature of not requiring
225  ! an eddy viscosity, which is a major drawback of the Liu et al.
226  ! model. That is why we use it here, vs. Liu et al.
227  ! (S_ice by Liu et al. and S_ice by F.A. are the two options
228  ! available in IC2, i.e. w3sic2md.ftn)
229  !
230  ! At time of writing (March 23 2015), there may be some problems
231  ! with the root-selection of IC3. For example with these settings:
232  ! hice=1 ; rho_ice=917.0 ; emod=4.9e+12 ; visc=5e+7 ;
233  ! h_water=deep (without using the IC3MAXTHK feature) the solution
234  ! is rather irregular:
235  ! T=11.11 k_i = 215.0e-5
236  ! T=10 k_i = 266.0e-5
237  ! T=9 k_i = 1.4e-5
238  ! T=8.1 k_i = 1.7e-5
239  ! With hice=0.1, ki is monotonically increasing in that range:
240  ! T=11.11 k_i = 0.97e-5
241  ! T=10 k_i = 2.64e-5
242  ! T=9 k_i = 3.90e-5
243  ! T=8.1 k_i = 4.47e-5
244  ! Of course, when using IC3MAXTHK=0.1, the first example (hice=1)
245  ! would switch to the "S_ice by F.A." model, and so this problem
246  ! is circumvented.
247  !
248  ! 3. Parameters :
249  !
250  ! Parameter list
251  ! ----------------------------------------------------------------
252  ! A R.A. I Action density spectrum (1-D).
253  ! DEPTH Real I Local water depth.
254  ! CG R.A. I Group velocities.
255  ! WN R.A. I Wavenumbers.
256  ! IX,IY I.S. I Grid indices.
257  ! S R.A. O Source term (1-D version).
258  ! D R.A. O Diagonal term of derivative (1-D version).
259  ! ----------------------------------------------------------------
260  !
261  ! 4. Subroutines used :
262  !
263  ! Name Type Module Description
264  ! ----------------------------------------------------------------
265  ! STRACE Subr. W3SERVMD Subroutine tracing (!/S switch).
266  ! PRT2DS Subr. W3ARRYMD Print plot output (!/T1 switch).
267  ! OUTMAT Subr. W3ARRYMD Matrix output (!/T2 switch).
268  ! ----------------------------------------------------------------
269  !
270  ! 5. Called by :
271  !
272  ! Name Type Module Description
273  ! ----------------------------------------------------------------
274  ! W3SRCE Subr. W3SRCEMD Source term integration.
275  ! W3EXPO Subr. N/A ASCII Point output post-processor.
276  ! W3EXNC Subr. N/A NetCDF Point output post-processor.
277  ! GXEXPO Subr. N/A GrADS point output post-processor.
278  ! ----------------------------------------------------------------
279  !
280  ! 6. Error messages :
281  !
282  ! None.
283  !
284  ! 7. Remarks :
285  !
286  ! If ice parameter 1 is zero, no calculations are made.
287  !
288  ! Code by S. Cheng sets NOICE=.TRUE. if ISNAN(ICECOEF1).
289  ! Comments are "maps may not be compatible"
290  ! This feature is not understood by me (ER) and so omitted.
291  !
292  !/ ------------------------------------------------------------------- /
293  ! On array size, S. Cheng says:
294  ! Upon checking the origin of CG, I would say CG = CG_IC3, this is
295  ! the topic ‘call W3IC3WNCG twice’. Recently I find they are not
296  ! exactly the same due to calculation and smoothing of cg using
297  ! several neighbor points. For different input array size, results
298  ! are slightly different. In subr. w3wave, the size of input arrays
299  ! is 0:NK+1, while in w3sic3, the size of all input arrays is 1:NK.
300  ! This array size difference is reflected in the resulting cg. The
301  ! small difference in cg between calling IC3 twice or just calling
302  ! once produces small difference in SWH. To eliminate this small
303  ! difference, I suggest to keep CG instead of CG_IC3, as well as WN,
304  ! WN_I, because other source terms use CG. I confirmed this change
305  ! would make results of ICE the same whether calling twice or once
306  ! by defining dimension WN_R, WN_I, CG_IC3 as 0:NK+1 instead of
307  ! 1:NK. Then CG_IC3 = CG.
308  !/ ------------------------------------------------------------------- /
309  ! On optimization, S. Cheng says:
310  ! For Wang and Shen’s model, D does not change in the loop
311  ! corresponding to NSTEPS in subr. W3SRCE. I find the most efficient
312  ! and easy way to speed up is that Add D and NSTEPS as inputs of
313  ! W3SIC3
314  ! If NSTEPS==1
315  ! Current Wang and Shen’s model code above.
316  ! ELSE
317  ! S = D*A
318  ! Endif
319  !/ ------------------------------------------------------------------- /
320  !
321  ! 8. Structure :
322  !
323  ! See source code.
324  !
325  ! 9. Switches :
326  !
327  ! !/S Enable subroutine tracing.
328  ! !/T Enable general test output.
329  ! !/T0 2-D print plot of source term.
330  ! !/T1 Print arrays.
331  !
332  ! 10. Source code :
333  !
334  !/ ------------------------------------------------------------------- /
335  USE constants, ONLY: tpi, dwat, abmin, delab, sizefwtable, &
336  fwtable, grav
337  USE w3odatmd, ONLY: ndse, iaproc, naproc, naperr
338  ! USE WMMDATMD, ONLY: IMPROC, NMPERR ! WMMDATMD unavailable to outp
339  USE w3servmd, ONLY: extcde
340  USE w3gdatmd, ONLY: nk, nth, nspec, sig, mapwn, ic3pars, dden, &
342  USE w3idatmd, ONLY: icep1, icep2, icep3, icep4, icep5, icei, &
343  inflags2
344 #ifdef W3_T
345  USE w3odatmd, ONLY: ndst
346 #endif
347 #ifdef W3_S
348  USE w3servmd, ONLY: strace
349 #endif
350 #ifdef W3_T0
351  USE w3arrymd, ONLY: prt2ds
352 #endif
353 #ifdef W3_T1
354  USE w3arrymd, ONLY: outmat
355 #endif
356  !
357  IMPLICIT NONE
358  !/
359  !/ ------------------------------------------------------------------- /
360  !/ Parameter list
361  !/
362  REAL, INTENT(IN) :: cg(nk), wn(nk), a(nspec), depth
363  REAL, INTENT(OUT) :: s(nspec), d(nspec)
364  INTEGER, INTENT(IN) :: ix, iy
365  !/
366  !/ ------------------------------------------------------------------- /
367  !/ Local parameters
368  !/
369 #ifdef W3_S
370  INTEGER, SAVE :: ient = 0
371 #endif
372  INTEGER :: ith
373 #ifdef W3_T0
374  REAL :: dout(nk,nth)
375 #endif
376  INTEGER :: ikth, ik
377  REAL :: icecoef1, icecoef2, icecoef3, &
378  icecoef4, icecoef5, iceconc
379  REAL, DIMENSION(NK) :: d1d, wn_i, wn_r, cg_ic3, cg_tmp
380  LOGICAL :: noice
381  REAL :: viscm=1.83e-6
382  REAL :: freq
383  ! ............VISCM=1.83E-6 : molecular viscosity of water at freezing
384  REAL :: pturb, pvisc, dturb, dvisc, &
385  smooth, re, uorb, aorb, eb, &
386  deli1, deli2, fw, xi, fturb, &
387  maxthk, maxcnc, use_cheng, &
388  use_cgice, fixedhice, &
389  fixedvisc,fixeddens,fixedelas
390  INTEGER :: ind, is, numin
391  !
392  !/
393  !/ ------------------------------------------------------------------- /
394  !/
395 #ifdef W3_S
396  CALL strace (ient, 'W3SIC3')
397 #endif
398  !
399  ! 0. Initializations ------------------------------------------------ /
400  !
401  !
402  d = 0.0
403  d1d = 0.0
404  !
405  wn_r = wn
406  wn_i = 0.0
407  cg_ic3 = 0.0
408  cg_tmp = 0.0
409  !
410  icecoef1 = 0.0
411  icecoef2 = 0.0
412  icecoef3 = 0.0
413  icecoef4 = 0.0
414  icecoef5 = 0.0
415  iceconc = 0.0
416  !
417  ! Rename variables to make code easier to read.
418  maxthk=ic3pars(1)
419  maxcnc=ic3pars(8)
420  use_cheng=ic3pars(9)
421  use_cgice=ic3pars(12)
422  fixedhice=ic3pars(13)
423  fixedvisc=ic3pars(14)
424  fixeddens=ic3pars(15)
425  fixedelas=ic3pars(16)
426 
427  ! --- Error checking for input ----------------------------------- /
428  ! --- Allow one and only one input option for each variable ------ /
429  numin=0
430  IF (inflags2(-7)) numin=numin+1
431  IF (fixedhice.GE.0.0) numin=numin+1
432  IF (numin.NE.1) THEN
433  IF ( iaproc .EQ. naperr ) &
434  WRITE (ndse,1001) 'ICE PARAMETER 1 (HICE)',numin
435  CALL extcde(2)
436  ENDIF
437 
438  numin=0
439  IF (inflags2(-6)) numin=numin+1
440  IF (fixedvisc.GE.0.0) numin=numin+1
441  IF (numin.NE.1) THEN
442  IF ( iaproc .EQ. naperr ) &
443  WRITE (ndse,1001) 'ICE PARAMETER 2 (VISC)',numin
444  CALL extcde(2)
445  ENDIF
446 
447  numin=0
448  IF (inflags2(-5)) numin=numin+1
449  IF (fixeddens.GE.0.0) numin=numin+1
450  IF (numin.NE.1) THEN
451  IF ( iaproc .EQ. naperr ) &
452  WRITE (ndse,1001) 'ICE PARAMETER 3 (DENS)',numin
453  CALL extcde(2)
454  ENDIF
455 
456  numin=0
457  IF (inflags2(-4)) numin=numin+1
458  IF (fixedelas.GE.0.0) numin=numin+1
459  IF (numin.NE.1) THEN
460  IF ( iaproc .EQ. naperr ) &
461  WRITE (ndse,1001) 'ICE PARAMETER 4 (ELAS)',numin
462  CALL extcde(2)
463  ENDIF
464 
465  ! --- Set local value to be used subsequently (ICEPx variables
466  ! are not used beyond this point). --------------------------- /
467  IF (inflags2(-7)) THEN
468  icecoef1 = icep1(ix,iy) ! ice thickness
469  ELSE
470  icecoef1 = fixedhice
471  ENDIF
472 
473  IF (inflags2(-6)) THEN
474  icecoef2 = icep2(ix,iy) ! effective viscosity of ice cover
475  ELSE
476  icecoef2 = fixedvisc
477  ENDIF
478 
479  IF (inflags2(-5)) THEN
480  icecoef3 = icep3(ix,iy) ! density of ice
481  ELSE
482  icecoef3 = fixeddens
483  ENDIF
484 
485  IF (inflags2(-4)) THEN
486  icecoef4 = icep4(ix,iy) ! effective shear modulus of ice
487  ELSE
488  icecoef4 = fixedelas
489  ENDIF
490 
491  ! ICECOEF5 = ICEP5(IX,IY) ! ICEP5 is inactive in W3SIC3
492 
493  IF (inflags2(4)) iceconc = icei(ix,iy)
494 
495  !
496  ! 1. No ice --------------------------------------------------------- /
497  !
498  noice=.false.
499  IF (icecoef1==0.0) noice=.true.
500  IF (inflags2(4).AND.(iceconc==0.0)) noice=.true.
501 
502  IF ( noice ) THEN
503 
504  d1d=0.0
505  !
506  ! 2. Ice ------------------------------------------------------------ /
507  ELSEIF ( use_cheng==1.0 .AND. &
508  ((icecoef1.LE.maxthk).OR.(iceconc.LE.maxcnc)) ) THEN
509 
510  ! 2.a Write test output ---------------------------------------------- /
511 #ifdef W3_T38
512  WRITE (ndst,9000) depth,icecoef1,icecoef2,icecoef3,icecoef4
513 #endif
514 
515  ! 2.b Make calculations using Cheng routines ------------------------- /
516 
517  ! --- Input to routine (part 1): 6 ice parameters from single
518  ! precision variables. ---------------------------------------
519 
520  CALL w3ic3wncg_cheng(wn_r, wn_i, cg_ic3, icecoef1, icecoef2, &
521  icecoef3, icecoef4, depth)
522  !
523  ! --- calculate source term --------------------------------------- /
524  ! --- see Remarks section re: array size -------------------------- /
525  IF ( use_cgice==1.0 ) THEN
526  cg_tmp=cg_ic3
527  ELSE
528  cg_tmp=cg
529  ENDIF
530  DO ik=1, nk
531  ! recall that D=S/E=-2*Cg*k_i
532  d1d(ik)= -2.0 * cg_tmp(ik) * wn_i(ik)
533 
534  END DO
535 
536  ELSEIF ( (icecoef1 .LE. maxthk) .OR. (iceconc .LE. maxcnc) ) THEN
537  !.......... e.g. if ice thickness is .le. 10 cm
538  !...............or concentration is .le. 1.0
539  !
540  ! 2.a Write test output ---------------------------------------------- /
541 #ifdef W3_T38
542  WRITE (ndst,9000) depth,icecoef1,icecoef2,icecoef3,icecoef4
543 #endif
544  !
545  ! 2.b Make calculations using original routines ---------------------- /
546  ! --- Input to routine (part 1): 6 ice parameters from single
547  ! precision variables. ---------------------------------------
548 
549  CALL w3ic3wncg_v1(wn_r, wn_i, cg_ic3, icecoef1, icecoef2, &
550  icecoef3, icecoef4, depth )
551  !
552  ! --- calculate source term --------------------------------------- /
553  IF ( use_cgice==1.0 ) THEN
554  cg_tmp=cg_ic3
555  ELSE
556  cg_tmp=cg
557  ENDIF
558  DO ik=1, nk
559  ! recall that D=S/E=-2*Cg*k_i
560  d1d(ik)= -2.0 * cg_tmp(ik) * wn_i(ik)
561  END DO
562  !
563  ELSE ! .. e.g. if ice thickness is .gt. 10 cm
564  ! Alternative by F.A., see Remarks section.
565  IF (ic3pars(2).GT.0.) THEN
566  uorb=0.
567  aorb=0.
568  fturb = ic3pars(2)
569  IF (ic3pars(7).GT.0) THEN
570  IF (ygrd(iy,ix).LT.0.AND.gtype.EQ.rlgtype.AND.flagll) &
571  fturb = ic3pars(7)
572  END IF
573  DO ik=1, nk
574  eb = 0.
575  DO ith=1, nth
576  is=ith+(ik-1)*nth
577  eb = eb + a(is)
578  END DO
579  !
580  ! UORB and AORB are the variances of the orbital
581  ! velocity and surface elevation
582  !
583  uorb = uorb + eb *sig(ik)**2 * dden(ik) / cg(ik)
584  aorb = aorb + eb * dden(ik) / cg(ik)
585  !deep water only
586  END DO
587  !
588  aorb = 2*sqrt(aorb) ! significant amplitude
589  uorb = 2*sqrt(uorb) ! significant amplitude
590 
591  re = uorb*aorb / viscm
592  smooth = 0.5*tanh((re-ic3pars(4))/ic3pars(5))
593  pturb=(0.5+smooth)
594  pvisc=(0.5-smooth)
595 
596  xi=(alog10(max(aorb/ic3pars(3),3.))-abmin)/delab
597  ind = min(sizefwtable-1, int(xi))
598  deli1= min(1. ,xi-float(ind))
599  deli2= 1. - deli1
600  fw =fwtable(ind)*deli2+fwtable(ind+1)*deli1
601  dturb=-1.* fturb*fw*uorb/grav
602  ELSE ! so case of IC3PARS(2).LE.0.
603  dturb = 0.
604  END IF ! IF (IC3PARS(2).GT.0.)
605 
606  DO ik=1, nk
607  dvisc = -1. *ic3pars(6) * wn(ik) * sqrt(viscm* sig(ik) / 2.)
608  d1d(ik) = pturb*dturb*sig(ik)**2 + pvisc*dvisc
609  END DO
610 
611  END IF ! IF ( NOICE ) THEN
612 
613  ! 2.c Fill diagional matrix ------------------------------------------ /
614  !
615  DO ikth=1, nspec
616  d(ikth) = d1d(mapwn(ikth))
617  END DO
618 
619  !
620  ! sign convention (example):
621  ! S is from -10e-3 to 0
622  ! A is from 0 to 10
623  ! See Remarks section re: optimization
624  s = d * a
625  !
626  ! ... Test output of arrays
627  !
628 #ifdef W3_T0
629  DO ik=1, nk
630  DO ith=1, nth
631  dout(ik,ith) = d(ith+(ik-1)*nth)
632  END DO
633  END DO
634  CALL prt2ds (ndst, nk, nk, nth, dout, sig(1:), ' ', 1., &
635  0.0, 0.001, 'Diag Sice', ' ', 'NONAME')
636 #endif
637  !
638 #ifdef W3_T1
639  CALL outmat (ndst, d, nth, nth, nk, 'diag Sice')
640 #endif
641  !
642  ! Formats
643  !
644 1001 FORMAT (/' *** WAVEWATCH III ERROR IN W3SIC3 : '/ &
645  ' ',a,' REQUIRED ONCE, BUT WAS PROVIDED BY USER '/ &
646  ' ',i4,' TIMES.'/)
647  !
648 #ifdef W3_T
649 9000 FORMAT (' TEST W3SIC3 : depth and 4 ice coef. : ',5e10.3)
650 #endif
651  !/
652  !/ End of W3SIC3 ----------------------------------------------------- /
653  !/
654  END SUBROUTINE w3sic3
655  !/ ------------------------------------------------------------------- /
656  !/
657  SUBROUTINE w3ic3wncg_v1(WN_R,WN_I,CG,ICE1,ICE2,ICE3,ICE4,DPT)
658  !/
659  !/ +-----------------------------------+
660  !/ | WAVEWATCH III NOAA/NCEP |
661  !/ | E. Rogers |
662  !/ | S. Zieger |
663  !/ | FORTRAN 90 |
664  !/ | Last update : 25-Oct-2013 |
665  !/ +-----------------------------------+
666  !/
667  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
668  !/ (E. Rogers)
669  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
670  !/
671  ! 1. Purpose :
672  !
673  ! Calculation of complex wavenumber for waves in ice. Outsourced
674  ! from W3SIC3 to allow update on wavenumbers and group
675  ! velocities at each time step an ice parameter is updated.
676  !
677  ! 2. Method :
678  !
679  ! <text here>
680  !
681  ! 3. Parameters :
682  !
683  ! Parameter list
684  ! ----------------------------------------------------------------
685  ! WN_R R. A. I/O Wave number (real part)
686  ! WN_I R. A. I/O Wave number (imag. part=wave attenuation)
687  ! CG R. A. I/O Group velocity
688  ! ICE1 REAL I Thickness of ice [in m]
689  ! ICE2 REAL I Effective viscosity of ice [in m2/s]
690  ! ICE3 REAL I Density of ice [in kg/m3]
691  ! ICE4 REAL I Effective shear modulus of ice [in Pa]
692  ! DPT REAL I Water depth [in m]
693  ! ----------------------------------------------------------------
694  !
695  ! 4. Subroutines used :
696  !
697  ! Name Type Module Description
698  ! ----------------------------------------------------------------
699  ! WAVNU1 Subr. W3DISPMD Wavenumber for waves in open water.
700  ! WN_CMPLX Func. W3SIC3MD Complex wavenumber for waves in ice.
701  ! WN_CMPLX_HF Func. W3SIC3MD Like WN_CMPLX, but for h-f
702  ! ----------------------------------------------------------------
703  !
704  ! 5. Called by :
705  !
706  ! Name Type Module Description
707  ! ----------------------------------------------------------------
708  ! W3SIC3 Subr. W3SIC3MD Ice source term.
709  ! ----------------------------------------------------------------
710  !
711  ! 6. Error messages :
712  !
713  ! See FORMAT 900.
714  !
715  ! 7. Remarks :
716  !
717  ! Optional: Cap WN_I at 2.0E-4, since in simple tests with "normal
718  ! resolution" (not finer than 1 km), WW3 has trouble resolving the
719  ! dissipation if k_i>2e-4. Also, very large values of dissipation
720  ! (e.g. k_i=100e-4) with IC3 occurs more in the higher frequencies
721  ! which makes WW3 slow down quite a bit. This is done via ICEKILIM
722  ! in the namelists.
723  !
724  ! This function does not get used in update by S. Cheng.
725  ! It should be removed if/when "V1" routines are removed.
726  !
727  ! 8. Structure :
728  !
729  ! See source code.
730  !
731  ! 9. Source code :
732  !/
733  !/ ------------------------------------------------------------------- /
734  !/
735  USE w3gdatmd, ONLY: nk, sig, ic3pars
736  USE w3dispmd, ONLY: wavnu1
737  USE w3odatmd, ONLY: ndse
738  USE w3servmd, ONLY: extcde
739  USE constants, ONLY: tpi
740  !/
741  IMPLICIT NONE
742  !/
743  REAL, INTENT(INOUT):: wn_r(:),wn_i(:),cg(:)
744  REAL, INTENT(IN) :: ice1, ice2, ice3, ice4, dpt
745 
746  INTEGER :: ik, kl,ku
747  REAL, ALLOCATABLE :: sigma(:),cg_ic3(:)
748  REAL :: k_ocean, cg_ocean
749  DOUBLE PRECISION :: kh, k_noice, hwat, hice, nu, dice, es_mod
750  DOUBLE PRECISION,PARAMETER :: khmax = 18.0d0 ! 18=OK, 19=fails
751  DOUBLE COMPLEX :: wncomplex,wncomplex_old
752  REAL :: stensec
753  REAL :: ic3hilim,ic3kilim
754  !
755  ALLOCATE( cg_ic3( SIZE(cg) ) )
756  ALLOCATE( sigma( SIZE(cg) ) )
757  cg_ic3 = 0.
758  sigma = 0.
759  stensec=tpi/10.0 ! sigma for T=10 sec
760 
761  ic3hilim=ic3pars(10)
762  ic3kilim=ic3pars(11)
763  !
764  ! --- Input to routine (part 1): set 6 double precision variables
765  ! using single precision variables. -------------------------- /
766  hwat = dble(dpt) ! water depth
767  hice = dble(ice1) ! ice thickness
768  nu = dble(ice2) ! "effective viscosity" parameter
769  dice = dble(ice3) ! density of ice
770  es_mod = dble(ice4) ! effective shear modulus of ice
771 
772  ! Optional: limit ice thickness
773  hice=min(dble(ic3hilim),hice)
774 
775  IF (SIZE(wn_r,1).EQ.nk) THEN
776  kl = 1
777  ku = nk
778  sigma = sig(1:nk)
779  ELSE IF (SIZE(wn_r,1).EQ.nk+2) THEN
780  kl = 1
781  ku = nk+2
782  sigma = sig(0:nk+1)
783  ELSE
784  WRITE(ndse,900)
785  CALL extcde(3)
786  END IF
787  !
788  wncomplex_old=cmplx(0.0d0,0.0d0)
789 
790  DO ik = kl,ku
791  ! --- Input to routine (part 2): set 2 double precision variables
792  ! using single precision variable. --------------------------- /
793  CALL wavnu1(sigma(ik),dpt,k_ocean,cg_ocean)
794  k_noice = dble(k_ocean)
795  !
796  ! --- Muller Method fails for deep water: workaround follows ----- /
797  kh = k_noice * hwat ! kh w/out ice
798  IF (kh.GT.khmax) THEN
799  hwat = khmax / k_noice
800  ENDIF
801  ! --- Calculate complex wavenumber ------------------------------- /
802 
803  IF((ik.GT.kl).AND.(sigma(ik).GT.stensec))THEN
804 
805  wncomplex = wn_cmplx_hf(dble(sigma(ik)),k_noice,es_mod,nu, &
806  dice,hice,hwat,dble(sigma(ik-1)),wncomplex_old)
807  wncomplex_old=wncomplex
808 
809  ELSE
810 
811  wncomplex = wn_cmplx_v1(dble(sigma(ik)),k_noice,es_mod,nu, &
812  dice,hice,hwat)
813  wncomplex_old=wncomplex
814 
815  ENDIF
816 
817  ! --- Output from function is type of DOUBLE COMPLEX. Set
818  ! precision of imaginary to single precision array element --- /
819  wn_i(ik) = real(aimag(wncomplex))
820 
821  ! Optional : limit ki
822  wn_i(ik) = min(wn_i(ik),ic3kilim) ! see Remarks above
823  wn_r(ik) = real(wncomplex)
824 
825  END DO
826  ! --- Update group velocitiy ----
827  cg_ic3 = delta(sigma) / delta(wn_r)
828  cg = cg_ic3
829 
830  DEALLOCATE(cg_ic3)
831  !
832 900 FORMAT (/' *** WAVEWATCH III ERROR IN W3SIC3_W3IC3WNCG : '/&
833  ' CANNOT DETERMINE BOUNDS OF WAVENUMBER ARRAY.')
834  !
835  !/
836  END SUBROUTINE w3ic3wncg_v1
837  !/ ------------------------------------------------------------------- /
838  !/
839  FUNCTION wn_cmplx_v1(SIGMA,WN_O,ES,NU,DICE,HICE,DEPTH) RESULT(WN)
840  !/
841  !/ +-----------------------------------+
842  !/ | WAVEWATCH III NOAA/NCEP |
843  !/ | E. Rogers |
844  !/ | S. Zieger |
845  !/ | FORTRAN 90 |
846  !/ | Last update : 30-Oct-2013 |
847  !/ +-----------------------------------+
848  !/
849  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
850  !/ (E. Rogers)
851  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
852  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
853  !/
854  ! 1. Purpose :
855  !
856  ! Calculate complex wavenumber for waves in ice.
857  !
858  ! 2. Method :
859  !
860  ! Wang and Shen (JGR 2010)
861  !
862  ! 3. Parameters :
863  !
864  ! Parameter list
865  ! ----------------------------------------------------------------
866  ! WN CMPLX DBL O Wave number (imag. part=wave attenuation)
867  ! SIGMA REAL DBL I Wave angular frequency [in rad]
868  ! WN_O REAL DBL I Wave number (open water)
869  ! ES REAL DBL I Effective shear modulus of ice [in Pa]
870  ! NU REAL DBL I Effective viscosity of ice [in m2/s]
871  ! DICE REAL DBL I Density of ice [in kg/m3]
872  ! HICE REAL DBL I Thickness of ice [in m]
873  ! DEPTH REAL DBL I Water depth [in m]
874  ! ----------------------------------------------------------------
875  !
876  ! 4. Subroutines used :
877  !
878  ! Name Type Module Description
879  ! ----------------------------------------------------------------
880  ! CMPLX_ROOT_MULLER_CHENG Func. W3SIC3MD Find root for complex
881  ! wavenumbers for waves in ice.
882  ! ----------------------------------------------------------------
883  !
884  ! 5. Called by :
885  !
886  ! Name Type Module Description
887  ! ----------------------------------------------------------------
888  ! W3IC3WNCG_V1 Subr. W3SIC3MD Ice source term.
889  ! ----------------------------------------------------------------
890  !
891  ! 6. Error messages :
892  !
893  ! 7. Remarks :
894  !
895  ! Original authors: Zhao and Shen.
896  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
897  ! University) to Erick Rogers (NRL) on April 19 2013.
898  !
899  ! Hayley Shen says,
900  ! We have determined that it may not be necessary to use curve
901  ! fitting or lookup tables to get the group velocity and the
902  ! attenuation coefficient. Attached is a short report with some
903  ! sample numerical solutions. To implement the viscoelastic model,
904  ! there are 4 fortran programs. According to Xin Zhao, the graduate
905  ! student, it is very fast to find roots. I suggest that perhaps you
906  ! try the pure viscous case by setting G=0 to start with. nu can be
907  ! set at 0.05*ice concentration (m^2/s) to begin with, because for
908  ! grease ice Newyear's data showed nu to be about 0.02-0.03 m^2/s.
909  ! By setting G=0 in you get exactly the Keller model for pure
910  ! viscous layer.
911  !
912  ! This routine provides the initial guess according to the parameters
913  ! of the present case. T>10s use open water, T<10s cases, calculate
914  ! T=10s first using open water as the initial guess.
915  !
916  ! 8. Structure :
917  !
918  ! See source code.
919  !
920  ! 9. Switches :
921  !
922  ! 10. Source code :
923  !
924  !/ ------------------------------------------------------------------- /
925  USE constants, ONLY: tpi
926  !/
927  IMPLICIT NONE
928  !/
929  !/ ------------------------------------------------------------------- /
930  !/ Parameter list
931  !/
932  DOUBLE PRECISION, INTENT(IN) :: sigma,wn_o,es,nu,dice,hice,depth
933  DOUBLE COMPLEX :: wn ! RESULT
934  !/
935  !/ ------------------------------------------------------------------- /
936  !/ Local parameters
937  !/
938  INTEGER :: i, nsub
939  DOUBLE PRECISION :: tt, ts, t
940  DOUBLE COMPLEX :: x0, x1, x2, wn0
941  !/
942  !/ ------------------------------------------------------------------- /
943  t = dble(tpi) / sigma
944  ts = 10.
945  nsub = int((ts-t) * 10.)
946  !/
947  IF (hice<0.001) THEN
948  wn = cmplx(wn_o,0.)
949  ELSE IF (t.LT.ts) THEN
950  x0 = 0.01
951  x1 = 0.1
952  x2 = 1.0
953  wn0 = cmplx_root_muller_v1(x0,x1,x2,0,dble(tpi)/ts, &
954  es,nu,dice,hice,depth )
955  x0 = 0.90 * wn0
956  x1 = wn0
957  x2 = 1.1*wn0
958  wn = cmplx_root_muller_v1(x0,x1,x2,1,dble(tpi)/ts, &
959  es,nu,dice,hice,depth )
960  DO i=1,nsub
961  x0 = 0.90 * wn
962  x1 = wn
963  x2 = 1.1 * wn
964  tt = ts - (ts-t) / real(nsub) * real(i)
965  wn = cmplx_root_muller_v1(x0,x1,x2,1,dble(tpi)/tt, &
966  es,nu,dice,hice,depth )
967  ENDDO
968  ELSE
969  x0 = 0.01
970  x1 = 0.1
971  x2 = 1.0
972  wn0 = cmplx_root_muller_v1(x0,x1,x2,0,sigma, &
973  es,nu,dice,hice,depth )
974  x0 = 0.8 * wn0
975  x1 = wn0
976  x2 = 1.2 * wn0
977  wn = cmplx_root_muller_v1(x0,x1,x2,1,sigma, &
978  es,nu,dice,hice,depth )
979  ENDIF
980  !/
981  END FUNCTION wn_cmplx_v1
982  !/ ------------------------------------------------------------------- /
983  !/
984  FUNCTION wn_cmplx_hf(SIGMA,WN_O,ES,NU,DICE,HICE,DEPTH,SIGMA_LAST, &
985  WN_LAST) RESULT(WN)
986  !/
987  !/ +-----------------------------------+
988  !/ | WAVEWATCH III NOAA/NCEP |
989  !/ | H. Shen |
990  !/ | E. Rogers |
991  !/ | FORTRAN 90 |
992  !/ | Last update : 17-Apr-2014 |
993  !/ +-----------------------------------+
994  !/
995  !/ 15-Jan-2014 : Origination (from WN_CMPLXA.f90) (H. Shen)
996  !/ 17-Apr-2014 : Import to WW3 (E. Rogers)
997  !/
998  ! 1. Purpose :
999  !
1000  ! Calculate complex wavenumber for waves in ice.
1001  !
1002  ! 2. Method :
1003  !
1004  ! Wang and Shen (JGR 2010)
1005  !
1006  ! 3. Parameters :
1007  !
1008  ! Parameter list
1009  ! ----------------------------------------------------------------
1010  ! WN CMPLX DBL O Wave number (imag. part=wave attenuation)
1011  ! SIGMA REAL DBL I Wave angular frequency [in rad]
1012  ! WN_O REAL DBL I Wave number (open water)
1013  ! ES REAL DBL I Effective shear modulus of ice [in Pa]
1014  ! NU REAL DBL I Effective viscosity of ice [in m2/s]
1015  ! DICE REAL DBL I Density of ice [in kg/m3]
1016  ! HICE REAL DBL I Thickness of ice [in m]
1017  ! DEPTH REAL DBL I Water depth [in m]
1018  ! SIGMA_LAST REAL DBL I : Like SIGMA, but of last IK
1019  ! WN_LAST REAL DBL I : WN_O of last IK
1020  ! ----------------------------------------------------------------
1021  !
1022  ! 4. Subroutines used :
1023  !
1024  ! Name Type Module Description
1025  ! ----------------------------------------------------------------
1026  ! CMPLX_ROOT_MULLER_CHENG Func. W3SIC3MD Find root for complex
1027  ! wavenumbers for waves in ice.
1028  ! ----------------------------------------------------------------
1029  !
1030  ! 5. Called by :
1031  !
1032  ! Name Type Module Description
1033  ! ----------------------------------------------------------------
1034  ! W3IC3WNCG_V1 Subr. W3SIC3MD Ice source term.
1035  ! ----------------------------------------------------------------
1036  !
1037  ! 6. Error messages :
1038  !
1039  ! 7. Remarks :
1040  !
1041  ! Original authors: Zhao and Shen.
1042  ! See notes in FUNCTION WN_CMPLX, not repeated here.
1043  ! New in this function, Hayley Shen says (Jan 15 2014) :
1044  ! "To speed up the computation, we need to add a new function
1045  ! WN_CMPLXA (attached) into the earlier version of the MODULE
1046  ! W3SIC3MD. When wave period T>=10s, we call old function WN_CMPLX
1047  ! directly. When T<10s, call the new function WN_CMPLXA with last
1048  ! calculation step's information: last complex wave number, last
1049  ! angular wave frequency. The calculation should be from large T
1050  ! to small T."
1051  !
1052  ! 8. Structure :
1053  !
1054  ! See source code.
1055  !
1056  ! 9. Switches :
1057  !
1058  ! 10. Source code :
1059  !
1060  USE constants, ONLY: tpi
1061  !/
1062  IMPLICIT NONE
1063  !/
1064  !/ ------------------------------------------------------------------- /
1065  !/ Parameter list
1066  !/
1067  DOUBLE PRECISION, INTENT(IN) :: sigma,wn_o,es,nu,dice,hice,depth
1068  DOUBLE PRECISION, INTENT(IN) :: sigma_last
1069  DOUBLE COMPLEX, INTENT(IN) :: wn_last
1070  DOUBLE COMPLEX :: wn ! RESULT
1071  !/
1072  !/ ------------------------------------------------------------------- /
1073  !/ Local parameters
1074  !/
1075  INTEGER :: i, nsub
1076  DOUBLE PRECISION :: tt, ts, t
1077  DOUBLE COMPLEX :: x0, x1, x2, wn0
1078  !/
1079  !/ ------------------------------------------------------------------- /
1080  t = dble(tpi) / sigma
1081  ts = dble(tpi) / sigma_last
1082  nsub = int((ts-t) * 10.)
1083  !/
1084  IF (hice<0.001) THEN
1085  wn = cmplx(wn_o,0.)
1086  ELSE
1087  x0 = 0.90 * wn_last
1088  x1 = wn_last
1089  x2 = 1.1 * wn_last
1090  wn = cmplx_root_muller_v1(x0,x1,x2,1,dble(tpi)/ts, &
1091  es,nu,dice,hice,depth )
1092  DO i=1,nsub
1093  x0 = 0.90 * wn
1094  x1 = wn
1095  x2 = 1.1 * wn
1096  tt = ts - (ts-t) / real(nsub) * real(i)
1097  wn = cmplx_root_muller_v1(x0,x1,x2,1,dble(tpi)/tt, &
1098  es,nu,dice,hice,depth )
1099  ENDDO
1100  ENDIF
1101  !/
1102  END FUNCTION wn_cmplx_hf
1103  !/ ------------------------------------------------------------------- /
1104  !/ ------------------------------------------------------------------- /
1105  !/
1106  FUNCTION cmplx_root_muller_v1(X0, X1, X2, JUDGE, SIGMA, ES, NU, &
1107  DICE, HICE, DEPTH) RESULT(P3)
1108  !/
1109  !/ +-----------------------------------+
1110  !/ | WAVEWATCH III NOAA/NCEP |
1111  !/ | E. Rogers |
1112  !/ | S. Zieger |
1113  !/ | FORTRAN 90 |
1114  !/ | Last update : 30-Oct-2013 |
1115  !/ +-----------------------------------+
1116  !/
1117  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
1118  !/ (E. Rogers)
1119  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
1120  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
1121  !/
1122  ! 1. Purpose :
1123  !
1124  ! Find root.
1125  !
1126  ! 2. Method :
1127  !
1128  ! Muller method for complex equations is a recursive approximation
1129  ! with initial guess X0, X1, and X2. To the initial guesses a
1130  ! quadratic parabola is fitted.
1131  !
1132  ! 3. Parameters :
1133  !
1134  ! Parameter list
1135  ! ----------------------------------------------------------------
1136  ! P3 CMPLX DBL O Approximation for the root problem
1137  ! X0 CMPLX DBL I Initial guess variable
1138  ! X1 CMPLX DBL I Initial guess variable
1139  ! X2 CMPLX DBL I Initial guess variable
1140  ! JUDGE INTEGER I "switch variable" for F_ZHAO
1141  ! SIGMA DOUBLE I Wave angular frequency
1142  ! ES DOUBLE I Effective shear modulus of ice
1143  ! NU DOUBLE I Effective viscosity of ice [in m2/s]
1144  ! DICE DOUBLE I Density of ice [in kg/m3]
1145  ! HICE DOUBLE I Thickness of ice [in m]
1146  ! DEPTH DOUBLE I Water depth [in m]
1147  ! ----------------------------------------------------------------
1148  !
1149  ! 4. Subroutines used :
1150  ! Name Type Module Description
1151  ! ----------------------------------------------------------------
1152  ! F_ZHAO Func. W3SIC3MD Wrapper function for root finding.
1153  ! ----------------------------------------------------------------
1154  !
1155  ! 5. Called by :
1156  !
1157  ! Name Type Module Description
1158  ! ----------------------------------------------------------------
1159  ! WN_CMPLX_V1 Find root for complex wave-
1160  ! WN_CMPLX_HF numbers for waves in ice.
1161  ! ----------------------------------------------------------------
1162  !
1163  ! 6. Error messages :
1164  !
1165  ! 7. Remarks :
1166  !
1167  ! Original authors: Zhao and Shen.
1168  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
1169  ! University) to Erick Rogers (NRL) on April 19 2013.
1170  !
1171  ! 8. Structure :
1172  !
1173  ! See source code.
1174  !
1175  ! 9. Switches :
1176  !
1177  ! 10. Source code :
1178  !
1179  !/ ------------------------------------------------------------------- /
1180  USE w3odatmd, ONLY: ndse
1181  USE w3servmd, ONLY: extcde
1182  !/
1183  IMPLICIT NONE
1184  !/
1185  !/ ------------------------------------------------------------------- /
1186  !/ Parameter list
1187  !/
1188  DOUBLE COMPLEX :: p3 ! RESULT
1189  DOUBLE COMPLEX, INTENT(IN) :: x0,x1,x2
1190  DOUBLE PRECISION, INTENT(IN) :: sigma,es,nu,dice,hice,depth
1191  INTEGER, INTENT(IN) :: judge
1192  !/
1193  !/ ------------------------------------------------------------------- /
1194  !/ Local parameters
1195  !/
1196  INTEGER :: i
1197  INTEGER, PARAMETER :: imax = 1000
1198  DOUBLE PRECISION :: dlta,epsi
1199  DOUBLE COMPLEX :: p0,p1,p2
1200  DOUBLE COMPLEX :: y0,y1,y2,y3
1201  DOUBLE COMPLEX :: a,b,c,q,disc,den1,den2
1202  !/
1203  !/ ------------------------------------------------------------------- /
1204  p0 = x0
1205  p1 = x1
1206  p2 = x2
1207  p3 = 0.0
1208  !
1209  i = 0
1210  epsi = 1.e-5
1211  dlta = 1.e-5
1212  y0 = f_zhao_v1(p0,judge,sigma,es,nu,dice,hice,depth)
1213  y1 = f_zhao_v1(p1,judge,sigma,es,nu,dice,hice,depth)
1214  y2 = f_zhao_v1(p2,judge,sigma,es,nu,dice,hice,depth)
1215  !
1216  DO i = 1,imax
1217  q = (p2 - p1) / (p1 - p0)
1218  a = q * y2 - q * (1.+q) * y1 + q**2. * y0
1219  b = (2. * q + 1.) * y2 - (1 + q)**2. * y1 + q**2. * y0
1220  c = (1. + q) * y2
1221  !
1222  IF ( abs(a).NE.0. ) THEN
1223 
1224  disc = b**2. - 4 * a * c;
1225  !
1226  den1 = ( b + sqrt( disc ) )
1227  den2 = ( b - sqrt( disc ) )
1228  !
1229  IF ( abs( den1 ) .LT. abs( den2 ) )THEN
1230  p3 = p2 - (p2 - p1) * (2 * c / den2)
1231  ELSE
1232  p3 = p2 - (p2 - p1) * (2 * c / den1)
1233  ENDIF
1234  !
1235  ELSE
1236  !
1237  IF ( abs(b) .NE. 0. )THEN
1238  p3 = p2 - (p2 - p1) * (c / b)
1239  ELSE
1240  WRITE(ndse,800)
1241  WRITE(ndse,801)x0,x1,x2
1242  WRITE(ndse,802)sigma,es,nu,dice,hice,depth
1243  WRITE(ndse,803)judge
1244  CALL extcde(2)
1245  ENDIF
1246  ENDIF
1247 
1248  y3 = f_zhao_v1(p3,judge,sigma,es,nu,dice,hice,depth);
1249 
1250  IF ( abs(p3-p2).LT.dlta .OR. abs(y3).LT.epsi ) THEN
1251  RETURN
1252  ENDIF
1253 
1254  p0 = p1
1255  p1 = p2
1256  p2 = p3
1257 
1258  y0 = y1
1259  y1 = y2
1260  y2 = y3
1261 
1262  ENDDO
1263  !
1264  WRITE(ndse,800)
1265  WRITE(ndse,801)x0,x1,x2
1266  WRITE(ndse,802)sigma,es,nu,dice,hice,depth
1267  WRITE(ndse,803)judge
1268  CALL extcde(2)
1269  !
1270 800 FORMAT (/' *** WAVEWATCH III ERROR IN W3SIC3_CMPLX_ROOT_MULLER'/&
1271  ' : MULLER METHOD FAILED TO FIND ROOT.' )
1272 801 FORMAT (/'X0,X1,X2 = ',3(1x,'(',f10.5,',',f10.5,')'))
1273 802 FORMAT (/'SIGMA,ES,NU,DICE,HICE,DEPTH = ',6(1x,f10.5))
1274 803 FORMAT (/'JUDGE = ',i5)
1275  !/
1276  END FUNCTION cmplx_root_muller_v1
1277  !/ ------------------------------------------------------------------- /
1278  !/
1279  FUNCTION f_zhao_v1(X,JUDGE,SIGMA,ES,NU,DICE,HICE,DEPTH) &
1280  result(fzhao)
1281  !/
1282  !/ +-----------------------------------+
1283  !/ | WAVEWATCH III NOAA/NCEP |
1284  !/ | E. Rogers |
1285  !/ | S. Zieger |
1286  !/ | FORTRAN 90 |
1287  !/ | Last update : 30-Oct-2013 |
1288  !/ +-----------------------------------+
1289  !/
1290  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
1291  !/ (E. Rogers)
1292  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
1293  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
1294  !/
1295  ! 1. Purpose :
1296  !
1297  ! Decide whether to call sub-function.
1298  !
1299  ! 2. Method :
1300  !
1301  ! Decide based on value of integer "JUDGE"
1302  !
1303  ! 3. Parameters :
1304  !
1305  ! Parameter list
1306  ! ----------------------------------------------------------------
1307  ! FZHAO COMPL8 O Result (double complex)
1308  ! X CMPLX8 I Approximate result (double complex)
1309  ! JUDGE INTEGR I Switch variable
1310  ! SIGMA DOUBLE I Wave angular frequency
1311  ! ES DOUBLE I Effective shear modulus
1312  ! NU DOUBLE I Effective viscosity parameter
1313  ! DICE DOUBLE I Density of ice
1314  ! HICE DOUBLE I Thickness of ice
1315  ! DEPTH DOUBLE I Water depth
1316  ! ----------------------------------------------------------------
1317  !
1318  ! 4. Subroutines used :
1319  !
1320  ! Name Type Module Description
1321  ! ----------------------------------------------------------------
1322  ! FUNC0_ZHAO Func. W3SIC3MD Function to find root.
1323  ! FUNC1_ZHAO Func. W3SIC3MD Function to find root.
1324  ! ----------------------------------------------------------------
1325  !
1326  ! 5. Called by :
1327  !
1328  ! Name Type Module Description
1329  ! ----------------------------------------------------------------
1330  ! CMPLX_ROOT_MULLER_V1 Func. W3SIC3MD Find root for complex wave-
1331  ! numbers for waves in ice.
1332  ! ----------------------------------------------------------------
1333  !
1334  ! 6. Error messages :
1335  !
1336  ! 7. Remarks :
1337  !
1338  ! Original authors: Zhao and Shen.
1339  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
1340  ! University) to Erick Rogers (NRL) on April 19 2013.
1341  !
1342  ! 8. Structure :
1343  !
1344  ! See source code.
1345  !
1346  ! 9. Switches :
1347  !
1348  ! 10. Source code :
1349  !/
1350  !/ ------------------------------------------------------------------- /
1351  !/
1352  IMPLICIT NONE
1353  !/
1354  !/ ------------------------------------------------------------------- /
1355  !/ Parameter list
1356  !/
1357  INTEGER, INTENT(IN) :: judge
1358  DOUBLE PRECISION, INTENT(IN) :: sigma,es,nu,dice,hice,depth
1359  DOUBLE COMPLEX, INTENT(IN) :: x
1360  DOUBLE COMPLEX :: fzhao ! RESULT
1361  !/
1362  !/ ------------------------------------------------------------------- /
1363  IF (judge.EQ.0) THEN
1364  fzhao = func0_zhao(x,sigma,depth)
1365  ELSE
1366  fzhao = func1_zhao(x,sigma,es,nu,dice,hice,depth)
1367  ENDIF
1368  !
1369  END FUNCTION f_zhao_v1
1370  !/ ------------------------------------------------------------------- /
1371  !/
1372  FUNCTION func0_zhao(WN, SIGMA, DEPTH) RESULT(FUNC0)
1373  !/
1374  !/ +-----------------------------------+
1375  !/ | WAVEWATCH III NOAA/NCEP |
1376  !/ | E. Rogers |
1377  !/ | S. Zieger |
1378  !/ | FORTRAN 90 |
1379  !/ | Last update : 30-Oct-2013 |
1380  !/ +-----------------------------------+
1381  !/
1382  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
1383  !/ (E. Rogers)
1384  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
1385  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
1386  !/
1387  ! 1. Purpose :
1388  !
1389  ! Calculate the difference between the left and right side
1390  ! of the dispersion relation. It is called by the Muller method.
1391  !
1392  ! 2. Method :
1393  !
1394  ! <text here>
1395  !
1396  ! 3. Parameters :
1397  !
1398  ! Parameter list
1399  ! ----------------------------------------------------------------
1400  ! FUNC0 COMPL DBL O Result (double complex)
1401  ! WN CMPLX DBL I Complex wavenumber
1402  ! SIGMA DOUBLE I Wave angular frequency
1403  ! DEPTH DOUBLE I Water depth [in m]
1404  ! ----------------------------------------------------------------
1405  !
1406  ! 4. Subroutines used :
1407  !
1408  ! 5. Called by :
1409  !
1410  ! Name Type Module Description
1411  ! ----------------------------------------------------------------
1412  ! F_ZHAO_V1 Func. W3SIC3MD Function for computation of complex
1413  ! wavenumbers for waves in ice.
1414  ! ----------------------------------------------------------------
1415  !
1416  ! 6. Error messages :
1417  !
1418  ! 7. Remarks :
1419  !
1420  ! Original authors: Zhao and Shen.
1421  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
1422  ! University) to Erick Rogers (NRL) on April 19 2013.
1423  !
1424  ! This function does not get used in update by S. Cheng.
1425  ! It should be removed if/when "V1" routines are removed.
1426  !
1427  ! 8. Structure :
1428  !
1429  ! See source code.
1430  !
1431  ! 9. Switches :
1432  !
1433  ! 10. Source code :
1434  !
1435  !/
1436  !/ ------------------------------------------------------------------- /
1437  USE constants, ONLY: grav
1438  !/
1439  IMPLICIT NONE
1440  !/
1441  !/ ------------------------------------------------------------------- /
1442  !/ Parameter list
1443  !/
1444  DOUBLE COMPLEX, INTENT(IN) :: wn
1445  DOUBLE PRECISION, INTENT(IN) :: sigma, depth
1446  DOUBLE COMPLEX :: func0 ! RESULT
1447  !/
1448  !/ ------------------------------------------------------------------- /
1449  !/ Local parameters
1450  !/
1451  DOUBLE COMPLEX :: th
1452  !/
1453  !/ ------------------------------------------------------------------- /
1454  IF (real(wn*depth).LE.4.) THEN
1455  th = (exp(wn*depth)-exp(-wn*depth)) &
1456  / (exp(wn*depth)+exp(-wn*depth))
1457  func0 = sigma**2. - th * wn * dble(grav)
1458  ELSE
1459  func0 = sigma**2. - wn * dble(grav)
1460  END IF
1461  !/
1462  END FUNCTION func0_zhao
1463  !/ ------------------------------------------------------------------- /
1464  !/
1465  FUNCTION func1_zhao(WN,SIGMA,ES,NU,DICE,HICE,DEPTH) RESULT(FUNC1)
1466  !/
1467  !/ +-----------------------------------+
1468  !/ | WAVEWATCH III NOAA/NCEP |
1469  !/ | E. Rogers |
1470  !/ | S. Zieger |
1471  !/ | FORTRAN 90 |
1472  !/ | Last update : 11-Oct-2013 |
1473  !/ +-----------------------------------+
1474  !/
1475  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
1476  !/ (E. Rogers)
1477  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
1478  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
1479  !/
1480  ! 1. Purpose :
1481  !
1482  ! <text here>
1483  !
1484  ! 2. Method :
1485  !
1486  ! <text here>
1487  !
1488  ! 3. Parameters :
1489  !
1490  ! Parameter list
1491  ! ----------------------------------------------------------------
1492  ! FUNC1 CMPLX DBL O Result (double complex)
1493  ! WN CMPLX DBL I Wavenumber (double complex)
1494  ! W REAL DBL I Wave angular frequency
1495  ! ES REAL DBL I Effective shear modulus on ice
1496  ! NU REAL DBL I Effective viscosity
1497  ! DICE REAL DBL I Density of ice
1498  ! HICE REAL DBL I Thickness of ice
1499  ! DEPTH REAL DBL I Water depth
1500  ! ----------------------------------------------------------------
1501  !
1502  ! 4. Subroutines used :
1503  !
1504  ! Name Type Module Description
1505  ! ----------------------------------------------------------------
1506  ! BSDET Func. W3SIC3MD Calculates the determinant for the
1507  ! dispersion relation.
1508  ! ----------------------------------------------------------------
1509  !
1510  ! 5. Called by :
1511  !
1512  ! Name Type Module Description
1513  ! ----------------------------------------------------------------
1514  ! F_ZHAO_V1 Func. W3SIC3MD Function for computation of complex
1515  ! wavenumbers for waves in ice.
1516  ! ----------------------------------------------------------------
1517  !
1518  ! 6. Error messages :
1519  !
1520  ! 7. Remarks :
1521  !
1522  ! Original authors: Zhao and Shen.
1523  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
1524  ! University) to Erick Rogers (NRL) on April 19 2013.
1525  !
1526  ! This function does not get used in update by S. Cheng.
1527  ! It should be removed if/when "V1" routines are removed.
1528  !
1529  ! 8. Structure :
1530  !
1531  ! See source code.
1532  !
1533  ! 9. Switches :
1534  !
1535  ! 10. Source code :
1536  !/
1537  !/ ------------------------------------------------------------------- /
1538  USE constants, ONLY: grav, dwat
1539  !/
1540  IMPLICIT NONE
1541  !/
1542  !/ ------------------------------------------------------------------- /
1543  !/ Parameter list
1544  !/
1545  DOUBLE COMPLEX, INTENT(IN) :: wn
1546  DOUBLE PRECISION, INTENT(IN) :: sigma, es, nu, dice, hice, depth
1547  DOUBLE COMPLEX :: func1 ! RESULT
1548  !/
1549  !/ ------------------------------------------------------------------- /
1550  !/ Local parameters
1551  !/
1552  DOUBLE COMPLEX :: ve,alpha,n,m,l,sk,ck,sa,ca,th,thh
1553  DOUBLE COMPLEX :: aa(4,4)
1554  !/
1555  !/ ------------------------------------------------------------------- /
1556  ve = cmplx( nu, es/dice/sigma )
1557  alpha = sqrt( wn**2. - sigma/ve * cmplx(0.,1.) )
1558  n = sigma + 2. * ve * wn**2. * cmplx(0.,1.)
1559  l = 2 * wn * alpha * sigma * ve
1560  sk = (exp(wn*hice)-exp(-wn*hice))/2.
1561  ck = (exp(wn*hice)+exp(-wn*hice))/2.
1562  sa = (exp(alpha*hice)-exp(-alpha*hice))/2.
1563  ca = (exp(alpha*hice)+exp(-alpha*hice))/2.
1564  !
1565  IF (real(wn*depth).LE.4.) THEN
1566  th = (exp(wn*depth)-exp(-wn*depth)) &
1567  / (exp(wn*depth)+exp(-wn*depth))
1568  thh = ( exp(wn*(depth-hice)) - exp(-wn*(depth-hice)) ) &
1569  / ( exp(wn*(depth-hice)) + exp(-wn*(depth-hice)) )
1570  ELSE
1571  th = 1.0
1572  thh = 1.0
1573  END IF
1574  !
1575  m = (dble(dwat)/dice - 1) * dble(grav) * wn &
1576  - dble(dwat) / dice * sigma**2 / th
1577  !
1578  IF (es.GT.1.e7) THEN
1579  aa(1,1) = 0.
1580  aa(1,2) = 2 * cmplx(0.,1.) * wn**2.
1581  aa(1,3) = alpha**2. + wn**2.
1582  aa(1,4) = 0.
1583  !
1584  aa(2,1) = n * sigma
1585  aa(2,2) = -wn * dble(grav)
1586  aa(2,3) = cmplx(0.,1.) * wn * dble(grav)
1587  aa(2,4) = l
1588  !
1589  aa(3,1) = -2. * cmplx(0.,1.) * wn**2. * sk
1590  aa(3,2) = 2. * cmplx(0.,1.) * wn**2. * ck
1591  aa(3,3) = (alpha**2. + wn**2.) * ca
1592  aa(3,4) = -(alpha**2. + wn**2.) * sa
1593  !
1594  aa(4,1) = n * sigma * ck - m * sk
1595  aa(4,2) = - n * sigma * sk + m * ck
1596  aa(4,3) = -cmplx(0.,1.) * m * ca - l * sa
1597  aa(4,4) = cmplx(0.,1.) * m * sa + l * ca
1598  !
1599  func1 = bsdet(aa,4)
1600  ELSE
1601  func1 = sigma**2. - th*wn*dble(grav) - th*dice/dble(dwat)* &
1602  (wn**2.*dble(grav)**2.*sk*sa - (n**4. + 16.* &
1603  ve**4.*wn**6.*alpha**2.)*sk*sa - 8. &
1604  *wn**3.*alpha*ve**2.*n**2.*(ck*ca-1.))/(4.*wn**3. &
1605  *alpha*ve**2.*sk*ca+n**2.*sa*ck-dble(grav)*wn*sk*sa)
1606  ENDIF
1607  !/
1608  END FUNCTION func1_zhao
1609  !/ ------------------------------------------------------------------- /
1610  !/
1611  FUNCTION bsdet(AA, N) RESULT(DET)
1612  !/
1613  !/ +-----------------------------------+
1614  !/ | WAVEWATCH III NOAA/NCEP |
1615  !/ | E. Rogers |
1616  !/ | S. Zieger |
1617  !/ | FORTRAN 90 |
1618  !/ | Last update : 11-Oct-2013 |
1619  !/ +-----------------------------------+
1620  !/
1621  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
1622  !/ (E. Rogers)
1623  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
1624  !/
1625  ! 1. Purpose :
1626  !
1627  ! This subroutine calculates the determinant for the
1628  ! dispersion relation.
1629  !
1630  ! 2. Method :
1631  !
1632  ! 3. Parameters :
1633  !
1634  ! Parameter list
1635  ! ----------------------------------------------------------------
1636  ! AA R.A. I/O Square array type of REAL
1637  ! N INT I Size of array (number of rows/cols)
1638  ! DET CMPLX DBLE I/O Determinant (double complex)
1639  ! ----------------------------------------------------------------
1640  !
1641  ! 4. Subroutines used :
1642  !
1643  ! 5. Called by :
1644  !
1645  ! Name Type Module Description
1646  ! ----------------------------------------------------------------
1647  ! FUNC1_ZHAO Func. W3SIC3MD Function for computation of complex
1648  ! wavenumbers for waves in ice.
1649  ! ----------------------------------------------------------------
1650  !
1651  ! 6. Error messages :
1652  !
1653  ! 7. Remarks :
1654  !
1655  ! Original authors: Zhao and Shen.
1656  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
1657  ! University) to Erick Rogers (NRL) on April 19 2013.
1658  !
1659  ! This function does not get used in update by S. Cheng.
1660  ! It should be removed if/when "V1" routines are removed.
1661  !
1662  ! 8. Source code :
1663  !
1664  !/ ------------------------------------------------------------------- /
1665  !/
1666  IMPLICIT NONE
1667  !/
1668  !/ ------------------------------------------------------------------- /
1669  !/ Parameter list
1670  !/
1671  INTEGER, INTENT(IN) :: n
1672  DOUBLE COMPLEX, INTENT(IN) :: aa(n,n)
1673  DOUBLE COMPLEX :: det ! RESULT
1674  !/
1675  !/ ------------------------------------------------------------------- /
1676  !/ Local parameters
1677  !/
1678  INTEGER :: k, i, j, is, js
1679  DOUBLE COMPLEX :: f, d, mat(n,n)
1680  DOUBLE PRECISION :: q
1681  !/
1682  !/ ------------------------------------------------------------------- /
1683  mat = aa
1684  f = 1.0
1685  det = 1.0
1686  loop100: DO k = 1,n-1
1687  q = 0.0
1688  loop10a: DO i = k,n
1689  loop10b: DO j = k,n
1690  IF (abs(mat(i,j)).GT.q) THEN
1691  q = abs(mat(i,j))
1692  is = i
1693  js = j
1694  END IF
1695  END DO loop10b
1696  END DO loop10a
1697  IF (q+1.0.EQ.1.0) THEN
1698  det = 0.0
1699  RETURN
1700  END IF
1701  IF (is.NE.k) THEN
1702  f = -f
1703  loop20: DO j = k,n
1704  d = mat(k,j)
1705  mat(k,j) = mat(is,j)
1706  mat(is,j) = d
1707  END DO loop20
1708  END IF
1709  IF (js.NE.k) THEN
1710  f = -f
1711  loop30: DO i = k,n
1712  d = mat(i,js)
1713  mat(i,js) = mat(i,k)
1714  mat(i,k) = d
1715  END DO loop30
1716  END IF
1717  det = det * mat(k,k)
1718  loop50: DO i = k+1,n
1719  d = mat(i,k) / mat(k,k)
1720  loop40: DO j = k+1,n
1721  mat(i,j) = mat(i,j) - d * mat(k,j)
1722  END DO loop40
1723  END DO loop50
1724  END DO loop100
1725  !/
1726  det = f * det * mat(n,n)
1727  !/
1728  !/ End of BSDET ------------------------------------------------------ /
1729  !/
1730  END FUNCTION bsdet
1731  !/ ------------------------------------------------------------------- /
1732  FUNCTION delta(X) RESULT(DX)
1733  !/
1734  !/ +-----------------------------------+
1735  !/ | WAVEWATCH III NOAA/NCEP |
1736  !/ | E. Rogers |
1737  !/ | S. Zieger |
1738  !/ | FORTRAN 90 |
1739  !/ | Last update : 22-Oct-2013 |
1740  !/ +-----------------------------------+
1741  !/
1742  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.12 )
1743  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
1744  !/
1745  ! 1. Purpose :
1746  !
1747  ! This function calculates bin withs for any discretized function.
1748  ! May be used for numerical integration and differentiation.
1749  !
1750  ! 2. Method :
1751  !
1752  ! 3. Parameters :
1753  !
1754  ! Parameter list
1755  ! ----------------------------------------------------------------
1756  ! X R.A. I Array type of REAL
1757  ! DX R.A O Bin widths if X
1758  ! ----------------------------------------------------------------
1759  !
1760  ! 4. Remarks :
1761  !
1762  ! This function does not get used in update by S. Cheng.
1763  ! It should be removed if/when "V1" routines are removed.
1764  !
1765  ! 5. Called by :
1766  ! W3IC3WNCG_V1
1767  !
1768  ! 6. Source code :
1769  !/
1770  IMPLICIT NONE
1771  !/
1772  REAL, INTENT(IN) :: x(:)
1773  REAL, ALLOCATABLE :: dx(:)
1774  INTEGER :: ix, nx
1775  !/
1776  nx = SIZE(x,1)
1777  ALLOCATE(dx(nx))
1778  dx = 0.
1779  !/
1780  DO ix = 1,nx
1781  IF (ix==1) THEN
1782  dx(ix) = (x(ix+1)-x(ix ))
1783  ELSE IF (ix==nx) THEN
1784  dx(ix) = (x(ix )-x(ix-1))
1785  ELSE
1786  dx(ix) = (x(ix+1)-x(ix-1)) / 2.
1787  END IF
1788  END DO
1789  !/
1790  END FUNCTION delta
1791 
1792  !/ ------------------------------------------------------------------- /
1793  !/ ------------------------------------------------------------------- /
1794  !/ ------------------------------------------------------------------- /
1795  ! Start of new codes (or new variants) provided by S. Cheng
1796  !/ ------------------------------------------------------------------- /
1797  !/ ------------------------------------------------------------------- /
1798  !/ ------------------------------------------------------------------- /
1799 
1800  SUBROUTINE w3ic3wncg_cheng(WN_R,WN_I,CG,ICE1,ICE2,ICE3,ICE4,DPT)
1801  !/ +-----------------------------------+
1802  !/ | WAVEWATCH III NOAA/NCEP |
1803  !/ | E. Rogers |
1804  !/ | S. Zieger |
1805  !/ | X. Zhao |
1806  !/ | S. Cheng |
1807  !/ | FORTRAN 90 |
1808  !/ | Last update : 13-Jan-2016 |
1809  !/ +-----------------------------------+
1810  !/
1811  ! 1. Purpose :
1812  !
1813  ! Calculation of complex wavenumber for waves in ice. Outsourced
1814  ! from W3SIC3 to allow update on wavenumbers and group
1815  ! velocities at each time step an ice parameter is updated.
1816  !
1817  ! 2. Method :
1818  !
1819  ! <text here>
1820  !
1821  ! 3. Parameters :
1822  !
1823  ! Parameter list
1824  ! ----------------------------------------------------------------
1825  ! WN_R R. A. I/O Wave number (real part)
1826  ! WN_I R. A. I/O Wave number (imag. part=wave attenuation)
1827  ! CG R. A. I/O Group velocity
1828  ! ICE1 REAL I Thickness of ice [in m]
1829  ! ICE2 REAL I Effective viscosity of ice [in m2/s]
1830  ! ICE3 REAL I Density of ice [in kg/m3]
1831  ! ICE4 REAL I Effective shear modulus of ice [in Pa]
1832  ! DPT REAL I Water depth [in m]
1833  ! ----------------------------------------------------------------
1834  !
1835  ! 4. Subroutines used :
1836  !
1837  ! Name Type Module Description
1838  ! ----------------------------------------------------------------
1839  ! WAVNU1 Subr. W3DISPMD Wavenumber for waves in open water.
1840  ! WN_CMPLX Func. W3SIC3MD Complex wavenumber for waves in ice.
1841  ! ----------------------------------------------------------------
1842  !
1843  ! 5. Called by :
1844  !
1845  ! Name Type Module Description
1846  ! ----------------------------------------------------------------
1847  ! W3SIC3 Subr. W3SIC3MD Ice source term.
1848  ! ----------------------------------------------------------------
1849  !
1850  ! 6. Error messages :
1851  !
1852  ! 7. Remarks :
1853  ! On pre-calculation table, S. Cheng says:
1854  ! Instead of interpolation, WN_R of arbitrary HICE is approximated
1855  ! by IC3WN_R in the look up table. IC3WN_R is related to an ice
1856  ! thickness in the table, which is closest to HICE and less than
1857  ! HICE
1858  !
1859  ! Fix submitted by Sukun March 2017:
1860  ! replace :
1861  ! I = MIN(INT(HICE/IC3_DITK)+1,ITKNUM)
1862  ! with :
1863  ! I = MIN(NINT(HICE/IC3_DITK),ITKNUM)
1864  !
1865  ! 8. Structure :
1866  !
1867  ! See source code.
1868  !
1869  ! 9. Source code :
1870  !/
1871  !/ ------------------------------------------------------------------- /
1872  !/
1873  USE w3gdatmd, ONLY: nk,sig, ic3pars
1874  USE w3adatmd, ONLY: ic3wn_r, ic3wn_i, ic3cg
1875  USE w3odatmd, ONLY: ndse
1876  USE w3servmd, ONLY: extcde
1877  USE w3dispmd, ONLY: wavnu1
1878  !/
1879  IMPLICIT NONE
1880  !/
1881  REAL, INTENT(IN) :: ice1, ice2, ice3, ice4, dpt
1882  REAL, INTENT(INOUT):: wn_r(:),wn_i(:),cg(:)
1883  REAL, ALLOCATABLE :: sigma(:)
1884  !
1885  INTEGER :: i, i1, i2, ik, kl,ku, itknum
1886  COMPLEX(8) :: wncomplex, x0,x1,x2, wnr, wnl
1887  REAL(8) :: depth, hice, nu, dice, es_mod, rr, k_ocean, &
1888  cg_ocean
1889  REAL :: ic3hilim,ic3kilim
1890 
1891  ic3hilim=ic3pars(10)
1892  ic3kilim=ic3pars(11)
1893 
1894  ALLOCATE( sigma( SIZE(cg) ) )
1895  sigma = 0.
1896  IF (SIZE(wn_r,1).EQ.nk) THEN
1897  kl = 1
1898  ku = nk
1899  i1 = 1
1900  i2 = nk
1901  sigma = sig(1:nk)
1902  ELSE IF (SIZE(wn_r,1).EQ.nk+2) THEN
1903  kl = 1
1904  ku = nk+2
1905  i1 = 0
1906  i2 = nk+1
1907  sigma = sig(0:nk+1)
1908  ELSE
1909  WRITE(ndse,900)
1910  CALL extcde(3)
1911  END IF
1912  depth = dpt ! water depth
1913  hice = ice1 ! ice thickness
1914 
1915  ! Optional: limit ice thickness
1916  hice=min(dble(ic3hilim),hice)
1917  nu = ice2 ! "effective viscosity" parameter
1918  dice = ice3 ! density of ice
1919  es_mod = ice4 ! effective shear modulus of ice
1920  !
1921  itknum = ceiling(ic3_maxitk/ic3_ditk)
1922  i = min(nint(hice/ic3_ditk),itknum)
1923 
1924  ! Find values in pre-calculated look-up table
1925  ! See Remarks section.
1926  wn_r = ic3wn_r(i1:i2, i)
1927  wn_i = ic3wn_i(i1:i2, i)
1928  cg = ic3cg(i1:i2, i)
1929  rr = 0.01
1930  !/ --- CHECK If it's shallow water situation, then it needs recalculate
1931  ! kr,ki,cg
1932  DO ik = kl,ku
1933  IF (wn_r(ik)*depth>4.0)THEN ! exit do-loop
1934  EXIT ! assume kr is proportional to frequency
1935  ELSE
1936  x1 = cmplx(wn_r(ik),wn_i(ik))
1937  x0 = x1*(1-rr)
1938  x2 = x1*(1+rr)
1939  wncomplex = cmplx_root_muller_cheng(x0,x1,x2,1, &
1940  dble(sigma(ik)),es_mod,nu,dice,hice,depth)
1941  wn_i(ik) = real(aimag(wncomplex)) ! ki
1942  wn_r(ik) = real(wncomplex) ! kr
1943  ENDIF
1944  ENDDO
1945 
1946  CALL smooth_k(wn_r,wn_i,sigma,ku-kl+ 1,0)
1947  ! Optional : limit ki
1948  DO ik = kl,ku
1949  wn_i(ik) = min(wn_i(ik),ic3kilim)
1950  ENDDO
1951 
1952 !!! --- Update group velocitiy ----
1953  CALL cginic3_cheng(cg,sigma,wn_r,ku-kl+1)
1954 
1955  DEALLOCATE(sigma)
1956 
1957 900 FORMAT (/' *** WAVEWATCH III ERROR IN W3SIC3_W3IC3WNCG : '/&
1958  ' CANNOT DETERMINE BOUNDS OF WAVENUMBER ARRAY.')
1959  END SUBROUTINE w3ic3wncg_cheng
1960  !
1961  !/ ------------------------------------------------------------------- /
1962  SUBROUTINE ic3table_cheng(ICE2,ICE3,ICE4)
1963  !/ +-----------------------------------+
1964  !/ | WAVEWATCH III NOAA/NCEP |
1965  !/ | E. Rogers |
1966  !/ | S. Zieger |
1967  !/ | X. Zhao |
1968  !/ | S. Cheng |
1969  !/ | FORTRAN 90 |
1970  !/ | Last update : 13-Jan-2016 |
1971  !/ +-----------------------------------+
1972  !/
1973  ! 1. Purpose :
1974  !
1975  ! It's a Preprocess part to create a table of wave nubmer,
1976  ! attenuation and group velocity
1977  ! for all ice thickness in deep water situation for main
1978  ! computation.
1979  !
1980  ! 2. Method :
1981  !
1982  ! 3. Parameters :
1983  !
1984  ! 4. Subroutines used :
1985  !
1986  ! Name Type Module Description
1987  ! ----------------------------------------------------------------
1988  ! CMPLX_ROOT_MULLER_CHENG Func. W3SIC3MD Find root for complex
1989  ! wavenumbers for waves in ice.
1990  ! ----------------------------------------------------------------
1991  !
1992  ! 5. Called by :
1993  !
1994  ! Name Type Module Description
1995  ! ----------------------------------------------------------------
1996  ! W3WAVE Subr. W3WAVEMD
1997  ! ----------------------------------------------------------------
1998  !
1999  ! 6. Error messages :
2000  !
2001  ! 7. Remarks :
2002  !
2003  ! Original authors: Cheng and Shen.
2004  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2005  ! University) to Erick Rogers (NRL) on Aug 25 2015
2006  !
2007  ! **UNRESOLVED BUG** This routine should be called again if ice
2008  ! rheology (visc., elast.) changes (either time or space).
2009  ! It doesn't. We need to set CALLEDIC3TABLE=0 if either parameter is
2010  ! changed.
2011  !
2012  ! 8. Structure :
2013  !
2014  ! See source code.
2015  !
2016  ! 9. Switches :
2017  !
2018  ! 10. Source code :
2019  !
2020  !/ ------------------------------------------------------------------- /
2021  USE w3gdatmd, ONLY: nk,sig
2022  USE w3adatmd, ONLY: ic3wn_r, ic3wn_i, ic3cg
2023  USE w3idatmd, ONLY: inflags2
2024  USE w3odatmd, ONLY: ndse
2025  USE w3servmd, ONLY: extcde
2026  USE constants, ONLY: grav
2027  !
2028  IMPLICIT NONE
2029  REAL :: ice1, ice2, ice3, ice4, dpt
2030  INTEGER :: i1, i2, jitk, itknum, ik
2031 
2032  dpt = 999.
2033 
2034  itknum = ceiling(ic3_maxitk/ic3_ditk)
2035  ic3wn_r(:,0) = sig**2/grav
2036  ic3wn_i(:,0) = 0
2037  DO jitk = 1,itknum
2038  ice1 = jitk*ic3_ditk !HICE
2039  CALL ic3precalc_cheng(ic3wn_r(:,jitk), ic3wn_i(:,jitk), &
2040  ic3cg(:,jitk), ice1, ice2, ice3, ice4, dpt)
2041  ENDDO
2042 
2043  RETURN
2044  END SUBROUTINE ic3table_cheng
2045 
2046  !/ ------------------------------------------------------------------- /
2047  SUBROUTINE ic3precalc_cheng(WN_R,WN_I,CG,ICE1,ICE2,ICE3,ICE4,DPT)
2048  !/ +-----------------------------------+
2049  !/ | WAVEWATCH III NOAA/NCEP |
2050  !/ | E. Rogers |
2051  !/ | S. Zieger |
2052  !/ | X. Zhao |
2053  !/ | S. Cheng |
2054  !/ | FORTRAN 90 |
2055  !/ | Last update : 13-Jan-2016 |
2056  !/ +-----------------------------------+
2057  !/
2058  ! 1. Purpose :
2059  !
2060  ! Preprocess part to create a table of wave nubmer, attenuation and
2061  ! group velocity for all ice thickness in deep water situation for
2062  ! main computation.
2063  !
2064  ! 2. Method :
2065  !
2066  ! Calculate them use Muller's method
2067  !
2068  ! 3. Parameters :
2069  !
2070  ! 4. Subroutines used :
2071  !
2072  ! Name Type Module Description
2073  ! ----------------------------------------------------------------
2074  ! CMPLX_ROOT_MULLER_CHENG Func. W3SIC3MD Find root for complex
2075  ! wavenumbers for waves in ice.
2076  ! ----------------------------------------------------------------
2077  !
2078  ! 5. Called by :
2079  !
2080  ! Name Type Module Description
2081  ! ----------------------------------------------------------------
2082  ! IC3TABLE_CHENG Subr. W3SIC3MD Create a table of kr,ki,cg
2083  ! ----------------------------------------------------------------
2084  !
2085  ! 6. Error messages :
2086  !
2087  ! 7. Remarks :
2088  !
2089  ! Original authors: Cheng and Shen.
2090  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2091  ! University) to Erick Rogers (NRL) on Aug 25 2015
2092  !
2093  ! Sukun Cheng in reference to MIN(WN_I(IK),--):
2094  ! "This artificial limitation reduces IC3 model’s effect,
2095  ! though it saves some time.
2096  ! ki > 2.e-4 is a common truth for angular frequency larger
2097  ! than the value around 2 or 3 depending on other parameters."
2098  !
2099  ! 8. Structure :
2100  !
2101  ! See source code.
2102  !
2103  ! 9. Switches :
2104  !
2105  ! 10. Source code :
2106  !
2107  !/ ------------------------------------------------------------------- /
2108  USE w3gdatmd, ONLY: nk, sig
2109  USE w3dispmd, ONLY: wavnu1
2110  USE w3odatmd, ONLY: ndse
2111  USE w3servmd, ONLY: extcde
2112  !/
2113  IMPLICIT NONE
2114  !/
2115  REAL, INTENT(INOUT):: wn_r(0:nk+1),wn_i(0:nk+1), cg(0:nk+1)
2116  REAL, INTENT(IN) :: ice1, ice2, ice3, ice4, dpt
2117 
2118  INTEGER :: ik, kl,ku,ix,num,switchid
2119  REAL :: k_ocean,cg_ocean
2120  REAL(8) :: kh, k_noice, depth, hice, nu, dice, &
2121  es_mod,sigmam1
2122  COMPLEX(8) :: wncomplex, x0,x1,x2,wnm1,wnm2,wn_o
2123  !
2124  ! --- Input to routine
2125  depth = dpt ! water depth
2126  hice = ice1 ! ice thickness
2127  nu = ice2 ! "effective viscosity" parameter
2128  dice = ice3 ! density of ice
2129  es_mod = ice4 ! effective shear modulus of ice
2130 
2131  kl = 0
2132  ku = nk+1
2133  switchid = 0
2134 
2135  DO ik = kl,ku
2136  CALL wavnu1(sig(ik),dpt,k_ocean,cg_ocean)
2137  k_noice = k_ocean
2138 
2139  ! --- Calculate complex wavenumber ------------------------------- /
2140  IF(ik<kl+2)THEN
2141  wnm1 = cmplx(0.,0.)
2142  wnm2 = cmplx(0.,0.)
2143  sigmam1 = 0.0
2144  ELSE
2145  wnm1 = cmplx(wn_r(ik-1),wn_i(ik-1))
2146  wnm2 = cmplx(wn_r(ik-2),wn_i(ik-2))
2147  sigmam1 = sig(ik-1)
2148  ENDIF
2149 
2150  wn_o = cmplx(k_noice,0.0)
2151  CALL wn_precalc_cheng(wncomplex,dble(sig(ik)),dble(sigmam1),wn_o, &
2152  wnm1,wnm2,es_mod,nu,dice,hice,depth,switchid,ik,ku)
2153  ! --- Output to routine
2154  wn_r(ik) = real(wncomplex) ! kr
2155  wn_i(ik) = imag(wncomplex) ! ki
2156  ENDDO
2157  CALL smooth_k(wn_r,wn_i,sig,ku-kl+1,switchid)
2158  CALL cginic3_cheng(cg,sig,wn_r,ku-kl+1)
2159  !/
2160  END SUBROUTINE ic3precalc_cheng
2161 
2162  !/ -------------------------------------------------------------------/
2163 
2164  SUBROUTINE wn_precalc_cheng(WN,SIGMA,SIGMAM1,WN_O,WNM1,WNM2,ES_MOD, &
2165  NU,DICE,HICE,DEPTH,SWITCHID,IK,KU)
2166  !/ +-----------------------------------+
2167  !/ | WAVEWATCH III NOAA/NCEP |
2168  !/ | S. Cheng |
2169  !/ | E. Rogers |
2170  !/ | S. Zieger |
2171  !/ | X. Zhao |
2172  !/ | FORTRAN 90 |
2173  !/ | Last update : 13-Jan-2016 |
2174  !/ +-----------------------------------+
2175  !/
2176  ! 1. Purpose :
2177  !
2178  ! Calculate complex wavenumber for waves in ice.
2179  !
2180  ! 2. Method :
2181  !
2182  ! Wang and Shen (JGR 2010)
2183  !
2184  ! 3. Parameters :
2185  !
2186  ! Parameter list
2187  ! ----------------------------------------------------------------
2188  ! WN CMPLX O Wave number (imag. part=wave attenuation)
2189  ! SIGMA REAL I Wave angular frequency [in rad]
2190  ! WN_O REAL I Wave number (open water)
2191  ! ES REAL I Effective shear modulus of ice [in Pa]
2192  ! NU REAL I Effective viscosity of ice [in m2/s]
2193  ! DICE REAL I Density of ice [in kg/m3]
2194  ! HICE REAL I Thickness of ice [in m]
2195  ! DEPTH REAL I Water depth [in m]
2196  ! ----------------------------------------------------------------
2197  !
2198  ! 4. Subroutines used :
2199  !
2200  ! Name Type Module Description
2201  ! ----------------------------------------------------------------
2202  ! CMPLX_ROOT_MULLER_CHENG Func. W3SIC3MD Find root for complex
2203  ! wavenumbers for waves in ice.
2204  ! ----------------------------------------------------------------
2205  !
2206  ! 5. Called by :
2207  !
2208  ! Name Type Module Description
2209  ! ----------------------------------------------------------------
2210  ! IC3PRECALC_CHENG xxx xxx xxxx
2211  ! ----------------------------------------------------------------
2212  !
2213  ! 6. Error messages :
2214  !
2215  ! 7. Remarks :
2216  !
2217  ! Updated authors: Cheng and Shen.
2218  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2219  ! University) to Erick Rogers (NRL) on Aug 25 2015
2220  ! Original authors: Zhao and Shen.
2221  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2222  ! University) to Erick Rogers (NRL) on April 19 2013.
2223  !
2224  ! Hayley Shen says,
2225  ! We have determined that it may not be necessary to use curve
2226  ! fitting or lookup tables to get the group velocity and the
2227  ! attenuation coefficient. Attached is a short report with some
2228  ! sample numerical solutions. To implement the viscoelastic model,
2229  ! there are 4 fortran programs. According to Xin Zhao, the graduate
2230  ! student, it is very fast to find roots. I suggest that perhaps you
2231  ! try the pure viscous case by setting G=0 to start with. nu can be
2232  ! set at 0.05*ice concentration (m^2/s) to begin with, because for
2233  ! grease ice Newyear’s data showed nu to be about 0.02-0.03 m^2/s.
2234  ! By setting G=0 in you get exactly the Keller model for pure
2235  ! viscous layer.
2236  !
2237  ! This routine provides the initial guess according to the parameters
2238  ! of the present case. T>10s use open water, T<10s cases, calculate
2239  ! T=10s first using open water as the initial guess.
2240  !
2241  ! 8. Structure :
2242  !
2243  ! See source code.
2244  !
2245  ! 9. Switches :
2246  !
2247  ! 10. Source code :
2248  !
2249  !/ ------------------------------------------------------------------- /
2250  USE constants, ONLY: tpi
2251  !/
2252  IMPLICIT NONE
2253  !/
2254  !/ ------------------------------------------------------------------- /
2255  !/ Parameter list
2256  !/
2257  REAL(8) :: SIGMA,SIGMAM1,ES_MOD,NU,DICE,HICE,DEPTH
2258  COMPLEX(8) :: WN_O, WNM1, WNM2, WN0, WN1,WN2
2259  COMPLEX(8),INTENT(OUT) :: WN ! RESULT
2260  !/
2261  !/ ------------------------------------------------------------------- /
2262  !/ Local parameters
2263  !/
2264  INTEGER :: I,IX,NUM,SWITCHID,IK,KU
2265  REAL(8) :: RR, R2, EPS, SIGMA0, KAPPA, DIS
2266  COMPLEX(8) :: X0, X1, X2, kp, ks, Gv
2267  !/
2268  !/ ------------------------------------------------------------------- /
2269  ! compute shear wave and pressure wave modes
2270  gv = cmplx(es_mod,-sigma*nu*dice)
2271  kp = sigma/sqrt(4*gv/dice)
2272  ks = 2*kp
2273  ! RR,R2 are empirical coefficients
2274  rr = 0.2
2275  r2 = 4
2276  eps = 1.d-10 ! assuming variable =0, if it is less than this value
2277  ! compute root 1
2278  ! initial guesses from wave number of open water
2279  !
2280  x1 = wn_o ! initial guess
2281  x0 = x1*(1-rr)
2282  x2 = x1*(1+rr)
2283 
2284  wn1 = cmplx_root_muller_cheng(x0,x1,x2,1,sigma, &
2285  es_mod,nu,dice,hice,depth)
2286  ! if root finder failed, or found shear wave mode,
2287  ! redo searching using simplified dispersion relation form, index 2
2288  IF (real(wn1)<0.or.abs(wn1-ks)/abs(ks)<0.03 .or. &
2289  abs(wn1-kp)/abs(kp)<0.03.and.es_mod>1.e7*nu)THEN
2290  wn1 = cmplx_root_muller_cheng(x0,x1,x2,2,sigma, &
2291  es_mod,nu,dice,hice,depth)
2292  ENDIF
2293  ! similar as wn1, but search with opposite order of inital guesses
2294  wn2 = cmplx_root_muller_cheng(x2,x1,x0,1,sigma, &
2295  es_mod,nu,dice,hice,depth)
2296  IF (real(wn2)<0.or.abs(wn2-ks)/abs(ks)<0.03)THEN
2297  wn2 = cmplx_root_muller_cheng(x2,x1,x0,2,sigma, &
2298  es_mod,nu,dice,hice,depth)
2299  ENDIF
2300  IF(abs(real(wn1)-real(wn_o))<abs(real(wn2)-real(wn_o)))THEN
2301  wn0 = wn1
2302  ELSE
2303  wn0 = wn2
2304  ENDIF
2305 
2306  IF(sigmam1==0.)THEN
2307  wn = wn0
2308  ELSE
2309  ! compute root 2
2310  ! Calculate the other wave number based on last frequency
2311  ! in the frequency array
2312  r2 = max(abs(wnm1-wnm2)/abs(wnm2), abs((sigma-sigmam1)/sigma))
2313  DO i = 1,7,2
2314  IF(i<3.AND.sigma>4)THEN
2315  cycle
2316  ENDIF
2317  num = 2**(i-1)
2318  rr = min(max(r2/real(num,8),0.001d0),0.5d0)
2319  x1 = wnm1
2320  DO ix = 1,num
2321  x0 = x1*(1-rr)
2322  x2 = x1*(1+rr)
2323  sigma0 = sigmam1 + (1.0*ix)/num*(sigma-sigmam1)
2324  wn = cmplx_root_muller_cheng(x0,x1,x2,1,sigma0, &
2325  es_mod,nu,dice,hice,depth)
2326  IF(real(wn)<0)THEN ! try another searching direction
2327  wn = cmplx_root_muller_cheng(x2,x1,x0,1,sigma0, &
2328  es_mod,nu,dice,hice,depth)
2329  ENDIF
2330  IF(real(wn)<0)THEN ! try another dispersion relation form
2331  wn = cmplx_root_muller_cheng(x0,x1,x2,3,sigma0, &
2332  es_mod,nu,dice,hice,depth)
2333  ENDIF
2334  kp = sigma0/sqrt(4*gv/dice)
2335  ks = 2*kp
2336  ! set 3 means simple dispersion relation form
2337  IF(abs(wn-ks)/abs(ks)<0.03.OR.real(wn)<0)THEN
2338  wn = cmplx_root_muller_cheng(x0,x1,x2,2,sigma0, &
2339  es_mod,nu,dice,hice,depth)
2340  ENDIF
2341  x1 = wn
2342  IF( real(wn)<0.99*real(wnm1).OR. abs(wn-wn0)>eps .AND. &
2343  (abs(x1-wn)/abs(wn)>0.3 .OR. &
2344  imag(wn)/(imag(x1)+eps)>10.OR. real(wn)<0))THEN
2345  EXIT ! redo with smaller intervals
2346  ENDIF
2347  x0 = x1
2348  x1 = wn
2349  ENDDO ! DO IX = 1,NUM
2350 
2351  IF(ix==num+1)THEN
2352  EXIT
2353  ENDIF
2354  wn = x1 !/ --- if exit of inner loop: give an approximate wn
2355  ENDDO ! DO I = 1,7,2
2356 
2357  ! part 2
2358  ! assume found two roots, choose from the two condidates.
2359  kp = sigma/sqrt(4*gv/dice)
2360  IF(real(wn0)>0.AND.imag(wn0)>=0.AND.abs(wn - wn0)>eps)THEN
2361  !do switch at last 3 points is not worth numerically.
2362  !For v>5.e-2, it is low chance to be wrong at the last 3 points
2363  ! we suppose to use two mode in the future
2364  IF(nu>0.AND.ik>=ku-1.OR. &
2365  nu>0.AND.switchid/=0)THEN
2366  ! assume one mode switch for general viscoelastic model
2367  ELSE
2368  dis = abs(real(wn)-real(wn_o))/abs(real(wn0)-real(wn_o))
2369  kappa = (imag(wn)+ eps)/(imag(wn0) + eps)
2370  ! wn0 has smaller attenuation and closer to k0
2371  IF ((dis >= 1 .AND. kappa>=1 .AND. &
2372  imag(wn0)>=0.1*imag(wnm1).AND. &
2373  abs(wn-kp)<abs(wn0-kp)) .OR. &
2374  ! wn0 has larger attenuation and closer to k0
2375  ( dis>=1 .AND. kappa<1 .AND. &
2376  ((kappa> 0.2 .AND. imag(wn0)/real(wn0)<0.5).or. &
2377  abs(real(wn)-real(kp))<abs(real(wn0)-real(kp)))).OR.&
2378  ! wn0 has smaller attenuation and farther to k0,
2379  ! wn0 could be wrong at high G
2380  ! (kappa>1 .and. dis<1 .and. dis> 0.8 ))then
2381  ( kappa>1 .AND. dis<1 .AND. &
2382  abs(real(wn)-real(wnm1))> &
2383  abs(real(wn0)-real(wnm1)) ))THEN
2384  wn = wn0
2385  switchid = ik
2386  ! wn0 has lager attenuation and farther to k0
2387  ELSEIF(dis<1 .AND. kappa<1) THEN
2388  ! keep wn without change
2389  ENDIF ! IF ((DIS >= 1 .AND. KAPPA>=1 .AND. &
2390  ENDIF ! IF(NU>0.AND.IK>=KU-2.OR. &
2391 
2392  ! choose dominant mode is farther than pressure wave.
2393  !but it doens't work for high viscosity.
2394  if (abs(wn-kp)/abs(kp)<0.03) then
2395  wn = wn0
2396  switchid = ik
2397  endif
2398  !if (real(wn)<=real(wnm1))then
2399  ! wn = wn0
2400  ! switchid = ik
2401  !endif
2402 
2403  IF (real(wn0)>real(wnm1).AND.real(wn0)<real(wn).and. &
2404  abs(imag(wn0)-imag(wnm1))<abs(imag(wn)-imag(wnm1)))THEN
2405  ! mainly for pure elastic case has multiple branchs
2406  wn = wn0
2407  switchid = ik
2408  ENDIF
2409  ENDIF ! IF(REAL(WN0)>0.AND.IMAG(WN0)>=0.AND.ABS(WN - WN0)....
2410  ENDIF ! IF(SIGMAM1==0.)THEN
2411 
2412  IF(real(wn)<0)THEN
2413  print*, "MULLER METHOD FAILED, ES_MOD,NU,HICE:",es_mod,nu,hice
2414  ENDIF
2415  RETURN
2416 
2417  END SUBROUTINE wn_precalc_cheng
2418  !/ -----------------------------------------------------------------
2419  !/
2420  SUBROUTINE cginic3_cheng(CG,SIGMA,WN_R,N)
2421  !/ +-----------------------------------+
2422  !/ | WAVEWATCH III NOAA/NCEP |
2423  !/ | E. Rogers |
2424  !/ | S. Zieger |
2425  !/ | X. Zhao |
2426  !/ | S. Cheng |
2427  !/ | FORTRAN 90 |
2428  !/ | Last update : 13-Jan-2016 |
2429  !/ +-----------------------------------+
2430  ! 1. Purpose :
2431  !
2432  ! Calculate group velocity in ic3 model
2433  !
2434  ! 2. Method :
2435  !
2436  ! finite differece
2437  !
2438  ! 3. Parameters :
2439  !
2440  ! Parameter list
2441  ! ----------------------------------------------------------------
2442  ! CG R. A. I/O Group velocity
2443  ! SIMGA R. A. angular frequency
2444  ! WN_R R. A. wave number
2445  ! N Int. array size
2446  ! ----------------------------------------------------------------
2447  !
2448  ! 4. Subroutines used :
2449  !
2450  ! None.
2451  !
2452  ! 5. Called by :
2453  !
2454  ! Name Type Module Description
2455  ! ----------------------------------------------------------------
2456  ! IC3PRECALC_CHENG Subr. W3SIC3MD Create table of kr,ki,cg for
2457  ! deep water
2458  ! W3IC3WNCG_CHENG Subr. W3SIC3MD Calculate kr,ki,cg
2459  ! ----------------------------------------------------------------
2460  !
2461  ! 6. Error messages :
2462  !
2463  ! 7. Remarks :
2464  ! Smooth function is used due to jump problem when wave modes
2465  ! switch
2466  !
2467  ! 8. Structure :
2468  !
2469  ! See source code.
2470  !
2471  ! 9. Source code :
2472  !/
2473  !/ ------------------------------------------------------------------- /
2474  !/
2475  REAL, INTENT(IN) :: SIGMA(1:N),WN_R(1:N)
2476  REAL, INTENT(OUT) :: CG(1:N)
2477  INTEGER :: N
2478  !/ LOCAL variables
2479  INTEGER :: IK, M
2480  REAL :: CG1,CG2,CG3,CG0(1:N)
2481  !/
2482  ik = 1
2483  cg(ik)=(sigma(ik+1)-sigma(ik))/(wn_r(ik+1)-wn_r(ik))
2484  ik = n
2485  cg(ik)=(sigma(ik)-sigma(ik-1))/(wn_r(ik)-wn_r(ik-1))
2486  DO ik = 2,n-1
2487  cg1 = (sigma(ik)-sigma(ik-1))/(wn_r(ik)-wn_r(ik-1))
2488  cg2 = (sigma(ik+1)-sigma(ik))/(wn_r(ik+1)-wn_r(ik))
2489  cg(ik) = 2.0/(1./cg1 + 1./cg2)
2490  END DO
2491 
2492  RETURN
2493  END SUBROUTINE cginic3_cheng
2494 
2495  !/ ------------------------------------------------------------------- /
2496  ! numerically smooth WN_R and WN_I by linear interpolation
2497  SUBROUTINE smooth_k(WN_R,WN_I,SIGMA,N,SWITCHID)
2498  REAL, INTENT(IN) :: SIGMA(N)
2499  REAL :: WN_R(N), WN_I(N),DIFF(N),REMOVEID(N)
2500  INTEGER :: N,I,J,SWITCHID
2501  !
2502  diff = 0
2503  ! remove kr in mode switch zone,
2504  ! if it is a local extremum or suddenly increasing
2505  DO j = 1,3 ! 3 times to guarantee wavenumber increases monotonically
2506  removeid = 0
2507  DO i = 2,n
2508  diff(i) = wn_r(i) - wn_r(i-1)
2509  ENDDO
2510  DO i = 3,n
2511  IF(diff(i)<=0.OR.diff(i)>3*diff(i-1).OR.switchid==i)THEN
2512  removeid(i) = 1
2513  removeid(i-1) = 1
2514  ENDIF
2515  ENDDO
2516  ! fill removed location with kr,ki by interpolation
2517  DO i = 2,n-1
2518  IF (removeid(i) ==1) THEN
2519  wn_r(i) = wn_r(i-1) + (wn_r(i+1)-wn_r(i-1))/ &
2520  (sigma(i+1)-sigma(i-1))*(sigma(i)-sigma(i-1))
2521  wn_i(i) = wn_i(i-1) + (wn_i(i+1)-wn_i(i-1))/ &
2522  (sigma(i+1)-sigma(i-1))*(sigma(i)-sigma(i-1))
2523  ENDIF
2524  ENDDO
2525  ENDDO
2526  ! mode switch upward at the last frequencies
2527  IF (diff(n)>3*diff(n-1))THEN
2528  i = n
2529  wn_r(i) = wn_r(i-1) + (wn_r(i-1)-wn_r(i-2))/ &
2530  (sigma(i-1)-sigma(i-2))*(sigma(i)-sigma(i-1))
2531  wn_i(i) = wn_i(i-1) + (wn_i(i-1)-wn_i(i-2))/ &
2532  (sigma(i-1)-sigma(i-2))*(sigma(i)-sigma(i-1))
2533  ENDIF
2534  RETURN
2535  END SUBROUTINE smooth_k
2536 
2537 
2538  !/ ------------------------------------------------------------------- /
2539 
2540  FUNCTION cmplx_root_muller_cheng(X0, X1, X2, JUDGE, &
2541  SIGMA,ES,NU,DICE,HICE,DEPTH ) RESULT(P3)
2542  !/ +-----------------------------------+
2543  !/ | WAVEWATCH III NOAA/NCEP |
2544  !/ | E. Rogers |
2545  !/ | S. Zieger |
2546  !/ | X. Zhao |
2547  !/ | S. Cheng |
2548  !/ | FORTRAN 90 |
2549  !/ | Last update : 13-Jan-2016 |
2550  !/ +-----------------------------------+
2551  !/
2552  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
2553  !/ (E. Rogers)
2554  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
2555  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
2556  !/
2557  ! 1. Purpose :
2558  !
2559  ! Find root.
2560  !
2561  ! 2. Method :
2562  !
2563  ! Muller method for complex equations is a recursive approximation
2564  ! with initial guess X0, X1, and X2. To the initial guesses a
2565  ! quadratic parabola is fitted.
2566  !
2567  ! 3. Parameters :
2568  !
2569  ! Parameter list
2570  ! ----------------------------------------------------------------
2571  ! P3 CMPLX DBL O Approximation for the root problem
2572  ! X0 CMPLX DBL I Initial guess variable
2573  ! X1 CMPLX DBL I Initial guess variable
2574  ! X2 CMPLX DBL I Initial guess variable
2575  ! SIGMA DOUBLE I Wave angular frequency
2576  ! ES DOUBLE I Effective shear modulus of ice
2577  ! NU DOUBLE I Effective viscosity of ice [in m2/s]
2578  ! DICE DOUBLE I Density of ice [in kg/m3]
2579  ! HICE DOUBLE I Thickness of ice [in m]
2580  ! DEPTH DOUBLE I Water depth [in m]
2581  ! ----------------------------------------------------------------
2582  !
2583  ! 4. Subroutines used :
2584  !
2585  ! Name Type Module Description
2586  ! ----------------------------------------------------------------
2587  ! F_ZHAO_CHENG xxxxx xxxx xxxx
2588  ! ----------------------------------------------------------------
2589  !
2590  ! 5. Called by :
2591  !
2592  ! Name Type Module Description
2593  ! ----------------------------------------------------------------
2594  ! WN_PRECALC_CHENG xxxxx xxxx
2595  ! W3IC3WNCG_CHENG xxxxx xxxx
2596  ! ----------------------------------------------------------------
2597  !
2598  ! 6. Error messages :
2599  !
2600  ! 7. Remarks :
2601  !
2602  ! Original authors: Zhao and Shen.
2603  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2604  ! University) to Erick Rogers (NRL) on April 19 2013.
2605  !
2606  ! 8. Structure :
2607  !
2608  ! See source code.
2609  !
2610  ! 9. Switches :
2611  !
2612  ! 10. Source code :
2613  !
2614  !/ ------------------------------------------------------------------- /
2615  USE w3odatmd, ONLY: ndse
2616  USE w3servmd, ONLY: extcde
2617  !/
2618  IMPLICIT NONE
2619  !/
2620  !/ ------------------------------------------------------------------- /
2621  !/ Parameter list
2622  !/
2623  COMPLEX(8) :: P3 ! RESULT
2624  COMPLEX(8), INTENT(IN):: X0,X1,X2
2625  REAL(8), INTENT(IN) :: SIGMA,ES,NU,DICE,HICE,DEPTH
2626  INTEGER, INTENT(IN) :: JUDGE
2627  !/
2628  !/ ------------------------------------------------------------------- /
2629  !/ Local parameters
2630  !/
2631 
2632  INTEGER :: I
2633  INTEGER, PARAMETER :: IMAX = 200
2634  REAL(8) :: DLTA,EPSI
2635  COMPLEX(8) :: P0,P1,P2
2636  COMPLEX(8) :: Y0,Y1,Y2,Y3
2637  COMPLEX(8) :: A,B,C,Q,DISC,DEN1,DEN2
2638  !/
2639  !/ ------------------------------------------------------------------- /
2640 
2641  p0 = x0
2642  p1 = x1
2643  p2 = x2
2644  p3 = 0.d0
2645 
2646  epsi = 1.d-8
2647  dlta = 1.d-8 ! relax it may cause error, too rigorous is not good neither.
2648  y0 = f_zhao_cheng(judge,p0,sigma,es,nu,dice,hice,depth)
2649  y1 = f_zhao_cheng(judge,p1,sigma,es,nu,dice,hice,depth)
2650  y2 = f_zhao_cheng(judge,p2,sigma,es,nu,dice,hice,depth)
2651 
2652  DO i = 1,imax
2653  q = (p2 - p1) / (p1 - p0)
2654  a = q * y2 - q * (1.d0+q) * y1 + q**2.d0 * y0
2655  b = (2.d0 * q + 1.d0) * y2 - (1.d0 + q)**2.d0 * y1 &
2656  + q**2.d0 * y0
2657  c = (1.d0 + q) * y2
2658 
2659  IF ( abs(a).NE.0.d0 ) THEN
2660 
2661  disc = b**2.d0 - 4.d0 * a * c;
2662 
2663  den1 = ( b + sqrt( disc ) )
2664  den2 = ( b - sqrt( disc ) )
2665 
2666  IF ( abs( den1 ) .LT. abs( den2 ) )THEN
2667  p3 = p2 - (p2 - p1) * (2.d0 * c / den2)
2668  ELSE
2669  p3 = p2 - (p2 - p1) * (2.d0 * c / den1)
2670  ENDIF
2671 
2672  ELSE
2673 
2674  IF ( abs(b) .NE. 0.d0 )THEN
2675  p3 = p2 - (p2 - p1) * (c / b)
2676  ELSE
2677  p3 = p2
2678  RETURN
2679  ENDIF
2680  ENDIF
2681 
2682  IF (imag(p3).LT.0)THEN
2683  p3 = real(p3) - cmplx(0.,1.)*imag(p3)
2684  ENDIF
2685  IF (real(p3).LT.0)THEN
2686  p3 = -real(p3) + cmplx(0.,1.)*imag(p3)
2687  ENDIF
2688 
2689  IF(nu==0)THEN
2690  p3 = cmplx(real(p3),0)
2691  ENDIF
2692  y3 = f_zhao_cheng(judge,p3,sigma,es,nu,dice,hice,depth);
2693  IF ( abs(p3-p2).LT.dlta .AND. abs(y3).LT.epsi ) THEN
2694  ! exit before finding a true root,Result may not be accurate
2695  RETURN
2696  ENDIF
2697 
2698  p0 = p1
2699  p1 = p2
2700  p2 = p3
2701 
2702  y0 = y1
2703  y1 = y2
2704  y2 = y3
2705  ENDDO
2706 
2707  p3 = cmplx(-100.,0)
2708  RETURN
2709 
2710  END FUNCTION cmplx_root_muller_cheng
2711  !/ ------------------------------------------------------------------- /
2712  !/
2713  FUNCTION f_zhao_cheng(JUDGE,X,SIGMA,ES,NU,DICE,HICE,DEPTH) &
2714  result(fzhao)
2715  !/ +-----------------------------------+
2716  !/ | WAVEWATCH III NOAA/NCEP |
2717  !/ | E. Rogers |
2718  !/ | S. Zieger |
2719  !/ | X. Zhao |
2720  !/ | S. Cheng |
2721  !/ | FORTRAN 90 |
2722  !/ | Last update : 13-Jan-2016 |
2723  !/ +-----------------------------------+
2724  !/
2725  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
2726  !/ (E. Rogers)
2727  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
2728  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
2729  !/
2730  ! 1. Purpose :
2731  !
2732  ! Decide whether to call sub-function.
2733  !
2734  ! 2. Method :
2735  !
2736  ! Decide based on value of integer "JUDGE"
2737  !
2738  ! 3. Parameters :
2739  !
2740  ! Parameter list
2741  ! ----------------------------------------------------------------
2742  ! FZHAO COMPL8 O Result (double complex)
2743  ! X CMPLX8 I Approximate result (double complex)
2744  ! JUDGE INTEGR I Switch variable
2745  ! SIGMA DOUBLE I Wave angular frequency
2746  ! ES DOUBLE I Effective shear modulus
2747  ! NU DOUBLE I Effective viscosity parameter
2748  ! DICE DOUBLE I Density of ice
2749  ! HICE DOUBLE I Thickness of ice
2750  ! DEPTH DOUBLE I Water depth
2751  ! ----------------------------------------------------------------
2752  !
2753  ! 4. Subroutines used :
2754  !
2755  ! Name Type Module Description
2756  ! ----------------------------------------------------------------
2757  ! DRFUN_dble Func. W3SIC3MD Function to find root with double
2758  ! precision.
2759  ! DRFUN_quad Func. W3SIC3MD Function to find root with quadruple
2760  ! precision.
2761  ! ----------------------------------------------------------------
2762  !
2763  ! 5. Called by :
2764  !
2765  ! Name Type Module Description
2766  ! ----------------------------------------------------------------
2767  ! CMPLX_ROOT_MULLER_CHENG Func. W3SIC3MD Find root for complex
2768  ! wavenumbers for waves in ice.
2769  ! ----------------------------------------------------------------
2770  !
2771  ! 6. Error messages :
2772  !
2773  ! 7. Remarks :
2774  !
2775  ! Updated authors: Cheng and Shen.
2776  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2777  ! University) to Erick Rogers (NRL) on Aug 25 2015
2778  ! Original authors: Zhao and Shen.
2779  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2780  ! University) to Erick Rogers (NRL) on April 19 2013.
2781  !
2782  ! 8. Structure :
2783  !
2784  ! See source code.
2785  !
2786  ! 9. Switches :
2787  !
2788  ! 10. Source code :
2789  !/
2790  !/ ------------------------------------------------------------------- /
2791  !/
2792  IMPLICIT NONE
2793  !/
2794  !/ ------------------------------------------------------------------- /
2795  !/ Parameter list
2796  !/
2797  INTEGER,INTENT(IN) :: JUDGE
2798  DOUBLE PRECISION, INTENT(IN) :: SIGMA,ES,NU,DICE,HICE,DEPTH
2799  DOUBLE COMPLEX, INTENT(IN) :: X
2800  DOUBLE COMPLEX :: FZHAO ! RESULT
2801  !/
2802  !/ ------------------------------------------------------------------- /
2803  IF (judge >0) THEN
2804  fzhao = drfun_dble_cheng(x,sigma,es,nu,dice,hice,depth,judge)
2805  ELSEIF(judge ==0)THEN
2806  fzhao = drfun_quad_cheng(x,sigma,es,nu,dice,hice,depth)
2807  ENDIF
2808  !
2809  END FUNCTION f_zhao_cheng
2810  !/ ------------------------------------------------------------------- /
2811  !/
2812  FUNCTION drfun_dble_cheng(WN,SIGMA,ES,NU,DICE,HICE,DEPTH,JUDGE) &
2813  result(func1)
2814  !/ +-----------------------------------+
2815  !/ | WAVEWATCH III NOAA/NCEP |
2816  !/ | E. Rogers |
2817  !/ | S. Zieger |
2818  !/ | X. Zhao |
2819  !/ | S. Cheng |
2820  !/ | FORTRAN 90 |
2821  !/ | Last update : 13-Jan-2016 |
2822  !/ +-----------------------------------+
2823  !/
2824  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
2825  !/ (E. Rogers)
2826  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
2827  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
2828  !/
2829  ! 1. Purpose :
2830  !
2831  ! Return dispersion relation function value for root finding
2832  !
2833  ! 2. Method :
2834  !
2835  ! function based on dispersion relation derived by Wang and Shen
2836  ! 2010
2837  !
2838  ! 3. Parameters :
2839  !
2840  ! Parameter list
2841  ! ----------------------------------------------------------------
2842  ! FUNC1 CMPLX DBL O Result (COMPLEX(8))
2843  ! WN CMPLX DBL I Wavenumber (COMPLEX(8))
2844  ! W REAL DBL I Wave angular frequency
2845  ! ES REAL DBL I Effective shear modulus on ice
2846  ! NU REAL DBL I Effective viscosity
2847  ! DICE REAL DBL I Density of ice
2848  ! HICE REAL DBL I Thickness of ice
2849  ! DEPTH REAL DBL I Water depth
2850  ! ----------------------------------------------------------------
2851  !
2852  ! 4. Subroutines used :
2853  !
2854  ! Name Type Module Description
2855  ! ----------------------------------------------------------------
2856  ! None.
2857  ! ----------------------------------------------------------------
2858  !
2859  ! 5. Called by :
2860  !
2861  ! Name Type Module Description
2862  ! ----------------------------------------------------------------
2863  ! F_ZHAO_CHENG xxx xxxx xxxxx
2864  ! ----------------------------------------------------------------
2865  !
2866  ! 6. Error messages :
2867  !
2868  ! 7. Remarks :
2869  !
2870  ! Updated authors: Cheng and Shen.
2871  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2872  ! University) to Erick Rogers (NRL) on Aug 25 2015
2873  ! Original authors: Zhao and Shen.
2874  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
2875  ! University) to Erick Rogers (NRL) on April 19 2013.
2876  !
2877  ! 8. Structure :
2878  !
2879  ! See source code.
2880  !
2881  ! 9. Switches :
2882  !
2883  ! 10. Source code :
2884  !/
2885  !/ ------------------------------------------------------------------- /
2886  USE constants, ONLY: grav, dwat
2887  !/
2888  IMPLICIT NONE
2889  !/
2890  !/ ------------------------------------------------------------------- /
2891  !/ Parameter list
2892  !/
2893  COMPLEX(8), INTENT(IN) :: wn
2894  REAL(8), INTENT(IN) :: sigma, es, nu, dice, hice, depth
2895  COMPLEX(8) :: func1,aa(4,4) ! RESULT
2896  INTEGER :: judge
2897  !/
2898  !/ ------------------------------------------------------------------- /
2899  !/ Local parameters
2900  !/
2901  COMPLEX(8) :: ve,alpha,n,m,l,sk,ck,sa,ca,th,thh,temp,j1,j2
2902  !/
2903  !/ ------------------------------------------------------------------- /
2904  ve = cmplx( nu, es/dice/sigma )
2905  alpha = sqrt( wn**2. - sigma/ve * cmplx(0.,1.d0) )
2906  n = sigma + 2. * ve * wn**2. * cmplx(0.,1.d0)
2907 
2908  temp = exp(wn*hice)
2909  sk = (temp - 1.d0/temp)/2.d0
2910  ck = (temp + 1.d0/temp)/2.d0
2911 
2912  temp = exp(alpha*hice)
2913  sa = (temp - 1.d0/temp)/2.d0
2914  ca = (temp + 1.d0/temp)/2.d0
2915  !
2916  temp = (wn*depth)
2917  IF ( real(temp).LT.18.d0 ) THEN
2918  temp = exp(temp)
2919  th = (temp - 1./temp)/(temp + 1./temp)
2920  ELSE
2921  th = 1.d0
2922  ENDIF
2923  ! JUDGE==3 is not used yet
2924  IF ((es>=1.e5.AND.judge/=2).or.judge==3) THEN
2925  l = 2 * wn * alpha * sigma * ve
2926  m = (dble(dwat)/dice - 1) * dble(grav) * wn &
2927  - dble(dwat) / dice * sigma**2 / th
2928  aa(1,1) = 0.
2929  aa(1,2) = 2 * cmplx(0.,1.) * wn**2.
2930  aa(1,3) = alpha**2. + wn**2.
2931  aa(1,4) = 0.
2932  !
2933  aa(2,1) = n * sigma
2934  aa(2,2) = -wn * dble(grav)
2935  aa(2,3) = cmplx(0.,1.) * wn * dble(grav)
2936  aa(2,4) = l
2937  !
2938  aa(3,1) = -2. * cmplx(0.,1.) * wn**2. * sk
2939  aa(3,2) = 2. * cmplx(0.,1.) * wn**2. * ck
2940  aa(3,3) = (alpha**2. + wn**2.) * ca
2941  aa(3,4) = -(alpha**2. + wn**2.) * sa
2942  !
2943  aa(4,1) = n * sigma * ck - m * sk
2944  aa(4,2) = - n * sigma * sk + m * ck
2945  aa(4,3) = -cmplx(0.,1.) * m * ca - l * sa
2946  aa(4,4) = cmplx(0.,1.) * m * sa + l * ca
2947  !
2948  func1 = bsdet(aa,4)
2949  ELSE
2950  j1 = dice/dble(dwat)*(wn**2.*dble(grav)**2.*sk*sa - (n**4. &
2951  + 16.* ve**4.*wn**6.*alpha**2.)*sk*sa - 8. &
2952  *wn**3.*alpha*ve**2.*n**2.*(ck*ca-1.))
2953  j2 = (4.*wn**3.*alpha*ve**2.*sk*ca+n**2.*sa*ck &
2954  -dble(grav)*wn*sk*sa)
2955  IF (judge==2)THEN
2956  func1 = (sigma**2. - th*wn*dble(grav)) - th*j1/(j2+1.e-20)
2957  ELSEIF (judge==1)THEN
2958  func1 = (sigma**2. - th*wn*dble(grav))*j2 - th*j1
2959  ENDIF
2960  ENDIF
2961  !/
2962  END FUNCTION drfun_dble_cheng
2963  !/ ------------------------------------------------------------------- /
2964 
2965  !/ ------------------------------------------------------------------- /
2966  !/
2967  FUNCTION drfun_quad_cheng(WN,SIGMA,ES,NU,DICE,HICE,DEPTH) &
2968  result(func1)
2969  !/ +-----------------------------------+
2970  !/ | WAVEWATCH III NOAA/NCEP |
2971  !/ | E. Rogers |
2972  !/ | S. Zieger |
2973  !/ | X. Zhao |
2974  !/ | S. Cheng |
2975  !/ | FORTRAN 90 |
2976  !/ | Last update : 13-Jan-2016 |
2977  !/ +-----------------------------------+
2978  !/
2979  !/ 06-May-2013 : Origination (port from Clarkson.f90)( version 4.10 )
2980  !/ (E. Rogers)
2981  !/ 09-Oct-2013 : Update to meet WW3 coding standard (S. Zieger)
2982  !/ 30-Oct-2013 : Clarkson.f90 update added (S. Zieger)
2983  !/
2984  ! 1. Purpose :
2985  !
2986  ! Return dispersion relation function value for root finding
2987  !
2988  ! 2. Method :
2989  !
2990  ! Use quadruple precision for computation
2991  !
2992  ! 3. Parameters :
2993  !
2994  ! Parameter list
2995  ! ----------------------------------------------------------------
2996  ! FUNC1 CMPLX DBL O Result (COMPLEX(8))
2997  ! WN CMPLX DBL I Wavenumber (COMPLEX(8))
2998  ! W REAL DBL I Wave angular frequency
2999  ! ES REAL DBL I Effective shear modulus on ice
3000  ! NU REAL DBL I Effective viscosity
3001  ! DICE REAL DBL I Density of ice
3002  ! HICE REAL DBL I Thickness of ice
3003  ! DEPTH REAL DBL I Water depth
3004  !
3005  ! ----------------------------------------------------------------
3006  !
3007  ! 4. Subroutines used :
3008  !
3009  ! Name Type Module Description
3010  ! ----------------------------------------------------------------
3011  ! None.
3012  ! ----------------------------------------------------------------
3013  !
3014  ! 5. Called by :
3015  !
3016  ! Name Type Module Description
3017  ! ----------------------------------------------------------------
3018  ! F_ZHAO_CHENG xxx xxxx xxxxx
3019  ! ----------------------------------------------------------------
3020  !
3021  ! 6. Error messages :
3022  !
3023  ! 7. Remarks :
3024  !
3025  ! Updated authors: Cheng and Shen.
3026  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
3027  ! University) to Erick Rogers (NRL) on Aug 25 2015
3028  ! Original authors: Zhao and Shen.
3029  ! This code is based on Fortran code provided by Hayley Shen (Clarkson
3030  ! University) to Erick Rogers (NRL) on April 19 2013.
3031  ! ER: S. Cheng had "COMPLEX(16)" for the local parameters. This is not
3032  ! supported by my compiler (gfortran on linux machine), so I changed
3033  ! it to "COMPLEX(8)"
3034  !
3035  ! 8. Structure :
3036  !
3037  ! See source code.
3038  !
3039  ! 9. Switches :
3040  !
3041  ! 10. Source code :
3042  !/
3043  !/ ------------------------------------------------------------------- /
3044  USE constants, ONLY: grav, dwat
3045  !/
3046  IMPLICIT NONE
3047  !/
3048  !/ ------------------------------------------------------------------- /
3049  !/ Parameter list
3050  !/
3051  COMPLEX(8), INTENT(IN) :: wn
3052  REAL(8), INTENT(IN) :: sigma, es, nu, dice, hice, depth
3053  COMPLEX(8) :: func1 ! RESULT
3054  !/
3055  !/ ------------------------------------------------------------------- /
3056  !/ Local parameters
3057  !/
3058  COMPLEX(8) :: ve,alpha,n,m,l,sk,ck,sa,ca,th,thh,temp,j1,j2
3059  !/
3060  !/ ------------------------------------------------------------------- /
3061  ve = cmplx( nu, es/dice/sigma )
3062  alpha = sqrt( wn**2. - sigma/ve * cmplx(0.,1.d0) )
3063  n = sigma + 2. * ve * wn**2. * cmplx(0.,1.d0)
3064 
3065  temp = exp(wn*hice)
3066  sk = (temp - 1.d0/temp)/2.d0
3067  ck = (temp + 1.d0/temp)/2.d0
3068 
3069  temp = exp(alpha*hice)
3070  sa = (temp - 1.d0/temp)/2.d0
3071  ca = (temp + 1.d0/temp)/2.d0
3072  !
3073  temp = (wn*depth)
3074  IF ( real(temp).LT.18.d0 ) THEN
3075  temp = exp(temp)
3076  th = (temp - 1./temp)/(temp + 1./temp)
3077  ELSE
3078  th = 1.d0
3079  ENDIF
3080  !
3081  j1 = dice/dble(dwat)*(wn**2.*dble(grav)**2.*sk*sa - (n**4. &
3082  + 16.* ve**4.*wn**6.*alpha**2.)*sk*sa - 8. &
3083  *wn**3.*alpha*ve**2.*n**2.*(ck*ca-1.))
3084  j2 = (4.*wn**3.*alpha*ve**2.*sk*ca+n**2.*sa*ck &
3085  -dble(grav)*wn*sk*sa)
3086  func1 = (sigma**2. - th*wn*dble(grav))*j2 - th*j1
3087  !/
3088  END FUNCTION drfun_quad_cheng
3089  !/ ------------------------------------------------------------------- /
3090  ! End of new codes (or new variants) provided by S. Cheng
3091  !/ ------------------------------------------------------------------- /
3092  !/
3093  !/ End of module W3SIC3MD -------------------------------------------- /
3094  !/
3095 END MODULE w3sic3md
w3gdatmd::nk
integer, pointer nk
Definition: w3gdatmd.F90:1230
constants::abmin
real, parameter abmin
ABMIN.
Definition: constants.F90:94
w3adatmd::ic3cg
real, dimension(:,:), pointer ic3cg
Definition: w3adatmd.F90:576
w3adatmd::ic3wn_i
real, dimension(:,:), pointer ic3wn_i
Definition: w3adatmd.F90:576
w3gdatmd::ygrd
double precision, dimension(:,:), pointer ygrd
Definition: w3gdatmd.F90:1205
w3adatmd
Define data structures to set up wave model auxiliary data for several models simultaneously.
Definition: w3adatmd.F90:26
w3gdatmd::nspec
integer, pointer nspec
Definition: w3gdatmd.F90:1230
w3sic3md::drfun_dble_cheng
complex(8) function drfun_dble_cheng(WN, SIGMA, ES, NU, DICE, HICE, DEPTH, JUDGE)
Definition: w3sic3md.F90:2814
w3sic3md::smooth_k
subroutine smooth_k(WN_R, WN_I, SIGMA, N, SWITCHID)
Definition: w3sic3md.F90:2498
w3gdatmd::rlgtype
integer, parameter rlgtype
Definition: w3gdatmd.F90:624
w3idatmd::inflags2
logical, dimension(:), pointer inflags2
Definition: w3idatmd.F90:260
w3gdatmd::sig
real, dimension(:), pointer sig
Definition: w3gdatmd.F90:1234
w3odatmd::iaproc
integer, pointer iaproc
Definition: w3odatmd.F90:457
w3adatmd::ic3wn_r
real, dimension(:,:), pointer ic3wn_r
Definition: w3adatmd.F90:576
w3sic3md::calledic3table
integer, save calledic3table
Definition: w3sic3md.F90:88
w3arrymd::outmat
subroutine outmat(NDS, A, MX, NX, NY, MNAME)
Definition: w3arrymd.F90:988
w3odatmd::ndse
integer, pointer ndse
Definition: w3odatmd.F90:456
constants::sizefwtable
integer, parameter sizefwtable
SIZEFWTABLE.
Definition: constants.F90:91
w3odatmd::naperr
integer, pointer naperr
Definition: w3odatmd.F90:457
w3sic3md::ic3table_cheng
subroutine, public ic3table_cheng(ICE2, ICE3, ICE4)
Definition: w3sic3md.F90:1963
w3servmd
Definition: w3servmd.F90:3
w3gdatmd::nth
integer, pointer nth
Definition: w3gdatmd.F90:1230
w3odatmd
Definition: w3odatmd.F90:3
constants::dwat
real, parameter dwat
DWAT Density of water (kg/m3).
Definition: constants.F90:62
w3sic3md::w3ic3wncg_cheng
subroutine, public w3ic3wncg_cheng(WN_R, WN_I, CG, ICE1, ICE2, ICE3, ICE4, DPT)
Definition: w3sic3md.F90:1801
w3odatmd::naproc
integer, pointer naproc
Definition: w3odatmd.F90:457
constants::tpi
real, parameter tpi
TPI 2*Pi.
Definition: constants.F90:72
w3servmd::strace
subroutine strace(IENT, SNAME)
Definition: w3servmd.F90:148
constants::fwtable
real, dimension(0:sizefwtable) fwtable
FWTABLE.
Definition: constants.F90:92
w3gdatmd::gtype
integer, pointer gtype
Definition: w3gdatmd.F90:1094
w3idatmd
Define data structures to set up wave model input data for several models simultaneously.
Definition: w3idatmd.F90:16
w3gdatmd::mapwn
integer, dimension(:), pointer mapwn
Definition: w3gdatmd.F90:1231
w3arrymd
Definition: w3arrymd.F90:3
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
constants::delab
real delab
DELAB.
Definition: constants.F90:93
w3gdatmd::ic3pars
real, dimension(:), pointer ic3pars
Definition: w3gdatmd.F90:1148
w3gdatmd::dden
real, dimension(:), pointer dden
Definition: w3gdatmd.F90:1234
w3gdatmd
Definition: w3gdatmd.F90:16
w3sic3md::drfun_quad_cheng
complex(8) function drfun_quad_cheng(WN, SIGMA, ES, NU, DICE, HICE, DEPTH)
Definition: w3sic3md.F90:2969
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
w3arrymd::prt2ds
subroutine prt2ds(NDS, NFR0, NFR, NTH, E, FR, UFR, FACSP, FSC, RRCUT, PRVAR, PRUNIT, PNTNME)
Definition: w3arrymd.F90:1943
w3sic3md::w3ic3wncg_v1
subroutine, public w3ic3wncg_v1(WN_R, WN_I, CG, ICE1, ICE2, ICE3, ICE4, DPT)
Definition: w3sic3md.F90:658
w3dispmd
Definition: w3dispmd.F90:3
w3sic3md::wn_precalc_cheng
subroutine wn_precalc_cheng(WN, SIGMA, SIGMAM1, WN_O, WNM1, WNM2, ES_MOD, NU, DICE, HICE, DEPTH, SWITCHID, IK, KU)
Definition: w3sic3md.F90:2166
w3sic3md::w3sic3
subroutine, public w3sic3(A, DEPTH, CG, WN, IX, IY, S, D)
Definition: w3sic3md.F90:97
w3sic3md::delta
real function, dimension(:), allocatable delta(X)
Definition: w3sic3md.F90:1733
constants::grav
real, parameter grav
GRAV Acc.
Definition: constants.F90:61
w3sic3md
Definition: w3sic3md.F90:3
w3gdatmd::flagll
logical, pointer flagll
Definition: w3gdatmd.F90:1219